Skip to content

Commit e70aa07

Browse files
author
Thomas Kiss
committed
ports/esp32: Updated network_ppp.c to match current documentation.
This commit updates the network.PPP module of the ESP32 port to match the current documentation. The the status() method should behave like the "common" LwIP implementation and the poll() method will raise an RuntimeError indicating that this is not really supported on this port. Signed-off-by: Thomas Kiss <thomas.kiss@lemonbeat.com>
1 parent f1018ee commit e70aa07

File tree

1 file changed

+109
-76
lines changed

1 file changed

+109
-76
lines changed

ports/esp32/network_ppp.c

Lines changed: 109 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,24 @@
4747

4848
#define PPP_CLOSE_TIMEOUT_MS (4000)
4949

50+
typedef enum {
51+
STATE_INACTIVE,
52+
STATE_ACTIVE,
53+
STATE_ERROR,
54+
STATE_CONNECTING,
55+
STATE_CONNECTED,
56+
} network_ppp_state_t;
57+
5058
typedef struct _ppp_if_obj_t {
5159
mp_obj_base_t base;
52-
bool active;
53-
bool connected;
60+
int error_code;
5461
volatile bool clean_close;
5562
ppp_pcb *pcb;
5663
mp_obj_t stream;
5764
SemaphoreHandle_t inactiveWaitSem;
5865
volatile TaskHandle_t client_task_handle;
5966
struct netif pppif;
67+
network_ppp_state_t state;
6068
} ppp_if_obj_t;
6169

6270
const mp_obj_type_t ppp_if_type;
@@ -68,18 +76,26 @@ static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
6876
switch (err_code) {
6977
case PPPERR_NONE:
7078
#if CONFIG_LWIP_IPV6
71-
self->connected = (pppif->ip_addr.u_addr.ip4.addr != 0);
79+
if (pppif->ip_addr.u_addr.ip4.addr != 0) {
80+
self->state = STATE_CONNECTED;
81+
}
7282
#else
73-
self->connected = (pppif->ip_addr.addr != 0);
83+
if (pppif->ip_addr.addr != 0) {
84+
self->state = STATE_CONNECTED;
85+
}
7486
#endif // CONFIG_LWIP_IPV6
7587
break;
7688
case PPPERR_USER:
89+
if (self->state >= STATE_ERROR) {
90+
// Indicate that we are no longer connected and thus
91+
// only need to free the PPP PCB, not close it.
92+
self->state = STATE_ACTIVE;
93+
}
7794
self->clean_close = true;
7895
break;
79-
case PPPERR_CONNECT:
80-
self->connected = false;
81-
break;
8296
default:
97+
self->state = STATE_ERROR;
98+
self->error_code = err_code;
8399
break;
84100
}
85101
}
@@ -90,16 +106,46 @@ static mp_obj_t ppp_make_new(mp_obj_t stream) {
90106
}
91107

92108
ppp_if_obj_t *self = mp_obj_malloc_with_finaliser(ppp_if_obj_t, &ppp_if_type);
109+
self->state = STATE_INACTIVE;
93110
self->stream = stream;
94-
self->active = false;
95-
self->connected = false;
111+
self->pcb = NULL;
96112
self->clean_close = false;
97113
self->client_task_handle = NULL;
98114

99115
return MP_OBJ_FROM_PTR(self);
100116
}
101117
MP_DEFINE_CONST_FUN_OBJ_1(esp_network_ppp_make_new_obj, ppp_make_new);
102118

119+
static mp_obj_t ppp_delete(mp_obj_t self_in) {
120+
ppp_if_obj_t *self = MP_OBJ_TO_PTR(self_in);
121+
if (self->state >= STATE_ACTIVE) {
122+
if (self->state >= STATE_ERROR) {
123+
// Still connected over the stream.
124+
// Force the connection to close, with nocarrier=1.
125+
self->state = STATE_INACTIVE;
126+
pppapi_close(self->pcb, 1);
127+
uint32_t t0 = mp_hal_ticks_ms();
128+
while (!self->clean_close && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
129+
mp_hal_delay_ms(10);
130+
}
131+
132+
// Shutdown task
133+
xTaskNotifyGive(self->client_task_handle);
134+
t0 = mp_hal_ticks_ms();
135+
while (self->client_task_handle != NULL && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
136+
mp_hal_delay_ms(10);
137+
}
138+
}
139+
// Free PPP PCB and reset state.
140+
self->state = STATE_INACTIVE;
141+
pppapi_free(self->pcb);
142+
self->pcb = NULL;
143+
self->clean_close = false;
144+
}
145+
return mp_const_none;
146+
}
147+
MP_DEFINE_CONST_FUN_OBJ_1(ppp_delete_obj, ppp_delete);
148+
103149
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0)
104150
static u32_t ppp_output_callback(ppp_pcb *pcb, const void *data, u32_t len, void *ctx)
105151
#else
@@ -141,72 +187,29 @@ static void pppos_client_task(void *self_in) {
141187
}
142188
}
143189

144-
static mp_obj_t ppp_active(size_t n_args, const mp_obj_t *args) {
145-
ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
146-
147-
if (n_args > 1) {
148-
if (mp_obj_is_true(args[1])) {
149-
if (self->active) {
150-
return mp_const_true;
151-
}
152-
153-
self->pcb = pppapi_pppos_create(&self->pppif, ppp_output_callback, ppp_status_cb, self);
154-
155-
if (self->pcb == NULL) {
156-
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("init failed"));
157-
}
158-
self->active = true;
159-
} else {
160-
if (!self->active) {
161-
return mp_const_false;
162-
}
163-
164-
if (self->client_task_handle != NULL) { // is connecting or connected?
165-
// Wait for PPPERR_USER, with timeout
166-
pppapi_close(self->pcb, 0);
167-
uint32_t t0 = mp_hal_ticks_ms();
168-
while (!self->clean_close && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
169-
mp_hal_delay_ms(10);
170-
}
171-
172-
// Shutdown task
173-
xTaskNotifyGive(self->client_task_handle);
174-
t0 = mp_hal_ticks_ms();
175-
while (self->client_task_handle != NULL && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
176-
mp_hal_delay_ms(10);
177-
}
178-
}
179-
180-
// Release PPP
181-
pppapi_free(self->pcb);
182-
self->pcb = NULL;
183-
self->active = false;
184-
self->connected = false;
185-
self->clean_close = false;
186-
}
187-
}
188-
return mp_obj_new_bool(self->active);
189-
}
190-
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ppp_active_obj, 1, 2, ppp_active);
191-
192190
static mp_obj_t ppp_connect_py(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
193191
enum { ARG_authmode, ARG_username, ARG_password };
194192
static const mp_arg_t allowed_args[] = {
195-
{ MP_QSTR_authmode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PPPAUTHTYPE_NONE} },
196-
{ MP_QSTR_username, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
197-
{ MP_QSTR_password, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
193+
{ MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PPPAUTHTYPE_NONE} },
194+
{ MP_QSTR_user, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
195+
{ MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
198196
};
199197

200198
mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)];
201199
mp_arg_parse_all(n_args - 1, args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args);
202200

203201
ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
204202

205-
if (!self->active) {
206-
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("must be active"));
203+
if (self->state == STATE_INACTIVE) {
204+
self->pcb = pppapi_pppos_create(&self->pppif, ppp_output_callback, ppp_status_cb, self);
205+
206+
if (self->pcb == NULL) {
207+
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("init failed"));
208+
}
209+
self->state = STATE_ACTIVE;
207210
}
208211

209-
if (self->client_task_handle != NULL) {
212+
if (self->client_task_handle != NULL || self->state == STATE_CONNECTING || self->state == STATE_CONNECTED) {
210213
mp_raise_OSError(MP_EALREADY);
211214
}
212215

@@ -238,17 +241,35 @@ static mp_obj_t ppp_connect_py(size_t n_args, const mp_obj_t *args, mp_map_t *kw
238241
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("failed to create worker task"));
239242
}
240243

244+
self->state = STATE_CONNECTING;
245+
241246
return mp_const_none;
242247
}
243248
MP_DEFINE_CONST_FUN_OBJ_KW(ppp_connect_obj, 1, ppp_connect_py);
244249

245-
static mp_obj_t ppp_delete(mp_obj_t self_in) {
250+
static mp_obj_t ppp_disconnect_py(mp_obj_t self_in) {
246251
ppp_if_obj_t *self = MP_OBJ_TO_PTR(self_in);
247-
mp_obj_t args[] = {self, mp_const_false};
248-
ppp_active(2, args);
252+
253+
if (self->client_task_handle != NULL || self->state == STATE_CONNECTING || self->state == STATE_CONNECTED) {
254+
// Wait for PPPERR_USER, with timeout
255+
pppapi_close(self->pcb, 0);
256+
uint32_t t0 = mp_hal_ticks_ms();
257+
while (!self->clean_close && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
258+
mp_hal_delay_ms(10);
259+
}
260+
261+
// Shutdown task
262+
xTaskNotifyGive(self->client_task_handle);
263+
t0 = mp_hal_ticks_ms();
264+
while (self->client_task_handle != NULL && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
265+
mp_hal_delay_ms(10);
266+
}
267+
}
268+
269+
self->clean_close = false;
249270
return mp_const_none;
250271
}
251-
MP_DEFINE_CONST_FUN_OBJ_1(ppp_delete_obj, ppp_delete);
272+
static MP_DEFINE_CONST_FUN_OBJ_1(ppp_disconnect_obj, ppp_disconnect_py);
252273

253274
static mp_obj_t ppp_ifconfig(size_t n_args, const mp_obj_t *args) {
254275
ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
@@ -321,13 +342,18 @@ static mp_obj_t ppp_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwar
321342
static MP_DEFINE_CONST_FUN_OBJ_KW(ppp_ipconfig_obj, 1, ppp_ipconfig);
322343

323344
static mp_obj_t ppp_status(mp_obj_t self_in) {
324-
return mp_const_none;
345+
ppp_if_obj_t *self = MP_OBJ_TO_PTR(self_in);
346+
if (self->state == STATE_ERROR) {
347+
return MP_OBJ_NEW_SMALL_INT(-self->error_code);
348+
} else {
349+
return MP_OBJ_NEW_SMALL_INT(self->state);
350+
}
325351
}
326352
static MP_DEFINE_CONST_FUN_OBJ_1(ppp_status_obj, ppp_status);
327353

328354
static mp_obj_t ppp_isconnected(mp_obj_t self_in) {
329355
ppp_if_obj_t *self = MP_OBJ_TO_PTR(self_in);
330-
return mp_obj_new_bool(self->connected);
356+
return mp_obj_new_bool(self->state == STATE_CONNECTED);
331357
}
332358
static MP_DEFINE_CONST_FUN_OBJ_1(ppp_isconnected_obj, ppp_isconnected);
333359

@@ -386,18 +412,25 @@ static mp_obj_t ppp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
386412
}
387413
static MP_DEFINE_CONST_FUN_OBJ_KW(ppp_config_obj, 1, ppp_config);
388414

415+
static mp_obj_t ppp_poll(size_t n_args, const mp_obj_t *args) {
416+
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Method not supported on ESP32"));
417+
}
418+
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ppp_poll_obj, 1, 2, ppp_poll);
419+
389420
static const mp_rom_map_elem_t ppp_if_locals_dict_table[] = {
390-
{ MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&ppp_active_obj) },
421+
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&ppp_delete_obj) },
422+
{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&ppp_config_obj) },
423+
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&ppp_status_obj) },
391424
{ MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&ppp_connect_obj) },
425+
{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&ppp_disconnect_obj) },
392426
{ MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&ppp_isconnected_obj) },
393-
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&ppp_status_obj) },
394-
{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&ppp_config_obj) },
395427
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&ppp_ifconfig_obj) },
396428
{ MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&ppp_ipconfig_obj) },
397-
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&ppp_delete_obj) },
398-
{ MP_ROM_QSTR(MP_QSTR_AUTH_NONE), MP_ROM_INT(PPPAUTHTYPE_NONE) },
399-
{ MP_ROM_QSTR(MP_QSTR_AUTH_PAP), MP_ROM_INT(PPPAUTHTYPE_PAP) },
400-
{ MP_ROM_QSTR(MP_QSTR_AUTH_CHAP), MP_ROM_INT(PPPAUTHTYPE_CHAP) },
429+
{ MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&ppp_poll_obj) },
430+
431+
{ MP_ROM_QSTR(MP_QSTR_SEC_NONE), MP_ROM_INT(PPPAUTHTYPE_NONE) },
432+
{ MP_ROM_QSTR(MP_QSTR_SEC_PAP), MP_ROM_INT(PPPAUTHTYPE_PAP) },
433+
{ MP_ROM_QSTR(MP_QSTR_SEC_CHAP), MP_ROM_INT(PPPAUTHTYPE_CHAP) },
401434
};
402435
static MP_DEFINE_CONST_DICT(ppp_if_locals_dict, ppp_if_locals_dict_table);
403436

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy