Bug fixes & state machine corrections

In case of carrier lost, we would like to inform PPP data pump.
That involved setting up link status flag down semaphores.
mbed_lwip_bringup() and mbed_lwip_bringdown() had been Ethernet specific only.
We extend these routines to support PPP as well. Currently we support only one interface
at a time. However, future enhancement to multi interface support should be trivial.
pull/4119/head
Hasnain Virk 2017-02-22 13:02:48 +02:00
parent 7e3c529d21
commit 87a4580e5f
6 changed files with 104 additions and 21 deletions

View File

@ -54,7 +54,7 @@ nsapi_error_t EthernetInterface::connect()
nsapi_error_t EthernetInterface::disconnect()
{
return mbed_lwip_bringdown();
return mbed_lwip_bringdown(false);
}
const char *EthernetInterface::get_mac_address()

View File

@ -298,10 +298,13 @@ static void mbed_lwip_tcpip_init_irq(void *eh)
}
static sys_sem_t lwip_netif_linked;
static sys_sem_t lwip_netif_unlinked;
static void mbed_lwip_netif_link_irq(struct netif *lwip_netif)
{
if (netif_is_link_up(lwip_netif)) {
sys_sem_signal(&lwip_netif_linked);
} else {
sys_sem_signal(&lwip_netif_unlinked);
}
}
@ -432,6 +435,7 @@ static void mbed_lwip_core_init(void)
sys_sem_new(&lwip_tcpip_inited, 0);
sys_sem_new(&lwip_netif_linked, 0);
sys_sem_new(&lwip_netif_unlinked, 0);
sys_sem_new(&lwip_netif_has_addr, 0);
tcpip_init(mbed_lwip_tcpip_init_irq, NULL);
@ -611,7 +615,7 @@ void mbed_lwip_clear_ipv6_addresses(struct netif *lwip_netif)
}
#endif
nsapi_error_t mbed_lwip_bringdown(void)
nsapi_error_t mbed_lwip_bringdown(bool ppp)
{
// Check if we've connected
if (!lwip_connected) {
@ -627,14 +631,30 @@ nsapi_error_t mbed_lwip_bringdown(void)
}
#endif
if (ppp) {
/* this is a blocking call, returns when PPP is properly closed */
err_t err = ppp_lwip_disconnect();
if (err) {
return mbed_lwip_err_remap(err);
}
MBED_ASSERT(!netif_is_link_up(&lwip_netif));
/*if (netif_is_link_up(&lwip_netif)) {
if (sys_arch_sem_wait(&lwip_netif_unlinked, 15000) == SYS_ARCH_TIMEOUT) {
return NSAPI_ERROR_DEVICE_ERROR;
}
}*/
} else {
netif_set_down(&lwip_netif);
}
#if LWIP_IPV6
mbed_lwip_clear_ipv6_addresses(&lwip_netif);
#endif
sys_sem_free(&lwip_netif_has_addr);
sys_sem_new(&lwip_netif_has_addr, 0);
lwip_connected = false;
return 0;
}
@ -653,14 +673,18 @@ static nsapi_error_t mbed_lwip_err_remap(err_t err) {
return NSAPI_ERROR_NO_CONNECTION;
case ERR_TIMEOUT:
case ERR_RTE:
case ERR_INPROGRESS:
case ERR_WOULDBLOCK:
return NSAPI_ERROR_WOULD_BLOCK;
case ERR_VAL:
case ERR_USE:
case ERR_ISCONN:
case ERR_ARG:
return NSAPI_ERROR_PARAMETER;
case ERR_INPROGRESS:
return NSAPI_ERROR_IN_PROGRESS;
case ERR_ALREADY:
return NSAPI_ERROR_ALREADY;
case ERR_ISCONN:
return NSAPI_ERROR_IS_CONNECTED;
default:
return NSAPI_ERROR_DEVICE_ERROR;
}

View File

@ -28,7 +28,7 @@ extern "C" {
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, bool ppp, const char *ip, const char *netmask, const char *gw);
nsapi_error_t mbed_lwip_bringdown(void);
nsapi_error_t mbed_lwip_bringdown(bool ppp);
const char *mbed_lwip_get_mac_address(void);
char *mbed_lwip_get_ip_address(char *buf, int buflen);

View File

@ -54,6 +54,9 @@ static volatile bool event_queued;
// Just one interface for now
static FileHandle *my_stream;
static ppp_pcb *my_ppp_pcb;
static bool ppp_link_up;
static sys_sem_t ppp_close_sem;
static void (*notify_ppp_link_status)(int) = 0;
static EventQueue *prepare_event_queue()
{
@ -66,7 +69,7 @@ static EventQueue *prepare_event_queue()
// Only need to queue 1 event. new blows on failure.
event_queue = new EventQueue(2 * EVENTS_EVENT_SIZE, NULL);
event_thread = new Thread(osPriorityNormal, 700);
event_thread = new Thread(osPriorityNormal, 900);
if (event_thread->start(callback(event_queue, &EventQueue::dispatch_forever)) != osOK) {
delete event_thread;
@ -79,7 +82,11 @@ static EventQueue *prepare_event_queue()
static u32_t ppp_output(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
{
FileHandle *stream = static_cast<FileHandle *>(ctx);
FileHandle *stream = my_stream;
if (!stream) {
return 0;
}
pollfh fhs;
fhs.fh = stream;
fhs.events = POLLOUT;
@ -269,10 +276,17 @@ hup:
return;
}
static void stream_cb(FileHandle *stream) {
if (!event_queued) {
/*static void ppp_carrier_lost()
{
if (my_stream) {
ppp_close(my_ppp_pcb, 1);
}
}*/
static void stream_cb() {
if (my_stream && !event_queued) {
event_queued = true;
if (event_queue->call(callback(ppp_input, stream)) == 0) {
if (event_queue->call(callback(ppp_input)) == 0) {
event_queued = false;
}
}
@ -280,7 +294,30 @@ static void stream_cb(FileHandle *stream) {
extern "C" err_t ppp_lwip_connect()
{
return ppp_connect(my_ppp_pcb, 0);
err_t ret = ppp_connect(my_ppp_pcb, 0);
// lwIP's ppp.txt says input must not be called until after connect
if (ret == ERR_OK) {
my_stream->sigio(callback(stream_cb));
}
return ret;
}
extern "C" err_t ppp_lwip_disconnect()
{
err_t ret = ppp_close(my_ppp_pcb, 0);
if (ret != ERR_OK) {
return ret;
}
/* close call made, now let's catch the response in the status callback */
sys_arch_sem_wait(&ppp_close_sem, 0);
/* Detach callbacks, and put handle back to default blocking mode */
my_stream->sigio(Callback<void()>());
my_stream->set_blocking(true);
my_stream = NULL;
return ret;
}
extern "C" nsapi_error_t ppp_lwip_if_init(struct netif *netif)
@ -291,29 +328,47 @@ extern "C" nsapi_error_t ppp_lwip_if_init(struct netif *netif)
if (!my_ppp_pcb) {
my_ppp_pcb = pppos_create(netif,
ppp_output, ppp_link_status, my_stream);
}
ppp_output, ppp_link_status, NULL);
if (!my_ppp_pcb) {
return NSAPI_ERROR_DEVICE_ERROR;
}
sys_sem_new(&ppp_close_sem, 0);
}
#if LWIP_IPV4
ppp_set_usepeerdns(my_ppp_pcb, true);
#endif
my_stream->sigio(callback(stream_cb, my_stream));
my_stream->set_blocking(false);
return NSAPI_ERROR_OK;
}
nsapi_error_t nsapi_ppp_init(FileHandle *stream)
nsapi_error_t nsapi_ppp_connect(FileHandle *stream, void (*ppp_link_status_cb)(int))
{
if (my_stream) {
return NSAPI_ERROR_PARAMETER;
}
my_stream = stream;
stream->set_blocking(false);
notify_ppp_link_status = ppp_link_status_cb;
// mustn't start calling input until after connect -
// attach deferred until ppp_lwip_connect, called from mbed_lwip_bringup
return mbed_lwip_bringup(false, true, NULL, NULL, NULL);
}
nsapi_error_t nsapi_ppp_disconnect(FileHandle *stream)
{
return mbed_lwip_bringdown(true);
}
/*void nsapi_ppp_carrier_lost(FileHandle *stream)
{
if (stream == my_stream) {
event_queue->call(callback(ppp_carrier_lost));
}
}*/
NetworkStack *nsapi_ppp_get_stack()
{
return nsapi_create_stack(&lwip_stack);

View File

@ -9,6 +9,7 @@ extern "C" {
#endif
nsapi_error_t ppp_lwip_if_init(struct netif *netif);
err_t ppp_lwip_connect(void);
err_t ppp_lwip_disconnect(void);
#ifdef __cplusplus
}
#endif

View File

@ -24,7 +24,10 @@
namespace mbed {
NetworkStack *nsapi_ppp_get_stack();
nsapi_error_t nsapi_ppp_init(FileHandle *stream);
nsapi_error_t nsapi_ppp_connect(FileHandle *stream, void(*link_status_cb)(int));
nsapi_error_t nsapi_ppp_disconnect(FileHandle *stream);
//void nsapi_ppp_carrier_lost(FileHandle *stream); // can be called from IRQ
} //namespace mbed