summaryrefslogtreecommitdiffstatshomepage
path: root/extmod
diff options
context:
space:
mode:
Diffstat (limited to 'extmod')
-rw-r--r--extmod/btstack/modbluetooth_btstack.c7
-rw-r--r--extmod/machine_pulse.c37
-rw-r--r--extmod/modbluetooth.c7
-rw-r--r--extmod/modbluetooth.h2
-rw-r--r--extmod/modframebuf.c57
-rw-r--r--extmod/modjson.c3
-rw-r--r--extmod/modlwip.c146
-rw-r--r--extmod/modnetwork.c39
-rw-r--r--extmod/modnetwork.h5
-rw-r--r--extmod/modre.c3
-rw-r--r--extmod/network_cyw43.c3
-rw-r--r--extmod/network_esp_hosted.c2
-rw-r--r--extmod/network_ppp_lwip.c9
-rw-r--r--extmod/network_wiznet5k.c2
-rw-r--r--extmod/nimble/modbluetooth_nimble.c21
-rw-r--r--extmod/nimble/modbluetooth_nimble.h2
-rw-r--r--extmod/vfs_lfsx.c2
17 files changed, 224 insertions, 123 deletions
diff --git a/extmod/btstack/modbluetooth_btstack.c b/extmod/btstack/modbluetooth_btstack.c
index b29970842c..7694a1874f 100644
--- a/extmod/btstack/modbluetooth_btstack.c
+++ b/extmod/btstack/modbluetooth_btstack.c
@@ -705,12 +705,12 @@ int mp_bluetooth_init(void) {
return 0;
}
-void mp_bluetooth_deinit(void) {
+int mp_bluetooth_deinit(void) {
DEBUG_printf("mp_bluetooth_deinit\n");
// Nothing to do if not initialised.
if (!MP_STATE_PORT(bluetooth_btstack_root_pointers)) {
- return;
+ return 0;
}
mp_bluetooth_gap_advertise_stop();
@@ -737,6 +737,9 @@ void mp_bluetooth_deinit(void) {
deinit_stack();
DEBUG_printf("mp_bluetooth_deinit: complete\n");
+
+ bool timeout = mp_bluetooth_btstack_state == MP_BLUETOOTH_BTSTACK_STATE_TIMEOUT;
+ return timeout ? MP_ETIMEDOUT : 0;
}
bool mp_bluetooth_is_active(void) {
diff --git a/extmod/machine_pulse.c b/extmod/machine_pulse.c
index 85dba86d9b..b78a63f182 100644
--- a/extmod/machine_pulse.c
+++ b/extmod/machine_pulse.c
@@ -30,20 +30,35 @@
#if MICROPY_PY_MACHINE_PULSE
-MP_WEAK mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us) {
+mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us) {
+ mp_uint_t nchanges = 2;
mp_uint_t start = mp_hal_ticks_us();
- while (mp_hal_pin_read(pin) != pulse_level) {
- if ((mp_uint_t)(mp_hal_ticks_us() - start) >= timeout_us) {
- return (mp_uint_t)-2;
- }
- }
- start = mp_hal_ticks_us();
- while (mp_hal_pin_read(pin) == pulse_level) {
- if ((mp_uint_t)(mp_hal_ticks_us() - start) >= timeout_us) {
- return (mp_uint_t)-1;
+ for (;;) {
+ // Sample ticks and pin as close together as possible, and always in the same
+ // order each time around the loop. This gives the most accurate measurement.
+ mp_uint_t t = mp_hal_ticks_us();
+ int pin_value = mp_hal_pin_read(pin);
+
+ if (pin_value == pulse_level) {
+ // Pin is at desired value. Flip desired value and see if we are done.
+ pulse_level = 1 - pulse_level;
+ if (--nchanges == 0) {
+ return t - start;
+ }
+ start = t;
+ } else {
+ // Pin hasn't changed yet, check for timeout.
+ mp_uint_t dt = t - start;
+ if (dt >= timeout_us) {
+ return -nchanges;
+ }
+
+ // Allow a port to perform background task processing if needed.
+ #ifdef MICROPY_PY_MACHINE_TIME_PULSE_US_HOOK
+ MICROPY_PY_MACHINE_TIME_PULSE_US_HOOK(dt);
+ #endif
}
}
- return mp_hal_ticks_us() - start;
}
static mp_obj_t machine_time_pulse_us_(size_t n_args, const mp_obj_t *args) {
diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c
index b95c42a4ee..ffa407809a 100644
--- a/extmod/modbluetooth.c
+++ b/extmod/modbluetooth.c
@@ -290,12 +290,13 @@ static mp_obj_t bluetooth_ble_make_new(const mp_obj_type_t *type, size_t n_args,
static mp_obj_t bluetooth_ble_active(size_t n_args, const mp_obj_t *args) {
if (n_args == 2) {
// Boolean enable/disable argument supplied, set current state.
+ int err;
if (mp_obj_is_true(args[1])) {
- int err = mp_bluetooth_init();
- bluetooth_handle_errno(err);
+ err = mp_bluetooth_init();
} else {
- mp_bluetooth_deinit();
+ err = mp_bluetooth_deinit();
}
+ bluetooth_handle_errno(err);
}
// Return current state.
return mp_obj_new_bool(mp_bluetooth_is_active());
diff --git a/extmod/modbluetooth.h b/extmod/modbluetooth.h
index 6a087c8e25..24f063fa5d 100644
--- a/extmod/modbluetooth.h
+++ b/extmod/modbluetooth.h
@@ -295,7 +295,7 @@ extern const mp_obj_type_t mp_type_bluetooth_uuid;
int mp_bluetooth_init(void);
// Disables the Bluetooth stack. Is a no-op when not enabled.
-void mp_bluetooth_deinit(void);
+int mp_bluetooth_deinit(void);
// Returns true when the Bluetooth stack is active.
bool mp_bluetooth_is_active(void);
diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c
index b718a66cc6..5c4b9abf0c 100644
--- a/extmod/modframebuf.c
+++ b/extmod/modframebuf.c
@@ -270,8 +270,7 @@ static void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, u
formats[fb->format].fill_rect(fb, x, y, xend - x, yend - y, col);
}
-static mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args_in) {
- mp_arg_check_num(n_args, n_kw, 4, 5, false);
+static mp_obj_t framebuf_make_new_helper(size_t n_args, const mp_obj_t *args_in, unsigned int buf_flags, mp_obj_framebuf_t *o) {
mp_int_t width = mp_obj_get_int(args_in[1]);
mp_int_t height = mp_obj_get_int(args_in[2]);
@@ -318,13 +317,15 @@ static mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size
}
mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(args_in[0], &bufinfo, MP_BUFFER_WRITE);
+ mp_get_buffer_raise(args_in[0], &bufinfo, buf_flags);
if ((strides_required * stride + (height_required - strides_required) * width_required) * bpp / 8 > bufinfo.len) {
mp_raise_ValueError(NULL);
}
- mp_obj_framebuf_t *o = mp_obj_malloc(mp_obj_framebuf_t, type);
+ if (o == NULL) {
+ o = mp_obj_malloc(mp_obj_framebuf_t, (const mp_obj_type_t *)&mp_type_framebuf);
+ }
o->buf_obj = args_in[0];
o->buf = bufinfo.buf;
o->width = width;
@@ -335,6 +336,11 @@ static mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size
return MP_OBJ_FROM_PTR(o);
}
+static mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args_in) {
+ mp_arg_check_num(n_args, n_kw, 4, 5, false);
+ return framebuf_make_new_helper(n_args, args_in, MP_BUFFER_WRITE, NULL);
+}
+
static void framebuf_args(const mp_obj_t *args_in, mp_int_t *args_out, int n) {
for (int i = 0; i < n; ++i) {
args_out[i] = mp_obj_get_int(args_in[i + 1]);
@@ -707,13 +713,27 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_poly_obj, 5, 6, framebuf_pol
#endif // MICROPY_PY_ARRAY
+static void get_readonly_framebuffer(mp_obj_t arg, mp_obj_framebuf_t *rofb) {
+ mp_obj_t fb = mp_obj_cast_to_native_base(arg, MP_OBJ_FROM_PTR(&mp_type_framebuf));
+ if (fb != MP_OBJ_NULL) {
+ *rofb = *(mp_obj_framebuf_t *)MP_OBJ_TO_PTR(fb);
+ } else {
+ // A tuple/list of the form: (buffer, width, height, format[, stride]).
+ size_t len;
+ mp_obj_t *items;
+ mp_obj_get_array(arg, &len, &items);
+ if (len < 4 || len > 5) {
+ mp_raise_ValueError(NULL);
+ }
+ framebuf_make_new_helper(len, items, MP_BUFFER_READ, rofb);
+ }
+}
+
static mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args_in) {
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args_in[0]);
- mp_obj_t source_in = mp_obj_cast_to_native_base(args_in[1], MP_OBJ_FROM_PTR(&mp_type_framebuf));
- if (source_in == MP_OBJ_NULL) {
- mp_raise_TypeError(NULL);
- }
- mp_obj_framebuf_t *source = MP_OBJ_TO_PTR(source_in);
+
+ mp_obj_framebuf_t source;
+ get_readonly_framebuffer(args_in[1], &source);
mp_int_t x = mp_obj_get_int(args_in[2]);
mp_int_t y = mp_obj_get_int(args_in[3]);
@@ -721,16 +741,17 @@ static mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args_in) {
if (n_args > 4) {
key = mp_obj_get_int(args_in[4]);
}
- mp_obj_framebuf_t *palette = NULL;
+ mp_obj_framebuf_t palette;
+ palette.buf = NULL;
if (n_args > 5 && args_in[5] != mp_const_none) {
- palette = MP_OBJ_TO_PTR(mp_obj_cast_to_native_base(args_in[5], MP_OBJ_FROM_PTR(&mp_type_framebuf)));
+ get_readonly_framebuffer(args_in[5], &palette);
}
if (
(x >= self->width) ||
(y >= self->height) ||
- (-x >= source->width) ||
- (-y >= source->height)
+ (-x >= source.width) ||
+ (-y >= source.height)
) {
// Out of bounds, no-op.
return mp_const_none;
@@ -741,15 +762,15 @@ static mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args_in) {
int y0 = MAX(0, y);
int x1 = MAX(0, -x);
int y1 = MAX(0, -y);
- int x0end = MIN(self->width, x + source->width);
- int y0end = MIN(self->height, y + source->height);
+ int x0end = MIN(self->width, x + source.width);
+ int y0end = MIN(self->height, y + source.height);
for (; y0 < y0end; ++y0) {
int cx1 = x1;
for (int cx0 = x0; cx0 < x0end; ++cx0) {
- uint32_t col = getpixel(source, cx1, y1);
- if (palette) {
- col = getpixel(palette, col, 0);
+ uint32_t col = getpixel(&source, cx1, y1);
+ if (palette.buf) {
+ col = getpixel(&palette, col, 0);
}
if (col != (uint32_t)key) {
setpixel(self, cx0, y0, col);
diff --git a/extmod/modjson.c b/extmod/modjson.c
index e655a02bc0..11aedd1983 100644
--- a/extmod/modjson.c
+++ b/extmod/modjson.c
@@ -160,7 +160,8 @@ static mp_obj_t mod_json_load(mp_obj_t stream_obj) {
for (;;) {
cont:
if (S_END(s)) {
- break;
+ // Input finished abruptly in the middle of a composite entity.
+ goto fail;
}
mp_obj_t next = MP_OBJ_NULL;
bool enter = false;
diff --git a/extmod/modlwip.c b/extmod/modlwip.c
index 961803f5e8..b53559ed8c 100644
--- a/extmod/modlwip.c
+++ b/extmod/modlwip.c
@@ -70,6 +70,10 @@
#define TCP_NODELAY TF_NODELAY
+// Socket flags
+#define MSG_PEEK 0x01
+#define MSG_DONTWAIT 0x02
+
// For compatibilily with older lwIP versions.
#ifndef ip_set_option
#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt))
@@ -673,13 +677,13 @@ static mp_uint_t lwip_raw_udp_send(lwip_socket_obj_t *socket, const byte *buf, m
}
// Helper function for recv/recvfrom to handle raw/UDP packets
-static mp_uint_t lwip_raw_udp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_t len, ip_addr_t *ip, mp_uint_t *port, int *_errno) {
+static mp_uint_t lwip_raw_udp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_t len, mp_int_t flags, ip_addr_t *ip, mp_uint_t *port, int *_errno) {
lwip_incoming_packet_t *slot = &socket->incoming.udp_raw.array[socket->incoming.udp_raw.iget];
if (slot->pbuf == NULL) {
- if (socket->timeout == 0) {
- // Non-blocking socket.
+ // Non-blocking socket or flag
+ if (socket->timeout == 0 || (flags & MSG_DONTWAIT)) {
*_errno = MP_EAGAIN;
return -1;
}
@@ -705,9 +709,11 @@ static mp_uint_t lwip_raw_udp_receive(lwip_socket_obj_t *socket, byte *buf, mp_u
MICROPY_PY_LWIP_ENTER
u16_t result = pbuf_copy_partial(p, buf, ((p->tot_len > len) ? len : p->tot_len), 0);
- pbuf_free(p);
- slot->pbuf = NULL;
- socket->incoming.udp_raw.iget = (socket->incoming.udp_raw.iget + 1) % LWIP_INCOMING_PACKET_QUEUE_LEN;
+ if ((flags & MSG_PEEK) == 0) {
+ pbuf_free(p);
+ slot->pbuf = NULL;
+ socket->incoming.udp_raw.iget = (socket->incoming.udp_raw.iget + 1) % LWIP_INCOMING_PACKET_QUEUE_LEN;
+ }
MICROPY_PY_LWIP_EXIT
@@ -815,14 +821,20 @@ static mp_uint_t lwip_tcp_send(lwip_socket_obj_t *socket, const byte *buf, mp_ui
}
// Helper function for recv/recvfrom to handle TCP packets
-static mp_uint_t lwip_tcp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) {
+static mp_uint_t lwip_tcp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_t len, mp_int_t flags, int *_errno) {
// Check for any pending errors
STREAM_ERROR_CHECK(socket);
+ if (socket->state == STATE_LISTENING) {
+ // original socket in listening state, not the accepted connection.
+ *_errno = MP_ENOTCONN;
+ return -1;
+ }
+
if (socket->incoming.tcp.pbuf == NULL) {
- // Non-blocking socket
- if (socket->timeout == 0) {
+ // Non-blocking socket or flag
+ if (socket->timeout == 0 || (flags & MSG_DONTWAIT)) {
if (socket->state == STATE_PEER_CLOSED) {
return 0;
}
@@ -867,19 +879,21 @@ static mp_uint_t lwip_tcp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_
memcpy(buf, (byte *)p->payload + socket->recv_offset, len);
- remaining -= len;
- if (remaining == 0) {
- socket->incoming.tcp.pbuf = p->next;
- // If we don't ref here, free() will free the entire chain,
- // if we ref, it does what we need: frees 1st buf, and decrements
- // next buf's refcount back to 1.
- pbuf_ref(p->next);
- pbuf_free(p);
- socket->recv_offset = 0;
- } else {
- socket->recv_offset += len;
+ if ((flags & MSG_PEEK) == 0) {
+ remaining -= len;
+ if (remaining == 0) {
+ socket->incoming.tcp.pbuf = p->next;
+ // If we don't ref here, free() will free the entire chain,
+ // if we ref, it does what we need: frees 1st buf, and decrements
+ // next buf's refcount back to 1.
+ pbuf_ref(p->next);
+ pbuf_free(p);
+ socket->recv_offset = 0;
+ } else {
+ socket->recv_offset += len;
+ }
+ tcp_recved(socket->pcb.tcp, len);
}
- tcp_recved(socket->pcb.tcp, len);
MICROPY_PY_LWIP_EXIT
@@ -1271,40 +1285,58 @@ static mp_obj_t lwip_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
}
static MP_DEFINE_CONST_FUN_OBJ_2(lwip_socket_send_obj, lwip_socket_send);
-static mp_obj_t lwip_socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
- lwip_socket_obj_t *socket = MP_OBJ_TO_PTR(self_in);
+// Common implementation for recv & recvfrom
+static mp_obj_t lwip_socket_recv_common(size_t n_args, const mp_obj_t *args, ip_addr_t *ip, mp_uint_t *port) {
+ lwip_socket_obj_t *socket = MP_OBJ_TO_PTR(args[0]);
+ mp_int_t len = mp_obj_get_int(args[1]);
+ mp_int_t flags = n_args > 2 ? mp_obj_get_int(args[2]) : 0;
int _errno;
+ vstr_t vstr;
+ mp_uint_t ret = 0;
lwip_socket_check_connected(socket);
- mp_int_t len = mp_obj_get_int(len_in);
- vstr_t vstr;
vstr_init_len(&vstr, len);
- mp_uint_t ret = 0;
switch (socket->type) {
- case MOD_NETWORK_SOCK_STREAM: {
- ret = lwip_tcp_receive(socket, (byte *)vstr.buf, len, &_errno);
+ case MOD_NETWORK_SOCK_STREAM:
+ if (ip != NULL) {
+ *ip = socket->tcp_peer_addr;
+ *port = (mp_uint_t)socket->tcp_peer_port;
+ }
+ ret = lwip_tcp_receive(socket, (byte *)vstr.buf, len, flags, &_errno);
break;
- }
case MOD_NETWORK_SOCK_DGRAM:
#if MICROPY_PY_LWIP_SOCK_RAW
case MOD_NETWORK_SOCK_RAW:
#endif
- ret = lwip_raw_udp_receive(socket, (byte *)vstr.buf, len, NULL, NULL, &_errno);
+ ret = lwip_raw_udp_receive(socket, (byte *)vstr.buf, len, flags, ip, port, &_errno);
break;
}
if (ret == -1) {
mp_raise_OSError(_errno);
}
-
if (ret == 0) {
return mp_const_empty_bytes;
}
vstr.len = ret;
return mp_obj_new_bytes_from_vstr(&vstr);
}
-static MP_DEFINE_CONST_FUN_OBJ_2(lwip_socket_recv_obj, lwip_socket_recv);
+
+static mp_obj_t lwip_socket_recv(size_t n_args, const mp_obj_t *args) {
+ return lwip_socket_recv_common(n_args, args, NULL, NULL);
+}
+static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(lwip_socket_recv_obj, 2, 3, lwip_socket_recv);
+
+static mp_obj_t lwip_socket_recvfrom(size_t n_args, const mp_obj_t *args) {
+ ip_addr_t ip;
+ mp_uint_t port;
+ mp_obj_t tuple[2];
+ tuple[0] = lwip_socket_recv_common(n_args, args, &ip, &port);
+ tuple[1] = lwip_format_inet_addr(&ip, port);
+ return mp_obj_new_tuple(2, tuple);
+}
+static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(lwip_socket_recvfrom_obj, 2, 3, lwip_socket_recvfrom);
static mp_obj_t lwip_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) {
lwip_socket_obj_t *socket = MP_OBJ_TO_PTR(self_in);
@@ -1339,50 +1371,6 @@ static mp_obj_t lwip_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t
}
static MP_DEFINE_CONST_FUN_OBJ_3(lwip_socket_sendto_obj, lwip_socket_sendto);
-static mp_obj_t lwip_socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
- lwip_socket_obj_t *socket = MP_OBJ_TO_PTR(self_in);
- int _errno;
-
- lwip_socket_check_connected(socket);
-
- mp_int_t len = mp_obj_get_int(len_in);
- vstr_t vstr;
- vstr_init_len(&vstr, len);
- ip_addr_t ip;
- mp_uint_t port;
-
- mp_uint_t ret = 0;
- switch (socket->type) {
- case MOD_NETWORK_SOCK_STREAM: {
- ip = socket->tcp_peer_addr;
- port = (mp_uint_t)socket->tcp_peer_port;
- ret = lwip_tcp_receive(socket, (byte *)vstr.buf, len, &_errno);
- break;
- }
- case MOD_NETWORK_SOCK_DGRAM:
- #if MICROPY_PY_LWIP_SOCK_RAW
- case MOD_NETWORK_SOCK_RAW:
- #endif
- ret = lwip_raw_udp_receive(socket, (byte *)vstr.buf, len, &ip, &port, &_errno);
- break;
- }
- if (ret == -1) {
- mp_raise_OSError(_errno);
- }
-
- mp_obj_t tuple[2];
- if (ret == 0) {
- tuple[0] = mp_const_empty_bytes;
- } else {
- vstr.len = ret;
- tuple[0] = mp_obj_new_bytes_from_vstr(&vstr);
- }
- tuple[1] = lwip_format_inet_addr(&ip, port);
-
- return mp_obj_new_tuple(2, tuple);
-}
-static MP_DEFINE_CONST_FUN_OBJ_2(lwip_socket_recvfrom_obj, lwip_socket_recvfrom);
-
static mp_obj_t lwip_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) {
lwip_socket_obj_t *socket = MP_OBJ_TO_PTR(self_in);
lwip_socket_check_connected(socket);
@@ -1542,12 +1530,12 @@ static mp_uint_t lwip_socket_read(mp_obj_t self_in, void *buf, mp_uint_t size, i
switch (socket->type) {
case MOD_NETWORK_SOCK_STREAM:
- return lwip_tcp_receive(socket, buf, size, errcode);
+ return lwip_tcp_receive(socket, buf, size, 0, errcode);
case MOD_NETWORK_SOCK_DGRAM:
#if MICROPY_PY_LWIP_SOCK_RAW
case MOD_NETWORK_SOCK_RAW:
#endif
- return lwip_raw_udp_receive(socket, buf, size, NULL, NULL, errcode);
+ return lwip_raw_udp_receive(socket, buf, size, 0, NULL, NULL, errcode);
}
// Unreachable
return MP_STREAM_ERROR;
@@ -1919,6 +1907,8 @@ static const mp_rom_map_elem_t mp_module_lwip_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_TCP), MP_ROM_INT(IP_PROTO_TCP) },
{ MP_ROM_QSTR(MP_QSTR_TCP_NODELAY), MP_ROM_INT(TCP_NODELAY) },
+ { MP_ROM_QSTR(MP_QSTR_MSG_PEEK), MP_ROM_INT(MSG_PEEK) },
+ { MP_ROM_QSTR(MP_QSTR_MSG_DONTWAIT), MP_ROM_INT(MSG_DONTWAIT) },
};
static MP_DEFINE_CONST_DICT(mp_module_lwip_globals, mp_module_lwip_globals_table);
diff --git a/extmod/modnetwork.c b/extmod/modnetwork.c
index 336836b6b8..b6855fcaaa 100644
--- a/extmod/modnetwork.c
+++ b/extmod/modnetwork.c
@@ -40,6 +40,19 @@
#if MICROPY_PY_NETWORK_CYW43
// So that CYW43_LINK_xxx constants are available to MICROPY_PORT_NETWORK_INTERFACES.
#include "lib/cyw43-driver/src/cyw43.h"
+extern const struct _mp_obj_type_t mp_network_cyw43_type;
+#endif
+
+#if MICROPY_PY_NETWORK_WIZNET5K
+extern const struct _mp_obj_type_t mod_network_nic_type_wiznet5k;
+#endif
+
+#if MICROPY_PY_NETWORK_NINAW10
+extern const struct _mp_obj_type_t mod_network_nic_type_nina;
+#endif
+
+#if MICROPY_PY_NETWORK_ESP_HOSTED
+extern const struct _mp_obj_type_t mod_network_esp_hosted_type;
#endif
#ifdef MICROPY_PY_NETWORK_INCLUDEFILE
@@ -166,6 +179,32 @@ static const mp_rom_map_elem_t mp_module_network_globals_table[] = {
MICROPY_PORT_NETWORK_INTERFACES
#endif
+ #if MICROPY_PY_NETWORK_CYW43
+ { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mp_network_cyw43_type) },
+ // CYW43 status constants, currently for rp2 port only.
+ // TODO move these to WIFI module for all ports.
+ #if defined(PICO_PROGRAM_NAME) && defined(CYW43_LINK_DOWN)
+ { MP_ROM_QSTR(MP_QSTR_STAT_IDLE), MP_ROM_INT(CYW43_LINK_DOWN) },
+ { MP_ROM_QSTR(MP_QSTR_STAT_CONNECTING), MP_ROM_INT(CYW43_LINK_JOIN) },
+ { MP_ROM_QSTR(MP_QSTR_STAT_WRONG_PASSWORD), MP_ROM_INT(CYW43_LINK_BADAUTH) },
+ { MP_ROM_QSTR(MP_QSTR_STAT_NO_AP_FOUND), MP_ROM_INT(CYW43_LINK_NONET) },
+ { MP_ROM_QSTR(MP_QSTR_STAT_CONNECT_FAIL), MP_ROM_INT(CYW43_LINK_FAIL) },
+ { MP_ROM_QSTR(MP_QSTR_STAT_GOT_IP), MP_ROM_INT(CYW43_LINK_UP) },
+ #endif
+ #endif
+
+ #if MICROPY_PY_NETWORK_WIZNET5K
+ { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) },
+ #endif
+
+ #if MICROPY_PY_NETWORK_NINAW10
+ { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mod_network_nic_type_nina) },
+ #endif
+
+ #if MICROPY_PY_NETWORK_ESP_HOSTED
+ { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mod_network_esp_hosted_type) },
+ #endif
+
// Allow a port to take mostly full control of the network module.
#ifdef MICROPY_PY_NETWORK_MODULE_GLOBALS_INCLUDEFILE
#include MICROPY_PY_NETWORK_MODULE_GLOBALS_INCLUDEFILE
diff --git a/extmod/modnetwork.h b/extmod/modnetwork.h
index 7e5a283353..d16329f07d 100644
--- a/extmod/modnetwork.h
+++ b/extmod/modnetwork.h
@@ -60,6 +60,11 @@ extern char mod_network_country_code[2];
#define MICROPY_PY_NETWORK_HOSTNAME_MAX_LEN (32)
#endif
+#if MICROPY_PY_NETWORK_NINAW10
+// This Network interface requires the extended socket state.
+#define MICROPY_PY_SOCKET_EXTENDED_STATE (1)
+#endif
+
// This is a null-terminated string.
extern char mod_network_hostname_data[MICROPY_PY_NETWORK_HOSTNAME_MAX_LEN + 1];
diff --git a/extmod/modre.c b/extmod/modre.c
index 1a118009cb..d17ec68d50 100644
--- a/extmod/modre.c
+++ b/extmod/modre.c
@@ -427,6 +427,9 @@ static mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
const char *re_str = mp_obj_str_get_str(args[0]);
int size = re1_5_sizecode(re_str);
if (size == -1) {
+ #if MICROPY_ERROR_REPORTING >= MICROPY_ERROR_REPORTING_NORMAL
+ mp_raise_ValueError(MP_ERROR_TEXT("regex too complex"));
+ #endif
goto error;
}
mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, re.insts, char, size, (mp_obj_type_t *)&re_type);
diff --git a/extmod/network_cyw43.c b/extmod/network_cyw43.c
index 1b1b10b407..9ebfa904db 100644
--- a/extmod/network_cyw43.c
+++ b/extmod/network_cyw43.c
@@ -143,6 +143,9 @@ static mp_obj_t network_cyw43_active(size_t n_args, const mp_obj_t *args) {
return mp_obj_new_bool(if_active[self->itf]);
} else {
bool value = mp_obj_is_true(args[1]);
+ if (!value && self->itf == CYW43_ITF_STA) {
+ cyw43_wifi_leave(self->cyw, self->itf);
+ }
cyw43_wifi_set_up(self->cyw, self->itf, value, get_country_code());
if_active[self->itf] = value;
return mp_const_none;
diff --git a/extmod/network_esp_hosted.c b/extmod/network_esp_hosted.c
index 04cfc36b32..6ed348450b 100644
--- a/extmod/network_esp_hosted.c
+++ b/extmod/network_esp_hosted.c
@@ -48,6 +48,8 @@
#include "esp_hosted_wifi.h"
#include "esp_hosted_hal.h"
+extern const mp_obj_type_t mod_network_esp_hosted_type;
+
typedef struct _esp_hosted_obj_t {
mp_obj_base_t base;
uint32_t itf;
diff --git a/extmod/network_ppp_lwip.c b/extmod/network_ppp_lwip.c
index 8eb90ea4a6..2c3dac9201 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/extmod/network_wiznet5k.c b/extmod/network_wiznet5k.c
index 533d39a187..e065c14866 100644
--- a/extmod/network_wiznet5k.c
+++ b/extmod/network_wiznet5k.c
@@ -78,6 +78,8 @@
#endif
+extern const mp_obj_type_t mod_network_nic_type_wiznet5k;
+
#ifndef printf
#define printf(...) mp_printf(MP_PYTHON_PRINTER, __VA_ARGS__)
#endif
diff --git a/extmod/nimble/modbluetooth_nimble.c b/extmod/nimble/modbluetooth_nimble.c
index 6ca0c17267..5e7030e36f 100644
--- a/extmod/nimble/modbluetooth_nimble.c
+++ b/extmod/nimble/modbluetooth_nimble.c
@@ -60,6 +60,7 @@
static uint8_t nimble_address_mode = BLE_OWN_ADDR_RANDOM;
#define NIMBLE_STARTUP_TIMEOUT 2000
+#define NIMBLE_SHUTDOWN_TIMEOUT 500
// Any BLE_HS_xxx code not in this table will default to MP_EIO.
static int8_t ble_hs_err_to_errno_table[] = {
@@ -554,7 +555,7 @@ static void ble_hs_shutdown_stop_cb(int status, void *arg) {
static struct ble_hs_stop_listener ble_hs_shutdown_stop_listener;
-void mp_bluetooth_nimble_port_shutdown(void) {
+int mp_bluetooth_nimble_port_shutdown(void) {
DEBUG_printf("mp_bluetooth_nimble_port_shutdown (nimble default)\n");
// By default, just call ble_hs_stop directly and wait for the stack to stop.
@@ -562,9 +563,17 @@ void mp_bluetooth_nimble_port_shutdown(void) {
ble_hs_stop(&ble_hs_shutdown_stop_listener, ble_hs_shutdown_stop_cb, NULL);
+ mp_uint_t timeout_start_ticks_ms = mp_hal_ticks_ms();
while (mp_bluetooth_nimble_ble_state != MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF) {
- mp_event_wait_indefinite();
+ mp_uint_t elapsed = mp_hal_ticks_ms() - timeout_start_ticks_ms;
+ if (elapsed > NIMBLE_SHUTDOWN_TIMEOUT) {
+ // Stack had not responded (via ble_hs_shutdown_stop_cb)
+ return MP_ETIMEDOUT;
+ }
+
+ mp_event_wait_ms(NIMBLE_SHUTDOWN_TIMEOUT - elapsed);
}
+ return 0;
}
#endif // !MICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY
@@ -659,10 +668,11 @@ int mp_bluetooth_init(void) {
return 0;
}
-void mp_bluetooth_deinit(void) {
+int mp_bluetooth_deinit(void) {
DEBUG_printf("mp_bluetooth_deinit %d\n", mp_bluetooth_nimble_ble_state);
+ int ret = 0;
if (mp_bluetooth_nimble_ble_state == MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF) {
- return;
+ return 0;
}
// Must call ble_hs_stop() in a port-specific way to stop the background
@@ -675,7 +685,7 @@ void mp_bluetooth_deinit(void) {
DEBUG_printf("mp_bluetooth_deinit: starting port shutdown\n");
- mp_bluetooth_nimble_port_shutdown();
+ ret = mp_bluetooth_nimble_port_shutdown();
assert(mp_bluetooth_nimble_ble_state == MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF);
} else {
mp_bluetooth_nimble_ble_state = MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF;
@@ -692,6 +702,7 @@ void mp_bluetooth_deinit(void) {
#endif
DEBUG_printf("mp_bluetooth_deinit: shut down\n");
+ return ret;
}
bool mp_bluetooth_is_active(void) {
diff --git a/extmod/nimble/modbluetooth_nimble.h b/extmod/nimble/modbluetooth_nimble.h
index d9bef64920..0dd20eb658 100644
--- a/extmod/nimble/modbluetooth_nimble.h
+++ b/extmod/nimble/modbluetooth_nimble.h
@@ -84,7 +84,7 @@ void mp_bluetooth_nimble_port_hci_deinit(void);
void mp_bluetooth_nimble_port_start(void);
// Tell the port to stop its background task.
-void mp_bluetooth_nimble_port_shutdown(void);
+int mp_bluetooth_nimble_port_shutdown(void);
// --- Called by the HCI UART layer to let us know when packets have been sent.
void mp_bluetooth_nimble_sent_hci_packet(void);
diff --git a/extmod/vfs_lfsx.c b/extmod/vfs_lfsx.c
index 4b10ca3aa5..404eab84f4 100644
--- a/extmod/vfs_lfsx.c
+++ b/extmod/vfs_lfsx.c
@@ -300,7 +300,7 @@ static mp_obj_t MP_VFS_LFSx(chdir)(mp_obj_t self_in, mp_obj_t path_in) {
struct LFSx_API (info) info;
int ret = LFSx_API(stat)(&self->lfs, path, &info);
if (ret < 0 || info.type != LFSx_MACRO(_TYPE_DIR)) {
- mp_raise_OSError(-MP_ENOENT);
+ mp_raise_OSError(MP_ENOENT);
}
}