Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Revision:
1:9db0e321a9f4
Parent:
0:5b88d5760320
--- a/features/lwipstack/lwip_tools.cpp	Tue Dec 17 23:23:45 2019 +0000
+++ b/features/lwipstack/lwip_tools.cpp	Tue Dec 31 06:02:27 2019 +0000
@@ -23,9 +23,14 @@
 #include "lwip/api.h"
 
 #include "LWIPStack.h"
+#include "lwip_tools.h"
 
 #include "netsocket/nsapi_types.h"
 
+#if !LWIP_IPV4 || !LWIP_IPV6
+static bool all_zeros(const uint8_t *p, int len);
+#endif
+
 /* LWIP error remapping */
 nsapi_error_t LWIP::err_remap(err_t err)
 {
@@ -74,6 +79,23 @@
     return NULL;
 }
 
+const ip_addr_t *LWIP::get_ipv6_link_local_addr(const struct netif *netif)
+{
+#if LWIP_IPV6
+    if (!netif_is_up(netif)) {
+        return NULL;
+    }
+
+    for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+        if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
+                ip6_addr_islinklocal(netif_ip6_addr(netif, i))) {
+            return netif_ip_addr6(netif, i);
+        }
+    }
+#endif
+    return NULL;
+}
+
 const ip_addr_t *LWIP::get_ipv6_addr(const struct netif *netif)
 {
 #if LWIP_IPV6
@@ -87,6 +109,12 @@
             return netif_ip_addr6(netif, i);
         }
     }
+
+    for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+        if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) {
+            return netif_ip_addr6(netif, i);
+        }
+    }
 #endif
     return NULL;
 }
@@ -192,3 +220,83 @@
     free(s->multicast_memberships);
     s->multicast_memberships = NULL;
 }
+
+bool convert_lwip_addr_to_mbed(nsapi_addr_t *out, const ip_addr_t *in)
+{
+#if LWIP_IPV6
+    if (IP_IS_V6(in)) {
+        out->version = NSAPI_IPv6;
+        SMEMCPY(out->bytes, ip_2_ip6(in), sizeof(ip6_addr_t));
+        return true;
+    }
+#endif
+#if LWIP_IPV4
+    if (IP_IS_V4(in)) {
+        out->version = NSAPI_IPv4;
+        SMEMCPY(out->bytes, ip_2_ip4(in), sizeof(ip4_addr_t));
+        return true;
+    }
+#endif
+#if LWIP_IPV6 && LWIP_IPV4
+    return false;
+#endif
+}
+
+bool convert_mbed_addr_to_lwip(ip_addr_t *out, const nsapi_addr_t *in)
+{
+#if LWIP_IPV6
+    if (in->version == NSAPI_IPv6) {
+        IP_SET_TYPE(out, IPADDR_TYPE_V6);
+        SMEMCPY(ip_2_ip6(out), in->bytes, sizeof(ip6_addr_t));
+        return true;
+    }
+#if !LWIP_IPV4
+    /* For bind() and other purposes, need to accept "null" of other type */
+    /* (People use IPv4 0.0.0.0 as a general null) */
+    if (in->version == NSAPI_UNSPEC ||
+            (in->version == NSAPI_IPv4 && all_zeros(in->bytes, 4))) {
+        ip_addr_set_zero_ip6(out);
+        return true;
+    }
+#endif
+#endif
+
+#if LWIP_IPV4
+    if (in->version == NSAPI_IPv4) {
+        IP_SET_TYPE(out, IPADDR_TYPE_V4);
+        SMEMCPY(ip_2_ip4(out), in->bytes, sizeof(ip4_addr_t));
+        return true;
+    }
+#if !LWIP_IPV6
+    /* For symmetry with above, accept IPv6 :: as a general null */
+    if (in->version == NSAPI_UNSPEC ||
+            (in->version == NSAPI_IPv6 && all_zeros(in->bytes, 16))) {
+        ip_addr_set_zero_ip4(out);
+        return true;
+    }
+#endif
+#endif
+
+#if LWIP_IPV4 && LWIP_IPV6
+    if (in->version == NSAPI_UNSPEC) {
+        ip6_addr_set_zero(ip_2_ip6(out));
+        IP_SET_TYPE(out, IPADDR_TYPE_ANY);
+        return true;
+    }
+#endif
+
+    return false;
+}
+
+#if !LWIP_IPV4 || !LWIP_IPV6
+static bool all_zeros(const uint8_t *p, int len)
+{
+    for (int i = 0; i < len; i++) {
+        if (p[i]) {
+            return false;
+        }
+    }
+
+    return true;
+}
+#endif