esp32/network_ppp: Add a timeout for closing PPP connection.

This also fixes deleting the PPP task, since eTaskGetState() never returns
eDeleted.

A limitation with this patch: once the PPP is deactivated (ppp.active(0))
it cannot be used again. A new PPP instance must be created instead.
pull/1/head
Damien George 2019-05-09 00:30:04 +10:00
parent 2630d3e51f
commit 0557f0b74b
1 changed files with 17 additions and 9 deletions

View File

@ -42,14 +42,17 @@
#include "lwip/dns.h"
#include "netif/ppp/pppapi.h"
#define PPP_CLOSE_TIMEOUT_MS (4000)
typedef struct _ppp_if_obj_t {
mp_obj_base_t base;
bool active;
bool connected;
volatile bool clean_close;
ppp_pcb *pcb;
mp_obj_t stream;
SemaphoreHandle_t inactiveWaitSem;
TaskHandle_t client_task_handle;
volatile TaskHandle_t client_task_handle;
struct netif pppif;
} ppp_if_obj_t;
@ -64,7 +67,7 @@ static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
self->connected = (pppif->ip_addr.u_addr.ip4.addr != 0);
break;
case PPPERR_USER:
xSemaphoreGive(self->inactiveWaitSem);
self->clean_close = true;
break;
case PPPERR_CONNECT:
self->connected = false;
@ -83,10 +86,9 @@ STATIC mp_obj_t ppp_make_new(mp_obj_t stream) {
self->stream = stream;
self->active = false;
self->connected = false;
self->inactiveWaitSem = xSemaphoreCreateBinary();
self->clean_close = false;
self->client_task_handle = NULL;
assert(self->inactiveWaitSem != NULL);
return MP_OBJ_FROM_PTR(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(ppp_make_new_obj, ppp_make_new);
@ -108,6 +110,8 @@ static void pppos_client_task(void *self_in) {
pppos_input_tcpip(self->pcb, (u8_t*)buf, len);
}
}
self->client_task_handle = NULL;
vTaskDelete(NULL);
}
@ -128,21 +132,24 @@ STATIC mp_obj_t ppp_active(size_t n_args, const mp_obj_t *args) {
pppapi_set_default(self->pcb);
pppapi_connect(self->pcb, 0);
xTaskCreate(pppos_client_task, "ppp", 2048, self, 1, &self->client_task_handle);
xTaskCreate(pppos_client_task, "ppp", 2048, self, 1, (TaskHandle_t*)&self->client_task_handle);
self->active = true;
} else {
if (!self->active) {
return mp_const_false;
}
// Wait for PPPERR_USER
// Wait for PPPERR_USER, with timeout
pppapi_close(self->pcb, 0);
xSemaphoreTake(self->inactiveWaitSem, portMAX_DELAY);
xSemaphoreGive(self->inactiveWaitSem);
uint32_t t0 = mp_hal_ticks_ms();
while (!self->clean_close && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
mp_hal_delay_ms(10);
}
// Shutdown task
xTaskNotifyGive(self->client_task_handle);
while (eTaskGetState(self->client_task_handle) != eDeleted) {
t0 = mp_hal_ticks_ms();
while (self->client_task_handle != NULL && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
mp_hal_delay_ms(10);
}
@ -151,6 +158,7 @@ STATIC mp_obj_t ppp_active(size_t n_args, const mp_obj_t *args) {
self->pcb = NULL;
self->active = false;
self->connected = false;
self->clean_close = false;
}
}
return mp_obj_new_bool(self->active);