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()
{
return mbed_lwip_bringup(_dhcp,
return mbed_lwip_bringup(_dhcp, false,
_ip_address[0] ? _ip_address : 0,
_netmask[0] ? _netmask : 0,
_gateway[0] ? _gateway : 0);

View File

@ -33,10 +33,12 @@
#include "lwip/mld6.h"
#include "lwip/dns.h"
#include "lwip/udp.h"
#include "emac_api.h"
#include "ppp_lwip.h"
#include "lwip_tcp_isn.h"
static nsapi_error_t mbed_lwip_err_remap(err_t err);
#if DEVICE_EMAC
#define MBED_NETIF_INIT_FN emac_lwip_if_init
#else
@ -58,7 +60,9 @@ static struct lwip_socket {
} lwip_arena[MEMP_NUM_NETCONN];
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)
{
@ -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)
(void) snprintf(lwip_mac_address, NSAPI_MAC_SIZE, "%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);
netif->hwaddr[0] = MBED_MAC_ADDR_0;
netif->hwaddr[1] = MBED_MAC_ADDR_1;
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
char mac[6];
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]);
mbed_mac_address((char *)netif->hwaddr);
#endif
netif->hwaddr_len = ETH_HWADDR_LEN;
/* 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++) {
seed <<= 8;
seed |= mac[i % 6];
seed |= netif->hwaddr[i % 6];
}
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 */
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)
@ -400,7 +415,7 @@ char *mbed_lwip_get_gateway(char *buf, nsapi_size_t buflen)
#endif
}
void mbed_lwip_init()
static void mbed_lwip_core_init(void)
{
// 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);
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);
sys_arch_sem_wait(&lwip_tcpip_inited, 0);
@ -426,50 +443,80 @@ void mbed_lwip_init()
nsapi_error_t mbed_lwip_emac_init(emac_interface_t *emac)
{
// Check if we've already set up netif
if (!mbed_lwip_get_mac_address()) {
// Set up network
sys_sem_new(&lwip_netif_linked, 0);
sys_sem_new(&lwip_netif_has_addr, 0);
#if LWIP_ETHERNET
// Choose a MAC address - driver can override
mbed_lwip_set_mac_address(&lwip_netif);
memset(&lwip_netif, 0, sizeof lwip_netif);
if (!netif_add(&lwip_netif,
// Set up network
if (!netif_add(&lwip_netif,
#if LWIP_IPV4
0, 0, 0,
#endif
emac, MBED_NETIF_INIT_FN, tcpip_input)) {
return NSAPI_ERROR_DEVICE_ERROR;
}
mbed_lwip_set_mac_address();
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 !DEVICE_EMAC
eth_arch_enable_interrupts();
0, 0, 0,
#endif
emac, MBED_NETIF_INIT_FN, tcpip_input)) {
return NSAPI_ERROR_DEVICE_ERROR;
}
// Note the MAC address actually in use
mbed_lwip_record_mac_address(&lwip_netif);
#if !DEVICE_EMAC
eth_arch_enable_interrupts();
#endif
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
if (lwip_connected) {
return NSAPI_ERROR_PARAMETER;
}
mbed_lwip_init();
mbed_lwip_core_init();
if (mbed_lwip_emac_init(NULL) != NSAPI_ERROR_OK) {
return NSAPI_ERROR_DEVICE_ERROR;
nsapi_error_t ret;
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
netif_create_ip6_linklocal_address(&lwip_netif, 1/*from MAC*/);
if (lwip_netif.hwaddr_len == ETH_HWADDR_LEN) {
netif_create_ip6_linklocal_address(&lwip_netif, 1/*from MAC*/);
}
#if LWIP_IPV6_MLD
/*
* For hardware/netifs that implement MAC filtering.
@ -485,23 +532,12 @@ nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask,
#if LWIP_IPV6_AUTOCONFIG
/* IPv6 address autoconfiguration not enabled by default */
lwip_netif.ip6_autoconfig_enabled = 1;
lwip_netif.ip6_autoconfig_enabled = 1;
#endif /* LWIP_IPV6_AUTOCONFIG */
#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;
}
}
#endif // LWIP_IPV6
#if LWIP_IPV4
if (!dhcp) {
if (!dhcp && !ppp) {
ip4_addr_t ip_addr;
ip4_addr_t netmask_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
netif_set_up(&lwip_netif);
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);
}
#if LWIP_DHCP
// 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 (!mbed_lwip_get_ip_addr(true, &lwip_netif)) {
ret = sys_arch_sem_wait(&lwip_netif_has_addr, 15000);
if (ret == SYS_ARCH_TIMEOUT) {
if (sys_arch_sem_wait(&lwip_netif_has_addr, 15000) == SYS_ARCH_TIMEOUT) {
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 preferred stack address is acquired
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

View File

@ -19,15 +19,15 @@
#include "nsapi.h"
#include "emac_api.h"
#include "lwip/opt.h"
#ifdef __cplusplus
extern "C" {
#endif
// 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_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);
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;
#ifdef __cplusplus
}
#endif

View File

@ -36,10 +36,10 @@ extern "C" { // "pppos.h" is missing extern C
#include "netif/ppp/pppapi.h"
}
#include "nsapi_ppp.h"
#include "ppp_lwip.h"
#include "lwip_stack.h"
static void (*notify_ppp_link_status_cb)(int) = 0;
namespace mbed {
using rtos::Thread;
@ -52,6 +52,7 @@ static Thread *event_thread;
static volatile bool event_queued;
// Just one interface for now
static FileHandle *my_stream;
static ppp_pcb *my_ppp_pcb;
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
/*
* 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()) {
return ERR_MEM;
return NSAPI_ERROR_NO_MEMORY;
}
if (!my_ppp_pcb) {
my_ppp_pcb = pppos_create(netif,
ppp_output, ppp_link_status, stream);
ppp_output, ppp_link_status, my_stream);
}
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
ppp_set_usepeerdns(my_ppp_pcb, true);
#endif
ppp_set_default(my_ppp_pcb);
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);
my_stream->sigio(callback(stream_cb, my_stream));
my_stream->set_blocking(false);
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);
}

View File

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