diff --git a/features/FEATURE_LWIP/lwip-interface/lwip_stack.c b/features/FEATURE_LWIP/lwip-interface/lwip_stack.c index f5fa6308b4..6c7fab23d8 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip_stack.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip_stack.c @@ -197,9 +197,9 @@ static bool convert_lwip_addr_to_mbed(nsapi_addr_t *out, const ip_addr_t *in) #endif } +#if LWIP_IPV4 static const ip_addr_t *mbed_lwip_get_ipv4_addr(const struct netif *netif) { -#if LWIP_IPV4 if (!netif_is_up(netif)) { return NULL; } @@ -207,14 +207,15 @@ static const ip_addr_t *mbed_lwip_get_ipv4_addr(const struct netif *netif) if (!ip4_addr_isany(netif_ip4_addr(netif))) { return netif_ip_addr4(netif); } -#endif return NULL; } +#endif +#if LWIP_IPV6 static const ip_addr_t *mbed_lwip_get_ipv6_addr(const struct netif *netif) { -#if LWIP_IPV6 + if (!netif_is_up(netif)) { return NULL; } @@ -225,17 +226,17 @@ static const ip_addr_t *mbed_lwip_get_ipv6_addr(const struct netif *netif) return netif_ip_addr6(netif, i); } } -#endif return NULL; - } +#endif const ip_addr_t *mbed_lwip_get_ip_addr(bool any_addr, const struct netif *netif) { const ip_addr_t *pref_ip_addr = 0; const ip_addr_t *npref_ip_addr = 0; +#if LWIP_IPV4 && LWIP_IPV6 #if IP_VERSION_PREF == PREF_IPV4 pref_ip_addr = mbed_lwip_get_ipv4_addr(netif); npref_ip_addr = mbed_lwip_get_ipv6_addr(netif); @@ -243,6 +244,11 @@ const ip_addr_t *mbed_lwip_get_ip_addr(bool any_addr, const struct netif *netif) pref_ip_addr = mbed_lwip_get_ipv6_addr(netif); npref_ip_addr = mbed_lwip_get_ipv4_addr(netif); #endif +#elif LWIP_IPV6 + pref_ip_addr = mbed_lwip_get_ipv6_addr(netif); +#elif LWIP_IPV4 + pref_ip_addr = mbed_lwip_get_ipv4_addr(netif); +#endif if (pref_ip_addr) { return pref_ip_addr; @@ -307,25 +313,38 @@ static void mbed_lwip_netif_link_irq(struct netif *lwip_netif) } } -static sys_sem_t lwip_netif_has_addr; +static char lwip_has_addr_state = 0; + +#define HAS_ANY_ADDR 1 +static sys_sem_t lwip_netif_has_any_addr; +#if PREF_ADDR_TIMEOUT +#define HAS_PREF_ADDR 2 +static sys_sem_t lwip_netif_has_pref_addr; +#endif +#if BOTH_ADDR_TIMEOUT +#define HAS_BOTH_ADDR 4 +static sys_sem_t lwip_netif_has_both_addr; +#endif + static void mbed_lwip_netif_status_irq(struct netif *lwip_netif) { - static bool any_addr = true; - if (netif_is_up(lwip_netif)) { - // Indicates that has address - if (any_addr == true && mbed_lwip_get_ip_addr(true, lwip_netif)) { - sys_sem_signal(&lwip_netif_has_addr); - any_addr = false; - return; + if (!(lwip_has_addr_state & HAS_ANY_ADDR) && mbed_lwip_get_ip_addr(true, lwip_netif)) { + sys_sem_signal(&lwip_netif_has_any_addr); + lwip_has_addr_state |= HAS_ANY_ADDR; } - - // Indicates that has preferred address - if (mbed_lwip_get_ip_addr(false, lwip_netif)) { - sys_sem_signal(&lwip_netif_has_addr); +#if PREF_ADDR_TIMEOUT + if (!(lwip_has_addr_state & HAS_PREF_ADDR) && mbed_lwip_get_ip_addr(false, lwip_netif)) { + sys_sem_signal(&lwip_netif_has_pref_addr); + lwip_has_addr_state |= HAS_PREF_ADDR; } - } else { - any_addr = true; +#endif +#if BOTH_ADDR_TIMEOUT + if (!(lwip_has_addr_state & HAS_BOTH_ADDR) && mbed_lwip_get_ipv4_addr(lwip_netif) && mbed_lwip_get_ipv6_addr(lwip_netif)) { + sys_sem_signal(&lwip_netif_has_both_addr); + lwip_has_addr_state |= HAS_BOTH_ADDR; + } +#endif } } @@ -435,8 +454,13 @@ static void mbed_lwip_core_init(void) sys_sem_new(&lwip_tcpip_inited, 0); sys_sem_new(&lwip_netif_linked, 0); sys_sem_new(&lwip_netif_unlinked, 0); - sys_sem_new(&lwip_netif_has_addr, 0); - + sys_sem_new(&lwip_netif_has_any_addr, 0); +#if PREF_ADDR_TIMEOUT + sys_sem_new(&lwip_netif_has_pref_addr, 0); +#endif +#if BOTH_ADDR_TIMEOUT + sys_sem_new(&lwip_netif_has_both_addr, 0); +#endif tcpip_init(mbed_lwip_tcpip_init_irq, NULL); sys_arch_sem_wait(&lwip_tcpip_inited, 0); @@ -603,20 +627,26 @@ nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const cha // If doesn't have address if (!mbed_lwip_get_ip_addr(true, &lwip_netif)) { - if (sys_arch_sem_wait(&lwip_netif_has_addr, DHCP_TIMEOUT * 1000) == SYS_ARCH_TIMEOUT) { + if (sys_arch_sem_wait(&lwip_netif_has_any_addr, DHCP_TIMEOUT * 1000) == SYS_ARCH_TIMEOUT) { if (ppp) { ppp_lwip_disconnect(); } - return NSAPI_ERROR_DHCP_FAILURE; } } -#if ADDR_TIMEOUT +#if PREF_ADDR_TIMEOUT // If address is not for preferred stack waits a while to see // if preferred stack address is acquired if (!mbed_lwip_get_ip_addr(false, &lwip_netif)) { - sys_arch_sem_wait(&lwip_netif_has_addr, ADDR_TIMEOUT * 1000); + sys_arch_sem_wait(&lwip_netif_has_pref_addr, PREF_ADDR_TIMEOUT * 1000); + } +#endif +#if BOTH_ADDR_TIMEOUT + // If addresses for both stacks are not available waits a while to + // see if address for both stacks are acquired + if (!(mbed_lwip_get_ipv4_addr(&lwip_netif) && mbed_lwip_get_ipv6_addr(&lwip_netif))) { + sys_arch_sem_wait(&lwip_netif_has_both_addr, BOTH_ADDR_TIMEOUT * 1000); } #endif @@ -677,10 +707,17 @@ nsapi_error_t mbed_lwip_bringdown_2(bool ppp) mbed_lwip_clear_ipv6_addresses(&lwip_netif); #endif - - sys_sem_free(&lwip_netif_has_addr); - sys_sem_new(&lwip_netif_has_addr, 0); - + sys_sem_free(&lwip_netif_has_any_addr); + sys_sem_new(&lwip_netif_has_any_addr, 0); +#if PREF_ADDR_TIMEOUT + sys_sem_free(&lwip_netif_has_pref_addr); + sys_sem_new(&lwip_netif_has_pref_addr, 0); +#endif +#if BOTH_ADDR_TIMEOUT + sys_sem_free(&lwip_netif_has_both_addr); + sys_sem_new(&lwip_netif_has_both_addr, 0); +#endif + lwip_has_addr_state = 0; lwip_connected = false; return 0; } @@ -789,19 +826,8 @@ static nsapi_error_t mbed_lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t enum netconn_type lwip_proto = proto == NSAPI_TCP ? NETCONN_TCP : NETCONN_UDP; -#if LWIP_IPV6 && LWIP_IPV4 - const ip_addr_t *ip_addr; - ip_addr = mbed_lwip_get_ip_addr(true, &lwip_netif); - - if (IP_IS_V6(ip_addr)) { - // Enable IPv6 (or dual-stack). LWIP dual-stack support is - // currently incomplete as of 2.0.0rc2 - eg we will only be able - // to do a UDP sendto to an address matching the type selected - // here. Matching "get_ip_addr" and DNS logic, use v4 if - // available. - lwip_proto |= NETCONN_TYPE_IPV6; - } -#elif LWIP_IPV6 +#if LWIP_IPV6 + // Enable IPv6 (or dual-stack) lwip_proto |= NETCONN_TYPE_IPV6; #endif diff --git a/features/FEATURE_LWIP/lwip-interface/lwipopts.h b/features/FEATURE_LWIP/lwip-interface/lwipopts.h index 18e47eea2b..c619c7f681 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwipopts.h +++ b/features/FEATURE_LWIP/lwip-interface/lwipopts.h @@ -46,12 +46,19 @@ #error "Either IPv4 or IPv6 must be enabled." #endif -// On dual stack configuration how long wait for preferred stack -// before selecting either IPv6 or IPv4 +// On dual stack configuration how long to wait for both or preferred stack +// addresses before completing bring up. #if LWIP_IPV4 && LWIP_IPV6 -#define ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT +#if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE +#define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT +#define PREF_ADDR_TIMEOUT 0 #else -#define ADDR_TIMEOUT 0 +#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT +#define BOTH_ADDR_TIMEOUT 0 +#endif +#else +#define PREF_ADDR_TIMEOUT 0 +#define BOTH_ADDR_TIMEOUT 0 #endif #define DHCP_TIMEOUT 60 @@ -242,6 +249,7 @@ #define AUTOIP_DEBUG LWIP_DBG_OFF #define DNS_DEBUG LWIP_DBG_OFF #define IP6_DEBUG LWIP_DBG_OFF + #if MBED_CONF_LWIP_ENABLE_PPP_TRACE #define PPP_DEBUG LWIP_DBG_ON #else @@ -260,6 +268,8 @@ #define LWIP_STATS 0 #endif +#define TRACE_TO_ASCII_HEX_DUMP 0 + #define LWIP_PLATFORM_BYTESWAP 1 #define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1 @@ -278,20 +288,25 @@ // Note generic macro name used rather than MBED_CONF_LWIP_PPP_ENABLED // to allow users like PPPCellularInterface to detect that nsapi_ppp.h is available. #if NSAPI_PPP_AVAILABLE -#define PPP_SUPPORT 1 -#define CHAP_SUPPORT 1 -#define PPP_INPROC_IRQ_SAFE 1 +#define PPP_SUPPORT 1 +#if MBED_CONF_LWIP_IPV6_ENABLED +#define PPP_IPV6_SUPPORT 1 +// Disable DAD for PPP +#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0 +#endif +#define CHAP_SUPPORT 1 +#define PPP_INPROC_IRQ_SAFE 1 // Save RAM -#define PAP_SUPPORT 0 -#define VJ_SUPPORT 0 -#define PRINTPKT_SUPPORT 0 +#define PAP_SUPPORT 0 +#define VJ_SUPPORT 0 +#define PRINTPKT_SUPPORT 0 // Broadcast -#define IP_SOF_BROADCAST 0 -#define IP_SOF_BROADCAST_RECV 0 +#define IP_SOF_BROADCAST 0 +#define IP_SOF_BROADCAST_RECV 0 -#define MAXNAMELEN 64 /* max length of hostname or name for auth */ -#define MAXSECRETLEN 64 +#define MAXNAMELEN 64 /* max length of hostname or name for auth */ +#define MAXSECRETLEN 64 #endif // NSAPI_PPP_AVAILABLE // Make sure we default these to off, so diff --git a/features/FEATURE_LWIP/lwip-interface/mbed_lib.json b/features/FEATURE_LWIP/lwip-interface/mbed_lib.json index 1fbfcadf87..0d654c594a 100644 --- a/features/FEATURE_LWIP/lwip-interface/mbed_lib.json +++ b/features/FEATURE_LWIP/lwip-interface/mbed_lib.json @@ -14,9 +14,13 @@ "value": 4 }, "addr-timeout": { - "help": "On dual-stack system how long to wait preferred stack's address in seconds", + "help": "On dual-stack system how long to additionally wait for other stack's address in seconds", "value": 5 - }, + }, + "addr-timeout-mode": { + "help": "Address timeout mode; true: wait both stack's addresses; false: wait for preferred stack's address", + "value": true + }, "ethernet-enabled": { "help": "Enable support for Ethernet interfaces", "value": true