10000 Add PPP networking · pycom/pycom-micropython-sigfox@7867134 · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit 7867134

Browse files
committed
Add PPP networking
This adds the PPP networking module from Genuine MicroPython.
1 parent 2536ff8 commit 7867134

File tree

4 files changed

+233
-0
lines changed

4 files changed

+233
-0
lines changed

esp32/application.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ APP_MODS_SRC_C = $(addprefix mods/,\
141141
moduos.c \
142142
modusocket.c \
143143
modnetwork.c \
144+
network_ppp.c \
144145
modwlan.c \
145146
modutime.c \
146147
modpycom.c \

esp32/mods/modnetwork.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_server_deinit_obj, network_server_deini
230230
STATIC const mp_map_elem_t mp_module_network_globals_table[] = {
231231
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_network) },
232232
{ MP_OBJ_NEW_QSTR(MP_QSTR_WLAN), (mp_obj_t)&mod_network_nic_type_wlan },
233+
{ MP_OBJ_NEW_QSTR(MP_QSTR_PPP), (mp_obj_t)&ppp_make_new_obj },
233234
#if defined (LOPY) || defined(LOPY4) || defined (FIPY)
234235
{ MP_OBJ_NEW_QSTR(MP_QSTR_LoRa), (mp_obj_t)&mod_network_nic_type_lora },
235236
#endif

esp32/mods/modnetwork.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,6 @@ void mod_network_register_nic(mp_obj_t nic);
131131
void mod_network_deregister_nic(mp_obj_t nic);
132132
mp_obj_t mod_network_find_nic(const mod_network_socket_obj_t *s, const uint8_t *ip);
133133

134+
MP_DECLARE_CONST_FUN_OBJ_1(ppp_make_new_obj);
135+
134136
#endif // MODNETWORK_H_

esp32/mods/network_ppp.c

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2018 "Eric Poulsen" <eric@zyxod.com>
7+
*
8+
* Based on the ESP IDF example code which is Public Domain / CC0
9+
*
10+
* Permission is hereby granted, free of charge, to any person obtaining a copy
11+
* of this software and associated documentation files (the "Software"), to deal
12+
* in the Software without restriction, including without limitation the rights
13+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
* copies of the Software, and to permit persons to whom the Software is
15+
* furnished to do so, subject to the following conditions:
16+
*
17+
* The above copyright notice and this permission notice shall be included in
18+
* all copies or substantial portions of the Software.
19+
*
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26+
* THE SOFTWARE.
27+
*/
28+
29+
#include "py/runtime.h"
30+
#include "py/mphal.h"
31+
#include "py/objtype.h"
32+
#include "py/stream.h"
33+
#include "netutils.h"
34+
#include "modmachine.h"
35+
36+
#include "netif/ppp/ppp.h"
37+
#include "netif/ppp/pppos.h"
38+
#include "lwip/err.h"
39+
#include "lwip/sockets.h"
40+
#include "lwip/sys.h"
41+
#include "lwip/netdb.h"
42+
#include "lwip/dns.h"
43+
#include "netif/ppp/pppapi.h"
44+
45+
#define PPP_CLOSE_TIMEOUT_MS (4000)
46+
47+
typedef struct _ppp_if_obj_t {
48+
mp_obj_base_t base;
49+
bool active;
50+
bool connected;
51+
volatile bool clean_close;
52+
ppp_pcb *pcb;
53+
mp_obj_t stream;
54+
SemaphoreHandle_t inactiveWaitSem;
55+
volatile TaskHandle_t client_task_handle;
56+
struct netif pppif;
57+
} ppp_if_obj_t;
58+
59+
const mp_obj_type_t ppp_if_type;
60+
61+
static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
62+
ppp_if_obj_t* self = ctx;
63+
struct netif *pppif = ppp_netif(self->pcb);
64+
65+
switch (err_code) {
66+
case PPPERR_NONE:
67+
self->connected = (pppif->ip_addr.u_addr.ip4.addr != 0);
68+
break;
69+
case PPPERR_USER:
70+
self->clean_close = true;
71+
break;
72+
case PPPERR_CONNECT:
73+
self->connected = false;
74+
break;
75+
default:
76+
break;
77+
}
78+
}
79+
80+
STATIC mp_obj_t ppp_make_new(mp_obj_t stream) {
81+
mp_get_stream_raise(stream, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE);
82+
83+
ppp_if_obj_t *self = m_new_obj_with_finaliser(ppp_if_obj_t);
84+
85+
self->base.type = &ppp_if_type;
86+
self->stream = stream;
87+
self->active = false;
88+
self->connected = false;
89+
self->clean_close = false;
90+
self->client_task_handle = NULL;
91+
92+
return MP_OBJ_FROM_PTR(self);
93+
}
94+
MP_DEFINE_CONST_FUN_OBJ_1(ppp_make_new_obj, ppp_make_new);
95+
96+
static u32_t ppp_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx) {
97+
ppp_if_obj_t *self = ctx;
98+
int err;
99+
return mp_stream_rw(self->stream, data, len, &err, MP_STREAM_RW_WRITE);
100+
}
101+
102+
static void pppos_client_task(void *self_in) {
103+
ppp_if_obj_t *self = (ppp_if_obj_t*)self_in;
104+
uint8_t buf[256];
105+
106+
while (ulTaskNotifyTake(pdTRUE, 0) == 0) {
107+
int err;
108+
int len = mp_stream_rw(self->stream, buf, sizeof(buf), &err, 0);
109+
if (len > 0) {
110+
pppos_input_tcpip(self->pcb, (u8_t*)buf, len);
111+
}
112+
}
113+
114+
self->client_task_handle = NULL;
115+
vTaskDelete(NULL);
116+
}
117+
118+
STATIC mp_obj_t ppp_active(size_t n_args, const mp_obj_t *args) {
119+
ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
120+
121+
if (n_args > 1) {
122+
if (mp_obj_is_true(args[1])) {
123+
if (self->active) {
124+
return mp_const_true;
125+
}
126+
127+
self->pcb = pppapi_pppos_create(&self->pppif, ppp_output_callback, ppp_status_cb, self);
128+
129+
if (self->pcb == NULL) {
130+
mp_raise_msg(&mp_type_RuntimeError, "init failed");
131+
}
132+
pppapi_set_default(self->pcb);
133+
pppapi_connect(self->pcb, 0);
134+
135+
xTaskCreate(pppos_client_task, "ppp", 2048, self, 1, (TaskHandle_t*)&self->client_task_handle);
136+
self->active = true;
137+
} else {
138+
if (!self->active) {
139+
return mp_const_false;
140+
}
141+
142+
// Wait for PPPERR_USER, with timeout
143+
pppapi_close(self->pcb, 0);
144+
uint32_t t0 = mp_hal_ticks_ms();
145+
while (!self->clean_close && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
146+
mp_hal_delay_ms(10);
147+
}
148+
149+
// Shutdown task
150+
xTaskNotifyGive(self->client_task_handle);
151+
t0 = mp_hal_ticks_ms();
152+
while (self->client_task_handle != NULL && mp_hal_ticks_ms() - t0 < PPP_CLOSE_TIMEOUT_MS) {
153+
mp_hal_delay_ms(10);
154+
}
155+
156+
// Release PPP
157+
pppapi_free(self->pcb);
158+
self->pcb = NULL;
159+
self->active = false;
160+
self->connected = false;
161+
self->clean_close = false;
162+
}
163+
}
164+
return mp_obj_new_bool(self->active);
165+
}
166+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ppp_active_obj, 1, 2, ppp_active);
167+
168+
STATIC mp_obj_t ppp_delete(mp_obj_t self_in) {
169+
ppp_if_obj_t* self = MP_OBJ_TO_PTR(self_in);
170+
mp_obj_t args[] = {self, mp_const_false};
171+
ppp_active(2, args);
172+
return mp_const_none;
173+
}
174+
MP_DEFINE_CONST_FUN_OBJ_1(ppp_delete_obj, ppp_delete);
175+
176+
STATIC mp_obj_t ppp_ifconfig(size_t n_args, const mp_obj_t *args) {
177+
ppp_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
178+
ip_addr_t dns;
179+
if (n_args == 1) {
180+
// get
181+
if (self->pcb != NULL) {
182+
dns = dns_getserver(0);
183+
struct netif *pppif = ppp_netif(self->pcb);
184+
mp_obj_t tuple[4] = {
185+
netutils_format_ipv4_addr((uint8_t*)&pppif->ip_addr, NETUTILS_BIG),
186+
netutils_format_ipv4_addr((uint8_t*)&pppif->gw, NETUTILS_BIG),
187+
netutils_format_ipv4_addr((uint8_t*)&pppif->netmask, NETUTILS_BIG),
188+
netutils_format_ipv4_addr((uint8_t*)&dns, NETUTILS_BIG),
189+
};
190+
return mp_obj_new_tuple(4, tuple);
191+
} else {
192+
mp_obj_t tuple[4] = { mp_const_none, mp_const_none, mp_const_none, mp_const_none };
193+
return mp_obj_new_tuple(4, tuple);
194+
}
195+
} else {
196+
mp_obj_t *items;
197+
mp_obj_get_array_fixed_n(args[1], 4, &items);
198+
netutils_parse_ipv4_addr(items[3], (uint8_t*)&dns.u_addr.ip4, NETUTILS_BIG);
199+
dns_setserver(0, &dns);
200+
return mp_const_none;
201+
}
202+
}
203+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ppp_ifconfig_obj, 1, 2, ppp_ifconfig);
204+
205+
STATIC mp_obj_t ppp_status(mp_obj_t self_in) {
206+
return mp_const_none;
207+
}
208+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(ppp_status_obj, ppp_status);
209+
210+
STATIC mp_obj_t ppp_isconnected(mp_obj_t self_in) {
211+
ppp_if_obj_t *self = MP_OBJ_TO_PTR(self_in);
212+
return mp_obj_new_bool(self->connected);
213+
}
214+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(ppp_isconnected_obj, ppp_isconnected);
215+
216+
STATIC const mp_rom_map_elem_t ppp_if_locals_dict_table[] = {
217+
{ MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&ppp_active_obj) },
218+
{ MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&ppp_isconnected_obj) },
219+
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&ppp_status_obj) },
220+
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&ppp_ifconfig_obj) },
221+
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&ppp_delete_obj) },
222+
};
223+
STATIC MP_DEFINE_CONST_DICT(ppp_if_locals_dict, ppp_if_locals_dict_table);
224+
225+
const mp_obj_type_t ppp_if_type = {
226+
{ &mp_type_type },
227+
.name = MP_QSTR_PPP,
228+
.locals_dict = (mp_obj_dict_t*)&ppp_if_locals_dict,
229+
};

0 commit comments

Comments
 (0)
0