diff --git a/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk index 10e362399f55..72eb1db85a01 100644 --- a/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk @@ -3,6 +3,8 @@ CIRCUITPY_CREATION_ID = 0x00320001 IDF_TARGET = esp32 +CIRCUITPY_MESSAGE_COMPRESSION_LEVEL = 9 + CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m @@ -17,3 +19,4 @@ CIRCUITPY_PIXELBUF = 0 CIRCUITPY_PS2IO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_KEYPAD = 0 diff --git a/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk b/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk index 5656781fcef4..1d370fd30e71 100644 --- a/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk +++ b/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk @@ -10,6 +10,8 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_AESIO = 0 +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_CANIO = 0 CIRCUITPY_CODEOP = 0 CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/common-hal/socketpool/Socket.c b/ports/espressif/common-hal/socketpool/Socket.c index a291bf510b41..942abbdb3ae5 100644 --- a/ports/espressif/common-hal/socketpool/Socket.c +++ b/ports/espressif/common-hal/socketpool/Socket.c @@ -602,6 +602,10 @@ void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint self->timeout_ms = timeout_ms; } +mp_int_t common_hal_socketpool_socket_get_type(socketpool_socket_obj_t *self) { + return self->type; +} + int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int level, int optname, const void *value, size_t optlen) { int err = lwip_setsockopt(self->num, level, optname, value, optlen); diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk index 3789a76e0b22..127cdaba380e 100644 --- a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk @@ -9,3 +9,4 @@ CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" CIRCUITPY__EVE = 1 +CIRCUITPY_SSL = 1 diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c index 87ff27fa4632..ca9f7969d627 100644 --- a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c @@ -19,12 +19,25 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_W5500_CS), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO19) }, { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_W5500_RST), MP_ROM_PTR(&pin_GPIO20) }, { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_W5500_INT), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) }, @@ -36,10 +49,12 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, @@ -50,5 +65,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.c b/ports/raspberrypi/common-hal/socketpool/Socket.c index 2baa76786bdb..d305f63c7882 100644 --- a/ports/raspberrypi/common-hal/socketpool/Socket.c +++ b/ports/raspberrypi/common-hal/socketpool/Socket.c @@ -1183,6 +1183,10 @@ void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint self->timeout = timeout_ms; } +mp_int_t common_hal_socketpool_socket_get_type(socketpool_socket_obj_t *self) { + return self->type; +} + int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int level, int optname, const void *value, size_t optlen) { int zero = 0; bool enable = optlen == sizeof(&zero) && memcmp(value, &zero, optlen); diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index 18784ba04dbf..417afcb96997 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -32,6 +32,7 @@ #include "py/mperrno.h" #include "py/objlist.h" +#include "py/objproperty.h" #include "py/objtuple.h" #include "py/runtime.h" #include "py/stream.h" @@ -383,7 +384,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, //| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely. //| """ //| ... -//| STATIC mp_obj_t socketpool_socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t timeout_ms; @@ -401,11 +401,24 @@ STATIC mp_obj_t socketpool_socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_ } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_settimeout_obj, socketpool_socket_settimeout); +//| type: int +//| """Read-only access to the socket type""" +//| +STATIC mp_obj_t socketpool_socket_obj_get_type(mp_obj_t self_in) { + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_socketpool_socket_get_type(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_get_type_obj, socketpool_socket_obj_get_type); + +MP_PROPERTY_GETTER(socketpool_socket_type_obj, + (mp_obj_t)&socketpool_socket_get_type_obj); + STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&socketpool_socket___exit___obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&socketpool_socket_close_obj) }, + { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socketpool_socket_accept_obj) }, { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socketpool_socket_bind_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socketpool_socket_close_obj) }, @@ -413,12 +426,13 @@ STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socketpool_socket_listen_obj) }, { MP_ROM_QSTR(MP_QSTR_recvfrom_into), MP_ROM_PTR(&socketpool_socket_recvfrom_into_obj) }, { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socketpool_socket_recv_into_obj) }, - { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socketpool_socket_send_obj) }, { MP_ROM_QSTR(MP_QSTR_sendall), MP_ROM_PTR(&socketpool_socket_sendall_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socketpool_socket_send_obj) }, { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socketpool_socket_sendto_obj) }, { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socketpool_socket_setblocking_obj) }, { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socketpool_socket_setsockopt_obj) }, { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socketpool_socket_settimeout_obj) }, + { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&socketpool_socket_type_obj) }, }; STATIC MP_DEFINE_CONST_DICT(socketpool_socket_locals_dict, socketpool_socket_locals_dict_table); @@ -472,7 +486,7 @@ STATIC const mp_stream_p_t socket_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( socketpool_socket_type, MP_QSTR_Socket, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, locals_dict, &socketpool_socket_locals_dict, protocol, &socket_stream_p ); diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h index 14022ea49e8c..ab54ea4a9c41 100644 --- a/shared-bindings/socketpool/Socket.h +++ b/shared-bindings/socketpool/Socket.h @@ -38,6 +38,7 @@ void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self, const c bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t *self); bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t *self); mp_uint_t common_hal_socketpool_socket_get_timeout(socketpool_socket_obj_t *self); +mp_int_t common_hal_socketpool_socket_get_type(socketpool_socket_obj_t *self); bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *self, int backlog); mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *self, uint8_t *buf, uint32_t len, uint8_t *ip, uint32_t *port); diff --git a/shared-bindings/socketpool/SocketPool.h b/shared-bindings/socketpool/SocketPool.h index 04b3ddc7e680..ab1e1daa5bd2 100644 --- a/shared-bindings/socketpool/SocketPool.h +++ b/shared-bindings/socketpool/SocketPool.h @@ -29,50 +29,12 @@ #include "common-hal/socketpool/SocketPool.h" +#include "shared-bindings/socketpool/__init__.h" +#include "shared-bindings/socketpool/enum.h" #include "shared-bindings/socketpool/Socket.h" extern const mp_obj_type_t socketpool_socketpool_type; -typedef enum { - SOCKETPOOL_SOCK_STREAM = 1, - SOCKETPOOL_SOCK_DGRAM = 2, - SOCKETPOOL_SOCK_RAW = 3 -} socketpool_socketpool_sock_t; - -typedef enum { - SOCKETPOOL_AF_INET = 2, - SOCKETPOOL_AF_INET6 = 10 -} socketpool_socketpool_addressfamily_t; - -typedef enum { - SOCKETPOOL_IPPROTO_IP = 0, - SOCKETPOOL_IPPROTO_ICMP = 1, - SOCKETPOOL_IPPROTO_TCP = 6, - SOCKETPOOL_IPPROTO_UDP = 17, - SOCKETPOOL_IPPROTO_IPV6 = 41, - SOCKETPOOL_IPPROTO_RAW = 255, -} socketpool_socketpool_ipproto_t; - -typedef enum { - SOCKETPOOL_TCP_NODELAY = 1, -} socketpool_socketpool_tcpopt_t; - -typedef enum { - SOCKETPOOL_SOL_SOCKET = 0xfff, -} socketpool_socketpool_optlevel_t; - -typedef enum { - SOCKETPOOL_SO_REUSEADDR = 0x0004, -} socketpool_socketpool_socketopt_t; - -typedef enum { - SOCKETPOOL_IP_MULTICAST_TTL = 5, -} socketpool_socketpool_ipopt_t; - -typedef enum { - SOCKETPOOL_EAI_NONAME = -2, -} socketpool_eai_t; - void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t *self, mp_obj_t radio); socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_t *self, diff --git a/shared-bindings/socketpool/enum.h b/shared-bindings/socketpool/enum.h new file mode 100644 index 000000000000..45dab2a9e1e2 --- /dev/null +++ b/shared-bindings/socketpool/enum.h @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#pragma once + +// Note: This file must be designed so it be included by ssl +// whether or not CIRCUITPY_SOCKETPOOL is set. +// +typedef enum { + SOCKETPOOL_SOCK_STREAM = 1, + SOCKETPOOL_SOCK_DGRAM = 2, + SOCKETPOOL_SOCK_RAW = 3 +} socketpool_socketpool_sock_t; + +typedef enum { + SOCKETPOOL_AF_INET = 2, + SOCKETPOOL_AF_INET6 = 10 +} socketpool_socketpool_addressfamily_t; + +typedef enum { + SOCKETPOOL_IPPROTO_IP = 0, + SOCKETPOOL_IPPROTO_ICMP = 1, + SOCKETPOOL_IPPROTO_TCP = 6, + SOCKETPOOL_IPPROTO_UDP = 17, + SOCKETPOOL_IPPROTO_IPV6 = 41, + SOCKETPOOL_IPPROTO_RAW = 255, +} socketpool_socketpool_ipproto_t; + +typedef enum { + SOCKETPOOL_TCP_NODELAY = 1, +} socketpool_socketpool_tcpopt_t; + +typedef enum { + SOCKETPOOL_SOL_SOCKET = 0xfff, +} socketpool_socketpool_optlevel_t; + +typedef enum { + SOCKETPOOL_SO_REUSEADDR = 0x0004, +} socketpool_socketpool_socketopt_t; + +typedef enum { + SOCKETPOOL_IP_MULTICAST_TTL = 5, +} socketpool_socketpool_ipopt_t; + +typedef enum { + SOCKETPOOL_EAI_NONAME = -2, +} socketpool_eai_t; diff --git a/shared-bindings/ssl/SSLContext.c b/shared-bindings/ssl/SSLContext.c index 63dbfa3816c1..6ac06ae194da 100644 --- a/shared-bindings/ssl/SSLContext.c +++ b/shared-bindings/ssl/SSLContext.c @@ -200,9 +200,9 @@ STATIC mp_obj_t ssl_sslcontext_wrap_socket(size_t n_args, const mp_obj_t *pos_ar mp_raise_ValueError(MP_ERROR_TEXT("Server side context cannot have hostname")); } - socketpool_socket_obj_t *sock = args[ARG_sock].u_obj; + mp_obj_t sock_obj = args[ARG_sock].u_obj; - return common_hal_ssl_sslcontext_wrap_socket(self, sock, server_side, server_hostname); + return common_hal_ssl_sslcontext_wrap_socket(self, sock_obj, server_side, server_hostname); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ssl_sslcontext_wrap_socket_obj, 1, ssl_sslcontext_wrap_socket); diff --git a/shared-bindings/ssl/SSLContext.h b/shared-bindings/ssl/SSLContext.h index 73454149c5b3..671edf73d622 100644 --- a/shared-bindings/ssl/SSLContext.h +++ b/shared-bindings/ssl/SSLContext.h @@ -33,7 +33,6 @@ #include "common-hal/ssl/SSLContext.h" #endif -#include "shared-bindings/socketpool/Socket.h" #include "shared-bindings/ssl/SSLSocket.h" extern const mp_obj_type_t ssl_sslcontext_type; @@ -41,7 +40,7 @@ extern const mp_obj_type_t ssl_sslcontext_type; void common_hal_ssl_sslcontext_construct(ssl_sslcontext_obj_t *self); ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t *self, - socketpool_socket_obj_t *sock, bool server_side, const char *server_hostname); + mp_obj_t socket, bool server_side, const char *server_hostname); void common_hal_ssl_sslcontext_load_verify_locations(ssl_sslcontext_obj_t *self, const char *cadata); diff --git a/shared-bindings/ssl/SSLSocket.c b/shared-bindings/ssl/SSLSocket.c index ac8f3b2c5add..4181ad3a156d 100644 --- a/shared-bindings/ssl/SSLSocket.c +++ b/shared-bindings/ssl/SSLSocket.c @@ -73,15 +73,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket___exit___obj, 4, 4, ssl //| Returns a tuple of (new_socket, remote_address)""" STATIC mp_obj_t ssl_sslsocket_accept(mp_obj_t self_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint8_t ip[4]; - uint32_t port; - - ssl_sslsocket_obj_t *sslsock = common_hal_ssl_sslsocket_accept(self, ip, &port); - - mp_obj_t tuple_contents[2]; - tuple_contents[0] = MP_OBJ_FROM_PTR(sslsock); - tuple_contents[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); - return mp_obj_new_tuple(2, tuple_contents); + return common_hal_ssl_sslsocket_accept(self); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(ssl_sslsocket_accept_obj, ssl_sslsocket_accept); @@ -96,18 +88,7 @@ STATIC mp_obj_t ssl_sslsocket_bind(mp_obj_t self_in, mp_obj_t addr_in) { mp_obj_t *addr_items; mp_obj_get_array_fixed_n(addr_in, 2, &addr_items); - size_t hostlen; - const char *host = mp_obj_str_get_data(addr_items[0], &hostlen); - mp_int_t port = mp_obj_get_int(addr_items[1]); - if (port < 0) { - mp_raise_ValueError(MP_ERROR_TEXT("port must be >= 0")); - } - - size_t error = common_hal_ssl_sslsocket_bind(self, host, hostlen, (uint32_t)port); - if (error != 0) { - mp_raise_OSError(error); - } - + common_hal_ssl_sslsocket_bind(self, addr_in); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_bind_obj, ssl_sslsocket_bind); @@ -128,18 +109,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(ssl_sslsocket_close_obj, ssl_sslsocket_close); //| ... STATIC mp_obj_t ssl_sslsocket_connect(mp_obj_t self_in, mp_obj_t addr_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); - - mp_obj_t *addr_items; - mp_obj_get_array_fixed_n(addr_in, 2, &addr_items); - - size_t hostlen; - const char *host = mp_obj_str_get_data(addr_items[0], &hostlen); - mp_int_t port = mp_obj_get_int(addr_items[1]); - if (port < 0) { - mp_raise_ValueError(MP_ERROR_TEXT("port must be >= 0")); - } - - common_hal_ssl_sslsocket_connect(self, host, hostlen, (uint32_t)port); + common_hal_ssl_sslsocket_connect(self, addr_in); return mp_const_none; } @@ -230,13 +200,22 @@ STATIC mp_obj_t ssl_sslsocket_send(mp_obj_t self_in, mp_obj_t buf_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_send_obj, ssl_sslsocket_send); -// //| def setsockopt(self, level: int, optname: int, value: int) -> None: +// //| def setsockopt(self, level: int, optname: int, value: int | ReadableBuffer) -> None: // //| """Sets socket options""" // //| ... // //| -// STATIC mp_obj_t ssl_sslsocket_setsockopt(size_t n_args, const mp_obj_t *args) { -// } -// STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket_setsockopt_obj, 4, 4, ssl_sslsocket_setsockopt); +STATIC mp_obj_t ssl_sslsocket_setsockopt(size_t n_args, const mp_obj_t *args) { + ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(args[0]); + mp_obj_t level = args[1]; + mp_obj_t optname = args[2]; + mp_obj_t optval = args[3]; + + // throws on error + common_hal_ssl_sslsocket_setsockopt(self, level, optname, optval); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket_setsockopt_obj, 4, 4, ssl_sslsocket_setsockopt); //| def settimeout(self, value: int) -> None: //| """Set the timeout value for this socket. @@ -246,17 +225,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_send_obj, ssl_sslsocket_send); //| ... STATIC mp_obj_t ssl_sslsocket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_uint_t timeout_ms; - if (timeout_in == mp_const_none) { - timeout_ms = -1; - } else { - #if MICROPY_PY_BUILTINS_FLOAT - timeout_ms = 1000 * mp_obj_get_float(timeout_in); - #else - timeout_ms = 1000 * mp_obj_get_int(timeout_in); - #endif - } - common_hal_ssl_sslsocket_settimeout(self, timeout_ms); + common_hal_ssl_sslsocket_settimeout(self, timeout_in); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_settimeout_obj, ssl_sslsocket_settimeout); @@ -271,9 +240,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_settimeout_obj, ssl_sslsocket_set STATIC mp_obj_t ssl_sslsocket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (mp_obj_is_true(blocking)) { - common_hal_ssl_sslsocket_settimeout(self, -1); + common_hal_ssl_sslsocket_settimeout(self, mp_const_none); } else { - common_hal_ssl_sslsocket_settimeout(self, 0); + common_hal_ssl_sslsocket_settimeout(self, MP_OBJ_NEW_SMALL_INT(0)); } return mp_const_none; } @@ -292,7 +261,7 @@ STATIC const mp_rom_map_elem_t ssl_sslsocket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&ssl_sslsocket_recv_into_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&ssl_sslsocket_send_obj) }, { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&ssl_sslsocket_setblocking_obj) }, - // { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&ssl_sslsocket_setsockopt_obj) }, + { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&ssl_sslsocket_setsockopt_obj) }, { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&ssl_sslsocket_settimeout_obj) }, }; diff --git a/shared-bindings/ssl/SSLSocket.h b/shared-bindings/ssl/SSLSocket.h index dc3d048e099c..1010817e37a2 100644 --- a/shared-bindings/ssl/SSLSocket.h +++ b/shared-bindings/ssl/SSLSocket.h @@ -34,13 +34,14 @@ extern const mp_obj_type_t ssl_sslsocket_type; -ssl_sslsocket_obj_t *common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self, uint8_t *ip, uint32_t *port); -size_t common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port); +mp_obj_t common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self); +void common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr); void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self); -void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port); +void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, mp_obj_t addr); bool common_hal_ssl_sslsocket_get_closed(ssl_sslsocket_obj_t *self); bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t *self); -bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog); +void common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog); mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t *self, uint8_t *buf, uint32_t len); mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t *self, const uint8_t *buf, uint32_t len); -void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, uint32_t timeout_ms); +void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj); +void common_hal_ssl_sslsocket_setsockopt(ssl_sslsocket_obj_t *self, mp_obj_t level, mp_obj_t optname, mp_obj_t optval); diff --git a/shared-module/ssl/SSLContext.c b/shared-module/ssl/SSLContext.c index cc01a8bde7cf..2c35fe8ae554 100644 --- a/shared-module/ssl/SSLContext.c +++ b/shared-module/ssl/SSLContext.c @@ -26,7 +26,6 @@ #include "shared-bindings/ssl/SSLContext.h" #include "shared-bindings/ssl/SSLSocket.h" -#include "shared-bindings/socketpool/SocketPool.h" #include "py/runtime.h" #include "py/stream.h" diff --git a/shared-module/ssl/SSLSocket.c b/shared-module/ssl/SSLSocket.c index 2abb4c6c4a36..79a01156a3af 100644 --- a/shared-module/ssl/SSLSocket.c +++ b/shared-module/ssl/SSLSocket.c @@ -27,12 +27,10 @@ */ #include "shared-bindings/ssl/SSLSocket.h" -#include "shared-bindings/socketpool/Socket.h" #include "shared-bindings/ssl/SSLContext.h" -#include "shared-bindings/socketpool/SocketPool.h" -#include "shared-bindings/socketpool/Socket.h" #include "shared/runtime/interrupt_char.h" +#include "shared/netutils/netutils.h" #include "py/mperrno.h" #include "py/mphal.h" #include "py/objstr.h" @@ -40,6 +38,8 @@ #include "py/stream.h" #include "supervisor/shared/tick.h" +#include "shared-bindings/socketpool/enum.h" + #include "mbedtls/version.h" #if defined(MBEDTLS_ERROR_C) @@ -106,11 +106,92 @@ STATIC NORETURN void mbedtls_raise_error(int err) { #endif } +// Because ssl_socket_send and ssl_socket_recv_into are callbacks from mbedtls code, +// it is not OK to exit them by raising an exception (nlr_jump'ing through +// foreign code is not permitted). Instead, preserve the error number of any OSError +// and turn anything else into -MP_EINVAL. +STATIC int call_method_errno(size_t n_args, const mp_obj_t *args) { + nlr_buf_t nlr; + mp_int_t result = -MP_EINVAL; + if (nlr_push(&nlr) == 0) { + mp_obj_t obj_result = mp_call_method_n_kw(n_args, 0, args); + result = (obj_result == mp_const_none) ? 0 : mp_obj_get_int(obj_result); + nlr_pop(); + return result; + } else { + mp_obj_t exc = MP_OBJ_FROM_PTR(nlr.ret_val); + if (nlr_push(&nlr) == 0) { + result = -mp_obj_get_int(mp_load_attr(exc, MP_QSTR_errno)); + nlr_pop(); + } + } + return result; +} + +static int ssl_socket_send(ssl_sslsocket_obj_t *self, const byte *buf, size_t len) { + mp_obj_array_t mv; + mp_obj_memoryview_init(&mv, 'B', 0, len, (void *)buf); + + self->send_args[2] = MP_OBJ_FROM_PTR(&mv); + return call_method_errno(1, self->send_args); +} + +static int ssl_socket_recv_into(ssl_sslsocket_obj_t *self, byte *buf, size_t len) { + mp_obj_array_t mv; + mp_obj_memoryview_init(&mv, 'B' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW, 0, len, buf); + + self->recv_into_args[2] = MP_OBJ_FROM_PTR(&mv); + return call_method_errno(1, self->recv_into_args); +} + +static void ssl_socket_connect(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { + self->connect_args[2] = addr_in; + mp_call_method_n_kw(1, 0, self->connect_args); +} + +static void ssl_socket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { + self->bind_args[2] = addr_in; + mp_call_method_n_kw(1, 0, self->bind_args); +} + +static void ssl_socket_close(ssl_sslsocket_obj_t *self) { + // swallow any exception raised by the underlying close method. + // This is not ideal. However, it avoids printing "MemoryError:" + // when attempting to close a userspace socket object during gc_sweep_all + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_call_method_n_kw(0, 0, self->close_args); + nlr_pop(); + } else { + nlr_pop(); + } +} + +static void ssl_socket_setsockopt(ssl_sslsocket_obj_t *self, mp_obj_t level_obj, mp_obj_t opt_obj, mp_obj_t optval_obj) { + self->setsockopt_args[2] = level_obj; + self->setsockopt_args[3] = opt_obj; + self->setsockopt_args[4] = optval_obj; + mp_call_method_n_kw(3, 0, self->setsockopt_args); +} + +static void ssl_socket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj) { + self->settimeout_args[2] = timeout_obj; + mp_call_method_n_kw(1, 0, self->settimeout_args); +} + +static void ssl_socket_listen(ssl_sslsocket_obj_t *self, mp_int_t backlog) { + self->listen_args[2] = MP_OBJ_NEW_SMALL_INT(backlog); + mp_call_method_n_kw(1, 0, self->listen_args); +} + +static mp_obj_t ssl_socket_accept(ssl_sslsocket_obj_t *self) { + return mp_call_method_n_kw(0, 0, self->accept_args); +} + STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) { - mp_obj_t sock = *(mp_obj_t *)ctx; + ssl_sslsocket_obj_t *self = (ssl_sslsocket_obj_t *)ctx; - // mp_uint_t out_sz = sock_stream->write(sock, buf, len, &err); - mp_int_t out_sz = socketpool_socket_send(sock, buf, len); + mp_int_t out_sz = ssl_socket_send(self, buf, len); DEBUG_PRINT("socket_send() -> %d", out_sz); if (out_sz < 0) { int err = -out_sz; @@ -118,27 +199,22 @@ STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) { if (mp_is_nonblocking_error(err)) { return MBEDTLS_ERR_SSL_WANT_WRITE; } - return -err; // convert an MP_ERRNO to something mbedtls passes through as error - } else { - return out_sz; } + return out_sz; } -// _mbedtls_ssl_recv is called by mbedtls to receive bytes from the underlying socket STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) { - mp_obj_t sock = *(mp_obj_t *)ctx; + ssl_sslsocket_obj_t *self = (ssl_sslsocket_obj_t *)ctx; - mp_int_t out_sz = socketpool_socket_recv_into(sock, buf, len); + mp_int_t out_sz = ssl_socket_recv_into(self, buf, len); DEBUG_PRINT("socket_recv() -> %d", out_sz); if (out_sz < 0) { int err = -out_sz; if (mp_is_nonblocking_error(err)) { return MBEDTLS_ERR_SSL_WANT_READ; } - return -err; - } else { - return out_sz; } + return out_sz; } @@ -153,16 +229,27 @@ static int urandom_adapter(void *unused, unsigned char *buf, size_t n) { #endif ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t *self, - socketpool_socket_obj_t *socket, bool server_side, const char *server_hostname) { + mp_obj_t socket, bool server_side, const char *server_hostname) { - if (socket->type != SOCKETPOOL_SOCK_STREAM) { + mp_int_t socket_type = mp_obj_get_int(mp_load_attr(socket, MP_QSTR_type)); + if (socket_type != SOCKETPOOL_SOCK_STREAM) { mp_raise_RuntimeError(MP_ERROR_TEXT("Invalid socket for TLS")); } ssl_sslsocket_obj_t *o = m_new_obj_with_finaliser(ssl_sslsocket_obj_t); o->base.type = &ssl_sslsocket_type; o->ssl_context = self; - o->sock = socket; + o->sock_obj = socket; + + mp_load_method(socket, MP_QSTR_accept, o->accept_args); + mp_load_method(socket, MP_QSTR_bind, o->bind_args); + mp_load_method(socket, MP_QSTR_close, o->close_args); + mp_load_method(socket, MP_QSTR_connect, o->connect_args); + mp_load_method(socket, MP_QSTR_listen, o->listen_args); + mp_load_method(socket, MP_QSTR_recv_into, o->recv_into_args); + mp_load_method(socket, MP_QSTR_send, o->send_args); + mp_load_method(socket, MP_QSTR_settimeout, o->settimeout_args); + mp_load_method(socket, MP_QSTR_setsockopt, o->setsockopt_args); mbedtls_ssl_init(&o->ssl); mbedtls_ssl_config_init(&o->conf); @@ -221,7 +308,7 @@ ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t } } - mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL); + mbedtls_ssl_set_bio(&o->ssl, o, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL); if (self->cert_buf.buf != NULL) { #if MBEDTLS_VERSION_MAJOR >= 3 @@ -290,13 +377,16 @@ mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t *self, const uint8_t mbedtls_raise_error(ret); } -size_t common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port) { - return common_hal_socketpool_socket_bind(self->sock, host, hostlen, port); +void common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { + ssl_socket_bind(self, addr_in); } void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self) { + if (self->closed) { + return; + } self->closed = true; - common_hal_socketpool_socket_close(self->sock); + ssl_socket_close(self); mbedtls_pk_free(&self->pkey); mbedtls_x509_crt_free(&self->cert); mbedtls_x509_crt_free(&self->cacert); @@ -342,8 +432,8 @@ STATIC void do_handshake(ssl_sslsocket_obj_t *self) { } } -void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port) { - common_hal_socketpool_socket_connect(self->sock, host, hostlen, port); +void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, mp_obj_t addr_in) { + ssl_socket_connect(self, addr_in); do_handshake(self); } @@ -355,17 +445,26 @@ bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t *self) { return !self->closed; } -bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog) { - return common_hal_socketpool_socket_listen(self->sock, backlog); +void common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog) { + return ssl_socket_listen(self, backlog); } -ssl_sslsocket_obj_t *common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self, uint8_t *ip, uint32_t *port) { - socketpool_socket_obj_t *sock = common_hal_socketpool_socket_accept(self->sock, ip, port); +mp_obj_t common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self) { + mp_obj_t accepted = ssl_socket_accept(self); + mp_obj_t sock = mp_obj_subscr(accepted, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL); ssl_sslsocket_obj_t *sslsock = common_hal_ssl_sslcontext_wrap_socket(self->ssl_context, sock, true, NULL); do_handshake(sslsock); - return sslsock; + mp_obj_t peer = mp_obj_subscr(accepted, MP_OBJ_NEW_SMALL_INT(1), MP_OBJ_SENTINEL); + mp_obj_t tuple_contents[2]; + tuple_contents[0] = MP_OBJ_FROM_PTR(sslsock); + tuple_contents[1] = peer; + return mp_obj_new_tuple(2, tuple_contents); +} + +void common_hal_ssl_sslsocket_setsockopt(ssl_sslsocket_obj_t *self, mp_obj_t level_obj, mp_obj_t optname_obj, mp_obj_t optval_obj) { + ssl_socket_setsockopt(self, level_obj, optname_obj, optval_obj); } -void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, uint32_t timeout_ms) { - common_hal_socketpool_socket_settimeout(self->sock, timeout_ms); +void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, mp_obj_t timeout_obj) { + ssl_socket_settimeout(self, timeout_obj); } diff --git a/shared-module/ssl/SSLSocket.h b/shared-module/ssl/SSLSocket.h index 881ee400ff4a..6d9be05febbb 100644 --- a/shared-module/ssl/SSLSocket.h +++ b/shared-module/ssl/SSLSocket.h @@ -30,7 +30,6 @@ #include "py/obj.h" #include "shared-module/ssl/SSLContext.h" -#include "common-hal/socketpool/Socket.h" #include "mbedtls/platform.h" #include "mbedtls/ssl.h" @@ -41,7 +40,7 @@ typedef struct ssl_sslsocket_obj { mp_obj_base_t base; - socketpool_socket_obj_t *sock; + mp_obj_t sock_obj; ssl_sslcontext_obj_t *ssl_context; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; @@ -51,4 +50,13 @@ typedef struct ssl_sslsocket_obj { mbedtls_x509_crt cert; mbedtls_pk_context pkey; bool closed; + mp_obj_t accept_args[2]; + mp_obj_t bind_args[3]; + mp_obj_t close_args[2]; + mp_obj_t connect_args[3]; + mp_obj_t listen_args[3]; + mp_obj_t recv_into_args[3]; + mp_obj_t send_args[3]; + mp_obj_t setsockopt_args[5]; + mp_obj_t settimeout_args[3]; } ssl_sslsocket_obj_t;