diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 4405766d00..5ddeb07c97 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -322,7 +322,6 @@ SRC_C += \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ eic_handler.c \ - fatfs_port.c \ lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \ mphalport.c \ reset.c \ diff --git a/ports/atmel-samd/fatfs_port.c b/ports/atmel-samd/fatfs_port.c deleted file mode 100644 index 58a0ef0d72..0000000000 --- a/ports/atmel-samd/fatfs_port.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ - -#include "py/mphal.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" /* FatFs lower layer API */ -#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */ -#include "shared/timeutils/timeutils.h" - -#if CIRCUITPY_RTC -#include "shared-bindings/rtc/RTC.h" -#endif - -DWORD get_fattime(void) { - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif - - -} diff --git a/ports/broadcom/Makefile b/ports/broadcom/Makefile index 757e7f3450..1786d1d189 100644 --- a/ports/broadcom/Makefile +++ b/ports/broadcom/Makefile @@ -65,7 +65,6 @@ SRC_C += bindings/videocore/__init__.c \ boards/$(BOARD)/pins.c \ background.c \ common-hal/videocore/Framebuffer.c \ - fatfs_port.c \ mphalport.c \ lib/sdmmc/sdmmc_cmd.c \ lib/sdmmc/sdmmc_common.c \ diff --git a/ports/broadcom/fatfs_port.c b/ports/broadcom/fatfs_port.c deleted file mode 100644 index 58a0ef0d72..0000000000 --- a/ports/broadcom/fatfs_port.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ - -#include "py/mphal.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" /* FatFs lower layer API */ -#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */ -#include "shared/timeutils/timeutils.h" - -#if CIRCUITPY_RTC -#include "shared-bindings/rtc/RTC.h" -#endif - -DWORD get_fattime(void) { - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif - - -} diff --git a/ports/cxd56/Makefile b/ports/cxd56/Makefile index 073d2d59ce..3317b90280 100644 --- a/ports/cxd56/Makefile +++ b/ports/cxd56/Makefile @@ -172,7 +172,6 @@ SRC_S = supervisor/cpu.s SRC_C += \ background.c \ - fatfs_port.c \ mphalport.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ diff --git a/ports/cxd56/fatfs_port.c b/ports/cxd56/fatfs_port.c deleted file mode 100644 index e672b095b7..0000000000 --- a/ports/cxd56/fatfs_port.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright 2019 Sony Semiconductor Solutions Corporation - * - * 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. - */ - -#include "py/mphal.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" /* FatFs lower layer API */ -#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */ -#include "shared/timeutils/timeutils.h" - -#if CIRCUITPY_RTC -#include "shared-bindings/rtc/RTC.h" -#endif - -DWORD get_fattime(void) { - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif -} diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index 30c35f9caf..4e2ada4317 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -250,7 +250,6 @@ endif SRC_C += \ background.c \ - fatfs_port.c \ mphalport.c \ bindings/espidf/__init__.c \ boards/$(BOARD)/board.c \ diff --git a/ports/espressif/common-hal/socketpool/Socket.c b/ports/espressif/common-hal/socketpool/Socket.c index ce177f3821..5f34d674b2 100644 --- a/ports/espressif/common-hal/socketpool/Socket.c +++ b/ports/espressif/common-hal/socketpool/Socket.c @@ -240,7 +240,7 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_ return sock; } -int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port) { +int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port, socketpool_socket_obj_t *accepted) { struct sockaddr_in accept_addr; socklen_t socklen = sizeof(accept_addr); int newsoc = -1; @@ -274,12 +274,25 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_ lwip_close(newsoc); return -MP_EBADF; } + + + if (accepted != NULL) { + // Close the active socket because we have another we accepted. + if (!common_hal_socketpool_socket_get_closed(accepted)) { + common_hal_socketpool_socket_close(accepted); + } + // Create the socket + accepted->num = newsoc; + accepted->pool = self->pool; + accepted->connected = true; + } + return newsoc; } socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port) { - int newsoc = socketpool_socket_accept(self, ip, port); + int newsoc = socketpool_socket_accept(self, ip, port, NULL); if (newsoc > 0) { mark_user_socket(newsoc); @@ -554,6 +567,15 @@ void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint self->timeout_ms = timeout_ms; } + +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); + if (err != 0) { + return -errno; + } + return 0; +} + bool common_hal_socketpool_readable(socketpool_socket_obj_t *self) { struct timeval immediate = {0, 0}; @@ -577,3 +599,18 @@ bool common_hal_socketpool_writable(socketpool_socket_obj_t *self) { // including returning true in the error case return num_triggered != 0; } + +void socketpool_socket_move(socketpool_socket_obj_t *self, socketpool_socket_obj_t *sock) { + *sock = *self; + self->connected = false; + self->num = -1; +} + +void socketpool_socket_reset(socketpool_socket_obj_t *self) { + if (self->base.type == &socketpool_socket_type) { + return; + } + self->base.type = &socketpool_socket_type; + self->connected = false; + self->num = -1; +} diff --git a/ports/espressif/fatfs_port.c b/ports/espressif/fatfs_port.c deleted file mode 100644 index 38c2d923b8..0000000000 --- a/ports/espressif/fatfs_port.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ - -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" -#include "shared/timeutils/timeutils.h" -#include "shared-bindings/rtc/RTC.h" -#include "shared-bindings/time/__init__.h" -#include "supervisor/fatfs_port.h" - -DWORD _time_override = 0; -DWORD get_fattime(void) { - if (_time_override > 0) { - return _time_override; - } - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif -} - -void override_fattime(DWORD time) { - _time_override = time; -} diff --git a/ports/litex/Makefile b/ports/litex/Makefile index 6b1e33c8d1..9e59c1a2fa 100644 --- a/ports/litex/Makefile +++ b/ports/litex/Makefile @@ -117,7 +117,6 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_VALENTYUSB_EPTRI -DCFG_TUD_CDC_RX_BUFSIZE=1024 SRC_C += \ background.c \ - fatfs_port.c \ mphalport.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c diff --git a/ports/litex/fatfs_port.c b/ports/litex/fatfs_port.c deleted file mode 100644 index 631f7f0982..0000000000 --- a/ports/litex/fatfs_port.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ - -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" - -DWORD get_fattime(void) { - // TODO: Implement this function. For now, fake it. - return ((2016 - 1980) << 25) | ((12) << 21) | ((4) << 16) | ((00) << 11) | ((18) << 5) | (23 / 2); -} diff --git a/ports/mimxrt10xx/Makefile b/ports/mimxrt10xx/Makefile index 4b05c91714..291871f275 100644 --- a/ports/mimxrt10xx/Makefile +++ b/ports/mimxrt10xx/Makefile @@ -150,7 +150,6 @@ SRC_C += \ boards/$(BOARD)/board.c \ boards/$(BOARD)/flash_config.c \ boards/$(BOARD)/pins.c \ - fatfs_port.c \ lib/tinyusb/src/portable/chipidea/ci_hs/dcd_ci_hs.c \ mphalport.c \ peripherals/mimxrt10xx/$(CHIP_FAMILY)/clocks.c \ diff --git a/ports/mimxrt10xx/fatfs_port.c b/ports/mimxrt10xx/fatfs_port.c deleted file mode 100644 index 58a0ef0d72..0000000000 --- a/ports/mimxrt10xx/fatfs_port.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ - -#include "py/mphal.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" /* FatFs lower layer API */ -#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */ -#include "shared/timeutils/timeutils.h" - -#if CIRCUITPY_RTC -#include "shared-bindings/rtc/RTC.h" -#endif - -DWORD get_fattime(void) { - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif - - -} diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index bbe102ffc8..c792223a0b 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -165,7 +165,6 @@ endif SRC_C += \ background.c \ - fatfs_port.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \ diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index cb4c80a23d..9b9ae92322 100644 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -211,13 +211,15 @@ CFLAGS += \ -msoft-float \ -mfloat-abi=soft -PICO_LDFLAGS = --specs=nosys.specs -Wl,--wrap=__aeabi_ldiv0 -Wl,--wrap=__aeabi_idiv0 -Wl,--wrap=__aeabi_lmul -Wl,--wrap=__clzsi2 -Wl,--wrap=__clzdi2 -Wl,--wrap=__ctzsi2 -Wl,--wrap=__ctzdi2 -Wl,--wrap=__popcountsi2 -Wl,--wrap=__popcountdi2 -Wl,--wrap=__clz -Wl,--wrap=__clzl -Wl,--wrap=__clzll -Wl,--wrap=__aeabi_idiv -Wl,--wrap=__aeabi_idivmod -Wl,--wrap=__aeabi_ldivmod -Wl,--wrap=__aeabi_uidiv -Wl,--wrap=__aeabi_uidivmod -Wl,--wrap=__aeabi_uldivmod -Wl,--wrap=__aeabi_dadd -Wl,--wrap=__aeabi_ddiv -Wl,--wrap=__aeabi_dmul -Wl,--wrap=__aeabi_drsub -Wl,--wrap=__aeabi_dsub -Wl,--wrap=__aeabi_cdcmpeq -Wl,--wrap=__aeabi_cdrcmple -Wl,--wrap=__aeabi_cdcmple -Wl,--wrap=__aeabi_dcmpeq -Wl,--wrap=__aeabi_dcmplt -Wl,--wrap=__aeabi_dcmple -Wl,--wrap=__aeabi_dcmpge -Wl,--wrap=__aeabi_dcmpgt -Wl,--wrap=__aeabi_dcmpun -Wl,--wrap=__aeabi_i2d -Wl,--wrap=__aeabi_l2d -Wl,--wrap=__aeabi_ui2d -Wl,--wrap=__aeabi_ul2d -Wl,--wrap=__aeabi_d2iz -Wl,--wrap=__aeabi_d2lz -Wl,--wrap=__aeabi_d2uiz -Wl,--wrap=__aeabi_d2ulz -Wl,--wrap=__aeabi_d2f -Wl,--wrap=sqrt -Wl,--wrap=cos -Wl,--wrap=sin -Wl,--wrap=tan -Wl,--wrap=atan2 -Wl,--wrap=exp -Wl,--wrap=log -Wl,--wrap=ldexp -Wl,--wrap=copysign -Wl,--wrap=trunc -Wl,--wrap=floor -Wl,--wrap=ceil -Wl,--wrap=round -Wl,--wrap=sincos -Wl,--wrap=asin -Wl,--wrap=acos -Wl,--wrap=atan -Wl,--wrap=sinh -Wl,--wrap=cosh -Wl,--wrap=tanh -Wl,--wrap=asinh -Wl,--wrap=acosh -Wl,--wrap=atanh -Wl,--wrap=exp2 -Wl,--wrap=log2 -Wl,--wrap=exp10 -Wl,--wrap=log10 -Wl,--wrap=pow -Wl,--wrap=powint -Wl,--wrap=hypot -Wl,--wrap=cbrt -Wl,--wrap=fmod -Wl,--wrap=drem -Wl,--wrap=remainder -Wl,--wrap=remquo -Wl,--wrap=expm1 -Wl,--wrap=log1p -Wl,--wrap=fma -Wl,--wrap=__aeabi_fadd -Wl,--wrap=__aeabi_fdiv -Wl,--wrap=__aeabi_fmul -Wl,--wrap=__aeabi_frsub -Wl,--wrap=__aeabi_fsub -Wl,--wrap=__aeabi_cfcmpeq -Wl,--wrap=__aeabi_cfrcmple -Wl,--wrap=__aeabi_cfcmple -Wl,--wrap=__aeabi_fcmpeq -Wl,--wrap=__aeabi_fcmplt -Wl,--wrap=__aeabi_fcmple -Wl,--wrap=__aeabi_fcmpge -Wl,--wrap=__aeabi_fcmpgt -Wl,--wrap=__aeabi_fcmpun -Wl,--wrap=__aeabi_i2f -Wl,--wrap=__aeabi_l2f -Wl,--wrap=__aeabi_ui2f -Wl,--wrap=__aeabi_ul2f -Wl,--wrap=__aeabi_f2iz -Wl,--wrap=__aeabi_f2lz -Wl,--wrap=__aeabi_f2uiz -Wl,--wrap=__aeabi_f2ulz -Wl,--wrap=__aeabi_f2d -Wl,--wrap=sqrtf -Wl,--wrap=cosf -Wl,--wrap=sinf -Wl,--wrap=tanf -Wl,--wrap=atan2f -Wl,--wrap=expf -Wl,--wrap=logf -Wl,--wrap=ldexpf -Wl,--wrap=copysignf -Wl,--wrap=truncf -Wl,--wrap=floorf -Wl,--wrap=ceilf -Wl,--wrap=roundf -Wl,--wrap=sincosf -Wl,--wrap=asinf -Wl,--wrap=acosf -Wl,--wrap=atanf -Wl,--wrap=sinhf -Wl,--wrap=coshf -Wl,--wrap=tanhf -Wl,--wrap=asinhf -Wl,--wrap=acoshf -Wl,--wrap=atanhf -Wl,--wrap=exp2f -Wl,--wrap=log2f -Wl,--wrap=exp10f -Wl,--wrap=log10f -Wl,--wrap=powf -Wl,--wrap=powintf -Wl,--wrap=hypotf -Wl,--wrap=cbrtf -Wl,--wrap=fmodf -Wl,--wrap=dremf -Wl,--wrap=remainderf -Wl,--wrap=remquof -Wl,--wrap=expm1f -Wl,--wrap=log1pf -Wl,--wrap=fmaf -Wl,--wrap=memcpy -Wl,--wrap=memset -Wl,--wrap=__aeabi_memcpy -Wl,--wrap=__aeabi_memset -Wl,--wrap=__aeabi_memcpy4 -Wl,--wrap=__aeabi_memset4 -Wl,--wrap=__aeabi_memcpy8 -Wl,--wrap=__aeabi_memset8 +PICO_LDFLAGS = --specs=nosys.specs --specs=nano.specs -Wl,--wrap=__aeabi_ldiv0 -Wl,--wrap=__aeabi_idiv0 -Wl,--wrap=__aeabi_lmul -Wl,--wrap=__clzsi2 -Wl,--wrap=__clzdi2 -Wl,--wrap=__ctzsi2 -Wl,--wrap=__ctzdi2 -Wl,--wrap=__popcountsi2 -Wl,--wrap=__popcountdi2 -Wl,--wrap=__clz -Wl,--wrap=__clzl -Wl,--wrap=__clzll -Wl,--wrap=__aeabi_idiv -Wl,--wrap=__aeabi_idivmod -Wl,--wrap=__aeabi_ldivmod -Wl,--wrap=__aeabi_uidiv -Wl,--wrap=__aeabi_uidivmod -Wl,--wrap=__aeabi_uldivmod -Wl,--wrap=__aeabi_dadd -Wl,--wrap=__aeabi_ddiv -Wl,--wrap=__aeabi_dmul -Wl,--wrap=__aeabi_drsub -Wl,--wrap=__aeabi_dsub -Wl,--wrap=__aeabi_cdcmpeq -Wl,--wrap=__aeabi_cdrcmple -Wl,--wrap=__aeabi_cdcmple -Wl,--wrap=__aeabi_dcmpeq -Wl,--wrap=__aeabi_dcmplt -Wl,--wrap=__aeabi_dcmple -Wl,--wrap=__aeabi_dcmpge -Wl,--wrap=__aeabi_dcmpgt -Wl,--wrap=__aeabi_dcmpun -Wl,--wrap=__aeabi_i2d -Wl,--wrap=__aeabi_l2d -Wl,--wrap=__aeabi_ui2d -Wl,--wrap=__aeabi_ul2d -Wl,--wrap=__aeabi_d2iz -Wl,--wrap=__aeabi_d2lz -Wl,--wrap=__aeabi_d2uiz -Wl,--wrap=__aeabi_d2ulz -Wl,--wrap=__aeabi_d2f -Wl,--wrap=sqrt -Wl,--wrap=cos -Wl,--wrap=sin -Wl,--wrap=tan -Wl,--wrap=atan2 -Wl,--wrap=exp -Wl,--wrap=log -Wl,--wrap=ldexp -Wl,--wrap=copysign -Wl,--wrap=trunc -Wl,--wrap=floor -Wl,--wrap=ceil -Wl,--wrap=round -Wl,--wrap=sincos -Wl,--wrap=asin -Wl,--wrap=acos -Wl,--wrap=atan -Wl,--wrap=sinh -Wl,--wrap=cosh -Wl,--wrap=tanh -Wl,--wrap=asinh -Wl,--wrap=acosh -Wl,--wrap=atanh -Wl,--wrap=exp2 -Wl,--wrap=log2 -Wl,--wrap=exp10 -Wl,--wrap=log10 -Wl,--wrap=pow -Wl,--wrap=powint -Wl,--wrap=hypot -Wl,--wrap=cbrt -Wl,--wrap=fmod -Wl,--wrap=drem -Wl,--wrap=remainder -Wl,--wrap=remquo -Wl,--wrap=expm1 -Wl,--wrap=log1p -Wl,--wrap=fma -Wl,--wrap=__aeabi_fadd -Wl,--wrap=__aeabi_fdiv -Wl,--wrap=__aeabi_fmul -Wl,--wrap=__aeabi_frsub -Wl,--wrap=__aeabi_fsub -Wl,--wrap=__aeabi_cfcmpeq -Wl,--wrap=__aeabi_cfrcmple -Wl,--wrap=__aeabi_cfcmple -Wl,--wrap=__aeabi_fcmpeq -Wl,--wrap=__aeabi_fcmplt -Wl,--wrap=__aeabi_fcmple -Wl,--wrap=__aeabi_fcmpge -Wl,--wrap=__aeabi_fcmpgt -Wl,--wrap=__aeabi_fcmpun -Wl,--wrap=__aeabi_i2f -Wl,--wrap=__aeabi_l2f -Wl,--wrap=__aeabi_ui2f -Wl,--wrap=__aeabi_ul2f -Wl,--wrap=__aeabi_f2iz -Wl,--wrap=__aeabi_f2lz -Wl,--wrap=__aeabi_f2uiz -Wl,--wrap=__aeabi_f2ulz -Wl,--wrap=__aeabi_f2d -Wl,--wrap=sqrtf -Wl,--wrap=cosf -Wl,--wrap=sinf -Wl,--wrap=tanf -Wl,--wrap=atan2f -Wl,--wrap=expf -Wl,--wrap=logf -Wl,--wrap=ldexpf -Wl,--wrap=copysignf -Wl,--wrap=truncf -Wl,--wrap=floorf -Wl,--wrap=ceilf -Wl,--wrap=roundf -Wl,--wrap=sincosf -Wl,--wrap=asinf -Wl,--wrap=acosf -Wl,--wrap=atanf -Wl,--wrap=sinhf -Wl,--wrap=coshf -Wl,--wrap=tanhf -Wl,--wrap=asinhf -Wl,--wrap=acoshf -Wl,--wrap=atanhf -Wl,--wrap=exp2f -Wl,--wrap=log2f -Wl,--wrap=exp10f -Wl,--wrap=log10f -Wl,--wrap=powf -Wl,--wrap=powintf -Wl,--wrap=hypotf -Wl,--wrap=cbrtf -Wl,--wrap=fmodf -Wl,--wrap=dremf -Wl,--wrap=remainderf -Wl,--wrap=remquof -Wl,--wrap=expm1f -Wl,--wrap=log1pf -Wl,--wrap=fmaf -Wl,--wrap=memcpy -Wl,--wrap=memset -Wl,--wrap=__aeabi_memcpy -Wl,--wrap=__aeabi_memset -Wl,--wrap=__aeabi_memcpy4 -Wl,--wrap=__aeabi_memset4 -Wl,--wrap=__aeabi_memcpy8 -Wl,--wrap=__aeabi_memset8 # Use toolchain libm if we're not using our own. ifndef INTERNAL_LIBM LIBS += -lm endif +LIBS += -lc + SRC_SDK := \ src/common/pico_sync/critical_section.c \ src/common/pico_sync/lock_core.c \ @@ -270,7 +272,6 @@ SRC_C += \ background.c \ peripherals/pins.c \ lib/crypto-algorithms/sha256.c \ - fatfs_port.c \ lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c \ lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c \ mphalport.c \ @@ -441,7 +442,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(LINK_LD) $(STEPECHO) "LINK $@" $(Q)echo $(OBJ) > $(BUILD)/firmware.objs $(Q)echo $(PICO_LDFLAGS) > $(BUILD)/firmware.ldflags - $(Q)$(CC) -o $@ $(CFLAGS) @$(BUILD)/firmware.ldflags -Wl,-T,$(LINK_LD) -Wl,-Map=$@.map -Wl,-cref -Wl,--gc-sections @$(BUILD)/firmware.objs + $(Q)$(CC) -o $@ $(CFLAGS) @$(BUILD)/firmware.ldflags -Wl,-T,$(LINK_LD) -Wl,-Map=$@.map -Wl,-cref -Wl,--gc-sections @$(BUILD)/firmware.objs -Wl,-lc $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LINK_LD) $(BUILD)/firmware.bin: $(BUILD)/firmware.elf diff --git a/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk b/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk index 9773755649..f36fdd6ec7 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk +++ b/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk @@ -14,7 +14,7 @@ CIRCUITPY_CYW43 = 1 CIRCUITPY_SSL = 1 CIRCUITPY_SSL_MBEDTLS = 1 CIRCUITPY_HASHLIB = 1 -CIRCUITPY_WEB_WORKFLOW = 0 +CIRCUITPY_WEB_WORKFLOW = 1 CIRCUITPY_MDNS = 0 CIRCUITPY_SOCKETPOOL = 1 CIRCUITPY_WIFI = 1 diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.c b/ports/raspberrypi/common-hal/socketpool/Socket.c index 440fe56d42..be3f2cd087 100644 --- a/ports/raspberrypi/common-hal/socketpool/Socket.c +++ b/ports/raspberrypi/common-hal/socketpool/Socket.c @@ -166,6 +166,7 @@ static inline void exec_user_callback(socketpool_socket_obj_t *socket) { mp_sched_schedule(socket->callback, MP_OBJ_FROM_PTR(socket)); } #endif + supervisor_workflow_request_background(); } #if MICROPY_PY_LWIP_SOCK_RAW @@ -745,57 +746,47 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_ return socket; } -int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port) { - return -MP_EBADF; -} - -socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *socket, - uint8_t *ip, uint32_t *port) { - if (socket->type != MOD_NETWORK_SOCK_STREAM) { - mp_raise_OSError(MP_EOPNOTSUPP); +int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port, socketpool_socket_obj_t *accepted) { + if (self->type != MOD_NETWORK_SOCK_STREAM) { + return -MP_EOPNOTSUPP; } - // Create new socket object, do it here because we must not raise an out-of-memory - // exception when the LWIP concurrency lock is held - socketpool_socket_obj_t *socket2 = m_new_ll_obj_with_finaliser(socketpool_socket_obj_t); - socket2->base.type = &socketpool_socket_type; + if (common_hal_socketpool_socket_get_closed(self)) { + return -MP_EBADF; + } MICROPY_PY_LWIP_ENTER - if (socket->pcb.tcp == NULL) { + if (self->pcb.tcp == NULL) { MICROPY_PY_LWIP_EXIT - m_del_obj(socketpool_socket_obj_t, socket2); - mp_raise_OSError(MP_EBADF); + return -MP_EBADF; } // I need to do this because "tcp_accepted", later, is a macro. - struct tcp_pcb *listener = socket->pcb.tcp; + struct tcp_pcb *listener = self->pcb.tcp; if (listener->state != LISTEN) { MICROPY_PY_LWIP_EXIT - m_del_obj(socketpool_socket_obj_t, socket2); - mp_raise_OSError(MP_EINVAL); + return -MP_EINVAL; } // accept incoming connection - struct tcp_pcb *volatile *incoming_connection = &lwip_socket_incoming_array(socket)[socket->incoming.connection.iget]; + struct tcp_pcb *volatile *incoming_connection = &lwip_socket_incoming_array(self)[self->incoming.connection.iget]; if (*incoming_connection == NULL) { - if (socket->timeout == 0) { + if (self->timeout == 0) { MICROPY_PY_LWIP_EXIT - m_del_obj(socketpool_socket_obj_t, socket2); - mp_raise_OSError(MP_EAGAIN); - } else if (socket->timeout != (unsigned)-1) { - mp_uint_t retries = socket->timeout / 100; - while (*incoming_connection == NULL) { + return -MP_EAGAIN; + } else if (self->timeout != (unsigned)-1) { + mp_uint_t retries = self->timeout / 100; + while (*incoming_connection == NULL && !mp_hal_is_interrupted()) { MICROPY_PY_LWIP_EXIT if (retries-- == 0) { - m_del_obj(socketpool_socket_obj_t, socket2); - mp_raise_OSError(MP_ETIMEDOUT); + return -MP_ETIMEDOUT; } mp_hal_delay_ms(100); MICROPY_PY_LWIP_REENTER } } else { - while (*incoming_connection == NULL) { + while (*incoming_connection == NULL && !mp_hal_is_interrupted()) { MICROPY_PY_LWIP_EXIT poll_sockets(); MICROPY_PY_LWIP_REENTER @@ -803,43 +794,75 @@ socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_o } } + if (*incoming_connection == NULL) { + // We were interrupted. + return 0; + } + + // Close the accepted socket because we have another we accepted. + if (!common_hal_socketpool_socket_get_closed(accepted)) { + common_hal_socketpool_socket_close(accepted); + } + // We get a new pcb handle... - socket2->pcb.tcp = *incoming_connection; - if (++socket->incoming.connection.iget >= socket->incoming.connection.alloc) { - socket->incoming.connection.iget = 0; + accepted->pcb.tcp = *incoming_connection; + if (++self->incoming.connection.iget >= self->incoming.connection.alloc) { + self->incoming.connection.iget = 0; } *incoming_connection = NULL; // ...and set up the new socket for it. - socket2->domain = MOD_NETWORK_AF_INET; - socket2->type = MOD_NETWORK_SOCK_STREAM; - socket2->incoming.pbuf = NULL; - socket2->timeout = socket->timeout; - socket2->state = STATE_CONNECTED; - socket2->recv_offset = 0; - socket2->callback = MP_OBJ_NULL; - tcp_arg(socket2->pcb.tcp, (void *)socket2); - tcp_err(socket2->pcb.tcp, _lwip_tcp_error); - tcp_recv(socket2->pcb.tcp, _lwip_tcp_recv); + accepted->domain = MOD_NETWORK_AF_INET; + accepted->type = MOD_NETWORK_SOCK_STREAM; + accepted->incoming.pbuf = NULL; + accepted->timeout = self->timeout; + accepted->state = STATE_CONNECTED; + accepted->recv_offset = 0; + accepted->callback = MP_OBJ_NULL; + tcp_arg(accepted->pcb.tcp, (void *)accepted); + tcp_err(accepted->pcb.tcp, _lwip_tcp_error); + tcp_recv(accepted->pcb.tcp, _lwip_tcp_recv); tcp_accepted(listener); MICROPY_PY_LWIP_EXIT + // output values + memcpy(ip, &(accepted->pcb.tcp->remote_ip), NETUTILS_IPV4ADDR_BUFSIZE); + *port = (mp_uint_t)accepted->pcb.tcp->remote_port; + + return 1; +} + +socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *socket, + uint8_t *ip, uint32_t *port) { + // Create new socket object, do it here because we must not raise an out-of-memory + // exception when the LWIP concurrency lock is held + socketpool_socket_obj_t *accepted = m_new_ll_obj_with_finaliser(socketpool_socket_obj_t); + socketpool_socket_reset(accepted); + + int ret = socketpool_socket_accept(socket, ip, port, accepted); + + if (ret <= 0) { + m_del_obj(socketpool_socket_obj_t, accepted); + if (ret == 0) { + // Interrupted. + return mp_const_none; + } + mp_raise_OSError(-ret); + } + DEBUG_printf("registering socket in socketpool_socket_accept()\n"); - if (!register_open_socket(socket2)) { + if (!register_open_socket(accepted)) { DEBUG_printf("collecting garbage to open socket\n"); gc_collect(); - if (!register_open_socket(socket2)) { + if (!register_open_socket(accepted)) { mp_raise_RuntimeError(translate("Out of sockets")); } } - mark_user_socket(socket2); + mark_user_socket(accepted); - // output values - memcpy(ip, &(socket2->pcb.tcp->remote_ip), NETUTILS_IPV4ADDR_BUFSIZE); - *port = (mp_uint_t)socket2->pcb.tcp->remote_port; - return MP_OBJ_FROM_PTR(socket2); + return MP_OBJ_FROM_PTR(accepted); } bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t *socket, @@ -847,21 +870,26 @@ bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t *socket, // get address ip_addr_t bind_addr; - int error = socketpool_resolve_host(socket->pool, host, &bind_addr); - if (error != 0) { - mp_raise_OSError(EHOSTUNREACH); - } + const ip_addr_t *bind_addr_ptr = &bind_addr; + if (hostlen > 0) { + int error = socketpool_resolve_host(socket->pool, host, &bind_addr); + if (error != 0) { + mp_raise_OSError(EHOSTUNREACH); + } + } else { + bind_addr_ptr = IP_ANY_TYPE; + } ip_set_option(socket->pcb.ip, SOF_REUSEADDR); err_t err = ERR_ARG; switch (socket->type) { case MOD_NETWORK_SOCK_STREAM: { - err = tcp_bind(socket->pcb.tcp, &bind_addr, port); + err = tcp_bind(socket->pcb.tcp, bind_addr_ptr, port); break; } case MOD_NETWORK_SOCK_DGRAM: { - err = udp_bind(socket->pcb.udp, &bind_addr, port); + err = udp_bind(socket->pcb.udp, bind_addr_ptr, port); break; } } @@ -1164,6 +1192,20 @@ void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint self->timeout = timeout_ms; } +int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int level, int optname, const void *value, size_t optlen) { + if (level == SOCKETPOOL_IPPROTO_TCP && optname == SOCKETPOOL_TCP_NODELAY) { + int one = 1; + bool enable = optlen == sizeof(&one) && memcmp(value, &one, optlen); + if (enable) { + tcp_set_flags(self->pcb.tcp, TF_NODELAY); + } else { + tcp_clear_flags(self->pcb.tcp, TF_NODELAY); + } + return 0; + } + return -MP_EOPNOTSUPP; +} + bool common_hal_socketpool_readable(socketpool_socket_obj_t *self) { MICROPY_PY_LWIP_ENTER; @@ -1206,3 +1248,32 @@ bool common_hal_socketpool_writable(socketpool_socket_obj_t *self) { return result; } + +void socketpool_socket_move(socketpool_socket_obj_t *self, socketpool_socket_obj_t *sock) { + *sock = *self; + self->state = _ERR_BADF; + + // Reregister the callbacks with the new socket copy. + MICROPY_PY_LWIP_ENTER; + + tcp_arg(self->pcb.tcp, NULL); + tcp_err(self->pcb.tcp, NULL); + tcp_recv(self->pcb.tcp, NULL); + + self->pcb.tcp = NULL; + + tcp_arg(sock->pcb.tcp, (void *)sock); + tcp_err(sock->pcb.tcp, _lwip_tcp_error); + tcp_recv(sock->pcb.tcp, _lwip_tcp_recv); + + MICROPY_PY_LWIP_EXIT; +} + +void socketpool_socket_reset(socketpool_socket_obj_t *self) { + if (self->base.type == &socketpool_socket_type) { + return; + } + self->base.type = &socketpool_socket_type; + self->pcb.tcp = NULL; + self->state = _ERR_BADF; +} diff --git a/ports/raspberrypi/common-hal/wifi/Radio.c b/ports/raspberrypi/common-hal/wifi/Radio.c index 2a74c16e0a..cb3fc258af 100644 --- a/ports/raspberrypi/common-hal/wifi/Radio.c +++ b/ports/raspberrypi/common-hal/wifi/Radio.c @@ -73,13 +73,12 @@ NORETURN static void ro_attribute(int attr) { } bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self) { - return true; + return self->enabled; } void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) { - if (!enabled) { - ro_attribute(MP_QSTR_enabled); - } + self->enabled = enabled; + // TODO: Actually enable and disable the WiFi module at this point. } mp_obj_t common_hal_wifi_radio_get_hostname(wifi_radio_obj_t *self) { @@ -242,6 +241,13 @@ mp_obj_t common_hal_wifi_radio_get_ipv4_subnet_ap(wifi_radio_obj_t *self) { return common_hal_ipaddress_new_ipv4address(NETIF_AP->netmask.addr); } +uint32_t wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) { + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_UP) { + return 0; + } + return NETIF_STA->ip_addr.addr; +} + mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) { if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_UP) { return mp_const_none; diff --git a/ports/raspberrypi/common-hal/wifi/Radio.h b/ports/raspberrypi/common-hal/wifi/Radio.h index 0dc18c8957..b2e9df9e3a 100644 --- a/ports/raspberrypi/common-hal/wifi/Radio.h +++ b/ports/raspberrypi/common-hal/wifi/Radio.h @@ -35,6 +35,7 @@ typedef struct { mp_obj_base_t base; char hostname[254]; // hostname max is 253 chars, + 1 for trailing NUL wifi_scannednetworks_obj_t *current_scan; + bool enabled; } wifi_radio_obj_t; extern void common_hal_wifi_radio_gc_collect(wifi_radio_obj_t *self); diff --git a/ports/raspberrypi/fatfs_port.c b/ports/raspberrypi/fatfs_port.c deleted file mode 100644 index 58a0ef0d72..0000000000 --- a/ports/raspberrypi/fatfs_port.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ - -#include "py/mphal.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" /* FatFs lower layer API */ -#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */ -#include "shared/timeutils/timeutils.h" - -#if CIRCUITPY_RTC -#include "shared-bindings/rtc/RTC.h" -#endif - -DWORD get_fattime(void) { - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif - - -} diff --git a/ports/stm/Makefile b/ports/stm/Makefile index cd37a9bda0..b69f8370c5 100755 --- a/ports/stm/Makefile +++ b/ports/stm/Makefile @@ -221,7 +221,6 @@ SRC_STM32 += boards/system_stm32$(MCU_SERIES_LOWER)xx.c SRC_C += \ background.c \ - fatfs_port.c \ mphalport.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ diff --git a/ports/stm/fatfs_port.c b/ports/stm/fatfs_port.c deleted file mode 100644 index 631f7f0982..0000000000 --- a/ports/stm/fatfs_port.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * - * 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. - */ - -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" - -DWORD get_fattime(void) { - // TODO: Implement this function. For now, fake it. - return ((2016 - 1980) << 25) | ((12) << 21) | ((4) << 16) | ((00) << 11) | ((18) << 5) | (23 / 2); -} diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index 7a60463c4b..fbf78a4cdc 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -344,38 +344,36 @@ STATIC mp_obj_t socketpool_socket_setblocking(mp_obj_t self_in, mp_obj_t blockin } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_setblocking_obj, socketpool_socket_setblocking); -// //| def setsockopt(self, level: int, optname: int, value: int) -> None: -// //| """Sets socket options""" -// //| ... -// //| -// STATIC mp_obj_t socketpool_socket_setsockopt(size_t n_args, const mp_obj_t *args) { -// // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); +//| def setsockopt(self, level: int, optname: int, value: int) -> None: +//| """Sets socket options""" +//| ... +STATIC mp_obj_t socketpool_socket_setsockopt(size_t n_args, const mp_obj_t *args) { + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); + mp_int_t level = mp_obj_get_int(args[1]); + mp_int_t opt = mp_obj_get_int(args[2]); -// // mp_int_t level = mp_obj_get_int(args[1]); -// // mp_int_t opt = mp_obj_get_int(args[2]); + const void *optval; + mp_uint_t optlen; + mp_int_t val; + if (mp_obj_is_integer(args[3])) { + val = mp_obj_get_int_truncated(args[3]); + optval = &val; + optlen = sizeof(val); + } else { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); + optval = bufinfo.buf; + optlen = bufinfo.len; + } -// // const void *optval; -// // mp_uint_t optlen; -// // mp_int_t val; -// // if (mp_obj_is_integer(args[3])) { -// // val = mp_obj_get_int_truncated(args[3]); -// // optval = &val; -// // optlen = sizeof(val); -// // } else { -// // mp_buffer_info_t bufinfo; -// // mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); -// // optval = bufinfo.buf; -// // optlen = bufinfo.len; -// // } + int _errno = common_hal_socketpool_socket_setsockopt(self, level, opt, optval, optlen); + if (_errno < 0) { + mp_raise_OSError(-_errno); + } -// // int _errno; -// // if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) { -// // mp_raise_OSError(_errno); -// // } - -// return mp_const_none; -// } -// STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, 4, socketpool_socket_setsockopt); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, 4, socketpool_socket_setsockopt); //| def settimeout(self, value: int) -> None: @@ -417,7 +415,7 @@ STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { { 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) }, + { 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) }, }; diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h index cf5a97a428..690c9f8363 100644 --- a/shared-bindings/socketpool/Socket.h +++ b/shared-bindings/socketpool/Socket.h @@ -46,13 +46,22 @@ mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t *self, const mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t *self, const char *host, size_t hostlen, uint32_t port, const uint8_t *buf, uint32_t len); void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint32_t timeout_ms); +int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int level, int optname, const void *value, size_t optlen); bool common_hal_socketpool_readable(socketpool_socket_obj_t *self); bool common_hal_socketpool_writable(socketpool_socket_obj_t *self); // Non-allocating versions for internal use. -int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port); +int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port, socketpool_socket_obj_t *accepted); void socketpool_socket_close(socketpool_socket_obj_t *self); int socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len); int socketpool_socket_recv_into(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len); + +// Moves self to sock without closing the real socket. self will think its closed afterwards. +void socketpool_socket_move(socketpool_socket_obj_t *self, socketpool_socket_obj_t *sock); + +// Resets the socket object state so it appears closed and disconnected. This only works on +// uninitialized memory. +void socketpool_socket_reset(socketpool_socket_obj_t *self); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H diff --git a/shared-bindings/socketpool/SocketPool.c b/shared-bindings/socketpool/SocketPool.c index e500784f1f..278288fa7e 100644 --- a/shared-bindings/socketpool/SocketPool.c +++ b/shared-bindings/socketpool/SocketPool.c @@ -52,7 +52,6 @@ //| returned by :py:attr:`wifi.radio` //| """ //| ... - STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); @@ -65,12 +64,6 @@ STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t return MP_OBJ_FROM_PTR(s); } -//| AF_INET: int -//| AF_INET6: int -//| SOCK_STREAM: int -//| SOCK_DGRAM: int -//| SOCK_RAW: int -//| //| def socket(self, family: int = AF_INET, type: int = SOCK_STREAM) -> socketpool.Socket: //| """Create a new socket //| @@ -114,7 +107,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(socketpool_socketpool_socket_obj, 1, socketpool_socke //| address information to call socket.socket() and socket.connect() with, //| as a tuple.""" //| ... -//| STATIC mp_obj_t socketpool_socketpool_getaddrinfo(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_host, ARG_port, ARG_family, ARG_type, ARG_proto, ARG_flags }; static const mp_arg_t allowed_args[] = { @@ -164,12 +156,28 @@ STATIC const mp_rom_map_elem_t socketpool_socketpool_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&socketpool_socketpool_getaddrinfo_obj) }, // class constants +//| AF_INET: int { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(SOCKETPOOL_AF_INET) }, +//| AF_INET6: int { MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(SOCKETPOOL_AF_INET6) }, +//| +//| SOCK_STREAM: int { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(SOCKETPOOL_SOCK_STREAM) }, +//| SOCK_DGRAM: int { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(SOCKETPOOL_SOCK_DGRAM) }, +//| SOCK_RAW: int { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(SOCKETPOOL_SOCK_RAW) }, +//| + +//| TCP_NODELAY: int + { MP_ROM_QSTR(MP_QSTR_TCP_NODELAY), MP_ROM_INT(SOCKETPOOL_TCP_NODELAY) }, +//| + +//| IPPROTO_TCP: int +//| + { MP_ROM_QSTR(MP_QSTR_IPPROTO_TCP), MP_ROM_INT(SOCKETPOOL_IPPROTO_TCP) }, +//| }; STATIC MP_DEFINE_CONST_DICT(socketpool_socketpool_locals_dict, socketpool_socketpool_locals_dict_table); diff --git a/shared-bindings/socketpool/SocketPool.h b/shared-bindings/socketpool/SocketPool.h index 92382078e1..5a2d9f4337 100644 --- a/shared-bindings/socketpool/SocketPool.h +++ b/shared-bindings/socketpool/SocketPool.h @@ -34,16 +34,24 @@ extern const mp_obj_type_t socketpool_socketpool_type; typedef enum { - SOCKETPOOL_SOCK_STREAM, - SOCKETPOOL_SOCK_DGRAM, - SOCKETPOOL_SOCK_RAW + SOCKETPOOL_SOCK_STREAM = 1, + SOCKETPOOL_SOCK_DGRAM = 2, + SOCKETPOOL_SOCK_RAW = 3 } socketpool_socketpool_sock_t; typedef enum { - SOCKETPOOL_AF_INET, - SOCKETPOOL_AF_INET6 + SOCKETPOOL_AF_INET = 2, + SOCKETPOOL_AF_INET6 = 10 } socketpool_socketpool_addressfamily_t; +typedef enum { + SOCKETPOOL_IPPROTO_TCP = 6, +} socketpool_socketpool_ipproto_t; + +typedef enum { + SOCKETPOOL_TCP_NODELAY = 1, +} socketpool_socketpool_tcpopt_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/supervisor/fatfs_port.h b/supervisor/fatfs.h similarity index 89% rename from supervisor/fatfs_port.h rename to supervisor/fatfs.h index e76ced524d..59226aae1c 100644 --- a/supervisor/fatfs_port.h +++ b/supervisor/fatfs.h @@ -24,11 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SUPERVISOR_FATFS_PORT_H -#define MICROPY_INCLUDED_SUPERVISOR_FATFS_PORT_H +#ifndef MICROPY_INCLUDED_SUPERVISOR_FATFS_H +#define MICROPY_INCLUDED_SUPERVISOR_FATFS_H #include "lib/oofatfs/ff.h" void override_fattime(DWORD time); -#endif // MICROPY_INCLUDED_SUPERVISOR_FATFS_PORT_H +#endif // MICROPY_INCLUDED_SUPERVISOR_FATFS_H diff --git a/supervisor/shared/bluetooth/file_transfer.c b/supervisor/shared/bluetooth/file_transfer.c index 159c639e4d..ae24c29899 100644 --- a/supervisor/shared/bluetooth/file_transfer.c +++ b/supervisor/shared/bluetooth/file_transfer.c @@ -42,7 +42,7 @@ #include "common-hal/_bleio/__init__.h" -#include "supervisor/fatfs_port.h" +#include "supervisor/fatfs.h" #include "supervisor/filesystem.h" #include "supervisor/shared/reload.h" #include "supervisor/shared/bluetooth/file_transfer.h" diff --git a/ports/nrf/fatfs_port.c b/supervisor/shared/fatfs.c similarity index 94% rename from ports/nrf/fatfs_port.c rename to supervisor/shared/fatfs.c index 38c2d923b8..76db02d6bf 100644 --- a/ports/nrf/fatfs_port.c +++ b/supervisor/shared/fatfs.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2022 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 @@ -24,12 +24,13 @@ * THE SOFTWARE. */ +#include "supervisor/fatfs.h" + #include "py/runtime.h" #include "lib/oofatfs/ff.h" #include "shared/timeutils/timeutils.h" #include "shared-bindings/rtc/RTC.h" #include "shared-bindings/time/__init__.h" -#include "supervisor/fatfs_port.h" DWORD _time_override = 0; DWORD get_fattime(void) { diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index 3f0b9ad8f7..2d6025b6aa 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -24,18 +24,20 @@ * THE SOFTWARE. */ +#include #include #include "extmod/vfs.h" #include "extmod/vfs_fat.h" #include "genhdr/mpversion.h" +#include "py/mperrno.h" #include "py/mpstate.h" #include "py/stackctrl.h" #include "shared-bindings/wifi/Radio.h" #include "shared-module/storage/__init__.h" #include "shared/timeutils/timeutils.h" -#include "supervisor/fatfs_port.h" +#include "supervisor/fatfs.h" #include "supervisor/filesystem.h" #include "supervisor/port.h" #include "supervisor/shared/reload.h" @@ -47,8 +49,12 @@ #include "shared-bindings/hashlib/__init__.h" #include "shared-bindings/hashlib/Hash.h" + +#if CIRCUITPY_MDNS #include "shared-bindings/mdns/RemoteService.h" #include "shared-bindings/mdns/Server.h" +#endif + #include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/socketpool/__init__.h" #include "shared-bindings/socketpool/Socket.h" @@ -62,11 +68,6 @@ #include "shared-module/dotenv/__init__.h" #endif -// TODO: Remove ESP specific stuff. For now, it is useful as we refine the server. -#include "esp_log.h" - -static const char *TAG = "CP webserver"; - enum request_state { STATE_METHOD, STATE_PATH, @@ -95,6 +96,7 @@ typedef struct { bool expect; bool json; bool websocket; + bool new_socket; uint32_t websocket_version; // RFC6455 for websockets says this header should be 24 base64 characters long. char websocket_key[24 + 1]; @@ -109,7 +111,10 @@ static uint32_t _last_ip = 0; static wifi_radio_error_t _last_wifi_status = WIFI_RADIO_ERROR_NONE; #endif +#if CIRCUITPY_MDNS static mdns_server_obj_t mdns; +#endif + static uint32_t web_api_port = 80; static socketpool_socketpool_obj_t pool; @@ -271,7 +276,7 @@ void supervisor_start_web_workflow(void) { // attempting to connect to the given network. _wifi_status = common_hal_wifi_radio_connect( &common_hal_wifi_radio_obj, (uint8_t *)ssid, ssid_len, (uint8_t *)password, password_len, - 0, 0.1, NULL, 0); + 0, 8, NULL, 0); if (_wifi_status != WIFI_RADIO_ERROR_NONE) { common_hal_wifi_radio_set_enabled(&common_hal_wifi_radio_obj, false); @@ -289,21 +294,20 @@ void supervisor_start_web_workflow(void) { new_port = strtoul(port_encoded, NULL, 10); } - bool first_start = mdns.base.type != &mdns_server_type; + bool first_start = pool.base.type != &socketpool_socketpool_type; bool port_changed = new_port != web_api_port; if (first_start) { - ESP_LOGI(TAG, "Starting web workflow"); + #if CIRCUITPY_MDNS mdns_server_construct(&mdns, true); mdns.base.type = &mdns_server_type; common_hal_mdns_server_set_instance_name(&mdns, MICROPY_HW_BOARD_NAME); + #endif pool.base.type = &socketpool_socketpool_type; common_hal_socketpool_socketpool_construct(&pool, &common_hal_wifi_radio_obj); - listening.base.type = &socketpool_socket_type; - active.base.type = &socketpool_socket_type; - active.num = -1; - active.connected = false; + socketpool_socket_reset(&listening); + socketpool_socket_reset(&active); websocket_init(); } @@ -312,7 +316,9 @@ void supervisor_start_web_workflow(void) { } if (first_start || port_changed) { web_api_port = new_port; + #if CIRCUITPY_MDNS common_hal_mdns_server_advertise_service(&mdns, "_circuitpython", "_tcp", web_api_port); + #endif socketpool_socket(&pool, SOCKETPOOL_AF_INET, SOCKETPOOL_SOCK_STREAM, &listening); common_hal_socketpool_socket_settimeout(&listening, 0); // Bind to any ip. @@ -326,17 +332,13 @@ void supervisor_start_web_workflow(void) { _api_password[api_password_len + 1] = '\0'; _base64_in_place(_api_password, api_password_len + 1, sizeof(_api_password)); } - - // TODO: - // GET /edit/ - // - Super basic editor #endif } void web_workflow_send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) { int total_sent = 0; - int sent = -EAGAIN; - while ((sent == -EAGAIN || (sent > 0 && total_sent < len)) && + int sent = -MP_EAGAIN; + while ((sent == -MP_EAGAIN || (sent > 0 && total_sent < len)) && common_hal_socketpool_socket_get_connected(socket)) { sent = socketpool_socket_send(socket, buf + total_sent, len - total_sent); if (sent > 0) { @@ -347,9 +349,6 @@ void web_workflow_send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, } } } - if (total_sent < len) { - ESP_LOGE(TAG, "short send %d %d", sent, len); - } } STATIC void _print_raw(void *env, const char *str, size_t len) { @@ -436,13 +435,15 @@ const char *ok_hosts[] = { static bool _origin_ok(const char *origin) { const char *http = "http://"; - const char *local = ".local"; // note: redirected requests send an Origin of "null" and will be caught by this if (strncmp(origin, http, strlen(http)) != 0) { return false; } // These are prefix checks up to : so that any port works. + // TODO: Support DHCP hostname in addition to MDNS. + #if CIRCUITPY_MDNS + const char *local = ".local"; const char *hostname = common_hal_mdns_server_get_hostname(&mdns); const char *end = origin + strlen(http) + strlen(hostname) + strlen(local); if (strncmp(origin + strlen(http), hostname, strlen(hostname)) == 0 && @@ -450,6 +451,9 @@ static bool _origin_ok(const char *origin) { (end[0] == '\0' || end[0] == ':')) { return true; } + #else + const char *end; + #endif _update_encoded_ip(); end = origin + strlen(http) + strlen(_our_ip_encoded); @@ -604,9 +608,10 @@ static void _reply_server_error(socketpool_socket_obj_t *socket, _request *reque _send_str(socket, "\r\n"); } +#if CIRCUITPY_MDNS static void _reply_redirect(socketpool_socket_obj_t *socket, _request *request, const char *path) { int nodelay = 1; - lwip_setsockopt(socket->num, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)); + common_hal_socketpool_socket_setsockopt(socket, SOCKETPOOL_IPPROTO_TCP, SOCKETPOOL_TCP_NODELAY, &nodelay, sizeof(nodelay)); const char *hostname = common_hal_mdns_server_get_hostname(&mdns); _send_strs(socket, "HTTP/1.1 307 Temporary Redirect\r\n", @@ -628,6 +633,7 @@ static void _reply_redirect(socketpool_socket_obj_t *socket, _request *request, _cors_header(socket, request); _send_str(socket, "\r\n"); } +#endif static void _reply_directory_json(socketpool_socket_obj_t *socket, _request *request, FF_DIR *dir, const char *request_path, const char *path) { socketpool_socket_send(socket, (const uint8_t *)OK_JSON, strlen(OK_JSON)); @@ -710,10 +716,9 @@ static void _reply_with_file(socketpool_socket_obj_t *socket, _request *request, while (send_offset < quantity_read) { int sent = socketpool_socket_send(socket, data_buffer + send_offset, quantity_read - send_offset); if (sent < 0) { - if (sent == -EAGAIN) { + if (sent == -MP_EAGAIN) { sent = 0; } else { - ESP_LOGE(TAG, "file send error %d", sent); break; } } @@ -726,15 +731,20 @@ static void _reply_with_file(socketpool_socket_obj_t *socket, _request *request, } static void _reply_with_devices_json(socketpool_socket_obj_t *socket, _request *request) { + #if CIRCUITPY_MDNS mdns_remoteservice_obj_t found_devices[32]; size_t total_results = mdns_server_find(&mdns, "_circuitpython", "_tcp", 1, found_devices, MP_ARRAY_SIZE(found_devices)); size_t count = MIN(total_results, MP_ARRAY_SIZE(found_devices)); + #else + size_t total_results = 0; + #endif socketpool_socket_send(socket, (const uint8_t *)OK_JSON, strlen(OK_JSON)); _cors_header(socket, request); _send_str(socket, "\r\n"); mp_print_t _socket_print = {socket, _print_chunk}; mp_printf(&_socket_print, "{\"total\": %d, \"devices\": [", total_results); + #if CIRCUITPY_MDNS for (size_t i = 0; i < count; i++) { if (i > 0) { _send_chunk(socket, ","); @@ -751,6 +761,7 @@ static void _reply_with_devices_json(socketpool_socket_obj_t *socket, _request * "\"ip\": \"%d.%d.%d.%d\"}", hostname, instance_name, port, octets[0], octets[1], octets[2], octets[3]); common_hal_mdns_remoteservice_deinit(&found_devices[i]); } + #endif _send_chunk(socket, "]}"); // Empty chunk signals the end of the response. _send_chunk(socket, ""); @@ -762,7 +773,11 @@ static void _reply_with_version_json(socketpool_socket_obj_t *socket, _request * _send_str(socket, "\r\n"); mp_print_t _socket_print = {socket, _print_chunk}; + #if CIRCUITPY_MDNS const char *hostname = common_hal_mdns_server_get_hostname(&mdns); + #else + const char *hostname = ""; + #endif _update_encoded_ip(); // Note: this leverages the fact that C concats consecutive string literals together. mp_printf(&_socket_print, @@ -848,7 +863,6 @@ static void _write_file_and_reply(socketpool_socket_obj_t *socket, _request *req return; } if (result != FR_OK) { - ESP_LOGE(TAG, "file write error %d %s", result, path); override_fattime(0); #if CIRCUITPY_USB_MSC usb_msc_unlock(); @@ -888,19 +902,13 @@ static void _write_file_and_reply(socketpool_socket_obj_t *socket, _request *req size_t read_len = MIN(sizeof(bytes), request->content_length - total_read); int len = socketpool_socket_recv_into(socket, bytes, read_len); if (len < 0) { - if (len == -EAGAIN) { + if (len == -MP_EAGAIN) { continue; - } else { - ESP_LOGE(TAG, "other error %d", len); } error = true; break; } - UINT actual; - f_write(&active_file, bytes, len, &actual); - if (actual != (UINT)len) { - ESP_LOGE(TAG, "didn't write whole file"); - } + f_write(&active_file, bytes, len, NULL); total_read += len; } @@ -934,7 +942,7 @@ STATIC_FILE(blinka_16x16_ico); static void _reply_static(socketpool_socket_obj_t *socket, _request *request, const uint8_t *response, size_t response_len, const char *content_type) { uint32_t total_length = response_len; char encoded_len[10]; - snprintf(encoded_len, sizeof(encoded_len), "%d", total_length); + snprintf(encoded_len, sizeof(encoded_len), "%" PRIu32, total_length); _send_strs(socket, "HTTP/1.1 200 OK\r\n", @@ -1004,9 +1012,10 @@ static void _decode_percents(char *str) { static bool _reply(socketpool_socket_obj_t *socket, _request *request) { if (request->redirect) { + #if CIRCUITPY_MDNS _reply_redirect(socket, request, request->path); + #endif } else if (strlen(request->origin) > 0 && !_origin_ok(request->origin)) { - ESP_LOGE(TAG, "bad origin %s", request->origin); _reply_forbidden(socket, request); } else if (strncmp(request->path, "/fs/", 4) == 0) { if (strcasecmp(request->method, "OPTIONS") == 0) { @@ -1061,7 +1070,6 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { if (result == FR_NO_PATH || result == FR_NO_FILE) { _reply_missing(socket, request); } else if (result != FR_OK) { - ESP_LOGE(TAG, "rm error %d %s", result, path); _reply_server_error(socket, request); } else { _reply_no_content(socket, request); @@ -1089,7 +1097,6 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { } else if (result == FR_NO_PATH || result == FR_NO_FILE) { // Missing higher directories or target file. _reply_missing(socket, request); } else if (result != FR_OK) { - ESP_LOGE(TAG, "move error %d %s", result, path); _reply_server_error(socket, request); } else { _reply_created(socket, request); @@ -1137,7 +1144,6 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { } else if (result == FR_NO_PATH) { _reply_missing(socket, request); } else if (result != FR_OK) { - ESP_LOGE(TAG, "mkdir error %d %s", result, path); _reply_server_error(socket, request); } else { _reply_created(socket, request); @@ -1237,6 +1243,7 @@ static void _reset_request(_request *request) { request->redirect = false; request->done = false; request->in_progress = false; + request->new_socket = false; request->authenticated = false; request->expect = false; request->json = false; @@ -1257,6 +1264,7 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) if (!request->in_progress) { autoreload_suspend(AUTORELOAD_SUSPEND_WEB); request->in_progress = true; + request->new_socket = false; } switch (request->state) { case STATE_METHOD: { @@ -1276,7 +1284,6 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) if (c == ' ') { request->path[request->offset] = '\0'; request->offset = 0; - ESP_LOGI(TAG, "Request %s %s", request->method, request->path); request->state = STATE_VERSION; } else if (request->offset > sizeof(request->path) - 1) { // Skip methods that are too long. @@ -1352,7 +1359,6 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) } else if (strcasecmp(request->header_key, "X-Destination") == 0) { strcpy(request->destination, request->header_value); } - ESP_LOGI(TAG, "Header %s %s", request->header_key, request->header_value); } else if (request->offset > sizeof(request->header_value) - 1) { // Skip methods that are too long. } else { @@ -1369,8 +1375,9 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) } if (error) { const char *error_response = "HTTP/1.1 501 Not Implemented\r\n\r\n"; + int nodelay = 1; - lwip_setsockopt(socket->num, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)); + common_hal_socketpool_socket_setsockopt(socket, SOCKETPOOL_IPPROTO_TCP, SOCKETPOOL_TCP_NODELAY, &nodelay, sizeof(nodelay)); socketpool_socket_send(socket, (const uint8_t *)error_response, strlen(error_response)); } if (!request->done) { @@ -1386,37 +1393,8 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) void supervisor_web_workflow_background(void) { - // Otherwise, see if we have another socket to accept. - if ((!common_hal_socketpool_socket_get_connected(&active) || !active_request.in_progress) && - !common_hal_socketpool_socket_get_closed(&listening) && - listening.num > 0) { - uint32_t ip; - uint32_t port; - int newsoc = socketpool_socket_accept(&listening, (uint8_t *)&ip, &port); - if (newsoc == -EBADF) { - common_hal_socketpool_socket_close(&listening); - return; - } - if (newsoc > 0) { - // Close the active socket because we have another we accepted. - if (!common_hal_socketpool_socket_get_closed(&active)) { - common_hal_socketpool_socket_close(&active); - } - // TODO: Don't do this because it uses the private struct layout. - // Create the socket - active.num = newsoc; - active.pool = &pool; - active.connected = true; - - common_hal_socketpool_socket_settimeout(&active, 0); - - _reset_request(&active_request); - - lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK); - } - } - - // If we have a request in progress, continue working on it. + // If we have a request in progress, continue working on it. Do this first + // so that we can accept another socket after finishing this request. if (common_hal_socketpool_socket_get_connected(&active)) { _process_request(&active, &active_request); } else { @@ -1424,6 +1402,28 @@ void supervisor_web_workflow_background(void) { common_hal_socketpool_socket_close(&active); } + // Otherwise, see if we have another socket to accept. + if ((!common_hal_socketpool_socket_get_connected(&active) || + (!active_request.in_progress && !active_request.new_socket)) && + !common_hal_socketpool_socket_get_closed(&listening)) { + uint32_t ip; + uint32_t port; + int newsoc = socketpool_socket_accept(&listening, (uint8_t *)&ip, &port, &active); + if (newsoc == -EBADF) { + common_hal_socketpool_socket_close(&listening); + return; + } + if (newsoc > 0) { + common_hal_socketpool_socket_settimeout(&active, 0); + + _reset_request(&active_request); + // Mark new sockets, otherwise we may accept another before the first + // could start its request. + active_request.new_socket = true; + } + } + + websocket_background(); } diff --git a/supervisor/shared/web_workflow/websocket.c b/supervisor/shared/web_workflow/websocket.c index 3901c4eefe..9d1cf9919f 100644 --- a/supervisor/shared/web_workflow/websocket.c +++ b/supervisor/shared/web_workflow/websocket.c @@ -29,15 +29,13 @@ #include "py/ringbuf.h" #include "py/runtime.h" #include "shared/runtime/interrupt_char.h" +#include "shared-bindings/socketpool/SocketPool.h" #include "supervisor/shared/web_workflow/web_workflow.h" #if CIRCUITPY_STATUS_BAR #include "supervisor/shared/status_bar.h" #endif -// TODO: Remove ESP specific stuff. For now, it is useful as we refine the server. -#include "esp_log.h" - typedef struct { socketpool_socket_obj_t socket; uint8_t opcode; @@ -57,24 +55,18 @@ STATIC uint8_t _buf[16]; static _websocket cp_serial; -static const char *TAG = "CP websocket"; - void websocket_init(void) { - cp_serial.socket.num = -1; - cp_serial.socket.connected = false; + socketpool_socket_reset(&cp_serial.socket); ringbuf_init(&_incoming_ringbuf, _buf, sizeof(_buf) - 1); } void websocket_handoff(socketpool_socket_obj_t *socket) { - cp_serial.socket = *socket; + socketpool_socket_move(socket, &cp_serial.socket); cp_serial.closed = false; cp_serial.opcode = 0; cp_serial.frame_index = 0; cp_serial.frame_len = 2; - // Mark the original socket object as closed without telling the lower level. - socket->connected = false; - socket->num = -1; #if CIRCUITPY_STATUS_BAR // Send the title bar for the new client. @@ -89,9 +81,6 @@ bool websocket_connected(void) { static bool _read_byte(uint8_t *c) { int len = socketpool_socket_recv_into(&cp_serial.socket, c, 1); if (len != 1) { - if (len != -EAGAIN) { - ESP_LOGE(TAG, "recv error %d", len); - } return false; } return true; @@ -147,13 +136,10 @@ static void _read_next_frame_header(void) { // Set the TCP socket to send immediately so that we send the payload back before // closing the connection. int nodelay = 1; - lwip_setsockopt(cp_serial.socket.num, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)); + common_hal_socketpool_socket_setsockopt(&cp_serial.socket, SOCKETPOOL_IPPROTO_TCP, SOCKETPOOL_TCP_NODELAY, &nodelay, sizeof(nodelay)); } uint8_t frame_header[2]; frame_header[0] = 1 << 7 | opcode; - if (cp_serial.payload_remaining > 125) { - ESP_LOGE(TAG, "CLOSE or PING has long payload"); - } frame_header[1] = cp_serial.payload_remaining; web_workflow_send_raw(&cp_serial.socket, (const uint8_t *)frame_header, 2); } diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index a8deb9606d..801025f41a 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -4,6 +4,7 @@ SRC_SUPERVISOR = \ supervisor/shared/background_callback.c \ supervisor/shared/board.c \ supervisor/shared/cpu.c \ + supervisor/shared/fatfs.c \ supervisor/shared/flash.c \ supervisor/shared/lock.c \ supervisor/shared/memory.c \