Skip to content

nsapi - Add optional API for static configuration of network interfaces #2664

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,57 @@


/* Interface implementation */
EthernetInterface::EthernetInterface()
: _dhcp(false), _ip_address(), _netmask(), _gateway()
{
}

int EthernetInterface::set_network(const char *ip_address, const char *netmask, const char *gateway)
{
_dhcp = false;
strncpy(_ip_address, ip_address ? ip_address : "", sizeof(_ip_address));
strncpy(_netmask, netmask ? netmask : "", sizeof(_netmask));
strncpy(_gateway, gateway ? gateway : "", sizeof(_gateway));
return 0;
}

int EthernetInterface::set_dhcp(bool dhcp)
{
_dhcp = dhcp;
return 0;
}

int EthernetInterface::connect()
{
return lwip_bringup();
return lwip_bringup(_dhcp,
_ip_address[0] ? _ip_address : 0,
_netmask[0] ? _netmask : 0,
_gateway[0] ? _gateway : 0);
}

int EthernetInterface::disconnect()
{
return lwip_bringdown();
}

const char *EthernetInterface::get_mac_address()
{
return lwip_get_mac_address();
}

const char *EthernetInterface::get_ip_address()
{
return lwip_get_ip_address();
}

const char *EthernetInterface::get_mac_address()
const char *EthernetInterface::get_netmask()
{
return lwip_get_mac_address();
return lwip_get_netmask();
}

const char *EthernetInterface::get_gateway()
{
return lwip_get_gateway();
}

NetworkStack *EthernetInterface::get_stack()
Expand Down
63 changes: 58 additions & 5 deletions features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,32 @@ class NetworkStack;
class EthernetInterface : public EthInterface
{
public:
/** EthernetInterface lifetime
*/
EthernetInterface();

/** Set a static IP address
*
* Configures this network interface to use a static IP address.
* Implicitly disables DHCP, which can be enabled in set_dhcp.
* Requires that the network is disconnected.
*
* @param address Null-terminated representation of the local IP address
* @param netmask Null-terminated representation of the local network mask
* @param gateway Null-terminated representation of the local gateway
* @return 0 on success, negative error code on failure
*/
virtual int set_network(const char *ip_address, const char *netmask, const char *gateway);

/** Enable or disable DHCP on the network
*
* Requires that the network is disconnected
*
* @param dhcp False to disable dhcp (defaults to enabled)
* @return 0 on success, negative error code on failure
*/
virtual int set_dhcp(bool dhcp);

/** Start the interface
* @return 0 on success, negative on failure
*/
Expand All @@ -41,22 +67,49 @@ class EthernetInterface : public EthInterface
*/
virtual int disconnect();

/** Get the internally stored IP address
* @return IP address of the interface or null if not yet connected
/** Get the local MAC address
*
* Provided MAC address is intended for info or debug purposes and
* may not be provided if the underlying network interface does not
* provide a MAC address
*
* @return Null-terminated representation of the local MAC address
* or null if no MAC address is available
*/
virtual const char *get_mac_address();

/** Get the local IP address
*
* @return Null-terminated representation of the local IP address
* or null if no IP address has been recieved
*/
virtual const char *get_ip_address();

/** Get the internally stored MAC address
* @return MAC address of the interface
/** Get the local network mask
*
* @return Null-terminated representation of the local network mask
* or null if no network mask has been recieved
*/
virtual const char *get_netmask();

/** Get the local gateway
*
* @return Null-terminated representation of the local gateway
* or null if no network mask has been recieved
*/
virtual const char *get_mac_address();
virtual const char *get_gateway();

protected:
/** Provide access to the underlying stack
*
* @return The underlying network stack
*/
virtual NetworkStack *get_stack();

bool _dhcp;
char _ip_address[NSAPI_IPv4_SIZE];
char _netmask[NSAPI_IPv4_SIZE];
char _gateway[NSAPI_IPv4_SIZE];
};


Expand Down
82 changes: 56 additions & 26 deletions features/net/FEATURE_IPV4/lwip-interface/lwip_stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,11 @@ static void lwip_socket_callback(struct netconn *nc, enum netconn_evt eh, u16_t

/* TCP/IP and Network Interface Initialisation */
static struct netif lwip_netif;

static char lwip_ip_addr[NSAPI_IP_SIZE] = "\0";
static char lwip_mac_addr[NSAPI_MAC_SIZE] = "\0";
static bool lwip_dhcp = false;
static char lwip_mac_address[NSAPI_MAC_SIZE] = "\0";
static char lwip_ip_address[NSAPI_IPv4_SIZE] = "\0";
static char lwip_netmask[NSAPI_IPv4_SIZE] = "\0";
static char lwip_gateway[NSAPI_IPv4_SIZE] = "\0";

static sys_sem_t lwip_tcpip_inited;
static void lwip_tcpip_init_irq(void *eh)
Expand All @@ -111,21 +113,23 @@ static sys_sem_t lwip_netif_up;
static void lwip_netif_status_irq(struct netif *lwip_netif)
{
if (netif_is_up(lwip_netif)) {
strcpy(lwip_ip_addr, inet_ntoa(lwip_netif->ip_addr));
strcpy(lwip_ip_address, inet_ntoa(lwip_netif->ip_addr));
strcpy(lwip_netmask, inet_ntoa(lwip_netif->netmask));
strcpy(lwip_gateway, inet_ntoa(lwip_netif->gw));
sys_sem_signal(&lwip_netif_up);
}
}

static void lwip_set_mac_address(void)
{
#if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
snprintf(lwip_mac_addr, 19, "%02x:%02x:%02x:%02x:%02x:%02x",
snprintf(lwip_mac_address, 19, "%02x:%02x:%02x:%02x:%02x:%02x",
MBED_MAC_ADDR_0, MBED_MAC_ADDR_1, MBED_MAC_ADDR_2,
MBED_MAC_ADDR_3, MBED_MAC_ADDR_4, MBED_MAC_ADDR_5);
#else
char mac[6];
mbed_mac_address(mac);
snprintf(lwip_mac_addr, 19, "%02x:%02x:%02x:%02x:%02x:%02x",
snprintf(lwip_mac_address, 19, "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
#endif
}
Expand All @@ -134,15 +138,26 @@ static void lwip_set_mac_address(void)
/* LWIP interface implementation */
const char *lwip_get_mac_address(void)
{
return lwip_mac_addr[0] ? lwip_mac_addr : 0;
return lwip_mac_address[0] ? lwip_mac_address : 0;
}

const char *lwip_get_ip_address(void)
{
return lwip_ip_addr[0] ? lwip_ip_addr : 0;
return lwip_ip_address[0] ? lwip_ip_address : 0;
}

const char *lwip_get_netmask(void)
{
return lwip_netmask[0] ? lwip_netmask : 0;
}

int lwip_bringup(void)
const char *lwip_get_gateway(void)
{
return lwip_gateway[0] ? lwip_gateway : 0;
}


int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw)
{
// Check if we've already connected
if (lwip_get_ip_address()) {
Expand All @@ -162,6 +177,7 @@ int lwip_bringup(void)
sys_arch_sem_wait(&lwip_tcpip_inited, 0);

memset(&lwip_netif, 0, sizeof lwip_netif);

netif_add(&lwip_netif, 0, 0, 0, NULL, eth_arch_enetif_init, tcpip_input);
netif_set_default(&lwip_netif);

Expand All @@ -175,7 +191,26 @@ int lwip_bringup(void)
lwip_arena_init();

// Connect to the network
dhcp_start(&lwip_netif);
lwip_dhcp = dhcp;
if (lwip_dhcp) {
err_t err = dhcp_start(&lwip_netif);
if (err) {
return NSAPI_ERROR_DHCP_FAILURE;
}
} else {
ip_addr_t ip_addr;
ip_addr_t netmask_addr;
ip_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(&lwip_netif, &ip_addr, &netmask_addr, &gw_addr);
netif_set_up(&lwip_netif);
}

// Wait for an IP Address
u32_t ret = sys_arch_sem_wait(&lwip_netif_up, 15000);
Expand All @@ -194,9 +229,17 @@ int lwip_bringdown(void)
}

// Disconnect from the network
dhcp_release(&lwip_netif);
dhcp_stop(&lwip_netif);
lwip_ip_addr[0] = '\0';
if (lwip_dhcp) {
dhcp_release(&lwip_netif);
dhcp_stop(&lwip_netif);
lwip_dhcp = false;

lwip_ip_address[0] = '\0';
lwip_netmask[0] = '\0';
lwip_gateway[0] = '\0';
} else {
netif_set_down(&lwip_netif);
}

return 0;
}
Expand Down Expand Up @@ -230,18 +273,6 @@ static int lwip_err_remap(err_t err) {


/* LWIP network stack implementation */
static nsapi_addr_t lwip_getaddr(nsapi_stack_t *stack)
{
if (!lwip_get_ip_address()) {
return (nsapi_addr_t){0};
}

nsapi_addr_t addr;
addr.version = NSAPI_IPv4;
inet_aton(lwip_get_ip_address(), (ip_addr_t *)addr.bytes);
return addr;
}

static int lwip_gethostbyname(nsapi_stack_t *stack, nsapi_addr_t *addr, const char *host)
{
err_t err = netconn_gethostbyname(host, (ip_addr_t *)addr->bytes);
Expand Down Expand Up @@ -487,7 +518,6 @@ static void lwip_socket_attach(nsapi_stack_t *stack, nsapi_socket_t handle, void

/* LWIP network stack */
const nsapi_stack_api_t lwip_stack_api = {
.get_ip_address = lwip_getaddr,
.gethostbyname = lwip_gethostbyname,
.socket_open = lwip_socket_open,
.socket_close = lwip_socket_close,
Expand Down
8 changes: 5 additions & 3 deletions features/net/FEATURE_IPV4/lwip-interface/lwip_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ extern "C" {


// Access to lwip through the nsapi
int lwip_bringup(void);
int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw);
int lwip_bringdown(void);

extern nsapi_stack_t lwip_stack;

const char *lwip_get_mac_address(void);
const char *lwip_get_ip_address(void);
const char *lwip_get_netmask(void);
const char *lwip_get_gateway(void);

extern nsapi_stack_t lwip_stack;


#ifdef __cplusplus
Expand Down
Loading