Enable* web workflow for Pico W

* Except for circuitpython.local which depends on MDNS and will be
done in a follow up PR.

Progress on #7214
This commit is contained in:
Scott Shawcroft 2022-11-18 11:21:02 -08:00
parent c525322a29
commit c3a96a63c0
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
32 changed files with 333 additions and 569 deletions

View File

@ -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 \

View File

@ -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
}

View File

@ -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 \

View File

@ -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
}

View File

@ -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 \

View File

@ -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
}

View File

@ -250,7 +250,6 @@ endif
SRC_C += \
background.c \
fatfs_port.c \
mphalport.c \
bindings/espidf/__init__.c \
boards/$(BOARD)/board.c \

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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 \

View File

@ -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
}

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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
}

View File

@ -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 \

View File

@ -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);
}

View File

@ -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) },
};

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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"

View File

@ -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) {

View File

@ -24,18 +24,20 @@
* THE SOFTWARE.
*/
#include <stdarg.h>
#include <string.h>
#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();
}

View File

@ -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);
}

View File

@ -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 \