summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/esp32/Makefile11
-rw-r--r--ports/esp32/modnetwork.c1
-rw-r--r--ports/esp32/modnetwork.h1
-rw-r--r--ports/esp32/network_ppp.c221
-rw-r--r--ports/esp32/sdkconfig.h1
5 files changed, 235 insertions, 0 deletions
diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile
index 0e0b73c53..39ecced42 100644
--- a/ports/esp32/Makefile
+++ b/ports/esp32/Makefile
@@ -165,6 +165,7 @@ SRC_C = \
modmachine.c \
modnetwork.c \
network_lan.c \
+ network_ppp.c \
modsocket.c \
modesp.c \
esp32_ulp.c \
@@ -499,6 +500,16 @@ ESPIDF_LWIP_O = $(addprefix $(ESPCOMP)/lwip/,\
netif/ethernet.o \
netif/lowpan6.o \
netif/ethernetif.o \
+ netif/ppp/ppp.o \
+ netif/ppp/magic.o \
+ netif/ppp/lcp.o \
+ netif/ppp/ipcp.o \
+ netif/ppp/auth.o \
+ netif/ppp/fsm.o \
+ netif/ppp/ipv6cp.o \
+ netif/ppp/utils.o \
+ netif/ppp/vj.o \
+ netif/ppp/pppos.o \
port/freertos/sys_arch.o \
port/netif/wlanif.o \
port/netif/ethernetif.o \
diff --git a/ports/esp32/modnetwork.c b/ports/esp32/modnetwork.c
index 2e305823f..e2e1560c1 100644
--- a/ports/esp32/modnetwork.c
+++ b/ports/esp32/modnetwork.c
@@ -676,6 +676,7 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&esp_initialize_obj) },
{ MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&get_wlan_obj) },
{ MP_ROM_QSTR(MP_QSTR_LAN), MP_ROM_PTR(&get_lan_obj) },
+ { MP_ROM_QSTR(MP_QSTR_PPP), MP_ROM_PTR(&ppp_make_new_obj) },
{ MP_ROM_QSTR(MP_QSTR_phy_mode), MP_ROM_PTR(&esp_phy_mode_obj) },
#if MODNETWORK_INCLUDE_CONSTANTS
diff --git a/ports/esp32/modnetwork.h b/ports/esp32/modnetwork.h
index b8dc1b852..f39a2919d 100644
--- a/ports/esp32/modnetwork.h
+++ b/ports/esp32/modnetwork.h
@@ -29,6 +29,7 @@
enum { PHY_LAN8720, PHY_TLK110 };
MP_DECLARE_CONST_FUN_OBJ_KW(get_lan_obj);
+MP_DECLARE_CONST_FUN_OBJ_1(ppp_make_new_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj);
void usocket_events_deinit(void);
diff --git a/ports/esp32/network_ppp.c b/ports/esp32/network_ppp.c
new file mode 100644
index 000000000..27dd5e043
--- /dev/null
+++ b/ports/esp32/network_ppp.c
@@ -0,0 +1,221 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 "Eric Poulsen" <eric@zyxod.com>
+ *
+ * Based on the ESP IDF example code which is Public Domain / CC0
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/runtime.h"
+#include "py/mphal.h"
+#include "py/objtype.h"
+#include "py/stream.h"
+#include "netutils.h"
+#include "modmachine.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"
+#include "lwip/dns.h"
+#include "lwip/pppapi.h"
+
+typedef struct _ppp_if_obj_t {
+ mp_obj_base_t base;
+ bool active;
+ bool connected;
+ ppp_pcb *pcb;
+ mp_obj_t stream;
+ SemaphoreHandle_t inactiveWaitSem;
+ TaskHandle_t client_task_handle;
+ struct netif pppif;
+} ppp_if_obj_t;
+
+const mp_obj_type_t ppp_if_type;
+
+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);
+
+ switch (err_code) {
+ case PPPERR_NONE:
+ self->connected = (pppif->ip_addr.u_addr.ip4.addr != 0);
+ break;
+ case PPPERR_USER:
+ xSemaphoreGive(self->inactiveWaitSem);
+ break;
+ case PPPERR_CONNECT:
+ self->connected = false;
+ break;
+ default:
+ break;
+ }
+}
+
+STATIC mp_obj_t ppp_make_new(mp_obj_t stream) {
+ mp_get_stream_raise(stream, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE);
+
+ ppp_if_obj_t *self = m_new_obj_with_finaliser(ppp_if_obj_t);
+
+ self->base.type = &ppp_if_type;
+ self->stream = stream;
+ self->active = false;
+ self->connected = false;
+ self->inactiveWaitSem = xSemaphoreCreateBinary();
+ 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);
+
+static u32_t ppp_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx) {
+ ppp_if_obj_t *self = ctx;
+ int err;
+ return mp_stream_rw(self->stream, data, len, &err, MP_STREAM_RW_WRITE);
+}
+
+static void pppos_client_task(void *self_in) {
+ ppp_if_obj_t *self = (ppp_if_obj_t*)self_in;
+ uint8_t buf[256];
+
+ while (ulTaskNotifyTake(pdTRUE, 0) == 0) {
+ int err;
+ int len = mp_stream_rw(self->stream, buf, sizeof(buf), &err, 0);
+ if (len > 0) {
+ pppos_input_tcpip(self->pcb, (u8_t*)buf, len);
+ }
+ }
+ vTaskDelete(NULL);
+}
+
+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]);
+
+ if (n_args > 1) {
+ if (mp_obj_is_true(args[1])) {
+ if (self->active) {
+ return mp_const_true;
+ }
+
+ self->pcb = pppapi_pppos_create(&self->pppif, ppp_output_callback, ppp_status_cb, self);
+
+ if (self->pcb == NULL) {
+ mp_raise_msg(&mp_type_RuntimeError, "init failed");
+ }
+ pppapi_set_default(self->pcb);
+ pppapi_connect(self->pcb, 0);
+
+ xTaskCreate(pppos_client_task, "ppp", 2048, self, 1, &self->client_task_handle);
+ self->active = true;
+ } else {
+ if (!self->active) {
+ return mp_const_false;
+ }
+
+ // Wait for PPPERR_USER
+ pppapi_close(self->pcb, 0);
+ xSemaphoreTake(self->inactiveWaitSem, portMAX_DELAY);
+ xSemaphoreGive(self->inactiveWaitSem);
+
+ // Shutdown task
+ xTaskNotifyGive(self->client_task_handle);
+ while (eTaskGetState(self->client_task_handle) != eDeleted) {
+ mp_hal_delay_ms(10);
+ }
+
+ // Release PPP
+ pppapi_free(self->pcb);
+ self->pcb = NULL;
+ self->active = false;
+ self->connected = false;
+ }
+ }
+ return mp_obj_new_bool(self->active);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ppp_active_obj, 1, 2, ppp_active);
+
+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);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(ppp_delete_obj, ppp_delete);
+
+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]);
+ ip_addr_t dns;
+ if (n_args == 1) {
+ // get
+ if (self->pcb != NULL) {
+ dns = dns_getserver(0);
+ struct netif *pppif = ppp_netif(self->pcb);
+ mp_obj_t tuple[4] = {
+ netutils_format_ipv4_addr((uint8_t*)&pppif->ip_addr, NETUTILS_BIG),
+ netutils_format_ipv4_addr((uint8_t*)&pppif->gw, NETUTILS_BIG),
+ netutils_format_ipv4_addr((uint8_t*)&pppif->netmask, NETUTILS_BIG),
+ netutils_format_ipv4_addr((uint8_t*)&dns, NETUTILS_BIG),
+ };
+ return mp_obj_new_tuple(4, tuple);
+ } else {
+ mp_obj_t tuple[4] = { mp_const_none, mp_const_none, mp_const_none, mp_const_none };
+ return mp_obj_new_tuple(4, tuple);
+ }
+ } else {
+ mp_obj_t *items;
+ mp_obj_get_array_fixed_n(args[1], 4, &items);
+ netutils_parse_ipv4_addr(items[3], (uint8_t*)&dns.u_addr.ip4, NETUTILS_BIG);
+ dns_setserver(0, &dns);
+ return mp_const_none;
+ }
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ppp_ifconfig_obj, 1, 2, ppp_ifconfig);
+
+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 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_isconnected), MP_ROM_PTR(&ppp_isconnected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&ppp_status_obj) },
+ { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&ppp_ifconfig_obj) },
+ { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&ppp_delete_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(ppp_if_locals_dict, ppp_if_locals_dict_table);
+
+const mp_obj_type_t ppp_if_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_PPP,
+ .locals_dict = (mp_obj_dict_t*)&ppp_if_locals_dict,
+};
diff --git a/ports/esp32/sdkconfig.h b/ports/esp32/sdkconfig.h
index 97b307ef0..5c6a4c899 100644
--- a/ports/esp32/sdkconfig.h
+++ b/ports/esp32/sdkconfig.h
@@ -130,6 +130,7 @@
#define CONFIG_LWIP_MAX_SOCKETS 8
#define CONFIG_LWIP_SO_REUSE 1
#define CONFIG_LWIP_ETHARP_TRUST_IP_MAC 1
+#define CONFIG_PPP_SUPPORT 1
#define CONFIG_IP_LOST_TIMER_INTERVAL 120
#define CONFIG_UDP_RECVMBOX_SIZE 6
#define CONFIG_TCP_MAXRTX 12