diff --git a/features/lwipstack/LWIPInterface.cpp b/features/lwipstack/LWIPInterface.cpp index 7dc25083ea..696963d5ce 100644 --- a/features/lwipstack/LWIPInterface.cpp +++ b/features/lwipstack/LWIPInterface.cpp @@ -680,23 +680,13 @@ nsapi_error_t LWIP::Interface::bringup(bool dhcp, const char *ip, const char *ne } #endif /* LWIP_IPV6 */ -#if LWIP_IPV4 - if (stack != IPV6_STACK) { - if (!dhcp && !ppp_enabled) { - ip4_addr_t ip_addr; - ip4_addr_t netmask_addr; - ip4_addr_t gw_addr; - - if (!inet_aton(ip, &ip_addr) || - !inet_aton(netmask, &netmask_addr) || - !inet_aton(gw, &gw_addr)) { - return NSAPI_ERROR_PARAMETER; - } - - netif_set_addr(&netif, &ip_addr, &netmask_addr, &gw_addr); + nsapi_error_t ret_add_ip = NSAPI_ERROR_OK; + if (!dhcp && !ppp_enabled) { + ret_add_ip = set_ip_address(ip, netmask, gw); + if (ret_add_ip != NSAPI_ERROR_OK) { + return ret_add_ip; } } -#endif if (client_callback) { client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING); @@ -753,6 +743,58 @@ nsapi_error_t LWIP::Interface::bringup(bool dhcp, const char *ip, const char *ne return NSAPI_ERROR_OK; } +nsapi_error_t LWIP::Interface::set_ip_address(const char *ip, + const char *netmask, + const char *gw, + uint8_t ipv6_flag) +{ + if (!ip) { + return NSAPI_ERROR_PARAMETER; + } + + int conv_ip = 1; + +#if LWIP_IPV4 + ip4_addr_t ip_addr; + ip4_addr_t netmask_addr; + ip4_addr_t gw_addr; + IP4_ADDR(&netmask_addr, 255, 255, 255, 255); + ip4_addr_set_zero(&gw_addr); + int conv_netmask = 1; + int conv_gw = 1; + + conv_ip = inet_aton(ip, &ip_addr); + if (netmask) { + conv_netmask = inet_aton(netmask, &netmask_addr); + } + if (gw) { + conv_gw = inet_aton(gw, &gw_addr); + } + if (conv_ip && conv_netmask && conv_gw) { + netif_set_addr(&netif, &ip_addr, &netmask_addr, &gw_addr); + return NSAPI_ERROR_OK; + } +#endif /* LWIP_IPV4 */ + +#if LWIP_IPV6 + ip6_addr_t ip_addr6; + + conv_ip = inet6_aton(ip, &ip_addr6); + if (conv_ip) { + s8_t chosen_idx; + err_t ret = netif_add_ip6_address(&netif, &ip_addr6, &chosen_idx); + // If failed here, consider increasing LWIP_IPV6_NUM_ADDRESSES. + MBED_ASSERT(chosen_idx >= 0); + if (!ret) { + netif_ip6_addr_set_state(&netif, chosen_idx, ipv6_flag); + return NSAPI_ERROR_OK; + } + } +#endif /* LWIP_IPV6 */ + + return NSAPI_ERROR_PARAMETER; +} + nsapi_error_t LWIP::Interface::bringdown() { // Check if we've connected diff --git a/features/lwipstack/LWIPStack.h b/features/lwipstack/LWIPStack.h index b418aeba41..a67a86393d 100644 --- a/features/lwipstack/LWIPStack.h +++ b/features/lwipstack/LWIPStack.h @@ -30,6 +30,12 @@ #include "netsocket/OnboardNetworkStack.h" #include "LWIPMemoryManager.h" +#if LWIP_IPV6 +#include "lwip/ip6_addr.h" +#define IP_ADDR_VALID IP6_ADDR_VALID +#else +#define IP_ADDR_VALID 0 +#endif class LWIP : public OnboardNetworkStack, private mbed::NonCopyable { public: @@ -38,6 +44,33 @@ public: class Interface final : public OnboardNetworkStack::Interface { public: + /** Set IP address to LWIP stack + * + * This function can set both IPv4 or IPv6 address to LWIP stack. + * + * bringup() can only take one IP address and in dual stack case + * another IP address can be set using this function. + * + * IPv4 or IPv6 address should be in format of https://tools.ietf.org/html/draft-main-ipaddr-text-rep-00. + * + * @param ip IP address to be used for the interface as IPv4 or IPv6 address string. + * This parameter should not be NULL. + * @param netmask Net mask to be used for the interface as IPv4 address string or NULL. + * NULL value will set this value to 255.255.255.255. + * This parameter will be ignored for IPv6 ip argument. + * @param gw Gateway address to be used for the interface as IPv4 address string or NULL + * NULL value will set this value to 0.0.0.0 + * This parameter will be ignored for IPv6 ip argument. + * @param ipv6_flag Provide this flag for IPv6 state flag override. For example, you can set IP6_ADDR_PREFERRED. + * Default value is IP6_ADDR_VALID. For IPv4, this value will be ignored. + * @return NSAPI_ERROR_OK on success, or error code + */ + nsapi_error_t set_ip_address(const char *ip, + const char *netmask, + const char *gw, + uint8_t ipv6_flag = IP_ADDR_VALID + ) override; + /** Connect the interface to the network * * Sets up a connection on specified network interface, using DHCP or provided network details. If the @a dhcp is set to diff --git a/features/netsocket/OnboardNetworkStack.h b/features/netsocket/OnboardNetworkStack.h index 68d1856468..71245b2d8d 100644 --- a/features/netsocket/OnboardNetworkStack.h +++ b/features/netsocket/OnboardNetworkStack.h @@ -51,6 +51,28 @@ public: ~Interface() = default; public: + /** Set IP address + * + * bringup() can only take one IP address and in dual stack case + * another IP address can be set using this function. + * + * Must be called before bringup(). + * + * @param ip IP address to be used for the interface as "W:X:Y:Z" or NULL + * @param netmask Net mask to be used for the interface as "W:X:Y:Z" or NULL + * @param gw Gateway address to be used for the interface as "W:X:Y:Z" or NULL + * @param ipv6_flag Provide this flag for IPv6 state flag override. For example, you can set IP6_ADDR_PREFERRED. + * For IPv4, this value will be ignored. + * @return NSAPI_ERROR_OK on success, or error code + */ + virtual nsapi_error_t set_ip_address(const char *ip, + const char *netmask, + const char *gw, + uint8_t ipv6_flag) + { + return NSAPI_ERROR_UNSUPPORTED; + } + /** Connect the interface to the network * * Sets up a connection on specified network interface, using DHCP or provided network details. If the @a dhcp is set to