LWIPBP3595Interface library for mbed-os.

Dependents:   LWIPBP3595Interface_STA_for_mbed-os

Fork of LWIPBP3595Interface by Rohm

Revision:
6:993197aaf5a4
Parent:
5:d03489ec5033
--- a/lwip_wifi_stack.c	Thu Nov 24 09:13:23 2016 +0000
+++ b/lwip_wifi_stack.c	Tue Mar 28 09:50:17 2017 +0000
@@ -87,6 +87,11 @@
 
 static void mbed_lwip_wifi_socket_callback(struct netconn *nc, enum netconn_evt eh, u16_t len)
 {
+    // Filter send minus events
+    if (eh == NETCONN_EVT_SENDMINUS && nc->state == NETCONN_WRITE) {
+        return;
+    }
+
     sys_prot_t prot = sys_arch_protect();
 
     for (int i = 0; i < MEMP_NUM_NETCONN; i++) {
@@ -221,7 +226,7 @@
 
 }
 
-const ip_addr_t *mbed_lwip_wifi_get_ip_addr(bool any_addr, const struct netif *netif)
+static const ip_addr_t *mbed_lwip_wifi_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;
@@ -243,36 +248,42 @@
     return NULL;
 }
 
-#if LWIP_IPV6
-void add_dns_addr(struct netif *lwip_netif)
+static void add_dns_addr_wifi(struct netif *lwip_netif)
 {
+    // Do nothing if not brought up
     const ip_addr_t *ip_addr = mbed_lwip_wifi_get_ip_addr(true, lwip_netif);
-    if (ip_addr) {
-        if (IP_IS_V6(ip_addr)) {
-            const ip_addr_t *dns_ip_addr;
-            bool dns_addr_exists = false;
+    if (!ip_addr) {
+        return;
+    }
 
-            for (char numdns = 0; numdns < DNS_MAX_SERVERS; numdns++) {
-                dns_ip_addr = dns_getserver(numdns);
-                if (!ip_addr_isany(dns_ip_addr)) {
-                   dns_addr_exists = true;
-                   break;
-                }
-            }
-
-            if (!dns_addr_exists) {
-                /* 2001:4860:4860::8888 google */
-                ip_addr_t ipv6_dns_addr = IPADDR6_INIT(
-                        PP_HTONL(0x20014860UL),
-                        PP_HTONL(0x48600000UL),
-                        PP_HTONL(0x00000000UL),
-                        PP_HTONL(0x00008888UL));
-                dns_setserver(0, &ipv6_dns_addr);
-            }
+    // Check for existing dns server
+    for (char numdns = 0; numdns < DNS_MAX_SERVERS; numdns++) {
+        const ip_addr_t *dns_ip_addr = dns_getserver(numdns);
+        if (!ip_addr_isany(dns_ip_addr)) {
+            return;
         }
     }
+
+#if LWIP_IPV6
+    if (IP_IS_V6(ip_addr)) {
+        /* 2001:4860:4860::8888 google */
+        ip_addr_t ipv6_dns_addr = IPADDR6_INIT(
+                PP_HTONL(0x20014860UL),
+                PP_HTONL(0x48600000UL),
+                PP_HTONL(0x00000000UL),
+                PP_HTONL(0x00008888UL));
+        dns_setserver(0, &ipv6_dns_addr);
+    }
+#endif
+
+#if LWIP_IPV4
+    if (IP_IS_V4(ip_addr)) {
+        /* 8.8.8.8 google */
+        ip_addr_t ipv4_dns_addr = IPADDR4_INIT(0x08080808);
+        dns_setserver(0, &ipv4_dns_addr);
+    }
+#endif
 }
-#endif
 
 static sys_sem_t lwip_tcpip_inited;
 static void mbed_lwip_wifi_tcpip_init_irq(void *eh)
@@ -293,16 +304,20 @@
 {
     static bool any_addr = true;
 
-    // Indicates that has address
-    if (any_addr == true && mbed_lwip_wifi_get_ip_addr(true, lwip_netif)) {
-        sys_sem_signal(&lwip_netif_has_addr);
-        any_addr = false;
-        return;
-    }
+    if (netif_is_up(lwip_netif)) {
+        // Indicates that has address
+        if (any_addr == true && mbed_lwip_wifi_get_ip_addr(true, lwip_netif)) {
+            sys_sem_signal(&lwip_netif_has_addr);
+            any_addr = false;
+            return;
+        }
 
-    // Indicates that has preferred address
-    if (mbed_lwip_wifi_get_ip_addr(false, lwip_netif)) {
-        sys_sem_signal(&lwip_netif_has_addr);
+        // Indicates that has preferred address
+        if (mbed_lwip_wifi_get_ip_addr(false, lwip_netif)) {
+            sys_sem_signal(&lwip_netif_has_addr);
+        }
+    } else {
+        any_addr = true;
     }
 }
 
@@ -426,7 +441,7 @@
   if (lwip_netif.mld_mac_filter != NULL) {
     ip6_addr_t ip6_allnodes_ll;
     ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
-    lwip_netif.mld_mac_filter(&lwip_netif, &ip6_allnodes_ll, MLD6_ADD_MAC_FILTER);
+    lwip_netif.mld_mac_filter(&lwip_netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
   }
 #endif /* LWIP_IPV6_MLD */
 
@@ -483,7 +498,6 @@
         if (ret == SYS_ARCH_TIMEOUT) {
             return NSAPI_ERROR_DHCP_FAILURE;
         }
-        lwip_connected = true;
     }
 
 #if ADDR_TIMEOUT
@@ -494,13 +508,21 @@
     }
 #endif
 
-#if LWIP_IPV6
-    add_dns_addr(&lwip_netif);
-#endif
+    add_dns_addr_wifi(&lwip_netif);
 
+    lwip_connected = true;
     return 0;
 }
 
+#if LWIP_IPV6
+static void mbed_lwip_wifi_clear_ipv6_addresses(struct netif *lwip_netif)
+{
+    for (u8_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+        netif_ip6_addr_set_state(lwip_netif, i, IP6_ADDR_INVALID);
+    }
+}
+#endif
+
 nsapi_error_t mbed_lwip_wifi_bringdown(void)
 {
     // Check if we've connected
@@ -514,13 +536,18 @@
         dhcp_release(&lwip_netif);
         dhcp_stop(&lwip_netif);
         lwip_dhcp = false;
-    } else {
-        netif_set_down(&lwip_netif);
     }
 #endif
 
+    netif_set_down(&lwip_netif);
+
+#if LWIP_IPV6
+    mbed_lwip_wifi_clear_ipv6_addresses(&lwip_netif);
+#endif
+
+    sys_sem_free(&lwip_netif_has_addr);
+    sys_sem_new(&lwip_netif_has_addr, 0);
     lwip_connected = false;
-    // TO DO - actually remove addresses from stack, and shut down properly
     return 0;
 }
 
@@ -529,11 +556,12 @@
     switch (err) {
         case ERR_OK:
         case ERR_CLSD:
-        case ERR_RST:
             return 0;
         case ERR_MEM:
             return NSAPI_ERROR_NO_MEMORY;
         case ERR_CONN:
+        case ERR_RST:
+        case ERR_ABRT:
             return NSAPI_ERROR_NO_CONNECTION;
         case ERR_TIMEOUT:
         case ERR_RTE:
@@ -592,6 +620,22 @@
     return 0;
 }
 
+static nsapi_error_t mbed_lwip_wifi_add_dns_server(nsapi_stack_t *stack, nsapi_addr_t addr)
+{
+    // Shift all dns servers down to give precedence to new server
+    for (int i = DNS_MAX_SERVERS-1; i > 0; i--) {
+        dns_setserver(i, dns_getserver(i-1));
+    }
+
+    ip_addr_t ip_addr;
+    if (!convert_mbed_addr_to_lwip(&ip_addr, &addr)) {
+        return NSAPI_ERROR_PARAMETER;
+    }
+
+    dns_setserver(0, &ip_addr);
+    return 0;
+}
+
 static nsapi_error_t mbed_lwip_wifi_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, nsapi_protocol_t proto)
 {
     // check if network is connected
@@ -707,6 +751,8 @@
     (void) netconn_peer(ns->conn, &peer_addr, port);
     convert_lwip_addr_to_mbed(addr, &peer_addr);
 
+    netconn_set_nonblocking(ns->conn, true);
+
     return 0;
 }
 
@@ -846,8 +892,9 @@
 }
 
 /* LWIP network stack */
-const nsapi_stack_api_t lwip_wifi_stack_api = {
+static const nsapi_stack_api_t lwip_wifi_stack_api = {
     .gethostbyname      = mbed_lwip_wifi_gethostbyname,
+    .add_dns_server     = mbed_lwip_wifi_add_dns_server,
     .socket_open        = mbed_lwip_wifi_socket_open,
     .socket_close       = mbed_lwip_wifi_socket_close,
     .socket_bind        = mbed_lwip_wifi_socket_bind,