Unify LWIP Ethernet and PPP initialisation

pull/4119/head
Kevin Bracey 2017-02-17 12:41:24 +02:00 committed by Hasnain Virk
parent 2abb078f27
commit 7e3c529d21
6 changed files with 171 additions and 101 deletions

View File

@ -46,7 +46,7 @@ nsapi_error_t EthernetInterface::set_dhcp(bool dhcp)
nsapi_error_t EthernetInterface::connect() nsapi_error_t EthernetInterface::connect()
{ {
return mbed_lwip_bringup(_dhcp, return mbed_lwip_bringup(_dhcp, false,
_ip_address[0] ? _ip_address : 0, _ip_address[0] ? _ip_address : 0,
_netmask[0] ? _netmask : 0, _netmask[0] ? _netmask : 0,
_gateway[0] ? _gateway : 0); _gateway[0] ? _gateway : 0);

View File

@ -33,10 +33,12 @@
#include "lwip/mld6.h" #include "lwip/mld6.h"
#include "lwip/dns.h" #include "lwip/dns.h"
#include "lwip/udp.h" #include "lwip/udp.h"
#include "emac_api.h" #include "emac_api.h"
#include "ppp_lwip.h"
#include "lwip_tcp_isn.h" #include "lwip_tcp_isn.h"
static nsapi_error_t mbed_lwip_err_remap(err_t err);
#if DEVICE_EMAC #if DEVICE_EMAC
#define MBED_NETIF_INIT_FN emac_lwip_if_init #define MBED_NETIF_INIT_FN emac_lwip_if_init
#else #else
@ -58,7 +60,9 @@ static struct lwip_socket {
} lwip_arena[MEMP_NUM_NETCONN]; } lwip_arena[MEMP_NUM_NETCONN];
static bool lwip_inited = false; static bool lwip_inited = false;
static bool lwip_connected = true; static bool lwip_connected = false;
static bool netif_inited = false;
static bool netif_is_ppp = false;
static struct lwip_socket *mbed_lwip_arena_alloc(void) static struct lwip_socket *mbed_lwip_arena_alloc(void)
{ {
@ -323,32 +327,43 @@ static void mbed_lwip_netif_status_irq(struct netif *lwip_netif)
} }
} }
static void mbed_lwip_set_mac_address(void) #if LWIP_ETHERNET
static void mbed_lwip_set_mac_address(struct netif *netif)
{ {
#if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE) #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
(void) snprintf(lwip_mac_address, NSAPI_MAC_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x", netif->hwaddr[0] = MBED_MAC_ADDR_0;
MBED_MAC_ADDR_0, MBED_MAC_ADDR_1, MBED_MAC_ADDR_2, netif->hwaddr[1] = MBED_MAC_ADDR_1;
MBED_MAC_ADDR_3, MBED_MAC_ADDR_4, MBED_MAC_ADDR_5); netif->hwaddr[2] = MBED_MAC_ADDR_2;
netif->hwaddr[3] = MBED_MAC_ADDR_3;
netif->hwaddr[4] = MBED_MAC_ADDR_4;
netif->hwaddr[5] = MBED_MAC_ADDR_5;
#else #else
char mac[6]; mbed_mac_address((char *)netif->hwaddr);
mbed_mac_address(mac);
(void) snprintf(lwip_mac_address, NSAPI_MAC_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
#endif #endif
netif->hwaddr_len = ETH_HWADDR_LEN;
/* Use mac address as additional seed to random number generator */ /* Use mac address as additional seed to random number generator */
uint64_t seed = mac[0]; uint64_t seed = netif->hwaddr[0];
for (uint8_t i = 1; i < 8; i++) { for (uint8_t i = 1; i < 8; i++) {
seed <<= 8; seed <<= 8;
seed |= mac[i % 6]; seed |= netif->hwaddr[i % 6];
} }
lwip_add_random_seed(seed); lwip_add_random_seed(seed);
} }
static void mbed_lwip_record_mac_address(const struct netif *netif)
{
const u8_t *mac = netif->hwaddr;
snprintf(lwip_mac_address, NSAPI_MAC_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
#endif // LWIP_ETHERNET
/* LWIP interface implementation */ /* LWIP interface implementation */
const char *mbed_lwip_get_mac_address(void) const char *mbed_lwip_get_mac_address(void)
{ {
return lwip_mac_address[0] ? lwip_mac_address : 0; return lwip_mac_address[0] ? lwip_mac_address : NULL;
} }
char *mbed_lwip_get_ip_address(char *buf, nsapi_size_t buflen) char *mbed_lwip_get_ip_address(char *buf, nsapi_size_t buflen)
@ -400,7 +415,7 @@ char *mbed_lwip_get_gateway(char *buf, nsapi_size_t buflen)
#endif #endif
} }
void mbed_lwip_init() static void mbed_lwip_core_init(void)
{ {
// Check if we've already brought up lwip // Check if we've already brought up lwip
@ -416,6 +431,8 @@ void mbed_lwip_init()
lwip_init_tcp_isn(0, (u8_t *) &tcp_isn_secret); lwip_init_tcp_isn(0, (u8_t *) &tcp_isn_secret);
sys_sem_new(&lwip_tcpip_inited, 0); sys_sem_new(&lwip_tcpip_inited, 0);
sys_sem_new(&lwip_netif_linked, 0);
sys_sem_new(&lwip_netif_has_addr, 0);
tcpip_init(mbed_lwip_tcpip_init_irq, NULL); tcpip_init(mbed_lwip_tcpip_init_irq, NULL);
sys_arch_sem_wait(&lwip_tcpip_inited, 0); sys_arch_sem_wait(&lwip_tcpip_inited, 0);
@ -426,13 +443,11 @@ void mbed_lwip_init()
nsapi_error_t mbed_lwip_emac_init(emac_interface_t *emac) nsapi_error_t mbed_lwip_emac_init(emac_interface_t *emac)
{ {
// Check if we've already set up netif #if LWIP_ETHERNET
if (!mbed_lwip_get_mac_address()) { // Choose a MAC address - driver can override
// Set up network mbed_lwip_set_mac_address(&lwip_netif);
sys_sem_new(&lwip_netif_linked, 0);
sys_sem_new(&lwip_netif_has_addr, 0);
memset(&lwip_netif, 0, sizeof lwip_netif); // Set up network
if (!netif_add(&lwip_netif, if (!netif_add(&lwip_netif,
#if LWIP_IPV4 #if LWIP_IPV4
0, 0, 0, 0, 0, 0,
@ -441,35 +456,67 @@ nsapi_error_t mbed_lwip_emac_init(emac_interface_t *emac)
return NSAPI_ERROR_DEVICE_ERROR; return NSAPI_ERROR_DEVICE_ERROR;
} }
mbed_lwip_set_mac_address(); // Note the MAC address actually in use
netif_set_default(&lwip_netif); mbed_lwip_record_mac_address(&lwip_netif);
netif_set_link_callback(&lwip_netif, mbed_lwip_netif_link_irq);
netif_set_status_callback(&lwip_netif, mbed_lwip_netif_status_irq);
#if !DEVICE_EMAC #if !DEVICE_EMAC
eth_arch_enable_interrupts(); eth_arch_enable_interrupts();
#endif #endif
}
return NSAPI_ERROR_OK; return NSAPI_ERROR_OK;
#else
return NSAPI_ERROR_UNSUPPORTED;
#endif //LWIP_ETHERNET
} }
nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw) // Backwards compatibility with people using DEVICE_EMAC
nsapi_error_t mbed_lwip_init(emac_interface_t *emac)
{
mbed_lwip_core_init();
return mbed_lwip_emac_init(emac);
}
nsapi_error_t mbed_lwip_bringup(bool dhcp, bool ppp, const char *ip, const char *netmask, const char *gw)
{ {
// Check if we've already connected // Check if we've already connected
if (lwip_connected) { if (lwip_connected) {
return NSAPI_ERROR_PARAMETER; return NSAPI_ERROR_PARAMETER;
} }
mbed_lwip_init(); mbed_lwip_core_init();
if (mbed_lwip_emac_init(NULL) != NSAPI_ERROR_OK) { nsapi_error_t ret;
return NSAPI_ERROR_DEVICE_ERROR; if (netif_inited) {
/* Can't cope with changing mode */
if (netif_is_ppp == ppp) {
ret = NSAPI_ERROR_OK;
} else {
ret = NSAPI_ERROR_PARAMETER;
}
} else {
if (ppp) {
ret = ppp_lwip_if_init(&lwip_netif);
} else {
ret = mbed_lwip_emac_init(NULL);
}
} }
if (ret != NSAPI_ERROR_OK) {
return ret;
}
netif_inited = true;
netif_is_ppp = ppp;
netif_set_default(&lwip_netif);
netif_set_link_callback(&lwip_netif, mbed_lwip_netif_link_irq);
netif_set_status_callback(&lwip_netif, mbed_lwip_netif_status_irq);
#if LWIP_IPV6 #if LWIP_IPV6
if (lwip_netif.hwaddr_len == ETH_HWADDR_LEN) {
netif_create_ip6_linklocal_address(&lwip_netif, 1/*from MAC*/); netif_create_ip6_linklocal_address(&lwip_netif, 1/*from MAC*/);
}
#if LWIP_IPV6_MLD #if LWIP_IPV6_MLD
/* /*
* For hardware/netifs that implement MAC filtering. * For hardware/netifs that implement MAC filtering.
@ -487,21 +534,10 @@ nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask,
/* IPv6 address autoconfiguration not enabled by default */ /* IPv6 address autoconfiguration not enabled by default */
lwip_netif.ip6_autoconfig_enabled = 1; lwip_netif.ip6_autoconfig_enabled = 1;
#endif /* LWIP_IPV6_AUTOCONFIG */ #endif /* LWIP_IPV6_AUTOCONFIG */
#endif // LWIP_IPV6
#endif
u32_t ret;
if (!netif_is_link_up(&lwip_netif)) {
ret = sys_arch_sem_wait(&lwip_netif_linked, 15000);
if (ret == SYS_ARCH_TIMEOUT) {
return NSAPI_ERROR_NO_CONNECTION;
}
}
#if LWIP_IPV4 #if LWIP_IPV4
if (!dhcp) { if (!dhcp && !ppp) {
ip4_addr_t ip_addr; ip4_addr_t ip_addr;
ip4_addr_t netmask_addr; ip4_addr_t netmask_addr;
ip4_addr_t gw_addr; ip4_addr_t gw_addr;
@ -516,7 +552,22 @@ nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask,
} }
#endif #endif
if (ppp) {
err_t err = ppp_lwip_connect();
if (err) {
return mbed_lwip_err_remap(err);
}
}
if (!netif_is_link_up(&lwip_netif)) {
if (sys_arch_sem_wait(&lwip_netif_linked, 15000) == SYS_ARCH_TIMEOUT) {
return NSAPI_ERROR_NO_CONNECTION;
}
}
if (!ppp) {
netif_set_up(&lwip_netif); netif_set_up(&lwip_netif);
}
#if LWIP_DHCP #if LWIP_DHCP
// Connect to the network // Connect to the network
@ -532,8 +583,7 @@ nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask,
// If doesn't have address // If doesn't have address
if (!mbed_lwip_get_ip_addr(true, &lwip_netif)) { if (!mbed_lwip_get_ip_addr(true, &lwip_netif)) {
ret = sys_arch_sem_wait(&lwip_netif_has_addr, 15000); if (sys_arch_sem_wait(&lwip_netif_has_addr, 15000) == SYS_ARCH_TIMEOUT) {
if (ret == SYS_ARCH_TIMEOUT) {
return NSAPI_ERROR_DHCP_FAILURE; return NSAPI_ERROR_DHCP_FAILURE;
} }
} }
@ -542,7 +592,7 @@ nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask,
// If address is not for preferred stack waits a while to see // If address is not for preferred stack waits a while to see
// if preferred stack address is acquired // if preferred stack address is acquired
if (!mbed_lwip_get_ip_addr(false, &lwip_netif)) { if (!mbed_lwip_get_ip_addr(false, &lwip_netif)) {
ret = sys_arch_sem_wait(&lwip_netif_has_addr, ADDR_TIMEOUT * 1000); sys_arch_sem_wait(&lwip_netif_has_addr, ADDR_TIMEOUT * 1000);
} }
#endif #endif

View File

@ -19,15 +19,15 @@
#include "nsapi.h" #include "nsapi.h"
#include "emac_api.h" #include "emac_api.h"
#include "lwip/opt.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
// Access to lwip through the nsapi // Access to lwip through the nsapi
void mbed_lwip_init(); nsapi_error_t mbed_lwip_init(emac_interface_t *emac);
nsapi_error_t mbed_lwip_emac_init(emac_interface_t *emac); nsapi_error_t mbed_lwip_emac_init(emac_interface_t *emac);
nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw); nsapi_error_t mbed_lwip_bringup(bool dhcp, bool ppp, const char *ip, const char *netmask, const char *gw);
nsapi_error_t mbed_lwip_bringdown(void); nsapi_error_t mbed_lwip_bringdown(void);
const char *mbed_lwip_get_mac_address(void); const char *mbed_lwip_get_mac_address(void);
@ -37,7 +37,6 @@ char *mbed_lwip_get_gateway(char *buf, int buflen);
extern nsapi_stack_t lwip_stack; extern nsapi_stack_t lwip_stack;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -36,10 +36,10 @@ extern "C" { // "pppos.h" is missing extern C
#include "netif/ppp/pppapi.h" #include "netif/ppp/pppapi.h"
} }
#include "nsapi_ppp.h"
#include "ppp_lwip.h"
#include "lwip_stack.h" #include "lwip_stack.h"
static void (*notify_ppp_link_status_cb)(int) = 0;
namespace mbed { namespace mbed {
using rtos::Thread; using rtos::Thread;
@ -52,6 +52,7 @@ static Thread *event_thread;
static volatile bool event_queued; static volatile bool event_queued;
// Just one interface for now // Just one interface for now
static FileHandle *my_stream;
static ppp_pcb *my_ppp_pcb; static ppp_pcb *my_ppp_pcb;
static EventQueue *prepare_event_queue() static EventQueue *prepare_event_queue()
@ -189,8 +190,6 @@ static void ppp_link_status(ppp_pcb *pcb, int err_code, void *ctx)
} }
} }
notify_ppp_link_status_cb(err_code);
#if 0 #if 0
/* /*
* This should be in the switch case, this is put outside of the switch * This should be in the switch case, this is put outside of the switch
@ -279,50 +278,43 @@ static void stream_cb(FileHandle *stream) {
} }
} }
err_t ppp_lwip_if_init(struct netif *netif, FileHandle *stream) extern "C" err_t ppp_lwip_connect()
{
return ppp_connect(my_ppp_pcb, 0);
}
extern "C" nsapi_error_t ppp_lwip_if_init(struct netif *netif)
{ {
if (!prepare_event_queue()) { if (!prepare_event_queue()) {
return ERR_MEM; return NSAPI_ERROR_NO_MEMORY;
} }
if (!my_ppp_pcb) { if (!my_ppp_pcb) {
my_ppp_pcb = pppos_create(netif, my_ppp_pcb = pppos_create(netif,
ppp_output, ppp_link_status, stream); ppp_output, ppp_link_status, my_stream);
} }
if (!my_ppp_pcb) { if (!my_ppp_pcb) {
return ERR_IF; return NSAPI_ERROR_DEVICE_ERROR;
} }
#if LWIP_IPV6_AUTOCONFIG
/* IPv6 address autoconfiguration not enabled by default */
netif->ip6_autoconfig_enabled = 1;
#endif /* LWIP_IPV6_AUTOCONFIG */
#if LWIP_IPV4 #if LWIP_IPV4
ppp_set_usepeerdns(my_ppp_pcb, true); ppp_set_usepeerdns(my_ppp_pcb, true);
#endif #endif
ppp_set_default(my_ppp_pcb); my_stream->sigio(callback(stream_cb, my_stream));
my_stream->set_blocking(false);
stream->sigio(callback(stream_cb, stream));
stream->set_blocking(false);
return ppp_connect(my_ppp_pcb, 0);
}
static struct netif my_ppp_netif;
nsapi_error_t mbed_ppp_init(FileHandle *stream, void (*link_status)(int))
{
notify_ppp_link_status_cb = link_status;
mbed_lwip_init();
ppp_lwip_if_init(&my_ppp_netif, stream);
return NSAPI_ERROR_OK; return NSAPI_ERROR_OK;
} }
NetworkStack *mbed_ppp_get_stack() nsapi_error_t nsapi_ppp_init(FileHandle *stream)
{
my_stream = stream;
return mbed_lwip_bringup(false, true, NULL, NULL, NULL);
}
NetworkStack *nsapi_ppp_get_stack()
{ {
return nsapi_create_stack(&lwip_stack); return nsapi_create_stack(&lwip_stack);
} }

View File

@ -1,18 +1,16 @@
/* /*
* Copyright (c) 2017 ARM Limited. All rights reserved. * Copyright (c) 2017 ARM Limited. All rights reserved.
*/ */
#ifndef PPP_LWIP_H_ #ifndef PPP_LWIP_H_
#define PPP_LWIP_H_ #define PPP_LWIP_H_
#include "FileHandle.h" #ifdef __cplusplus
#include "NetworkStack.h" extern "C" {
#endif
namespace mbed { nsapi_error_t ppp_lwip_if_init(struct netif *netif);
err_t ppp_lwip_connect(void);
NetworkStack *mbed_ppp_get_stack(); #ifdef __cplusplus
nsapi_error_t mbed_ppp_init(FileHandle *stream, void (*link_status)(int));
} }
#endif
#endif /* PPP_LWIP_H_ */ #endif /* PPP_LWIP_H_ */

View File

@ -0,0 +1,31 @@
/** \addtogroup netsocket */
/** @{*/
/* nsapi_ppp.h
* Modified work Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSAPI_PPP_H_
#define NSAPI_PPP_H_
#include "FileHandle.h"
#include "NetworkStack.h"
namespace mbed {
NetworkStack *nsapi_ppp_get_stack();
nsapi_error_t nsapi_ppp_init(FileHandle *stream);
} //namespace mbed
#endif /* NSAPI_PPP_H_ */