diff --git a/os/various/lwip_bindings/lwipthread.c b/os/various/lwip_bindings/lwipthread.c index 9ee40211a..ee4303fcc 100644 --- a/os/various/lwip_bindings/lwipthread.c +++ b/os/various/lwip_bindings/lwipthread.c @@ -270,7 +270,7 @@ static net_addr_mode_t addressMode; static ip4_addr_t ip, gateway, netmask; static struct netif thisif; -static void linkup_cb(void *p) +void lwipDefaultLinkUpCB(void *p) { struct netif *ifc = (struct netif*) p; (void) ifc; @@ -284,7 +284,7 @@ static void linkup_cb(void *p) #endif } -static void linkdown_cb(void *p) +void lwipDefaultLinkDownCB(void *p) { struct netif *ifc = (struct netif*) p; (void) ifc; @@ -309,6 +309,8 @@ static THD_FUNCTION(lwip_thread, p) { event_listener_t el0, el1; static const MACConfig mac_config = {thisif.hwaddr}; err_t result; + tcpip_callback_fn link_up_cb = NULL; + tcpip_callback_fn link_down_cb = NULL; chRegSetThreadName(LWIP_THREAD_NAME); @@ -317,7 +319,7 @@ static THD_FUNCTION(lwip_thread, p) { /* TCP/IP parameters, runtime or compile time.*/ if (p) { - struct lwipthread_opts *opts = p; + lwipthread_opts_t *opts = p; unsigned i; for (i = 0; i < 6; i++) @@ -329,6 +331,8 @@ static THD_FUNCTION(lwip_thread, p) { #if LWIP_NETIF_HOSTNAME thisif.hostname = opts->ourHostName; #endif + link_up_cb = opts->link_up_cb; + link_down_cb = opts->link_down_cb; } else { thisif.hwaddr[0] = LWIP_ETHADDR_0; @@ -352,6 +356,11 @@ static THD_FUNCTION(lwip_thread, p) { #endif } + if (!link_up_cb) + link_up_cb = lwipDefaultLinkUpCB; + if (!link_down_cb) + link_down_cb = lwipDefaultLinkDownCB; + #if LWIP_NETIF_HOSTNAME if (thisif.hostname == NULL) thisif.hostname = LWIP_NETIF_HOSTNAME_STRING; @@ -391,12 +400,12 @@ static THD_FUNCTION(lwip_thread, p) { if (current_link_status) { tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up, &thisif, 0); - tcpip_callback_with_block(linkup_cb, &thisif, 0); + tcpip_callback_with_block(link_up_cb, &thisif, 0); } else { tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down, &thisif, 0); - tcpip_callback_with_block(linkdown_cb, &thisif, 0); + tcpip_callback_with_block(link_down_cb, &thisif, 0); } } } @@ -432,6 +441,7 @@ static THD_FUNCTION(lwip_thread, p) { * then the static configuration is used. */ void lwipInit(const lwipthread_opts_t *opts) { + /* Creating the lwIP thread (it changes priority internally).*/ chThdCreateStatic(wa_lwip_thread, sizeof (wa_lwip_thread), chThdGetPriorityX() - 1, lwip_thread, (void *)opts); @@ -444,4 +454,77 @@ void lwipInit(const lwipthread_opts_t *opts) { chSysUnlock(); } +typedef struct lwip_reconf_params { + const lwipreconf_opts_t *opts; + semaphore_t completion; +} lwip_reconf_params_t; + +static void do_reconfigure(void *p) +{ + lwip_reconf_params_t *reconf = (lwip_reconf_params_t*) p; + + switch (addressMode) { +#if LWIP_DHCP + case NET_ADDRESS_DHCP: { + if (netif_is_up(&thisif)) + dhcp_stop(&thisif); + break; + } +#endif + case NET_ADDRESS_STATIC: { + ip4_addr_t zero = { 0 }; + netif_set_ipaddr(&thisif, &zero); + netif_set_netmask(&thisif, &zero); + netif_set_gw(&thisif, &zero); + break; + } +#if LWIP_AUTOIP + case NET_ADDRESS_AUTO: { + if (netif_is_up(&thisif)) + autoip_stop(&thisif); + break; + } +#endif + } + + ip.addr = reconf->opts->address; + gateway.addr = reconf->opts->gateway; + netmask.addr = reconf->opts->netmask; + addressMode = reconf->opts->addrMode; + + switch (addressMode) { +#if LWIP_DHCP + case NET_ADDRESS_DHCP: { + if (netif_is_up(&thisif)) + dhcp_start(&thisif); + break; + } +#endif + case NET_ADDRESS_STATIC: { + netif_set_ipaddr(&thisif, &ip); + netif_set_netmask(&thisif, &netmask); + netif_set_gw(&thisif, &gateway); + break; + } +#if LWIP_AUTOIP + case NET_ADDRESS_AUTO: { + if (netif_is_up(&thisif)) + autoip_start(&thisif); + break; + } +#endif + } + + chSemSignal(&reconf->completion); +} + +void lwipReconfigure(const lwipreconf_opts_t *opts) +{ + lwip_reconf_params_t params; + params.opts = opts; + chSemObjectInit(¶ms.completion, 0); + tcpip_callback_with_block(do_reconfigure, ¶ms, 0); + chSemWait(¶ms.completion); +} + /** @} */ diff --git a/os/various/lwip_bindings/lwipthread.h b/os/various/lwip_bindings/lwipthread.h index 8018195f2..b40d05ffd 100644 --- a/os/various/lwip_bindings/lwipthread.h +++ b/os/various/lwip_bindings/lwipthread.h @@ -232,12 +232,40 @@ typedef struct lwipthread_opts { #if LWIP_NETIF_HOSTNAME || defined(__DOXYGEN__) const char *ourHostName; #endif + /** + * @brief Link up callback. + * + * @note Called from the tcpip thread when the link goes up. + * Can be NULL to default to lwipDefaultLinkUpCB. + */ + void (*link_up_cb)(void*); + /** + * @brief Link down callback. + * + * @note Called from the tcpip thread when the link goes down. + * Can be NULL to default to lwipDefaultLinkDownCB. + */ + void (*link_down_cb)(void*); } lwipthread_opts_t; +/** + * @brief Parameters for lwipReconfigure. + * @note Same meaning as in lwipthread_opts_t. + */ +typedef struct lwipreconf_opts { + uint32_t address; + uint32_t netmask; + uint32_t gateway; + net_addr_mode_t addrMode; +} lwipreconf_opts_t; + #ifdef __cplusplus extern "C" { #endif + void lwipDefaultLinkUpCB(void *p); + void lwipDefaultLinkDownCB(void *p); void lwipInit(const lwipthread_opts_t *opts); + void lwipReconfigure(const lwipreconf_opts_t *opts); #ifdef __cplusplus } #endif diff --git a/readme.txt b/readme.txt index 25e3080e5..7510d4a2e 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,7 @@ ***************************************************************************** *** Next *** +- NEW: Added dynamic reconfiguration API to lwIP bindings. - FIX: Corrected I2C4 BDMA #define conditional in I2Cv3 (bug #1082) - RT: Relocated the "ctx" field in the thread structure in order to save some RAM, it caused unused space in the "ch" variable.