Шаг 3: добавляем дополнительные возможности
Этот раздел сейчас дорабатывается. Приносим извинения за неудобства. Если вам нужна срочная помощь, обратитесь в службу поддержки Tibbo.
Этот и другие проекты из раздела примеров кода опубликованы на нашем сайте под названием "test_dhcp_lib".
Качественный код предусматривает, что события могут пойти не по плану. Вот несколько идей, как сделать код надёжнее:
Проверка результата dhcp_start()
Эта функция возвращает одно из значений en_dhcp_status_codes(), и возвращённый результат нужно проверять! Решите сами, что делать в каждом конкретном случае, или просто остановите выполнение при ошибке:
...
if dhcp_start(PL_SOCK_INTERFACE_NET)<>DHCP_STATUS_OK then sys.halt 'do the same for the Wi-Fi interface
...
Что делать при вызове callback_dhcp_failure()
Запущенный DHCP-клиент продолжает работать бесконечно. Тем не менее в какой-то момент приложению придётся признать, что DHCP-конфигурация действительно не удалась, и пора что-то предпринять. Здесь пригодится набор альтернативных параметров конфигурации. В коде ниже счётчики net_dhcp_fail_ctr и wln_dhcp_fail_ctr накапливают число сбоев. Обратите внимание, что dhcp_stop() вызывается, как только счётчик достигает DHCP_FAIL_LIMIT:
include "global.tbh"
'--------------------------------------------------------------------
const DHCP_FAIL_LIMIT=1 'max number of DHCP retry "batches"
const ALT_NET_IP="192.168.1.40"
const ALT_NET_GATEWAY_IP="192.168.1.1"
const ALT_NET_NETMASK="255.255.255.0"
const ALT_WLN_IP="192.168.1.41"
const ALT_WLN_GATEWAY_IP="192.168.1.1"
const ALT_WLN_NETMASK="255.255.255.0"
'--------------------------------------------------------------------
#if NET_AVAILABLE
dim net_dhcp_fail_ctr as byte 'no need to init to 0 (this is automatic for global vars)
#endif
#if WLN_AVAILABLE
dim wln_dhcp_fail_ctr as byte 'no need to init to 0 (this is automatic for global vars)
#endif
'====================================================================
sub callback_dhcp_ok(renew as no_yes, interface as pl_sock_interfaces, byref ip as string, byref gateway_ip as string, byref netmask as string, lease_time as dword)
dim f as byte
#if NET_AVAILABLE
if interface=PL_SOCK_INTERFACE_NET then
if renew=YES and net.ip<>ip then
'this is a lease renewal and the DHCP server has issues new IP
'it is better to reboot than deal with the implications of the changed IP
sys.reboot
end if
if net.ip<>ip then
'no need to close sockets -- this is definitely NOT a renewal an the DHCP lib
'has already closed all socket connections on this interface prior to setting
'the IP to 0.0.0.0
net.ip=ip
net.gatewayip=gateway_ip
net.netmask=netmask
net_dhcp_fail_ctr=0
end if
end if
#endif
#if WLN_AVAILABLE
if interface=PL_SOCK_INTERFACE_WLN then
if renew=YES and wln.ip<>ip then
'this is a lease renewal and the DHCP server has issues new IP
'it is better to reboot than deal with the implications of the changed IP
sys.reboot
end if
if wln.ip<>ip then
'no need to close sockets -- this is definitely NOT a renewal an the DHCP lib
'has already closed all socket connections on this interface prior to setting
'the IP to 0.0.0.0
wln.ip=ip
wln.gatewayip=gateway_ip
wln.netmask=netmask
wln_dhcp_fail_ctr=0
end if
end if
#endif
end sub
'--------------------------------------------------------------------
sub callback_dhcp_failure(interface as pl_sock_interfaces,failure_code as en_dhcp_status_codes)
#if NET_AVAILABLE
if interface=PL_SOCK_INTERFACE_NET then
if net_dhcp_fail_ctr>=DHCP_FAIL_LIMIT then
net.ip=ALT_NET_IP
net.gatewayip=ALT_NET_GATEWAY_IP
net.netmask=ALT_NET_NETMASK
dhcp_stop(PL_SOCK_INTERFACE_NET)
else
net_dhcp_fail_ctr=net_dhcp_fail_ctr+1
end if
end if
#endif
#if WLN_AVAILABLE
if interface=PL_SOCK_INTERFACE_WLN then
if wln_dhcp_fail_ctr>=DHCP_FAIL_LIMIT then
wln.ip=ALT_WLN_IP
wln.gatewayip=ALT_WLN_GATEWAY_IP
wln.netmask=ALT_WLN_NETMASK
dhcp_stop(PL_SOCK_INTERFACE_WLN)
else
wln_dhcp_fail_ctr=wln_dhcp_fail_ctr+1
end if
end if
#endif
end sub
...
Что делать при вызове callback_dhcp_pre_clear_ip()
Это сильно зависит от приложения, но мы советуем аккуратно закрыть существующие TCP-соединения. Всё, что останется без присмотра, DHCP-библиотека жёстко оборвёт (молотком sock.discard), поэтому о сокетных соединениях лучше позаботиться заранее. Вот пример, где ожидается отправка неотправленных данных в сокете "SOCK_DATA":
...
sock.num=SOCK_DATA
while sock.txlen>0
doevents 'optional, allows other things in your app to execute
wend
...
Что делать при вызове callback_dhcp_pre_buffrq()
...
'--------------------------------------------------------------------
sub callback_dhcp_pre_buffrq(required_buff_pages as byte)
sock_release(SOCK_DATA) 'this deallocates buffers
end sub
'--------------------------------------------------------------------
sub callback_dhcp_buff_released()
sock.num=SOCK_DATA
sock.rxbuffrq(sys.freebuffpages/2)
sock.txbuffrq(sys.freebuffpages/2)
sys.buffalloc
'proceed with socket setup
end sub
...