Netsocket: Implement set_ip_address to enable setting second address

set_ip_address API can be used to set a static IPv4 address or IPv6 link-local
address to network stack.

This is needed for example in cellular use cases where device gets multiple IP
addresses from cellular context.
pull/12606/head
Kimmo Vaisanen 2020-03-10 10:28:39 +02:00
parent 64bc9d9dd7
commit 09fe16618a
3 changed files with 112 additions and 15 deletions

View File

@ -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

View File

@ -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<LWIP> {
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

View File

@ -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