diff options
Diffstat (limited to 'extmod')
-rw-r--r-- | extmod/btstack/modbluetooth_btstack.c | 7 | ||||
-rw-r--r-- | extmod/machine_pulse.c | 37 | ||||
-rw-r--r-- | extmod/modbluetooth.c | 7 | ||||
-rw-r--r-- | extmod/modbluetooth.h | 2 | ||||
-rw-r--r-- | extmod/modframebuf.c | 57 | ||||
-rw-r--r-- | extmod/modjson.c | 3 | ||||
-rw-r--r-- | extmod/modlwip.c | 146 | ||||
-rw-r--r-- | extmod/modnetwork.c | 39 | ||||
-rw-r--r-- | extmod/modnetwork.h | 5 | ||||
-rw-r--r-- | extmod/modre.c | 3 | ||||
-rw-r--r-- | extmod/network_cyw43.c | 3 | ||||
-rw-r--r-- | extmod/network_esp_hosted.c | 2 | ||||
-rw-r--r-- | extmod/network_ppp_lwip.c | 9 | ||||
-rw-r--r-- | extmod/network_wiznet5k.c | 2 | ||||
-rw-r--r-- | extmod/nimble/modbluetooth_nimble.c | 21 | ||||
-rw-r--r-- | extmod/nimble/modbluetooth_nimble.h | 2 | ||||
-rw-r--r-- | extmod/vfs_lfsx.c | 2 |
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); } } |