diff --git a/TESTS/network/interface/README.md b/TESTS/network/interface/README.md index 90e912dfda4..d4496fc36c2 100644 --- a/TESTS/network/interface/README.md +++ b/TESTS/network/interface/README.md @@ -155,10 +155,14 @@ Test `NetworkInterface::get_connection_status()`. 1. Check that `get_connection_status()` returns status `NSAPI_STATUS_DISCONNECTED`. 2. Connect interface. 3. Poll the `get_connection_status()` until it returns status `NSAPI_STATUS_GLOBAL_UP`. -4. Disconnect interface. -5. Check that `get_connection_status()` returns status `NSAPI_STATUS_DISCONNECTED`. -6. Repeat connect and disconnect steps 2 to 5 four times. +4. (IPv6 only) Get IPv6 link local address using `get_ipv6_link_local_address` API. +5. (IPv6 only) Check that `get_ipv6_link_local_address` returned status `NSAPI_ERROR_OK`. +6. (IPv6 only) Check that the IP address associated with the Socket Address is not `NULL`. +7. (IPv6 only) Check that the IP version of the IPv6 link local address is `NSAPI_IPv6`. +8. Disconnect interface. +9. Check that `get_connection_status()` returns status `NSAPI_STATUS_DISCONNECTED`. +10. Repeat connect and disconnect steps 2 to 5 four times. **Expected result:** -`Connect()` and `disconnect()` calls return `NSAPI_ERROR_OK`. The right status is returned by `get_connection_status()`. +`Connect()`, `get_ipv6_link_local_address` and `disconnect()` calls return `NSAPI_ERROR_OK`. The right status is returned by `get_connection_status()`. And the right IPv6 link local address is returned by `get_ipv6_link_local_address`. diff --git a/TESTS/network/interface/networkinterface_status.cpp b/TESTS/network/interface/networkinterface_status.cpp index e59796a31cd..56217c43610 100644 --- a/TESTS/network/interface/networkinterface_status.cpp +++ b/TESTS/network/interface/networkinterface_status.cpp @@ -156,6 +156,15 @@ void NETWORKINTERFACE_STATUS_GET() ThisThread::sleep_for(500); } +#if MBED_CONF_LWIP_IPV6_ENABLED + /* if IPv6 is enabled, validate ipv6_link_local_address API*/ + SocketAddress ipv6_link_local_address = NULL; + err = net->get_ipv6_link_local_address(&ipv6_link_local_address); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err); + TEST_ASSERT_NOT_NULL(ipv6_link_local_address.get_ip_address()); + TEST_ASSERT_EQUAL(NSAPI_IPv6, ipv6_link_local_address.get_ip_version()); +#endif + err = net->disconnect(); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err); diff --git a/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp b/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp index 603b1ef3e4f..94846704a46 100644 --- a/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp +++ b/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp @@ -94,6 +94,7 @@ class EmacNetworkStackMock : public OnboardNetworkStack { MOCK_CONST_METHOD0(get_connection_status, nsapi_connection_status_t()); MOCK_METHOD2(get_mac_address, char *(char *buf, nsapi_size_t buflen)); MOCK_METHOD2(get_ip_address, char *(char *buf, nsapi_size_t buflen)); + MOCK_METHOD1(get_ipv6_link_local_address, nsapi_error_t(SocketAddress *address)); MOCK_METHOD2(get_netmask, char *(char *buf, nsapi_size_t buflen)); MOCK_METHOD2(get_gateway, char *(char *buf, nsapi_size_t buflen)); }; diff --git a/UNITTESTS/stubs/NetworkInterface_stub.cpp b/UNITTESTS/stubs/NetworkInterface_stub.cpp index 50009573bed..9d64871a5c3 100644 --- a/UNITTESTS/stubs/NetworkInterface_stub.cpp +++ b/UNITTESTS/stubs/NetworkInterface_stub.cpp @@ -31,6 +31,11 @@ const char *NetworkInterface::get_ip_address() return 0; } +nsapi_error_t NetworkInterface::get_ipv6_link_local_address(SocketAddress *address) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + const char *NetworkInterface::get_netmask() { return 0; diff --git a/UNITTESTS/stubs/NetworkStack_stub.cpp b/UNITTESTS/stubs/NetworkStack_stub.cpp index 31f3b91533b..45779c3e079 100644 --- a/UNITTESTS/stubs/NetworkStack_stub.cpp +++ b/UNITTESTS/stubs/NetworkStack_stub.cpp @@ -93,6 +93,12 @@ const char *NetworkStack::get_ip_address() { return NULL; } + +nsapi_error_t NetworkStack::get_ipv6_link_local_address(SocketAddress *address) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + const char *NetworkStack::get_ip_address_if(const char *interface_name) { return NULL; diff --git a/features/lwipstack/LWIPInterface.cpp b/features/lwipstack/LWIPInterface.cpp index 619a3623cd8..fb63a762539 100644 --- a/features/lwipstack/LWIPInterface.cpp +++ b/features/lwipstack/LWIPInterface.cpp @@ -37,6 +37,7 @@ #include "lwip/udp.h" #include "LWIPStack.h" +#include "lwip_tools.h" LWIP::Interface *LWIP::Interface::list; @@ -271,6 +272,30 @@ char *LWIP::Interface::get_interface_name(char *buf) return buf; } +nsapi_error_t LWIP::Interface::get_ipv6_link_local_address(SocketAddress *address) +{ +#if LWIP_IPV6 + const ip_addr_t *addr = LWIP::get_ipv6_link_local_addr(&netif); + nsapi_addr_t out; + bool ret; + + if (!addr) { + return NSAPI_ERROR_PARAMETER; + } + + ret = convert_lwip_addr_to_mbed(&out, addr); + if (ret != true) { + return NSAPI_ERROR_PARAMETER; + } + + address->set_addr(out); + + return NSAPI_ERROR_OK; +#else + return NSAPI_ERROR_UNSUPPORTED; +#endif +} + char *LWIP::Interface::get_ip_address(char *buf, nsapi_size_t buflen) { const ip_addr_t *addr = LWIP::get_ip_addr(true, &netif); diff --git a/features/lwipstack/LWIPStack.h b/features/lwipstack/LWIPStack.h index 5e99126c423..a5756645a98 100644 --- a/features/lwipstack/LWIPStack.h +++ b/features/lwipstack/LWIPStack.h @@ -101,6 +101,13 @@ class LWIP : public OnboardNetworkStack, private mbed::NonCopyable { */ virtual char *get_ip_address(char *buf, nsapi_size_t buflen); + /** Get the IPv6 link local address in SocketAddress representation + * + * @address SocketAddress representation of the link local IPv6 address + * @return NSAPI_ERROR_OK on success, or error code + */ + virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address); + /** Copies IP address of the name based network interface to user supplied buffer * * @param buf buffer to which IP address will be copied as "W:X:Y:Z" @@ -571,6 +578,7 @@ class LWIP : public OnboardNetworkStack, private mbed::NonCopyable { static const ip_addr_t *get_ip_addr(bool any_addr, const struct netif *netif); static const ip_addr_t *get_ipv4_addr(const struct netif *netif); static const ip_addr_t *get_ipv6_addr(const struct netif *netif); + static const ip_addr_t *get_ipv6_link_local_addr(const struct netif *netif); static void add_dns_addr(struct netif *lwip_netif, const char *interface_name); diff --git a/features/lwipstack/lwip_tools.cpp b/features/lwipstack/lwip_tools.cpp index 3988b7194bc..6a9ca39db0f 100644 --- a/features/lwipstack/lwip_tools.cpp +++ b/features/lwipstack/lwip_tools.cpp @@ -79,6 +79,23 @@ const ip_addr_t *LWIP::get_ipv4_addr(const struct netif *netif) 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 diff --git a/features/netsocket/EMACInterface.cpp b/features/netsocket/EMACInterface.cpp index e1c16f009a6..15904c8fb48 100644 --- a/features/netsocket/EMACInterface.cpp +++ b/features/netsocket/EMACInterface.cpp @@ -95,6 +95,15 @@ const char *EMACInterface::get_ip_address() return NULL; } +nsapi_error_t EMACInterface::get_ipv6_link_local_address(SocketAddress *address) +{ + if (_interface) { + return _interface->get_ipv6_link_local_address(address); + } + + return NSAPI_ERROR_NO_CONNECTION; +} + const char *EMACInterface::get_netmask() { if (_interface && _interface->get_netmask(_netmask, sizeof(_netmask))) { diff --git a/features/netsocket/EMACInterface.h b/features/netsocket/EMACInterface.h index a2034191ad4..d6f71c81777 100644 --- a/features/netsocket/EMACInterface.h +++ b/features/netsocket/EMACInterface.h @@ -103,6 +103,13 @@ class EMACInterface : public virtual NetworkInterface { */ virtual const char *get_ip_address(); + /** Get the IPv6 link local address + * + * @address SocketAddress representation of the link local IPv6 address + * @return 0 on success, negative error code on failure + */ + virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address); + /** Get the local network mask * * @return Null-terminated representation of the local network mask diff --git a/features/netsocket/NetworkInterface.cpp b/features/netsocket/NetworkInterface.cpp index fc307c458b9..ca838cc77f7 100644 --- a/features/netsocket/NetworkInterface.cpp +++ b/features/netsocket/NetworkInterface.cpp @@ -37,6 +37,11 @@ const char *NetworkInterface::get_ip_address() return 0; } +nsapi_error_t NetworkInterface::get_ipv6_link_local_address(SocketAddress *address) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + const char *NetworkInterface::get_netmask() { return 0; diff --git a/features/netsocket/NetworkInterface.h b/features/netsocket/NetworkInterface.h index 40724a9d745..ef97733d64c 100644 --- a/features/netsocket/NetworkInterface.h +++ b/features/netsocket/NetworkInterface.h @@ -107,6 +107,13 @@ class NetworkInterface: public DNS { */ virtual const char *get_ip_address(); + /** Get the IPv6 link local address + * + * @address SocketAddress representation of the link local IPv6 address + * @return NSAPI_ERROR_OK on success, negative error code on failure + */ + virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address); + /** Get the local network mask. * * @return Null-terminated representation of the local network mask diff --git a/features/netsocket/NetworkStack.cpp b/features/netsocket/NetworkStack.cpp index 16bce4cd93c..1acf4d0c47e 100644 --- a/features/netsocket/NetworkStack.cpp +++ b/features/netsocket/NetworkStack.cpp @@ -29,6 +29,11 @@ const char *NetworkStack::get_ip_address() return 0; } +nsapi_error_t NetworkStack::get_ipv6_link_local_address(SocketAddress *address) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + const char *NetworkStack::get_ip_address_if(const char *interface_name) { return 0; diff --git a/features/netsocket/NetworkStack.h b/features/netsocket/NetworkStack.h index a9cc6e5bc4a..e7cd244ec34 100644 --- a/features/netsocket/NetworkStack.h +++ b/features/netsocket/NetworkStack.h @@ -48,6 +48,13 @@ class NetworkStack: public DNS { */ virtual const char *get_ip_address(); + /** Get the IPv6 link local address + * + * @address SocketAddress representation of the link local IPv6 address + * @return NSAPI_ERROR_OK on success, negative error code on failure + */ + virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address); + /** Get the local IP address on interface name * * @param interface_name Network interface_name diff --git a/features/netsocket/OnboardNetworkStack.h b/features/netsocket/OnboardNetworkStack.h index f68a6518dee..0a0c8430e5c 100644 --- a/features/netsocket/OnboardNetworkStack.h +++ b/features/netsocket/OnboardNetworkStack.h @@ -119,6 +119,16 @@ class OnboardNetworkStack : public NetworkStack { virtual char *get_ip_address(char *buf, nsapi_size_t buflen) = 0; + /** Copies IPv6 link local address of the network interface in SocketAddress format + * + * @address SocketAddress representation of the link local IPv6 address + * @return NSAPI_ERROR_OK on success, negative error code on failure + */ + virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address) + { + return NSAPI_ERROR_UNSUPPORTED; + } + /** Copies IP address of the network interface to user supplied buffer * * @param buf buffer to which IP address will be copied as "W:X:Y:Z" diff --git a/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.ar b/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.ar index ee3cbdc4e82..bd407e793aa 100644 Binary files a/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.ar and b/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.ar differ diff --git a/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.ar b/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.ar index 094cc8f191b..6c7966bca6a 100644 Binary files a/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.ar and b/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.ar differ diff --git a/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.ar b/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.ar index aca5f21f2fd..27656161cde 100644 Binary files a/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.ar and b/targets/TARGET_WICED/TOOLCHAIN_ARMC6/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.ar differ diff --git a/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.a b/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.a index 9a3e98356f3..b669475d1af 100644 Binary files a/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.a and b/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.a differ diff --git a/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.a b/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.a index 129a83df29f..0824444382b 100644 Binary files a/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.a and b/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.a differ diff --git a/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.a b/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.a index a629fb1c668..2152d5aaaf7 100644 Binary files a/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.a and b/targets/TARGET_WICED/TOOLCHAIN_GCC_ARM/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.a differ diff --git a/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.a b/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.a index 2d5dd483090..ad4ba05e33a 100644 Binary files a/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.a and b/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_ADV_WISE_1530/libwiced_drivers.a differ diff --git a/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.a b/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.a index c9b2a4c2b5d..c7ccb22bc89 100644 Binary files a/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.a and b/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_MXCHIP_EMW3166/libwiced_drivers.a differ diff --git a/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.a b/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.a index 8af9900cf37..fed1f7c72a4 100644 Binary files a/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.a and b/targets/TARGET_WICED/TOOLCHAIN_IAR/TARGET_MTB_USI_WM_BN_BM_22/libwiced_drivers.a differ