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:
parent
c525322a29
commit
c3a96a63c0
|
@ -322,7 +322,6 @@ SRC_C += \
|
||||||
boards/$(BOARD)/board.c \
|
boards/$(BOARD)/board.c \
|
||||||
boards/$(BOARD)/pins.c \
|
boards/$(BOARD)/pins.c \
|
||||||
eic_handler.c \
|
eic_handler.c \
|
||||||
fatfs_port.c \
|
|
||||||
lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \
|
lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \
|
||||||
mphalport.c \
|
mphalport.c \
|
||||||
reset.c \
|
reset.c \
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -65,7 +65,6 @@ SRC_C += bindings/videocore/__init__.c \
|
||||||
boards/$(BOARD)/pins.c \
|
boards/$(BOARD)/pins.c \
|
||||||
background.c \
|
background.c \
|
||||||
common-hal/videocore/Framebuffer.c \
|
common-hal/videocore/Framebuffer.c \
|
||||||
fatfs_port.c \
|
|
||||||
mphalport.c \
|
mphalport.c \
|
||||||
lib/sdmmc/sdmmc_cmd.c \
|
lib/sdmmc/sdmmc_cmd.c \
|
||||||
lib/sdmmc/sdmmc_common.c \
|
lib/sdmmc/sdmmc_common.c \
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -172,7 +172,6 @@ SRC_S = supervisor/cpu.s
|
||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
background.c \
|
background.c \
|
||||||
fatfs_port.c \
|
|
||||||
mphalport.c \
|
mphalport.c \
|
||||||
boards/$(BOARD)/board.c \
|
boards/$(BOARD)/board.c \
|
||||||
boards/$(BOARD)/pins.c \
|
boards/$(BOARD)/pins.c \
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -250,7 +250,6 @@ endif
|
||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
background.c \
|
background.c \
|
||||||
fatfs_port.c \
|
|
||||||
mphalport.c \
|
mphalport.c \
|
||||||
bindings/espidf/__init__.c \
|
bindings/espidf/__init__.c \
|
||||||
boards/$(BOARD)/board.c \
|
boards/$(BOARD)/board.c \
|
||||||
|
|
|
@ -240,7 +240,7 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_
|
||||||
return sock;
|
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;
|
struct sockaddr_in accept_addr;
|
||||||
socklen_t socklen = sizeof(accept_addr);
|
socklen_t socklen = sizeof(accept_addr);
|
||||||
int newsoc = -1;
|
int newsoc = -1;
|
||||||
|
@ -274,12 +274,25 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_
|
||||||
lwip_close(newsoc);
|
lwip_close(newsoc);
|
||||||
return -MP_EBADF;
|
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;
|
return newsoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self,
|
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self,
|
||||||
uint8_t *ip, uint32_t *port) {
|
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) {
|
if (newsoc > 0) {
|
||||||
mark_user_socket(newsoc);
|
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;
|
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) {
|
bool common_hal_socketpool_readable(socketpool_socket_obj_t *self) {
|
||||||
struct timeval immediate = {0, 0};
|
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
|
// including returning true in the error case
|
||||||
return num_triggered != 0;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -117,7 +117,6 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_VALENTYUSB_EPTRI -DCFG_TUD_CDC_RX_BUFSIZE=1024
|
||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
background.c \
|
background.c \
|
||||||
fatfs_port.c \
|
|
||||||
mphalport.c \
|
mphalport.c \
|
||||||
boards/$(BOARD)/board.c \
|
boards/$(BOARD)/board.c \
|
||||||
boards/$(BOARD)/pins.c
|
boards/$(BOARD)/pins.c
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -150,7 +150,6 @@ SRC_C += \
|
||||||
boards/$(BOARD)/board.c \
|
boards/$(BOARD)/board.c \
|
||||||
boards/$(BOARD)/flash_config.c \
|
boards/$(BOARD)/flash_config.c \
|
||||||
boards/$(BOARD)/pins.c \
|
boards/$(BOARD)/pins.c \
|
||||||
fatfs_port.c \
|
|
||||||
lib/tinyusb/src/portable/chipidea/ci_hs/dcd_ci_hs.c \
|
lib/tinyusb/src/portable/chipidea/ci_hs/dcd_ci_hs.c \
|
||||||
mphalport.c \
|
mphalport.c \
|
||||||
peripherals/mimxrt10xx/$(CHIP_FAMILY)/clocks.c \
|
peripherals/mimxrt10xx/$(CHIP_FAMILY)/clocks.c \
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -165,7 +165,6 @@ endif
|
||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
background.c \
|
background.c \
|
||||||
fatfs_port.c \
|
|
||||||
boards/$(BOARD)/board.c \
|
boards/$(BOARD)/board.c \
|
||||||
boards/$(BOARD)/pins.c \
|
boards/$(BOARD)/pins.c \
|
||||||
device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \
|
device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \
|
||||||
|
|
|
@ -211,13 +211,15 @@ CFLAGS += \
|
||||||
-msoft-float \
|
-msoft-float \
|
||||||
-mfloat-abi=soft
|
-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.
|
# Use toolchain libm if we're not using our own.
|
||||||
ifndef INTERNAL_LIBM
|
ifndef INTERNAL_LIBM
|
||||||
LIBS += -lm
|
LIBS += -lm
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
LIBS += -lc
|
||||||
|
|
||||||
SRC_SDK := \
|
SRC_SDK := \
|
||||||
src/common/pico_sync/critical_section.c \
|
src/common/pico_sync/critical_section.c \
|
||||||
src/common/pico_sync/lock_core.c \
|
src/common/pico_sync/lock_core.c \
|
||||||
|
@ -270,7 +272,6 @@ SRC_C += \
|
||||||
background.c \
|
background.c \
|
||||||
peripherals/pins.c \
|
peripherals/pins.c \
|
||||||
lib/crypto-algorithms/sha256.c \
|
lib/crypto-algorithms/sha256.c \
|
||||||
fatfs_port.c \
|
|
||||||
lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c \
|
lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c \
|
||||||
lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c \
|
lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c \
|
||||||
mphalport.c \
|
mphalport.c \
|
||||||
|
@ -441,7 +442,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(LINK_LD)
|
||||||
$(STEPECHO) "LINK $@"
|
$(STEPECHO) "LINK $@"
|
||||||
$(Q)echo $(OBJ) > $(BUILD)/firmware.objs
|
$(Q)echo $(OBJ) > $(BUILD)/firmware.objs
|
||||||
$(Q)echo $(PICO_LDFLAGS) > $(BUILD)/firmware.ldflags
|
$(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)
|
$(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LINK_LD)
|
||||||
|
|
||||||
$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
|
$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
|
||||||
|
|
|
@ -14,7 +14,7 @@ CIRCUITPY_CYW43 = 1
|
||||||
CIRCUITPY_SSL = 1
|
CIRCUITPY_SSL = 1
|
||||||
CIRCUITPY_SSL_MBEDTLS = 1
|
CIRCUITPY_SSL_MBEDTLS = 1
|
||||||
CIRCUITPY_HASHLIB = 1
|
CIRCUITPY_HASHLIB = 1
|
||||||
CIRCUITPY_WEB_WORKFLOW = 0
|
CIRCUITPY_WEB_WORKFLOW = 1
|
||||||
CIRCUITPY_MDNS = 0
|
CIRCUITPY_MDNS = 0
|
||||||
CIRCUITPY_SOCKETPOOL = 1
|
CIRCUITPY_SOCKETPOOL = 1
|
||||||
CIRCUITPY_WIFI = 1
|
CIRCUITPY_WIFI = 1
|
||||||
|
|
|
@ -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));
|
mp_sched_schedule(socket->callback, MP_OBJ_FROM_PTR(socket));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
supervisor_workflow_request_background();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MICROPY_PY_LWIP_SOCK_RAW
|
#if MICROPY_PY_LWIP_SOCK_RAW
|
||||||
|
@ -745,57 +746,47 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
return -MP_EBADF;
|
if (self->type != MOD_NETWORK_SOCK_STREAM) {
|
||||||
}
|
return -MP_EOPNOTSUPP;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new socket object, do it here because we must not raise an out-of-memory
|
if (common_hal_socketpool_socket_get_closed(self)) {
|
||||||
// exception when the LWIP concurrency lock is held
|
return -MP_EBADF;
|
||||||
socketpool_socket_obj_t *socket2 = m_new_ll_obj_with_finaliser(socketpool_socket_obj_t);
|
}
|
||||||
socket2->base.type = &socketpool_socket_type;
|
|
||||||
|
|
||||||
MICROPY_PY_LWIP_ENTER
|
MICROPY_PY_LWIP_ENTER
|
||||||
|
|
||||||
if (socket->pcb.tcp == NULL) {
|
if (self->pcb.tcp == NULL) {
|
||||||
MICROPY_PY_LWIP_EXIT
|
MICROPY_PY_LWIP_EXIT
|
||||||
m_del_obj(socketpool_socket_obj_t, socket2);
|
return -MP_EBADF;
|
||||||
mp_raise_OSError(MP_EBADF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// I need to do this because "tcp_accepted", later, is a macro.
|
// 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) {
|
if (listener->state != LISTEN) {
|
||||||
MICROPY_PY_LWIP_EXIT
|
MICROPY_PY_LWIP_EXIT
|
||||||
m_del_obj(socketpool_socket_obj_t, socket2);
|
return -MP_EINVAL;
|
||||||
mp_raise_OSError(MP_EINVAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// accept incoming connection
|
// 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 (*incoming_connection == NULL) {
|
||||||
if (socket->timeout == 0) {
|
if (self->timeout == 0) {
|
||||||
MICROPY_PY_LWIP_EXIT
|
MICROPY_PY_LWIP_EXIT
|
||||||
m_del_obj(socketpool_socket_obj_t, socket2);
|
return -MP_EAGAIN;
|
||||||
mp_raise_OSError(MP_EAGAIN);
|
} else if (self->timeout != (unsigned)-1) {
|
||||||
} else if (socket->timeout != (unsigned)-1) {
|
mp_uint_t retries = self->timeout / 100;
|
||||||
mp_uint_t retries = socket->timeout / 100;
|
while (*incoming_connection == NULL && !mp_hal_is_interrupted()) {
|
||||||
while (*incoming_connection == NULL) {
|
|
||||||
MICROPY_PY_LWIP_EXIT
|
MICROPY_PY_LWIP_EXIT
|
||||||
if (retries-- == 0) {
|
if (retries-- == 0) {
|
||||||
m_del_obj(socketpool_socket_obj_t, socket2);
|
return -MP_ETIMEDOUT;
|
||||||
mp_raise_OSError(MP_ETIMEDOUT);
|
|
||||||
}
|
}
|
||||||
mp_hal_delay_ms(100);
|
mp_hal_delay_ms(100);
|
||||||
MICROPY_PY_LWIP_REENTER
|
MICROPY_PY_LWIP_REENTER
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (*incoming_connection == NULL) {
|
while (*incoming_connection == NULL && !mp_hal_is_interrupted()) {
|
||||||
MICROPY_PY_LWIP_EXIT
|
MICROPY_PY_LWIP_EXIT
|
||||||
poll_sockets();
|
poll_sockets();
|
||||||
MICROPY_PY_LWIP_REENTER
|
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...
|
// We get a new pcb handle...
|
||||||
socket2->pcb.tcp = *incoming_connection;
|
accepted->pcb.tcp = *incoming_connection;
|
||||||
if (++socket->incoming.connection.iget >= socket->incoming.connection.alloc) {
|
if (++self->incoming.connection.iget >= self->incoming.connection.alloc) {
|
||||||
socket->incoming.connection.iget = 0;
|
self->incoming.connection.iget = 0;
|
||||||
}
|
}
|
||||||
*incoming_connection = NULL;
|
*incoming_connection = NULL;
|
||||||
|
|
||||||
// ...and set up the new socket for it.
|
// ...and set up the new socket for it.
|
||||||
socket2->domain = MOD_NETWORK_AF_INET;
|
accepted->domain = MOD_NETWORK_AF_INET;
|
||||||
socket2->type = MOD_NETWORK_SOCK_STREAM;
|
accepted->type = MOD_NETWORK_SOCK_STREAM;
|
||||||
socket2->incoming.pbuf = NULL;
|
accepted->incoming.pbuf = NULL;
|
||||||
socket2->timeout = socket->timeout;
|
accepted->timeout = self->timeout;
|
||||||
socket2->state = STATE_CONNECTED;
|
accepted->state = STATE_CONNECTED;
|
||||||
socket2->recv_offset = 0;
|
accepted->recv_offset = 0;
|
||||||
socket2->callback = MP_OBJ_NULL;
|
accepted->callback = MP_OBJ_NULL;
|
||||||
tcp_arg(socket2->pcb.tcp, (void *)socket2);
|
tcp_arg(accepted->pcb.tcp, (void *)accepted);
|
||||||
tcp_err(socket2->pcb.tcp, _lwip_tcp_error);
|
tcp_err(accepted->pcb.tcp, _lwip_tcp_error);
|
||||||
tcp_recv(socket2->pcb.tcp, _lwip_tcp_recv);
|
tcp_recv(accepted->pcb.tcp, _lwip_tcp_recv);
|
||||||
|
|
||||||
tcp_accepted(listener);
|
tcp_accepted(listener);
|
||||||
|
|
||||||
MICROPY_PY_LWIP_EXIT
|
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");
|
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");
|
DEBUG_printf("collecting garbage to open socket\n");
|
||||||
gc_collect();
|
gc_collect();
|
||||||
if (!register_open_socket(socket2)) {
|
if (!register_open_socket(accepted)) {
|
||||||
mp_raise_RuntimeError(translate("Out of sockets"));
|
mp_raise_RuntimeError(translate("Out of sockets"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mark_user_socket(socket2);
|
mark_user_socket(accepted);
|
||||||
|
|
||||||
// output values
|
return MP_OBJ_FROM_PTR(accepted);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t *socket,
|
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
|
// get address
|
||||||
ip_addr_t bind_addr;
|
ip_addr_t bind_addr;
|
||||||
|
const ip_addr_t *bind_addr_ptr = &bind_addr;
|
||||||
|
if (hostlen > 0) {
|
||||||
int error = socketpool_resolve_host(socket->pool, host, &bind_addr);
|
int error = socketpool_resolve_host(socket->pool, host, &bind_addr);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
mp_raise_OSError(EHOSTUNREACH);
|
mp_raise_OSError(EHOSTUNREACH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
bind_addr_ptr = IP_ANY_TYPE;
|
||||||
|
}
|
||||||
ip_set_option(socket->pcb.ip, SOF_REUSEADDR);
|
ip_set_option(socket->pcb.ip, SOF_REUSEADDR);
|
||||||
|
|
||||||
err_t err = ERR_ARG;
|
err_t err = ERR_ARG;
|
||||||
switch (socket->type) {
|
switch (socket->type) {
|
||||||
case MOD_NETWORK_SOCK_STREAM: {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case MOD_NETWORK_SOCK_DGRAM: {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1164,6 +1192,20 @@ void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint
|
||||||
self->timeout = timeout_ms;
|
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) {
|
bool common_hal_socketpool_readable(socketpool_socket_obj_t *self) {
|
||||||
|
|
||||||
MICROPY_PY_LWIP_ENTER;
|
MICROPY_PY_LWIP_ENTER;
|
||||||
|
@ -1206,3 +1248,32 @@ bool common_hal_socketpool_writable(socketpool_socket_obj_t *self) {
|
||||||
|
|
||||||
return result;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -73,13 +73,12 @@ NORETURN static void ro_attribute(int attr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self) {
|
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) {
|
void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) {
|
||||||
if (!enabled) {
|
self->enabled = enabled;
|
||||||
ro_attribute(MP_QSTR_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) {
|
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);
|
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) {
|
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) {
|
if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_UP) {
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
|
|
|
@ -35,6 +35,7 @@ typedef struct {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
char hostname[254]; // hostname max is 253 chars, + 1 for trailing NUL
|
char hostname[254]; // hostname max is 253 chars, + 1 for trailing NUL
|
||||||
wifi_scannednetworks_obj_t *current_scan;
|
wifi_scannednetworks_obj_t *current_scan;
|
||||||
|
bool enabled;
|
||||||
} wifi_radio_obj_t;
|
} wifi_radio_obj_t;
|
||||||
|
|
||||||
extern void common_hal_wifi_radio_gc_collect(wifi_radio_obj_t *self);
|
extern void common_hal_wifi_radio_gc_collect(wifi_radio_obj_t *self);
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -221,7 +221,6 @@ SRC_STM32 += boards/system_stm32$(MCU_SERIES_LOWER)xx.c
|
||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
background.c \
|
background.c \
|
||||||
fatfs_port.c \
|
|
||||||
mphalport.c \
|
mphalport.c \
|
||||||
boards/$(BOARD)/board.c \
|
boards/$(BOARD)/board.c \
|
||||||
boards/$(BOARD)/pins.c \
|
boards/$(BOARD)/pins.c \
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_setblocking_obj, socketpool_socket_setblocking);
|
||||||
|
|
||||||
// //| def setsockopt(self, level: int, optname: int, value: int) -> None:
|
//| def setsockopt(self, level: int, optname: int, value: int) -> None:
|
||||||
// //| """Sets socket options"""
|
//| """Sets socket options"""
|
||||||
// //| ...
|
//| ...
|
||||||
// //|
|
STATIC mp_obj_t socketpool_socket_setsockopt(size_t n_args, const mp_obj_t *args) {
|
||||||
// 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]);
|
||||||
// // mod_network_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]);
|
const void *optval;
|
||||||
// // mp_int_t opt = mp_obj_get_int(args[2]);
|
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;
|
int _errno = common_hal_socketpool_socket_setsockopt(self, level, opt, optval, optlen);
|
||||||
// // mp_uint_t optlen;
|
if (_errno < 0) {
|
||||||
// // mp_int_t val;
|
mp_raise_OSError(-_errno);
|
||||||
// // 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;
|
return mp_const_none;
|
||||||
// // if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) {
|
}
|
||||||
// // mp_raise_OSError(_errno);
|
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:
|
//| 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_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_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_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) },
|
{ MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socketpool_socket_settimeout_obj) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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,
|
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);
|
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);
|
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_readable(socketpool_socket_obj_t *self);
|
||||||
bool common_hal_socketpool_writable(socketpool_socket_obj_t *self);
|
bool common_hal_socketpool_writable(socketpool_socket_obj_t *self);
|
||||||
|
|
||||||
// Non-allocating versions for internal use.
|
// 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);
|
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_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len);
|
||||||
int socketpool_socket_recv_into(socketpool_socket_obj_t *self,
|
int socketpool_socket_recv_into(socketpool_socket_obj_t *self,
|
||||||
const uint8_t *buf, uint32_t len);
|
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
|
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H
|
||||||
|
|
|
@ -52,7 +52,6 @@
|
||||||
//| returned by :py:attr:`wifi.radio`
|
//| 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) {
|
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);
|
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);
|
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:
|
//| def socket(self, family: int = AF_INET, type: int = SOCK_STREAM) -> socketpool.Socket:
|
||||||
//| """Create a new 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,
|
//| address information to call socket.socket() and socket.connect() with,
|
||||||
//| as a tuple."""
|
//| 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) {
|
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 };
|
enum { ARG_host, ARG_port, ARG_family, ARG_type, ARG_proto, ARG_flags };
|
||||||
static const mp_arg_t allowed_args[] = {
|
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) },
|
{ MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&socketpool_socketpool_getaddrinfo_obj) },
|
||||||
|
|
||||||
// class constants
|
// class constants
|
||||||
|
//| AF_INET: int
|
||||||
{ MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(SOCKETPOOL_AF_INET) },
|
{ 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) },
|
{ 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) },
|
{ 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) },
|
{ 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) },
|
{ 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);
|
STATIC MP_DEFINE_CONST_DICT(socketpool_socketpool_locals_dict, socketpool_socketpool_locals_dict_table);
|
||||||
|
|
|
@ -34,16 +34,24 @@
|
||||||
extern const mp_obj_type_t socketpool_socketpool_type;
|
extern const mp_obj_type_t socketpool_socketpool_type;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SOCKETPOOL_SOCK_STREAM,
|
SOCKETPOOL_SOCK_STREAM = 1,
|
||||||
SOCKETPOOL_SOCK_DGRAM,
|
SOCKETPOOL_SOCK_DGRAM = 2,
|
||||||
SOCKETPOOL_SOCK_RAW
|
SOCKETPOOL_SOCK_RAW = 3
|
||||||
} socketpool_socketpool_sock_t;
|
} socketpool_socketpool_sock_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SOCKETPOOL_AF_INET,
|
SOCKETPOOL_AF_INET = 2,
|
||||||
SOCKETPOOL_AF_INET6
|
SOCKETPOOL_AF_INET6 = 10
|
||||||
} socketpool_socketpool_addressfamily_t;
|
} 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);
|
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,
|
socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_t *self,
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MICROPY_INCLUDED_SUPERVISOR_FATFS_PORT_H
|
#ifndef MICROPY_INCLUDED_SUPERVISOR_FATFS_H
|
||||||
#define MICROPY_INCLUDED_SUPERVISOR_FATFS_PORT_H
|
#define MICROPY_INCLUDED_SUPERVISOR_FATFS_H
|
||||||
|
|
||||||
#include "lib/oofatfs/ff.h"
|
#include "lib/oofatfs/ff.h"
|
||||||
|
|
||||||
void override_fattime(DWORD time);
|
void override_fattime(DWORD time);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_SUPERVISOR_FATFS_PORT_H
|
#endif // MICROPY_INCLUDED_SUPERVISOR_FATFS_H
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
#include "common-hal/_bleio/__init__.h"
|
#include "common-hal/_bleio/__init__.h"
|
||||||
|
|
||||||
#include "supervisor/fatfs_port.h"
|
#include "supervisor/fatfs.h"
|
||||||
#include "supervisor/filesystem.h"
|
#include "supervisor/filesystem.h"
|
||||||
#include "supervisor/shared/reload.h"
|
#include "supervisor/shared/reload.h"
|
||||||
#include "supervisor/shared/bluetooth/file_transfer.h"
|
#include "supervisor/shared/bluetooth/file_transfer.h"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* 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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -24,12 +24,13 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "supervisor/fatfs.h"
|
||||||
|
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "lib/oofatfs/ff.h"
|
#include "lib/oofatfs/ff.h"
|
||||||
#include "shared/timeutils/timeutils.h"
|
#include "shared/timeutils/timeutils.h"
|
||||||
#include "shared-bindings/rtc/RTC.h"
|
#include "shared-bindings/rtc/RTC.h"
|
||||||
#include "shared-bindings/time/__init__.h"
|
#include "shared-bindings/time/__init__.h"
|
||||||
#include "supervisor/fatfs_port.h"
|
|
||||||
|
|
||||||
DWORD _time_override = 0;
|
DWORD _time_override = 0;
|
||||||
DWORD get_fattime(void) {
|
DWORD get_fattime(void) {
|
|
@ -24,18 +24,20 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "extmod/vfs.h"
|
#include "extmod/vfs.h"
|
||||||
#include "extmod/vfs_fat.h"
|
#include "extmod/vfs_fat.h"
|
||||||
#include "genhdr/mpversion.h"
|
#include "genhdr/mpversion.h"
|
||||||
|
#include "py/mperrno.h"
|
||||||
#include "py/mpstate.h"
|
#include "py/mpstate.h"
|
||||||
#include "py/stackctrl.h"
|
#include "py/stackctrl.h"
|
||||||
|
|
||||||
#include "shared-bindings/wifi/Radio.h"
|
#include "shared-bindings/wifi/Radio.h"
|
||||||
#include "shared-module/storage/__init__.h"
|
#include "shared-module/storage/__init__.h"
|
||||||
#include "shared/timeutils/timeutils.h"
|
#include "shared/timeutils/timeutils.h"
|
||||||
#include "supervisor/fatfs_port.h"
|
#include "supervisor/fatfs.h"
|
||||||
#include "supervisor/filesystem.h"
|
#include "supervisor/filesystem.h"
|
||||||
#include "supervisor/port.h"
|
#include "supervisor/port.h"
|
||||||
#include "supervisor/shared/reload.h"
|
#include "supervisor/shared/reload.h"
|
||||||
|
@ -47,8 +49,12 @@
|
||||||
|
|
||||||
#include "shared-bindings/hashlib/__init__.h"
|
#include "shared-bindings/hashlib/__init__.h"
|
||||||
#include "shared-bindings/hashlib/Hash.h"
|
#include "shared-bindings/hashlib/Hash.h"
|
||||||
|
|
||||||
|
#if CIRCUITPY_MDNS
|
||||||
#include "shared-bindings/mdns/RemoteService.h"
|
#include "shared-bindings/mdns/RemoteService.h"
|
||||||
#include "shared-bindings/mdns/Server.h"
|
#include "shared-bindings/mdns/Server.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "shared-bindings/microcontroller/Processor.h"
|
#include "shared-bindings/microcontroller/Processor.h"
|
||||||
#include "shared-bindings/socketpool/__init__.h"
|
#include "shared-bindings/socketpool/__init__.h"
|
||||||
#include "shared-bindings/socketpool/Socket.h"
|
#include "shared-bindings/socketpool/Socket.h"
|
||||||
|
@ -62,11 +68,6 @@
|
||||||
#include "shared-module/dotenv/__init__.h"
|
#include "shared-module/dotenv/__init__.h"
|
||||||
#endif
|
#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 {
|
enum request_state {
|
||||||
STATE_METHOD,
|
STATE_METHOD,
|
||||||
STATE_PATH,
|
STATE_PATH,
|
||||||
|
@ -95,6 +96,7 @@ typedef struct {
|
||||||
bool expect;
|
bool expect;
|
||||||
bool json;
|
bool json;
|
||||||
bool websocket;
|
bool websocket;
|
||||||
|
bool new_socket;
|
||||||
uint32_t websocket_version;
|
uint32_t websocket_version;
|
||||||
// RFC6455 for websockets says this header should be 24 base64 characters long.
|
// RFC6455 for websockets says this header should be 24 base64 characters long.
|
||||||
char websocket_key[24 + 1];
|
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;
|
static wifi_radio_error_t _last_wifi_status = WIFI_RADIO_ERROR_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CIRCUITPY_MDNS
|
||||||
static mdns_server_obj_t mdns;
|
static mdns_server_obj_t mdns;
|
||||||
|
#endif
|
||||||
|
|
||||||
static uint32_t web_api_port = 80;
|
static uint32_t web_api_port = 80;
|
||||||
|
|
||||||
static socketpool_socketpool_obj_t pool;
|
static socketpool_socketpool_obj_t pool;
|
||||||
|
@ -271,7 +276,7 @@ void supervisor_start_web_workflow(void) {
|
||||||
// attempting to connect to the given network.
|
// attempting to connect to the given network.
|
||||||
_wifi_status = common_hal_wifi_radio_connect(
|
_wifi_status = common_hal_wifi_radio_connect(
|
||||||
&common_hal_wifi_radio_obj, (uint8_t *)ssid, ssid_len, (uint8_t *)password, password_len,
|
&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) {
|
if (_wifi_status != WIFI_RADIO_ERROR_NONE) {
|
||||||
common_hal_wifi_radio_set_enabled(&common_hal_wifi_radio_obj, false);
|
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);
|
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;
|
bool port_changed = new_port != web_api_port;
|
||||||
|
|
||||||
if (first_start) {
|
if (first_start) {
|
||||||
ESP_LOGI(TAG, "Starting web workflow");
|
#if CIRCUITPY_MDNS
|
||||||
mdns_server_construct(&mdns, true);
|
mdns_server_construct(&mdns, true);
|
||||||
mdns.base.type = &mdns_server_type;
|
mdns.base.type = &mdns_server_type;
|
||||||
common_hal_mdns_server_set_instance_name(&mdns, MICROPY_HW_BOARD_NAME);
|
common_hal_mdns_server_set_instance_name(&mdns, MICROPY_HW_BOARD_NAME);
|
||||||
|
#endif
|
||||||
pool.base.type = &socketpool_socketpool_type;
|
pool.base.type = &socketpool_socketpool_type;
|
||||||
common_hal_socketpool_socketpool_construct(&pool, &common_hal_wifi_radio_obj);
|
common_hal_socketpool_socketpool_construct(&pool, &common_hal_wifi_radio_obj);
|
||||||
|
|
||||||
listening.base.type = &socketpool_socket_type;
|
socketpool_socket_reset(&listening);
|
||||||
active.base.type = &socketpool_socket_type;
|
socketpool_socket_reset(&active);
|
||||||
active.num = -1;
|
|
||||||
active.connected = false;
|
|
||||||
|
|
||||||
websocket_init();
|
websocket_init();
|
||||||
}
|
}
|
||||||
|
@ -312,7 +316,9 @@ void supervisor_start_web_workflow(void) {
|
||||||
}
|
}
|
||||||
if (first_start || port_changed) {
|
if (first_start || port_changed) {
|
||||||
web_api_port = new_port;
|
web_api_port = new_port;
|
||||||
|
#if CIRCUITPY_MDNS
|
||||||
common_hal_mdns_server_advertise_service(&mdns, "_circuitpython", "_tcp", web_api_port);
|
common_hal_mdns_server_advertise_service(&mdns, "_circuitpython", "_tcp", web_api_port);
|
||||||
|
#endif
|
||||||
socketpool_socket(&pool, SOCKETPOOL_AF_INET, SOCKETPOOL_SOCK_STREAM, &listening);
|
socketpool_socket(&pool, SOCKETPOOL_AF_INET, SOCKETPOOL_SOCK_STREAM, &listening);
|
||||||
common_hal_socketpool_socket_settimeout(&listening, 0);
|
common_hal_socketpool_socket_settimeout(&listening, 0);
|
||||||
// Bind to any ip.
|
// Bind to any ip.
|
||||||
|
@ -326,17 +332,13 @@ void supervisor_start_web_workflow(void) {
|
||||||
_api_password[api_password_len + 1] = '\0';
|
_api_password[api_password_len + 1] = '\0';
|
||||||
_base64_in_place(_api_password, api_password_len + 1, sizeof(_api_password));
|
_base64_in_place(_api_password, api_password_len + 1, sizeof(_api_password));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// GET /edit/
|
|
||||||
// - Super basic editor
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void web_workflow_send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) {
|
void web_workflow_send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) {
|
||||||
int total_sent = 0;
|
int total_sent = 0;
|
||||||
int sent = -EAGAIN;
|
int sent = -MP_EAGAIN;
|
||||||
while ((sent == -EAGAIN || (sent > 0 && total_sent < len)) &&
|
while ((sent == -MP_EAGAIN || (sent > 0 && total_sent < len)) &&
|
||||||
common_hal_socketpool_socket_get_connected(socket)) {
|
common_hal_socketpool_socket_get_connected(socket)) {
|
||||||
sent = socketpool_socket_send(socket, buf + total_sent, len - total_sent);
|
sent = socketpool_socket_send(socket, buf + total_sent, len - total_sent);
|
||||||
if (sent > 0) {
|
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) {
|
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) {
|
static bool _origin_ok(const char *origin) {
|
||||||
const char *http = "http://";
|
const char *http = "http://";
|
||||||
const char *local = ".local";
|
|
||||||
|
|
||||||
// note: redirected requests send an Origin of "null" and will be caught by this
|
// note: redirected requests send an Origin of "null" and will be caught by this
|
||||||
if (strncmp(origin, http, strlen(http)) != 0) {
|
if (strncmp(origin, http, strlen(http)) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// These are prefix checks up to : so that any port works.
|
// 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 *hostname = common_hal_mdns_server_get_hostname(&mdns);
|
||||||
const char *end = origin + strlen(http) + strlen(hostname) + strlen(local);
|
const char *end = origin + strlen(http) + strlen(hostname) + strlen(local);
|
||||||
if (strncmp(origin + strlen(http), hostname, strlen(hostname)) == 0 &&
|
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] == ':')) {
|
(end[0] == '\0' || end[0] == ':')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
const char *end;
|
||||||
|
#endif
|
||||||
|
|
||||||
_update_encoded_ip();
|
_update_encoded_ip();
|
||||||
end = origin + strlen(http) + strlen(_our_ip_encoded);
|
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");
|
_send_str(socket, "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CIRCUITPY_MDNS
|
||||||
static void _reply_redirect(socketpool_socket_obj_t *socket, _request *request, const char *path) {
|
static void _reply_redirect(socketpool_socket_obj_t *socket, _request *request, const char *path) {
|
||||||
int nodelay = 1;
|
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);
|
const char *hostname = common_hal_mdns_server_get_hostname(&mdns);
|
||||||
_send_strs(socket,
|
_send_strs(socket,
|
||||||
"HTTP/1.1 307 Temporary Redirect\r\n",
|
"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);
|
_cors_header(socket, request);
|
||||||
_send_str(socket, "\r\n");
|
_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) {
|
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));
|
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) {
|
while (send_offset < quantity_read) {
|
||||||
int sent = socketpool_socket_send(socket, data_buffer + send_offset, quantity_read - send_offset);
|
int sent = socketpool_socket_send(socket, data_buffer + send_offset, quantity_read - send_offset);
|
||||||
if (sent < 0) {
|
if (sent < 0) {
|
||||||
if (sent == -EAGAIN) {
|
if (sent == -MP_EAGAIN) {
|
||||||
sent = 0;
|
sent = 0;
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG, "file send error %d", sent);
|
|
||||||
break;
|
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) {
|
static void _reply_with_devices_json(socketpool_socket_obj_t *socket, _request *request) {
|
||||||
|
#if CIRCUITPY_MDNS
|
||||||
mdns_remoteservice_obj_t found_devices[32];
|
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 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));
|
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));
|
socketpool_socket_send(socket, (const uint8_t *)OK_JSON, strlen(OK_JSON));
|
||||||
_cors_header(socket, request);
|
_cors_header(socket, request);
|
||||||
_send_str(socket, "\r\n");
|
_send_str(socket, "\r\n");
|
||||||
mp_print_t _socket_print = {socket, _print_chunk};
|
mp_print_t _socket_print = {socket, _print_chunk};
|
||||||
|
|
||||||
mp_printf(&_socket_print, "{\"total\": %d, \"devices\": [", total_results);
|
mp_printf(&_socket_print, "{\"total\": %d, \"devices\": [", total_results);
|
||||||
|
#if CIRCUITPY_MDNS
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
_send_chunk(socket, ",");
|
_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]);
|
"\"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]);
|
common_hal_mdns_remoteservice_deinit(&found_devices[i]);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
_send_chunk(socket, "]}");
|
_send_chunk(socket, "]}");
|
||||||
// Empty chunk signals the end of the response.
|
// Empty chunk signals the end of the response.
|
||||||
_send_chunk(socket, "");
|
_send_chunk(socket, "");
|
||||||
|
@ -762,7 +773,11 @@ static void _reply_with_version_json(socketpool_socket_obj_t *socket, _request *
|
||||||
_send_str(socket, "\r\n");
|
_send_str(socket, "\r\n");
|
||||||
mp_print_t _socket_print = {socket, _print_chunk};
|
mp_print_t _socket_print = {socket, _print_chunk};
|
||||||
|
|
||||||
|
#if CIRCUITPY_MDNS
|
||||||
const char *hostname = common_hal_mdns_server_get_hostname(&mdns);
|
const char *hostname = common_hal_mdns_server_get_hostname(&mdns);
|
||||||
|
#else
|
||||||
|
const char *hostname = "";
|
||||||
|
#endif
|
||||||
_update_encoded_ip();
|
_update_encoded_ip();
|
||||||
// Note: this leverages the fact that C concats consecutive string literals together.
|
// Note: this leverages the fact that C concats consecutive string literals together.
|
||||||
mp_printf(&_socket_print,
|
mp_printf(&_socket_print,
|
||||||
|
@ -848,7 +863,6 @@ static void _write_file_and_reply(socketpool_socket_obj_t *socket, _request *req
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (result != FR_OK) {
|
if (result != FR_OK) {
|
||||||
ESP_LOGE(TAG, "file write error %d %s", result, path);
|
|
||||||
override_fattime(0);
|
override_fattime(0);
|
||||||
#if CIRCUITPY_USB_MSC
|
#if CIRCUITPY_USB_MSC
|
||||||
usb_msc_unlock();
|
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);
|
size_t read_len = MIN(sizeof(bytes), request->content_length - total_read);
|
||||||
int len = socketpool_socket_recv_into(socket, bytes, read_len);
|
int len = socketpool_socket_recv_into(socket, bytes, read_len);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (len == -EAGAIN) {
|
if (len == -MP_EAGAIN) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
ESP_LOGE(TAG, "other error %d", len);
|
|
||||||
}
|
}
|
||||||
error = true;
|
error = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
UINT actual;
|
f_write(&active_file, bytes, len, NULL);
|
||||||
f_write(&active_file, bytes, len, &actual);
|
|
||||||
if (actual != (UINT)len) {
|
|
||||||
ESP_LOGE(TAG, "didn't write whole file");
|
|
||||||
}
|
|
||||||
total_read += len;
|
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) {
|
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;
|
uint32_t total_length = response_len;
|
||||||
char encoded_len[10];
|
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,
|
_send_strs(socket,
|
||||||
"HTTP/1.1 200 OK\r\n",
|
"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) {
|
static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
|
||||||
if (request->redirect) {
|
if (request->redirect) {
|
||||||
|
#if CIRCUITPY_MDNS
|
||||||
_reply_redirect(socket, request, request->path);
|
_reply_redirect(socket, request, request->path);
|
||||||
|
#endif
|
||||||
} else if (strlen(request->origin) > 0 && !_origin_ok(request->origin)) {
|
} else if (strlen(request->origin) > 0 && !_origin_ok(request->origin)) {
|
||||||
ESP_LOGE(TAG, "bad origin %s", request->origin);
|
|
||||||
_reply_forbidden(socket, request);
|
_reply_forbidden(socket, request);
|
||||||
} else if (strncmp(request->path, "/fs/", 4) == 0) {
|
} else if (strncmp(request->path, "/fs/", 4) == 0) {
|
||||||
if (strcasecmp(request->method, "OPTIONS") == 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) {
|
if (result == FR_NO_PATH || result == FR_NO_FILE) {
|
||||||
_reply_missing(socket, request);
|
_reply_missing(socket, request);
|
||||||
} else if (result != FR_OK) {
|
} else if (result != FR_OK) {
|
||||||
ESP_LOGE(TAG, "rm error %d %s", result, path);
|
|
||||||
_reply_server_error(socket, request);
|
_reply_server_error(socket, request);
|
||||||
} else {
|
} else {
|
||||||
_reply_no_content(socket, request);
|
_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.
|
} else if (result == FR_NO_PATH || result == FR_NO_FILE) { // Missing higher directories or target file.
|
||||||
_reply_missing(socket, request);
|
_reply_missing(socket, request);
|
||||||
} else if (result != FR_OK) {
|
} else if (result != FR_OK) {
|
||||||
ESP_LOGE(TAG, "move error %d %s", result, path);
|
|
||||||
_reply_server_error(socket, request);
|
_reply_server_error(socket, request);
|
||||||
} else {
|
} else {
|
||||||
_reply_created(socket, request);
|
_reply_created(socket, request);
|
||||||
|
@ -1137,7 +1144,6 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
|
||||||
} else if (result == FR_NO_PATH) {
|
} else if (result == FR_NO_PATH) {
|
||||||
_reply_missing(socket, request);
|
_reply_missing(socket, request);
|
||||||
} else if (result != FR_OK) {
|
} else if (result != FR_OK) {
|
||||||
ESP_LOGE(TAG, "mkdir error %d %s", result, path);
|
|
||||||
_reply_server_error(socket, request);
|
_reply_server_error(socket, request);
|
||||||
} else {
|
} else {
|
||||||
_reply_created(socket, request);
|
_reply_created(socket, request);
|
||||||
|
@ -1237,6 +1243,7 @@ static void _reset_request(_request *request) {
|
||||||
request->redirect = false;
|
request->redirect = false;
|
||||||
request->done = false;
|
request->done = false;
|
||||||
request->in_progress = false;
|
request->in_progress = false;
|
||||||
|
request->new_socket = false;
|
||||||
request->authenticated = false;
|
request->authenticated = false;
|
||||||
request->expect = false;
|
request->expect = false;
|
||||||
request->json = false;
|
request->json = false;
|
||||||
|
@ -1257,6 +1264,7 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request)
|
||||||
if (!request->in_progress) {
|
if (!request->in_progress) {
|
||||||
autoreload_suspend(AUTORELOAD_SUSPEND_WEB);
|
autoreload_suspend(AUTORELOAD_SUSPEND_WEB);
|
||||||
request->in_progress = true;
|
request->in_progress = true;
|
||||||
|
request->new_socket = false;
|
||||||
}
|
}
|
||||||
switch (request->state) {
|
switch (request->state) {
|
||||||
case STATE_METHOD: {
|
case STATE_METHOD: {
|
||||||
|
@ -1276,7 +1284,6 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request)
|
||||||
if (c == ' ') {
|
if (c == ' ') {
|
||||||
request->path[request->offset] = '\0';
|
request->path[request->offset] = '\0';
|
||||||
request->offset = 0;
|
request->offset = 0;
|
||||||
ESP_LOGI(TAG, "Request %s %s", request->method, request->path);
|
|
||||||
request->state = STATE_VERSION;
|
request->state = STATE_VERSION;
|
||||||
} else if (request->offset > sizeof(request->path) - 1) {
|
} else if (request->offset > sizeof(request->path) - 1) {
|
||||||
// Skip methods that are too long.
|
// 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) {
|
} else if (strcasecmp(request->header_key, "X-Destination") == 0) {
|
||||||
strcpy(request->destination, request->header_value);
|
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) {
|
} else if (request->offset > sizeof(request->header_value) - 1) {
|
||||||
// Skip methods that are too long.
|
// Skip methods that are too long.
|
||||||
} else {
|
} else {
|
||||||
|
@ -1369,8 +1375,9 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request)
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
const char *error_response = "HTTP/1.1 501 Not Implemented\r\n\r\n";
|
const char *error_response = "HTTP/1.1 501 Not Implemented\r\n\r\n";
|
||||||
|
|
||||||
int nodelay = 1;
|
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));
|
socketpool_socket_send(socket, (const uint8_t *)error_response, strlen(error_response));
|
||||||
}
|
}
|
||||||
if (!request->done) {
|
if (!request->done) {
|
||||||
|
@ -1386,37 +1393,8 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request)
|
||||||
|
|
||||||
|
|
||||||
void supervisor_web_workflow_background(void) {
|
void supervisor_web_workflow_background(void) {
|
||||||
// Otherwise, see if we have another socket to accept.
|
// If we have a request in progress, continue working on it. Do this first
|
||||||
if ((!common_hal_socketpool_socket_get_connected(&active) || !active_request.in_progress) &&
|
// so that we can accept another socket after finishing this request.
|
||||||
!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 (common_hal_socketpool_socket_get_connected(&active)) {
|
if (common_hal_socketpool_socket_get_connected(&active)) {
|
||||||
_process_request(&active, &active_request);
|
_process_request(&active, &active_request);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1424,6 +1402,28 @@ void supervisor_web_workflow_background(void) {
|
||||||
common_hal_socketpool_socket_close(&active);
|
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();
|
websocket_background();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,15 +29,13 @@
|
||||||
#include "py/ringbuf.h"
|
#include "py/ringbuf.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "shared/runtime/interrupt_char.h"
|
#include "shared/runtime/interrupt_char.h"
|
||||||
|
#include "shared-bindings/socketpool/SocketPool.h"
|
||||||
#include "supervisor/shared/web_workflow/web_workflow.h"
|
#include "supervisor/shared/web_workflow/web_workflow.h"
|
||||||
|
|
||||||
#if CIRCUITPY_STATUS_BAR
|
#if CIRCUITPY_STATUS_BAR
|
||||||
#include "supervisor/shared/status_bar.h"
|
#include "supervisor/shared/status_bar.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: Remove ESP specific stuff. For now, it is useful as we refine the server.
|
|
||||||
#include "esp_log.h"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
socketpool_socket_obj_t socket;
|
socketpool_socket_obj_t socket;
|
||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
|
@ -57,24 +55,18 @@ STATIC uint8_t _buf[16];
|
||||||
|
|
||||||
static _websocket cp_serial;
|
static _websocket cp_serial;
|
||||||
|
|
||||||
static const char *TAG = "CP websocket";
|
|
||||||
|
|
||||||
void websocket_init(void) {
|
void websocket_init(void) {
|
||||||
cp_serial.socket.num = -1;
|
socketpool_socket_reset(&cp_serial.socket);
|
||||||
cp_serial.socket.connected = false;
|
|
||||||
|
|
||||||
ringbuf_init(&_incoming_ringbuf, _buf, sizeof(_buf) - 1);
|
ringbuf_init(&_incoming_ringbuf, _buf, sizeof(_buf) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void websocket_handoff(socketpool_socket_obj_t *socket) {
|
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.closed = false;
|
||||||
cp_serial.opcode = 0;
|
cp_serial.opcode = 0;
|
||||||
cp_serial.frame_index = 0;
|
cp_serial.frame_index = 0;
|
||||||
cp_serial.frame_len = 2;
|
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
|
#if CIRCUITPY_STATUS_BAR
|
||||||
// Send the title bar for the new client.
|
// Send the title bar for the new client.
|
||||||
|
@ -89,9 +81,6 @@ bool websocket_connected(void) {
|
||||||
static bool _read_byte(uint8_t *c) {
|
static bool _read_byte(uint8_t *c) {
|
||||||
int len = socketpool_socket_recv_into(&cp_serial.socket, c, 1);
|
int len = socketpool_socket_recv_into(&cp_serial.socket, c, 1);
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
if (len != -EAGAIN) {
|
|
||||||
ESP_LOGE(TAG, "recv error %d", len);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
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
|
// Set the TCP socket to send immediately so that we send the payload back before
|
||||||
// closing the connection.
|
// closing the connection.
|
||||||
int nodelay = 1;
|
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];
|
uint8_t frame_header[2];
|
||||||
frame_header[0] = 1 << 7 | opcode;
|
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;
|
frame_header[1] = cp_serial.payload_remaining;
|
||||||
web_workflow_send_raw(&cp_serial.socket, (const uint8_t *)frame_header, 2);
|
web_workflow_send_raw(&cp_serial.socket, (const uint8_t *)frame_header, 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ SRC_SUPERVISOR = \
|
||||||
supervisor/shared/background_callback.c \
|
supervisor/shared/background_callback.c \
|
||||||
supervisor/shared/board.c \
|
supervisor/shared/board.c \
|
||||||
supervisor/shared/cpu.c \
|
supervisor/shared/cpu.c \
|
||||||
|
supervisor/shared/fatfs.c \
|
||||||
supervisor/shared/flash.c \
|
supervisor/shared/flash.c \
|
||||||
supervisor/shared/lock.c \
|
supervisor/shared/lock.c \
|
||||||
supervisor/shared/memory.c \
|
supervisor/shared/memory.c \
|
||||||
|
|
Loading…
Reference in New Issue