diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.c b/ports/raspberrypi/common-hal/socketpool/Socket.c index 37c37445de..71a31379ad 100644 --- a/ports/raspberrypi/common-hal/socketpool/Socket.c +++ b/ports/raspberrypi/common-hal/socketpool/Socket.c @@ -504,6 +504,11 @@ STATIC mp_uint_t lwip_tcp_send(socketpool_socket_obj_t *socket, const byte *buf, if (err != ERR_MEM) { break; } + if (err == ERR_MEM && write_len > TCP_MSS) { + // Decreasing the amount sent to the next lower number of MSS + write_len = (write_len - 1) / TCP_MSS * TCP_MSS; + continue; + } err = tcp_output(socket->pcb.tcp); if (err != ERR_OK) { break; diff --git a/ports/raspberrypi/common-hal/wifi/Radio.c b/ports/raspberrypi/common-hal/wifi/Radio.c index f5d4983dcb..498ec862b2 100644 --- a/ports/raspberrypi/common-hal/wifi/Radio.c +++ b/ports/raspberrypi/common-hal/wifi/Radio.c @@ -158,6 +158,13 @@ void common_hal_wifi_radio_start_station(wifi_radio_obj_t *self) { } void common_hal_wifi_radio_stop_station(wifi_radio_obj_t *self) { + cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA); + // This is wrong, but without this call the state of ITF_STA is still + // reported as CYW43_LINK_JOIN (by wifi_link_status) and CYW43_LINK_UP + // (by tcpip_link_status). Until AP support is added, we can ignore the + // problem. + cyw43_wifi_leave(&cyw43_state, CYW43_ITF_AP); + bindings_cyw43_wifi_enforce_pm(); } void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, uint8_t authmode, uint8_t max_connections) { diff --git a/ports/raspberrypi/lwip_inc/lwipopts.h b/ports/raspberrypi/lwip_inc/lwipopts.h index ac4dd1564b..936a141602 100644 --- a/ports/raspberrypi/lwip_inc/lwipopts.h +++ b/ports/raspberrypi/lwip_inc/lwipopts.h @@ -47,6 +47,7 @@ #define LWIP_TCP 1 #define LWIP_UDP 1 #define LWIP_DNS 1 +#define LWIP_DNS_SUPPORT_MDNS_QUERIES 1 #define LWIP_TCP_KEEPALIVE 1 #define LWIP_NETIF_TX_SINGLE_PBUF 1 #define DHCP_DOES_ARP_CHECK 0 @@ -91,4 +92,13 @@ #define LWIP_NO_CTYPE_H 1 +#define X8_F "02x" +#define U16_F "u" +#define U32_F "lu" +#define S32_F "ld" +#define X32_F "lx" + +#define S16_F "d" +#define X16_F "x" +#define SZT_F "u" #endif /* __LWIPOPTS_H__ */ diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index 7f0d870771..89b23125c5 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -37,6 +37,7 @@ #include "py/mperrno.h" #include "shared/netutils/netutils.h" +#include "shared/runtime/interrupt_char.h" //| class Socket: //| """TCP, UDP and RAW socket. Cannot be created directly. Instead, call @@ -255,6 +256,46 @@ STATIC mp_obj_t _socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, _socketpool_socket_send); +//| def sendall(self, bytes: ReadableBuffer) -> None: +//| """Send some bytes to the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| +//| This calls send() repeatedly until all the data is sent or an error +//| occurs. If an error occurs, it's impossible to tell how much data +//| has been sent. +//| +//| :param ~bytes bytes: some bytes to send""" +//| ... +STATIC mp_obj_t _socketpool_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) { + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (common_hal_socketpool_socket_get_closed(self)) { + // Bad file number. + mp_raise_OSError(MP_EBADF); + } + if (!common_hal_socketpool_socket_get_connected(self)) { + mp_raise_BrokenPipeError(); + } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + while (bufinfo.len > 0) { + mp_int_t ret = common_hal_socketpool_socket_send(self, bufinfo.buf, bufinfo.len); + if (ret == -1) { + mp_raise_BrokenPipeError(); + } + bufinfo.len -= ret; + bufinfo.buf += ret; + if (bufinfo.len > 0) { + RUN_BACKGROUND_TASKS; + // Allow user to break out of sendall with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + return 0; + } + } + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_sendall_obj, _socketpool_socket_sendall); + //| def sendto(self, bytes: ReadableBuffer, address: Tuple[str, int]) -> int: //| """Send some bytes to a specific address. //| Suits sockets of type SOCK_DGRAM @@ -372,6 +413,7 @@ STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { { 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_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) },