mirror of https://github.com/ARMmbed/mbed-os.git
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
parent
7e3c529d21
commit
87a4580e5f
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
netif_set_down(&lwip_netif);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue