diff --git a/extmod/network_ppp_lwip.c b/extmod/network_ppp_lwip.c index 8eb90ea4a6529..2c3dac92012a0 100644 --- a/extmod/network_ppp_lwip.c +++ b/extmod/network_ppp_lwip.c @@ -24,6 +24,10 @@ * THE SOFTWARE. */ +// This file is intended to closely match ports/esp32/network_ppp.c. Changes can +// and should probably be applied to both files. Compare them directly by using: +// git diff --no-index extmod/network_ppp_lwip.c ports/esp32/network_ppp.c + #include "py/runtime.h" #include "py/mphal.h" #include "py/stream.h" @@ -80,7 +84,6 @@ static void network_ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) { break; case PPPERR_USER: if (self->state >= STATE_ERROR) { - network_ppp_stream_uart_irq_disable(self); // Indicate that we are no longer connected and thus // only need to free the PPP PCB, not close it. self->state = STATE_ACTIVE; @@ -121,6 +124,7 @@ static mp_obj_t network_ppp___del__(mp_obj_t self_in) { self->state = STATE_INACTIVE; ppp_close(self->pcb, 1); } + network_ppp_stream_uart_irq_disable(self); // Free PPP PCB and reset state. self->state = STATE_INACTIVE; ppp_free(self->pcb); @@ -295,7 +299,8 @@ static mp_obj_t network_ppp_connect(size_t n_args, const mp_obj_t *args, mp_map_ ppp_set_auth(self->pcb, parsed_args[ARG_security].u_int, user_str, key_str); } - netif_set_default(self->pcb->netif); + ppp_set_default(self->pcb); + ppp_set_usepeerdns(self->pcb, true); if (ppp_connect(self->pcb, 0) != ERR_OK) { diff --git a/ports/esp32/modnetwork.h b/ports/esp32/modnetwork.h index 308a515c6e249..383e200b983c2 100644 --- a/ports/esp32/modnetwork.h +++ b/ports/esp32/modnetwork.h @@ -52,7 +52,7 @@ extern const mp_obj_type_t esp_network_wlan_type; MP_DECLARE_CONST_FUN_OBJ_0(esp_network_initialize_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_network_get_wlan_obj); MP_DECLARE_CONST_FUN_OBJ_KW(esp_network_get_lan_obj); -MP_DECLARE_CONST_FUN_OBJ_1(esp_network_ppp_make_new_obj); +extern const struct _mp_obj_type_t esp_network_ppp_lwip_type; MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_network_ifconfig_obj); MP_DECLARE_CONST_FUN_OBJ_KW(esp_network_ipconfig_obj); MP_DECLARE_CONST_FUN_OBJ_KW(esp_nic_ipconfig_obj); diff --git a/ports/esp32/modnetwork_globals.h b/ports/esp32/modnetwork_globals.h index 1aad785ee3d9c..9e355e958f1a4 100644 --- a/ports/esp32/modnetwork_globals.h +++ b/ports/esp32/modnetwork_globals.h @@ -8,7 +8,7 @@ { MP_ROM_QSTR(MP_QSTR_LAN), MP_ROM_PTR(&esp_network_get_lan_obj) }, #endif #if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) && defined(CONFIG_LWIP_PPP_SUPPORT) -{ MP_ROM_QSTR(MP_QSTR_PPP), MP_ROM_PTR(&esp_network_ppp_make_new_obj) }, +{ MP_ROM_QSTR(MP_QSTR_PPP), MP_ROM_PTR(&esp_network_ppp_lwip_type) }, #endif { MP_ROM_QSTR(MP_QSTR_phy_mode), MP_ROM_PTR(&esp_network_phy_mode_obj) }, { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&esp_network_ipconfig_obj) }, diff --git a/ports/esp32/network_ppp.c b/ports/esp32/network_ppp.c index 4dd5a3718c295..8b700c98ef386 100644 --- a/ports/esp32/network_ppp.c +++ b/ports/esp32/network_ppp.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2018 "Eric Poulsen" + * Copyright (c) 2024 Damien P. George * * Based on the ESP IDF example code which is Public Domain / CC0 * @@ -26,172 +27,265 @@ * THE SOFTWARE. */ +// This file is intended to closely match extmod/network_ppp_lwip.c. Changes can +// and should probably be applied to both files. Compare them directly by using: +// git diff --no-index extmod/network_ppp_lwip.c ports/esp32/network_ppp.c + #include "py/runtime.h" #include "py/mphal.h" -#include "py/objtype.h" #include "py/stream.h" -#include "shared/netutils/netutils.h" -#include "modmachine.h" -#include "ppp_set_auth.h" -#include "netif/ppp/ppp.h" -#include "netif/ppp/pppos.h" -#include "lwip/err.h" -#include "lwip/sockets.h" -#include "lwip/sys.h" -#include "lwip/netdb.h" +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) && defined(CONFIG_LWIP_PPP_SUPPORT) + #include "lwip/dns.h" +#include "netif/ppp/ppp.h" #include "netif/ppp/pppapi.h" +#include "netif/ppp/pppos.h" -#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) && defined(CONFIG_LWIP_PPP_SUPPORT) +// Includes for port-specific changes compared to network_ppp_lwip.c +#include "shared/netutils/netutils.h" +#include "ppp_set_auth.h" -#define PPP_CLOSE_TIMEOUT_MS (4000) +// Enable this to see the serial data going between the PPP layer. +#define PPP_TRACE_IN_OUT (0) -typedef struct _ppp_if_obj_t { +typedef enum { + STATE_INACTIVE, + STATE_ACTIVE, + STATE_ERROR, + STATE_CONNECTING, + STATE_CONNECTED, +} network_ppp_state_t; + +typedef struct _network_ppp_obj_t { mp_obj_base_t base; - bool active; - bool connected; - volatile bool clean_close; - ppp_pcb *pcb; + network_ppp_state_t state; + int error_code; mp_obj_t stream; - SemaphoreHandle_t inactiveWaitSem; - volatile TaskHandle_t client_task_handle; - struct netif pppif; -} ppp_if_obj_t; + ppp_pcb *pcb; + struct netif netif; +} network_ppp_obj_t; -const mp_obj_type_t ppp_if_type; +const mp_obj_type_t esp_network_ppp_lwip_type; + +static mp_obj_t network_ppp___del__(mp_obj_t self_in); + +static void network_ppp_stream_uart_irq_disable(network_ppp_obj_t *self) { + if (self->stream == mp_const_none) { + return; + } -static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) { - ppp_if_obj_t *self = ctx; - struct netif *pppif = ppp_netif(self->pcb); + // Disable UART IRQ. + mp_obj_t dest[3]; + mp_load_method(self->stream, MP_QSTR_irq, dest); + dest[2] = mp_const_none; + mp_call_method_n_kw(1, 0, dest); +} +static void network_ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) { + network_ppp_obj_t *self = ctx; switch (err_code) { case PPPERR_NONE: - #if CONFIG_LWIP_IPV6 - self->connected = (pppif->ip_addr.u_addr.ip4.addr != 0); - #else - self->connected = (pppif->ip_addr.addr != 0); - #endif // CONFIG_LWIP_IPV6 + self->state = STATE_CONNECTED; break; case PPPERR_USER: - self->clean_close = true; - break; - case PPPERR_CONNECT: - self->connected = false; + if (self->state >= STATE_ERROR) { + // Indicate that we are no longer connected and thus + // only need to free the PPP PCB, not close it. + self->state = STATE_ACTIVE; + } + // Clean up the PPP PCB. + network_ppp___del__(MP_OBJ_FROM_PTR(self)); break; default: + self->state = STATE_ERROR; + self->error_code = err_code; break; } } -static mp_obj_t ppp_make_new(mp_obj_t stream) { +static mp_obj_t network_ppp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + mp_arg_check_num(n_args, n_kw, 1, 1, false); + + mp_obj_t stream = all_args[0]; + if (stream != mp_const_none) { mp_get_stream_raise(stream, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE); } - ppp_if_obj_t *self = mp_obj_malloc_with_finaliser(ppp_if_obj_t, &ppp_if_type); + network_ppp_obj_t *self = mp_obj_malloc_with_finaliser(network_ppp_obj_t, type); + self->state = STATE_INACTIVE; self->stream = stream; - self->active = false; - self->connected = false; - self->clean_close = false; - self->client_task_handle = NULL; + self->pcb = NULL; return MP_OBJ_FROM_PTR(self); } -MP_DEFINE_CONST_FUN_OBJ_1(esp_network_ppp_make_new_obj, ppp_make_new); -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) -static u32_t ppp_output_callback(ppp_pcb *pcb, const void *data, u32_t len, void *ctx) -#else -static u32_t ppp_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx) -#endif -{ - ppp_if_obj_t *self = ctx; - - mp_obj_t stream = self->stream; - if (stream == mp_const_none) { - return 0; +static mp_obj_t network_ppp___del__(mp_obj_t self_in) { + network_ppp_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->state >= STATE_ACTIVE) { + if (self->state >= STATE_ERROR) { + // Still connected over the stream. + // Force the connection to close, with nocarrier=1. + self->state = STATE_INACTIVE; + pppapi_close(self->pcb, 1); + } + network_ppp_stream_uart_irq_disable(self); + // Free PPP PCB and reset state. + self->state = STATE_INACTIVE; + pppapi_free(self->pcb); + self->pcb = NULL; } - - int err; - return mp_stream_rw(stream, (void *)data, len, &err, MP_STREAM_RW_WRITE); + return mp_const_none; } +static MP_DEFINE_CONST_FUN_OBJ_1(network_ppp___del___obj, network_ppp___del__); -static void pppos_client_task(void *self_in) { - ppp_if_obj_t *self = (ppp_if_obj_t *)self_in; - uint8_t buf[256]; +static mp_obj_t network_ppp_poll(size_t n_args, const mp_obj_t *args) { + network_ppp_obj_t *self = MP_OBJ_TO_PTR(args[0]); - int len = 0; - while (ulTaskNotifyTake(pdTRUE, len <= 0) == 0) { - mp_obj_t stream = self->stream; - if (stream == mp_const_none) { - len = 0; - } else { - int err; - len = mp_stream_rw(stream, buf, sizeof(buf), &err, 0); - if (len > 0) { - pppos_input_tcpip(self->pcb, (u8_t *)buf, len); - } - } + if (self->state <= STATE_ERROR) { + return MP_OBJ_NEW_SMALL_INT(-MP_EPERM); } - self->client_task_handle = NULL; - vTaskDelete(NULL); - for (;;) { + mp_int_t total_len = 0; + mp_obj_t stream = self->stream; + while (stream != mp_const_none) { + uint8_t buf[256]; + int err; + mp_uint_t len = mp_stream_rw(stream, buf, sizeof(buf), &err, 0); + if (len == 0) { + break; + } + #if PPP_TRACE_IN_OUT + mp_printf(&mp_plat_print, "ppp_in(n=%u,data=", len); + for (size_t i = 0; i < len; ++i) { + mp_printf(&mp_plat_print, "%02x:", buf[i]); + } + mp_printf(&mp_plat_print, ")\n"); + #endif + pppos_input(self->pcb, (u8_t *)buf, len); + total_len += len; } + + return MP_OBJ_NEW_SMALL_INT(total_len); } +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ppp_poll_obj, 1, 2, network_ppp_poll); -static mp_obj_t ppp_active(size_t n_args, const mp_obj_t *args) { - ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); +static void network_ppp_stream_uart_irq_enable(network_ppp_obj_t *self) { + if (self->stream == mp_const_none) { + return; + } - if (n_args > 1) { - if (mp_obj_is_true(args[1])) { - if (self->active) { - return mp_const_true; - } + // Enable UART IRQ to call PPP.poll() when incoming data is ready. + mp_obj_t dest[4]; + mp_load_method(self->stream, MP_QSTR_irq, dest); + dest[2] = mp_obj_new_bound_meth(MP_OBJ_FROM_PTR(&network_ppp_poll_obj), MP_OBJ_FROM_PTR(self)); + dest[3] = mp_load_attr(self->stream, MP_QSTR_IRQ_RXIDLE); + mp_call_method_n_kw(2, 0, dest); +} - self->pcb = pppapi_pppos_create(&self->pppif, ppp_output_callback, ppp_status_cb, self); +static mp_obj_t network_ppp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + if (n_args != 1 && kwargs->used != 0) { + mp_raise_TypeError(MP_ERROR_TEXT("either pos or kw args are allowed")); + } + network_ppp_obj_t *self = MP_OBJ_TO_PTR(args[0]); - if (self->pcb == NULL) { - mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("init failed")); - } - self->active = true; - } else { - if (!self->active) { - return mp_const_false; + if (kwargs->used != 0) { + for (size_t i = 0; i < kwargs->alloc; i++) { + if (mp_map_slot_is_filled(kwargs, i)) { + switch (mp_obj_str_get_qstr(kwargs->table[i].key)) { + case MP_QSTR_stream: { + if (kwargs->table[i].value != mp_const_none) { + mp_get_stream_raise(kwargs->table[i].value, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE); + } + if (self->state >= STATE_ACTIVE) { + network_ppp_stream_uart_irq_disable(self); + } + self->stream = kwargs->table[i].value; + if (self->state >= STATE_ACTIVE) { + network_ppp_stream_uart_irq_enable(self); + } + break; + } + default: + break; + } } + } + return mp_const_none; + } - if (self->client_task_handle != NULL) { // is connecting or connected? - // Wait for PPPERR_USER, with timeout - pppapi_close(self->pcb, 0); - 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); - } + if (n_args != 2) { + mp_raise_TypeError(MP_ERROR_TEXT("can query only one param")); + } - // Shutdown task - xTaskNotifyGive(self->client_task_handle); - 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); + mp_obj_t val = mp_const_none; + + switch (mp_obj_str_get_qstr(args[1])) { + case MP_QSTR_stream: { + val = self->stream; + break; + } + case MP_QSTR_ifname: { + if (self->pcb != NULL) { + struct netif *pppif = ppp_netif(self->pcb); + char ifname[NETIF_NAMESIZE + 1] = {0}; + netif_index_to_name(netif_get_index(pppif), ifname); + if (ifname[0] != 0) { + val = mp_obj_new_str_from_cstr((char *)ifname); } } - - // Release PPP - pppapi_free(self->pcb); - self->pcb = NULL; - self->active = false; - self->connected = false; - self->clean_close = false; + break; } + default: + mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); + } + + return val; +} +static MP_DEFINE_CONST_FUN_OBJ_KW(network_ppp_config_obj, 1, network_ppp_config); + +static mp_obj_t network_ppp_status(mp_obj_t self_in) { + network_ppp_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->state == STATE_ERROR) { + return MP_OBJ_NEW_SMALL_INT(-self->error_code); + } else { + return MP_OBJ_NEW_SMALL_INT(self->state); + } +} +static MP_DEFINE_CONST_FUN_OBJ_1(network_ppp_status_obj, network_ppp_status); + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) +static u32_t network_ppp_output_callback(ppp_pcb *pcb, const void *data, u32_t len, void *ctx) +#else +static u32_t network_ppp_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx) +#endif +{ + network_ppp_obj_t *self = ctx; + #if PPP_TRACE_IN_OUT + mp_printf(&mp_plat_print, "ppp_out(n=%u,data=", len); + for (size_t i = 0; i < len; ++i) { + mp_printf(&mp_plat_print, "%02x:", ((const uint8_t *)data)[i]); + } + mp_printf(&mp_plat_print, ")\n"); + #endif + mp_obj_t stream = self->stream; + if (stream == mp_const_none) { + return 0; } - return mp_obj_new_bool(self->active); + int err; + // The return value from this output callback is the number of bytes written out. + // If it's less than the requested number of bytes then lwIP will propagate out an error. + return mp_stream_rw(stream, (void *)data, len, &err, MP_STREAM_RW_WRITE); } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ppp_active_obj, 1, 2, ppp_active); -static mp_obj_t ppp_connect_py(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - enum { ARG_authmode, ARG_username, ARG_password }; +static mp_obj_t network_ppp_connect(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + enum { ARG_security, ARG_user, ARG_key, ARG_authmode, ARG_username, ARG_password }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_user, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + // Deprecated arguments for backwards compatibility { MP_QSTR_authmode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PPPAUTHTYPE_NONE} }, { MP_QSTR_username, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, { MP_QSTR_password, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, @@ -200,17 +294,34 @@ static mp_obj_t ppp_connect_py(size_t n_args, const mp_obj_t *args, mp_map_t *kw mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args); - ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); + // Use deprecated arguments as defaults + if (parsed_args[ARG_security].u_int == -1) { + parsed_args[ARG_security].u_int = parsed_args[ARG_authmode].u_int; + } + if (parsed_args[ARG_user].u_obj == mp_const_none) { + parsed_args[ARG_user].u_obj = parsed_args[ARG_username].u_obj; + } + if (parsed_args[ARG_key].u_obj == mp_const_none) { + parsed_args[ARG_key].u_obj = parsed_args[ARG_password].u_obj; + } + + network_ppp_obj_t *self = MP_OBJ_TO_PTR(args[0]); + + if (self->state == STATE_INACTIVE) { + self->pcb = pppapi_pppos_create(&self->netif, network_ppp_output_callback, network_ppp_status_cb, self); + if (self->pcb == NULL) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("pppos_create failed")); + } + self->state = STATE_ACTIVE; - if (!self->active) { - mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("must be active")); + network_ppp_stream_uart_irq_enable(self); } - if (self->client_task_handle != NULL) { + if (self->state == STATE_CONNECTING || self->state == STATE_CONNECTED) { mp_raise_OSError(MP_EALREADY); } - switch (parsed_args[ARG_authmode].u_int) { + switch (parsed_args[ARG_security].u_int) { case PPPAUTHTYPE_NONE: case PPPAUTHTYPE_PAP: case PPPAUTHTYPE_CHAP: @@ -219,39 +330,49 @@ static mp_obj_t ppp_connect_py(size_t n_args, const mp_obj_t *args, mp_map_t *kw mp_raise_ValueError(MP_ERROR_TEXT("invalid auth")); } - if (parsed_args[ARG_authmode].u_int != PPPAUTHTYPE_NONE) { - const char *username_str = mp_obj_str_get_str(parsed_args[ARG_username].u_obj); - const char *password_str = mp_obj_str_get_str(parsed_args[ARG_password].u_obj); - pppapi_set_auth(self->pcb, parsed_args[ARG_authmode].u_int, username_str, password_str); + if (parsed_args[ARG_security].u_int != PPPAUTHTYPE_NONE) { + const char *user_str = mp_obj_str_get_str(parsed_args[ARG_user].u_obj); + const char *key_str = mp_obj_str_get_str(parsed_args[ARG_key].u_obj); + pppapi_set_auth(self->pcb, parsed_args[ARG_security].u_int, user_str, key_str); } - if (pppapi_set_default(self->pcb) != ESP_OK) { - mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("set default failed")); + + if (pppapi_set_default(self->pcb) != ERR_OK) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("ppp_set_default failed")); } ppp_set_usepeerdns(self->pcb, true); - if (pppapi_connect(self->pcb, 0) != ESP_OK) { - mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("connect failed")); + if (pppapi_connect(self->pcb, 0) != ERR_OK) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("ppp_connect failed")); } - if (xTaskCreatePinnedToCore(pppos_client_task, "ppp", 2048, self, 1, (TaskHandle_t *)&self->client_task_handle, MP_TASK_COREID) != pdPASS) { - mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("failed to create worker task")); - } + self->state = STATE_CONNECTING; + + // Do a poll in case there is data waiting on the input stream. + network_ppp_poll(1, args); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_KW(ppp_connect_obj, 1, ppp_connect_py); +static MP_DEFINE_CONST_FUN_OBJ_KW(network_ppp_connect_obj, 1, network_ppp_connect); -static mp_obj_t ppp_delete(mp_obj_t self_in) { - ppp_if_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_t args[] = {self, mp_const_false}; - ppp_active(2, args); +static mp_obj_t network_ppp_disconnect(mp_obj_t self_in) { + network_ppp_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->state == STATE_CONNECTING || self->state == STATE_CONNECTED) { + // Initiate close and wait for PPPERR_USER callback. + pppapi_close(self->pcb, 0); + } return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_1(ppp_delete_obj, ppp_delete); +static MP_DEFINE_CONST_FUN_OBJ_1(network_ppp_disconnect_obj, network_ppp_disconnect); + +static mp_obj_t network_ppp_isconnected(mp_obj_t self_in) { + network_ppp_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(self->state == STATE_CONNECTED); +} +static MP_DEFINE_CONST_FUN_OBJ_1(network_ppp_isconnected_obj, network_ppp_isconnected); -static mp_obj_t ppp_ifconfig(size_t n_args, const mp_obj_t *args) { - ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); +static mp_obj_t network_ppp_ifconfig(size_t n_args, const mp_obj_t *args) { + network_ppp_obj_t *self = MP_OBJ_TO_PTR(args[0]); if (n_args == 1) { // get const ip_addr_t *dns; @@ -282,11 +403,11 @@ static mp_obj_t ppp_ifconfig(size_t n_args, const mp_obj_t *args) { return mp_const_none; } } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ppp_ifconfig_obj, 1, 2, ppp_ifconfig); +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ppp_ifconfig_obj, 1, 2, network_ppp_ifconfig); -static mp_obj_t ppp_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { +static mp_obj_t network_ppp_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + network_ppp_obj_t *self = MP_OBJ_TO_PTR(args[0]); if (kwargs->used == 0) { - ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); if (self->pcb == NULL) { mp_raise_ValueError(MP_ERROR_TEXT("PPP not active")); } @@ -318,94 +439,64 @@ static mp_obj_t ppp_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwar } return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_KW(ppp_ipconfig_obj, 1, ppp_ipconfig); +static MP_DEFINE_CONST_FUN_OBJ_KW(network_ppp_ipconfig_obj, 1, network_ppp_ipconfig); -static mp_obj_t ppp_status(mp_obj_t self_in) { - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_1(ppp_status_obj, ppp_status); - -static mp_obj_t ppp_isconnected(mp_obj_t self_in) { - ppp_if_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool(self->connected); -} -static MP_DEFINE_CONST_FUN_OBJ_1(ppp_isconnected_obj, ppp_isconnected); - -static mp_obj_t ppp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { - if (n_args != 1 && kwargs->used != 0) { - mp_raise_TypeError(MP_ERROR_TEXT("either pos or kw args are allowed")); - } - ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]); - - if (kwargs->used != 0) { - for (size_t i = 0; i < kwargs->alloc; i++) { - if (mp_map_slot_is_filled(kwargs, i)) { - switch (mp_obj_str_get_qstr(kwargs->table[i].key)) { - case MP_QSTR_stream: { - if (kwargs->table[i].value != mp_const_none) { - mp_get_stream_raise(kwargs->table[i].value, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE); - } - self->stream = kwargs->table[i].value; - break; - } - default: - break; - } +static mp_obj_t network_ppp_active(size_t n_args, const mp_obj_t *args) { + network_ppp_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (n_args > 1) { + if (mp_obj_is_true(args[1])) { + if (self->state >= STATE_ACTIVE) { + return mp_const_true; } - } - return mp_const_none; - } - if (n_args != 2) { - mp_raise_TypeError(MP_ERROR_TEXT("can query only one param")); - } - - mp_obj_t val = mp_const_none; + self->pcb = pppapi_pppos_create(&self->netif, network_ppp_output_callback, network_ppp_status_cb, self); + if (self->pcb == NULL) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("pppos_create failed")); + } + self->state = STATE_ACTIVE; - switch (mp_obj_str_get_qstr(args[1])) { - case MP_QSTR_stream: { - val = self->stream; - break; - } - case MP_QSTR_ifname: { - if (self->pcb != NULL) { - struct netif *pppif = ppp_netif(self->pcb); - char ifname[NETIF_NAMESIZE + 1] = {0}; - netif_index_to_name(netif_get_index(pppif), ifname); - if (ifname[0] != 0) { - val = mp_obj_new_str_from_cstr((char *)ifname); - } + network_ppp_stream_uart_irq_enable(self); + } else { + if (self->state < STATE_ACTIVE) { + return mp_const_false; } - break; + + network_ppp___del__(MP_OBJ_FROM_PTR(self)); } - default: - mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); } - - return val; + return mp_obj_new_bool(self->state >= STATE_ACTIVE); } -static MP_DEFINE_CONST_FUN_OBJ_KW(ppp_config_obj, 1, ppp_config); - -static const mp_rom_map_elem_t ppp_if_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&ppp_active_obj) }, - { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&ppp_connect_obj) }, - { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&ppp_isconnected_obj) }, - { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&ppp_status_obj) }, - { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&ppp_config_obj) }, - { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&ppp_ifconfig_obj) }, - { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&ppp_ipconfig_obj) }, - { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&ppp_delete_obj) }, +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ppp_active_obj, 1, 2, network_ppp_active); + +static const mp_rom_map_elem_t network_ppp_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&network_ppp___del___obj) }, + { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_ppp_config_obj) }, + { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_ppp_status_obj) }, + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&network_ppp_connect_obj) }, + { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&network_ppp_disconnect_obj) }, + { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_ppp_isconnected_obj) }, + { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_ppp_ifconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&network_ppp_ipconfig_obj) }, + { MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&network_ppp_poll_obj) }, + + { MP_ROM_QSTR(MP_QSTR_SEC_NONE), MP_ROM_INT(PPPAUTHTYPE_NONE) }, + { MP_ROM_QSTR(MP_QSTR_SEC_PAP), MP_ROM_INT(PPPAUTHTYPE_PAP) }, + { MP_ROM_QSTR(MP_QSTR_SEC_CHAP), MP_ROM_INT(PPPAUTHTYPE_CHAP) }, + + // Deprecated interface for backwards compatibility + { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&network_ppp_active_obj) }, { MP_ROM_QSTR(MP_QSTR_AUTH_NONE), MP_ROM_INT(PPPAUTHTYPE_NONE) }, { MP_ROM_QSTR(MP_QSTR_AUTH_PAP), MP_ROM_INT(PPPAUTHTYPE_PAP) }, { MP_ROM_QSTR(MP_QSTR_AUTH_CHAP), MP_ROM_INT(PPPAUTHTYPE_CHAP) }, }; -static MP_DEFINE_CONST_DICT(ppp_if_locals_dict, ppp_if_locals_dict_table); +static MP_DEFINE_CONST_DICT(network_ppp_locals_dict, network_ppp_locals_dict_table); MP_DEFINE_CONST_OBJ_TYPE( - ppp_if_type, + esp_network_ppp_lwip_type, MP_QSTR_PPP, MP_TYPE_FLAG_NONE, - locals_dict, &ppp_if_locals_dict + make_new, network_ppp_make_new, + locals_dict, &network_ppp_locals_dict ); #endif 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