From 8bab7b664c9627dfbaa32b3bf64893d7487f1cd0 Mon Sep 17 00:00:00 2001 From: Yihui Xiong Date: Wed, 19 Aug 2020 20:18:17 +0800 Subject: [PATCH 01/78] support to get HID OUT report --- shared-bindings/usb_hid/Device.c | 20 ++++++++++++++++++++ shared-module/usb_hid/Device.c | 17 ++++++++++------- shared-module/usb_hid/Device.h | 2 ++ tools/gen_usb_descriptor.py | 16 +++++++++++++--- tools/hid_report_descriptors.py | 18 +++++++++--------- 5 files changed, 54 insertions(+), 19 deletions(-) diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index 83c0df4ae4..2fbc5fe51b 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -58,6 +58,25 @@ STATIC mp_obj_t usb_hid_device_send_report(mp_obj_t self_in, mp_obj_t buffer) { } MP_DEFINE_CONST_FUN_OBJ_2(usb_hid_device_send_report_obj, usb_hid_device_send_report); +//|report: bytes +//| """The HID OUT report as a `bytes`. (read-only)""" +//| +STATIC mp_obj_t usb_hid_device_obj_get_report(mp_obj_t self_in) { + usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->out_report_buffer == 0) { + return mp_const_none; + } + return mp_obj_new_bytes(self->out_report_buffer, self->out_report_length); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_report_obj, usb_hid_device_obj_get_report); + +const mp_obj_property_t usb_hid_device_report_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&usb_hid_device_get_report_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + //| usage_page: int //| """The usage page of the device as an `int`. Can be thought of a category. (read-only)""" //| @@ -96,6 +115,7 @@ const mp_obj_property_t usb_hid_device_usage_obj = { STATIC const mp_rom_map_elem_t usb_hid_device_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_report), MP_ROM_PTR(&usb_hid_device_report_obj) }, { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj)}, { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj)}, }; diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c index 8e9df6f040..943c9bfed7 100644 --- a/shared-module/usb_hid/Device.c +++ b/shared-module/usb_hid/Device.c @@ -84,14 +84,17 @@ uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, // Callbacks invoked when receive Set_Report request through control endpoint void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { + if (report_type == HID_REPORT_TYPE_INVALID) { + report_id = buffer[0]; + buffer++; + bufsize--; + } else if (report_type != HID_REPORT_TYPE_OUTPUT) { + return; + } + usb_hid_device_obj_t* hid_device = get_hid_device(report_id); - if ( report_type == HID_REPORT_TYPE_OUTPUT ) { - // Check if it is Keyboard device - if (hid_device->usage_page == HID_USAGE_PAGE_DESKTOP && - hid_device->usage == HID_USAGE_DESKTOP_KEYBOARD) { - // This is LED indicator (CapsLock, NumLock) - // TODO Light up some LED here - } + if (hid_device && hid_device->out_report_length >= bufsize) { + memcpy(hid_device->out_report_buffer, buffer, bufsize); } } diff --git a/shared-module/usb_hid/Device.h b/shared-module/usb_hid/Device.h index 10f2ee897d..93c3518b43 100644 --- a/shared-module/usb_hid/Device.h +++ b/shared-module/usb_hid/Device.h @@ -43,6 +43,8 @@ typedef struct { uint8_t report_length; uint8_t usage_page; uint8_t usage; + uint8_t* out_report_buffer; + uint8_t out_report_length; } usb_hid_device_obj_t; diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py index fb91fd3345..4ad6cfb565 100644 --- a/tools/gen_usb_descriptor.py +++ b/tools/gen_usb_descriptor.py @@ -535,7 +535,7 @@ c_file.write(""" }; """) -c_file.write("\n"); +c_file.write("\n") hid_descriptor_length = len(bytes(combined_hid_report_descriptor)) @@ -593,12 +593,18 @@ for name in args.hid_devices: static uint8_t {name}_report_buffer[{report_length}]; """.format(name=name.lower(), report_length=hid_report_descriptors.HID_DEVICE_DATA[name].report_length)) + if hid_report_descriptors.HID_DEVICE_DATA[name].out_report_length > 0: + c_file.write("""\ +static uint8_t {name}_out_report_buffer[{report_length}]; +""".format(name=name.lower(), report_length=hid_report_descriptors.HID_DEVICE_DATA[name].out_report_length)) + # Write out table of device objects. c_file.write(""" usb_hid_device_obj_t usb_hid_devices[] = { -"""); +""") for name in args.hid_devices: device_data = hid_report_descriptors.HID_DEVICE_DATA[name] + out_report_buffer = '{}_out_report_buffer'.format(name.lower()) if device_data.out_report_length > 0 else 'NULL' c_file.write("""\ {{ .base = {{ .type = &usb_hid_device_type }}, @@ -607,11 +613,15 @@ for name in args.hid_devices: .report_length = {report_length}, .usage_page = {usage_page:#04x}, .usage = {usage:#04x}, + .out_report_buffer = {out_report_buffer}, + .out_report_length = {out_report_length}, }}, """.format(name=name.lower(), report_id=report_ids[name], report_length=device_data.report_length, usage_page=device_data.usage_page, - usage=device_data.usage)) + usage=device_data.usage, + out_report_buffer=out_report_buffer, + out_report_length=device_data.out_report_length)) c_file.write("""\ }; """) diff --git a/tools/hid_report_descriptors.py b/tools/hid_report_descriptors.py index e13e0dbdd1..aaa5b18b1f 100644 --- a/tools/hid_report_descriptors.py +++ b/tools/hid_report_descriptors.py @@ -18,16 +18,16 @@ from adafruit_usb_descriptor import hid # Information about each kind of device # report_length does not include report ID in first byte, if present when sent. -DeviceData = namedtuple('DeviceData', ('report_length', 'usage_page', 'usage')) +DeviceData = namedtuple('DeviceData', ('report_length', 'out_report_length', 'usage_page', 'usage')) HID_DEVICE_DATA = { - "KEYBOARD" : DeviceData(report_length=8, usage_page=0x01, usage=0x06), # Generic Desktop, Keyboard - "MOUSE" : DeviceData(report_length=4, usage_page=0x01, usage=0x02), # Generic Desktop, Mouse - "CONSUMER" : DeviceData(report_length=2, usage_page=0x0C, usage=0x01), # Consumer, Consumer Control - "SYS_CONTROL" : DeviceData(report_length=1, usage_page=0x01, usage=0x80), # Generic Desktop, Sys Control - "GAMEPAD" : DeviceData(report_length=6, usage_page=0x01, usage=0x05), # Generic Desktop, Game Pad - "DIGITIZER" : DeviceData(report_length=5, usage_page=0x0D, usage=0x02), # Digitizers, Pen - "XAC_COMPATIBLE_GAMEPAD" : DeviceData(report_length=3, usage_page=0x01, usage=0x05), # Generic Desktop, Game Pad - "RAW" : DeviceData(report_length=64, usage_page=0xFFAF, usage=0xAF), # Vendor 0xFFAF "Adafruit", 0xAF + "KEYBOARD" : DeviceData(report_length=8, out_report_length=1, usage_page=0x01, usage=0x06), # Generic Desktop, Keyboard + "MOUSE" : DeviceData(report_length=4, out_report_length=0, usage_page=0x01, usage=0x02), # Generic Desktop, Mouse + "CONSUMER" : DeviceData(report_length=2, out_report_length=0, usage_page=0x0C, usage=0x01), # Consumer, Consumer Control + "SYS_CONTROL" : DeviceData(report_length=1, out_report_length=0, usage_page=0x01, usage=0x80), # Generic Desktop, Sys Control + "GAMEPAD" : DeviceData(report_length=6, out_report_length=0, usage_page=0x01, usage=0x05), # Generic Desktop, Game Pad + "DIGITIZER" : DeviceData(report_length=5, out_report_length=0, usage_page=0x0D, usage=0x02), # Digitizers, Pen + "XAC_COMPATIBLE_GAMEPAD" : DeviceData(report_length=3, out_report_length=0, usage_page=0x01, usage=0x05), # Generic Desktop, Game Pad + "RAW" : DeviceData(report_length=64, out_report_length=0, usage_page=0xFFAF, usage=0xAF), # Vendor 0xFFAF "Adafruit", 0xAF } def keyboard_hid_descriptor(report_id): From 9aca580195b8381d0db6663dd0dbe22f465ce170 Mon Sep 17 00:00:00 2001 From: Yihui Xiong Date: Wed, 19 Aug 2020 21:33:51 +0800 Subject: [PATCH 02/78] fix --- shared-bindings/usb_hid/Device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index 2fbc5fe51b..a6c268c74d 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -58,7 +58,7 @@ STATIC mp_obj_t usb_hid_device_send_report(mp_obj_t self_in, mp_obj_t buffer) { } MP_DEFINE_CONST_FUN_OBJ_2(usb_hid_device_send_report_obj, usb_hid_device_send_report); -//|report: bytes +//| report: bytes //| """The HID OUT report as a `bytes`. (read-only)""" //| STATIC mp_obj_t usb_hid_device_obj_get_report(mp_obj_t self_in) { From c5b8401a15b4a34736d0ba86691eb441f65099e2 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 28 Jul 2020 18:23:33 -0700 Subject: [PATCH 03/78] First crack at native wifi API --- ports/esp32s2/Makefile | 25 ++- ports/esp32s2/common-hal/wifi/Network.c | 31 ++++ ports/esp32s2/common-hal/wifi/Network.h | 37 +++++ ports/esp32s2/common-hal/wifi/Radio.c | 59 +++++++ ports/esp32s2/common-hal/wifi/Radio.h | 37 +++++ ports/esp32s2/common-hal/wifi/__init__.c | 49 ++++++ ports/esp32s2/common-hal/wifi/__init__.h | 32 ++++ ports/esp32s2/esp-idf | 2 +- ports/esp32s2/mpconfigport.mk | 2 + ports/esp32s2/sdkconfig.defaults | 6 +- py/circuitpy_defns.mk | 6 + py/circuitpy_mpconfig.h | 8 + py/circuitpy_mpconfig.mk | 3 + shared-bindings/wifi/Network.c | 70 ++++++++ shared-bindings/wifi/Network.h | 40 +++++ shared-bindings/wifi/Radio.c | 196 +++++++++++++++++++++++ shared-bindings/wifi/Radio.h | 52 ++++++ shared-bindings/wifi/__init__.c | 71 ++++++++ shared-bindings/wifi/__init__.h | 38 +++++ 19 files changed, 753 insertions(+), 11 deletions(-) create mode 100644 ports/esp32s2/common-hal/wifi/Network.c create mode 100644 ports/esp32s2/common-hal/wifi/Network.h create mode 100644 ports/esp32s2/common-hal/wifi/Radio.c create mode 100644 ports/esp32s2/common-hal/wifi/Radio.h create mode 100644 ports/esp32s2/common-hal/wifi/__init__.c create mode 100644 ports/esp32s2/common-hal/wifi/__init__.h create mode 100644 shared-bindings/wifi/Network.c create mode 100644 shared-bindings/wifi/Network.h create mode 100644 shared-bindings/wifi/Radio.c create mode 100644 shared-bindings/wifi/Radio.h create mode 100644 shared-bindings/wifi/__init__.c create mode 100644 shared-bindings/wifi/__init__.h diff --git a/ports/esp32s2/Makefile b/ports/esp32s2/Makefile index 19b89a13a1..b4abac60d7 100644 --- a/ports/esp32s2/Makefile +++ b/ports/esp32s2/Makefile @@ -78,8 +78,11 @@ INC += -Iesp-idf/components/freertos/xtensa/include INC += -Iesp-idf/components/esp32s2/include INC += -Iesp-idf/components/xtensa/esp32s2/include INC += -Iesp-idf/components/esp_common/include +INC += -Iesp-idf/components/esp_event/include +INC += -Iesp-idf/components/esp_netif/include INC += -Iesp-idf/components/esp_ringbuf/include INC += -Iesp-idf/components/esp_rom/include +INC += -Iesp-idf/components/esp_wifi/include INC += -Iesp-idf/components/xtensa/include INC += -Iesp-idf/components/esp_timer/include INC += -Iesp-idf/components/soc/include @@ -129,7 +132,7 @@ LDFLAGS += -L$(BUILD)/esp-idf/esp-idf/esp32s2 \ -Tesp32s2.rom.newlib-data.ld \ -Tesp32s2.rom.newlib-funcs.ld \ -Tesp32s2.rom.spiflash.ld -LIBS := -lgcc -lc +LIBS := -lgcc -lc -lstdc++ # @@ -238,20 +241,25 @@ $(BUILD)/esp-idf/partition_table/partition-table.bin: $(BUILD)/esp-idf/config/sd # run menuconfig menuconfig: $(BUILD)/esp-idf/config - ninja -C $(BUILD)/esp-idf menuconfig - diff --old-line-format= --unchanged-line-format= sdkconfig.defaults $(BUILD)/esp-idf/sdkconfig > boards/$(BOARD)/sdkconfig || true + $(Q)ninja -C $(BUILD)/esp-idf menuconfig + $(Q)diff --old-line-format= --unchanged-line-format= sdkconfig.defaults $(BUILD)/esp-idf/sdkconfig > boards/$(BOARD)/sdkconfig || true # qstr builds include headers so we need to make sure they are up to date $(HEADER_BUILD)/qstr.i.last: | $(BUILD)/esp-idf/config/sdkconfig.h # Order here matters -ESP_IDF_COMPONENTS_LINK = freertos log esp_system esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf # +ESP_IDF_COMPONENTS_LINK = freertos log esp_system esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash ESP_IDF_COMPONENTS_INCLUDE = driver freertos log soc INC += $(foreach component, $(ESP_IDF_COMPONENTS_INCLUDE), -Iesp-idf/components/$(component)/include) ESP_IDF_COMPONENTS_EXPANDED = $(foreach component, $(ESP_IDF_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/$(component)/lib$(component).a) +ESP_IDF_WIFI_COMPONENTS_EXPANDED = $(foreach component, $(ESP_IDF_WIFI_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/$(component)/lib$(component).a) + +MBEDTLS_COMPONENTS_LINK = crypto tls x509 +MBEDTLS_COMPONENTS_LINK_EXPANDED = $(foreach component, $(MBEDTLS_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/mbedtls/mbedtls/library/libmbed$(component).a) + BINARY_BLOBS = esp-idf/components/xtensa/esp32s2/libhal.a BINARY_WIFI_BLOBS = libcoexist.a libcore.a libespnow.a libmesh.a libnet80211.a libpp.a librtc.a libsmartconfig.a libphy.a BINARY_BLOBS += $(addprefix esp-idf/components/esp_wifi/lib/esp32s2/, $(BINARY_WIFI_BLOBS)) @@ -265,18 +273,23 @@ all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 .PHONY: esp-idf-stamp esp-idf-stamp: $(BUILD)/esp-idf/config/sdkconfig.h - ninja -C $(BUILD)/esp-idf \ + $(Q)ninja -C $(BUILD)/esp-idf \ bootloader/bootloader.bin \ esp-idf/bootloader_support/libbootloader_support.a \ esp-idf/esp32s2/ld/esp32s2.project.ld \ + esp-idf/esp_event/libesp_event.a \ esp-idf/esp_system/libesp_system.a \ + esp-idf/esp_wifi/libesp_wifi.a \ + esp-idf/nvs_flash/libnvs_flash.a \ + esp-idf/wpa_supplicant/libwpa_supplicant.a \ + esp-idf/mbedtls/libmbedtls.a \ esp-idf/freertos/libfreertos.a \ esp-idf/log/liblog.a \ esp-idf/xtensa/libxtensa.a $(BUILD)/firmware.elf: $(OBJ) | esp-idf-stamp $(STEPECHO) "LINK $@" - $(Q)$(CC) -o $@ $(LDFLAGS) $^ $(ESP_IDF_COMPONENTS_EXPANDED) $(BINARY_BLOBS) build-$(BOARD)/esp-idf/esp-idf/newlib/libnewlib.a -u newlib_include_pthread_impl -Wl,--start-group $(LIBS) -Wl,--end-group + $(Q)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(ESP_IDF_COMPONENTS_EXPANDED) $(BINARY_BLOBS) $(MBEDTLS_COMPONENTS_LINK_EXPANDED) build-$(BOARD)/esp-idf/esp-idf/newlib/libnewlib.a -Wl,--end-group -u newlib_include_pthread_impl -Wl,--start-group $(LIBS) -Wl,--end-group build-$(BOARD)/esp-idf/esp-idf/pthread/libpthread.a -u __cxx_fatal_exception # $(Q)$(SIZE) $@ | $(PYTHON3) $(TOP)/tools/build_memory_info.py $(BUILD)/esp-idf/esp-idf/esp32s2/esp32s2_out.ld $(BUILD)/circuitpython-firmware.bin: $(BUILD)/firmware.elf diff --git a/ports/esp32s2/common-hal/wifi/Network.c b/ports/esp32s2/common-hal/wifi/Network.c new file mode 100644 index 0000000000..a270fd9dcc --- /dev/null +++ b/ports/esp32s2/common-hal/wifi/Network.c @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/wifi/Network.h" + +mp_obj_t common_hal_wifi_network_get_ssid(wifi_network_obj_t *self) { + return mp_const_none; +} diff --git a/ports/esp32s2/common-hal/wifi/Network.h b/ports/esp32s2/common-hal/wifi/Network.h new file mode 100644 index 0000000000..26d02d3fc2 --- /dev/null +++ b/ports/esp32s2/common-hal/wifi/Network.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_NETWORK_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_NETWORK_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} wifi_network_obj_t; + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_NETWORK_H diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c new file mode 100644 index 0000000000..bbbeb23a20 --- /dev/null +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -0,0 +1,59 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/wifi/Radio.h" + +bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self) { + return true; +} + +void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) { + +} + +mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) { + return mp_const_none; +} + +mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) { + return mp_const_none; +} + +void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self) { + +} + +bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, mp_float_t timeout) { + return false; +} + +mp_obj_t common_hal_wifi_radio_get_ip_address(wifi_radio_obj_t *self) { + return mp_const_none; +} + +mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address) { + return 0; +} diff --git a/ports/esp32s2/common-hal/wifi/Radio.h b/ports/esp32s2/common-hal/wifi/Radio.h new file mode 100644 index 0000000000..56fc0d9d6e --- /dev/null +++ b/ports/esp32s2/common-hal/wifi/Radio.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_RADIO_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_RADIO_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} wifi_radio_obj_t; + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_RADIO_H diff --git a/ports/esp32s2/common-hal/wifi/__init__.c b/ports/esp32s2/common-hal/wifi/__init__.c new file mode 100644 index 0000000000..42410f4839 --- /dev/null +++ b/ports/esp32s2/common-hal/wifi/__init__.c @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/wifi/Radio.h" + +#include "py/runtime.h" + +#include "esp-idf/components/esp_wifi/include/esp_wifi.h" + +wifi_radio_obj_t common_hal_wifi_radio_obj; + +void common_hal_wifi_init(void) { + common_hal_wifi_radio_obj.base.type = &wifi_radio_type; + wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); + + esp_err_t result = esp_wifi_init(&config); + if (result == ESP_ERR_NO_MEM) { + mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate Wifi memory")); + } else if (result != ESP_OK) { + // handle this + } +} + +void wifi_reset(void) { + esp_wifi_deinit(); +} diff --git a/ports/esp32s2/common-hal/wifi/__init__.h b/ports/esp32s2/common-hal/wifi/__init__.h new file mode 100644 index 0000000000..e7ff7ec04a --- /dev/null +++ b/ports/esp32s2/common-hal/wifi/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI___INIT___H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI___INIT___H + +#include "py/obj.h" + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI___INIT___H diff --git a/ports/esp32s2/esp-idf b/ports/esp32s2/esp-idf index 160ba4924d..f5aff20b37 160000 --- a/ports/esp32s2/esp-idf +++ b/ports/esp32s2/esp-idf @@ -1 +1 @@ -Subproject commit 160ba4924d8b588e718f76e3a0d0e92c11052fa3 +Subproject commit f5aff20b378f7c4002605a4158a41630c21f343d diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index a7873aa468..dcfb0ecc5c 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -29,4 +29,6 @@ CIRCUITPY_RANDOM = 0 # Requires OS CIRCUITPY_USB_MIDI = 0 # Requires USB CIRCUITPY_ULAB = 0 # No requirements, but takes extra flash +CIRCUITPY_WIFI = 1 + CIRCUITPY_MODULE ?= none diff --git a/ports/esp32s2/sdkconfig.defaults b/ports/esp32s2/sdkconfig.defaults index 729ebac889..8245c7db6c 100644 --- a/ports/esp32s2/sdkconfig.defaults +++ b/ports/esp32s2/sdkconfig.defaults @@ -279,9 +279,7 @@ CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y # # Ethernet # -CONFIG_ETH_ENABLED=y -CONFIG_ETH_USE_SPI_ETHERNET=y -# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set +# CONFIG_ETH_USE_SPI_ETHERNET is not set # CONFIG_ETH_USE_OPENETH is not set # end of Ethernet @@ -299,7 +297,7 @@ CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set -CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y +# CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER is not set # end of ESP NETIF Adapter # diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index b70ae64a80..5d5b6996d1 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -261,6 +261,9 @@ endif ifeq ($(CIRCUITPY_WATCHDOG),1) SRC_PATTERNS += watchdog/% endif +ifeq ($(CIRCUITPY_WIFI),1) +SRC_PATTERNS += wifi/% +endif ifeq ($(CIRCUITPY_PEW),1) SRC_PATTERNS += _pew/% endif @@ -333,6 +336,9 @@ SRC_COMMON_HAL_ALL = \ watchdog/WatchDogMode.c \ watchdog/WatchDogTimer.c \ watchdog/__init__.c \ + wifi/Network.c \ + wifi/Radio.c \ + wifi/__init__.c \ SRC_COMMON_HAL = $(filter $(SRC_PATTERNS), $(SRC_COMMON_HAL_ALL)) diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 12d667d8f8..2db20ca1d1 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -683,6 +683,13 @@ extern const struct _mp_obj_module_t watchdog_module; #define WATCHDOG_MODULE #endif +#if CIRCUITPY_WIFI +extern const struct _mp_obj_module_t wifi_module; +#define WIFI_MODULE { MP_ROM_QSTR(MP_QSTR_wifi), MP_ROM_PTR(&wifi_module) }, +#else +#define WIFI_MODULE +#endif + // Define certain native modules with weak links so they can be replaced with Python // implementations. This list may grow over time. #define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \ @@ -759,6 +766,7 @@ extern const struct _mp_obj_module_t watchdog_module; USB_MIDI_MODULE \ USTACK_MODULE \ WATCHDOG_MODULE \ + WIFI_MODULE \ // If weak links are enabled, just include strong links in the main list of modules, // and also include the underscore alternate names. diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index bdc1e77d54..abbd5a9a0b 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -254,6 +254,9 @@ CFLAGS += -DCIRCUITPY_ULAB=$(CIRCUITPY_ULAB) CIRCUITPY_WATCHDOG ?= 0 CFLAGS += -DCIRCUITPY_WATCHDOG=$(CIRCUITPY_WATCHDOG) +CIRCUITPY_WIFI ?= 0 +CFLAGS += -DCIRCUITPY_WIFI=$(CIRCUITPY_WIFI) + # Enabled micropython.native decorator (experimental) CIRCUITPY_ENABLE_MPY_NATIVE ?= 0 CFLAGS += -DCIRCUITPY_ENABLE_MPY_NATIVE=$(CIRCUITPY_ENABLE_MPY_NATIVE) diff --git a/shared-bindings/wifi/Network.c b/shared-bindings/wifi/Network.c new file mode 100644 index 0000000000..b4d389dcc9 --- /dev/null +++ b/shared-bindings/wifi/Network.c @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/wifi/Network.h" + +//| class Network: +//| """A wifi network provided by a nearby access point. +//| +//| """ +//| + +//| def __init__(self) -> None: +//| """You cannot create an instance of `wifi.Network`. They are returned by `wifi.Radio.start_scanning_networks`.""" +//| ... +//| + +//| ssid: str +//| """True when the wifi network is enabled.""" +//| +STATIC mp_obj_t wifi_network_get_ssid(mp_obj_t self) { + return common_hal_wifi_network_get_ssid(self); + +} +MP_DEFINE_CONST_FUN_OBJ_1(wifi_network_get_ssid_obj, wifi_network_get_ssid); + +const mp_obj_property_t wifi_network_ssid_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&wifi_network_get_ssid_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t wifi_network_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_ssid), MP_ROM_PTR(&wifi_network_ssid_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(wifi_network_locals_dict, wifi_network_locals_dict_table); + +const mp_obj_type_t wifi_network_type = { + .base = { &mp_type_type }, + .name = MP_QSTR_Network, + .locals_dict = (mp_obj_t)&wifi_network_locals_dict, +}; diff --git a/shared-bindings/wifi/Network.h b/shared-bindings/wifi/Network.h new file mode 100644 index 0000000000..8a3d10ca74 --- /dev/null +++ b/shared-bindings/wifi/Network.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_NETWORK_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_NETWORK_H + +#include + +#include "common-hal/wifi/Network.h" + +#include "py/objstr.h" + +const mp_obj_type_t wifi_network_type; + +extern mp_obj_t common_hal_wifi_network_get_ssid(wifi_network_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_NETWORK_H diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c new file mode 100644 index 0000000000..1eb07d8fcf --- /dev/null +++ b/shared-bindings/wifi/Radio.c @@ -0,0 +1,196 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/wifi/__init__.h" + +//| class Radio: +//| """Native wifi radio. +//| +//| This class manages the station and access point functionality of the native +//| Wifi radio. +//| +//| """ +//| + +//| def __init__(self) -> None: +//| """You cannot create an instance of `wifi.Radio`. +//| Use `wifi.radio` to access the sole instance available.""" +//| ... +//| + +//| enabled: bool +//| """True when the wifi radio is enabled.""" +//| +STATIC mp_obj_t wifi_radio_get_enabled(mp_obj_t self) { + return mp_obj_new_bool(common_hal_wifi_radio_get_enabled(self)); + +} +MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_enabled_obj, wifi_radio_get_enabled); + +const mp_obj_property_t wifi_radio_enabled_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&wifi_radio_get_enabled_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| mac_address: Address +//| """MAC address of the wifi radio. (read-only)""" +//| +STATIC mp_obj_t wifi_radio_get_mac_address(mp_obj_t self) { + return MP_OBJ_FROM_PTR(common_hal_wifi_radio_get_mac_address(self)); + +} +MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_mac_address_obj, wifi_radio_get_mac_address); + +const mp_obj_property_t wifi_radio_mac_address_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&wifi_radio_get_mac_address_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + + +//| def start_scanning_networks(self) -> Iterable[Network]: +//| """""" +//| ... +//| +STATIC mp_obj_t wifi_radio_start_scanning_networks(mp_obj_t self_in) { + wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_wifi_radio_start_scanning_networks(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_start_scanning_networks_obj, wifi_radio_start_scanning_networks); + +//| def stop_scanning_networks(self) -> None: +//| """Stop scanning for Wifi networks and free any resources used to do it.""" +//| ... +//| +STATIC mp_obj_t wifi_radio_stop_scanning_networks(mp_obj_t self_in) { + wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_wifi_radio_stop_scanning_networks(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_scanning_networks_obj, wifi_radio_stop_scanning_networks); + +//| def connect(self, ssid: ReadableBuffer, password: ReadableBuffer = b"", *, timeout: Optional[float] = None) -> bool: +//| """""" +//| ... +//| +STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_ssid, ARG_password, ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_password, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + wifi_radio_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_float_t timeout = 0; + if (args[ARG_timeout].u_obj != mp_const_none) { + timeout = mp_obj_get_float(args[ARG_timeout].u_obj); + } + + + mp_buffer_info_t ssid; + ssid.len = 0; + if (args[ARG_ssid].u_obj != MP_OBJ_NULL) { + mp_get_buffer_raise(args[ARG_ssid].u_obj, &ssid, MP_BUFFER_READ); + } + + mp_buffer_info_t password; + password.len = 0; + if (args[ARG_password].u_obj != MP_OBJ_NULL) { + mp_get_buffer_raise(args[ARG_password].u_obj, &password, MP_BUFFER_READ); + } + + return mp_obj_new_bool(common_hal_wifi_radio_connect(self, ssid.buf, ssid.len, password.buf, password.len, timeout)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_connect_obj, 1, wifi_radio_connect); + +//| ip_address: Optional[ipaddress.IPAddress] +//| """IP Address of the radio when connected to an access point. None otherwise.""" +//| +STATIC mp_obj_t wifi_radio_get_ip_address(mp_obj_t self) { + return common_hal_wifi_radio_get_ip_address(self); + +} +MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ip_address_obj, wifi_radio_get_ip_address); + +const mp_obj_property_t wifi_radio_ip_address_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&wifi_radio_get_ip_address_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +//| def ping(self, ip) -> int: +//| """Ping an IP to test connectivity. Returns echo time in milliseconds.""" +//| ... +//| +STATIC mp_obj_t wifi_radio_ping(mp_obj_t self_in, mp_obj_t ip_address) { + wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_wifi_radio_ping(self, ip_address); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(wifi_radio_ping_obj, wifi_radio_ping); + +STATIC const mp_rom_map_elem_t wifi_radio_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_enabled), MP_ROM_PTR(&wifi_radio_enabled_obj) }, + { MP_ROM_QSTR(MP_QSTR_mac_address), MP_ROM_PTR(&wifi_radio_mac_address_obj) }, + + { MP_ROM_QSTR(MP_QSTR_start_scanning_networks), MP_ROM_PTR(&wifi_radio_start_scanning_networks_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_scanning_networks), MP_ROM_PTR(&wifi_radio_stop_scanning_networks_obj) }, + + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&wifi_radio_connect_obj) }, + // { MP_ROM_QSTR(MP_QSTR_connect_to_enterprise), MP_ROM_PTR(&wifi_radio_connect_to_enterprise_obj) }, + + { MP_ROM_QSTR(MP_QSTR_ip_address), MP_ROM_PTR(&wifi_radio_ip_address_obj) }, + + // { MP_ROM_QSTR(MP_QSTR_access_point_active), MP_ROM_PTR(&wifi_radio_access_point_active_obj) }, + // { MP_ROM_QSTR(MP_QSTR_start_access_point), MP_ROM_PTR(&wifi_radio_start_access_point_obj) }, + + { MP_ROM_QSTR(MP_QSTR_ping), MP_ROM_PTR(&wifi_radio_ping_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(wifi_radio_locals_dict, wifi_radio_locals_dict_table); + +const mp_obj_type_t wifi_radio_type = { + .base = { &mp_type_type }, + .name = MP_QSTR_Radio, + .locals_dict = (mp_obj_t)&wifi_radio_locals_dict, +}; diff --git a/shared-bindings/wifi/Radio.h b/shared-bindings/wifi/Radio.h new file mode 100644 index 0000000000..c3bdac5ba8 --- /dev/null +++ b/shared-bindings/wifi/Radio.h @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_RADIO_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_RADIO_H + +#include + +#include "common-hal/wifi/Radio.h" + +#include "py/objstr.h" + +const mp_obj_type_t wifi_radio_type; + +extern bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self); +extern void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled); + +extern mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self); + +extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self); +extern void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self); + +extern bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, mp_float_t timeout); + +extern mp_obj_t common_hal_wifi_radio_get_ip_address(wifi_radio_obj_t *self); + +extern mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_RADIO_H diff --git a/shared-bindings/wifi/__init__.c b/shared-bindings/wifi/__init__.c new file mode 100644 index 0000000000..a12881094c --- /dev/null +++ b/shared-bindings/wifi/__init__.c @@ -0,0 +1,71 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objexcept.h" +#include "py/runtime.h" +#include "shared-bindings/wifi/__init__.h" +#include "shared-bindings/wifi/Network.h" +#include "shared-bindings/wifi/Radio.h" + +//| """ +//| The `wifi` module provides necessary low-level functionality for managing wifi +//| wifi connections. Use `socketpool` for communicating over the network. +//| +//| .. attribute:: radio +//| +//| Wifi radio used to manage both station and AP modes. +//| This object is the sole instance of `wifi.Radio`.""" +//| + + +// Called when wifi is imported. +STATIC mp_obj_t wifi___init__(void) { + common_hal_wifi_init(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(wifi___init___obj, wifi___init__); + + +STATIC const mp_rom_map_elem_t wifi_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_wifi) }, + { MP_ROM_QSTR(MP_QSTR_Network), MP_ROM_PTR(&wifi_network_type) }, + { MP_ROM_QSTR(MP_QSTR_Radio), MP_ROM_PTR(&wifi_radio_type) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_radio), MP_ROM_PTR(&common_hal_wifi_radio_obj) }, + + // Initialization + { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&wifi___init___obj) }, + +}; + +STATIC MP_DEFINE_CONST_DICT(wifi_module_globals, wifi_module_globals_table); + + +const mp_obj_module_t wifi_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&wifi_module_globals, +}; diff --git a/shared-bindings/wifi/__init__.h b/shared-bindings/wifi/__init__.h new file mode 100644 index 0000000000..c06ee16be7 --- /dev/null +++ b/shared-bindings/wifi/__init__.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_WIFI___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_WIFI___INIT___H + +#include "py/objlist.h" + +#include "shared-bindings/wifi/Radio.h" + +extern wifi_radio_obj_t common_hal_wifi_radio_obj; + +void common_hal_wifi_init(void); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_WIFI___INIT___H From 1a6f4e0fe0f8417ea99a3cdb55d8764f47258bea Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 30 Jul 2020 17:58:12 -0700 Subject: [PATCH 04/78] Scanning WIP. Need to sort out supervisor memory --- ports/esp32s2/Makefile | 4 +- ports/esp32s2/common-hal/wifi/Network.h | 4 +- ports/esp32s2/common-hal/wifi/Radio.c | 44 ++++- ports/esp32s2/common-hal/wifi/Radio.h | 14 +- .../esp32s2/common-hal/wifi/ScannedNetworks.c | 159 ++++++++++++++++++ .../esp32s2/common-hal/wifi/ScannedNetworks.h | 62 +++++++ ports/esp32s2/common-hal/wifi/__init__.c | 72 +++++++- ports/esp32s2/common-hal/wifi/__init__.h | 2 + ports/esp32s2/esp-idf | 2 +- ports/esp32s2/partitions.csv | 10 +- ports/esp32s2/sdkconfig.defaults | 26 +-- ports/esp32s2/supervisor/port.c | 32 +++- py/circuitpy_defns.mk | 1 + shared-bindings/wifi/Radio.c | 4 +- shared-bindings/wifi/ScannedNetworks.c | 68 ++++++++ shared-bindings/wifi/ScannedNetworks.h | 39 +++++ supervisor/port.h | 2 + 17 files changed, 513 insertions(+), 32 deletions(-) create mode 100644 ports/esp32s2/common-hal/wifi/ScannedNetworks.c create mode 100644 ports/esp32s2/common-hal/wifi/ScannedNetworks.h create mode 100644 shared-bindings/wifi/ScannedNetworks.c create mode 100644 shared-bindings/wifi/ScannedNetworks.h diff --git a/ports/esp32s2/Makefile b/ports/esp32s2/Makefile index b4abac60d7..e14a737b7c 100644 --- a/ports/esp32s2/Makefile +++ b/ports/esp32s2/Makefile @@ -248,7 +248,7 @@ menuconfig: $(BUILD)/esp-idf/config $(HEADER_BUILD)/qstr.i.last: | $(BUILD)/esp-idf/config/sdkconfig.h # Order here matters -ESP_IDF_COMPONENTS_LINK = freertos log esp_system esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash +ESP_IDF_COMPONENTS_LINK = freertos log esp_system esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash esp_netif lwip ESP_IDF_COMPONENTS_INCLUDE = driver freertos log soc @@ -278,8 +278,10 @@ esp-idf-stamp: $(BUILD)/esp-idf/config/sdkconfig.h esp-idf/bootloader_support/libbootloader_support.a \ esp-idf/esp32s2/ld/esp32s2.project.ld \ esp-idf/esp_event/libesp_event.a \ + esp-idf/esp_netif/libesp_netif.a \ esp-idf/esp_system/libesp_system.a \ esp-idf/esp_wifi/libesp_wifi.a \ + esp-idf/lwip/liblwip.a \ esp-idf/nvs_flash/libnvs_flash.a \ esp-idf/wpa_supplicant/libwpa_supplicant.a \ esp-idf/mbedtls/libmbedtls.a \ diff --git a/ports/esp32s2/common-hal/wifi/Network.h b/ports/esp32s2/common-hal/wifi/Network.h index 26d02d3fc2..ab75fcafe5 100644 --- a/ports/esp32s2/common-hal/wifi/Network.h +++ b/ports/esp32s2/common-hal/wifi/Network.h @@ -29,9 +29,11 @@ #include "py/obj.h" +#include "esp-idf/components/esp_wifi/include/esp_wifi_types.h" + typedef struct { mp_obj_base_t base; - // Stores no state currently. + wifi_ap_record_t record; } wifi_network_obj_t; #endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_NETWORK_H diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c index bbbeb23a20..0bdcfb01a4 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.c +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -26,28 +26,62 @@ #include "shared-bindings/wifi/Radio.h" +#include "py/runtime.h" +#include "shared-bindings/wifi/ScannedNetworks.h" + +#include "esp-idf/components/esp_wifi/include/esp_wifi.h" + bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self) { - return true; + return self->started; } void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) { - + if (self->started && !enabled) { + esp_wifi_stop(); + self->started = false; + return; + } + if (!self->started && enabled) { + esp_wifi_start(); + self->started = true; + return; + } } mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) { + uint8_t mac[6]; + esp_wifi_get_mac(ESP_IF_WIFI_STA, mac); return mp_const_none; } mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) { - return mp_const_none; + if (self->current_scan != NULL) { + mp_raise_RuntimeError(translate("Already scanning for wifi networks")); + } + // check enabled + + wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t); + self->current_scan = scan; + scan->base.type = &wifi_scannednetworks_type; + scan->start_channel = 1; + scan->end_channel = 11; + scan->radio_event_group = self->event_group_handle; + wifi_scannednetworks_scan_next_channel(scan); + return scan; } void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self) { - + // Free the memory used to store the found aps. + wifi_scannednetworks_deinit(self->current_scan); + self->current_scan = NULL; } bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, mp_float_t timeout) { - return false; + // check enabled + wifi_config_t config; + esp_err_t result = esp_wifi_set_config(ESP_IF_WIFI_STA, &config); + result = esp_wifi_connect(); + return result == ESP_OK; } mp_obj_t common_hal_wifi_radio_get_ip_address(wifi_radio_obj_t *self) { diff --git a/ports/esp32s2/common-hal/wifi/Radio.h b/ports/esp32s2/common-hal/wifi/Radio.h index 56fc0d9d6e..f681213dd8 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.h +++ b/ports/esp32s2/common-hal/wifi/Radio.h @@ -29,9 +29,21 @@ #include "py/obj.h" +#include "esp-idf/components/esp_event/include/esp_event.h" + +#include "shared-bindings/wifi/ScannedNetworks.h" + +// Event bits for the Radio event group. +#define WIFI_SCAN_DONE_BIT BIT0 + typedef struct { mp_obj_base_t base; - // Stores no state currently. + esp_event_handler_instance_t handler_instance_all_wifi; + esp_event_handler_instance_t handler_instance_got_ip; + wifi_scannednetworks_obj_t *current_scan; + StaticEventGroup_t event_group; + EventGroupHandle_t event_group_handle; + bool started; } wifi_radio_obj_t; #endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_RADIO_H diff --git a/ports/esp32s2/common-hal/wifi/ScannedNetworks.c b/ports/esp32s2/common-hal/wifi/ScannedNetworks.c new file mode 100644 index 0000000000..a67a5f3bd8 --- /dev/null +++ b/ports/esp32s2/common-hal/wifi/ScannedNetworks.c @@ -0,0 +1,159 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 + +#include "lib/utils/interrupt_char.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/wifi/__init__.h" +#include "shared-bindings/wifi/Network.h" +#include "shared-bindings/wifi/Radio.h" +#include "shared-bindings/wifi/ScannedNetworks.h" + +#include "esp-idf/components/esp_wifi/include/esp_wifi.h" + +static void wifi_scannednetworks_done(wifi_scannednetworks_obj_t *self) { + self->done = true; + free(self->results); + self->results = NULL; +} + +static bool wifi_scannednetworks_wait_for_scan(wifi_scannednetworks_obj_t *self) { + EventBits_t bits = xEventGroupWaitBits(self->radio_event_group, + WIFI_SCAN_DONE_BIT, + pdTRUE, + pdTRUE, + 0); + while ((bits & WIFI_SCAN_DONE_BIT) == 0 && !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + bits = xEventGroupWaitBits(self->radio_event_group, + WIFI_SCAN_DONE_BIT, + pdTRUE, + pdTRUE, + 0); + } + return !mp_hal_is_interrupted(); +} + +mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) { + if (self->done) { + return mp_const_none; + } + // If we are scanning, wait and then load them. + if (self->scanning) { + // We may have to scan more than one channel to get a result. + while (!self->done) { + if (!wifi_scannednetworks_wait_for_scan(self)) { + wifi_scannednetworks_done(self); + return mp_const_none; + } + + esp_wifi_scan_get_ap_num(&self->total_results); + if (self->total_results > 0) { + break; + } + // If total_results is zero then we need to start a scan and wait again. + wifi_scannednetworks_scan_next_channel(self); + } + // We not have found any more results so we're done. + if (self->done) { + return mp_const_none; + } + // If we need more space than we have, realloc. + if (self->total_results > self->max_results) { + wifi_ap_record_t* results = m_renew_maybe(wifi_ap_record_t, + self->results, + self->max_results, + self->total_results, + true /* allow move */); + if (results != NULL) { + self->results = results; + self->max_results = self->total_results; + } else { + if (self->max_results == 0) { + // No room for any results should error. + mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate wifi scan memory")); + } + // Unable to allocate more results, so load what we can. + self->total_results = self->max_results; + } + } + esp_wifi_scan_get_ap_records(&self->total_results, self->results); + self->scanning = false; + } + + wifi_network_obj_t *entry = m_new_obj(wifi_network_obj_t); + entry->base.type = &wifi_network_type; + memcpy(&entry->record, &self->results[self->current_result], sizeof(wifi_ap_record_t)); + self->current_result++; + + // If we're returning our last network then start the next channel scan or + // be done. + if (self->current_result >= self->total_results) { + wifi_scannednetworks_scan_next_channel(self); + self->total_results = 0; + self->current_result = 0; + } + + return MP_OBJ_FROM_PTR(entry); +} + +// We don't do a linear scan so that we look at a variety of spectrum up front. +static uint8_t scan_pattern[] = {6, 1, 11, 3, 9, 13, 2, 4, 8, 12, 5, 7, 10, 14}; + +void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self) { + wifi_scan_config_t config; + uint8_t next_channel = sizeof(scan_pattern); + while (self->current_channel_index < sizeof(scan_pattern)) { + next_channel = scan_pattern[self->current_channel_index]; + self->current_channel_index++; + if (self->start_channel <= next_channel && next_channel <= self->end_channel) { + break; + } + } + if (next_channel == sizeof(scan_pattern) || + esp_wifi_scan_start(&config, false) != ESP_OK) { + wifi_scannednetworks_done(self); + } else { + self->scanning = true; + } +} + +void wifi_scannednetworks_deinit(wifi_scannednetworks_obj_t* self) { + // if a scan is active, make sure and clean up the idf's buffer of results. + if (self->scanning) { + esp_wifi_scan_stop(); + if (wifi_scannednetworks_wait_for_scan(self)) { + uint16_t number = 0; + esp_wifi_scan_get_ap_records(&number, NULL); + self->scanning = false; + } + } + wifi_scannednetworks_done(self); +} diff --git a/ports/esp32s2/common-hal/wifi/ScannedNetworks.h b/ports/esp32s2/common-hal/wifi/ScannedNetworks.h new file mode 100644 index 0000000000..cd57e95f29 --- /dev/null +++ b/ports/esp32s2/common-hal/wifi/ScannedNetworks.h @@ -0,0 +1,62 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_SCANNEDNETWORKS_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_SCANNEDNETWORKS_H + +#include + +#include "py/obj.h" + +#include "FreeRTOS.h" +#include "freertos/event_groups.h" + +#include "esp-idf/components/esp_wifi/include/esp_wifi_types.h" + +typedef struct { + mp_obj_base_t base; + uint8_t current_channel_index; + EventGroupHandle_t radio_event_group; + + // Results from the last channel scan + wifi_ap_record_t* results; + uint16_t current_result; + uint16_t total_results; + uint16_t max_results; + + // Limits on what channels to scan. + uint8_t start_channel; + uint8_t end_channel; // Inclusive + + bool done; + bool scanning; +} wifi_scannednetworks_obj_t; + +void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self); +void wifi_scannednetworks_deinit(wifi_scannednetworks_obj_t *self); + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_SCANNEDNETWORKS_H diff --git a/ports/esp32s2/common-hal/wifi/__init__.c b/ports/esp32s2/common-hal/wifi/__init__.c index 42410f4839..9f08603b50 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.c +++ b/ports/esp32s2/common-hal/wifi/__init__.c @@ -28,22 +28,88 @@ #include "py/runtime.h" +#include "esp_log.h" +static const char *TAG = "cp wifi"; + #include "esp-idf/components/esp_wifi/include/esp_wifi.h" wifi_radio_obj_t common_hal_wifi_radio_obj; -void common_hal_wifi_init(void) { - common_hal_wifi_radio_obj.base.type = &wifi_radio_type; - wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); +static void event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { + ESP_LOGI(TAG, "event"); + wifi_radio_obj_t* radio = arg; + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) { + xEventGroupSetBits(radio->event_group_handle, WIFI_SCAN_DONE_BIT); + } + // esp_wifi_connect(); + // if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + // esp_wifi_connect(); + // } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + // if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { + // esp_wifi_connect(); + // s_retry_num++; + // ESP_LOGI(TAG, "retry to connect to the AP"); + // } else { + // xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + // } + // ESP_LOGI(TAG,"connect to the AP fail"); + // } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + // ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + // ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + // s_retry_num = 0; + // xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + // } +} +static bool wifi_inited; + +void common_hal_wifi_init(void) { + ESP_LOGI(TAG, "init"); + wifi_inited = true; + common_hal_wifi_radio_obj.base.type = &wifi_radio_type; + + ESP_ERROR_CHECK(esp_netif_init()); + + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_sta(); + + wifi_radio_obj_t* self = &common_hal_wifi_radio_obj; + self->event_group_handle = xEventGroupCreateStatic(&self->event_group); + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &event_handler, + self, + self->handler_instance_all_wifi)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &event_handler, + self, + self->handler_instance_got_ip)); + + + wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); esp_err_t result = esp_wifi_init(&config); if (result == ESP_ERR_NO_MEM) { mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate Wifi memory")); } else if (result != ESP_OK) { // handle this } + common_hal_wifi_radio_set_enabled(self, true); } void wifi_reset(void) { + ESP_LOGI(TAG, "reset"); + if (!wifi_inited) { + return; + } + wifi_radio_obj_t* radio = &common_hal_wifi_radio_obj; + common_hal_wifi_radio_set_enabled(radio, false); + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, + ESP_EVENT_ANY_ID, + radio->handler_instance_all_wifi)); + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, + IP_EVENT_STA_GOT_IP, + radio->handler_instance_got_ip)); esp_wifi_deinit(); } diff --git a/ports/esp32s2/common-hal/wifi/__init__.h b/ports/esp32s2/common-hal/wifi/__init__.h index e7ff7ec04a..bb68bcfdf0 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.h +++ b/ports/esp32s2/common-hal/wifi/__init__.h @@ -29,4 +29,6 @@ #include "py/obj.h" +void wifi_reset(void); + #endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI___INIT___H diff --git a/ports/esp32s2/esp-idf b/ports/esp32s2/esp-idf index f5aff20b37..e15ce11ebc 160000 --- a/ports/esp32s2/esp-idf +++ b/ports/esp32s2/esp-idf @@ -1 +1 @@ -Subproject commit f5aff20b378f7c4002605a4158a41630c21f343d +Subproject commit e15ce11ebca15a1f6eca22779e89f761b1fc2142 diff --git a/ports/esp32s2/partitions.csv b/ports/esp32s2/partitions.csv index 47fb295e5e..dd12c609dc 100644 --- a/ports/esp32s2/partitions.csv +++ b/ports/esp32s2/partitions.csv @@ -3,8 +3,8 @@ # bootloader.bin 0x1000 # partition table 0x8000, 0xC00 otadata, data, ota, 0xd000, 0x2000, -ota_0, 0, ota_0, 0x10000, 512K, -ota_1, 0, ota_1, 0x90000, 512K, -phy_init, data, phy, 0x110000, 0x1000, -nvs, data, nvs, 0x111000, 0x6000, -user_fs, data, fat, 0x200000, 2M, +ota_0, 0, ota_0, 0x10000, 0x100000, +ota_1, 0, ota_1, 0x110000, 0x100000, +phy_init, data, phy, 0x210000, 0x1000, +nvs, data, nvs, 0x211000, 0x6000, +user_fs, data, fat, 0x217000, 0x1e9000, diff --git a/ports/esp32s2/sdkconfig.defaults b/ports/esp32s2/sdkconfig.defaults index 8245c7db6c..f7693ce18f 100644 --- a/ports/esp32s2/sdkconfig.defaults +++ b/ports/esp32s2/sdkconfig.defaults @@ -122,8 +122,8 @@ CONFIG_PARTITION_TABLE_MD5=y # # Compiler options # -CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y -# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set +CONFIG_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_COMPILER_OPTIMIZATION_PERF is not set # CONFIG_COMPILER_OPTIMIZATION_NONE is not set # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE is not set @@ -331,10 +331,17 @@ CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP32_WIFI_RX_BA_WIN=6 -CONFIG_ESP32_WIFI_NVS_ENABLED=y +# CONFIG_ESP32_WIFI_NVS_ENABLED is not set CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -# CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE is not set +CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE=y +CONFIG_ESP32_WIFI_DEBUG_LOG_DEBUG=y +# CONFIG_ESP32_WIFI_DEBUG_LOG_VERBOSE is not set +# CONFIG_ESP32_WIFI_DEBUG_LOG_MODULE_ALL is not set +CONFIG_ESP32_WIFI_DEBUG_LOG_MODULE_WIFI=y +# CONFIG_ESP32_WIFI_DEBUG_LOG_MODULE_COEX is not set +# CONFIG_ESP32_WIFI_DEBUG_LOG_MODULE_MESH is not set +# CONFIG_ESP32_WIFI_DEBUG_LOG_SUBMODULE is not set CONFIG_ESP32_WIFI_IRAM_OPT=y CONFIG_ESP32_WIFI_RX_IRAM_OPT=y # CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE is not set @@ -387,7 +394,6 @@ CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set CONFIG_FREERTOS_DEBUG_OCDAWARE=y @@ -576,8 +582,8 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y CONFIG_MBEDTLS_SSL_RENEGOTIATION=y # CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set -CONFIG_MBEDTLS_SSL_PROTO_TLS1=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y +# CONFIG_MBEDTLS_SSL_PROTO_TLS1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_1 is not set CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y CONFIG_MBEDTLS_SSL_PROTO_DTLS=y CONFIG_MBEDTLS_SSL_ALPN=y @@ -708,7 +714,7 @@ CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 CONFIG_WPA_MBEDTLS_CRYPTO=y # CONFIG_WPA_DEBUG_PRINT is not set # CONFIG_WPA_TESTING_OPTIONS is not set -# CONFIG_WPA_TLS_V12 is not set +CONFIG_WPA_TLS_V12=y # CONFIG_WPA_WPS_WARS is not set # end of Supplicant # end of Component config @@ -743,8 +749,8 @@ CONFIG_MONITOR_BAUD_115200B=y # CONFIG_MONITOR_BAUD_OTHER is not set CONFIG_MONITOR_BAUD_OTHER_VAL=115200 CONFIG_MONITOR_BAUD=115200 -CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y -# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set +CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y # CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED is not set CONFIG_OPTIMIZATION_ASSERTIONS_SILENT=y # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index e4767e5146..24e826c195 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -39,15 +39,25 @@ #include "common-hal/busio/SPI.h" #include "common-hal/busio/UART.h" #include "common-hal/pulseio/PWMOut.h" +#include "common-hal/wifi/__init__.h" #include "supervisor/memory.h" #include "supervisor/shared/tick.h" +#include "esp-idf/components/heap/include/esp_heap_caps.h" + +#include "esp_log.h" +static const char *TAG = "cp port"; + +#define HEAP_SIZE (96 * 1024) + STATIC esp_timer_handle_t _tick_timer; void tick_timer_cb(void* arg) { supervisor_tick(); } +uint32_t* heap; + safe_mode_t port_init(void) { esp_timer_create_args_t args; args.callback = &tick_timer_cb; @@ -55,6 +65,12 @@ safe_mode_t port_init(void) { args.dispatch_method = ESP_TIMER_TASK; args.name = "CircuitPython Tick"; esp_timer_create(&args, &_tick_timer); + + heap = malloc(HEAP_SIZE); + if (heap == NULL) { + heap_caps_print_heap_info(MALLOC_CAP_8BIT); + ESP_LOGE(TAG, "failed to allocate heap"); + } never_reset_module_internal_pins(); return NO_SAFE_MODE; } @@ -73,6 +89,9 @@ void reset_port(void) { spi_reset(); uart_reset(); #endif +#if CIRCUITPY_WIFI + wifi_reset(); +#endif } void reset_to_bootloader(void) { @@ -81,14 +100,14 @@ void reset_to_bootloader(void) { void reset_cpu(void) { } -uint32_t heap[64 / sizeof(uint32_t) * 1024]; - uint32_t *port_heap_get_bottom(void) { + + ESP_EARLY_LOGI(TAG, "heap %x", heap); return heap; } uint32_t *port_heap_get_top(void) { - return heap + sizeof(heap) / sizeof(heap[0]); + return heap + (HEAP_SIZE / sizeof(uint32_t)); } uint32_t *port_stack_get_limit(void) { @@ -110,6 +129,13 @@ supervisor_allocation* port_fixed_stack(void) { return &_fixed_stack; } +supervisor_allocation _fixed_heap; +supervisor_allocation* port_fixed_heap(void) { + _fixed_heap.ptr = port_heap_get_bottom(); + _fixed_heap.length = (port_heap_get_top() - port_heap_get_bottom()) * sizeof(uint32_t); + return &_fixed_heap; +} + // Place the word to save just after our BSS section that gets blanked. void port_set_saved_word(uint32_t value) { } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 5d5b6996d1..caf65d27ef 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -338,6 +338,7 @@ SRC_COMMON_HAL_ALL = \ watchdog/__init__.c \ wifi/Network.c \ wifi/Radio.c \ + wifi/ScannedNetworks.c \ wifi/__init__.c \ SRC_COMMON_HAL = $(filter $(SRC_PATTERNS), $(SRC_COMMON_HAL_ALL)) diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index 1eb07d8fcf..c5bee83114 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -78,8 +78,8 @@ const mp_obj_property_t wifi_radio_mac_address_obj = { }; -//| def start_scanning_networks(self) -> Iterable[Network]: -//| """""" +//| def start_scanning_networks(self, *, start_channel=1, stop_channel=11) -> Iterable[Network]: +//| """Scans for available wifi networks over the given channel range. Make sure the channels are allowed in your country.""" //| ... //| STATIC mp_obj_t wifi_radio_start_scanning_networks(mp_obj_t self_in) { diff --git a/shared-bindings/wifi/ScannedNetworks.c b/shared-bindings/wifi/ScannedNetworks.c new file mode 100644 index 0000000000..3e60d5f108 --- /dev/null +++ b/shared-bindings/wifi/ScannedNetworks.c @@ -0,0 +1,68 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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 + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/wifi/ScannedNetworks.h" + +//| class ScannedNetworks: +//| """Iterates over wifi `Network`s found while scanning. This object is always created +//| by a `wifi.Radio`: it has no user-visible constructor.""" +//| +STATIC mp_obj_t scannednetworks_iternext(mp_obj_t self_in) { + mp_check_self(MP_OBJ_IS_TYPE(self_in, &wifi_scannednetworks_type)); + wifi_scannednetworks_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_t network = common_hal_wifi_scannednetworks_next(self); + if (network != mp_const_none) { + return network; + } + return MP_OBJ_STOP_ITERATION; +} + +//| def __init__(self) -> None: +//| """Cannot be instantiated directly. Use `wifi.Radio.start_scanning_networks`.""" +//| ... +//| +//| def __iter__(self) -> Iterator[Network]: +//| """Returns itself since it is the iterator.""" +//| ... +//| +//| def __next__(self) -> Network: +//| """Returns the next `wifi.Network`. +//| Raises `StopIteration` if scanning is finished and no other results are available.""" +//| ... +//| + +const mp_obj_type_t wifi_scannednetworks_type = { + { &mp_type_type }, + .name = MP_QSTR_ScannedNetworks, + .getiter = mp_identity_getiter, + .iternext = scannednetworks_iternext, +}; diff --git a/shared-bindings/wifi/ScannedNetworks.h b/shared-bindings/wifi/ScannedNetworks.h new file mode 100644 index 0000000000..8e0aa435d0 --- /dev/null +++ b/shared-bindings/wifi/ScannedNetworks.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_SCANNEDNETWORKS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_SCANNEDNETWORKS_H + +#include "py/obj.h" +#include "common-hal/wifi/ScannedNetworks.h" + +extern const mp_obj_type_t wifi_scannednetworks_type; + +mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_SCANNEDNETWORKS_H diff --git a/supervisor/port.h b/supervisor/port.h index ad5b3cf32a..ddb96bd524 100644 --- a/supervisor/port.h +++ b/supervisor/port.h @@ -69,6 +69,8 @@ uint32_t *port_heap_get_bottom(void); // Get heap top address uint32_t *port_heap_get_top(void); +supervisor_allocation* port_fixed_heap(void); + // Save and retrieve a word from memory that is preserved over reset. Used for safe mode. void port_set_saved_word(uint32_t); uint32_t port_get_saved_word(void); From ddcff85fa23f44c899c135b70603ba78b839a046 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 31 Jul 2020 19:29:22 -0700 Subject: [PATCH 05/78] Add debugging. Scanning doesn't crash but returns no results. Need to config station. --- main.c | 5 +-- ports/esp32s2/common-hal/wifi/Radio.c | 31 +++++++++++++++++-- ports/esp32s2/common-hal/wifi/Radio.h | 4 +++ .../esp32s2/common-hal/wifi/ScannedNetworks.c | 29 +++++++++++++---- ports/esp32s2/common-hal/wifi/__init__.c | 19 +++++++++--- ports/esp32s2/supervisor/port.c | 3 +- shared-bindings/wifi/ScannedNetworks.c | 5 +++ supervisor/shared/memory.c | 4 +++ 8 files changed, 85 insertions(+), 15 deletions(-) diff --git a/main.c b/main.c index fb73b09b1f..3a14df0fa6 100755 --- a/main.c +++ b/main.c @@ -436,11 +436,12 @@ int run_repl(void) { } int __attribute__((used)) main(void) { - memory_init(); - // initialise the cpu and peripherals safe_mode_t safe_mode = port_init(); + // Init memory after the port in case the port needs to set aside memory. + memory_init(); + // Turn on LEDs init_status_leds(); rgb_led_status_init(); diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c index 0bdcfb01a4..a2944dd52c 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.c +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -31,18 +31,41 @@ #include "esp-idf/components/esp_wifi/include/esp_wifi.h" +#include "esp_log.h" +static const char *TAG = "cp radio"; + +static void start_station(wifi_radio_obj_t *self) { + if (self->sta_mode) { + return; + } + wifi_mode_t next_mode; + if (self->ap_mode) { + next_mode = WIFI_MODE_APSTA; + } else { + next_mode = WIFI_MODE_STA; + } + esp_wifi_set_mode(next_mode); + + esp_wifi_set_config(WIFI_MODE_STA, &self->sta_config); +} + bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self) { return self->started; } void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) { if (self->started && !enabled) { - esp_wifi_stop(); + ESP_LOGI(TAG, "stop"); + if (self->current_scan != NULL) { + common_hal_wifi_radio_stop_scanning_networks(self); + } + ESP_ERROR_CHECK(esp_wifi_stop()); self->started = false; return; } if (!self->started && enabled) { - esp_wifi_start(); + ESP_LOGI(TAG, "start"); + ESP_ERROR_CHECK(esp_wifi_start()); self->started = true; return; } @@ -59,7 +82,9 @@ mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) { mp_raise_RuntimeError(translate("Already scanning for wifi networks")); } // check enabled + start_station(self); + ESP_LOGI(TAG, "start scan"); wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t); self->current_scan = scan; scan->base.type = &wifi_scannednetworks_type; @@ -72,8 +97,10 @@ mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) { void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self) { // Free the memory used to store the found aps. + ESP_EARLY_LOGI(TAG, "stop scan"); wifi_scannednetworks_deinit(self->current_scan); self->current_scan = NULL; + ESP_EARLY_LOGI(TAG, "stop scan done"); } bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, mp_float_t timeout) { diff --git a/ports/esp32s2/common-hal/wifi/Radio.h b/ports/esp32s2/common-hal/wifi/Radio.h index f681213dd8..11b30799ac 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.h +++ b/ports/esp32s2/common-hal/wifi/Radio.h @@ -43,7 +43,11 @@ typedef struct { wifi_scannednetworks_obj_t *current_scan; StaticEventGroup_t event_group; EventGroupHandle_t event_group_handle; + wifi_config_t sta_config; + esp_netif_t *netif; bool started; + bool ap_mode; + bool sta_mode; } wifi_radio_obj_t; #endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_RADIO_H diff --git a/ports/esp32s2/common-hal/wifi/ScannedNetworks.c b/ports/esp32s2/common-hal/wifi/ScannedNetworks.c index a67a5f3bd8..248defa574 100644 --- a/ports/esp32s2/common-hal/wifi/ScannedNetworks.c +++ b/ports/esp32s2/common-hal/wifi/ScannedNetworks.c @@ -38,10 +38,16 @@ #include "esp-idf/components/esp_wifi/include/esp_wifi.h" +#include "esp_log.h" +static const char *TAG = "cp scannednetworks"; + static void wifi_scannednetworks_done(wifi_scannednetworks_obj_t *self) { self->done = true; - free(self->results); - self->results = NULL; + ESP_EARLY_LOGI(TAG, "free %x", self->results); + if (self->results != NULL) { + m_free(self->results); + self->results = NULL; + } } static bool wifi_scannednetworks_wait_for_scan(wifi_scannednetworks_obj_t *self) { @@ -75,6 +81,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) } esp_wifi_scan_get_ap_num(&self->total_results); + self->scanning = false; if (self->total_results > 0) { break; } @@ -83,6 +90,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) } // We not have found any more results so we're done. if (self->done) { + ESP_LOGI(TAG, "return done"); return mp_const_none; } // If we need more space than we have, realloc. @@ -92,6 +100,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) self->max_results, self->total_results, true /* allow move */); + ESP_EARLY_LOGI(TAG, "alloc %x", results); if (results != NULL) { self->results = results; self->max_results = self->total_results; @@ -128,7 +137,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) static uint8_t scan_pattern[] = {6, 1, 11, 3, 9, 13, 2, 4, 8, 12, 5, 7, 10, 14}; void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self) { - wifi_scan_config_t config; + uint8_t next_channel = sizeof(scan_pattern); while (self->current_channel_index < sizeof(scan_pattern)) { next_channel = scan_pattern[self->current_channel_index]; @@ -137,11 +146,19 @@ void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self) { break; } } - if (next_channel == sizeof(scan_pattern) || - esp_wifi_scan_start(&config, false) != ESP_OK) { + wifi_scan_config_t config = { 0 }; + config.channel = next_channel; + if (next_channel == sizeof(scan_pattern)) { + ESP_LOGI(TAG, "scan done"); wifi_scannednetworks_done(self); } else { - self->scanning = true; + esp_err_t result = esp_wifi_scan_start(&config, false); + if (result != ESP_OK) { + ESP_LOGI(TAG, "start failed 0x%x", result); + wifi_scannednetworks_done(self); + } else { + self->scanning = true; + } } } diff --git a/ports/esp32s2/common-hal/wifi/__init__.c b/ports/esp32s2/common-hal/wifi/__init__.c index 9f08603b50..d4a1d9892e 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.c +++ b/ports/esp32s2/common-hal/wifi/__init__.c @@ -33,11 +33,13 @@ static const char *TAG = "cp wifi"; #include "esp-idf/components/esp_wifi/include/esp_wifi.h" +#include "esp-idf/components/heap/include/esp_heap_caps.h" + wifi_radio_obj_t common_hal_wifi_radio_obj; static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - ESP_LOGI(TAG, "event"); + ESP_LOGI(TAG, "event %x", event_id); wifi_radio_obj_t* radio = arg; if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) { xEventGroupSetBits(radio->event_group_handle, WIFI_SCAN_DONE_BIT); @@ -65,16 +67,20 @@ static void event_handler(void* arg, esp_event_base_t event_base, static bool wifi_inited; void common_hal_wifi_init(void) { - ESP_LOGI(TAG, "init"); + ESP_EARLY_LOGI(TAG, "init"); + heap_caps_print_heap_info(MALLOC_CAP_8BIT); wifi_inited = true; common_hal_wifi_radio_obj.base.type = &wifi_radio_type; ESP_ERROR_CHECK(esp_netif_init()); + ESP_EARLY_LOGI(TAG, "create event loop"); ESP_ERROR_CHECK(esp_event_loop_create_default()); - esp_netif_create_default_wifi_sta(); + ESP_EARLY_LOGI(TAG, "create wifi sta"); wifi_radio_obj_t* self = &common_hal_wifi_radio_obj; + self->netif = esp_netif_create_default_wifi_sta(); + self->event_group_handle = xEventGroupCreateStatic(&self->event_group); ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, @@ -88,6 +94,7 @@ void common_hal_wifi_init(void) { self->handler_instance_got_ip)); + ESP_EARLY_LOGI(TAG, "wifi init"); wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); esp_err_t result = esp_wifi_init(&config); if (result == ESP_ERR_NO_MEM) { @@ -95,6 +102,7 @@ void common_hal_wifi_init(void) { } else if (result != ESP_OK) { // handle this } + ESP_EARLY_LOGI(TAG, "enable radio"); common_hal_wifi_radio_set_enabled(self, true); } @@ -111,5 +119,8 @@ void wifi_reset(void) { ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, radio->handler_instance_got_ip)); - esp_wifi_deinit(); + ESP_ERROR_CHECK(esp_wifi_deinit()); + esp_netif_destroy(radio->netif); + radio->netif = NULL; + ESP_ERROR_CHECK(esp_netif_deinit()); } diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 24e826c195..9a1ac5e2c8 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -48,7 +48,7 @@ #include "esp_log.h" static const char *TAG = "cp port"; -#define HEAP_SIZE (96 * 1024) +#define HEAP_SIZE (64 * 1024) STATIC esp_timer_handle_t _tick_timer; @@ -92,6 +92,7 @@ void reset_port(void) { #if CIRCUITPY_WIFI wifi_reset(); #endif + heap_caps_print_heap_info(MALLOC_CAP_8BIT); } void reset_to_bootloader(void) { diff --git a/shared-bindings/wifi/ScannedNetworks.c b/shared-bindings/wifi/ScannedNetworks.c index 3e60d5f108..c6b77d70b7 100644 --- a/shared-bindings/wifi/ScannedNetworks.c +++ b/shared-bindings/wifi/ScannedNetworks.c @@ -32,6 +32,9 @@ #include "py/runtime.h" #include "shared-bindings/wifi/ScannedNetworks.h" +#include "esp_log.h" +static const char *TAG = "cp iternext"; + //| class ScannedNetworks: //| """Iterates over wifi `Network`s found while scanning. This object is always created //| by a `wifi.Radio`: it has no user-visible constructor.""" @@ -43,6 +46,8 @@ STATIC mp_obj_t scannednetworks_iternext(mp_obj_t self_in) { if (network != mp_const_none) { return network; } + + ESP_EARLY_LOGI(TAG, "stop iteration"); return MP_OBJ_STOP_ITERATION; } diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c index 8ae8a16997..79bdeef9db 100755 --- a/supervisor/shared/memory.c +++ b/supervisor/shared/memory.c @@ -31,6 +31,9 @@ #include "supervisor/shared/display.h" +#include "esp_log.h" +static const char *TAG = "memory"; + #define CIRCUITPY_SUPERVISOR_ALLOC_COUNT (12) static supervisor_allocation allocations[CIRCUITPY_SUPERVISOR_ALLOC_COUNT]; @@ -39,6 +42,7 @@ uint32_t* low_address; uint32_t* high_address; void memory_init(void) { + ESP_LOGE(TAG, "memory init"); low_address = port_heap_get_bottom(); high_address = port_heap_get_top(); } From c62ab6e09a4dda33b75bcb0ee5fed800b756e564 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 5 Aug 2020 12:53:35 -0700 Subject: [PATCH 06/78] Add ipaddress --- ports/esp32s2/common-hal/wifi/Network.c | 15 +- ports/esp32s2/common-hal/wifi/Radio.c | 51 ++++- ports/esp32s2/common-hal/wifi/Radio.h | 2 + .../esp32s2/common-hal/wifi/ScannedNetworks.c | 7 +- ports/esp32s2/common-hal/wifi/__init__.c | 40 +++- py/circuitpy_defns.mk | 5 + py/circuitpy_mpconfig.h | 7 + py/circuitpy_mpconfig.mk | 3 + shared-bindings/ipaddress/IPv4Address.c | 180 ++++++++++++++++++ shared-bindings/ipaddress/IPv4Address.h | 38 ++++ shared-bindings/ipaddress/__init__.c | 65 +++++++ shared-bindings/ipaddress/__init__.h | 34 ++++ shared-bindings/wifi/Network.c | 39 +++- shared-bindings/wifi/Network.h | 2 + shared-bindings/wifi/Radio.c | 28 +-- shared-bindings/wifi/Radio.h | 4 +- shared-module/ipaddress/IPv4Address.c | 39 ++++ shared-module/ipaddress/IPv4Address.h | 37 ++++ shared-module/ipaddress/__init__.c | 35 ++++ shared-module/ipaddress/__init__.h | 36 ++++ 20 files changed, 634 insertions(+), 33 deletions(-) create mode 100644 shared-bindings/ipaddress/IPv4Address.c create mode 100644 shared-bindings/ipaddress/IPv4Address.h create mode 100644 shared-bindings/ipaddress/__init__.c create mode 100644 shared-bindings/ipaddress/__init__.h create mode 100644 shared-module/ipaddress/IPv4Address.c create mode 100644 shared-module/ipaddress/IPv4Address.h create mode 100644 shared-module/ipaddress/__init__.c create mode 100644 shared-module/ipaddress/__init__.h diff --git a/ports/esp32s2/common-hal/wifi/Network.c b/ports/esp32s2/common-hal/wifi/Network.c index a270fd9dcc..0320e8f92f 100644 --- a/ports/esp32s2/common-hal/wifi/Network.c +++ b/ports/esp32s2/common-hal/wifi/Network.c @@ -26,6 +26,19 @@ #include "shared-bindings/wifi/Network.h" +#include + +#include "py/obj.h" + mp_obj_t common_hal_wifi_network_get_ssid(wifi_network_obj_t *self) { - return mp_const_none; + const char* cstr = (const char*) self->record.ssid; + return mp_obj_new_str(cstr, strlen(cstr)); +} + +mp_obj_t common_hal_wifi_network_get_rssi(wifi_network_obj_t *self) { + return mp_obj_new_int(self->record.rssi); +} + +mp_obj_t common_hal_wifi_network_get_channel(wifi_network_obj_t *self) { + return mp_obj_new_int(self->record.primary); } diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c index a2944dd52c..623ba9e345 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.c +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -26,7 +26,11 @@ #include "shared-bindings/wifi/Radio.h" +#include + +#include "lib/utils/interrupt_char.h" #include "py/runtime.h" +#include "shared-bindings/ipaddress/IPv4Address.h" #include "shared-bindings/wifi/ScannedNetworks.h" #include "esp-idf/components/esp_wifi/include/esp_wifi.h" @@ -103,16 +107,51 @@ void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self) { ESP_EARLY_LOGI(TAG, "stop scan done"); } -bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, mp_float_t timeout) { +bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout) { // check enabled - wifi_config_t config; - esp_err_t result = esp_wifi_set_config(ESP_IF_WIFI_STA, &config); + wifi_config_t* config = &self->sta_config; + memcpy(&config->sta.ssid, ssid, ssid_len); + config->sta.ssid[ssid_len] = 0; + if (password_len > 0) { + memcpy(&config->sta.password, password, password_len); + } + config->sta.password[password_len] = 0; + config->sta.channel = channel; + ESP_EARLY_LOGI(TAG, "connecting to %s", config->sta.ssid); + esp_err_t result = esp_wifi_set_config(ESP_IF_WIFI_STA, config); + if (result != ESP_OK) { + ESP_EARLY_LOGI(TAG, "config fail %d", result); + } result = esp_wifi_connect(); - return result == ESP_OK; + if (result != ESP_OK) { + ESP_EARLY_LOGI(TAG, "connect fail %d", result); + } + + EventBits_t bits; + do { + RUN_BACKGROUND_TASKS; + bits = xEventGroupWaitBits(self->event_group_handle, + WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT, + pdTRUE, + pdTRUE, + 0); + } while ((bits & (WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT)) == 0 && !mp_hal_is_interrupted()); + if ((bits & WIFI_DISCONNECTED_BIT) != 0) { + return false; + } + return true; } -mp_obj_t common_hal_wifi_radio_get_ip_address(wifi_radio_obj_t *self) { - return mp_const_none; +mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) { + if (!esp_netif_is_netif_up(self->netif)) { + return mp_const_none; + } + esp_netif_ip_info_t ip_info; + esp_err_t result = esp_netif_get_ip_info(self->netif, &ip_info); + if (result != ESP_OK) { + ESP_EARLY_LOGI(TAG, "get ip fail %d", result); + } + return common_hal_ipaddress_new_ipv4address(ip_info.ip.addr); } mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address) { diff --git a/ports/esp32s2/common-hal/wifi/Radio.h b/ports/esp32s2/common-hal/wifi/Radio.h index 11b30799ac..e7dce94776 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.h +++ b/ports/esp32s2/common-hal/wifi/Radio.h @@ -35,6 +35,8 @@ // Event bits for the Radio event group. #define WIFI_SCAN_DONE_BIT BIT0 +#define WIFI_CONNECTED_BIT BIT1 +#define WIFI_DISCONNECTED_BIT BIT2 typedef struct { mp_obj_base_t base; diff --git a/ports/esp32s2/common-hal/wifi/ScannedNetworks.c b/ports/esp32s2/common-hal/wifi/ScannedNetworks.c index 248defa574..060e13f8ea 100644 --- a/ports/esp32s2/common-hal/wifi/ScannedNetworks.c +++ b/ports/esp32s2/common-hal/wifi/ScannedNetworks.c @@ -29,6 +29,7 @@ #include #include "lib/utils/interrupt_char.h" +#include "py/gc.h" #include "py/objstr.h" #include "py/runtime.h" #include "shared-bindings/wifi/__init__.h" @@ -45,7 +46,10 @@ static void wifi_scannednetworks_done(wifi_scannednetworks_obj_t *self) { self->done = true; ESP_EARLY_LOGI(TAG, "free %x", self->results); if (self->results != NULL) { - m_free(self->results); + // Check to see if the heap is still active. If not, it'll be freed automatically. + if (gc_alloc_possible()) { + m_free(self->results); + } self->results = NULL; } } @@ -137,7 +141,6 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) static uint8_t scan_pattern[] = {6, 1, 11, 3, 9, 13, 2, 4, 8, 12, 5, 7, 10, 14}; void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self) { - uint8_t next_channel = sizeof(scan_pattern); while (self->current_channel_index < sizeof(scan_pattern)) { next_channel = scan_pattern[self->current_channel_index]; diff --git a/ports/esp32s2/common-hal/wifi/__init__.c b/ports/esp32s2/common-hal/wifi/__init__.c index d4a1d9892e..1dc9ef9a89 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.c +++ b/ports/esp32s2/common-hal/wifi/__init__.c @@ -41,9 +41,32 @@ static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { ESP_LOGI(TAG, "event %x", event_id); wifi_radio_obj_t* radio = arg; - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) { - xEventGroupSetBits(radio->event_group_handle, WIFI_SCAN_DONE_BIT); + if (event_base == WIFI_EVENT) { + if (event_id == WIFI_EVENT_SCAN_DONE) { + ESP_LOGI(TAG, "scan done"); + xEventGroupSetBits(radio->event_group_handle, WIFI_SCAN_DONE_BIT); + } else if (event_id == WIFI_EVENT_STA_START) { + ESP_LOGI(TAG, "station start"); + + } else if (event_id == WIFI_EVENT_STA_STOP) { + ESP_LOGI(TAG, "station stop"); + + } else if (event_id == WIFI_EVENT_STA_CONNECTED) { + ESP_LOGI(TAG, "connected to ap"); + } else if (event_id == WIFI_EVENT_STA_DISCONNECTED) { + ESP_LOGI(TAG, "disconnected"); + wifi_event_sta_disconnected_t* d = (wifi_event_sta_disconnected_t*) event_data; + ESP_LOGI(TAG, "reason %d", d->reason); + if (event_id != WIFI_REASON_ASSOC_LEAVE) { + // reconnect + } + xEventGroupSetBits(radio->event_group_handle, WIFI_DISCONNECTED_BIT); + } else if (event_id == WIFI_EVENT_STA_AUTHMODE_CHANGE) { + ESP_LOGI(TAG, "auth change"); + + } } + // esp_wifi_connect(); // if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { // esp_wifi_connect(); @@ -56,12 +79,13 @@ static void event_handler(void* arg, esp_event_base_t event_base, // xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); // } // ESP_LOGI(TAG,"connect to the AP fail"); - // } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - // ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; - // ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); - // s_retry_num = 0; - // xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); - // } + // } else + if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + // s_retry_num = 0; + xEventGroupSetBits(radio->event_group_handle, WIFI_CONNECTED_BIT); + } } static bool wifi_inited; diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index caf65d27ef..1a5145c8ba 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -168,6 +168,9 @@ endif ifeq ($(CIRCUITPY_I2CPERIPHERAL),1) SRC_PATTERNS += i2cperipheral/% endif +ifeq ($(CIRCUITPY_IPADDRESS),1) +SRC_PATTERNS += ipaddress/% +endif ifeq ($(CIRCUITPY_MATH),1) SRC_PATTERNS += math/% endif @@ -408,6 +411,8 @@ SRC_SHARED_MODULE_ALL = \ fontio/__init__.c \ framebufferio/FramebufferDisplay.c \ framebufferio/__init__.c \ + ipaddress/IPv4Address.c \ + ipaddress/__init__.c \ sdcardio/SDCard.c \ sdcardio/__init__.c \ gamepad/GamePad.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 2db20ca1d1..8ff2ddc67d 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -420,6 +420,13 @@ extern const struct _mp_obj_module_t i2cperipheral_module; #define I2CPERIPHERAL_MODULE #endif +#if CIRCUITPY_IPADDRESS +extern const struct _mp_obj_module_t ipaddress_module; +#define IPADDRESS_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_ipaddress), (mp_obj_t)&ipaddress_module }, +#else +#define IPADDRESS_MODULE +#endif + #if CIRCUITPY_MATH extern const struct _mp_obj_module_t math_module; #define MATH_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index abbd5a9a0b..499e87aed0 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -120,6 +120,9 @@ CFLAGS += -DCIRCUITPY_GNSS=$(CIRCUITPY_GNSS) CIRCUITPY_I2CPERIPHERAL ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_I2CPERIPHERAL=$(CIRCUITPY_I2CPERIPHERAL) +CIRCUITPY_IPADDRESS ?= $(CIRCUITPY_WIFI) +CFLAGS += -DCIRCUITPY_IPADDRESS=$(CIRCUITPY_IPADDRESS) + CIRCUITPY_MATH ?= 1 CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH) diff --git a/shared-bindings/ipaddress/IPv4Address.c b/shared-bindings/ipaddress/IPv4Address.c new file mode 100644 index 0000000000..3cef7516df --- /dev/null +++ b/shared-bindings/ipaddress/IPv4Address.c @@ -0,0 +1,180 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * + * 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 +#include + +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/ipaddress/IPv4Address.h" + +//| class IPv4Address: +//| """Encapsulates an IPv4 address.""" +//| + +//| def __init__(self, address: Union[str, int]) -> None: +//| """Create a new Address object encapsulating the address value. +//| +//| The value itself can be one of:""" +//| ... +//| +STATIC mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_address }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_OBJ | MP_ARG_REQUIRED }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + ipaddress_ipv4address_obj_t *self = m_new_obj(ipaddress_ipv4address_obj_t); + self->base.type = &ipaddress_ipv4address_type; + + const mp_obj_t address = args[ARG_address].u_obj; + mp_buffer_info_t buf_info; + mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); + if (buf_info.len != 4) { + mp_raise_ValueError_varg(translate("Address must be %d bytes long"), 4); + } + + common_hal_ipaddress_ipv4address_construct(self, buf_info.buf, buf_info.len); + + return MP_OBJ_FROM_PTR(self); +} + +//| packed: bytes +//| """The bytes that make up the address (read-only).""" +//| +STATIC mp_obj_t ipaddress_ipv4address_get_packed(mp_obj_t self_in) { + ipaddress_ipv4address_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_ipaddress_ipv4address_get_packed(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(ipaddress_ipv4address_get_packed_obj, ipaddress_ipv4address_get_packed); + +const mp_obj_property_t ipaddress_ipv4address_packed_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&ipaddress_ipv4address_get_packed_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| version: int +//| """4 for IPv4, 6 for IPv6""" +//| +STATIC mp_obj_t ipaddress_ipv4address_get_version(mp_obj_t self_in) { + ipaddress_ipv4address_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_buffer_info_t buf_info; + mp_obj_t address_bytes = common_hal_ipaddress_ipv4address_get_packed(self); + mp_get_buffer_raise(address_bytes, &buf_info, MP_BUFFER_READ); + mp_int_t version = 6; + if (buf_info.len == 4) { + version = 4; + } + + return MP_OBJ_NEW_SMALL_INT(version); +} +MP_DEFINE_CONST_FUN_OBJ_1(ipaddress_ipv4address_get_version_obj, ipaddress_ipv4address_get_version); + +const mp_obj_property_t ipaddress_ipv4address_version_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&ipaddress_ipv4address_get_version_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| def __eq__(self, other: Address) -> bool: +//| """Two Address objects are equal if their addresses and address types are equal.""" +//| ... +//| +STATIC mp_obj_t ipaddress_ipv4address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + switch (op) { + // Two Addresses are equal if their address bytes and address_type are equal + case MP_BINARY_OP_EQUAL: + if (MP_OBJ_IS_TYPE(rhs_in, &ipaddress_ipv4address_type)) { + ipaddress_ipv4address_obj_t *lhs = MP_OBJ_TO_PTR(lhs_in); + ipaddress_ipv4address_obj_t *rhs = MP_OBJ_TO_PTR(rhs_in); + return mp_obj_new_bool( + mp_obj_equal(common_hal_ipaddress_ipv4address_get_packed(lhs), + common_hal_ipaddress_ipv4address_get_packed(rhs))); + + } else { + return mp_const_false; + } + + default: + return MP_OBJ_NULL; // op not supported + } +} + +//| def __hash__(self) -> int: +//| """Returns a hash for the Address data.""" +//| ... +//| +STATIC mp_obj_t ipaddress_ipv4address_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + switch (op) { + // Two Addresses are equal if their address bytes and address_type are equal + case MP_UNARY_OP_HASH: { + mp_obj_t bytes = common_hal_ipaddress_ipv4address_get_packed(MP_OBJ_TO_PTR(self_in)); + GET_STR_HASH(bytes, h); + if (h == 0) { + GET_STR_DATA_LEN(bytes, data, len); + h = qstr_compute_hash(data, len); + } + return MP_OBJ_NEW_SMALL_INT(h); + } + default: + return MP_OBJ_NULL; // op not supported + } +} + +STATIC void ipaddress_ipv4address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + ipaddress_ipv4address_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_buffer_info_t buf_info; + mp_obj_t address_bytes = common_hal_ipaddress_ipv4address_get_packed(self); + mp_get_buffer_raise(address_bytes, &buf_info, MP_BUFFER_READ); + + const uint8_t *buf = (uint8_t *) buf_info.buf; + mp_printf(print, "%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]); +} + +STATIC const mp_rom_map_elem_t ipaddress_ipv4address_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_packed), MP_ROM_PTR(&ipaddress_ipv4address_packed_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(ipaddress_ipv4address_locals_dict, ipaddress_ipv4address_locals_dict_table); + +const mp_obj_type_t ipaddress_ipv4address_type = { + { &mp_type_type }, + .name = MP_QSTR_Address, + .make_new = ipaddress_ipv4address_make_new, + .print = ipaddress_ipv4address_print, + .unary_op = ipaddress_ipv4address_unary_op, + .binary_op = ipaddress_ipv4address_binary_op, + .locals_dict = (mp_obj_dict_t*)&ipaddress_ipv4address_locals_dict +}; diff --git a/shared-bindings/ipaddress/IPv4Address.h b/shared-bindings/ipaddress/IPv4Address.h new file mode 100644 index 0000000000..cf66b92b35 --- /dev/null +++ b/shared-bindings/ipaddress/IPv4Address.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS_IPV4ADDRESS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS_IPV4ADDRESS_H + +#include "shared-module/ipaddress/IPv4Address.h" + +extern const mp_obj_type_t ipaddress_ipv4address_type; + +mp_obj_t common_hal_ipaddress_new_ipv4address(mp_int_t value); +void common_hal_ipaddress_ipv4address_construct(ipaddress_ipv4address_obj_t* self, uint8_t* buf, size_t len); +mp_obj_t common_hal_ipaddress_ipv4address_get_packed(ipaddress_ipv4address_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS_IPV4ADDRESS_H diff --git a/shared-bindings/ipaddress/__init__.c b/shared-bindings/ipaddress/__init__.c new file mode 100644 index 0000000000..f9427ab847 --- /dev/null +++ b/shared-bindings/ipaddress/__init__.c @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objexcept.h" +#include "py/runtime.h" +#include "shared-bindings/ipaddress/__init__.h" +#include "shared-bindings/ipaddress/IPv4Address.h" + +//| """ +//| The `ipaddress` module provides types for IP addresses. It is a subset of CPython's ipaddress +//| module. +//| """ +//| + +//| def ip_address(obj: Union[int]) -> IPv4Address: +//| """Return a corresponding IP address object or raise ValueError if not possible.""" +//| ... +//| + +STATIC mp_obj_t ipaddress_ip_address(mp_obj_t ip_in) { + mp_int_t value; + if (!mp_obj_get_int_maybe(ip_in, &value)) { + mp_raise_ValueError(translate("Only raw int supported for ip.")); + } + + return common_hal_ipaddress_new_ipv4address(value); +} +MP_DEFINE_CONST_FUN_OBJ_1(ipaddress_ip_address_obj, ipaddress_ip_address); + +STATIC const mp_rom_map_elem_t ipaddress_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ipaddress) }, + { MP_ROM_QSTR(MP_QSTR_ip_address), MP_ROM_PTR(&ipaddress_ip_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_IPv4Address), MP_ROM_PTR(&ipaddress_ipv4address_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(ipaddress_module_globals, ipaddress_module_globals_table); + + +const mp_obj_module_t ipaddress_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&ipaddress_module_globals, +}; diff --git a/shared-bindings/ipaddress/__init__.h b/shared-bindings/ipaddress/__init__.h new file mode 100644 index 0000000000..a31629ccae --- /dev/null +++ b/shared-bindings/ipaddress/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H + +#include "shared-module/ipaddress/__init__.h" + +mp_obj_t common_hal_ipaddress_new_ipv4address(mp_int_t value); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H diff --git a/shared-bindings/wifi/Network.c b/shared-bindings/wifi/Network.c index b4d389dcc9..b6d5e0901e 100644 --- a/shared-bindings/wifi/Network.c +++ b/shared-bindings/wifi/Network.c @@ -42,7 +42,7 @@ //| //| ssid: str -//| """True when the wifi network is enabled.""" +//| """String id of the network""" //| STATIC mp_obj_t wifi_network_get_ssid(mp_obj_t self) { return common_hal_wifi_network_get_ssid(self); @@ -57,8 +57,45 @@ const mp_obj_property_t wifi_network_ssid_obj = { (mp_obj_t)&mp_const_none_obj }, }; + +//| rssi: int +//| """Signal strength of the network""" +//| +STATIC mp_obj_t wifi_network_get_rssi(mp_obj_t self) { + return common_hal_wifi_network_get_rssi(self); + +} +MP_DEFINE_CONST_FUN_OBJ_1(wifi_network_get_rssi_obj, wifi_network_get_rssi); + +const mp_obj_property_t wifi_network_rssi_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&wifi_network_get_rssi_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + + +//| channel: int +//| """Channel number the network is operating on""" +//| +STATIC mp_obj_t wifi_network_get_channel(mp_obj_t self) { + return common_hal_wifi_network_get_channel(self); + +} +MP_DEFINE_CONST_FUN_OBJ_1(wifi_network_get_channel_obj, wifi_network_get_channel); + +const mp_obj_property_t wifi_network_channel_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&wifi_network_get_channel_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + + STATIC const mp_rom_map_elem_t wifi_network_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_ssid), MP_ROM_PTR(&wifi_network_ssid_obj) }, + { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&wifi_network_rssi_obj) }, + { MP_ROM_QSTR(MP_QSTR_channel), MP_ROM_PTR(&wifi_network_channel_obj) }, }; STATIC MP_DEFINE_CONST_DICT(wifi_network_locals_dict, wifi_network_locals_dict_table); diff --git a/shared-bindings/wifi/Network.h b/shared-bindings/wifi/Network.h index 8a3d10ca74..6a7f7be4a0 100644 --- a/shared-bindings/wifi/Network.h +++ b/shared-bindings/wifi/Network.h @@ -36,5 +36,7 @@ const mp_obj_type_t wifi_network_type; extern mp_obj_t common_hal_wifi_network_get_ssid(wifi_network_obj_t *self); +extern mp_obj_t common_hal_wifi_network_get_rssi(wifi_network_obj_t *self); +extern mp_obj_t common_hal_wifi_network_get_channel(wifi_network_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_NETWORK_H diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index c5bee83114..1d14235730 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -102,16 +102,18 @@ STATIC mp_obj_t wifi_radio_stop_scanning_networks(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_scanning_networks_obj, wifi_radio_stop_scanning_networks); -//| def connect(self, ssid: ReadableBuffer, password: ReadableBuffer = b"", *, timeout: Optional[float] = None) -> bool: -//| """""" +//| def connect(self, ssid: ReadableBuffer, password: ReadableBuffer = b"", *, channel: Optional[int] = 0, timeout: Optional[float] = None) -> bool: +//| """Connects to the given ssid and waits for an ip address. Reconnections are handled +//| automatically once one connection succeeds.""" //| ... //| STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_ssid, ARG_password, ARG_timeout }; + enum { ARG_ssid, ARG_password, ARG_channel, ARG_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_password, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; wifi_radio_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -136,22 +138,22 @@ STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_m mp_get_buffer_raise(args[ARG_password].u_obj, &password, MP_BUFFER_READ); } - return mp_obj_new_bool(common_hal_wifi_radio_connect(self, ssid.buf, ssid.len, password.buf, password.len, timeout)); + return mp_obj_new_bool(common_hal_wifi_radio_connect(self, ssid.buf, ssid.len, password.buf, password.len, args[ARG_channel].u_int, timeout)); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_connect_obj, 1, wifi_radio_connect); -//| ip_address: Optional[ipaddress.IPAddress] -//| """IP Address of the radio when connected to an access point. None otherwise.""" +//| ipv4_address: Optional[ipaddress.IPv4Address] +//| """IP v4 Address of the radio when connected to an access point. None otherwise.""" //| -STATIC mp_obj_t wifi_radio_get_ip_address(mp_obj_t self) { - return common_hal_wifi_radio_get_ip_address(self); +STATIC mp_obj_t wifi_radio_get_ipv4_address(mp_obj_t self) { + return common_hal_wifi_radio_get_ipv4_address(self); } -MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ip_address_obj, wifi_radio_get_ip_address); +MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_address_obj, wifi_radio_get_ipv4_address); -const mp_obj_property_t wifi_radio_ip_address_obj = { +const mp_obj_property_t wifi_radio_ipv4_address_obj = { .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&wifi_radio_get_ip_address_obj, + .proxy = { (mp_obj_t)&wifi_radio_get_ipv4_address_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj }, }; @@ -179,7 +181,7 @@ STATIC const mp_rom_map_elem_t wifi_radio_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&wifi_radio_connect_obj) }, // { MP_ROM_QSTR(MP_QSTR_connect_to_enterprise), MP_ROM_PTR(&wifi_radio_connect_to_enterprise_obj) }, - { MP_ROM_QSTR(MP_QSTR_ip_address), MP_ROM_PTR(&wifi_radio_ip_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_ipv4_address), MP_ROM_PTR(&wifi_radio_ipv4_address_obj) }, // { MP_ROM_QSTR(MP_QSTR_access_point_active), MP_ROM_PTR(&wifi_radio_access_point_active_obj) }, // { MP_ROM_QSTR(MP_QSTR_start_access_point), MP_ROM_PTR(&wifi_radio_start_access_point_obj) }, diff --git a/shared-bindings/wifi/Radio.h b/shared-bindings/wifi/Radio.h index c3bdac5ba8..3890885aeb 100644 --- a/shared-bindings/wifi/Radio.h +++ b/shared-bindings/wifi/Radio.h @@ -43,9 +43,9 @@ extern mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self); extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self); -extern bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, mp_float_t timeout); +extern bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout); -extern mp_obj_t common_hal_wifi_radio_get_ip_address(wifi_radio_obj_t *self); +extern mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self); extern mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address); diff --git a/shared-module/ipaddress/IPv4Address.c b/shared-module/ipaddress/IPv4Address.c new file mode 100644 index 0000000000..f573d9d0a2 --- /dev/null +++ b/shared-module/ipaddress/IPv4Address.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" + +#include "shared-bindings/ipaddress/__init__.h" +#include "shared-bindings/ipaddress/IPv4Address.h" + + +void common_hal_ipaddress_ipv4address_construct(ipaddress_ipv4address_obj_t* self, uint8_t* buf, size_t len) { + self->ip_bytes = mp_obj_new_bytes(buf, len); +} + +mp_obj_t common_hal_ipaddress_ipv4address_get_packed(ipaddress_ipv4address_obj_t* self) { + return self->ip_bytes; +} diff --git a/shared-module/ipaddress/IPv4Address.h b/shared-module/ipaddress/IPv4Address.h new file mode 100644 index 0000000000..3f2bde0911 --- /dev/null +++ b/shared-module/ipaddress/IPv4Address.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_IPADDRESS_IPV4ADDRESS_H +#define MICROPY_INCLUDED_SHARED_MODULE_IPADDRESS_IPV4ADDRESS_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + mp_obj_t ip_bytes; +} ipaddress_ipv4address_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_IPADDRESS_IPV4ADDRESS_H diff --git a/shared-module/ipaddress/__init__.c b/shared-module/ipaddress/__init__.c new file mode 100644 index 0000000000..e5d857d5dd --- /dev/null +++ b/shared-module/ipaddress/__init__.c @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/ipaddress/__init__.h" +#include "shared-bindings/ipaddress/IPv4Address.h" + +mp_obj_t common_hal_ipaddress_new_ipv4address(mp_int_t value) { + ipaddress_ipv4address_obj_t* self = m_new_obj(ipaddress_ipv4address_obj_t); + self->base.type = &ipaddress_ipv4address_type; + common_hal_ipaddress_ipv4address_construct(self, (uint8_t*) &value, 4); + return self; +} diff --git a/shared-module/ipaddress/__init__.h b/shared-module/ipaddress/__init__.h new file mode 100644 index 0000000000..7d5f2c2207 --- /dev/null +++ b/shared-module/ipaddress/__init__.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_IPADDRESS___INIT___H +#define MICROPY_INCLUDED_SHARED_MODULE_IPADDRESS___INIT___H + +#include + +#include "py/obj.h" + +mp_obj_t common_hal_ipaddress_new_ipv4(uint32_t value); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_IPADDRESS___INIT___H From cdab5e793e9663132f18a9de2b82ae8457e2681b Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 5 Aug 2020 13:31:35 -0700 Subject: [PATCH 07/78] Update to latest idf --- ports/esp32s2/Makefile | 4 +++- ports/esp32s2/esp-idf | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ports/esp32s2/Makefile b/ports/esp32s2/Makefile index e14a737b7c..23a97a6fec 100644 --- a/ports/esp32s2/Makefile +++ b/ports/esp32s2/Makefile @@ -128,6 +128,7 @@ LDFLAGS += -L$(BUILD)/esp-idf/esp-idf/esp32s2 \ -Tesp32s2.peripherals.ld \ -Lesp-idf/components/esp_rom/esp32s2/ld \ -Tesp32s2.rom.ld \ + -Tesp32s2.rom.api.ld \ -Tesp32s2.rom.libgcc.ld \ -Tesp32s2.rom.newlib-data.ld \ -Tesp32s2.rom.newlib-funcs.ld \ @@ -248,7 +249,7 @@ menuconfig: $(BUILD)/esp-idf/config $(HEADER_BUILD)/qstr.i.last: | $(BUILD)/esp-idf/config/sdkconfig.h # Order here matters -ESP_IDF_COMPONENTS_LINK = freertos log esp_system esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash esp_netif lwip +ESP_IDF_COMPONENTS_LINK = freertos log esp_system esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash esp_netif lwip esp_rom ESP_IDF_COMPONENTS_INCLUDE = driver freertos log soc @@ -279,6 +280,7 @@ esp-idf-stamp: $(BUILD)/esp-idf/config/sdkconfig.h esp-idf/esp32s2/ld/esp32s2.project.ld \ esp-idf/esp_event/libesp_event.a \ esp-idf/esp_netif/libesp_netif.a \ + esp-idf/esp_rom/libesp_rom.a \ esp-idf/esp_system/libesp_system.a \ esp-idf/esp_wifi/libesp_wifi.a \ esp-idf/lwip/liblwip.a \ diff --git a/ports/esp32s2/esp-idf b/ports/esp32s2/esp-idf index e15ce11ebc..7391805502 160000 --- a/ports/esp32s2/esp-idf +++ b/ports/esp32s2/esp-idf @@ -1 +1 @@ -Subproject commit e15ce11ebca15a1f6eca22779e89f761b1fc2142 +Subproject commit 739180550254d4d68335cd3b443ada8909905bac From c53a72d3f5ed1f556637ebc3eca2ad27e8eb9fff Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 6 Aug 2020 16:15:35 -0700 Subject: [PATCH 08/78] Fix ipaddress import and parse ipv4 strings --- py/circuitpy_mpconfig.h | 1 + shared-bindings/ipaddress/__init__.c | 29 +++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 8ff2ddc67d..f2789ee587 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -741,6 +741,7 @@ extern const struct _mp_obj_module_t wifi_module; GAMEPADSHIFT_MODULE \ GNSS_MODULE \ I2CPERIPHERAL_MODULE \ + IPADDRESS_MODULE \ JSON_MODULE \ MATH_MODULE \ _EVE_MODULE \ diff --git a/shared-bindings/ipaddress/__init__.c b/shared-bindings/ipaddress/__init__.c index f9427ab847..b88b3afbb9 100644 --- a/shared-bindings/ipaddress/__init__.c +++ b/shared-bindings/ipaddress/__init__.c @@ -25,6 +25,8 @@ */ #include "py/objexcept.h" +#include "py/objstr.h" +#include "py/parsenum.h" #include "py/runtime.h" #include "shared-bindings/ipaddress/__init__.h" #include "shared-bindings/ipaddress/IPv4Address.h" @@ -42,7 +44,32 @@ STATIC mp_obj_t ipaddress_ip_address(mp_obj_t ip_in) { mp_int_t value; - if (!mp_obj_get_int_maybe(ip_in, &value)) { + if (mp_obj_get_int_maybe(ip_in, &value)) { + // We're done. + } else if (MP_OBJ_IS_STR(ip_in)) { + GET_STR_DATA_LEN(ip_in, str_data, str_len); + size_t period_count = 0; + size_t period_index[4] = {0, 0, 0, str_len}; + for (size_t i = 0; i < str_len; i++) { + if (str_data[i] == '.') { + if (period_count < 3) { + period_index[period_count] = i; + } + period_count++; + } + } + if (period_count > 3) { + mp_raise_ValueError(translate("Not a valid IP string.")); + } + + size_t last_period = 0; + for (size_t i = 0; i < 4; i++) { + mp_obj_t octet = mp_parse_num_integer((const char*) str_data + last_period, period_index[i] - last_period, 10, NULL); + last_period = period_index[i] + 1; + value |= MP_OBJ_SMALL_INT_VALUE(octet) << (24 - i * 8); + + } + } else { mp_raise_ValueError(translate("Only raw int supported for ip.")); } From 3860991111511a9e4a60ea24f208b8de8f801ce7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 10 Aug 2020 17:56:49 -0700 Subject: [PATCH 09/78] Ping work and start to add socketpool --- ports/esp32s2/Makefile | 4 + ports/esp32s2/common-hal/wifi/Radio.c | 29 +- ports/esp32s2/esp-idf | 2 +- py/circuitpy_defns.mk | 3 + py/circuitpy_mpconfig.h | 9 + py/circuitpy_mpconfig.mk | 3 + shared-bindings/socketpool/__init__.c | 603 ++++++++++++++++++++++++++ shared-bindings/wifi/Radio.c | 27 +- shared-bindings/wifi/Radio.h | 2 +- shared-module/ipaddress/__init__.c | 5 + shared-module/ipaddress/__init__.h | 4 + 11 files changed, 680 insertions(+), 11 deletions(-) create mode 100644 shared-bindings/socketpool/__init__.c diff --git a/ports/esp32s2/Makefile b/ports/esp32s2/Makefile index 23a97a6fec..ab470d095c 100644 --- a/ports/esp32s2/Makefile +++ b/ports/esp32s2/Makefile @@ -85,6 +85,10 @@ INC += -Iesp-idf/components/esp_rom/include INC += -Iesp-idf/components/esp_wifi/include INC += -Iesp-idf/components/xtensa/include INC += -Iesp-idf/components/esp_timer/include +INC += -Iesp-idf/components/newlib/platform_include +INC += -Iesp-idf/components/lwip/lwip/src/include +INC += -Iesp-idf/components/lwip/port/esp32/include +INC += -Iesp-idf/components/lwip/include/apps/sntp INC += -Iesp-idf/components/soc/include INC += -Iesp-idf/components/soc/src/esp32s2/include INC += -Iesp-idf/components/soc/soc/include diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c index 623ba9e345..49ad0592e7 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.c +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -32,8 +32,10 @@ #include "py/runtime.h" #include "shared-bindings/ipaddress/IPv4Address.h" #include "shared-bindings/wifi/ScannedNetworks.h" +#include "shared-module/ipaddress/__init__.h" #include "esp-idf/components/esp_wifi/include/esp_wifi.h" +#include "esp-idf/components/lwip/include/apps/ping/ping_sock.h" #include "esp_log.h" static const char *TAG = "cp radio"; @@ -154,6 +156,29 @@ mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) { return common_hal_ipaddress_new_ipv4address(ip_info.ip.addr); } -mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address) { - return 0; +mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address, mp_float_t timeout) { + esp_ping_config_t ping_config = ESP_PING_DEFAULT_CONFIG(); + ipaddress_ipaddress_to_esp_idf(ip_address, &ping_config.target_addr); + ping_config.count = 1; + + size_t timeout_ms = timeout * 1000; + + esp_ping_handle_t ping; + esp_ping_new_session(&ping_config, NULL, &ping); + esp_ping_start(ping); + + uint32_t received = 0; + uint32_t total_time_ms = 0; + while (received == 0 && total_time_ms < timeout_ms) { + RUN_BACKGROUND_TASKS; + esp_ping_get_profile(ping, ESP_PING_PROF_DURATION, &total_time_ms, sizeof(total_time_ms)); + esp_ping_get_profile(ping, ESP_PING_PROF_REPLY, &received, sizeof(received)); + } + uint32_t elapsed_time = 0xffffffff; + if (received > 0) { + esp_ping_get_profile(ping, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time)); + } + esp_ping_delete_session(ping); + + return elapsed_time; } diff --git a/ports/esp32s2/esp-idf b/ports/esp32s2/esp-idf index 7391805502..01c86ed7d6 160000 --- a/ports/esp32s2/esp-idf +++ b/ports/esp32s2/esp-idf @@ -1 +1 @@ -Subproject commit 739180550254d4d68335cd3b443ada8909905bac +Subproject commit 01c86ed7d6f4bbbaeda0c461c5f20e3d9872b44b diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 1a5145c8ba..c1b293b94e 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -228,6 +228,9 @@ endif ifeq ($(CIRCUITPY_SHARPDISPLAY),1) SRC_PATTERNS += sharpdisplay/% endif +ifeq ($(CIRCUITPY_SOCKETPOOL),1) +SRC_PATTERNS += socketpool/% +endif ifeq ($(CIRCUITPY_STAGE),1) SRC_PATTERNS += _stage/% endif diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index f2789ee587..846328dcdf 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -573,6 +573,7 @@ extern const struct _mp_obj_module_t sdioio_module; #define SDIOIO_MODULE #endif + #if CIRCUITPY_SHARPDISPLAY extern const struct _mp_obj_module_t sharpdisplay_module; #define SHARPDISPLAY_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_sharpdisplay),(mp_obj_t)&sharpdisplay_module }, @@ -580,6 +581,13 @@ extern const struct _mp_obj_module_t sharpdisplay_module; #define SHARPDISPLAY_MODULE #endif +#if CIRCUITPY_SOCKETPOOL +extern const struct _mp_obj_module_t socketpool_module; +#define SOCKETPOOL_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_socketpool), (mp_obj_t)&socketpool_module }, +#else +#define SOCKETPOOL_MODULE +#endif + #if CIRCUITPY_STAGE extern const struct _mp_obj_module_t stage_module; #define STAGE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__stage), (mp_obj_t)&stage_module }, @@ -764,6 +772,7 @@ extern const struct _mp_obj_module_t wifi_module; SDCARDIO_MODULE \ SDIOIO_MODULE \ SHARPDISPLAY_MODULE \ + SOCKETPOOL_MODULE \ STAGE_MODULE \ STORAGE_MODULE \ STRUCT_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 499e87aed0..2ef8feb3ab 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -185,6 +185,9 @@ CFLAGS += -DCIRCUITPY_SDIOIO=$(CIRCUITPY_SDIOIO) CIRCUITPY_SHARPDISPLAY ?= $(CIRCUITPY_FRAMEBUFFERIO) CFLAGS += -DCIRCUITPY_SHARPDISPLAY=$(CIRCUITPY_SHARPDISPLAY) +CIRCUITPY_SOCKETPOOL ?= 0 +CFLAGS += -DCIRCUITPY_SOCKETPOOL=$(CIRCUITPY_SOCKETPOOL) + # Currently always off. CIRCUITPY_STAGE ?= 0 CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE) diff --git a/shared-bindings/socketpool/__init__.c b/shared-bindings/socketpool/__init__.c new file mode 100644 index 0000000000..53ac57d11a --- /dev/null +++ b/shared-bindings/socketpool/__init__.c @@ -0,0 +1,603 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * 2018 Nick Moore for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "py/objtuple.h" +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "py/mperrno.h" +#include "lib/netutils/netutils.h" + +#include "shared-module/network/__init__.h" + +//| """TCP, UDP and RAW socket support +//| +//| .. warning:: This module is disabled in 6.x and will removed in 7.x. Please use networking +//| libraries instead. (Native networking will provide a socket compatible class.) +//| +//| Create TCP, UDP and RAW sockets for communicating over the Internet.""" +//| + +STATIC const mp_obj_type_t socket_type; + +//| class socket: +//| +//| def __init__(self, family: int, type: int, proto: int) -> None: +//| """Create a new socket +//| +//| :param ~int family: AF_INET or AF_INET6 +//| :param ~int type: SOCK_STREAM, SOCK_DGRAM or SOCK_RAW +//| :param ~int proto: IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW (ignored)""" +//| ... +//| + +STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 4, false); + + // create socket object (not bound to any NIC yet) + mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t); + s->base.type = &socket_type; + s->nic = MP_OBJ_NULL; + s->nic_type = NULL; + s->u_param.domain = MOD_NETWORK_AF_INET; + s->u_param.type = MOD_NETWORK_SOCK_STREAM; + s->u_param.fileno = -1; + if (n_args >= 1) { + s->u_param.domain = mp_obj_get_int(args[0]); + if (n_args >= 2) { + s->u_param.type = mp_obj_get_int(args[1]); + if (n_args >= 4) { + s->u_param.fileno = mp_obj_get_int(args[3]); + } + } + } + + return MP_OBJ_FROM_PTR(s); +} + +STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) { + if (self->nic == MP_OBJ_NULL) { + // select NIC based on IP + self->nic = network_module_find_nic(ip); + self->nic_type = (mod_network_nic_type_t*)mp_obj_get_type(self->nic); + + // call the NIC to open the socket + int _errno; + if (self->nic_type->socket(self, &_errno) != 0) { + mp_raise_OSError(_errno); + } + } +} + +//| def bind(self, address: tuple) -> None: +//| """Bind a socket to an address +//| +//| :param ~tuple address: tuple of (remote_address, remote_port)""" +//| ... +//| + +STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // get address + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // check if we need to select a NIC + socket_select_nic(self, ip); + + // call the NIC to bind the socket + int _errno; + if (self->nic_type->bind(self, ip, port, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind); + +//| def listen(self, backlog: int) -> None: +//| """Set socket to listen for incoming connections +//| +//| :param ~int backlog: length of backlog queue for waiting connetions""" +//| ... +//| + +STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (self->nic == MP_OBJ_NULL) { + // not connected + // TODO I think we can listen even if not bound... + mp_raise_OSError(MP_ENOTCONN); + } + + int _errno; + if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen); + +//| def accept(self) -> tuple: +//| """Accept a connection on a listening socket of type SOCK_STREAM, +//| creating a new socket of type SOCK_STREAM. +//| Returns a tuple of (new_socket, remote_address)""" +//| + +STATIC mp_obj_t socket_accept(mp_obj_t self_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // create new socket object + // starts with empty NIC so that finaliser doesn't run close() method if accept() fails + mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t); + socket2->base.type = &socket_type; + socket2->nic = MP_OBJ_NULL; + socket2->nic_type = NULL; + + // accept incoming connection + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port; + int _errno; + if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + // new socket has valid state, so set the NIC to the same as parent + socket2->nic = self->nic; + socket2->nic_type = self->nic_type; + + // make the return value + mp_obj_tuple_t *client = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + client->items[0] = MP_OBJ_FROM_PTR(socket2); + client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); + + return MP_OBJ_FROM_PTR(client); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept); + +//| def connect(self, address: tuple) -> None: +//| """Connect a socket to a remote address +//| +//| :param ~tuple address: tuple of (remote_address, remote_port)""" +//| ... +//| + +STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // get address + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // check if we need to select a NIC + socket_select_nic(self, ip); + + // call the NIC to connect the socket + int _errno; + if (self->nic_type->connect(self, ip, port, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect); + +//| def send(self, bytes: ReadableBuffer) -> int: +//| """Send some bytes to the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| +//| :param ~bytes bytes: some bytes to send""" +//| ... +//| + +STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_EPIPE); + } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + int _errno; + mp_int_t ret = self->nic_type->send(self, bufinfo.buf, bufinfo.len, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + return mp_obj_new_int_from_uint(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send); + + +// helper function for socket_recv and socket_recv_into to handle common operations of both +STATIC mp_int_t _socket_recv_into(mod_network_socket_obj_t *sock, byte *buf, mp_int_t len) { + int _errno; + mp_int_t ret = sock->nic_type->recv(sock, buf, len, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + return ret; +} + + +//| def recv_into(self, buffer: WriteableBuffer, bufsize: int) -> int: +//| """Reads some bytes from the connected remote address, writing +//| into the provided buffer. If bufsize <= len(buffer) is given, +//| a maximum of bufsize bytes will be read into the buffer. If no +//| valid value is given for bufsize, the default is the length of +//| the given buffer. +//| +//| Suits sockets of type SOCK_STREAM +//| Returns an int of number of bytes read. +//| +//| :param bytearray buffer: buffer to receive into +//| :param int bufsize: optionally, a maximum number of bytes to read.""" +//| ... +//| + +STATIC mp_obj_t socket_recv_into(size_t n_args, const mp_obj_t *args) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); + mp_int_t len = bufinfo.len; + if (n_args == 3) { + mp_int_t given_len = mp_obj_get_int(args[2]); + if (given_len < len) { + len = given_len; + } + } + + mp_int_t ret = _socket_recv_into(self, (byte*)bufinfo.buf, len); + return mp_obj_new_int_from_uint(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_recv_into_obj, 2, 3, socket_recv_into); + +//| def recv(self, bufsize: int) -> bytes: +//| """Reads some bytes from the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| Returns a bytes() of length <= bufsize +//| +//| :param ~int bufsize: maximum number of bytes to receive""" +//| ... +//| + +STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } + mp_int_t len = mp_obj_get_int(len_in); + vstr_t vstr; + vstr_init_len(&vstr, len); + mp_int_t ret = _socket_recv_into(self, (byte*)vstr.buf, len); + if (ret == 0) { + return mp_const_empty_bytes; + } + vstr.len = ret; + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv); + +//| def sendto(self, bytes: ReadableBuffer, address: tuple) -> int: +//| """Send some bytes to a specific address. +//| Suits sockets of type SOCK_DGRAM +//| +//| :param ~bytes bytes: some bytes to send +//| :param ~tuple address: tuple of (remote_address, remote_port)""" +//| ... +//| + +STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // get the data + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); + + // get address + uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // check if we need to select a NIC + socket_select_nic(self, ip); + + // call the NIC to sendto + int _errno; + mp_int_t ret = self->nic_type->sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + + return mp_obj_new_int(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto); + +//| def recvfrom(self, bufsize: int) -> Tuple[bytes, tuple]: +//| """Reads some bytes from the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| +//| Returns a tuple containing +//| * a bytes() of length <= bufsize +//| * a remote_address, which is a tuple of ip address and port number +//| +//| :param ~int bufsize: maximum number of bytes to receive""" +//| ... +//| + +STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } + vstr_t vstr; + vstr_init_len(&vstr, mp_obj_get_int(len_in)); + byte ip[4]; + mp_uint_t port; + int _errno; + mp_int_t ret = self->nic_type->recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno); + if (ret == -1) { + mp_raise_OSError(_errno); + } + mp_obj_t tuple[2]; + if (ret == 0) { + tuple[0] = mp_const_empty_bytes; + } else { + vstr.len = ret; + tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + } + tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recvfrom_obj, socket_recvfrom); + +//| def setsockopt(self, level: int, optname: int, value: int) -> None: +//| """Sets socket options""" +//| ... +//| + +STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) { + 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]); + + const void *optval; + mp_uint_t optlen; + mp_int_t val; + if (mp_obj_is_integer(args[3])) { + val = mp_obj_get_int_truncated(args[3]); + optval = &val; + optlen = sizeof(val); + } else { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); + optval = bufinfo.buf; + optlen = bufinfo.len; + } + + int _errno; + if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) { + mp_raise_OSError(_errno); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_setsockopt); + +//| def settimeout(self, value: int) -> None: +//| """Set the timeout value for this socket. +//| +//| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely.""" +//| ... +//| + +STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->nic == MP_OBJ_NULL) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } + mp_uint_t timeout; + if (timeout_in == mp_const_none) { + timeout = -1; + } else { + #if MICROPY_PY_BUILTINS_FLOAT + timeout = 1000 * mp_obj_get_float(timeout_in); + #else + timeout = 1000 * mp_obj_get_int(timeout_in); + #endif + } + int _errno; + if (self->nic_type->settimeout(self, timeout, &_errno) != 0) { + mp_raise_OSError(_errno); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_settimeout_obj, socket_settimeout); + +//| def setblocking(self, flag: bool) -> Optional[int]: +//| """Set the blocking behaviour of this socket. +//| +//| :param ~bool flag: False means non-blocking, True means block indefinitely.""" +//| ... +//| + +// method socket.setblocking(flag) +STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { + if (mp_obj_is_true(blocking)) { + return socket_settimeout(self_in, mp_const_none); + } else { + return socket_settimeout(self_in, MP_OBJ_NEW_SMALL_INT(0)); + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking); + +STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, + { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socket_bind_obj) }, + { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socket_listen_obj) }, + { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socket_accept_obj) }, + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&socket_connect_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socket_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&socket_recv_obj) }, + { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socket_sendto_obj) }, + { MP_ROM_QSTR(MP_QSTR_recvfrom), MP_ROM_PTR(&socket_recvfrom_obj) }, + { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socket_recv_into_obj) }, + { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socket_setsockopt_obj) }, + { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socket_settimeout_obj) }, + { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table); + +mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (request == MP_STREAM_CLOSE) { + if (self->nic != MP_OBJ_NULL) { + self->nic_type->close(self); + self->nic = MP_OBJ_NULL; + } + return 0; + } + return self->nic_type->ioctl(self, request, arg, errcode); +} + +STATIC const mp_stream_p_t socket_stream_p = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream) + .ioctl = socket_ioctl, + .is_text = false, +}; + +STATIC const mp_obj_type_t socket_type = { + { &mp_type_type }, + .name = MP_QSTR_socket, + .make_new = socket_make_new, + .protocol = &socket_stream_p, + .locals_dict = (mp_obj_dict_t*)&socket_locals_dict, +}; + +//| def getaddrinfo(host: str, port: int) -> tuple: +//| """Gets the address information for a hostname and port +//| +//| Returns the appropriate family, socket type, socket protocol and +//| address information to call socket.socket() and socket.connect() with, +//| as a tuple.""" +//| ... +//| + +STATIC mp_obj_t socket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { + size_t hlen; + const char *host = mp_obj_str_get_data(host_in, &hlen); + mp_int_t port = mp_obj_get_int(port_in); + uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + bool have_ip = false; + + if (hlen > 0) { + // check if host is already in IP form + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + netutils_parse_ipv4_addr(host_in, out_ip, NETUTILS_BIG); + have_ip = true; + nlr_pop(); + } else { + // swallow exception: host was not in IP form so need to do DNS lookup + } + } + + if (!have_ip) { + // find a NIC that can do a name lookup + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; + mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); + if (nic_type->gethostbyname != NULL) { + int ret = nic_type->gethostbyname(nic, host, hlen, out_ip); + if (ret != 0) { + mp_raise_OSError(ret); + } + have_ip = true; + break; + } + } + } + + if (!have_ip) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC"))); + } + + mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL)); + tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET); + tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM); + tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); + tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_); + tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG); + return mp_obj_new_list(1, (mp_obj_t*)&tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_getaddrinfo_obj, socket_getaddrinfo); + +STATIC const mp_rom_map_elem_t socket_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usocket) }, + + { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&socket_type) }, + { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&socket_getaddrinfo_obj) }, + + // class constants + { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(MOD_NETWORK_AF_INET) }, + { MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(MOD_NETWORK_AF_INET6) }, + + { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(MOD_NETWORK_SOCK_STREAM) }, + { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(MOD_NETWORK_SOCK_DGRAM) }, + { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(MOD_NETWORK_SOCK_RAW) }, + + /* + { MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(MOD_NETWORK_IPPROTO_IP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_ICMP), MP_ROM_INT(MOD_NETWORK_IPPROTO_ICMP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV4), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV4) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_TCP), MP_ROM_INT(MOD_NETWORK_IPPROTO_TCP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_UDP), MP_ROM_INT(MOD_NETWORK_IPPROTO_UDP) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV6), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV6) }, + { MP_ROM_QSTR(MP_QSTR_IPPROTO_RAW), MP_ROM_INT(MOD_NETWORK_IPPROTO_RAW) }, + */ +}; + +STATIC MP_DEFINE_CONST_DICT(socket_globals, socket_globals_table); + +const mp_obj_module_t socket_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&socket_globals, +}; diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index 1d14235730..6884b83de0 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -158,18 +158,31 @@ const mp_obj_property_t wifi_radio_ipv4_address_obj = { (mp_obj_t)&mp_const_none_obj }, }; -//| def ping(self, ip) -> int: -//| """Ping an IP to test connectivity. Returns echo time in milliseconds.""" +//| def ping(self, ip, *, timeout: float = 0.5) -> float: +//| """Ping an IP to test connectivity. Returns echo time in seconds.""" //| ... //| -STATIC mp_obj_t wifi_radio_ping(mp_obj_t self_in, mp_obj_t ip_address) { - wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t wifi_radio_ping(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_ip, ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_ip, MP_ARG_REQUIRED | MP_ARG_OBJ, }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; - common_hal_wifi_radio_ping(self, ip_address); + wifi_radio_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - return mp_const_none; + mp_float_t timeout = 0.5; + if (args[ARG_timeout].u_obj != mp_const_none) { + timeout = mp_obj_get_float(args[ARG_timeout].u_obj); + } + + mp_int_t time_ms = common_hal_wifi_radio_ping(self, args[ARG_ip].u_obj, timeout); + + return mp_obj_new_float(time_ms / 1000); } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(wifi_radio_ping_obj, wifi_radio_ping); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_ping_obj, 1, wifi_radio_ping); STATIC const mp_rom_map_elem_t wifi_radio_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_enabled), MP_ROM_PTR(&wifi_radio_enabled_obj) }, diff --git a/shared-bindings/wifi/Radio.h b/shared-bindings/wifi/Radio.h index 3890885aeb..c83a135a6a 100644 --- a/shared-bindings/wifi/Radio.h +++ b/shared-bindings/wifi/Radio.h @@ -47,6 +47,6 @@ extern bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, extern mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self); -extern mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address); +extern mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address, mp_float_t timeout); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_RADIO_H diff --git a/shared-module/ipaddress/__init__.c b/shared-module/ipaddress/__init__.c index e5d857d5dd..031f317aab 100644 --- a/shared-module/ipaddress/__init__.c +++ b/shared-module/ipaddress/__init__.c @@ -33,3 +33,8 @@ mp_obj_t common_hal_ipaddress_new_ipv4address(mp_int_t value) { common_hal_ipaddress_ipv4address_construct(self, (uint8_t*) &value, 4); return self; } + + +void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t* esp_ip_address) { + // FIX THIS TOMORROW! +} diff --git a/shared-module/ipaddress/__init__.h b/shared-module/ipaddress/__init__.h index 7d5f2c2207..9f1e007779 100644 --- a/shared-module/ipaddress/__init__.h +++ b/shared-module/ipaddress/__init__.h @@ -31,6 +31,10 @@ #include "py/obj.h" +#include "lwip/api.h" + mp_obj_t common_hal_ipaddress_new_ipv4(uint32_t value); +void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t* esp_ip_address); + #endif // MICROPY_INCLUDED_SHARED_MODULE_IPADDRESS___INIT___H From 7bdd243bf6f3cd84ddfd9cf6f35a2d6d8a6a415f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 11 Aug 2020 14:50:37 -0700 Subject: [PATCH 10/78] Ping works! --- ports/esp32s2/common-hal/wifi/Radio.c | 1 + ports/esp32s2/common-hal/wifi/__init__.c | 14 ++++++++++++++ ports/esp32s2/common-hal/wifi/__init__.h | 4 ++++ shared-bindings/ipaddress/IPv4Address.h | 2 +- shared-bindings/ipaddress/__init__.c | 9 +++++---- shared-bindings/ipaddress/__init__.h | 2 +- shared-bindings/wifi/Radio.c | 2 +- shared-module/ipaddress/__init__.c | 7 +------ shared-module/ipaddress/__init__.h | 4 ---- 9 files changed, 28 insertions(+), 17 deletions(-) diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c index 49ad0592e7..d4f17f2bb0 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.c +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -28,6 +28,7 @@ #include +#include "common-hal/wifi/__init__.h" #include "lib/utils/interrupt_char.h" #include "py/runtime.h" #include "shared-bindings/ipaddress/IPv4Address.h" diff --git a/ports/esp32s2/common-hal/wifi/__init__.c b/ports/esp32s2/common-hal/wifi/__init__.c index 1dc9ef9a89..eb033256d2 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.c +++ b/ports/esp32s2/common-hal/wifi/__init__.c @@ -24,6 +24,9 @@ * THE SOFTWARE. */ +#include "common-hal/wifi/__init__.h" + +#include "shared-bindings/ipaddress/IPv4Address.h" #include "shared-bindings/wifi/Radio.h" #include "py/runtime.h" @@ -148,3 +151,14 @@ void wifi_reset(void) { radio->netif = NULL; ESP_ERROR_CHECK(esp_netif_deinit()); } + +void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t* esp_ip_address) { + if (!MP_OBJ_IS_TYPE(ip_address, &ipaddress_ipv4address_type)) { + mp_raise_ValueError(translate("Only IPv4 addresses supported")); + } + mp_obj_t packed = common_hal_ipaddress_ipv4address_get_packed(ip_address); + size_t len; + const char* bytes = mp_obj_str_get_data(packed, &len); + + IP_ADDR4(esp_ip_address, bytes[0], bytes[1], bytes[2], bytes[3]); +} diff --git a/ports/esp32s2/common-hal/wifi/__init__.h b/ports/esp32s2/common-hal/wifi/__init__.h index bb68bcfdf0..d2bd06c570 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.h +++ b/ports/esp32s2/common-hal/wifi/__init__.h @@ -29,6 +29,10 @@ #include "py/obj.h" +#include "lwip/api.h" + void wifi_reset(void); +void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t* esp_ip_address); + #endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI___INIT___H diff --git a/shared-bindings/ipaddress/IPv4Address.h b/shared-bindings/ipaddress/IPv4Address.h index cf66b92b35..b45cf3bacb 100644 --- a/shared-bindings/ipaddress/IPv4Address.h +++ b/shared-bindings/ipaddress/IPv4Address.h @@ -31,7 +31,7 @@ extern const mp_obj_type_t ipaddress_ipv4address_type; -mp_obj_t common_hal_ipaddress_new_ipv4address(mp_int_t value); +mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value); void common_hal_ipaddress_ipv4address_construct(ipaddress_ipv4address_obj_t* self, uint8_t* buf, size_t len); mp_obj_t common_hal_ipaddress_ipv4address_get_packed(ipaddress_ipv4address_obj_t* self); diff --git a/shared-bindings/ipaddress/__init__.c b/shared-bindings/ipaddress/__init__.c index b88b3afbb9..1c0ac9153b 100644 --- a/shared-bindings/ipaddress/__init__.c +++ b/shared-bindings/ipaddress/__init__.c @@ -43,8 +43,8 @@ //| STATIC mp_obj_t ipaddress_ip_address(mp_obj_t ip_in) { - mp_int_t value; - if (mp_obj_get_int_maybe(ip_in, &value)) { + uint32_t value; + if (mp_obj_get_int_maybe(ip_in, (mp_int_t*) &value)) { // We're done. } else if (MP_OBJ_IS_STR(ip_in)) { GET_STR_DATA_LEN(ip_in, str_data, str_len); @@ -63,11 +63,12 @@ STATIC mp_obj_t ipaddress_ip_address(mp_obj_t ip_in) { } size_t last_period = 0; + value = 0; for (size_t i = 0; i < 4; i++) { mp_obj_t octet = mp_parse_num_integer((const char*) str_data + last_period, period_index[i] - last_period, 10, NULL); last_period = period_index[i] + 1; - value |= MP_OBJ_SMALL_INT_VALUE(octet) << (24 - i * 8); - + mp_int_t int_octet = MP_OBJ_SMALL_INT_VALUE(octet); + value |= int_octet << (i * 8); } } else { mp_raise_ValueError(translate("Only raw int supported for ip.")); diff --git a/shared-bindings/ipaddress/__init__.h b/shared-bindings/ipaddress/__init__.h index a31629ccae..76d8bfa766 100644 --- a/shared-bindings/ipaddress/__init__.h +++ b/shared-bindings/ipaddress/__init__.h @@ -29,6 +29,6 @@ #include "shared-module/ipaddress/__init__.h" -mp_obj_t common_hal_ipaddress_new_ipv4address(mp_int_t value); +mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index 6884b83de0..260a280c2b 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -180,7 +180,7 @@ STATIC mp_obj_t wifi_radio_ping(size_t n_args, const mp_obj_t *pos_args, mp_map_ mp_int_t time_ms = common_hal_wifi_radio_ping(self, args[ARG_ip].u_obj, timeout); - return mp_obj_new_float(time_ms / 1000); + return mp_obj_new_float(time_ms / 1000.0); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_ping_obj, 1, wifi_radio_ping); diff --git a/shared-module/ipaddress/__init__.c b/shared-module/ipaddress/__init__.c index 031f317aab..2fce9d8f51 100644 --- a/shared-module/ipaddress/__init__.c +++ b/shared-module/ipaddress/__init__.c @@ -27,14 +27,9 @@ #include "shared-bindings/ipaddress/__init__.h" #include "shared-bindings/ipaddress/IPv4Address.h" -mp_obj_t common_hal_ipaddress_new_ipv4address(mp_int_t value) { +mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value) { ipaddress_ipv4address_obj_t* self = m_new_obj(ipaddress_ipv4address_obj_t); self->base.type = &ipaddress_ipv4address_type; common_hal_ipaddress_ipv4address_construct(self, (uint8_t*) &value, 4); return self; } - - -void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t* esp_ip_address) { - // FIX THIS TOMORROW! -} diff --git a/shared-module/ipaddress/__init__.h b/shared-module/ipaddress/__init__.h index 9f1e007779..7d5f2c2207 100644 --- a/shared-module/ipaddress/__init__.h +++ b/shared-module/ipaddress/__init__.h @@ -31,10 +31,6 @@ #include "py/obj.h" -#include "lwip/api.h" - mp_obj_t common_hal_ipaddress_new_ipv4(uint32_t value); -void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t* esp_ip_address); - #endif // MICROPY_INCLUDED_SHARED_MODULE_IPADDRESS___INIT___H From c9ece21c2846d57f3c32b364be1209d884e388b1 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 11 Aug 2020 16:04:55 -0700 Subject: [PATCH 11/78] SocketPool stubbed out --- ports/esp32s2/common-hal/socketpool/Socket.c | 25 + ports/esp32s2/common-hal/socketpool/Socket.h | 36 ++ .../common-hal/socketpool/SocketPool.c | 25 + .../common-hal/socketpool/SocketPool.h | 34 + .../esp32s2/common-hal/socketpool/__init__.c | 31 + .../esp32s2/common-hal/socketpool/__init__.h | 31 + py/circuitpy_defns.mk | 3 + py/circuitpy_mpconfig.mk | 2 +- shared-bindings/socketpool/Socket.c | 473 ++++++++++++++ shared-bindings/socketpool/Socket.h | 38 ++ shared-bindings/socketpool/SocketPool.c | 164 +++++ shared-bindings/socketpool/SocketPool.h | 48 ++ shared-bindings/socketpool/__init__.c | 586 +----------------- shared-bindings/socketpool/__init__.h | 34 + 14 files changed, 961 insertions(+), 569 deletions(-) create mode 100644 ports/esp32s2/common-hal/socketpool/Socket.c create mode 100644 ports/esp32s2/common-hal/socketpool/Socket.h create mode 100644 ports/esp32s2/common-hal/socketpool/SocketPool.c create mode 100644 ports/esp32s2/common-hal/socketpool/SocketPool.h create mode 100644 ports/esp32s2/common-hal/socketpool/__init__.c create mode 100644 ports/esp32s2/common-hal/socketpool/__init__.h create mode 100644 shared-bindings/socketpool/Socket.c create mode 100644 shared-bindings/socketpool/Socket.h create mode 100644 shared-bindings/socketpool/SocketPool.c create mode 100644 shared-bindings/socketpool/SocketPool.h create mode 100644 shared-bindings/socketpool/__init__.h diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c new file mode 100644 index 0000000000..fa0e7d5f3f --- /dev/null +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -0,0 +1,25 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ diff --git a/ports/esp32s2/common-hal/socketpool/Socket.h b/ports/esp32s2/common-hal/socketpool/Socket.h new file mode 100644 index 0000000000..4540b6d439 --- /dev/null +++ b/ports/esp32s2/common-hal/socketpool/Socket.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKET_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKET_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} socketpool_socket_obj_t; + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKET_H diff --git a/ports/esp32s2/common-hal/socketpool/SocketPool.c b/ports/esp32s2/common-hal/socketpool/SocketPool.c new file mode 100644 index 0000000000..fa0e7d5f3f --- /dev/null +++ b/ports/esp32s2/common-hal/socketpool/SocketPool.c @@ -0,0 +1,25 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ diff --git a/ports/esp32s2/common-hal/socketpool/SocketPool.h b/ports/esp32s2/common-hal/socketpool/SocketPool.h new file mode 100644 index 0000000000..dc46d8958a --- /dev/null +++ b/ports/esp32s2/common-hal/socketpool/SocketPool.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKETPOOL_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKETPOOL_H + +typedef struct { + mp_obj_base_t base; +} socketpool_socketpool_obj_t; + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKETPOOL_H diff --git a/ports/esp32s2/common-hal/socketpool/__init__.c b/ports/esp32s2/common-hal/socketpool/__init__.c new file mode 100644 index 0000000000..8f9565b46e --- /dev/null +++ b/ports/esp32s2/common-hal/socketpool/__init__.c @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H + + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H diff --git a/ports/esp32s2/common-hal/socketpool/__init__.h b/ports/esp32s2/common-hal/socketpool/__init__.h new file mode 100644 index 0000000000..8f9565b46e --- /dev/null +++ b/ports/esp32s2/common-hal/socketpool/__init__.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H + + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index c1b293b94e..43f6977f0f 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -337,6 +337,9 @@ SRC_COMMON_HAL_ALL = \ rtc/__init__.c \ sdioio/SDCard.c \ sdioio/__init__.c \ + socketpool/__init__.c \ + socketpool/SocketPool.c \ + socketpool/Socket.c \ supervisor/Runtime.c \ supervisor/__init__.c \ watchdog/WatchDogMode.c \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 2ef8feb3ab..35ed6df028 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -185,7 +185,7 @@ CFLAGS += -DCIRCUITPY_SDIOIO=$(CIRCUITPY_SDIOIO) CIRCUITPY_SHARPDISPLAY ?= $(CIRCUITPY_FRAMEBUFFERIO) CFLAGS += -DCIRCUITPY_SHARPDISPLAY=$(CIRCUITPY_SHARPDISPLAY) -CIRCUITPY_SOCKETPOOL ?= 0 +CIRCUITPY_SOCKETPOOL ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_SOCKETPOOL=$(CIRCUITPY_SOCKETPOOL) # Currently always off. diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c new file mode 100644 index 0000000000..e4d79616a6 --- /dev/null +++ b/shared-bindings/socketpool/Socket.c @@ -0,0 +1,473 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * 2018 Nick Moore for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/socketpool/Socket.h" + +#include +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/objtuple.h" +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/mperrno.h" + +//| class Socket: +//| """TCP, UDP and RAW socket. Cannot be created directly. Instead, call +//| `SocketPool.socket()`. +//| +//| Provides a subset of CPython's `socket.socket` API. It only implements the versions of +//| recv that do not allocate bytes objects.""" +//| + +//| def __enter__(self) -> Socket: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically closes the Socket when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +STATIC mp_obj_t socketpool_socket___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + // common_hal_pulseio_pwmout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket___exit___obj, 4, 4, socketpool_socket___exit__); + +//| def bind(self, address: tuple) -> None: +//| """Bind a socket to an address +//| +//| :param ~tuple address: tuple of (remote_address, remote_port)""" +//| ... +//| + +STATIC mp_obj_t socketpool_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { + // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // // get address + // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + // mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // // check if we need to select a NIC + // socket_select_nic(self, ip); + + // // call the NIC to bind the socket + // int _errno; + // if (self->nic_type->bind(self, ip, port, &_errno) != 0) { + // mp_raise_OSError(_errno); + // } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_bind_obj, socketpool_socket_bind); + +//| def listen(self, backlog: int) -> None: +//| """Set socket to listen for incoming connections +//| +//| :param ~int backlog: length of backlog queue for waiting connetions""" +//| ... +//| + +STATIC mp_obj_t socketpool_socket_listen(mp_obj_t self_in, mp_obj_t backlog) { + // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // if (self->nic == MP_OBJ_NULL) { + // // not connected + // // TODO I think we can listen even if not bound... + // mp_raise_OSError(MP_ENOTCONN); + // } + + // int _errno; + // if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) { + // mp_raise_OSError(_errno); + // } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_listen_obj, socketpool_socket_listen); + +//| def accept(self) -> tuple: +//| """Accept a connection on a listening socket of type SOCK_STREAM, +//| creating a new socket of type SOCK_STREAM. +//| Returns a tuple of (new_socket, remote_address)""" +//| + +STATIC mp_obj_t socketpool_socket_accept(mp_obj_t self_in) { + // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // // create new socket object + // // starts with empty NIC so that finaliser doesn't run close() method if accept() fails + // mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t); + // socket2->base.type = &socket_type; + // socket2->nic = MP_OBJ_NULL; + // socket2->nic_type = NULL; + + // // accept incoming connection + // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + // mp_uint_t port; + // int _errno; + // if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) { + // mp_raise_OSError(_errno); + // } + + // // new socket has valid state, so set the NIC to the same as parent + // socket2->nic = self->nic; + // socket2->nic_type = self->nic_type; + + // // make the return value + // mp_obj_tuple_t *client = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + // client->items[0] = MP_OBJ_FROM_PTR(socket2); + // client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, socketpool_socket_accept); + +//| def close(self) -> None: +//| """Closes this Socket and makes its resources available to its SocketPool.""" +//| +STATIC mp_obj_t socketpool_socket_close(mp_obj_t self_in) { + // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // // create new socket object + // // starts with empty NIC so that finaliser doesn't run close() method if accept() fails + // mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t); + // socket2->base.type = &socket_type; + // socket2->nic = MP_OBJ_NULL; + // socket2->nic_type = NULL; + + // // accept incoming connection + // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + // mp_uint_t port; + // int _errno; + // if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) { + // mp_raise_OSError(_errno); + // } + + // // new socket has valid state, so set the NIC to the same as parent + // socket2->nic = self->nic; + // socket2->nic_type = self->nic_type; + + // // make the return value + // mp_obj_tuple_t *client = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + // client->items[0] = MP_OBJ_FROM_PTR(socket2); + // client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_close_obj, socketpool_socket_close); + +//| def connect(self, address: tuple) -> None: +//| """Connect a socket to a remote address +//| +//| :param ~tuple address: tuple of (remote_address, remote_port)""" +//| ... +//| + +STATIC mp_obj_t socketpool_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { + // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // // get address + // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + // mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // // check if we need to select a NIC + // socket_select_nic(self, ip); + + // // call the NIC to connect the socket + // int _errno; + // if (self->nic_type->connect(self, ip, port, &_errno) != 0) { + // mp_raise_OSError(_errno); + // } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_connect_obj, socketpool_socket_connect); + +//| def send(self, bytes: ReadableBuffer) -> int: +//| """Send some bytes to the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| +//| :param ~bytes bytes: some bytes to send""" +//| ... +//| + +STATIC mp_obj_t socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) { + mp_int_t ret = 0; + // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + // if (self->nic == MP_OBJ_NULL) { + // // not connected + // mp_raise_OSError(MP_EPIPE); + // } + // mp_buffer_info_t bufinfo; + // mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + // int _errno; + // mp_int_t ret = self->nic_type->send(self, bufinfo.buf, bufinfo.len, &_errno); + // if (ret == -1) { + // mp_raise_OSError(_errno); + // } + return mp_obj_new_int_from_uint(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, socketpool_socket_send); + + +// helper function for socket_recv and socket_recv_into to handle common operations of both +// STATIC mp_int_t _socket_recv_into(mod_network_socket_obj_t *sock, byte *buf, mp_int_t len) { +// mp_int_t ret = 0; +// // int _errno; +// // mp_int_t ret = sock->nic_type->recv(sock, buf, len, &_errno); +// // if (ret == -1) { +// // mp_raise_OSError(_errno); +// // } +// return ret; +// } + + +//| def recv_into(self, buffer: WriteableBuffer, bufsize: int) -> int: +//| """Reads some bytes from the connected remote address, writing +//| into the provided buffer. If bufsize <= len(buffer) is given, +//| a maximum of bufsize bytes will be read into the buffer. If no +//| valid value is given for bufsize, the default is the length of +//| the given buffer. +//| +//| Suits sockets of type SOCK_STREAM +//| Returns an int of number of bytes read. +//| +//| :param bytearray buffer: buffer to receive into +//| :param int bufsize: optionally, a maximum number of bytes to read.""" +//| ... +//| + +STATIC mp_obj_t socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args) { + // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); + // if (self->nic == MP_OBJ_NULL) { + // // not connected + // mp_raise_OSError(MP_ENOTCONN); + // } + // mp_buffer_info_t bufinfo; + // mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); + // mp_int_t len = bufinfo.len; + // if (n_args == 3) { + // mp_int_t given_len = mp_obj_get_int(args[2]); + // if (given_len < len) { + // len = given_len; + // } + // } + + // mp_int_t ret = _socket_recv_into(self, (byte*)bufinfo.buf, len); + mp_int_t ret = 0; + return mp_obj_new_int_from_uint(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_recv_into_obj, 2, 3, socketpool_socket_recv_into); + +//| def sendto(self, bytes: ReadableBuffer, address: tuple) -> int: +//| """Send some bytes to a specific address. +//| Suits sockets of type SOCK_DGRAM +//| +//| :param ~bytes bytes: some bytes to send +//| :param ~tuple address: tuple of (remote_address, remote_port)""" +//| ... +//| + +STATIC mp_obj_t socketpool_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { + // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + + // // get the data + // mp_buffer_info_t bufinfo; + // mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); + + // // get address + // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + // mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + + // // check if we need to select a NIC + // socket_select_nic(self, ip); + + // // call the NIC to sendto + // int _errno; + // mp_int_t ret = self->nic_type->sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno); + // if (ret == -1) { + // mp_raise_OSError(_errno); + // } + mp_int_t ret = 0; + + return mp_obj_new_int(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(socketpool_socket_sendto_obj, socketpool_socket_sendto); + +//| def recvfrom(self, bufsize: int) -> Tuple[bytes, tuple]: +//| """Reads some bytes from the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| +//| Returns a tuple containing +//| * a bytes() of length <= bufsize +//| * a remote_address, which is a tuple of ip address and port number +//| +//| :param ~int bufsize: maximum number of bytes to receive""" +//| ... +//| + +STATIC mp_obj_t socketpool_socket_recvfrom_into(mp_obj_t self_in, mp_obj_t len_in) { + // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + // if (self->nic == MP_OBJ_NULL) { + // // not connected + // mp_raise_OSError(MP_ENOTCONN); + // } + // vstr_t vstr; + // vstr_init_len(&vstr, mp_obj_get_int(len_in)); + // byte ip[4]; + // mp_uint_t port; + // int _errno; + // mp_int_t ret = self->nic_type->recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno); + // if (ret == -1) { + // mp_raise_OSError(_errno); + // } + mp_obj_t tuple[2]; + // if (ret == 0) { + // tuple[0] = mp_const_empty_bytes; + // } else { + // vstr.len = ret; + // tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + // } + // tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_recvfrom_into_obj, socketpool_socket_recvfrom_into); + +//| def setsockopt(self, level: int, optname: int, value: int) -> None: +//| """Sets socket options""" +//| ... +//| + +STATIC mp_obj_t socketpool_socket_setsockopt(size_t n_args, const mp_obj_t *args) { + // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); + + // mp_int_t level = mp_obj_get_int(args[1]); + // mp_int_t opt = mp_obj_get_int(args[2]); + + // const void *optval; + // mp_uint_t optlen; + // mp_int_t val; + // if (mp_obj_is_integer(args[3])) { + // val = mp_obj_get_int_truncated(args[3]); + // optval = &val; + // optlen = sizeof(val); + // } else { + // mp_buffer_info_t bufinfo; + // mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); + // optval = bufinfo.buf; + // optlen = bufinfo.len; + // } + + // int _errno; + // if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) { + // mp_raise_OSError(_errno); + // } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, 4, socketpool_socket_setsockopt); + +//| def settimeout(self, value: int) -> None: +//| """Set the timeout value for this socket. +//| +//| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely.""" +//| ... +//| + +STATIC mp_obj_t socketpool_socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { + // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + // if (self->nic == MP_OBJ_NULL) { + // // not connected + // mp_raise_OSError(MP_ENOTCONN); + // } + // mp_uint_t timeout; + // if (timeout_in == mp_const_none) { + // timeout = -1; + // } else { + // #if MICROPY_PY_BUILTINS_FLOAT + // timeout = 1000 * mp_obj_get_float(timeout_in); + // #else + // timeout = 1000 * mp_obj_get_int(timeout_in); + // #endif + // } + // int _errno; + // if (self->nic_type->settimeout(self, timeout, &_errno) != 0) { + // mp_raise_OSError(_errno); + // } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_settimeout_obj, socketpool_socket_settimeout); + +//| def setblocking(self, flag: bool) -> Optional[int]: +//| """Set the blocking behaviour of this socket. +//| +//| :param ~bool flag: False means non-blocking, True means block indefinitely.""" +//| ... +//| + +// method socket.setblocking(flag) +STATIC mp_obj_t socketpool_socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { + // if (mp_obj_is_true(blocking)) { + // return socket_settimeout(self_in, mp_const_none); + // } else { + // return socket_settimeout(self_in, MP_OBJ_NEW_SMALL_INT(0)); + // } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_setblocking_obj, socketpool_socket_setblocking); + +STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&socketpool_socket___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&socketpool_socket_close_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socketpool_socket_close_obj) }, + + { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socketpool_socket_bind_obj) }, + { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socketpool_socket_listen_obj) }, + { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socketpool_socket_accept_obj) }, + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&socketpool_socket_connect_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socketpool_socket_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socketpool_socket_sendto_obj) }, + { MP_ROM_QSTR(MP_QSTR_recvfrom_into), MP_ROM_PTR(&socketpool_socket_recvfrom_into_obj) }, + { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socketpool_socket_recv_into_obj) }, + { MP_ROM_QSTR(MP_QSTR_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_setblocking), MP_ROM_PTR(&socketpool_socket_setblocking_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(socketpool_socket_locals_dict, socketpool_socket_locals_dict_table); + +const mp_obj_type_t socketpool_socket_type = { + { &mp_type_type }, + .name = MP_QSTR_Socket, + .locals_dict = (mp_obj_dict_t*)&socketpool_socket_locals_dict, +}; diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h new file mode 100644 index 0000000000..bbe6227efe --- /dev/null +++ b/shared-bindings/socketpool/Socket.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H + +#include "common-hal/socketpool/Socket.h" + +extern const mp_obj_type_t socketpool_socket_type; + +// mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value); +// void common_hal_ipaddress_ipv4address_construct(ipaddress_ipv4address_obj_t* self, uint8_t* buf, size_t len); +// mp_obj_t common_hal_ipaddress_ipv4address_get_packed(ipaddress_ipv4address_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H diff --git a/shared-bindings/socketpool/SocketPool.c b/shared-bindings/socketpool/SocketPool.c new file mode 100644 index 0000000000..ed5ff82750 --- /dev/null +++ b/shared-bindings/socketpool/SocketPool.c @@ -0,0 +1,164 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * 2018 Nick Moore for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "py/objtuple.h" +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/mperrno.h" + +#include "shared-bindings/socketpool/Socket.h" +#include "shared-bindings/socketpool/SocketPool.h" + +//| class SocketPool: +//| + +STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 4, false); + + socketpool_socketpool_obj_t *s = m_new_obj_with_finaliser(socketpool_socketpool_obj_t); + s->base.type = &socketpool_socketpool_type; + + return MP_OBJ_FROM_PTR(s); +} + + +//| def socket(self, family: int, type: int, proto: int) -> None: +//| """Create a new socket +//| +//| :param ~int family: AF_INET or AF_INET6 +//| :param ~int type: SOCK_STREAM, SOCK_DGRAM or SOCK_RAW +//| :param ~int proto: IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW (ignored)""" +//| ... +//| +STATIC mp_obj_t socketpool_socketpool_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 4, false); + + // create socket object (not bound to any NIC yet) + socketpool_socket_obj_t *s = m_new_obj_with_finaliser(socketpool_socket_obj_t); + s->base.type = &socketpool_socket_type; + // s->nic = MP_OBJ_NULL; + // s->nic_type = NULL; + // s->u_param.domain = MOD_NETWORK_AF_INET; + // s->u_param.type = MOD_NETWORK_SOCK_STREAM; + // s->u_param.fileno = -1; + // if (n_args >= 1) { + // s->u_param.domain = mp_obj_get_int(args[0]); + // if (n_args >= 2) { + // s->u_param.type = mp_obj_get_int(args[1]); + // if (n_args >= 4) { + // s->u_param.fileno = mp_obj_get_int(args[3]); + // } + // } + // } + + return MP_OBJ_FROM_PTR(s); +} +MP_DEFINE_CONST_FUN_OBJ_KW(socketpool_socketpool_socket_obj, 1, socketpool_socketpool_socket); + +//| def getaddrinfo(host: str, port: int) -> tuple: +//| """Gets the address information for a hostname and port +//| +//| Returns the appropriate family, socket type, socket protocol and +//| address information to call socket.socket() and socket.connect() with, +//| as a tuple.""" +//| ... +//| + +STATIC mp_obj_t socketpool_socketpool_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { + // size_t hlen; + // const char *host = mp_obj_str_get_data(host_in, &hlen); + // mp_int_t port = mp_obj_get_int(port_in); + // uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE]; + // bool have_ip = false; + + // if (hlen > 0) { + // // check if host is already in IP form + // nlr_buf_t nlr; + // if (nlr_push(&nlr) == 0) { + // netutils_parse_ipv4_addr(host_in, out_ip, NETUTILS_BIG); + // have_ip = true; + // nlr_pop(); + // } else { + // // swallow exception: host was not in IP form so need to do DNS lookup + // } + // } + + // if (!have_ip) { + // // find a NIC that can do a name lookup + // for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + // mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; + // mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); + // if (nic_type->gethostbyname != NULL) { + // int ret = nic_type->gethostbyname(nic, host, hlen, out_ip); + // if (ret != 0) { + // mp_raise_OSError(ret); + // } + // have_ip = true; + // break; + // } + // } + // } + + // if (!have_ip) { + // nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC"))); + // } + + // mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL)); + // tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET); + // tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM); + // tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); + // tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_); + // tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG); + // return mp_obj_new_list(1, (mp_obj_t*)&tuple); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socketpool_getaddrinfo_obj, socketpool_socketpool_getaddrinfo); + +STATIC const mp_rom_map_elem_t socketpool_socketpool_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&socketpool_socketpool_socket_obj) }, + { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&socketpool_socketpool_getaddrinfo_obj) }, + + // class constants + { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(SOCKETPOOL_AF_INET) }, + { MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(SOCKETPOOL_AF_INET6) }, + + { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(SOCKETPOOL_SOCK_STREAM) }, + { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(SOCKETPOOL_SOCK_DGRAM) }, + { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(SOCKETPOOL_SOCK_RAW) }, +}; + +STATIC MP_DEFINE_CONST_DICT(socketpool_socketpool_locals_dict, socketpool_socketpool_locals_dict_table); + +const mp_obj_type_t socketpool_socketpool_type = { + { &mp_type_type }, + .name = MP_QSTR_SocketPool, + .make_new = socketpool_socketpool_make_new, + .locals_dict = (mp_obj_dict_t*)&socketpool_socketpool_locals_dict, +}; diff --git a/shared-bindings/socketpool/SocketPool.h b/shared-bindings/socketpool/SocketPool.h new file mode 100644 index 0000000000..1852cc1680 --- /dev/null +++ b/shared-bindings/socketpool/SocketPool.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKETPOOL_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKETPOOL_H + +#include "common-hal/socketpool/SocketPool.h" + +extern const mp_obj_type_t socketpool_socketpool_type; + +// mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value); +// void common_hal_ipaddress_ipv4address_construct(ipaddress_ipv4address_obj_t* self, uint8_t* buf, size_t len); +// mp_obj_t common_hal_ipaddress_ipv4address_get_packed(ipaddress_ipv4address_obj_t* self); +typedef enum { + SOCKETPOOL_SOCK_STREAM, + SOCKETPOOL_SOCK_DGRAM, + SOCKETPOOL_SOCK_RAW +} socketpool_socketpool_sock_t; + +typedef enum { + SOCKETPOOL_AF_INET, + SOCKETPOOL_AF_INET6 +} socketpool_socketpool_af_t; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKETPOOL_H diff --git a/shared-bindings/socketpool/__init__.c b/shared-bindings/socketpool/__init__.c index 53ac57d11a..06d5be5cda 100644 --- a/shared-bindings/socketpool/__init__.c +++ b/shared-bindings/socketpool/__init__.c @@ -3,8 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George - * 2018 Nick Moore for Adafruit Industries + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,579 +24,30 @@ * THE SOFTWARE. */ -#include -#include - -#include "py/objtuple.h" -#include "py/objlist.h" +#include "py/objexcept.h" +#include "py/objstr.h" +#include "py/parsenum.h" #include "py/runtime.h" -#include "py/stream.h" -#include "py/mperrno.h" -#include "lib/netutils/netutils.h" +#include "shared-bindings/socketpool/__init__.h" +#include "shared-bindings/socketpool/Socket.h" +#include "shared-bindings/socketpool/SocketPool.h" -#include "shared-module/network/__init__.h" - -//| """TCP, UDP and RAW socket support -//| -//| .. warning:: This module is disabled in 6.x and will removed in 7.x. Please use networking -//| libraries instead. (Native networking will provide a socket compatible class.) -//| -//| Create TCP, UDP and RAW sockets for communicating over the Internet.""" +//| """ +//| The `ipaddress` module provides types for IP addresses. It is a subset of CPython's ipaddress +//| module. +//| """ //| -STATIC const mp_obj_type_t socket_type; +STATIC const mp_rom_map_elem_t socketpool_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_socketpool) }, -//| class socket: -//| -//| def __init__(self, family: int, type: int, proto: int) -> None: -//| """Create a new socket -//| -//| :param ~int family: AF_INET or AF_INET6 -//| :param ~int type: SOCK_STREAM, SOCK_DGRAM or SOCK_RAW -//| :param ~int proto: IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW (ignored)""" -//| ... -//| - -STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - mp_arg_check_num(n_args, kw_args, 0, 4, false); - - // create socket object (not bound to any NIC yet) - mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t); - s->base.type = &socket_type; - s->nic = MP_OBJ_NULL; - s->nic_type = NULL; - s->u_param.domain = MOD_NETWORK_AF_INET; - s->u_param.type = MOD_NETWORK_SOCK_STREAM; - s->u_param.fileno = -1; - if (n_args >= 1) { - s->u_param.domain = mp_obj_get_int(args[0]); - if (n_args >= 2) { - s->u_param.type = mp_obj_get_int(args[1]); - if (n_args >= 4) { - s->u_param.fileno = mp_obj_get_int(args[3]); - } - } - } - - return MP_OBJ_FROM_PTR(s); -} - -STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) { - if (self->nic == MP_OBJ_NULL) { - // select NIC based on IP - self->nic = network_module_find_nic(ip); - self->nic_type = (mod_network_nic_type_t*)mp_obj_get_type(self->nic); - - // call the NIC to open the socket - int _errno; - if (self->nic_type->socket(self, &_errno) != 0) { - mp_raise_OSError(_errno); - } - } -} - -//| def bind(self, address: tuple) -> None: -//| """Bind a socket to an address -//| -//| :param ~tuple address: tuple of (remote_address, remote_port)""" -//| ... -//| - -STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { - mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - - // get address - uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; - mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); - - // check if we need to select a NIC - socket_select_nic(self, ip); - - // call the NIC to bind the socket - int _errno; - if (self->nic_type->bind(self, ip, port, &_errno) != 0) { - mp_raise_OSError(_errno); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind); - -//| def listen(self, backlog: int) -> None: -//| """Set socket to listen for incoming connections -//| -//| :param ~int backlog: length of backlog queue for waiting connetions""" -//| ... -//| - -STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) { - mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - - if (self->nic == MP_OBJ_NULL) { - // not connected - // TODO I think we can listen even if not bound... - mp_raise_OSError(MP_ENOTCONN); - } - - int _errno; - if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) { - mp_raise_OSError(_errno); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen); - -//| def accept(self) -> tuple: -//| """Accept a connection on a listening socket of type SOCK_STREAM, -//| creating a new socket of type SOCK_STREAM. -//| Returns a tuple of (new_socket, remote_address)""" -//| - -STATIC mp_obj_t socket_accept(mp_obj_t self_in) { - mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - - // create new socket object - // starts with empty NIC so that finaliser doesn't run close() method if accept() fails - mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t); - socket2->base.type = &socket_type; - socket2->nic = MP_OBJ_NULL; - socket2->nic_type = NULL; - - // accept incoming connection - uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; - mp_uint_t port; - int _errno; - if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) { - mp_raise_OSError(_errno); - } - - // new socket has valid state, so set the NIC to the same as parent - socket2->nic = self->nic; - socket2->nic_type = self->nic_type; - - // make the return value - mp_obj_tuple_t *client = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); - client->items[0] = MP_OBJ_FROM_PTR(socket2); - client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); - - return MP_OBJ_FROM_PTR(client); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept); - -//| def connect(self, address: tuple) -> None: -//| """Connect a socket to a remote address -//| -//| :param ~tuple address: tuple of (remote_address, remote_port)""" -//| ... -//| - -STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { - mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - - // get address - uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; - mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); - - // check if we need to select a NIC - socket_select_nic(self, ip); - - // call the NIC to connect the socket - int _errno; - if (self->nic_type->connect(self, ip, port, &_errno) != 0) { - mp_raise_OSError(_errno); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect); - -//| def send(self, bytes: ReadableBuffer) -> int: -//| """Send some bytes to the connected remote address. -//| Suits sockets of type SOCK_STREAM -//| -//| :param ~bytes bytes: some bytes to send""" -//| ... -//| - -STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) { - mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->nic == MP_OBJ_NULL) { - // not connected - mp_raise_OSError(MP_EPIPE); - } - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); - int _errno; - mp_int_t ret = self->nic_type->send(self, bufinfo.buf, bufinfo.len, &_errno); - if (ret == -1) { - mp_raise_OSError(_errno); - } - return mp_obj_new_int_from_uint(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send); - - -// helper function for socket_recv and socket_recv_into to handle common operations of both -STATIC mp_int_t _socket_recv_into(mod_network_socket_obj_t *sock, byte *buf, mp_int_t len) { - int _errno; - mp_int_t ret = sock->nic_type->recv(sock, buf, len, &_errno); - if (ret == -1) { - mp_raise_OSError(_errno); - } - return ret; -} - - -//| def recv_into(self, buffer: WriteableBuffer, bufsize: int) -> int: -//| """Reads some bytes from the connected remote address, writing -//| into the provided buffer. If bufsize <= len(buffer) is given, -//| a maximum of bufsize bytes will be read into the buffer. If no -//| valid value is given for bufsize, the default is the length of -//| the given buffer. -//| -//| Suits sockets of type SOCK_STREAM -//| Returns an int of number of bytes read. -//| -//| :param bytearray buffer: buffer to receive into -//| :param int bufsize: optionally, a maximum number of bytes to read.""" -//| ... -//| - -STATIC mp_obj_t socket_recv_into(size_t n_args, const mp_obj_t *args) { - mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); - if (self->nic == MP_OBJ_NULL) { - // not connected - mp_raise_OSError(MP_ENOTCONN); - } - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); - mp_int_t len = bufinfo.len; - if (n_args == 3) { - mp_int_t given_len = mp_obj_get_int(args[2]); - if (given_len < len) { - len = given_len; - } - } - - mp_int_t ret = _socket_recv_into(self, (byte*)bufinfo.buf, len); - return mp_obj_new_int_from_uint(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_recv_into_obj, 2, 3, socket_recv_into); - -//| def recv(self, bufsize: int) -> bytes: -//| """Reads some bytes from the connected remote address. -//| Suits sockets of type SOCK_STREAM -//| Returns a bytes() of length <= bufsize -//| -//| :param ~int bufsize: maximum number of bytes to receive""" -//| ... -//| - -STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) { - mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->nic == MP_OBJ_NULL) { - // not connected - mp_raise_OSError(MP_ENOTCONN); - } - mp_int_t len = mp_obj_get_int(len_in); - vstr_t vstr; - vstr_init_len(&vstr, len); - mp_int_t ret = _socket_recv_into(self, (byte*)vstr.buf, len); - if (ret == 0) { - return mp_const_empty_bytes; - } - vstr.len = ret; - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv); - -//| def sendto(self, bytes: ReadableBuffer, address: tuple) -> int: -//| """Send some bytes to a specific address. -//| Suits sockets of type SOCK_DGRAM -//| -//| :param ~bytes bytes: some bytes to send -//| :param ~tuple address: tuple of (remote_address, remote_port)""" -//| ... -//| - -STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { - mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - - // get the data - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); - - // get address - uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; - mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); - - // check if we need to select a NIC - socket_select_nic(self, ip); - - // call the NIC to sendto - int _errno; - mp_int_t ret = self->nic_type->sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno); - if (ret == -1) { - mp_raise_OSError(_errno); - } - - return mp_obj_new_int(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto); - -//| def recvfrom(self, bufsize: int) -> Tuple[bytes, tuple]: -//| """Reads some bytes from the connected remote address. -//| Suits sockets of type SOCK_STREAM -//| -//| Returns a tuple containing -//| * a bytes() of length <= bufsize -//| * a remote_address, which is a tuple of ip address and port number -//| -//| :param ~int bufsize: maximum number of bytes to receive""" -//| ... -//| - -STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { - mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->nic == MP_OBJ_NULL) { - // not connected - mp_raise_OSError(MP_ENOTCONN); - } - vstr_t vstr; - vstr_init_len(&vstr, mp_obj_get_int(len_in)); - byte ip[4]; - mp_uint_t port; - int _errno; - mp_int_t ret = self->nic_type->recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno); - if (ret == -1) { - mp_raise_OSError(_errno); - } - mp_obj_t tuple[2]; - if (ret == 0) { - tuple[0] = mp_const_empty_bytes; - } else { - vstr.len = ret; - tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); - } - tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); - return mp_obj_new_tuple(2, tuple); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recvfrom_obj, socket_recvfrom); - -//| def setsockopt(self, level: int, optname: int, value: int) -> None: -//| """Sets socket options""" -//| ... -//| - -STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) { - 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]); - - const void *optval; - mp_uint_t optlen; - mp_int_t val; - if (mp_obj_is_integer(args[3])) { - val = mp_obj_get_int_truncated(args[3]); - optval = &val; - optlen = sizeof(val); - } else { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); - optval = bufinfo.buf; - optlen = bufinfo.len; - } - - int _errno; - if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) { - mp_raise_OSError(_errno); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_setsockopt); - -//| def settimeout(self, value: int) -> None: -//| """Set the timeout value for this socket. -//| -//| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely.""" -//| ... -//| - -STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { - mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->nic == MP_OBJ_NULL) { - // not connected - mp_raise_OSError(MP_ENOTCONN); - } - mp_uint_t timeout; - if (timeout_in == mp_const_none) { - timeout = -1; - } else { - #if MICROPY_PY_BUILTINS_FLOAT - timeout = 1000 * mp_obj_get_float(timeout_in); - #else - timeout = 1000 * mp_obj_get_int(timeout_in); - #endif - } - int _errno; - if (self->nic_type->settimeout(self, timeout, &_errno) != 0) { - mp_raise_OSError(_errno); - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_settimeout_obj, socket_settimeout); - -//| def setblocking(self, flag: bool) -> Optional[int]: -//| """Set the blocking behaviour of this socket. -//| -//| :param ~bool flag: False means non-blocking, True means block indefinitely.""" -//| ... -//| - -// method socket.setblocking(flag) -STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { - if (mp_obj_is_true(blocking)) { - return socket_settimeout(self_in, mp_const_none); - } else { - return socket_settimeout(self_in, MP_OBJ_NEW_SMALL_INT(0)); - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking); - -STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, - { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, - { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socket_bind_obj) }, - { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socket_listen_obj) }, - { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socket_accept_obj) }, - { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&socket_connect_obj) }, - { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socket_send_obj) }, - { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&socket_recv_obj) }, - { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socket_sendto_obj) }, - { MP_ROM_QSTR(MP_QSTR_recvfrom), MP_ROM_PTR(&socket_recvfrom_obj) }, - { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socket_recv_into_obj) }, - { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socket_setsockopt_obj) }, - { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socket_settimeout_obj) }, - { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, + { MP_ROM_QSTR(MP_QSTR_SocketPool), MP_ROM_PTR(&socketpool_socketpool_type) }, + { MP_ROM_QSTR(MP_QSTR_Socket), MP_ROM_PTR(&socketpool_socket_type) }, }; -STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table); +STATIC MP_DEFINE_CONST_DICT(socketpool_globals, socketpool_globals_table); -mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { - mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (request == MP_STREAM_CLOSE) { - if (self->nic != MP_OBJ_NULL) { - self->nic_type->close(self); - self->nic = MP_OBJ_NULL; - } - return 0; - } - return self->nic_type->ioctl(self, request, arg, errcode); -} - -STATIC const mp_stream_p_t socket_stream_p = { - MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream) - .ioctl = socket_ioctl, - .is_text = false, -}; - -STATIC const mp_obj_type_t socket_type = { - { &mp_type_type }, - .name = MP_QSTR_socket, - .make_new = socket_make_new, - .protocol = &socket_stream_p, - .locals_dict = (mp_obj_dict_t*)&socket_locals_dict, -}; - -//| def getaddrinfo(host: str, port: int) -> tuple: -//| """Gets the address information for a hostname and port -//| -//| Returns the appropriate family, socket type, socket protocol and -//| address information to call socket.socket() and socket.connect() with, -//| as a tuple.""" -//| ... -//| - -STATIC mp_obj_t socket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { - size_t hlen; - const char *host = mp_obj_str_get_data(host_in, &hlen); - mp_int_t port = mp_obj_get_int(port_in); - uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE]; - bool have_ip = false; - - if (hlen > 0) { - // check if host is already in IP form - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - netutils_parse_ipv4_addr(host_in, out_ip, NETUTILS_BIG); - have_ip = true; - nlr_pop(); - } else { - // swallow exception: host was not in IP form so need to do DNS lookup - } - } - - if (!have_ip) { - // find a NIC that can do a name lookup - for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { - mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; - mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); - if (nic_type->gethostbyname != NULL) { - int ret = nic_type->gethostbyname(nic, host, hlen, out_ip); - if (ret != 0) { - mp_raise_OSError(ret); - } - have_ip = true; - break; - } - } - } - - if (!have_ip) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC"))); - } - - mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL)); - tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET); - tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM); - tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); - tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_); - tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG); - return mp_obj_new_list(1, (mp_obj_t*)&tuple); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_getaddrinfo_obj, socket_getaddrinfo); - -STATIC const mp_rom_map_elem_t socket_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usocket) }, - - { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&socket_type) }, - { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&socket_getaddrinfo_obj) }, - - // class constants - { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(MOD_NETWORK_AF_INET) }, - { MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(MOD_NETWORK_AF_INET6) }, - - { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(MOD_NETWORK_SOCK_STREAM) }, - { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(MOD_NETWORK_SOCK_DGRAM) }, - { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(MOD_NETWORK_SOCK_RAW) }, - - /* - { MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(MOD_NETWORK_IPPROTO_IP) }, - { MP_ROM_QSTR(MP_QSTR_IPPROTO_ICMP), MP_ROM_INT(MOD_NETWORK_IPPROTO_ICMP) }, - { MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV4), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV4) }, - { MP_ROM_QSTR(MP_QSTR_IPPROTO_TCP), MP_ROM_INT(MOD_NETWORK_IPPROTO_TCP) }, - { MP_ROM_QSTR(MP_QSTR_IPPROTO_UDP), MP_ROM_INT(MOD_NETWORK_IPPROTO_UDP) }, - { MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV6), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV6) }, - { MP_ROM_QSTR(MP_QSTR_IPPROTO_RAW), MP_ROM_INT(MOD_NETWORK_IPPROTO_RAW) }, - */ -}; - -STATIC MP_DEFINE_CONST_DICT(socket_globals, socket_globals_table); - -const mp_obj_module_t socket_module = { +const mp_obj_module_t socketpool_module = { .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&socket_globals, + .globals = (mp_obj_dict_t*)&socketpool_globals, }; diff --git a/shared-bindings/socketpool/__init__.h b/shared-bindings/socketpool/__init__.h new file mode 100644 index 0000000000..76d8bfa766 --- /dev/null +++ b/shared-bindings/socketpool/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H + +#include "shared-module/ipaddress/__init__.h" + +mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H From eb2c38825edfe28007c2bc6c37bdb0a3269f27e7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 12 Aug 2020 16:57:39 -0700 Subject: [PATCH 12/78] HTTP works with my adafruit_requests --- ports/esp32s2/CMakeLists.txt | 5 +- ports/esp32s2/Makefile | 5 +- ports/esp32s2/common-hal/socketpool/Socket.c | 54 ++ ports/esp32s2/common-hal/socketpool/Socket.h | 9 + .../common-hal/socketpool/SocketPool.c | 74 +++ .../common-hal/socketpool/SocketPool.h | 2 + ports/esp32s2/common-hal/ssl/SSLContext.c | 39 ++ ports/esp32s2/common-hal/ssl/SSLContext.h | 37 ++ ports/esp32s2/common-hal/ssl/__init__.c | 31 ++ ports/esp32s2/common-hal/ssl/__init__.h | 31 ++ ports/esp32s2/common-hal/wifi/__init__.c | 4 +- ports/esp32s2/esp-idf | 2 +- ports/esp32s2/mpconfigport.mk | 17 +- ports/esp32s2/partitions.csv | 9 +- ports/esp32s2/sdkconfig.defaults | 56 ++- shared-bindings/ipaddress/__init__.c | 60 ++- shared-bindings/ipaddress/__init__.h | 2 + shared-bindings/socketpool/Socket.c | 465 +++++++++--------- shared-bindings/socketpool/Socket.h | 7 +- shared-bindings/socketpool/SocketPool.c | 118 ++--- shared-bindings/socketpool/SocketPool.h | 13 +- 21 files changed, 680 insertions(+), 360 deletions(-) create mode 100644 ports/esp32s2/common-hal/ssl/SSLContext.c create mode 100644 ports/esp32s2/common-hal/ssl/SSLContext.h create mode 100644 ports/esp32s2/common-hal/ssl/__init__.c create mode 100644 ports/esp32s2/common-hal/ssl/__init__.h diff --git a/ports/esp32s2/CMakeLists.txt b/ports/esp32s2/CMakeLists.txt index 716588cf22..0d7f48995e 100644 --- a/ports/esp32s2/CMakeLists.txt +++ b/ports/esp32s2/CMakeLists.txt @@ -3,7 +3,10 @@ cmake_minimum_required(VERSION 3.13) set(ENV{IDF_PATH} ${CMAKE_SOURCE_DIR}/esp-idf) -set(COMPONENTS esptool_py soc driver log main) + +# The component list here determines what options we get in menuconfig and what the ninja file +# can build. +set(COMPONENTS esptool_py soc driver log main esp-tls mbedtls esp_event esp_netif esp_wifi lwip wpa_supplicant freertos) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(circuitpython) diff --git a/ports/esp32s2/Makefile b/ports/esp32s2/Makefile index ab470d095c..142387f63e 100644 --- a/ports/esp32s2/Makefile +++ b/ports/esp32s2/Makefile @@ -85,6 +85,8 @@ INC += -Iesp-idf/components/esp_rom/include INC += -Iesp-idf/components/esp_wifi/include INC += -Iesp-idf/components/xtensa/include INC += -Iesp-idf/components/esp_timer/include +INC += -Iesp-idf/components/mbedtls/mbedtls/include +INC += -Iesp-idf/components/mbedtls/port/include/ INC += -Iesp-idf/components/newlib/platform_include INC += -Iesp-idf/components/lwip/lwip/src/include INC += -Iesp-idf/components/lwip/port/esp32/include @@ -253,7 +255,7 @@ menuconfig: $(BUILD)/esp-idf/config $(HEADER_BUILD)/qstr.i.last: | $(BUILD)/esp-idf/config/sdkconfig.h # Order here matters -ESP_IDF_COMPONENTS_LINK = freertos log esp_system esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash esp_netif lwip esp_rom +ESP_IDF_COMPONENTS_LINK = freertos log esp_system esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash esp_netif lwip esp_rom esp-tls ESP_IDF_COMPONENTS_INCLUDE = driver freertos log soc @@ -281,6 +283,7 @@ esp-idf-stamp: $(BUILD)/esp-idf/config/sdkconfig.h $(Q)ninja -C $(BUILD)/esp-idf \ bootloader/bootloader.bin \ esp-idf/bootloader_support/libbootloader_support.a \ + esp-idf/esp-tls/libesp-tls.a \ esp-idf/esp32s2/ld/esp32s2.project.ld \ esp-idf/esp_event/libesp_event.a \ esp-idf/esp_netif/libesp_netif.a \ diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c index fa0e7d5f3f..0ed8b09147 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.c +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -23,3 +23,57 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + +#include "shared-bindings/socketpool/Socket.h" + +#include "esp_log.h" +static const char *TAG = "socket"; + +void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms) { + self->timeout_ms = timeout_ms; +} + +bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const char* host, mp_uint_t hostlen, mp_int_t port) { + // For simplicity we use esp_tls for all TCP connections. If it's not SSL, ssl_context will be + // NULL and should still work. This makes regular TCP connections more memory expensive but TLS + // should become more and more common. Therefore, we optimize for the TLS case. + + ESP_LOGI(TAG, "connecting to %s:%d %p", host, port, self->ssl_context); + int result = esp_tls_conn_new_sync(host, hostlen, port, self->ssl_context, self->tcp); + ESP_LOGI(TAG, "result %d", result); + return result >= 0; +} + +mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { + size_t sent = esp_tls_conn_write(self->tcp, buf, len); + + ESP_LOGI(TAG, "sent %d bytes", sent); + if (sent < 0) { + // raise an error + } + return sent; +} + +mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { + size_t received = esp_tls_conn_read(self->tcp, (void*) buf, len); + + ESP_LOGI(TAG, "received %d bytes", received); + if (received == 0) { + // socket closed + } + if (received < 0) { + // raise an error + } + return received; +} + +void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) { + if (self->tcp != NULL) { + int status = esp_tls_conn_destroy(self->tcp); + + if (status < 0) { + // raise an error + } + self->tcp = NULL; + } +} diff --git a/ports/esp32s2/common-hal/socketpool/Socket.h b/ports/esp32s2/common-hal/socketpool/Socket.h index 4540b6d439..8a250a115a 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.h +++ b/ports/esp32s2/common-hal/socketpool/Socket.h @@ -29,8 +29,17 @@ #include "py/obj.h" +#include "common-hal/socketpool/SocketPool.h" + +#include "esp-idf/components/esp-tls/esp_tls.h" + typedef struct { mp_obj_base_t base; + int num; + esp_tls_t* tcp; + esp_tls_cfg_t* ssl_context; + socketpool_socketpool_obj_t* pool; + mp_uint_t timeout_ms; } socketpool_socket_obj_t; #endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKET_H diff --git a/ports/esp32s2/common-hal/socketpool/SocketPool.c b/ports/esp32s2/common-hal/socketpool/SocketPool.c index fa0e7d5f3f..0b9c1776bf 100644 --- a/ports/esp32s2/common-hal/socketpool/SocketPool.c +++ b/ports/esp32s2/common-hal/socketpool/SocketPool.c @@ -23,3 +23,77 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + +#include "shared-bindings/socketpool/SocketPool.h" + +#include "py/runtime.h" + +#include "esp-idf/components/lwip/lwip/src/include/lwip/netdb.h" + +socketpool_socket_obj_t* common_hal_socketpool_socket(socketpool_socketpool_obj_t* self, + socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type) { + + int addr_family; + int ipproto; + if (family == SOCKETPOOL_AF_INET) { + addr_family = AF_INET; + ipproto = IPPROTO_IP; + } else { // INET6 + addr_family = AF_INET6; + ipproto = IPPROTO_IPV6; + } + + int socket_type; + if (type == SOCKETPOOL_SOCK_STREAM) { + socket_type = SOCK_STREAM; + } else if (type == SOCKETPOOL_SOCK_DGRAM) { + socket_type = SOCK_DGRAM; + } else { // SOCKETPOOL_SOCK_RAW + socket_type = SOCK_RAW; + } + + int socknum = -1; + esp_tls_t* tcp_handle = NULL; + if (socket_type == SOCK_DGRAM || socket_type == SOCK_RAW) { + socknum = lwip_socket(addr_family, socket_type, ipproto); + } else { + tcp_handle = esp_tls_init(); + } + if (socknum < 0 && tcp_handle == NULL) { + mp_raise_RuntimeError(translate("Out of sockets")); + } + + socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t); + sock->base.type = &socketpool_socket_type; + sock->num = socknum; + sock->tcp = tcp_handle; + sock->ssl_context = NULL; + sock->pool = self; + return sock; +} + + +mp_obj_t common_hal_socketpool_socketpool_gethostbyname(socketpool_socketpool_obj_t* self, + const char* host) { + + const struct addrinfo hints = { + .ai_family = AF_INET, + .ai_socktype = SOCK_STREAM, + }; + struct addrinfo *res; + int err = getaddrinfo(host, NULL, &hints, &res); + if (err != 0 || res == NULL) { + return mp_const_none; + } + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + struct in_addr *addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; + #pragma GCC diagnostic pop + char ip_str[IP4ADDR_STRLEN_MAX]; + inet_ntoa_r(*addr, ip_str, IP4ADDR_STRLEN_MAX); + mp_obj_t ip_obj = mp_obj_new_str(ip_str, strlen(ip_str)); + freeaddrinfo(res); + + return ip_obj; +} diff --git a/ports/esp32s2/common-hal/socketpool/SocketPool.h b/ports/esp32s2/common-hal/socketpool/SocketPool.h index dc46d8958a..ae9988d593 100644 --- a/ports/esp32s2/common-hal/socketpool/SocketPool.h +++ b/ports/esp32s2/common-hal/socketpool/SocketPool.h @@ -27,6 +27,8 @@ #ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKETPOOL_H #define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKETPOOL_H +#include "py/obj.h" + typedef struct { mp_obj_base_t base; } socketpool_socketpool_obj_t; diff --git a/ports/esp32s2/common-hal/ssl/SSLContext.c b/ports/esp32s2/common-hal/ssl/SSLContext.c new file mode 100644 index 0000000000..98fedb3a84 --- /dev/null +++ b/ports/esp32s2/common-hal/ssl/SSLContext.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/socketpool/SocketPool.h" + +#include "py/runtime.h" + +#include "esp-idf/components/lwip/lwip/src/include/lwip/netdb.h" + +socketpool_socket_obj_t* common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t* self, + socketpool_socket_obj_t* socket, bool server_side, const char* server_hostname) { + + + // Should we store server hostname on the socket in case connect is called with an ip? + return socket; +} diff --git a/ports/esp32s2/common-hal/ssl/SSLContext.h b/ports/esp32s2/common-hal/ssl/SSLContext.h new file mode 100644 index 0000000000..e44b1f7fe7 --- /dev/null +++ b/ports/esp32s2/common-hal/ssl/SSLContext.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL_SSLCONTEXT_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL_SSLCONTEXT_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + esp_tls_cfg_t ssl_config; +} ssl_sslcontext_obj_t; + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL_SSL_CONTEXT_H diff --git a/ports/esp32s2/common-hal/ssl/__init__.c b/ports/esp32s2/common-hal/ssl/__init__.c new file mode 100644 index 0000000000..8f9565b46e --- /dev/null +++ b/ports/esp32s2/common-hal/ssl/__init__.c @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H + + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H diff --git a/ports/esp32s2/common-hal/ssl/__init__.h b/ports/esp32s2/common-hal/ssl/__init__.h new file mode 100644 index 0000000000..8f9565b46e --- /dev/null +++ b/ports/esp32s2/common-hal/ssl/__init__.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H + + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H diff --git a/ports/esp32s2/common-hal/wifi/__init__.c b/ports/esp32s2/common-hal/wifi/__init__.c index eb033256d2..b9147496b9 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.c +++ b/ports/esp32s2/common-hal/wifi/__init__.c @@ -113,12 +113,12 @@ void common_hal_wifi_init(void) { ESP_EVENT_ANY_ID, &event_handler, self, - self->handler_instance_all_wifi)); + &self->handler_instance_all_wifi)); ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, self, - self->handler_instance_got_ip)); + &self->handler_instance_got_ip)); ESP_EARLY_LOGI(TAG, "wifi init"); diff --git a/ports/esp32s2/esp-idf b/ports/esp32s2/esp-idf index 01c86ed7d6..83595f7659 160000 --- a/ports/esp32s2/esp-idf +++ b/ports/esp32s2/esp-idf @@ -1 +1 @@ -Subproject commit 01c86ed7d6f4bbbaeda0c461c5f20e3d9872b44b +Subproject commit 83595f76591aebf0cca9a578258276e67f628b06 diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index dcfb0ecc5c..62d2da6079 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -13,22 +13,17 @@ USB_SERIAL_NUMBER_LENGTH = 12 LONGINT_IMPL = MPZ # These modules are implemented in ports//common-hal: +CIRCUITPY_FULL_BUILD = 1 CIRCUITPY_ANALOGIO = 0 -CIRCUITPY_NVM = 0 CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_AUDIOIO = 0 -CIRCUITPY_ROTARYIO = 0 -CIRCUITPY_RTC = 0 +CIRCUITPY_COUNTIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 -CIRCUITPY_COUNTIO = 0 - -# These modules are implemented in shared-module/ - they can be included in -# any port once their prerequisites in common-hal are complete. -CIRCUITPY_RANDOM = 0 # Requires OS -CIRCUITPY_USB_MIDI = 0 # Requires USB -CIRCUITPY_ULAB = 0 # No requirements, but takes extra flash - +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_NVM = 0 +CIRCUITPY_USB_MIDI = 0 # We don't have enough endpoints to include MIDI. CIRCUITPY_WIFI = 1 CIRCUITPY_MODULE ?= none diff --git a/ports/esp32s2/partitions.csv b/ports/esp32s2/partitions.csv index dd12c609dc..6317ff52ad 100644 --- a/ports/esp32s2/partitions.csv +++ b/ports/esp32s2/partitions.csv @@ -3,8 +3,7 @@ # bootloader.bin 0x1000 # partition table 0x8000, 0xC00 otadata, data, ota, 0xd000, 0x2000, -ota_0, 0, ota_0, 0x10000, 0x100000, -ota_1, 0, ota_1, 0x110000, 0x100000, -phy_init, data, phy, 0x210000, 0x1000, -nvs, data, nvs, 0x211000, 0x6000, -user_fs, data, fat, 0x217000, 0x1e9000, +ota_0, 0, ota_0, 0x10000, 0x120000, +ota_1, 0, ota_1, 0x130000, 0x120000, +phy_init, data, phy, 0x250000, 0x1000, +user_fs, data, fat, 0x251000, 0x1af000, diff --git a/ports/esp32s2/sdkconfig.defaults b/ports/esp32s2/sdkconfig.defaults index f7693ce18f..2faaa028c1 100644 --- a/ports/esp32s2/sdkconfig.defaults +++ b/ports/esp32s2/sdkconfig.defaults @@ -37,6 +37,7 @@ CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 # # Bootloader config # +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set @@ -64,15 +65,19 @@ CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 # # Security features # +CONFIG_SECURE_TARGET_HAS_SECURE_ROM_DL_MODE=y # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set # CONFIG_SECURE_BOOT is not set # CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# CONFIG_SECURE_DISABLE_ROM_DL_MODE is not set +# CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE is not set # end of Security features # # Serial flasher config # CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_WITH_STUB=y # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set CONFIG_ESPTOOLPY_FLASHMODE_DIO=y @@ -96,6 +101,7 @@ CONFIG_ESPTOOLPY_BEFORE="default_reset" CONFIG_ESPTOOLPY_AFTER_RESET=y # CONFIG_ESPTOOLPY_AFTER_NORESET is not set CONFIG_ESPTOOLPY_AFTER="hard_reset" +# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set # CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set # CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y @@ -186,6 +192,14 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y CONFIG_EFUSE_MAX_BLK_LEN=256 # end of eFuse Bit Manager +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_ESP_TLS_SERVER=y +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# end of ESP-TLS + # # ESP32S2-specific # @@ -245,6 +259,10 @@ CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y # CONFIG_ESP32S2_RTC_CLK_SRC_INT_8MD256 is not set CONFIG_ESP32S2_RTC_CLK_CAL_CYCLES=576 # CONFIG_ESP32S2_NO_BLOBS is not set +# CONFIG_ESP32S2_KEEP_USB_ALIVE is not set +# CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM is not set +# CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE is not set +CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y # end of ESP32S2-specific # @@ -263,15 +281,16 @@ CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_USB_CDC is not set # CONFIG_ESP_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_UART_TX_GPIO=1 -CONFIG_ESP_CONSOLE_UART_RX_GPIO=3 CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 CONFIG_ESP_INT_WDT=y CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 # CONFIG_ESP_TASK_WDT is not set +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y # end of Common ESP-related @@ -307,6 +326,7 @@ CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y # CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT is not set # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set # CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y # end of ESP System Settings # @@ -436,12 +456,15 @@ CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y CONFIG_LWIP_TIMERS_ONDEMAND=y CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y # CONFIG_LWIP_SO_RCVBUF is not set # CONFIG_LWIP_NETBUF_RECVINFO is not set -CONFIG_LWIP_IP_FRAG=y -# CONFIG_LWIP_IP_REASSEMBLY is not set +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set # CONFIG_LWIP_IP_FORWARD is not set # CONFIG_LWIP_STATS is not set # CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set @@ -482,6 +505,7 @@ CONFIG_LWIP_TCP_QUEUE_OOSEQ=y CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set # CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=3000 # end of TCP # @@ -496,6 +520,7 @@ CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF # CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set # # ICMP @@ -518,6 +543,20 @@ CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 # end of SNTP CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Debug +# +# CONFIG_LWIP_NETIF_DEBUG is not set +# CONFIG_LWIP_PBUF_DEBUG is not set +# CONFIG_LWIP_ETHARP_DEBUG is not set +# CONFIG_LWIP_API_LIB_DEBUG is not set +# CONFIG_LWIP_SOCKETS_DEBUG is not set +# CONFIG_LWIP_IP_DEBUG is not set +# CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_IP6_DEBUG is not set +# CONFIG_LWIP_ICMP6_DEBUG is not set +# end of Debug # end of LWIP # @@ -681,6 +720,7 @@ CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 # # Auto-detect flash chips @@ -714,7 +754,6 @@ CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 CONFIG_WPA_MBEDTLS_CRYPTO=y # CONFIG_WPA_DEBUG_PRINT is not set # CONFIG_WPA_TESTING_OPTIONS is not set -CONFIG_WPA_TLS_V12=y # CONFIG_WPA_WPS_WARS is not set # end of Supplicant # end of Component config @@ -771,10 +810,9 @@ CONFIG_MAIN_TASK_STACK_SIZE=8192 CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_CONSOLE_UART_DEFAULT=y # CONFIG_CONSOLE_UART_CUSTOM is not set -# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y CONFIG_CONSOLE_UART_NUM=0 -CONFIG_CONSOLE_UART_TX_GPIO=1 -CONFIG_CONSOLE_UART_RX_GPIO=3 CONFIG_CONSOLE_UART_BAUDRATE=115200 CONFIG_INT_WDT=y CONFIG_INT_WDT_TIMEOUT_MS=300 diff --git a/shared-bindings/ipaddress/__init__.c b/shared-bindings/ipaddress/__init__.c index 1c0ac9153b..76b63202cc 100644 --- a/shared-bindings/ipaddress/__init__.c +++ b/shared-bindings/ipaddress/__init__.c @@ -37,6 +37,45 @@ //| """ //| + +bool ipaddress_parse_ipv4address(const char* str_data, size_t str_len, uint32_t* ip_out) { + size_t period_count = 0; + size_t period_index[4] = {0, 0, 0, str_len}; + for (size_t i = 0; i < str_len; i++) { + if (str_data[i] == '.') { + if (period_count < 3) { + period_index[period_count] = i; + } + period_count++; + } + } + if (period_count > 3) { + return false; + } + + size_t last_period = 0; + if (ip_out != NULL) { + *ip_out = 0; + } + for (size_t i = 0; i < 4; i++) { + // Catch exceptions thrown by mp_parse_num_integer + nlr_buf_t nlr; + mp_obj_t octet; + if (nlr_push(&nlr) == 0) { + octet = mp_parse_num_integer((const char*) str_data + last_period, period_index[i] - last_period, 10, NULL); + nlr_pop(); + } else { + return false; + } + last_period = period_index[i] + 1; + if (ip_out != NULL) { + mp_int_t int_octet = MP_OBJ_SMALL_INT_VALUE(octet); + *ip_out |= int_octet << (i * 8); + } + } + return true; +} + //| def ip_address(obj: Union[int]) -> IPv4Address: //| """Return a corresponding IP address object or raise ValueError if not possible.""" //| ... @@ -48,28 +87,9 @@ STATIC mp_obj_t ipaddress_ip_address(mp_obj_t ip_in) { // We're done. } else if (MP_OBJ_IS_STR(ip_in)) { GET_STR_DATA_LEN(ip_in, str_data, str_len); - size_t period_count = 0; - size_t period_index[4] = {0, 0, 0, str_len}; - for (size_t i = 0; i < str_len; i++) { - if (str_data[i] == '.') { - if (period_count < 3) { - period_index[period_count] = i; - } - period_count++; - } - } - if (period_count > 3) { + if (!ipaddress_parse_ipv4address((const char*) str_data, str_len, &value)) { mp_raise_ValueError(translate("Not a valid IP string.")); } - - size_t last_period = 0; - value = 0; - for (size_t i = 0; i < 4; i++) { - mp_obj_t octet = mp_parse_num_integer((const char*) str_data + last_period, period_index[i] - last_period, 10, NULL); - last_period = period_index[i] + 1; - mp_int_t int_octet = MP_OBJ_SMALL_INT_VALUE(octet); - value |= int_octet << (i * 8); - } } else { mp_raise_ValueError(translate("Only raw int supported for ip.")); } diff --git a/shared-bindings/ipaddress/__init__.h b/shared-bindings/ipaddress/__init__.h index 76d8bfa766..a1c31775f9 100644 --- a/shared-bindings/ipaddress/__init__.h +++ b/shared-bindings/ipaddress/__init__.h @@ -29,6 +29,8 @@ #include "shared-module/ipaddress/__init__.h" +bool ipaddress_parse_ipv4address(const char* ip_str, size_t len, uint32_t* ip_out); + mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index e4d79616a6..f6f90ceb1f 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -62,94 +62,94 @@ STATIC mp_obj_t socketpool_socket___exit__(size_t n_args, const mp_obj_t *args) } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket___exit___obj, 4, 4, socketpool_socket___exit__); -//| def bind(self, address: tuple) -> None: -//| """Bind a socket to an address -//| -//| :param ~tuple address: tuple of (remote_address, remote_port)""" -//| ... -//| +// //| def bind(self, address: tuple) -> None: +// //| """Bind a socket to an address +// //| +// //| :param ~tuple address: tuple of (remote_address, remote_port)""" +// //| ... +// //| -STATIC mp_obj_t socketpool_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { - // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); +// STATIC mp_obj_t socketpool_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { +// // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - // // get address - // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; - // mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); +// // // get address +// // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; +// // mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); - // // check if we need to select a NIC - // socket_select_nic(self, ip); +// // // check if we need to select a NIC +// // socket_select_nic(self, ip); - // // call the NIC to bind the socket - // int _errno; - // if (self->nic_type->bind(self, ip, port, &_errno) != 0) { - // mp_raise_OSError(_errno); - // } +// // // call the NIC to bind the socket +// // int _errno; +// // if (self->nic_type->bind(self, ip, port, &_errno) != 0) { +// // mp_raise_OSError(_errno); +// // } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_bind_obj, socketpool_socket_bind); +// return mp_const_none; +// } +// STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_bind_obj, socketpool_socket_bind); -//| def listen(self, backlog: int) -> None: -//| """Set socket to listen for incoming connections -//| -//| :param ~int backlog: length of backlog queue for waiting connetions""" -//| ... -//| +// //| def listen(self, backlog: int) -> None: +// //| """Set socket to listen for incoming connections +// //| +// //| :param ~int backlog: length of backlog queue for waiting connetions""" +// //| ... +// //| -STATIC mp_obj_t socketpool_socket_listen(mp_obj_t self_in, mp_obj_t backlog) { - // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); +// STATIC mp_obj_t socketpool_socket_listen(mp_obj_t self_in, mp_obj_t backlog) { +// // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - // if (self->nic == MP_OBJ_NULL) { - // // not connected - // // TODO I think we can listen even if not bound... - // mp_raise_OSError(MP_ENOTCONN); - // } +// // if (self->nic == MP_OBJ_NULL) { +// // // not connected +// // // TODO I think we can listen even if not bound... +// // mp_raise_OSError(MP_ENOTCONN); +// // } - // int _errno; - // if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) { - // mp_raise_OSError(_errno); - // } +// // int _errno; +// // if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) { +// // mp_raise_OSError(_errno); +// // } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_listen_obj, socketpool_socket_listen); +// return mp_const_none; +// } +// STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_listen_obj, socketpool_socket_listen); -//| def accept(self) -> tuple: -//| """Accept a connection on a listening socket of type SOCK_STREAM, -//| creating a new socket of type SOCK_STREAM. -//| Returns a tuple of (new_socket, remote_address)""" -//| +// //| def accept(self) -> tuple: +// //| """Accept a connection on a listening socket of type SOCK_STREAM, +// //| creating a new socket of type SOCK_STREAM. +// //| Returns a tuple of (new_socket, remote_address)""" +// //| -STATIC mp_obj_t socketpool_socket_accept(mp_obj_t self_in) { - // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); +// STATIC mp_obj_t socketpool_socket_accept(mp_obj_t self_in) { +// // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - // // create new socket object - // // starts with empty NIC so that finaliser doesn't run close() method if accept() fails - // mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t); - // socket2->base.type = &socket_type; - // socket2->nic = MP_OBJ_NULL; - // socket2->nic_type = NULL; +// // // create new socket object +// // // starts with empty NIC so that finaliser doesn't run close() method if accept() fails +// // mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t); +// // socket2->base.type = &socket_type; +// // socket2->nic = MP_OBJ_NULL; +// // socket2->nic_type = NULL; - // // accept incoming connection - // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; - // mp_uint_t port; - // int _errno; - // if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) { - // mp_raise_OSError(_errno); - // } +// // // accept incoming connection +// // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; +// // mp_uint_t port; +// // int _errno; +// // if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) { +// // mp_raise_OSError(_errno); +// // } - // // new socket has valid state, so set the NIC to the same as parent - // socket2->nic = self->nic; - // socket2->nic_type = self->nic_type; +// // // new socket has valid state, so set the NIC to the same as parent +// // socket2->nic = self->nic; +// // socket2->nic_type = self->nic_type; - // // make the return value - // mp_obj_tuple_t *client = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); - // client->items[0] = MP_OBJ_FROM_PTR(socket2); - // client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); +// // // make the return value +// // mp_obj_tuple_t *client = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); +// // client->items[0] = MP_OBJ_FROM_PTR(socket2); +// // client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, socketpool_socket_accept); +// return mp_const_none; +// } +// STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, socketpool_socket_accept); //| def close(self) -> None: //| """Closes this Socket and makes its resources available to its SocketPool.""" @@ -193,20 +193,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_close_obj, socketpool_socket_ //| STATIC mp_obj_t socketpool_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { - // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - // // get address - // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; - // mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); + mp_obj_t *addr_items; + mp_obj_get_array_fixed_n(addr_in, 2, &addr_items); - // // check if we need to select a NIC - // socket_select_nic(self, ip); + size_t hostlen; + const char* host = mp_obj_str_get_data(addr_items[0], &hostlen); + mp_int_t port = mp_obj_get_int(addr_items[1]); - // // call the NIC to connect the socket - // int _errno; - // if (self->nic_type->connect(self, ip, port, &_errno) != 0) { - // mp_raise_OSError(_errno); - // } + bool ok = common_hal_socketpool_socket_connect(self, host, hostlen, port); + if (!ok) { + mp_raise_OSError(0); + } return mp_const_none; } @@ -221,19 +220,17 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_connect_obj, socketpool_socke //| STATIC mp_obj_t socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) { - mp_int_t ret = 0; - // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); // if (self->nic == MP_OBJ_NULL) { // // not connected // mp_raise_OSError(MP_EPIPE); // } - // mp_buffer_info_t bufinfo; - // mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); - // int _errno; - // mp_int_t ret = self->nic_type->send(self, bufinfo.buf, bufinfo.len, &_errno); - // if (ret == -1) { - // mp_raise_OSError(_errno); - // } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + mp_int_t ret = common_hal_socketpool_socket_send(self, bufinfo.buf, bufinfo.len); + if (ret == -1) { + mp_raise_OSError(0); + } return mp_obj_new_int_from_uint(ret); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, socketpool_socket_send); @@ -267,134 +264,133 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, socketpool_socket_s //| STATIC mp_obj_t socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args) { - // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); // if (self->nic == MP_OBJ_NULL) { // // not connected // mp_raise_OSError(MP_ENOTCONN); // } - // mp_buffer_info_t bufinfo; - // mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); - // mp_int_t len = bufinfo.len; - // if (n_args == 3) { - // mp_int_t given_len = mp_obj_get_int(args[2]); - // if (given_len < len) { - // len = given_len; - // } - // } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); + mp_int_t len = bufinfo.len; + if (n_args == 3) { + mp_int_t given_len = mp_obj_get_int(args[2]); + if (given_len < len) { + len = given_len; + } + } - // mp_int_t ret = _socket_recv_into(self, (byte*)bufinfo.buf, len); - mp_int_t ret = 0; + mp_int_t ret = common_hal_socketpool_socket_recv_into(self, (byte*)bufinfo.buf, len); return mp_obj_new_int_from_uint(ret); } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_recv_into_obj, 2, 3, socketpool_socket_recv_into); -//| def sendto(self, bytes: ReadableBuffer, address: tuple) -> int: -//| """Send some bytes to a specific address. -//| Suits sockets of type SOCK_DGRAM -//| -//| :param ~bytes bytes: some bytes to send -//| :param ~tuple address: tuple of (remote_address, remote_port)""" -//| ... -//| +// //| def sendto(self, bytes: ReadableBuffer, address: tuple) -> int: +// //| """Send some bytes to a specific address. +// //| Suits sockets of type SOCK_DGRAM +// //| +// //| :param ~bytes bytes: some bytes to send +// //| :param ~tuple address: tuple of (remote_address, remote_port)""" +// //| ... +// //| -STATIC mp_obj_t socketpool_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { - // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); +// STATIC mp_obj_t socketpool_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { +// // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - // // get the data - // mp_buffer_info_t bufinfo; - // mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); +// // // get the data +// // mp_buffer_info_t bufinfo; +// // mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); - // // get address - // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; - // mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); +// // // get address +// // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; +// // mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG); - // // check if we need to select a NIC - // socket_select_nic(self, ip); +// // // check if we need to select a NIC +// // socket_select_nic(self, ip); - // // call the NIC to sendto - // int _errno; - // mp_int_t ret = self->nic_type->sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno); - // if (ret == -1) { - // mp_raise_OSError(_errno); - // } - mp_int_t ret = 0; +// // // call the NIC to sendto +// // int _errno; +// // mp_int_t ret = self->nic_type->sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno); +// // if (ret == -1) { +// // mp_raise_OSError(_errno); +// // } +// mp_int_t ret = 0; - return mp_obj_new_int(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(socketpool_socket_sendto_obj, socketpool_socket_sendto); +// return mp_obj_new_int(ret); +// } +// STATIC MP_DEFINE_CONST_FUN_OBJ_3(socketpool_socket_sendto_obj, socketpool_socket_sendto); -//| def recvfrom(self, bufsize: int) -> Tuple[bytes, tuple]: -//| """Reads some bytes from the connected remote address. -//| Suits sockets of type SOCK_STREAM -//| -//| Returns a tuple containing -//| * a bytes() of length <= bufsize -//| * a remote_address, which is a tuple of ip address and port number -//| -//| :param ~int bufsize: maximum number of bytes to receive""" -//| ... -//| +// //| def recvfrom(self, bufsize: int) -> Tuple[bytes, tuple]: +// //| """Reads some bytes from the connected remote address. +// //| Suits sockets of type SOCK_STREAM +// //| +// //| Returns a tuple containing +// //| * a bytes() of length <= bufsize +// //| * a remote_address, which is a tuple of ip address and port number +// //| +// //| :param ~int bufsize: maximum number of bytes to receive""" +// //| ... +// //| -STATIC mp_obj_t socketpool_socket_recvfrom_into(mp_obj_t self_in, mp_obj_t len_in) { - // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - // if (self->nic == MP_OBJ_NULL) { - // // not connected - // mp_raise_OSError(MP_ENOTCONN); - // } - // vstr_t vstr; - // vstr_init_len(&vstr, mp_obj_get_int(len_in)); - // byte ip[4]; - // mp_uint_t port; - // int _errno; - // mp_int_t ret = self->nic_type->recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno); - // if (ret == -1) { - // mp_raise_OSError(_errno); - // } - mp_obj_t tuple[2]; - // if (ret == 0) { - // tuple[0] = mp_const_empty_bytes; - // } else { - // vstr.len = ret; - // tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); - // } - // tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); - return mp_obj_new_tuple(2, tuple); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_recvfrom_into_obj, socketpool_socket_recvfrom_into); +// STATIC mp_obj_t socketpool_socket_recvfrom_into(mp_obj_t self_in, mp_obj_t len_in) { +// // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); +// // if (self->nic == MP_OBJ_NULL) { +// // // not connected +// // mp_raise_OSError(MP_ENOTCONN); +// // } +// // vstr_t vstr; +// // vstr_init_len(&vstr, mp_obj_get_int(len_in)); +// // byte ip[4]; +// // mp_uint_t port; +// // int _errno; +// // mp_int_t ret = self->nic_type->recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno); +// // if (ret == -1) { +// // mp_raise_OSError(_errno); +// // } +// mp_obj_t tuple[2]; +// // if (ret == 0) { +// // tuple[0] = mp_const_empty_bytes; +// // } else { +// // vstr.len = ret; +// // tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +// // } +// // tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); +// return mp_obj_new_tuple(2, tuple); +// } +// STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_recvfrom_into_obj, socketpool_socket_recvfrom_into); -//| def setsockopt(self, level: int, optname: int, value: int) -> None: -//| """Sets socket options""" -//| ... -//| +// //| def setsockopt(self, level: int, optname: int, value: int) -> None: +// //| """Sets socket options""" +// //| ... +// //| -STATIC mp_obj_t socketpool_socket_setsockopt(size_t n_args, const mp_obj_t *args) { - // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); +// STATIC mp_obj_t socketpool_socket_setsockopt(size_t n_args, const mp_obj_t *args) { +// // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); - // mp_int_t level = mp_obj_get_int(args[1]); - // mp_int_t opt = mp_obj_get_int(args[2]); +// // mp_int_t level = mp_obj_get_int(args[1]); +// // mp_int_t opt = mp_obj_get_int(args[2]); - // const void *optval; - // mp_uint_t optlen; - // mp_int_t val; - // if (mp_obj_is_integer(args[3])) { - // val = mp_obj_get_int_truncated(args[3]); - // optval = &val; - // optlen = sizeof(val); - // } else { - // mp_buffer_info_t bufinfo; - // mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); - // optval = bufinfo.buf; - // optlen = bufinfo.len; - // } +// // const void *optval; +// // mp_uint_t optlen; +// // mp_int_t val; +// // if (mp_obj_is_integer(args[3])) { +// // val = mp_obj_get_int_truncated(args[3]); +// // optval = &val; +// // optlen = sizeof(val); +// // } else { +// // mp_buffer_info_t bufinfo; +// // mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); +// // optval = bufinfo.buf; +// // optlen = bufinfo.len; +// // } - // int _errno; - // if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) { - // mp_raise_OSError(_errno); - // } +// // int _errno; +// // if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) { +// // mp_raise_OSError(_errno); +// // } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, 4, socketpool_socket_setsockopt); +// return mp_const_none; +// } +// STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, 4, socketpool_socket_setsockopt); //| def settimeout(self, value: int) -> None: //| """Set the timeout value for this socket. @@ -404,46 +400,39 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, //| STATIC mp_obj_t socketpool_socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { - // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - // if (self->nic == MP_OBJ_NULL) { - // // not connected - // mp_raise_OSError(MP_ENOTCONN); - // } - // mp_uint_t timeout; - // if (timeout_in == mp_const_none) { - // timeout = -1; - // } else { - // #if MICROPY_PY_BUILTINS_FLOAT - // timeout = 1000 * mp_obj_get_float(timeout_in); - // #else - // timeout = 1000 * mp_obj_get_int(timeout_in); - // #endif - // } - // int _errno; - // if (self->nic_type->settimeout(self, timeout, &_errno) != 0) { - // mp_raise_OSError(_errno); - // } + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t timeout_ms; + if (timeout_in == mp_const_none) { + timeout_ms = -1; + } else { + #if MICROPY_PY_BUILTINS_FLOAT + timeout_ms = 1000 * mp_obj_get_float(timeout_in); + #else + timeout_ms = 1000 * mp_obj_get_int(timeout_in); + #endif + } + common_hal_socketpool_socket_settimeout(self, timeout_ms); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_settimeout_obj, socketpool_socket_settimeout); -//| def setblocking(self, flag: bool) -> Optional[int]: -//| """Set the blocking behaviour of this socket. -//| -//| :param ~bool flag: False means non-blocking, True means block indefinitely.""" -//| ... -//| +// //| def setblocking(self, flag: bool) -> Optional[int]: +// //| """Set the blocking behaviour of this socket. +// //| +// //| :param ~bool flag: False means non-blocking, True means block indefinitely.""" +// //| ... +// //| -// method socket.setblocking(flag) -STATIC mp_obj_t socketpool_socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { - // if (mp_obj_is_true(blocking)) { - // return socket_settimeout(self_in, mp_const_none); - // } else { - // return socket_settimeout(self_in, MP_OBJ_NEW_SMALL_INT(0)); - // } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_setblocking_obj, socketpool_socket_setblocking); +// // method socket.setblocking(flag) +// STATIC mp_obj_t socketpool_socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { +// // if (mp_obj_is_true(blocking)) { +// // return socket_settimeout(self_in, mp_const_none); +// // } else { +// // return socket_settimeout(self_in, MP_OBJ_NEW_SMALL_INT(0)); +// // } +// return mp_const_none; +// } +// STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_setblocking_obj, socketpool_socket_setblocking); STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, @@ -451,17 +440,17 @@ STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&socketpool_socket_close_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socketpool_socket_close_obj) }, - { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socketpool_socket_bind_obj) }, - { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socketpool_socket_listen_obj) }, - { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socketpool_socket_accept_obj) }, + // { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socketpool_socket_bind_obj) }, + // { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socketpool_socket_listen_obj) }, + // { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socketpool_socket_accept_obj) }, { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&socketpool_socket_connect_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socketpool_socket_send_obj) }, - { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socketpool_socket_sendto_obj) }, - { MP_ROM_QSTR(MP_QSTR_recvfrom_into), MP_ROM_PTR(&socketpool_socket_recvfrom_into_obj) }, + // { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socketpool_socket_sendto_obj) }, + // { MP_ROM_QSTR(MP_QSTR_recvfrom_into), MP_ROM_PTR(&socketpool_socket_recvfrom_into_obj) }, { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socketpool_socket_recv_into_obj) }, - { MP_ROM_QSTR(MP_QSTR_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_setblocking), MP_ROM_PTR(&socketpool_socket_setblocking_obj) }, + // { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socketpool_socket_setblocking_obj) }, }; STATIC MP_DEFINE_CONST_DICT(socketpool_socket_locals_dict, socketpool_socket_locals_dict_table); diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h index bbe6227efe..94c939e7b8 100644 --- a/shared-bindings/socketpool/Socket.h +++ b/shared-bindings/socketpool/Socket.h @@ -31,8 +31,9 @@ extern const mp_obj_type_t socketpool_socket_type; -// mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value); -// void common_hal_ipaddress_ipv4address_construct(ipaddress_ipv4address_obj_t* self, uint8_t* buf, size_t len); -// mp_obj_t common_hal_ipaddress_ipv4address_get_packed(ipaddress_ipv4address_obj_t* self); +void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms); +bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const char* host, size_t hostlen, mp_int_t port); +mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len); +mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H diff --git a/shared-bindings/socketpool/SocketPool.c b/shared-bindings/socketpool/SocketPool.c index ed5ff82750..2be071c789 100644 --- a/shared-bindings/socketpool/SocketPool.c +++ b/shared-bindings/socketpool/SocketPool.c @@ -33,6 +33,7 @@ #include "py/runtime.h" #include "py/mperrno.h" +#include "shared-bindings/ipaddress/__init__.h" #include "shared-bindings/socketpool/Socket.h" #include "shared-bindings/socketpool/SocketPool.h" @@ -45,6 +46,8 @@ STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t socketpool_socketpool_obj_t *s = m_new_obj_with_finaliser(socketpool_socketpool_obj_t); s->base.type = &socketpool_socketpool_type; + // common_hal_socketpool_socketpool_construct(s, ); + return MP_OBJ_FROM_PTR(s); } @@ -58,31 +61,22 @@ STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t //| ... //| STATIC mp_obj_t socketpool_socketpool_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_arg_check_num(n_args, kw_args, 0, 4, false); + mp_arg_check_num(n_args, kw_args, 0, 5, false); - // create socket object (not bound to any NIC yet) - socketpool_socket_obj_t *s = m_new_obj_with_finaliser(socketpool_socket_obj_t); - s->base.type = &socketpool_socket_type; - // s->nic = MP_OBJ_NULL; - // s->nic_type = NULL; - // s->u_param.domain = MOD_NETWORK_AF_INET; - // s->u_param.type = MOD_NETWORK_SOCK_STREAM; - // s->u_param.fileno = -1; - // if (n_args >= 1) { - // s->u_param.domain = mp_obj_get_int(args[0]); - // if (n_args >= 2) { - // s->u_param.type = mp_obj_get_int(args[1]); - // if (n_args >= 4) { - // s->u_param.fileno = mp_obj_get_int(args[3]); - // } - // } - // } - - return MP_OBJ_FROM_PTR(s); + socketpool_socketpool_obj_t *self = pos_args[0]; + socketpool_socketpool_addressfamily_t family = SOCKETPOOL_AF_INET; + socketpool_socketpool_sock_t type = SOCKETPOOL_SOCK_STREAM; + if (n_args >= 2) { + family = mp_obj_get_int(pos_args[1]); + if (n_args >= 3) { + type = mp_obj_get_int(pos_args[2]); + } + } + return common_hal_socketpool_socket(self, family, type); } MP_DEFINE_CONST_FUN_OBJ_KW(socketpool_socketpool_socket_obj, 1, socketpool_socketpool_socket); -//| def getaddrinfo(host: str, port: int) -> tuple: +//| def getaddrinfo(host: str, port: int, family: int = 0, type: int = 0, proto: int = 0, flags: int = 0) -> tuple: //| """Gets the address information for a hostname and port //| //| Returns the appropriate family, socket type, socket protocol and @@ -91,55 +85,49 @@ MP_DEFINE_CONST_FUN_OBJ_KW(socketpool_socketpool_socket_obj, 1, socketpool_socke //| ... //| -STATIC mp_obj_t socketpool_socketpool_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { - // size_t hlen; - // const char *host = mp_obj_str_get_data(host_in, &hlen); - // mp_int_t port = mp_obj_get_int(port_in); - // uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE]; - // bool have_ip = false; +STATIC mp_obj_t socketpool_socketpool_getaddrinfo(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_host, ARG_port, ARG_family, ARG_type, ARG_proto, ARG_flags }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_host, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_port, MP_ARG_INT | MP_ARG_REQUIRED }, + { MP_QSTR_family, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_type, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_port, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_flags, MP_ARG_INT, {.u_int = 0} }, + }; + socketpool_socketpool_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - // if (hlen > 0) { - // // check if host is already in IP form - // nlr_buf_t nlr; - // if (nlr_push(&nlr) == 0) { - // netutils_parse_ipv4_addr(host_in, out_ip, NETUTILS_BIG); - // have_ip = true; - // nlr_pop(); - // } else { - // // swallow exception: host was not in IP form so need to do DNS lookup - // } - // } + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // if (!have_ip) { - // // find a NIC that can do a name lookup - // for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { - // mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; - // mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); - // if (nic_type->gethostbyname != NULL) { - // int ret = nic_type->gethostbyname(nic, host, hlen, out_ip); - // if (ret != 0) { - // mp_raise_OSError(ret); - // } - // have_ip = true; - // break; - // } - // } - // } + const char *host = mp_obj_str_get_str(args[ARG_host].u_obj); + mp_int_t port = args[ARG_port].u_int; + mp_obj_t ip_str = mp_const_none; - // if (!have_ip) { - // nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC"))); - // } + if (strlen(host) > 0 && ipaddress_parse_ipv4address(host, strlen(host), NULL)) { + ip_str = args[ARG_host].u_obj; + } - // mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL)); - // tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET); - // tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM); - // tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); - // tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_); - // tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG); - // return mp_obj_new_list(1, (mp_obj_t*)&tuple); - return mp_const_none; + if (ip_str == mp_const_none) { + ip_str = common_hal_socketpool_socketpool_gethostbyname(self, host); + } + + if (ip_str == mp_const_none) { + mp_raise_OSError(0); + } + + mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL)); + tuple->items[0] = MP_OBJ_NEW_SMALL_INT(SOCKETPOOL_AF_INET); + tuple->items[1] = MP_OBJ_NEW_SMALL_INT(SOCKETPOOL_SOCK_STREAM); + tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); + tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_); + mp_obj_tuple_t *sockaddr = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + sockaddr->items[0] = ip_str; + sockaddr->items[1] = MP_OBJ_NEW_SMALL_INT(port); + tuple->items[4] = MP_OBJ_FROM_PTR(sockaddr); + return mp_obj_new_list(1, (mp_obj_t*)&tuple); } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socketpool_getaddrinfo_obj, socketpool_socketpool_getaddrinfo); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(socketpool_socketpool_getaddrinfo_obj, 3, socketpool_socketpool_getaddrinfo); STATIC const mp_rom_map_elem_t socketpool_socketpool_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&socketpool_socketpool_socket_obj) }, diff --git a/shared-bindings/socketpool/SocketPool.h b/shared-bindings/socketpool/SocketPool.h index 1852cc1680..42bd885185 100644 --- a/shared-bindings/socketpool/SocketPool.h +++ b/shared-bindings/socketpool/SocketPool.h @@ -29,11 +29,10 @@ #include "common-hal/socketpool/SocketPool.h" +#include "shared-bindings/socketpool/Socket.h" + extern const mp_obj_type_t socketpool_socketpool_type; -// mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value); -// void common_hal_ipaddress_ipv4address_construct(ipaddress_ipv4address_obj_t* self, uint8_t* buf, size_t len); -// mp_obj_t common_hal_ipaddress_ipv4address_get_packed(ipaddress_ipv4address_obj_t* self); typedef enum { SOCKETPOOL_SOCK_STREAM, SOCKETPOOL_SOCK_DGRAM, @@ -43,6 +42,12 @@ typedef enum { typedef enum { SOCKETPOOL_AF_INET, SOCKETPOOL_AF_INET6 -} socketpool_socketpool_af_t; +} socketpool_socketpool_addressfamily_t; + +socketpool_socket_obj_t* common_hal_socketpool_socket(socketpool_socketpool_obj_t* self, + socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type); + +mp_obj_t common_hal_socketpool_socketpool_gethostbyname(socketpool_socketpool_obj_t* self, + const char* host); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKETPOOL_H From 430530c74ba0780b2afb232756d3f5cd3b417179 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 13 Aug 2020 16:55:49 -0700 Subject: [PATCH 13/78] SSL works until it runs out of memory --- ports/esp32s2/common-hal/socketpool/Socket.c | 6 +- ports/esp32s2/common-hal/socketpool/Socket.h | 3 +- ports/esp32s2/common-hal/ssl/SSLContext.c | 8 +- ports/esp32s2/common-hal/ssl/SSLContext.h | 2 + ports/esp32s2/common-hal/ssl/__init__.c | 9 +- ports/esp32s2/common-hal/ssl/__init__.h | 6 +- ports/esp32s2/supervisor/port.c | 2 +- py/circuitpy_defns.mk | 5 ++ py/circuitpy_mpconfig.h | 8 ++ py/circuitpy_mpconfig.mk | 3 + shared-bindings/socketpool/__init__.h | 10 +-- shared-bindings/ssl/SSLContext.c | 93 ++++++++++++++++++++ shared-bindings/ssl/SSLContext.h | 52 +++++++++++ shared-bindings/ssl/__init__.c | 74 ++++++++++++++++ shared-bindings/ssl/__init__.h | 34 +++++++ 15 files changed, 296 insertions(+), 19 deletions(-) create mode 100644 shared-bindings/ssl/SSLContext.c create mode 100644 shared-bindings/ssl/SSLContext.h create mode 100644 shared-bindings/ssl/__init__.c create mode 100644 shared-bindings/ssl/__init__.h diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c index 0ed8b09147..83bb455693 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.c +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -39,7 +39,11 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const c // should become more and more common. Therefore, we optimize for the TLS case. ESP_LOGI(TAG, "connecting to %s:%d %p", host, port, self->ssl_context); - int result = esp_tls_conn_new_sync(host, hostlen, port, self->ssl_context, self->tcp); + esp_tls_cfg_t* tls_config = NULL; + if (self->ssl_context != NULL) { + tls_config = &self->ssl_context->ssl_config; + } + int result = esp_tls_conn_new_sync(host, hostlen, port, tls_config, self->tcp); ESP_LOGI(TAG, "result %d", result); return result >= 0; } diff --git a/ports/esp32s2/common-hal/socketpool/Socket.h b/ports/esp32s2/common-hal/socketpool/Socket.h index 8a250a115a..ba832faac2 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.h +++ b/ports/esp32s2/common-hal/socketpool/Socket.h @@ -30,6 +30,7 @@ #include "py/obj.h" #include "common-hal/socketpool/SocketPool.h" +#include "common-hal/ssl/SSLContext.h" #include "esp-idf/components/esp-tls/esp_tls.h" @@ -37,7 +38,7 @@ typedef struct { mp_obj_base_t base; int num; esp_tls_t* tcp; - esp_tls_cfg_t* ssl_context; + ssl_sslcontext_obj_t* ssl_context; socketpool_socketpool_obj_t* pool; mp_uint_t timeout_ms; } socketpool_socket_obj_t; diff --git a/ports/esp32s2/common-hal/ssl/SSLContext.c b/ports/esp32s2/common-hal/ssl/SSLContext.c index 98fedb3a84..e24fd338b6 100644 --- a/ports/esp32s2/common-hal/ssl/SSLContext.c +++ b/ports/esp32s2/common-hal/ssl/SSLContext.c @@ -24,16 +24,18 @@ * THE SOFTWARE. */ -#include "shared-bindings/socketpool/SocketPool.h" +#include "shared-bindings/ssl/SSLContext.h" #include "py/runtime.h" -#include "esp-idf/components/lwip/lwip/src/include/lwip/netdb.h" +void common_hal_ssl_sslcontext_construct(ssl_sslcontext_obj_t* self) { + +} socketpool_socket_obj_t* common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t* self, socketpool_socket_obj_t* socket, bool server_side, const char* server_hostname) { - + socket->ssl_context = self; // Should we store server hostname on the socket in case connect is called with an ip? return socket; } diff --git a/ports/esp32s2/common-hal/ssl/SSLContext.h b/ports/esp32s2/common-hal/ssl/SSLContext.h index e44b1f7fe7..41d199f080 100644 --- a/ports/esp32s2/common-hal/ssl/SSLContext.h +++ b/ports/esp32s2/common-hal/ssl/SSLContext.h @@ -29,6 +29,8 @@ #include "py/obj.h" +#include "esp-idf/components/esp-tls/esp_tls.h" + typedef struct { mp_obj_base_t base; esp_tls_cfg_t ssl_config; diff --git a/ports/esp32s2/common-hal/ssl/__init__.c b/ports/esp32s2/common-hal/ssl/__init__.c index 8f9565b46e..a105e53624 100644 --- a/ports/esp32s2/common-hal/ssl/__init__.c +++ b/ports/esp32s2/common-hal/ssl/__init__.c @@ -24,8 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H -#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H +#include "shared-bindings/ssl/SSLContext.h" +#include "esp-idf/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h" -#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H +void common_hal_ssl_create_default_context(ssl_sslcontext_obj_t* self) { + memset(&self->ssl_config, 0, sizeof(esp_tls_cfg_t)); + self->ssl_config.crt_bundle_attach = esp_crt_bundle_attach; +} diff --git a/ports/esp32s2/common-hal/ssl/__init__.h b/ports/esp32s2/common-hal/ssl/__init__.h index 8f9565b46e..fe83a79194 100644 --- a/ports/esp32s2/common-hal/ssl/__init__.h +++ b/ports/esp32s2/common-hal/ssl/__init__.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H -#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL___INIT___H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL___INIT___H -#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL___INIT___H diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 9a1ac5e2c8..bebecd8ae3 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -48,7 +48,7 @@ #include "esp_log.h" static const char *TAG = "cp port"; -#define HEAP_SIZE (64 * 1024) +#define HEAP_SIZE (48 * 1024) STATIC esp_timer_handle_t _tick_timer; diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 43f6977f0f..56cd937a85 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -231,6 +231,9 @@ endif ifeq ($(CIRCUITPY_SOCKETPOOL),1) SRC_PATTERNS += socketpool/% endif +ifeq ($(CIRCUITPY_SSL),1) +SRC_PATTERNS += ssl/% +endif ifeq ($(CIRCUITPY_STAGE),1) SRC_PATTERNS += _stage/% endif @@ -340,6 +343,8 @@ SRC_COMMON_HAL_ALL = \ socketpool/__init__.c \ socketpool/SocketPool.c \ socketpool/Socket.c \ + ssl/__init__.c \ + ssl/SSLContext.c \ supervisor/Runtime.c \ supervisor/__init__.c \ watchdog/WatchDogMode.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 846328dcdf..b2543dcad8 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -588,6 +588,13 @@ extern const struct _mp_obj_module_t socketpool_module; #define SOCKETPOOL_MODULE #endif +#if CIRCUITPY_SSL +extern const struct _mp_obj_module_t ssl_module; +#define SSL_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_ssl), (mp_obj_t)&ssl_module }, +#else +#define SSL_MODULE +#endif + #if CIRCUITPY_STAGE extern const struct _mp_obj_module_t stage_module; #define STAGE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__stage), (mp_obj_t)&stage_module }, @@ -773,6 +780,7 @@ extern const struct _mp_obj_module_t wifi_module; SDIOIO_MODULE \ SHARPDISPLAY_MODULE \ SOCKETPOOL_MODULE \ + SSL_MODULE \ STAGE_MODULE \ STORAGE_MODULE \ STRUCT_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 35ed6df028..8b34dced24 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -188,6 +188,9 @@ CFLAGS += -DCIRCUITPY_SHARPDISPLAY=$(CIRCUITPY_SHARPDISPLAY) CIRCUITPY_SOCKETPOOL ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_SOCKETPOOL=$(CIRCUITPY_SOCKETPOOL) +CIRCUITPY_SSL ?= $(CIRCUITPY_WIFI) +CFLAGS += -DCIRCUITPY_SSL=$(CIRCUITPY_SSL) + # Currently always off. CIRCUITPY_STAGE ?= 0 CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE) diff --git a/shared-bindings/socketpool/__init__.h b/shared-bindings/socketpool/__init__.h index 76d8bfa766..a017e96c6d 100644 --- a/shared-bindings/socketpool/__init__.h +++ b/shared-bindings/socketpool/__init__.h @@ -24,11 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL___INIT___H -#include "shared-module/ipaddress/__init__.h" - -mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL___INIT___H diff --git a/shared-bindings/ssl/SSLContext.c b/shared-bindings/ssl/SSLContext.c new file mode 100644 index 0000000000..d47baf3455 --- /dev/null +++ b/shared-bindings/ssl/SSLContext.c @@ -0,0 +1,93 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * 2018 Nick Moore for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "py/objtuple.h" +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/mperrno.h" + +#include "shared-bindings/ssl/SSLContext.h" + +//| class SSLContext: +//| + +STATIC mp_obj_t ssl_sslcontext_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 0, 1, false); + + ssl_sslcontext_obj_t *s = m_new_obj(ssl_sslcontext_obj_t); + s->base.type = &ssl_sslcontext_type; + + common_hal_ssl_sslcontext_construct(s); + + return MP_OBJ_FROM_PTR(s); +} + +//| def wrap_socket(sock: socketpool.Socket, *, server_side: bool = False, server_hostname: str = None) -> socketpool.Socket: +//| """Wraps the socket into a socket-compatible class that handles SSL negotiation. +//| The socket must be of type SOCK_STREAM.""" +//| ... +//| + +STATIC mp_obj_t ssl_sslcontext_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sock, ARG_server_side, ARG_server_hostname }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sock, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + ssl_sslcontext_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const char *server_hostname = mp_obj_str_get_str(args[ARG_server_hostname].u_obj); + bool server_side = args[ARG_server_side].u_bool; + if (server_side && server_hostname != NULL) { + mp_raise_ValueError(translate("Server side context cannot have hostname.")); + } + + socketpool_socket_obj_t* sock = args[ARG_sock].u_obj; + + return common_hal_ssl_sslcontext_wrap_socket(self, sock, server_side, server_hostname); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ssl_sslcontext_wrap_socket_obj, 2, ssl_sslcontext_wrap_socket); + +STATIC const mp_rom_map_elem_t ssl_sslcontext_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_wrap_socket), MP_ROM_PTR(&ssl_sslcontext_wrap_socket_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(ssl_sslcontext_locals_dict, ssl_sslcontext_locals_dict_table); + +const mp_obj_type_t ssl_sslcontext_type = { + { &mp_type_type }, + .name = MP_QSTR_SSLContext, + .make_new = ssl_sslcontext_make_new, + .locals_dict = (mp_obj_dict_t*)&ssl_sslcontext_locals_dict, +}; diff --git a/shared-bindings/ssl/SSLContext.h b/shared-bindings/ssl/SSLContext.h new file mode 100644 index 0000000000..3bb1391164 --- /dev/null +++ b/shared-bindings/ssl/SSLContext.h @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_SSL_SSLCONTEXT_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_SSL_SSLCONTEXT_H + +#include "common-hal/ssl/SSLContext.h" + +#include "shared-bindings/socketpool/Socket.h" + +extern const mp_obj_type_t ssl_sslcontext_type; + +// typedef enum { +// SOCKETPOOL_SOCK_STREAM, +// SOCKETPOOL_SOCK_DGRAM, +// SOCKETPOOL_SOCK_RAW +// } socketpool_socketpool_sock_t; + +// typedef enum { +// SOCKETPOOL_AF_INET, +// SOCKETPOOL_AF_INET6 +// } socketpool_socketpool_addressfamily_t; + +void common_hal_ssl_sslcontext_construct(ssl_sslcontext_obj_t* self); + +socketpool_socket_obj_t* common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t* self, + socketpool_socket_obj_t* sock, bool server_side, const char* server_hostname); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SSL_SSLCONTEXT_H diff --git a/shared-bindings/ssl/__init__.c b/shared-bindings/ssl/__init__.c new file mode 100644 index 0000000000..fec4c76676 --- /dev/null +++ b/shared-bindings/ssl/__init__.c @@ -0,0 +1,74 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objexcept.h" +#include "py/objstr.h" +#include "py/parsenum.h" +#include "py/runtime.h" +#include "shared-bindings/ssl/__init__.h" +#include "shared-bindings/ssl/SSLContext.h" + +//| """ +//| The `ssl` module provides SSL contexts to wrap sockets in. +//| """ +//| + +//| def create_default_context() -> ssl.SSLContext: +//| """Return the default SSLContext.""" +//| ... +//| + +STATIC mp_obj_t ssl_create_default_context(void) { + ssl_sslcontext_obj_t *s = m_new_obj(ssl_sslcontext_obj_t); + s->base.type = &ssl_sslcontext_type; + + common_hal_ssl_create_default_context(s); + return s; +} +MP_DEFINE_CONST_FUN_OBJ_0(ssl_create_default_context_obj, ssl_create_default_context); + +STATIC const mp_rom_map_elem_t ssl_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ssl) }, + + { MP_ROM_QSTR(MP_QSTR_create_default_context), MP_ROM_PTR(&ssl_create_default_context_obj) }, + + { MP_ROM_QSTR(MP_QSTR_SSLContext), MP_ROM_PTR(&ssl_sslcontext_type) }, + + // class constants + // { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(SOCKETPOOL_AF_INET) }, + // { MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(SOCKETPOOL_AF_INET6) }, + + // { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(SOCKETPOOL_SOCK_STREAM) }, + // { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(SOCKETPOOL_SOCK_DGRAM) }, + // { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(SOCKETPOOL_SOCK_RAW) }, +}; + +STATIC MP_DEFINE_CONST_DICT(ssl_globals, ssl_globals_table); + +const mp_obj_module_t ssl_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&ssl_globals, +}; diff --git a/shared-bindings/ssl/__init__.h b/shared-bindings/ssl/__init__.h new file mode 100644 index 0000000000..5ddada64e6 --- /dev/null +++ b/shared-bindings/ssl/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_SSL___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_SSL___INIT___H + +#include "common-hal/ssl/SSLContext.h" + +void common_hal_ssl_create_default_context(ssl_sslcontext_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SSL___INIT___H From b3a449c2764f25a3c4becdbbed47e02ca36f755b Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 14 Aug 2020 15:52:18 -0700 Subject: [PATCH 14/78] Turn on json and enable socket.close --- ports/esp32s2/mpconfigport.h | 2 +- shared-bindings/socketpool/Socket.c | 28 ++-------------------------- shared-bindings/socketpool/Socket.h | 1 + 3 files changed, 4 insertions(+), 27 deletions(-) diff --git a/ports/esp32s2/mpconfigport.h b/ports/esp32s2/mpconfigport.h index d340bb4805..c06e63439c 100644 --- a/ports/esp32s2/mpconfigport.h +++ b/ports/esp32s2/mpconfigport.h @@ -31,7 +31,7 @@ #define CIRCUITPY_INTERNAL_NVM_SIZE (0) #define MICROPY_NLR_THUMB (0) -#define MICROPY_PY_UJSON (0) +#define MICROPY_PY_UJSON (1) #define MICROPY_USE_INTERNAL_PRINTF (0) #include "py/circuitpy_mpconfig.h" diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index f6f90ceb1f..64a051301c 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -155,32 +155,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket___exit___obj, 4, 4, //| """Closes this Socket and makes its resources available to its SocketPool.""" //| STATIC mp_obj_t socketpool_socket_close(mp_obj_t self_in) { - // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - - // // create new socket object - // // starts with empty NIC so that finaliser doesn't run close() method if accept() fails - // mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t); - // socket2->base.type = &socket_type; - // socket2->nic = MP_OBJ_NULL; - // socket2->nic_type = NULL; - - // // accept incoming connection - // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE]; - // mp_uint_t port; - // int _errno; - // if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) { - // mp_raise_OSError(_errno); - // } - - // // new socket has valid state, so set the NIC to the same as parent - // socket2->nic = self->nic; - // socket2->nic_type = self->nic_type; - - // // make the return value - // mp_obj_tuple_t *client = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); - // client->items[0] = MP_OBJ_FROM_PTR(socket2); - // client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG); - + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_socketpool_socket_close(self); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_close_obj, socketpool_socket_close); diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h index 94c939e7b8..a1aeccbe3e 100644 --- a/shared-bindings/socketpool/Socket.h +++ b/shared-bindings/socketpool/Socket.h @@ -35,5 +35,6 @@ void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_u bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const char* host, size_t hostlen, mp_int_t port); mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len); mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len); +void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H From 1034cc12177d998df1c7f3381668040bb13ced58 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 14 Aug 2020 15:56:01 -0700 Subject: [PATCH 15/78] Add espidf module. --- ports/esp32s2/Makefile | 1 + ports/esp32s2/bindings/espidf/__init__.c | 79 ++++++++++++++++++++++++ ports/esp32s2/mpconfigport.mk | 1 + py/circuitpy_mpconfig.h | 8 +++ py/circuitpy_mpconfig.mk | 6 ++ 5 files changed, 95 insertions(+) create mode 100644 ports/esp32s2/bindings/espidf/__init__.c diff --git a/ports/esp32s2/Makefile b/ports/esp32s2/Makefile index 142387f63e..ea9c685926 100644 --- a/ports/esp32s2/Makefile +++ b/ports/esp32s2/Makefile @@ -166,6 +166,7 @@ SRC_C += \ background.c \ fatfs_port.c \ mphalport.c \ + bindings/espidf/__init__.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ modules/$(CIRCUITPY_MODULE).c \ diff --git a/ports/esp32s2/bindings/espidf/__init__.c b/ports/esp32s2/bindings/espidf/__init__.c new file mode 100644 index 0000000000..11df76ec00 --- /dev/null +++ b/ports/esp32s2/bindings/espidf/__init__.c @@ -0,0 +1,79 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "py/runtime.h" + +#include "esp-idf/components/heap/include/esp_heap_caps.h" + +//| """Direct access to a few ESP-IDF details. This module *should not* include any functionality +//| that could be implemented by other frameworks. It should only include ESP-IDF specific +//| things.""" + +//| def heap_caps_get_total_size() -> int: +//| """Return the total size of the ESP-IDF, which includes the CircuitPython heap.""" +//| ... +//| + +STATIC mp_obj_t espidf_heap_caps_get_total_size(void) { + return MP_OBJ_NEW_SMALL_INT(heap_caps_get_total_size(MALLOC_CAP_8BIT)); +} +MP_DEFINE_CONST_FUN_OBJ_0(espidf_heap_caps_get_total_size_obj, espidf_heap_caps_get_total_size); + +//| def heap_caps_get_free_size() -> int: +//| """Return total free memory in the ESP-IDF heap.""" +//| ... +//| + +STATIC mp_obj_t espidf_heap_caps_get_free_size(void) { + return MP_OBJ_NEW_SMALL_INT(heap_caps_get_free_size(MALLOC_CAP_8BIT)); +} +MP_DEFINE_CONST_FUN_OBJ_0(espidf_heap_caps_get_free_size_obj, espidf_heap_caps_get_free_size); + +//| def heap_caps_get_largest_free_block() -> int: +//| """Return the size of largest free memory block in the ESP-IDF heap.""" +//| ... +//| + +STATIC mp_obj_t espidf_heap_caps_get_largest_free_block(void) { + return MP_OBJ_NEW_SMALL_INT(heap_caps_get_largest_free_block(MALLOC_CAP_8BIT)); +} +MP_DEFINE_CONST_FUN_OBJ_0(espidf_heap_caps_get_largest_free_block_obj, espidf_heap_caps_get_largest_free_block); + +STATIC const mp_rom_map_elem_t espidf_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_espidf) }, + + { MP_ROM_QSTR(MP_QSTR_heap_caps_get_total_size), MP_ROM_PTR(&espidf_heap_caps_get_total_size_obj)}, + { MP_ROM_QSTR(MP_QSTR_heap_caps_get_free_size), MP_ROM_PTR(&espidf_heap_caps_get_free_size_obj)}, + { MP_ROM_QSTR(MP_QSTR_heap_caps_get_largest_free_block), MP_ROM_PTR(&espidf_heap_caps_get_largest_free_block_obj)}, +}; + +STATIC MP_DEFINE_CONST_DICT(espidf_module_globals, espidf_module_globals_table); + +const mp_obj_module_t espidf_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&espidf_module_globals, +}; diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index 62d2da6079..5252714388 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -25,5 +25,6 @@ CIRCUITPY_RTC = 0 CIRCUITPY_NVM = 0 CIRCUITPY_USB_MIDI = 0 # We don't have enough endpoints to include MIDI. CIRCUITPY_WIFI = 1 +CIRCUITPY_ESPIDF = 1 CIRCUITPY_MODULE ?= none diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index b2543dcad8..b3fd8a05d6 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -363,6 +363,13 @@ extern const struct _mp_obj_module_t terminalio_module; #define TERMINALIO_MODULE #endif +#if CIRCUITPY_ESPIDF +extern const struct _mp_obj_module_t espidf_module; +#define ESPIDF_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_espidf),(mp_obj_t)&espidf_module }, +#else +#define ESPIDF_MODULE +#endif + #if CIRCUITPY_FRAMEBUFFERIO extern const struct _mp_obj_module_t framebufferio_module; #define FRAMEBUFFERIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_framebufferio), (mp_obj_t)&framebufferio_module }, @@ -750,6 +757,7 @@ extern const struct _mp_obj_module_t wifi_module; TERMINALIO_MODULE \ VECTORIO_MODULE \ ERRNO_MODULE \ + ESPIDF_MODULE \ FRAMEBUFFERIO_MODULE \ FREQUENCYIO_MODULE \ GAMEPAD_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 8b34dced24..b6fd805d35 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -95,6 +95,12 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO) CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO) +# CIRCUITPY_ESPIDF is handled in the atmel-samd tree. +# Only for ESP32S chips. +# Assume not a ESP build. +CIRCUITPY_ESPIDF ?= 0 +CFLAGS += -DCIRCUITPY_ESPIDF=$(CIRCUITPY_ESPIDF) + ifeq ($(CIRCUITPY_DISPLAYIO),1) CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD) else From dcc42f6281ad928c6218acaab8e72bdf52038851 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 14 Aug 2020 17:03:29 -0700 Subject: [PATCH 16/78] Remove debug prints --- ports/esp32s2/common-hal/socketpool/Socket.c | 7 - ports/esp32s2/common-hal/wifi/Radio.c | 158 ++++++++---------- .../esp32s2/common-hal/wifi/ScannedNetworks.c | 8 - ports/esp32s2/common-hal/wifi/__init__.c | 28 +--- ports/esp32s2/supervisor/port.c | 10 -- shared-bindings/socketpool/__init__.c | 4 +- shared-bindings/ssl/__init__.c | 8 - 7 files changed, 73 insertions(+), 150 deletions(-) diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c index 83bb455693..b9c6dca6ff 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.c +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -26,9 +26,6 @@ #include "shared-bindings/socketpool/Socket.h" -#include "esp_log.h" -static const char *TAG = "socket"; - void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms) { self->timeout_ms = timeout_ms; } @@ -38,20 +35,17 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const c // NULL and should still work. This makes regular TCP connections more memory expensive but TLS // should become more and more common. Therefore, we optimize for the TLS case. - ESP_LOGI(TAG, "connecting to %s:%d %p", host, port, self->ssl_context); esp_tls_cfg_t* tls_config = NULL; if (self->ssl_context != NULL) { tls_config = &self->ssl_context->ssl_config; } int result = esp_tls_conn_new_sync(host, hostlen, port, tls_config, self->tcp); - ESP_LOGI(TAG, "result %d", result); return result >= 0; } mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { size_t sent = esp_tls_conn_write(self->tcp, buf, len); - ESP_LOGI(TAG, "sent %d bytes", sent); if (sent < 0) { // raise an error } @@ -61,7 +55,6 @@ mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { size_t received = esp_tls_conn_read(self->tcp, (void*) buf, len); - ESP_LOGI(TAG, "received %d bytes", received); if (received == 0) { // socket closed } diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c index d4f17f2bb0..0f97565da0 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.c +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -38,99 +38,84 @@ #include "esp-idf/components/esp_wifi/include/esp_wifi.h" #include "esp-idf/components/lwip/include/apps/ping/ping_sock.h" -#include "esp_log.h" -static const char *TAG = "cp radio"; - static void start_station(wifi_radio_obj_t *self) { - if (self->sta_mode) { - return; - } - wifi_mode_t next_mode; - if (self->ap_mode) { - next_mode = WIFI_MODE_APSTA; - } else { - next_mode = WIFI_MODE_STA; - } - esp_wifi_set_mode(next_mode); + if (self->sta_mode) { + return; + } + wifi_mode_t next_mode; + if (self->ap_mode) { + next_mode = WIFI_MODE_APSTA; + } else { + next_mode = WIFI_MODE_STA; + } + esp_wifi_set_mode(next_mode); - esp_wifi_set_config(WIFI_MODE_STA, &self->sta_config); + esp_wifi_set_config(WIFI_MODE_STA, &self->sta_config); } bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self) { - return self->started; + return self->started; } void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) { - if (self->started && !enabled) { - ESP_LOGI(TAG, "stop"); - if (self->current_scan != NULL) { - common_hal_wifi_radio_stop_scanning_networks(self); - } - ESP_ERROR_CHECK(esp_wifi_stop()); - self->started = false; - return; - } - if (!self->started && enabled) { - ESP_LOGI(TAG, "start"); - ESP_ERROR_CHECK(esp_wifi_start()); - self->started = true; - return; - } + if (self->started && !enabled) { + if (self->current_scan != NULL) { + common_hal_wifi_radio_stop_scanning_networks(self); + } + ESP_ERROR_CHECK(esp_wifi_stop()); + self->started = false; + return; + } + if (!self->started && enabled) { + ESP_ERROR_CHECK(esp_wifi_start()); + self->started = true; + return; + } } mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) { - uint8_t mac[6]; - esp_wifi_get_mac(ESP_IF_WIFI_STA, mac); - return mp_const_none; + uint8_t mac[6]; + esp_wifi_get_mac(ESP_IF_WIFI_STA, mac); + return mp_const_none; } mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) { - if (self->current_scan != NULL) { - mp_raise_RuntimeError(translate("Already scanning for wifi networks")); - } - // check enabled - start_station(self); + if (self->current_scan != NULL) { + mp_raise_RuntimeError(translate("Already scanning for wifi networks")); + } + // check enabled + start_station(self); - ESP_LOGI(TAG, "start scan"); - wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t); - self->current_scan = scan; - scan->base.type = &wifi_scannednetworks_type; - scan->start_channel = 1; - scan->end_channel = 11; - scan->radio_event_group = self->event_group_handle; - wifi_scannednetworks_scan_next_channel(scan); - return scan; + wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t); + self->current_scan = scan; + scan->base.type = &wifi_scannednetworks_type; + scan->start_channel = 1; + scan->end_channel = 11; + scan->radio_event_group = self->event_group_handle; + wifi_scannednetworks_scan_next_channel(scan); + return scan; } void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self) { - // Free the memory used to store the found aps. - ESP_EARLY_LOGI(TAG, "stop scan"); - wifi_scannednetworks_deinit(self->current_scan); - self->current_scan = NULL; - ESP_EARLY_LOGI(TAG, "stop scan done"); + // Free the memory used to store the found aps. + wifi_scannednetworks_deinit(self->current_scan); + self->current_scan = NULL; } bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout) { - // check enabled - wifi_config_t* config = &self->sta_config; - memcpy(&config->sta.ssid, ssid, ssid_len); - config->sta.ssid[ssid_len] = 0; - if (password_len > 0) { - memcpy(&config->sta.password, password, password_len); - } - config->sta.password[password_len] = 0; - config->sta.channel = channel; - ESP_EARLY_LOGI(TAG, "connecting to %s", config->sta.ssid); - esp_err_t result = esp_wifi_set_config(ESP_IF_WIFI_STA, config); - if (result != ESP_OK) { - ESP_EARLY_LOGI(TAG, "config fail %d", result); - } - result = esp_wifi_connect(); - if (result != ESP_OK) { - ESP_EARLY_LOGI(TAG, "connect fail %d", result); - } + // check enabled + wifi_config_t* config = &self->sta_config; + memcpy(&config->sta.ssid, ssid, ssid_len); + config->sta.ssid[ssid_len] = 0; + if (password_len > 0) { + memcpy(&config->sta.password, password, password_len); + } + config->sta.password[password_len] = 0; + config->sta.channel = channel; + esp_wifi_set_config(ESP_IF_WIFI_STA, config); + esp_wifi_connect(); - EventBits_t bits; + EventBits_t bits; do { RUN_BACKGROUND_TASKS; bits = xEventGroupWaitBits(self->event_group_handle, @@ -140,21 +125,18 @@ bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t 0); } while ((bits & (WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT)) == 0 && !mp_hal_is_interrupted()); if ((bits & WIFI_DISCONNECTED_BIT) != 0) { - return false; + return false; } - return true; + return true; } mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) { - if (!esp_netif_is_netif_up(self->netif)) { - return mp_const_none; - } - esp_netif_ip_info_t ip_info; - esp_err_t result = esp_netif_get_ip_info(self->netif, &ip_info); - if (result != ESP_OK) { - ESP_EARLY_LOGI(TAG, "get ip fail %d", result); - } - return common_hal_ipaddress_new_ipv4address(ip_info.ip.addr); + if (!esp_netif_is_netif_up(self->netif)) { + return mp_const_none; + } + esp_netif_ip_info_t ip_info; + esp_netif_get_ip_info(self->netif, &ip_info); + return common_hal_ipaddress_new_ipv4address(ip_info.ip.addr); } mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address, mp_float_t timeout) { @@ -171,15 +153,15 @@ mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address, uint32_t received = 0; uint32_t total_time_ms = 0; while (received == 0 && total_time_ms < timeout_ms) { - RUN_BACKGROUND_TASKS; - esp_ping_get_profile(ping, ESP_PING_PROF_DURATION, &total_time_ms, sizeof(total_time_ms)); - esp_ping_get_profile(ping, ESP_PING_PROF_REPLY, &received, sizeof(received)); + RUN_BACKGROUND_TASKS; + esp_ping_get_profile(ping, ESP_PING_PROF_DURATION, &total_time_ms, sizeof(total_time_ms)); + esp_ping_get_profile(ping, ESP_PING_PROF_REPLY, &received, sizeof(received)); } - uint32_t elapsed_time = 0xffffffff; + uint32_t elapsed_time = 0xffffffff; if (received > 0) { - esp_ping_get_profile(ping, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time)); + esp_ping_get_profile(ping, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time)); } esp_ping_delete_session(ping); - return elapsed_time; + return elapsed_time; } diff --git a/ports/esp32s2/common-hal/wifi/ScannedNetworks.c b/ports/esp32s2/common-hal/wifi/ScannedNetworks.c index 060e13f8ea..c13fef0718 100644 --- a/ports/esp32s2/common-hal/wifi/ScannedNetworks.c +++ b/ports/esp32s2/common-hal/wifi/ScannedNetworks.c @@ -39,12 +39,8 @@ #include "esp-idf/components/esp_wifi/include/esp_wifi.h" -#include "esp_log.h" -static const char *TAG = "cp scannednetworks"; - static void wifi_scannednetworks_done(wifi_scannednetworks_obj_t *self) { self->done = true; - ESP_EARLY_LOGI(TAG, "free %x", self->results); if (self->results != NULL) { // Check to see if the heap is still active. If not, it'll be freed automatically. if (gc_alloc_possible()) { @@ -94,7 +90,6 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) } // We not have found any more results so we're done. if (self->done) { - ESP_LOGI(TAG, "return done"); return mp_const_none; } // If we need more space than we have, realloc. @@ -104,7 +99,6 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) self->max_results, self->total_results, true /* allow move */); - ESP_EARLY_LOGI(TAG, "alloc %x", results); if (results != NULL) { self->results = results; self->max_results = self->total_results; @@ -152,12 +146,10 @@ void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self) { wifi_scan_config_t config = { 0 }; config.channel = next_channel; if (next_channel == sizeof(scan_pattern)) { - ESP_LOGI(TAG, "scan done"); wifi_scannednetworks_done(self); } else { esp_err_t result = esp_wifi_scan_start(&config, false); if (result != ESP_OK) { - ESP_LOGI(TAG, "start failed 0x%x", result); wifi_scannednetworks_done(self); } else { self->scanning = true; diff --git a/ports/esp32s2/common-hal/wifi/__init__.c b/ports/esp32s2/common-hal/wifi/__init__.c index b9147496b9..95b182288e 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.c +++ b/ports/esp32s2/common-hal/wifi/__init__.c @@ -31,9 +31,6 @@ #include "py/runtime.h" -#include "esp_log.h" -static const char *TAG = "cp wifi"; - #include "esp-idf/components/esp_wifi/include/esp_wifi.h" #include "esp-idf/components/heap/include/esp_heap_caps.h" @@ -42,31 +39,20 @@ wifi_radio_obj_t common_hal_wifi_radio_obj; static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - ESP_LOGI(TAG, "event %x", event_id); wifi_radio_obj_t* radio = arg; if (event_base == WIFI_EVENT) { if (event_id == WIFI_EVENT_SCAN_DONE) { - ESP_LOGI(TAG, "scan done"); xEventGroupSetBits(radio->event_group_handle, WIFI_SCAN_DONE_BIT); } else if (event_id == WIFI_EVENT_STA_START) { - ESP_LOGI(TAG, "station start"); - } else if (event_id == WIFI_EVENT_STA_STOP) { - ESP_LOGI(TAG, "station stop"); - } else if (event_id == WIFI_EVENT_STA_CONNECTED) { - ESP_LOGI(TAG, "connected to ap"); } else if (event_id == WIFI_EVENT_STA_DISCONNECTED) { - ESP_LOGI(TAG, "disconnected"); - wifi_event_sta_disconnected_t* d = (wifi_event_sta_disconnected_t*) event_data; - ESP_LOGI(TAG, "reason %d", d->reason); + // wifi_event_sta_disconnected_t* d = (wifi_event_sta_disconnected_t*) event_data; if (event_id != WIFI_REASON_ASSOC_LEAVE) { // reconnect } xEventGroupSetBits(radio->event_group_handle, WIFI_DISCONNECTED_BIT); } else if (event_id == WIFI_EVENT_STA_AUTHMODE_CHANGE) { - ESP_LOGI(TAG, "auth change"); - } } @@ -84,9 +70,6 @@ static void event_handler(void* arg, esp_event_base_t event_base, // ESP_LOGI(TAG,"connect to the AP fail"); // } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; - ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); - // s_retry_num = 0; xEventGroupSetBits(radio->event_group_handle, WIFI_CONNECTED_BIT); } } @@ -94,17 +77,12 @@ static void event_handler(void* arg, esp_event_base_t event_base, static bool wifi_inited; void common_hal_wifi_init(void) { - ESP_EARLY_LOGI(TAG, "init"); - heap_caps_print_heap_info(MALLOC_CAP_8BIT); wifi_inited = true; common_hal_wifi_radio_obj.base.type = &wifi_radio_type; ESP_ERROR_CHECK(esp_netif_init()); - - ESP_EARLY_LOGI(TAG, "create event loop"); ESP_ERROR_CHECK(esp_event_loop_create_default()); - ESP_EARLY_LOGI(TAG, "create wifi sta"); wifi_radio_obj_t* self = &common_hal_wifi_radio_obj; self->netif = esp_netif_create_default_wifi_sta(); @@ -120,8 +98,6 @@ void common_hal_wifi_init(void) { self, &self->handler_instance_got_ip)); - - ESP_EARLY_LOGI(TAG, "wifi init"); wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); esp_err_t result = esp_wifi_init(&config); if (result == ESP_ERR_NO_MEM) { @@ -129,12 +105,10 @@ void common_hal_wifi_init(void) { } else if (result != ESP_OK) { // handle this } - ESP_EARLY_LOGI(TAG, "enable radio"); common_hal_wifi_radio_set_enabled(self, true); } void wifi_reset(void) { - ESP_LOGI(TAG, "reset"); if (!wifi_inited) { return; } diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index bebecd8ae3..afd1234413 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -45,9 +45,6 @@ #include "esp-idf/components/heap/include/esp_heap_caps.h" -#include "esp_log.h" -static const char *TAG = "cp port"; - #define HEAP_SIZE (48 * 1024) STATIC esp_timer_handle_t _tick_timer; @@ -67,10 +64,6 @@ safe_mode_t port_init(void) { esp_timer_create(&args, &_tick_timer); heap = malloc(HEAP_SIZE); - if (heap == NULL) { - heap_caps_print_heap_info(MALLOC_CAP_8BIT); - ESP_LOGE(TAG, "failed to allocate heap"); - } never_reset_module_internal_pins(); return NO_SAFE_MODE; } @@ -92,7 +85,6 @@ void reset_port(void) { #if CIRCUITPY_WIFI wifi_reset(); #endif - heap_caps_print_heap_info(MALLOC_CAP_8BIT); } void reset_to_bootloader(void) { @@ -102,8 +94,6 @@ void reset_cpu(void) { } uint32_t *port_heap_get_bottom(void) { - - ESP_EARLY_LOGI(TAG, "heap %x", heap); return heap; } diff --git a/shared-bindings/socketpool/__init__.c b/shared-bindings/socketpool/__init__.c index 06d5be5cda..d3f8ba3028 100644 --- a/shared-bindings/socketpool/__init__.c +++ b/shared-bindings/socketpool/__init__.c @@ -33,8 +33,8 @@ #include "shared-bindings/socketpool/SocketPool.h" //| """ -//| The `ipaddress` module provides types for IP addresses. It is a subset of CPython's ipaddress -//| module. +//| The `socketpool` module provides sockets through a pool. The pools themselves +//| act like CPython's `socket` module. //| """ //| diff --git a/shared-bindings/ssl/__init__.c b/shared-bindings/ssl/__init__.c index fec4c76676..57f4e6f4af 100644 --- a/shared-bindings/ssl/__init__.c +++ b/shared-bindings/ssl/__init__.c @@ -56,14 +56,6 @@ STATIC const mp_rom_map_elem_t ssl_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_create_default_context), MP_ROM_PTR(&ssl_create_default_context_obj) }, { MP_ROM_QSTR(MP_QSTR_SSLContext), MP_ROM_PTR(&ssl_sslcontext_type) }, - - // class constants - // { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(SOCKETPOOL_AF_INET) }, - // { MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(SOCKETPOOL_AF_INET6) }, - - // { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(SOCKETPOOL_SOCK_STREAM) }, - // { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(SOCKETPOOL_SOCK_DGRAM) }, - // { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(SOCKETPOOL_SOCK_RAW) }, }; STATIC MP_DEFINE_CONST_DICT(ssl_globals, ssl_globals_table); From 9602ee6265ff20f6e075753bbb105578f680d519 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 18 Aug 2020 14:02:59 -0700 Subject: [PATCH 17/78] Disable wifi debug logging and memory log --- ports/esp32s2/sdkconfig.defaults | 9 +-------- supervisor/shared/memory.c | 4 ---- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/ports/esp32s2/sdkconfig.defaults b/ports/esp32s2/sdkconfig.defaults index 2faaa028c1..a50b61ebf4 100644 --- a/ports/esp32s2/sdkconfig.defaults +++ b/ports/esp32s2/sdkconfig.defaults @@ -354,14 +354,7 @@ CONFIG_ESP32_WIFI_RX_BA_WIN=6 # CONFIG_ESP32_WIFI_NVS_ENABLED is not set CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE=y -CONFIG_ESP32_WIFI_DEBUG_LOG_DEBUG=y -# CONFIG_ESP32_WIFI_DEBUG_LOG_VERBOSE is not set -# CONFIG_ESP32_WIFI_DEBUG_LOG_MODULE_ALL is not set -CONFIG_ESP32_WIFI_DEBUG_LOG_MODULE_WIFI=y -# CONFIG_ESP32_WIFI_DEBUG_LOG_MODULE_COEX is not set -# CONFIG_ESP32_WIFI_DEBUG_LOG_MODULE_MESH is not set -# CONFIG_ESP32_WIFI_DEBUG_LOG_SUBMODULE is not set +# CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE is not set CONFIG_ESP32_WIFI_IRAM_OPT=y CONFIG_ESP32_WIFI_RX_IRAM_OPT=y # CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE is not set diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c index 79bdeef9db..8ae8a16997 100755 --- a/supervisor/shared/memory.c +++ b/supervisor/shared/memory.c @@ -31,9 +31,6 @@ #include "supervisor/shared/display.h" -#include "esp_log.h" -static const char *TAG = "memory"; - #define CIRCUITPY_SUPERVISOR_ALLOC_COUNT (12) static supervisor_allocation allocations[CIRCUITPY_SUPERVISOR_ALLOC_COUNT]; @@ -42,7 +39,6 @@ uint32_t* low_address; uint32_t* high_address; void memory_init(void) { - ESP_LOGE(TAG, "memory init"); low_address = port_heap_get_bottom(); high_address = port_heap_get_top(); } From eb8b42aff1e887125dda56bafd2b52312c1c7e05 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 18 Aug 2020 17:06:59 -0700 Subject: [PATCH 18/78] Add basic error handling --- lib/tinyusb | 2 +- ports/esp32s2/bindings/espidf/__init__.c | 31 +++++++++++++ ports/esp32s2/bindings/espidf/__init__.h | 34 ++++++++++++++ ports/esp32s2/common-hal/socketpool/Socket.c | 29 ++++++++++-- ports/esp32s2/common-hal/socketpool/Socket.h | 1 + .../common-hal/socketpool/SocketPool.c | 21 ++++++++- py/modbuiltins.c | 3 ++ py/obj.h | 2 + py/objexcept.c | 10 ++-- py/runtime.c | 4 ++ py/runtime.h | 1 + shared-bindings/ipaddress/IPv4Address.c | 46 +++++++++++++------ shared-bindings/socketpool/Socket.c | 27 +++++++---- shared-bindings/socketpool/Socket.h | 2 + shared-bindings/socketpool/SocketPool.c | 10 +++- shared-bindings/socketpool/SocketPool.h | 2 + shared-bindings/ssl/SSLContext.c | 6 ++- shared-bindings/ssl/SSLContext.h | 11 ----- 18 files changed, 194 insertions(+), 48 deletions(-) create mode 100644 ports/esp32s2/bindings/espidf/__init__.h diff --git a/lib/tinyusb b/lib/tinyusb index 22100b252f..e90cf7a676 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 22100b252fc2eb8f51ed407949645653c4880fd9 +Subproject commit e90cf7a676eddcbd9c35d2d99a0a9cd14686e2ce diff --git a/ports/esp32s2/bindings/espidf/__init__.c b/ports/esp32s2/bindings/espidf/__init__.c index 11df76ec00..7c3a8c713d 100644 --- a/ports/esp32s2/bindings/espidf/__init__.c +++ b/ports/esp32s2/bindings/espidf/__init__.c @@ -27,6 +27,8 @@ #include "py/obj.h" #include "py/runtime.h" +#include "bindings/espidf/__init__.h" + #include "esp-idf/components/heap/include/esp_heap_caps.h" //| """Direct access to a few ESP-IDF details. This module *should not* include any functionality @@ -63,12 +65,41 @@ STATIC mp_obj_t espidf_heap_caps_get_largest_free_block(void) { } MP_DEFINE_CONST_FUN_OBJ_0(espidf_heap_caps_get_largest_free_block_obj, espidf_heap_caps_get_largest_free_block); +//| class MemoryError(MemoryError): +//| """Raised when an ESP IDF memory allocation fails.""" +//| ... +//| +NORETURN void mp_raise_espidf_MemoryError(void) { + nlr_raise(mp_obj_new_exception(&mp_type_espidf_MemoryError)); +} + +void espidf_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { + mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS; + bool is_subclass = kind & PRINT_EXC_SUBCLASS; + if (!is_subclass && (k == PRINT_EXC)) { + mp_print_str(print, qstr_str(MP_OBJ_QSTR_VALUE(MP_QSTR_espidf))); + mp_print_str(print, "."); + } + mp_obj_exception_print(print, o_in, kind); +} + +const mp_obj_type_t mp_type_espidf_MemoryError = { + { &mp_type_type }, + .name = MP_QSTR_MemoryError, + .print = espidf_exception_print, + .make_new = mp_obj_exception_make_new, + .attr = mp_obj_exception_attr, + .parent = &mp_type_MemoryError, +}; + STATIC const mp_rom_map_elem_t espidf_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_espidf) }, { MP_ROM_QSTR(MP_QSTR_heap_caps_get_total_size), MP_ROM_PTR(&espidf_heap_caps_get_total_size_obj)}, { MP_ROM_QSTR(MP_QSTR_heap_caps_get_free_size), MP_ROM_PTR(&espidf_heap_caps_get_free_size_obj)}, { MP_ROM_QSTR(MP_QSTR_heap_caps_get_largest_free_block), MP_ROM_PTR(&espidf_heap_caps_get_largest_free_block_obj)}, + + { MP_ROM_QSTR(MP_QSTR_MemoryError), MP_ROM_PTR(&mp_type_espidf_MemoryError) }, }; STATIC MP_DEFINE_CONST_DICT(espidf_module_globals, espidf_module_globals_table); diff --git a/ports/esp32s2/bindings/espidf/__init__.h b/ports/esp32s2/bindings/espidf/__init__.h new file mode 100644 index 0000000000..356c1c8140 --- /dev/null +++ b/ports/esp32s2/bindings/espidf/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_BINDINGS_ESPIDF___INIT___H +#define MICROPY_INCLUDED_ESP32S2_BINDINGS_ESPIDF___INIT___H + +extern const mp_obj_type_t mp_type_espidf_MemoryError; + +NORETURN void mp_raise_espidf_MemoryError(void); + +#endif // MICROPY_INCLUDED_ESP32S2_BINDINGS_ESPIDF___INIT___H diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c index b9c6dca6ff..36018b3d14 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.c +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -26,6 +26,9 @@ #include "shared-bindings/socketpool/Socket.h" +#include "py/mperrno.h" +#include "py/runtime.h" + void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms) { self->timeout_ms = timeout_ms; } @@ -40,14 +43,26 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const c tls_config = &self->ssl_context->ssl_config; } int result = esp_tls_conn_new_sync(host, hostlen, port, tls_config, self->tcp); - return result >= 0; + self->connected = result >= 0; + if (result < 0) { + int esp_tls_code; + esp_tls_get_and_clear_last_error(self->tcp->error_handle, &esp_tls_code, NULL); + + // mp_raise_espidf_MemoryError + mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d"), esp_tls_code); + } + return self->connected; +} + +bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t* self) { + return self->connected; } mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { size_t sent = esp_tls_conn_write(self->tcp, buf, len); if (sent < 0) { - // raise an error + mp_raise_OSError(MP_ENOTCONN); } return sent; } @@ -57,14 +72,18 @@ mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, if (received == 0) { // socket closed + common_hal_socketpool_socket_close(self); } if (received < 0) { - // raise an error + mp_raise_BrokenPipeError(); } return received; } void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) { + if (self->connected) { + self->connected = false; + } if (self->tcp != NULL) { int status = esp_tls_conn_destroy(self->tcp); @@ -74,3 +93,7 @@ void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) { self->tcp = NULL; } } + +bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t* self) { + return self->tcp == NULL; +} diff --git a/ports/esp32s2/common-hal/socketpool/Socket.h b/ports/esp32s2/common-hal/socketpool/Socket.h index ba832faac2..c23dd171cf 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.h +++ b/ports/esp32s2/common-hal/socketpool/Socket.h @@ -37,6 +37,7 @@ typedef struct { mp_obj_base_t base; int num; + bool connected; esp_tls_t* tcp; ssl_sslcontext_obj_t* ssl_context; socketpool_socketpool_obj_t* pool; diff --git a/ports/esp32s2/common-hal/socketpool/SocketPool.c b/ports/esp32s2/common-hal/socketpool/SocketPool.c index 0b9c1776bf..2af5bf7221 100644 --- a/ports/esp32s2/common-hal/socketpool/SocketPool.c +++ b/ports/esp32s2/common-hal/socketpool/SocketPool.c @@ -27,9 +27,19 @@ #include "shared-bindings/socketpool/SocketPool.h" #include "py/runtime.h" +#include "shared-bindings/wifi/__init__.h" #include "esp-idf/components/lwip/lwip/src/include/lwip/netdb.h" +#include "bindings/espidf/__init__.h" + + +void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t* self, mp_obj_t radio) { + if (radio != MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj)) { + mp_raise_ValueError(translate("SocketPool can only be used with wifi.radio.")); + } +} + socketpool_socket_obj_t* common_hal_socketpool_socket(socketpool_socketpool_obj_t* self, socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type) { @@ -52,12 +62,21 @@ socketpool_socket_obj_t* common_hal_socketpool_socket(socketpool_socketpool_obj_ socket_type = SOCK_RAW; } + if (socket_type == SOCK_DGRAM || socket_type == SOCK_RAW || + addr_family == AF_INET6 || ipproto == IPPROTO_IPV6) { + mp_raise_NotImplementedError(translate("Only IPv4 SOCK_STREAM sockets supported.")); + } + int socknum = -1; esp_tls_t* tcp_handle = NULL; if (socket_type == SOCK_DGRAM || socket_type == SOCK_RAW) { - socknum = lwip_socket(addr_family, socket_type, ipproto); + // socknum = lwip_socket(addr_family, socket_type, ipproto); } else { tcp_handle = esp_tls_init(); + + if (tcp_handle == NULL) { + mp_raise_espidf_MemoryError(); + } } if (socknum < 0 && tcp_handle == NULL) { mp_raise_RuntimeError(translate("Out of sockets")); diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 905c3471f1..41e1d4e488 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -726,6 +726,9 @@ STATIC const mp_rom_map_elem_t mp_module_builtins_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_NameError), MP_ROM_PTR(&mp_type_NameError) }, { MP_ROM_QSTR(MP_QSTR_NotImplementedError), MP_ROM_PTR(&mp_type_NotImplementedError) }, { MP_ROM_QSTR(MP_QSTR_OSError), MP_ROM_PTR(&mp_type_OSError) }, + { MP_ROM_QSTR(MP_QSTR_TimeoutError), MP_ROM_PTR(&mp_type_TimeoutError) }, + { MP_ROM_QSTR(MP_QSTR_ConnectionError), MP_ROM_PTR(&mp_type_ConnectionError) }, + { MP_ROM_QSTR(MP_QSTR_BrokenPipeError), MP_ROM_PTR(&mp_type_BrokenPipeError) }, { MP_ROM_QSTR(MP_QSTR_OverflowError), MP_ROM_PTR(&mp_type_OverflowError) }, { MP_ROM_QSTR(MP_QSTR_RuntimeError), MP_ROM_PTR(&mp_type_RuntimeError) }, #if MICROPY_PY_ASYNC_AWAIT diff --git a/py/obj.h b/py/obj.h index e9d867f77b..c5ef74ef3f 100644 --- a/py/obj.h +++ b/py/obj.h @@ -604,6 +604,8 @@ extern const mp_obj_type_t mp_type_NameError; extern const mp_obj_type_t mp_type_NotImplementedError; extern const mp_obj_type_t mp_type_OSError; extern const mp_obj_type_t mp_type_TimeoutError; +extern const mp_obj_type_t mp_type_ConnectionError; +extern const mp_obj_type_t mp_type_BrokenPipeError; extern const mp_obj_type_t mp_type_OverflowError; extern const mp_obj_type_t mp_type_RuntimeError; extern const mp_obj_type_t mp_type_StopAsyncIteration; diff --git a/py/objexcept.c b/py/objexcept.c index e3b953543e..01ba6da9c4 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -282,15 +282,17 @@ MP_DEFINE_EXCEPTION(Exception, BaseException) MP_DEFINE_EXCEPTION(UnboundLocalError, NameError) */ MP_DEFINE_EXCEPTION(OSError, Exception) - MP_DEFINE_EXCEPTION(TimeoutError, OSError) - /* - MP_DEFINE_EXCEPTION(BlockingIOError, OSError) - MP_DEFINE_EXCEPTION(ChildProcessError, OSError) + MP_DEFINE_EXCEPTION(TimeoutError, OSError) MP_DEFINE_EXCEPTION(ConnectionError, OSError) MP_DEFINE_EXCEPTION(BrokenPipeError, ConnectionError) + /* MP_DEFINE_EXCEPTION(ConnectionAbortedError, ConnectionError) MP_DEFINE_EXCEPTION(ConnectionRefusedError, ConnectionError) MP_DEFINE_EXCEPTION(ConnectionResetError, ConnectionError) + */ + /* + MP_DEFINE_EXCEPTION(BlockingIOError, OSError) + MP_DEFINE_EXCEPTION(ChildProcessError, OSError) MP_DEFINE_EXCEPTION(InterruptedError, OSError) MP_DEFINE_EXCEPTION(IsADirectoryError, OSError) MP_DEFINE_EXCEPTION(NotADirectoryError, OSError) diff --git a/py/runtime.c b/py/runtime.c index f9ef7819d1..216432ea42 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1602,6 +1602,10 @@ NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...) { va_end(argptr); } +NORETURN void mp_raise_BrokenPipeError(void) { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_BrokenPipeError, MP_OBJ_NEW_SMALL_INT(MP_EPIPE))); +} + NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_NotImplementedError, msg); } diff --git a/py/runtime.h b/py/runtime.h index dbc04b94ec..c5d07c4175 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -166,6 +166,7 @@ NORETURN void mp_raise_OSError(int errno_); NORETURN void mp_raise_OSError_errno_str(int errno_, mp_obj_t str); NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg); NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...); +NORETURN void mp_raise_BrokenPipeError(void); NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg); NORETURN void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, ...); NORETURN void mp_raise_OverflowError_varg(const compressed_string_t *fmt, ...); diff --git a/shared-bindings/ipaddress/IPv4Address.c b/shared-bindings/ipaddress/IPv4Address.c index 3cef7516df..29536dfa43 100644 --- a/shared-bindings/ipaddress/IPv4Address.c +++ b/shared-bindings/ipaddress/IPv4Address.c @@ -25,22 +25,24 @@ * THE SOFTWARE. */ +#include "shared-bindings/ipaddress/IPv4Address.h" + #include #include #include "py/objproperty.h" #include "py/objstr.h" #include "py/runtime.h" -#include "shared-bindings/ipaddress/IPv4Address.h" +#include "shared-bindings/ipaddress/__init__.h" //| class IPv4Address: //| """Encapsulates an IPv4 address.""" //| -//| def __init__(self, address: Union[str, int]) -> None: -//| """Create a new Address object encapsulating the address value. +//| def __init__(self, address: Union[str, bytes]) -> None: +//| """Create a new IPv4Address object encapsulating the address value. //| -//| The value itself can be one of:""" +//| The value itself can either be bytes or a string formatted address."" //| ... //| STATIC mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -52,17 +54,33 @@ STATIC mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + const mp_obj_t address = args[ARG_address].u_obj; + + uint32_t value; + uint8_t* buf = NULL; + if (mp_obj_get_int_maybe(address, (mp_int_t*) &value)) { + // We're done. + buf = (uint8_t*) value; + } else if (MP_OBJ_IS_STR(address)) { + GET_STR_DATA_LEN(address, str_data, str_len); + if (!ipaddress_parse_ipv4address((const char*) str_data, str_len, &value)) { + mp_raise_ValueError(translate("Not a valid IP string.")); + } + } else { + mp_buffer_info_t buf_info; + if (mp_get_buffer(address, &buf_info, MP_BUFFER_READ)) { + if (buf_info.len != 4) { + mp_raise_ValueError_varg(translate("Address must be %d bytes long"), 4); + } + buf = buf_info.buf; + } + } + + ipaddress_ipv4address_obj_t *self = m_new_obj(ipaddress_ipv4address_obj_t); self->base.type = &ipaddress_ipv4address_type; - const mp_obj_t address = args[ARG_address].u_obj; - mp_buffer_info_t buf_info; - mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); - if (buf_info.len != 4) { - mp_raise_ValueError_varg(translate("Address must be %d bytes long"), 4); - } - - common_hal_ipaddress_ipv4address_construct(self, buf_info.buf, buf_info.len); + common_hal_ipaddress_ipv4address_construct(self, buf, 4); return MP_OBJ_FROM_PTR(self); } @@ -108,7 +126,7 @@ const mp_obj_property_t ipaddress_ipv4address_version_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//| def __eq__(self, other: Address) -> bool: +//| def __eq__(self, other: IPv4Address) -> bool: //| """Two Address objects are equal if their addresses and address types are equal.""" //| ... //| @@ -133,7 +151,7 @@ STATIC mp_obj_t ipaddress_ipv4address_binary_op(mp_binary_op_t op, mp_obj_t lhs_ } //| def __hash__(self) -> int: -//| """Returns a hash for the Address data.""" +//| """Returns a hash for the IPv4Address data.""" //| ... //| STATIC mp_obj_t ipaddress_ipv4address_unary_op(mp_unary_op_t op, mp_obj_t self_in) { diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index 64a051301c..ddead95078 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -57,7 +57,7 @@ //| STATIC mp_obj_t socketpool_socket___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; - // common_hal_pulseio_pwmout_deinit(args[0]); + common_hal_socketpool_socket_close(args[0]); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket___exit___obj, 4, 4, socketpool_socket___exit__); @@ -197,15 +197,18 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_connect_obj, socketpool_socke STATIC mp_obj_t socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); - // if (self->nic == MP_OBJ_NULL) { - // // not connected - // mp_raise_OSError(MP_EPIPE); - // } + if (common_hal_socketpool_socket_get_closed(self)) { + // Bad file number. + mp_raise_OSError(MP_EBADF); + } + if (!common_hal_socketpool_socket_get_connected(self)) { + mp_raise_BrokenPipeError(); + } mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); mp_int_t ret = common_hal_socketpool_socket_send(self, bufinfo.buf, bufinfo.len); if (ret == -1) { - mp_raise_OSError(0); + mp_raise_BrokenPipeError(); } return mp_obj_new_int_from_uint(ret); } @@ -241,10 +244,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, socketpool_socket_s STATIC mp_obj_t socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); - // if (self->nic == MP_OBJ_NULL) { - // // not connected - // mp_raise_OSError(MP_ENOTCONN); - // } + if (common_hal_socketpool_socket_get_closed(self)) { + // Bad file number. + mp_raise_OSError(MP_EBADF); + } + if (!common_hal_socketpool_socket_get_connected(self)) { + // not connected + mp_raise_OSError(MP_ENOTCONN); + } mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); mp_int_t len = bufinfo.len; diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h index a1aeccbe3e..4597aed38d 100644 --- a/shared-bindings/socketpool/Socket.h +++ b/shared-bindings/socketpool/Socket.h @@ -36,5 +36,7 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const c mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len); mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len); void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self); +bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t* self); +bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t* self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H diff --git a/shared-bindings/socketpool/SocketPool.c b/shared-bindings/socketpool/SocketPool.c index 2be071c789..f8812f61f1 100644 --- a/shared-bindings/socketpool/SocketPool.c +++ b/shared-bindings/socketpool/SocketPool.c @@ -38,15 +38,21 @@ #include "shared-bindings/socketpool/SocketPool.h" //| class SocketPool: +//| """A pool of socket resources available for the given radio. Only one +//| SocketPool can be created for each radio. +//| +//| SocketPool should be used in place of CPython's socket which provides +//| a pool of sockets provided by the underlying OS.""" //| STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - mp_arg_check_num(n_args, kw_args, 0, 4, false); + mp_arg_check_num(n_args, kw_args, 1, 1, false); socketpool_socketpool_obj_t *s = m_new_obj_with_finaliser(socketpool_socketpool_obj_t); s->base.type = &socketpool_socketpool_type; + mp_obj_t radio = args[1]; - // common_hal_socketpool_socketpool_construct(s, ); + common_hal_socketpool_socketpool_construct(s, radio); return MP_OBJ_FROM_PTR(s); } diff --git a/shared-bindings/socketpool/SocketPool.h b/shared-bindings/socketpool/SocketPool.h index 42bd885185..b007aad8f4 100644 --- a/shared-bindings/socketpool/SocketPool.h +++ b/shared-bindings/socketpool/SocketPool.h @@ -44,6 +44,8 @@ typedef enum { SOCKETPOOL_AF_INET6 } socketpool_socketpool_addressfamily_t; +void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t* self, mp_obj_t radio); + socketpool_socket_obj_t* common_hal_socketpool_socket(socketpool_socketpool_obj_t* self, socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type); diff --git a/shared-bindings/ssl/SSLContext.c b/shared-bindings/ssl/SSLContext.c index d47baf3455..5d44dc0f54 100644 --- a/shared-bindings/ssl/SSLContext.c +++ b/shared-bindings/ssl/SSLContext.c @@ -3,8 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George - * 2018 Nick Moore for Adafruit Industries + * SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,6 +35,9 @@ #include "shared-bindings/ssl/SSLContext.h" //| class SSLContext: +//| """Settings related to SSL that can be applied to a socket by wrapping it. +//| This is useful to provide SSL certificates to specific connections +//| rather than all of them.""" //| STATIC mp_obj_t ssl_sslcontext_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { diff --git a/shared-bindings/ssl/SSLContext.h b/shared-bindings/ssl/SSLContext.h index 3bb1391164..f7f985af70 100644 --- a/shared-bindings/ssl/SSLContext.h +++ b/shared-bindings/ssl/SSLContext.h @@ -33,17 +33,6 @@ extern const mp_obj_type_t ssl_sslcontext_type; -// typedef enum { -// SOCKETPOOL_SOCK_STREAM, -// SOCKETPOOL_SOCK_DGRAM, -// SOCKETPOOL_SOCK_RAW -// } socketpool_socketpool_sock_t; - -// typedef enum { -// SOCKETPOOL_AF_INET, -// SOCKETPOOL_AF_INET6 -// } socketpool_socketpool_addressfamily_t; - void common_hal_ssl_sslcontext_construct(ssl_sslcontext_obj_t* self); socketpool_socket_obj_t* common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t* self, From 80b15f6b3b8bc513e8edcec48a0c97205be27fd3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 19 Aug 2020 17:51:33 -0700 Subject: [PATCH 19/78] Add error handling w/temp debug logs --- ports/esp32s2/common-hal/socketpool/Socket.c | 43 +++++++++++++++++--- ports/esp32s2/common-hal/wifi/Radio.c | 5 +++ ports/esp32s2/common-hal/wifi/__init__.c | 12 +++++- shared-bindings/socketpool/Socket.c | 9 ++++ shared-bindings/socketpool/SocketPool.c | 4 ++ shared-bindings/wifi/Radio.c | 6 ++- 6 files changed, 71 insertions(+), 8 deletions(-) diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c index 36018b3d14..074d9885f3 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.c +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -26,8 +26,13 @@ #include "shared-bindings/socketpool/Socket.h" +#include "lib/utils/interrupt_char.h" #include "py/mperrno.h" #include "py/runtime.h" +#include "supervisor/shared/tick.h" + +#include "esp_log.h" +static const char* TAG = "socket"; void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms) { self->timeout_ms = timeout_ms; @@ -43,13 +48,15 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const c tls_config = &self->ssl_context->ssl_config; } int result = esp_tls_conn_new_sync(host, hostlen, port, tls_config, self->tcp); + ESP_EARLY_LOGW(TAG, "connect result %d", result); self->connected = result >= 0; if (result < 0) { int esp_tls_code; - esp_tls_get_and_clear_last_error(self->tcp->error_handle, &esp_tls_code, NULL); + int flags; + esp_err_t err = esp_tls_get_and_clear_last_error(self->tcp->error_handle, &esp_tls_code, &flags); // mp_raise_espidf_MemoryError - mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d"), esp_tls_code); + mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x"), esp_tls_code, flags, err); } return self->connected; } @@ -68,19 +75,44 @@ mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const } mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { - size_t received = esp_tls_conn_read(self->tcp, (void*) buf, len); + size_t received = 0; + ssize_t last_read = 1; + uint64_t start_ticks = supervisor_ticks_ms64(); + while (received < len && + last_read > 0 && + (self->timeout_ms == 0 || supervisor_ticks_ms64() - start_ticks <= self->timeout_ms) && + !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + size_t available = esp_tls_get_bytes_avail(self->tcp); + ESP_EARLY_LOGW(TAG, "available %d", available); + size_t remaining = len - received; + if (available > remaining) { + available = remaining; + } + if (true || available > 0) { + if (available == 0) { + available = len - received; + } + last_read = esp_tls_conn_read(self->tcp, (void*) buf + received, available); + ESP_EARLY_LOGW(TAG, "read %d out of %d", last_read, available); + received += last_read; + } + } - if (received == 0) { + if (last_read == 0) { // socket closed + ESP_EARLY_LOGW(TAG, "receive close %d %d", received, len); common_hal_socketpool_socket_close(self); } - if (received < 0) { + if (last_read < 0) { + // ESP_EARLY_LOGI(TAG, "received %d", received); mp_raise_BrokenPipeError(); } return received; } void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) { + // ESP_EARLY_LOGW(TAG, "close"); if (self->connected) { self->connected = false; } @@ -95,5 +127,6 @@ void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) { } bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t* self) { + // ESP_EARLY_LOGW(TAG, "tcp %p", self->tcp); return self->tcp == NULL; } diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c index 0f97565da0..be8e7e6d9f 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.c +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -38,6 +38,9 @@ #include "esp-idf/components/esp_wifi/include/esp_wifi.h" #include "esp-idf/components/lwip/include/apps/ping/ping_sock.h" +#include "esp_log.h" +static const char* TAG = "radio"; + static void start_station(wifi_radio_obj_t *self) { if (self->sta_mode) { return; @@ -160,6 +163,8 @@ mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address, uint32_t elapsed_time = 0xffffffff; if (received > 0) { esp_ping_get_profile(ping, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time)); + } else { + ESP_EARLY_LOGW(TAG, "received none - time %d timeout %d", total_time_ms, timeout_ms); } esp_ping_delete_session(ping); diff --git a/ports/esp32s2/common-hal/wifi/__init__.c b/ports/esp32s2/common-hal/wifi/__init__.c index 95b182288e..f845e092fc 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.c +++ b/ports/esp32s2/common-hal/wifi/__init__.c @@ -37,6 +37,9 @@ wifi_radio_obj_t common_hal_wifi_radio_obj; +#include "esp_log.h" +static const char* TAG = "wifi"; + static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { wifi_radio_obj_t* radio = arg; @@ -46,11 +49,15 @@ static void event_handler(void* arg, esp_event_base_t event_base, } else if (event_id == WIFI_EVENT_STA_START) { } else if (event_id == WIFI_EVENT_STA_STOP) { } else if (event_id == WIFI_EVENT_STA_CONNECTED) { + ESP_EARLY_LOGW(TAG, "connected"); } else if (event_id == WIFI_EVENT_STA_DISCONNECTED) { - // wifi_event_sta_disconnected_t* d = (wifi_event_sta_disconnected_t*) event_data; - if (event_id != WIFI_REASON_ASSOC_LEAVE) { + ESP_EARLY_LOGW(TAG, "disconnected"); + wifi_event_sta_disconnected_t* d = (wifi_event_sta_disconnected_t*) event_data; + uint8_t reason = d->reason; + if (reason != WIFI_REASON_ASSOC_LEAVE) { // reconnect } + ESP_EARLY_LOGW(TAG, "reason %d 0x%02x", reason, reason); xEventGroupSetBits(radio->event_group_handle, WIFI_DISCONNECTED_BIT); } else if (event_id == WIFI_EVENT_STA_AUTHMODE_CHANGE) { } @@ -70,6 +77,7 @@ static void event_handler(void* arg, esp_event_base_t event_base, // ESP_LOGI(TAG,"connect to the AP fail"); // } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ESP_EARLY_LOGW(TAG, "got ip"); xEventGroupSetBits(radio->event_group_handle, WIFI_CONNECTED_BIT); } } diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index ddead95078..932e8e856c 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -36,6 +36,9 @@ #include "py/runtime.h" #include "py/mperrno.h" +#include "esp_log.h" +static const char* TAG = "socket binding"; + //| class Socket: //| """TCP, UDP and RAW socket. Cannot be created directly. Instead, call //| `SocketPool.socket()`. @@ -180,6 +183,7 @@ STATIC mp_obj_t socketpool_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { bool ok = common_hal_socketpool_socket_connect(self, host, hostlen, port); if (!ok) { + ESP_EARLY_LOGW(TAG, "socket connect failed"); mp_raise_OSError(0); } @@ -262,6 +266,11 @@ STATIC mp_obj_t socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args) } } + if (len == 0) { + ESP_EARLY_LOGW(TAG, "len 0"); + mp_raise_OSError(0); + } + mp_int_t ret = common_hal_socketpool_socket_recv_into(self, (byte*)bufinfo.buf, len); return mp_obj_new_int_from_uint(ret); } diff --git a/shared-bindings/socketpool/SocketPool.c b/shared-bindings/socketpool/SocketPool.c index f8812f61f1..579a4824c8 100644 --- a/shared-bindings/socketpool/SocketPool.c +++ b/shared-bindings/socketpool/SocketPool.c @@ -37,6 +37,9 @@ #include "shared-bindings/socketpool/Socket.h" #include "shared-bindings/socketpool/SocketPool.h" +#include "esp_log.h" +static const char* TAG = "socketpool binding"; + //| class SocketPool: //| """A pool of socket resources available for the given radio. Only one //| SocketPool can be created for each radio. @@ -119,6 +122,7 @@ STATIC mp_obj_t socketpool_socketpool_getaddrinfo(size_t n_args, const mp_obj_t } if (ip_str == mp_const_none) { + ESP_EARLY_LOGW(TAG, "no ip str"); mp_raise_OSError(0); } diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index 260a280c2b..6fd0c33744 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -159,7 +159,8 @@ const mp_obj_property_t wifi_radio_ipv4_address_obj = { }; //| def ping(self, ip, *, timeout: float = 0.5) -> float: -//| """Ping an IP to test connectivity. Returns echo time in seconds.""" +//| """Ping an IP to test connectivity. Returns echo time in seconds. +//| Returns None when it times out.""" //| ... //| STATIC mp_obj_t wifi_radio_ping(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -179,6 +180,9 @@ STATIC mp_obj_t wifi_radio_ping(size_t n_args, const mp_obj_t *pos_args, mp_map_ } mp_int_t time_ms = common_hal_wifi_radio_ping(self, args[ARG_ip].u_obj, timeout); + if (time_ms == -1) { + return mp_const_none; + } return mp_obj_new_float(time_ms / 1000.0); } From 701e80a0252dbb63d64830a8d55f76b6296cb647 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 21 Aug 2020 11:00:02 -0700 Subject: [PATCH 20/78] Make socket reads interruptable --- ports/esp32s2/common-hal/socketpool/Socket.c | 32 +++++++++++++++----- ports/esp32s2/common-hal/wifi/Radio.c | 13 ++++++-- ports/esp32s2/common-hal/wifi/Radio.h | 3 ++ ports/esp32s2/common-hal/wifi/__init__.c | 20 ++++++++++-- ports/esp32s2/sdkconfig.defaults | 2 +- py/runtime.c | 4 +++ py/runtime.h | 1 + shared-bindings/wifi/Radio.c | 14 ++++++++- shared-bindings/wifi/Radio.h | 10 +++++- 9 files changed, 82 insertions(+), 17 deletions(-) diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c index 074d9885f3..db8356f66f 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.c +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -55,9 +55,13 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const c int flags; esp_err_t err = esp_tls_get_and_clear_last_error(self->tcp->error_handle, &esp_tls_code, &flags); - // mp_raise_espidf_MemoryError - mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x"), esp_tls_code, flags, err); + if (err == ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) { + mp_raise_espidf_MemoryError(); + } else { + mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x"), esp_tls_code, flags, err); + } } + return self->connected; } @@ -78,23 +82,35 @@ mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, size_t received = 0; ssize_t last_read = 1; uint64_t start_ticks = supervisor_ticks_ms64(); + int sockfd; + esp_err_t err = esp_tls_get_conn_sockfd(self->tcp, &sockfd); + if (err != ESP_OK) { + mp_raise_OSError(MP_EBADF); + } while (received < len && last_read > 0 && (self->timeout_ms == 0 || supervisor_ticks_ms64() - start_ticks <= self->timeout_ms) && !mp_hal_is_interrupted()) { RUN_BACKGROUND_TASKS; size_t available = esp_tls_get_bytes_avail(self->tcp); - ESP_EARLY_LOGW(TAG, "available %d", available); + if (available == 0) { + // This reads the raw socket buffer and is used for non-TLS connections + // and between encrypted TLS blocks. + int status = lwip_ioctl(sockfd, FIONREAD, &available); + if (status < 0) { + // ESP_EARLY_LOGW(TAG, "ioctl fail. socket %d status %d errno %d available %d", sockfd, status, errno, available); + last_read = status; + break; + } + } + // ESP_EARLY_LOGW(TAG, "available %d", available); size_t remaining = len - received; if (available > remaining) { available = remaining; } - if (true || available > 0) { - if (available == 0) { - available = len - received; - } + if (available > 0) { last_read = esp_tls_conn_read(self->tcp, (void*) buf + received, available); - ESP_EARLY_LOGW(TAG, "read %d out of %d", last_read, available); + // ESP_EARLY_LOGW(TAG, "read %d out of %d", last_read, available); received += last_read; } } diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c index be8e7e6d9f..038ce9e754 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.c +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -105,7 +105,7 @@ void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self) { self->current_scan = NULL; } -bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout) { +wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout) { // check enabled wifi_config_t* config = &self->sta_config; memcpy(&config->sta.ssid, ssid, ssid_len); @@ -116,6 +116,8 @@ bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t config->sta.password[password_len] = 0; config->sta.channel = channel; esp_wifi_set_config(ESP_IF_WIFI_STA, config); + self->starting_retries = 5; + self->retries_left = 5; esp_wifi_connect(); EventBits_t bits; @@ -128,9 +130,14 @@ bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t 0); } while ((bits & (WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT)) == 0 && !mp_hal_is_interrupted()); if ((bits & WIFI_DISCONNECTED_BIT) != 0) { - return false; + if (self->last_disconnect_reason == WIFI_REASON_AUTH_FAIL) { + return WIFI_RADIO_ERROR_AUTH; + } else if (self->last_disconnect_reason == WIFI_REASON_NO_AP_FOUND) { + return WIFI_RADIO_ERROR_NO_AP_FOUND; + } + return WIFI_RADIO_ERROR_UNKNOWN; } - return true; + return WIFI_RADIO_ERROR_NONE; } mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) { diff --git a/ports/esp32s2/common-hal/wifi/Radio.h b/ports/esp32s2/common-hal/wifi/Radio.h index e7dce94776..205aef1761 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.h +++ b/ports/esp32s2/common-hal/wifi/Radio.h @@ -50,6 +50,9 @@ typedef struct { bool started; bool ap_mode; bool sta_mode; + uint8_t retries_left; + uint8_t starting_retries; + uint8_t last_disconnect_reason; } wifi_radio_obj_t; #endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_RADIO_H diff --git a/ports/esp32s2/common-hal/wifi/__init__.c b/ports/esp32s2/common-hal/wifi/__init__.c index f845e092fc..d455679467 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.c +++ b/ports/esp32s2/common-hal/wifi/__init__.c @@ -54,11 +54,24 @@ static void event_handler(void* arg, esp_event_base_t event_base, ESP_EARLY_LOGW(TAG, "disconnected"); wifi_event_sta_disconnected_t* d = (wifi_event_sta_disconnected_t*) event_data; uint8_t reason = d->reason; - if (reason != WIFI_REASON_ASSOC_LEAVE) { - // reconnect - } ESP_EARLY_LOGW(TAG, "reason %d 0x%02x", reason, reason); + if (radio->retries_left > 0 && + (reason == WIFI_REASON_AUTH_EXPIRE || + reason == WIFI_REASON_ASSOC_EXPIRE || + reason == WIFI_REASON_CONNECTION_FAIL || + reason == WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT)) { + radio->retries_left--; + ESP_EARLY_LOGI(TAG, "Retrying connect. %d retries remaining", radio->retries_left); + esp_wifi_connect(); + return; + } + + radio->last_disconnect_reason = reason; xEventGroupSetBits(radio->event_group_handle, WIFI_DISCONNECTED_BIT); + + // if (reason != WIFI_REASON_ASSOC_LEAVE) { + // // reconnect + // } } else if (event_id == WIFI_EVENT_STA_AUTHMODE_CHANGE) { } } @@ -78,6 +91,7 @@ static void event_handler(void* arg, esp_event_base_t event_base, // } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { ESP_EARLY_LOGW(TAG, "got ip"); + radio->retries_left = radio->starting_retries; xEventGroupSetBits(radio->event_group_handle, WIFI_CONNECTED_BIT); } } diff --git a/ports/esp32s2/sdkconfig.defaults b/ports/esp32s2/sdkconfig.defaults index a50b61ebf4..c0a56c1432 100644 --- a/ports/esp32s2/sdkconfig.defaults +++ b/ports/esp32s2/sdkconfig.defaults @@ -452,7 +452,7 @@ CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# CONFIG_LWIP_SO_RCVBUF is not set +CONFIG_LWIP_SO_RCVBUF=y # CONFIG_LWIP_NETBUF_RECVINFO is not set CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y diff --git a/py/runtime.c b/py/runtime.c index 216432ea42..e63e2337d9 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1602,6 +1602,10 @@ NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...) { va_end(argptr); } +NORETURN void mp_raise_ConnectionError(const compressed_string_t *msg) { + mp_raise_msg(&mp_type_ConnectionError, msg); +} + NORETURN void mp_raise_BrokenPipeError(void) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_BrokenPipeError, MP_OBJ_NEW_SMALL_INT(MP_EPIPE))); } diff --git a/py/runtime.h b/py/runtime.h index c5d07c4175..ad7d0feaba 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -166,6 +166,7 @@ NORETURN void mp_raise_OSError(int errno_); NORETURN void mp_raise_OSError_errno_str(int errno_, mp_obj_t str); NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg); NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...); +NORETURN void mp_raise_ConnectionError(const compressed_string_t *msg); NORETURN void mp_raise_BrokenPipeError(void); NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg); NORETURN void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, ...); diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index 6fd0c33744..2d356e5d96 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -136,9 +136,21 @@ STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_m password.len = 0; if (args[ARG_password].u_obj != MP_OBJ_NULL) { mp_get_buffer_raise(args[ARG_password].u_obj, &password, MP_BUFFER_READ); + if (password.len > 0 && (password.len < 8 || password.len > 63)) { + mp_raise_ValueError(translate("WiFi password must be between 8 and 63 characters.")); + } } - return mp_obj_new_bool(common_hal_wifi_radio_connect(self, ssid.buf, ssid.len, password.buf, password.len, args[ARG_channel].u_int, timeout)); + wifi_radio_error_t error = common_hal_wifi_radio_connect(self, ssid.buf, ssid.len, password.buf, password.len, args[ARG_channel].u_int, timeout); + if (error == WIFI_RADIO_ERROR_AUTH) { + mp_raise_ConnectionError(translate("Authentication failure")); + } else if (error == WIFI_RADIO_ERROR_NO_AP_FOUND) { + mp_raise_ConnectionError(translate("No network with that ssid")); + } else if (error != WIFI_RADIO_ERROR_NONE) { + mp_raise_ConnectionError(translate("Unknown failure")); + } + + return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_connect_obj, 1, wifi_radio_connect); diff --git a/shared-bindings/wifi/Radio.h b/shared-bindings/wifi/Radio.h index c83a135a6a..812814f9ea 100644 --- a/shared-bindings/wifi/Radio.h +++ b/shared-bindings/wifi/Radio.h @@ -35,6 +35,14 @@ const mp_obj_type_t wifi_radio_type; + +typedef enum { + WIFI_RADIO_ERROR_NONE, + WIFI_RADIO_ERROR_UNKNOWN, + WIFI_RADIO_ERROR_AUTH, + WIFI_RADIO_ERROR_NO_AP_FOUND +} wifi_radio_error_t; + extern bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled); @@ -43,7 +51,7 @@ extern mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self); extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self); -extern bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout); +extern wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout); extern mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self); From da61845f565ee7c5c00a15559301cc96359acbd0 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 21 Aug 2020 13:32:59 -0700 Subject: [PATCH 21/78] Add missing include --- ports/esp32s2/common-hal/socketpool/Socket.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c index db8356f66f..003ba24434 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.c +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -26,6 +26,7 @@ #include "shared-bindings/socketpool/Socket.h" +#include "bindings/espidf/__init__.h" #include "lib/utils/interrupt_char.h" #include "py/mperrno.h" #include "py/runtime.h" From 69fc872944e55ac36f3ede0d643087b21d6f7047 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 25 Aug 2020 16:14:31 -0700 Subject: [PATCH 22/78] Fix espidf.MemoryError print --- ports/esp32s2/bindings/espidf/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/esp32s2/bindings/espidf/__init__.c b/ports/esp32s2/bindings/espidf/__init__.c index 7c3a8c713d..3b910cfe6f 100644 --- a/ports/esp32s2/bindings/espidf/__init__.c +++ b/ports/esp32s2/bindings/espidf/__init__.c @@ -77,7 +77,7 @@ void espidf_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS; bool is_subclass = kind & PRINT_EXC_SUBCLASS; if (!is_subclass && (k == PRINT_EXC)) { - mp_print_str(print, qstr_str(MP_OBJ_QSTR_VALUE(MP_QSTR_espidf))); + mp_print_str(print, qstr_str(MP_OBJ_QSTR_VALUE(MP_ROM_QSTR(MP_QSTR_espidf)))); mp_print_str(print, "."); } mp_obj_exception_print(print, o_in, kind); From f3bc712539ec13e73fe2b809ee274df57dca5f46 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 25 Aug 2020 16:15:00 -0700 Subject: [PATCH 23/78] Fix SocketPool radio check --- shared-bindings/socketpool/SocketPool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/socketpool/SocketPool.c b/shared-bindings/socketpool/SocketPool.c index 579a4824c8..5624a6632d 100644 --- a/shared-bindings/socketpool/SocketPool.c +++ b/shared-bindings/socketpool/SocketPool.c @@ -53,7 +53,7 @@ STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t socketpool_socketpool_obj_t *s = m_new_obj_with_finaliser(socketpool_socketpool_obj_t); s->base.type = &socketpool_socketpool_type; - mp_obj_t radio = args[1]; + mp_obj_t radio = args[0]; common_hal_socketpool_socketpool_construct(s, radio); From 380cbfba55e45f9f0d8ccae6c28c23b1ea93147f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 25 Aug 2020 16:15:45 -0700 Subject: [PATCH 24/78] Add hash to Socket so it can be used in dicts --- ports/esp32s2/common-hal/socketpool/Socket.c | 21 ++++++++----------- .../common-hal/socketpool/SocketPool.c | 1 - ports/esp32s2/common-hal/wifi/Radio.c | 5 ----- shared-bindings/socketpool/Socket.c | 18 ++++++++++++++-- shared-bindings/socketpool/Socket.h | 1 + 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c index 003ba24434..654ea42d55 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.c +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -32,9 +32,6 @@ #include "py/runtime.h" #include "supervisor/shared/tick.h" -#include "esp_log.h" -static const char* TAG = "socket"; - void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms) { self->timeout_ms = timeout_ms; } @@ -49,7 +46,6 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const c tls_config = &self->ssl_context->ssl_config; } int result = esp_tls_conn_new_sync(host, hostlen, port, tls_config, self->tcp); - ESP_EARLY_LOGW(TAG, "connect result %d", result); self->connected = result >= 0; if (result < 0) { int esp_tls_code; @@ -58,8 +54,11 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const c if (err == ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) { mp_raise_espidf_MemoryError(); + } else if (ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED) { + // What should this error be? + mp_raise_OSError_msg_varg(translate("Failed SSL handshake")); } else { - mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x"), esp_tls_code, flags, err); + mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x %d"), esp_tls_code, flags, err, result); } } @@ -99,37 +98,31 @@ mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, // and between encrypted TLS blocks. int status = lwip_ioctl(sockfd, FIONREAD, &available); if (status < 0) { - // ESP_EARLY_LOGW(TAG, "ioctl fail. socket %d status %d errno %d available %d", sockfd, status, errno, available); last_read = status; break; } } - // ESP_EARLY_LOGW(TAG, "available %d", available); size_t remaining = len - received; if (available > remaining) { available = remaining; } if (available > 0) { last_read = esp_tls_conn_read(self->tcp, (void*) buf + received, available); - // ESP_EARLY_LOGW(TAG, "read %d out of %d", last_read, available); received += last_read; } } if (last_read == 0) { // socket closed - ESP_EARLY_LOGW(TAG, "receive close %d %d", received, len); common_hal_socketpool_socket_close(self); } if (last_read < 0) { - // ESP_EARLY_LOGI(TAG, "received %d", received); mp_raise_BrokenPipeError(); } return received; } void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) { - // ESP_EARLY_LOGW(TAG, "close"); if (self->connected) { self->connected = false; } @@ -144,6 +137,10 @@ void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) { } bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t* self) { - // ESP_EARLY_LOGW(TAG, "tcp %p", self->tcp); return self->tcp == NULL; } + + +mp_uint_t common_hal_socketpool_socket_get_hash(socketpool_socket_obj_t* self) { + return self->num; +} diff --git a/ports/esp32s2/common-hal/socketpool/SocketPool.c b/ports/esp32s2/common-hal/socketpool/SocketPool.c index 2af5bf7221..dbc9c91924 100644 --- a/ports/esp32s2/common-hal/socketpool/SocketPool.c +++ b/ports/esp32s2/common-hal/socketpool/SocketPool.c @@ -33,7 +33,6 @@ #include "bindings/espidf/__init__.h" - void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t* self, mp_obj_t radio) { if (radio != MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj)) { mp_raise_ValueError(translate("SocketPool can only be used with wifi.radio.")); diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c index 038ce9e754..ae3fa2f175 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.c +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -38,9 +38,6 @@ #include "esp-idf/components/esp_wifi/include/esp_wifi.h" #include "esp-idf/components/lwip/include/apps/ping/ping_sock.h" -#include "esp_log.h" -static const char* TAG = "radio"; - static void start_station(wifi_radio_obj_t *self) { if (self->sta_mode) { return; @@ -170,8 +167,6 @@ mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address, uint32_t elapsed_time = 0xffffffff; if (received > 0) { esp_ping_get_profile(ping, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time)); - } else { - ESP_EARLY_LOGW(TAG, "received none - time %d timeout %d", total_time_ms, timeout_ms); } esp_ping_delete_session(ping); diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index 932e8e856c..250e9c874e 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -267,8 +267,7 @@ STATIC mp_obj_t socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args) } if (len == 0) { - ESP_EARLY_LOGW(TAG, "len 0"); - mp_raise_OSError(0); + return MP_OBJ_NEW_SMALL_INT(0); } mp_int_t ret = common_hal_socketpool_socket_recv_into(self, (byte*)bufinfo.buf, len); @@ -426,6 +425,20 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_settimeout_obj, socketpool_so // } // STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_setblocking_obj, socketpool_socket_setblocking); +//| def __hash__(self) -> int: +//| """Returns a hash for the Socket.""" +//| ... +//| +STATIC mp_obj_t socketpool_socket_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + switch (op) { + case MP_UNARY_OP_HASH: { + return MP_OBJ_NEW_SMALL_INT(common_hal_socketpool_socket_get_hash(MP_OBJ_TO_PTR(self_in))); + } + default: + return MP_OBJ_NULL; // op not supported + } +} + STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&socketpool_socket___exit___obj) }, @@ -451,4 +464,5 @@ const mp_obj_type_t socketpool_socket_type = { { &mp_type_type }, .name = MP_QSTR_Socket, .locals_dict = (mp_obj_dict_t*)&socketpool_socket_locals_dict, + .unary_op = socketpool_socket_unary_op, }; diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h index 4597aed38d..f0be95c925 100644 --- a/shared-bindings/socketpool/Socket.h +++ b/shared-bindings/socketpool/Socket.h @@ -38,5 +38,6 @@ mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self); bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t* self); bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t* self); +mp_uint_t common_hal_socketpool_socket_get_hash(socketpool_socket_obj_t* self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H From 6fbeb28bd6804fe884ee4cfcaf56199a0859d439 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 25 Aug 2020 16:40:45 -0700 Subject: [PATCH 25/78] Update translations --- locale/circuitpython.pot | 74 +++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index fe726acf27..b7b442414b 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-21 21:39-0500\n" +"POT-Creation-Date: 2020-08-25 16:39-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -273,7 +273,7 @@ msgstr "" msgid "A hardware interrupt channel is already in use" msgstr "" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "" @@ -302,7 +302,7 @@ msgstr "" msgid "All sync event channels in use" msgstr "" -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pwmio/PWMOut.c msgid "All timers for this pin are in use" msgstr "" @@ -314,7 +314,7 @@ msgstr "" #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c -#: ports/stm/peripherals/timers.c shared-bindings/pulseio/PWMOut.c +#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "" @@ -371,6 +371,10 @@ msgstr "" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "" @@ -552,7 +556,7 @@ msgstr "" msgid "Cannot unambiguously get sizeof scalar" msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "Cannot vary frequency on a timer that is already in use" msgstr "" @@ -621,23 +625,23 @@ msgstr "" msgid "Could not initialize UART" msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "Could not initialize channel" msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "Could not initialize timer" msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "Could not re-init channel" msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "Could not re-init timer" msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "Could not restart PWM" msgstr "" @@ -645,7 +649,7 @@ msgstr "" msgid "Could not set address" msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "Could not start PWM" msgstr "" @@ -836,7 +840,7 @@ msgstr "" msgid "Frequency captured is above capability. Capture Paused." msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "Frequency must match existing PWMOut using this timer" msgstr "" @@ -938,9 +942,9 @@ msgstr "" msgid "Invalid DAC pin supplied" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PWMOut.c -#: ports/cxd56/common-hal/pulseio/PWMOut.c -#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c +#: ports/atmel-samd/common-hal/pwmio/PWMOut.c +#: ports/cxd56/common-hal/pwmio/PWMOut.c ports/nrf/common-hal/pwmio/PWMOut.c +#: shared-bindings/pwmio/PWMOut.c msgid "Invalid PWM frequency" msgstr "" @@ -980,7 +984,7 @@ msgstr "" msgid "Invalid format chunk size" msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "Invalid frequency supplied" msgstr "" @@ -998,8 +1002,8 @@ msgid "Invalid phase" msgstr "" #: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c shared-module/rgbmatrix/RGBMatrix.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c +#: shared-module/rgbmatrix/RGBMatrix.c msgid "Invalid pin" msgstr "" @@ -1023,7 +1027,7 @@ msgstr "" msgid "Invalid pins" msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "Invalid pins for PWMOut" msgstr "" @@ -1205,10 +1209,14 @@ msgstr "" msgid "No long integer support" msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "No more timers available on this pin." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "" @@ -1229,6 +1237,10 @@ msgstr "" msgid "Nordic Soft Device failure assertion." msgstr "" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string." +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1269,16 +1281,20 @@ msgid "" "%d bpp given" msgstr "" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip." +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "" -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pwmio/PWMOut.c msgid "" "PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" msgstr "" -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pwmio/PWMOut.c msgid "" "PWM frequency not writable when variable_frequency is False on construction." msgstr "" @@ -1465,6 +1481,10 @@ msgstr "" msgid "Serializer in use" msgstr "" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1560,7 +1580,7 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: ports/stm/common-hal/pulseio/PWMOut.c +#: ports/stm/common-hal/pwmio/PWMOut.c msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" @@ -1660,6 +1680,10 @@ msgstr "" msgid "Unexpected nrfx uuid type" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1763,6 +1787,10 @@ msgid "" "To list built-in modules please do `help(\"modules\")`.\n" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters." +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "" From 46dc133d04bb6c38faea820576978827edd4337d Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 26 Aug 2020 17:18:16 -0700 Subject: [PATCH 26/78] Fix stub and doc builds --- conf.py | 1 + shared-bindings/ipaddress/IPv4Address.c | 2 +- shared-bindings/wifi/ScannedNetworks.c | 2 +- shared-bindings/wifi/__init__.c | 9 ++++----- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/conf.py b/conf.py index 4a8b72584e..bd9e31d7f9 100644 --- a/conf.py +++ b/conf.py @@ -144,6 +144,7 @@ version = release = final_version # directories to ignore when looking for source files. exclude_patterns = ["**/build*", ".git", + ".env", ".venv", ".direnv", "docs/autoapi", diff --git a/shared-bindings/ipaddress/IPv4Address.c b/shared-bindings/ipaddress/IPv4Address.c index 29536dfa43..03d1874cfc 100644 --- a/shared-bindings/ipaddress/IPv4Address.c +++ b/shared-bindings/ipaddress/IPv4Address.c @@ -42,7 +42,7 @@ //| def __init__(self, address: Union[str, bytes]) -> None: //| """Create a new IPv4Address object encapsulating the address value. //| -//| The value itself can either be bytes or a string formatted address."" +//| The value itself can either be bytes or a string formatted address.""" //| ... //| STATIC mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/shared-bindings/wifi/ScannedNetworks.c b/shared-bindings/wifi/ScannedNetworks.c index c6b77d70b7..c927d7282f 100644 --- a/shared-bindings/wifi/ScannedNetworks.c +++ b/shared-bindings/wifi/ScannedNetworks.c @@ -36,7 +36,7 @@ static const char *TAG = "cp iternext"; //| class ScannedNetworks: -//| """Iterates over wifi `Network`s found while scanning. This object is always created +//| """Iterates over all `wifi.Network` objects found while scanning. This object is always created //| by a `wifi.Radio`: it has no user-visible constructor.""" //| STATIC mp_obj_t scannednetworks_iternext(mp_obj_t self_in) { diff --git a/shared-bindings/wifi/__init__.c b/shared-bindings/wifi/__init__.c index a12881094c..352ceb3318 100644 --- a/shared-bindings/wifi/__init__.c +++ b/shared-bindings/wifi/__init__.c @@ -32,12 +32,11 @@ //| """ //| The `wifi` module provides necessary low-level functionality for managing wifi -//| wifi connections. Use `socketpool` for communicating over the network. +//| wifi connections. Use `socketpool` for communicating over the network.""" //| -//| .. attribute:: radio -//| -//| Wifi radio used to manage both station and AP modes. -//| This object is the sole instance of `wifi.Radio`.""" +//| radio: Radio +//| """Wifi radio used to manage both station and AP modes. +//| This object is the sole instance of `wifi.Radio`.""" //| From fd6e63d806e1b3611df20ed4d3a85bcadb63947f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 27 Aug 2020 11:43:06 -0700 Subject: [PATCH 27/78] Hopefully final partition scheme. --- ports/esp32s2/partitions.csv | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/ports/esp32s2/partitions.csv b/ports/esp32s2/partitions.csv index 6317ff52ad..7c9a1cac90 100644 --- a/ports/esp32s2/partitions.csv +++ b/ports/esp32s2/partitions.csv @@ -1,9 +1,10 @@ # ESP-IDF Partition Table # Name, Type, SubType, Offset, Size, Flags -# bootloader.bin 0x1000 -# partition table 0x8000, 0xC00 -otadata, data, ota, 0xd000, 0x2000, -ota_0, 0, ota_0, 0x10000, 0x120000, -ota_1, 0, ota_1, 0x130000, 0x120000, -phy_init, data, phy, 0x250000, 0x1000, -user_fs, data, fat, 0x251000, 0x1af000, +# bootloader.bin 0x1000 +# partition table 0x8000, 0xC00 +otadata, data, ota, 0xd000, 0x2000, +phy_init, data, phy, 0xf000, 0x1000, +ota_0, 0, ota_0, 0x10000, 0x160000, +ota_1, 0, ota_1, 0x170000, 0x160000, +uf2, app, factory,0x2d0000, 256K, +user_fs, data, fat, 0x310000, 960K, From 2b71635c4978a337542292cfc78460440d59338d Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 27 Aug 2020 11:45:51 -0700 Subject: [PATCH 28/78] Fix esp-idf requirements --- ports/esp32s2/esp-idf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/esp32s2/esp-idf b/ports/esp32s2/esp-idf index 83595f7659..de733cdab5 160000 --- a/ports/esp32s2/esp-idf +++ b/ports/esp32s2/esp-idf @@ -1 +1 @@ -Subproject commit 83595f76591aebf0cca9a578258276e67f628b06 +Subproject commit de733cdab556c5713c94ba95078f4024dd56fd87 From 5d8ac0428b239be2b0487a2da2d2192aa7ed8725 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 27 Aug 2020 13:34:37 -0700 Subject: [PATCH 29/78] -Os espruino_pico to save space --- ports/stm/boards/espruino_pico/mpconfigboard.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ports/stm/boards/espruino_pico/mpconfigboard.mk b/ports/stm/boards/espruino_pico/mpconfigboard.mk index b1b023dd58..556ff35c45 100644 --- a/ports/stm/boards/espruino_pico/mpconfigboard.mk +++ b/ports/stm/boards/espruino_pico/mpconfigboard.mk @@ -9,6 +9,8 @@ MCU_SERIES = F4 MCU_VARIANT = STM32F401xE MCU_PACKAGE = UFQFPN48 +OPTIMIZATION_FLAGS = -Os + LD_COMMON = boards/common_default.ld # use for internal flash LD_FILE = boards/STM32F401xd_fs.ld From 07740d19f3fd647979b223b8ffffcb6776c613e3 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 1 Sep 2020 17:12:22 -0500 Subject: [PATCH 30/78] add bigram compression to makeqstrdata Compress common unicode bigrams by making code points in the range 0x80 - 0xbf (inclusive) represent them. Then, they can be greedily encoded and the substituted code points handled by the existing Huffman compression. Normally code points in the range 0x80-0xbf are not used in Unicode, so we stake our own claim. Using the more arguably correct "Private Use Area" (PUA) would mean that for scripts that only use code points under 256 we would use more memory for the "values" table. bigram means "two letters", and is also sometimes called a "digram". It's nothing to do with "big RAM". For our purposes, a bigram represents two successive unicode code points, so for instance in our build on trinket m0 for english the most frequent are: ['t ', 'e ', 'in', 'd ', ...]. The bigrams are selected based on frequency in the corpus, but the selection is not necessarily optimal, for these reasons I can think of: * Suppose the corpus was just "tea" repeated 100 times. The top bigrams would be "te", and "ea". However, overlap, "te" could never be used. Thus, some bigrams might actually waste space * I _assume_ this has to be why e.g., bigram 0x86 "s " is more frequent than bigram 0x85 " a" in English for Trinket M0, because sequences like "can't add" would get the "t " digram and then be unable to use the " a" digram. * And generally, if a bigram is frequent then so are its constituents. Say that "i" and "n" both encode to just 5 or 6 bits, then the huffman code for "in" had better compress to 10 or fewer bits or it's a net loss! * I checked though! "i" is 5 bits, "n" is 6 bits (lucky guess) but the bigram 0x83 also just 6 bits, so this one is a win of 5 bits for every "it" minus overhead. Yay, this round goes to team compression. * On the other hand, the least frequent bigram 0x9d " n" is 10 bits long and its constituent code points are 4+6 bits so there's no savings, but there is the cost of the table entry. * and somehow 0x9f 'an' is never used at all! With or without accounting for overlaps, there is some optimum number of bigrams. Adding one more bigram uses at least 2 bytes (for the entry in the bigram table; 4 bytes if code points >255 are in the source text) and also needs a slot in the Huffman dictionary, so adding bigrams beyond the optimim number makes compression worse again. If it's an improvement, the fact that it's not guaranteed optimal doesn't seem to matter too much. It just leaves a little more fruit for the next sweep to pick up. Perhaps try adding the most frequent bigram not yet present, until it doesn't improve compression overall. Right now, de_DE is again the "fullest" build on trinket_m0. (It's reclaimed that spot from the ja translation somehow) This change saves 104 bytes there, increasing free space about 6.8%. In the larger (but not critically full) pyportal build it saves 324 bytes. The specific number of bigrams used (32) was chosen as it is the max number that fit within the 0x80..0xbf range. Larger tables would require the use of 16 bit code points in the de_DE build, losing savings overall. (Side note: The most frequent letters in English have been said to be: ETA OIN SHRDLU; but we have UAC EIL MOPRST in our corpus) --- py/makeqstrdata.py | 33 +++++++++++++++++++++++++++++---- supervisor/shared/translate.c | 9 +++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 04c8938766..28aed3df97 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -100,9 +100,30 @@ def translate(translation_file, i18ns): translations.append((original, translation)) return translations +def frequent_ngrams(corpus, sz, n): + return collections.Counter(corpus[i:i+sz] for i in range(len(corpus)-sz)).most_common(n) + +def ngrams_to_pua(translation, ngrams): + if len(ngrams) > 32: + start = 0xe000 + else: + start = 0x80 + for i, g in enumerate(ngrams): + translation = translation.replace(g, chr(start + i)) + return translation + +def pua_to_ngrams(compressed, ngrams): + if len(ngrams) > 32: + start, end = 0xe000, 0xf8ff + else: + start, end = 0x80, 0xbf + return "".join(ngrams[ord(c) - start] if (start <= ord(c) <= end) else c for c in compressed) + def compute_huffman_coding(translations, qstrs, compression_filename): all_strings = [x[1] for x in translations] all_strings_concat = "".join(all_strings) + ngrams = [i[0] for i in frequent_ngrams(all_strings_concat, 2, 32)] + all_strings_concat = ngrams_to_pua(all_strings_concat, ngrams) counts = collections.Counter(all_strings_concat) cb = huffman.codebook(counts.items()) values = [] @@ -128,7 +149,8 @@ def compute_huffman_coding(translations, qstrs, compression_filename): for i in range(1, max(length_count) + 2): lengths.append(length_count.get(i, 0)) print("// values", values, "lengths", len(lengths), lengths) - print("// estimated total memory size", len(lengths) + 2*len(values) + sum(len(cb[u]) for u in all_strings_concat)) + ngramdata = [ord(ni) for i in ngrams for ni in i] + print("// estimated total memory size", len(lengths) + 2*len(values) + 2 * len(ngramdata) + sum((len(cb[u]) + 7)//8 for u in all_strings_concat)) print("//", values, lengths) values_type = "uint16_t" if max(ord(u) for u in values) > 255 else "uint8_t" max_translation_encoded_length = max(len(translation.encode("utf-8")) for original,translation in translations) @@ -136,10 +158,11 @@ def compute_huffman_coding(translations, qstrs, compression_filename): f.write("const uint8_t lengths[] = {{ {} }};\n".format(", ".join(map(str, lengths)))) f.write("const {} values[] = {{ {} }};\n".format(values_type, ", ".join(str(ord(u)) for u in values))) f.write("#define compress_max_length_bits ({})\n".format(max_translation_encoded_length.bit_length())) - return values, lengths + f.write("const {} ngrams[] = {{ {} }};\n".format(values_type, ", ".join(str(u) for u in ngramdata))) + return values, lengths, ngrams def decompress(encoding_table, encoded, encoded_length_bits): - values, lengths = encoding_table + values, lengths, ngrams = encoding_table dec = [] this_byte = 0 this_bit = 7 @@ -187,6 +210,7 @@ def decompress(encoding_table, encoded, encoded_length_bits): searched_length += lengths[bit_length] v = values[searched_length + bits - max_code] + v = pua_to_ngrams(v, ngrams) i += len(v.encode('utf-8')) dec.append(v) return ''.join(dec) @@ -194,7 +218,8 @@ def decompress(encoding_table, encoded, encoded_length_bits): def compress(encoding_table, decompressed, encoded_length_bits, len_translation_encoded): if not isinstance(decompressed, str): raise TypeError() - values, lengths = encoding_table + values, lengths, ngrams = encoding_table + decompressed = ngrams_to_pua(decompressed, ngrams) enc = bytearray(len(decompressed) * 3) #print(decompressed) #print(lengths) diff --git a/supervisor/shared/translate.c b/supervisor/shared/translate.c index 606f8fa91a..49ee8f143f 100644 --- a/supervisor/shared/translate.c +++ b/supervisor/shared/translate.c @@ -34,6 +34,7 @@ #include "genhdr/compression.generated.h" #endif +#include "py/misc.h" #include "supervisor/serial.h" void serial_write_compressed(const compressed_string_t* compressed) { @@ -46,10 +47,18 @@ STATIC int put_utf8(char *buf, int u) { if(u <= 0x7f) { *buf = u; return 1; + } else if(MP_ARRAY_SIZE(ngrams) <= 64 && u <= 0xbf) { + int n = (u - 0x80) * 2; + int ret = put_utf8(buf, ngrams[n]); + return ret + put_utf8(buf + ret, ngrams[n+1]); } else if(u <= 0x07ff) { *buf++ = 0b11000000 | (u >> 6); *buf = 0b10000000 | (u & 0b00111111); return 2; + } else if(MP_ARRAY_SIZE(ngrams) > 64 && u >= 0xe000 && u <= 0xf8ff) { + int n = (u - 0xe000) * 2; + int ret = put_utf8(buf, ngrams[n]); + return ret + put_utf8(buf + ret, ngrams[n+1]); } else { // u <= 0xffff) *buf++ = 0b11000000 | (u >> 12); *buf = 0b10000000 | ((u >> 6) & 0b00111111); From f1c7389b2951edc3e24091565b1465252ac40a1e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 2 Sep 2020 15:50:51 -0500 Subject: [PATCH 31/78] locales: Replace NBSP characters with true spaces These characters, at code point 0xa0, are unintended. --- locale/cs.po | 6 +++--- locale/pl.po | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/locale/cs.po b/locale/cs.po index cd81c258fe..3e22ac2514 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -44,15 +44,15 @@ msgstr "" #: py/obj.c msgid " File \"%q\"" -msgstr "  Soubor \"%q\"" +msgstr " Soubor \"%q\"" #: py/obj.c msgid " File \"%q\", line %d" -msgstr "  Soubor \"%q\", řádek %d" +msgstr " Soubor \"%q\", řádek %d" #: main.c msgid " output:\n" -msgstr " výstup:\n" +msgstr " výstup:\n" #: py/objstr.c #, c-format diff --git a/locale/pl.po b/locale/pl.po index b072629cd1..cd4b905e73 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -1971,7 +1971,7 @@ msgstr "wartość kalibracji poza zakresem +/-127" #: py/emitinlinethumb.c msgid "can only have up to 4 parameters to Thumb assembly" -msgstr "asembler Thumb może przyjąć do 4 parameterów" +msgstr "asembler Thumb może przyjąć do 4 parameterów" #: py/emitinlinextensa.c msgid "can only have up to 4 parameters to Xtensa assembly" @@ -3562,7 +3562,7 @@ msgstr "" #~ msgstr "Nie udało się odkryć serwisów" #~ msgid "Failed to get local address" -#~ msgstr "Nie udało się uzyskać lokalnego adresu" +#~ msgstr "Nie udało się uzyskać lokalnego adresu" #~ msgid "Failed to get softdevice state" #~ msgstr "Nie udało się odczytać stanu softdevice" @@ -3610,7 +3610,7 @@ msgstr "" #~ msgstr "Nie udało się zapisać gatts, błąd 0x%04x" #~ msgid "Flash erase failed" -#~ msgstr "Nie udało się skasować flash" +#~ msgstr "Nie udało się skasować flash" #~ msgid "Flash erase failed to start, err 0x%04x" #~ msgstr "Nie udało się rozpocząć kasowania flash, błąd 0x%04x" From c34cb82ecb26ac2d5d85394ec535928194cd9e5e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 2 Sep 2020 15:52:02 -0500 Subject: [PATCH 32/78] makeqstrdata: correct range of low code points to 0x80..0x9f inclusive The previous range was unintentionally big and overlaps some characters we'd like to use (and also 0xa0, which we don't intentionally use) --- py/makeqstrdata.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 28aed3df97..350f11c4cb 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -116,7 +116,7 @@ def pua_to_ngrams(compressed, ngrams): if len(ngrams) > 32: start, end = 0xe000, 0xf8ff else: - start, end = 0x80, 0xbf + start, end = 0x80, 0x9f return "".join(ngrams[ord(c) - start] if (start <= ord(c) <= end) else c for c in compressed) def compute_huffman_coding(translations, qstrs, compression_filename): @@ -146,6 +146,7 @@ def compute_huffman_coding(translations, qstrs, compression_filename): last_l = l lengths = bytearray() print("// length count", length_count) + print("// bigrams", ngrams) for i in range(1, max(length_count) + 2): lengths.append(length_count.get(i, 0)) print("// values", values, "lengths", len(lengths), lengths) From cbfd38d1ce8839e11e828b0e8742d5d983446313 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 2 Sep 2020 19:09:23 -0500 Subject: [PATCH 33/78] Rename functions to encode_ngrams / decode_ngrams --- py/makeqstrdata.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 350f11c4cb..40c50b7b43 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -103,7 +103,7 @@ def translate(translation_file, i18ns): def frequent_ngrams(corpus, sz, n): return collections.Counter(corpus[i:i+sz] for i in range(len(corpus)-sz)).most_common(n) -def ngrams_to_pua(translation, ngrams): +def encode_ngrams(translation, ngrams): if len(ngrams) > 32: start = 0xe000 else: @@ -112,7 +112,7 @@ def ngrams_to_pua(translation, ngrams): translation = translation.replace(g, chr(start + i)) return translation -def pua_to_ngrams(compressed, ngrams): +def decode_ngrams(compressed, ngrams): if len(ngrams) > 32: start, end = 0xe000, 0xf8ff else: @@ -123,7 +123,7 @@ def compute_huffman_coding(translations, qstrs, compression_filename): all_strings = [x[1] for x in translations] all_strings_concat = "".join(all_strings) ngrams = [i[0] for i in frequent_ngrams(all_strings_concat, 2, 32)] - all_strings_concat = ngrams_to_pua(all_strings_concat, ngrams) + all_strings_concat = encode_ngrams(all_strings_concat, ngrams) counts = collections.Counter(all_strings_concat) cb = huffman.codebook(counts.items()) values = [] @@ -211,7 +211,7 @@ def decompress(encoding_table, encoded, encoded_length_bits): searched_length += lengths[bit_length] v = values[searched_length + bits - max_code] - v = pua_to_ngrams(v, ngrams) + v = decode_ngrams(v, ngrams) i += len(v.encode('utf-8')) dec.append(v) return ''.join(dec) @@ -220,7 +220,7 @@ def compress(encoding_table, decompressed, encoded_length_bits, len_translation_ if not isinstance(decompressed, str): raise TypeError() values, lengths, ngrams = encoding_table - decompressed = ngrams_to_pua(decompressed, ngrams) + decompressed = encode_ngrams(decompressed, ngrams) enc = bytearray(len(decompressed) * 3) #print(decompressed) #print(lengths) From 0b94638aeb667f2a417d859487083241a5749128 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 3 Sep 2020 16:32:12 -0700 Subject: [PATCH 34/78] Changes based on Dan's feedback --- locale/circuitpython.pot | 14 +-- ports/esp32s2/common-hal/socketpool/Socket.c | 11 +-- .../common-hal/socketpool/SocketPool.c | 4 +- .../esp32s2/common-hal/socketpool/__init__.c | 6 -- ports/esp32s2/common-hal/wifi/Radio.c | 14 +-- .../esp32s2/common-hal/wifi/ScannedNetworks.c | 1 + ports/esp32s2/common-hal/wifi/__init__.c | 91 +++++++++---------- ports/esp32s2/mpconfigport.mk | 3 +- ports/esp32s2/partitions.csv | 12 +-- py/circuitpy_mpconfig.mk | 2 +- shared-bindings/ipaddress/IPv4Address.c | 4 +- shared-bindings/ipaddress/__init__.c | 4 +- shared-bindings/socketpool/SocketPool.c | 2 +- shared-bindings/ssl/SSLContext.c | 2 +- shared-bindings/wifi/Radio.c | 11 +-- shared-module/ipaddress/__init__.c | 2 +- 16 files changed, 78 insertions(+), 105 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 2ba112d00e..5122e7ba8f 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-27 11:21-0400\n" +"POT-Creation-Date: 2020-09-03 15:16-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1238,7 +1238,7 @@ msgid "Nordic Soft Device failure assertion." msgstr "" #: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c -msgid "Not a valid IP string." +msgid "Not a valid IP string" msgstr "" #: ports/nrf/common-hal/_bleio/__init__.c @@ -1282,7 +1282,7 @@ msgid "" msgstr "" #: shared-bindings/ipaddress/__init__.c -msgid "Only raw int supported for ip." +msgid "Only raw int supported for ip" msgstr "" #: shared-bindings/audiobusio/PDMIn.c @@ -1365,10 +1365,6 @@ msgstr "" msgid "Pull not used when direction is output." msgstr "" -#: ports/stm/ref/pulseout-pre-timeralloc.c -msgid "PulseOut not supported on this chip" -msgstr "" - #: ports/stm/common-hal/os/__init__.c msgid "RNG DeInit Error" msgstr "" @@ -1486,7 +1482,7 @@ msgid "Serializer in use" msgstr "" #: shared-bindings/ssl/SSLContext.c -msgid "Server side context cannot have hostname." +msgid "Server side context cannot have hostname" msgstr "" #: shared-bindings/nvm/ByteArray.c @@ -1792,7 +1788,7 @@ msgid "" msgstr "" #: shared-bindings/wifi/Radio.c -msgid "WiFi password must be between 8 and 63 characters." +msgid "WiFi password must be between 8 and 63 characters" msgstr "" #: ports/nrf/common-hal/_bleio/PacketBuffer.c diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c index 654ea42d55..0a994c604e 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.c +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -55,7 +55,6 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const c if (err == ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) { mp_raise_espidf_MemoryError(); } else if (ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED) { - // What should this error be? mp_raise_OSError_msg_varg(translate("Failed SSL handshake")); } else { mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x %d"), esp_tls_code, flags, err, result); @@ -123,15 +122,9 @@ mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, } void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) { - if (self->connected) { - self->connected = false; - } + self->connected = false; if (self->tcp != NULL) { - int status = esp_tls_conn_destroy(self->tcp); - - if (status < 0) { - // raise an error - } + esp_tls_conn_destroy(self->tcp); self->tcp = NULL; } } diff --git a/ports/esp32s2/common-hal/socketpool/SocketPool.c b/ports/esp32s2/common-hal/socketpool/SocketPool.c index dbc9c91924..4a07f21c48 100644 --- a/ports/esp32s2/common-hal/socketpool/SocketPool.c +++ b/ports/esp32s2/common-hal/socketpool/SocketPool.c @@ -35,7 +35,7 @@ void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t* self, mp_obj_t radio) { if (radio != MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj)) { - mp_raise_ValueError(translate("SocketPool can only be used with wifi.radio.")); + mp_raise_ValueError(translate("SocketPool can only be used with wifi.radio")); } } @@ -63,7 +63,7 @@ socketpool_socket_obj_t* common_hal_socketpool_socket(socketpool_socketpool_obj_ if (socket_type == SOCK_DGRAM || socket_type == SOCK_RAW || addr_family == AF_INET6 || ipproto == IPPROTO_IPV6) { - mp_raise_NotImplementedError(translate("Only IPv4 SOCK_STREAM sockets supported.")); + mp_raise_NotImplementedError(translate("Only IPv4 SOCK_STREAM sockets supported")); } int socknum = -1; diff --git a/ports/esp32s2/common-hal/socketpool/__init__.c b/ports/esp32s2/common-hal/socketpool/__init__.c index 8f9565b46e..fa0e7d5f3f 100644 --- a/ports/esp32s2/common-hal/socketpool/__init__.c +++ b/ports/esp32s2/common-hal/socketpool/__init__.c @@ -23,9 +23,3 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - -#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H -#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H - - -#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL___INIT___H diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c index ae3fa2f175..3c6ab57570 100644 --- a/ports/esp32s2/common-hal/wifi/Radio.c +++ b/ports/esp32s2/common-hal/wifi/Radio.c @@ -73,10 +73,12 @@ void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) { } } +#define MAC_ADDRESS_LENGTH 6 + mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) { - uint8_t mac[6]; + uint8_t mac[MAC_ADDRESS_LENGTH]; esp_wifi_get_mac(ESP_IF_WIFI_STA, mac); - return mp_const_none; + return mp_obj_new_bytes(mac, MAC_ADDRESS_LENGTH); } mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) { @@ -87,8 +89,8 @@ mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) { start_station(self); wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t); - self->current_scan = scan; scan->base.type = &wifi_scannednetworks_type; + self->current_scan = scan; scan->start_channel = 1; scan->end_channel = 11; scan->radio_event_group = self->event_group_handle; @@ -107,9 +109,7 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t wifi_config_t* config = &self->sta_config; memcpy(&config->sta.ssid, ssid, ssid_len); config->sta.ssid[ssid_len] = 0; - if (password_len > 0) { - memcpy(&config->sta.password, password, password_len); - } + memcpy(&config->sta.password, password, password_len); config->sta.password[password_len] = 0; config->sta.channel = channel; esp_wifi_set_config(ESP_IF_WIFI_STA, config); @@ -159,7 +159,7 @@ mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address, uint32_t received = 0; uint32_t total_time_ms = 0; - while (received == 0 && total_time_ms < timeout_ms) { + while (received == 0 && total_time_ms < timeout_ms && !mp_hal_is_interrupted()) { RUN_BACKGROUND_TASKS; esp_ping_get_profile(ping, ESP_PING_PROF_DURATION, &total_time_ms, sizeof(total_time_ms)); esp_ping_get_profile(ping, ESP_PING_PROF_REPLY, &received, sizeof(received)); diff --git a/ports/esp32s2/common-hal/wifi/ScannedNetworks.c b/ports/esp32s2/common-hal/wifi/ScannedNetworks.c index c13fef0718..507c6d1861 100644 --- a/ports/esp32s2/common-hal/wifi/ScannedNetworks.c +++ b/ports/esp32s2/common-hal/wifi/ScannedNetworks.c @@ -162,6 +162,7 @@ void wifi_scannednetworks_deinit(wifi_scannednetworks_obj_t* self) { if (self->scanning) { esp_wifi_scan_stop(); if (wifi_scannednetworks_wait_for_scan(self)) { + // Ignore the number of records since we're throwing them away. uint16_t number = 0; esp_wifi_scan_get_ap_records(&number, NULL); self->scanning = false; diff --git a/ports/esp32s2/common-hal/wifi/__init__.c b/ports/esp32s2/common-hal/wifi/__init__.c index d455679467..b9ea9da06f 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.c +++ b/ports/esp32s2/common-hal/wifi/__init__.c @@ -44,51 +44,42 @@ static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { wifi_radio_obj_t* radio = arg; if (event_base == WIFI_EVENT) { - if (event_id == WIFI_EVENT_SCAN_DONE) { - xEventGroupSetBits(radio->event_group_handle, WIFI_SCAN_DONE_BIT); - } else if (event_id == WIFI_EVENT_STA_START) { - } else if (event_id == WIFI_EVENT_STA_STOP) { - } else if (event_id == WIFI_EVENT_STA_CONNECTED) { - ESP_EARLY_LOGW(TAG, "connected"); - } else if (event_id == WIFI_EVENT_STA_DISCONNECTED) { - ESP_EARLY_LOGW(TAG, "disconnected"); - wifi_event_sta_disconnected_t* d = (wifi_event_sta_disconnected_t*) event_data; - uint8_t reason = d->reason; - ESP_EARLY_LOGW(TAG, "reason %d 0x%02x", reason, reason); - if (radio->retries_left > 0 && - (reason == WIFI_REASON_AUTH_EXPIRE || - reason == WIFI_REASON_ASSOC_EXPIRE || - reason == WIFI_REASON_CONNECTION_FAIL || - reason == WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT)) { - radio->retries_left--; - ESP_EARLY_LOGI(TAG, "Retrying connect. %d retries remaining", radio->retries_left); - esp_wifi_connect(); - return; + switch (event_id) { + case WIFI_EVENT_SCAN_DONE: + xEventGroupSetBits(radio->event_group_handle, WIFI_SCAN_DONE_BIT); + break; + case WIFI_EVENT_STA_CONNECTED: + ESP_EARLY_LOGW(TAG, "connected"); + break; + case WIFI_EVENT_STA_DISCONNECTED: { + ESP_EARLY_LOGW(TAG, "disconnected"); + wifi_event_sta_disconnected_t* d = (wifi_event_sta_disconnected_t*) event_data; + uint8_t reason = d->reason; + ESP_EARLY_LOGW(TAG, "reason %d 0x%02x", reason, reason); + if (radio->retries_left > 0 && + (reason == WIFI_REASON_AUTH_EXPIRE || + reason == WIFI_REASON_ASSOC_EXPIRE || + reason == WIFI_REASON_CONNECTION_FAIL || + reason == WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT)) { + radio->retries_left--; + ESP_EARLY_LOGI(TAG, "Retrying connect. %d retries remaining", radio->retries_left); + esp_wifi_connect(); + return; + } + + radio->last_disconnect_reason = reason; + xEventGroupSetBits(radio->event_group_handle, WIFI_DISCONNECTED_BIT); } - radio->last_disconnect_reason = reason; - xEventGroupSetBits(radio->event_group_handle, WIFI_DISCONNECTED_BIT); - - // if (reason != WIFI_REASON_ASSOC_LEAVE) { - // // reconnect - // } - } else if (event_id == WIFI_EVENT_STA_AUTHMODE_CHANGE) { + // Cases to handle later. + // case WIFI_EVENT_STA_START: + // case WIFI_EVENT_STA_STOP: + // case WIFI_EVENT_STA_AUTHMODE_CHANGE: + default: + break; } } - // esp_wifi_connect(); - // if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - // esp_wifi_connect(); - // } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - // if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { - // esp_wifi_connect(); - // s_retry_num++; - // ESP_LOGI(TAG, "retry to connect to the AP"); - // } else { - // xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); - // } - // ESP_LOGI(TAG,"connect to the AP fail"); - // } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { ESP_EARLY_LOGW(TAG, "got ip"); radio->retries_left = radio->starting_retries; @@ -100,7 +91,7 @@ static bool wifi_inited; void common_hal_wifi_init(void) { wifi_inited = true; - common_hal_wifi_radio_obj.base.type = &wifi_radio_type; + common_hal_wifi_radio_obj.base.type = &wifi_radio_type; ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); @@ -120,13 +111,13 @@ void common_hal_wifi_init(void) { self, &self->handler_instance_got_ip)); - wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); - esp_err_t result = esp_wifi_init(&config); - if (result == ESP_ERR_NO_MEM) { - mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate Wifi memory")); - } else if (result != ESP_OK) { - // handle this - } + wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); + esp_err_t result = esp_wifi_init(&config); + if (result == ESP_ERR_NO_MEM) { + mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate Wifi memory")); + } else if (result != ESP_OK) { + mp_raise_RuntimeError(translate("Failed to init wifi")); + } common_hal_wifi_radio_set_enabled(self, true); } @@ -135,14 +126,14 @@ void wifi_reset(void) { return; } wifi_radio_obj_t* radio = &common_hal_wifi_radio_obj; - common_hal_wifi_radio_set_enabled(radio, false); + common_hal_wifi_radio_set_enabled(radio, false); ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, radio->handler_instance_all_wifi)); ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, radio->handler_instance_got_ip)); - ESP_ERROR_CHECK(esp_wifi_deinit()); + ESP_ERROR_CHECK(esp_wifi_deinit()); esp_netif_destroy(radio->netif); radio->netif = NULL; ESP_ERROR_CHECK(esp_netif_deinit()); diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index 5252714388..ee98ce1f42 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -23,7 +23,8 @@ CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 CIRCUITPY_NVM = 0 -CIRCUITPY_USB_MIDI = 0 # We don't have enough endpoints to include MIDI. +# We don't have enough endpoints to include MIDI. +CIRCUITPY_USB_MIDI = 0 CIRCUITPY_WIFI = 1 CIRCUITPY_ESPIDF = 1 diff --git a/ports/esp32s2/partitions.csv b/ports/esp32s2/partitions.csv index 7c9a1cac90..cf9b3cca84 100644 --- a/ports/esp32s2/partitions.csv +++ b/ports/esp32s2/partitions.csv @@ -1,10 +1,10 @@ # ESP-IDF Partition Table # Name, Type, SubType, Offset, Size, Flags -# bootloader.bin 0x1000 -# partition table 0x8000, 0xC00 -otadata, data, ota, 0xd000, 0x2000, -phy_init, data, phy, 0xf000, 0x1000, -ota_0, 0, ota_0, 0x10000, 0x160000, -ota_1, 0, ota_1, 0x170000, 0x160000, +# bootloader.bin,, 0x1000, 32K +# partition table,, 0x8000, 4K +nvs, data, nvs, 0x9000, 20K, +otadata, data, ota, 0xe000, 8K, +ota_0, 0, ota_0, 0x10000, 1408K, +ota_1, 0, ota_1, 0x170000, 1408K, uf2, app, factory,0x2d0000, 256K, user_fs, data, fat, 0x310000, 960K, diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 2629883f80..ca2f60508e 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -95,7 +95,7 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO) CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO) -# CIRCUITPY_ESPIDF is handled in the atmel-samd tree. +# CIRCUITPY_ESPIDF is handled in the esp32s2 tree. # Only for ESP32S chips. # Assume not a ESP build. CIRCUITPY_ESPIDF ?= 0 diff --git a/shared-bindings/ipaddress/IPv4Address.c b/shared-bindings/ipaddress/IPv4Address.c index 03d1874cfc..b2a10158ae 100644 --- a/shared-bindings/ipaddress/IPv4Address.c +++ b/shared-bindings/ipaddress/IPv4Address.c @@ -39,7 +39,7 @@ //| """Encapsulates an IPv4 address.""" //| -//| def __init__(self, address: Union[str, bytes]) -> None: +//| def __init__(self, address: Union[int, str, bytes]) -> None: //| """Create a new IPv4Address object encapsulating the address value. //| //| The value itself can either be bytes or a string formatted address.""" @@ -64,7 +64,7 @@ STATIC mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t } else if (MP_OBJ_IS_STR(address)) { GET_STR_DATA_LEN(address, str_data, str_len); if (!ipaddress_parse_ipv4address((const char*) str_data, str_len, &value)) { - mp_raise_ValueError(translate("Not a valid IP string.")); + mp_raise_ValueError(translate("Not a valid IP string")); } } else { mp_buffer_info_t buf_info; diff --git a/shared-bindings/ipaddress/__init__.c b/shared-bindings/ipaddress/__init__.c index 76b63202cc..7ec2984ef7 100644 --- a/shared-bindings/ipaddress/__init__.c +++ b/shared-bindings/ipaddress/__init__.c @@ -88,10 +88,10 @@ STATIC mp_obj_t ipaddress_ip_address(mp_obj_t ip_in) { } else if (MP_OBJ_IS_STR(ip_in)) { GET_STR_DATA_LEN(ip_in, str_data, str_len); if (!ipaddress_parse_ipv4address((const char*) str_data, str_len, &value)) { - mp_raise_ValueError(translate("Not a valid IP string.")); + mp_raise_ValueError(translate("Not a valid IP string")); } } else { - mp_raise_ValueError(translate("Only raw int supported for ip.")); + mp_raise_ValueError(translate("Only raw int supported for ip")); } return common_hal_ipaddress_new_ipv4address(value); diff --git a/shared-bindings/socketpool/SocketPool.c b/shared-bindings/socketpool/SocketPool.c index 5624a6632d..0eeebd6911 100644 --- a/shared-bindings/socketpool/SocketPool.c +++ b/shared-bindings/socketpool/SocketPool.c @@ -61,7 +61,7 @@ STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t } -//| def socket(self, family: int, type: int, proto: int) -> None: +//| def socket(self, family: int = AF_INET, type: int = SOCK_STREAM, proto: int = IPPROTO_TCP) -> None: //| """Create a new socket //| //| :param ~int family: AF_INET or AF_INET6 diff --git a/shared-bindings/ssl/SSLContext.c b/shared-bindings/ssl/SSLContext.c index 5d44dc0f54..d2c236d3bf 100644 --- a/shared-bindings/ssl/SSLContext.c +++ b/shared-bindings/ssl/SSLContext.c @@ -72,7 +72,7 @@ STATIC mp_obj_t ssl_sslcontext_wrap_socket(size_t n_args, const mp_obj_t *pos_ar const char *server_hostname = mp_obj_str_get_str(args[ARG_server_hostname].u_obj); bool server_side = args[ARG_server_side].u_bool; if (server_side && server_hostname != NULL) { - mp_raise_ValueError(translate("Server side context cannot have hostname.")); + mp_raise_ValueError(translate("Server side context cannot have hostname")); } socketpool_socket_obj_t* sock = args[ARG_sock].u_obj; diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index 2d356e5d96..329dcb1b5f 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -61,7 +61,7 @@ const mp_obj_property_t wifi_radio_enabled_obj = { (mp_obj_t)&mp_const_none_obj }, }; -//| mac_address: Address +//| mac_address: bytes //| """MAC address of the wifi radio. (read-only)""" //| STATIC mp_obj_t wifi_radio_get_mac_address(mp_obj_t self) { @@ -110,7 +110,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_scanning_networks_obj, wifi_rad STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_ssid, ARG_password, ARG_channel, ARG_timeout }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_password, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, @@ -127,17 +127,14 @@ STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_m mp_buffer_info_t ssid; - ssid.len = 0; - if (args[ARG_ssid].u_obj != MP_OBJ_NULL) { - mp_get_buffer_raise(args[ARG_ssid].u_obj, &ssid, MP_BUFFER_READ); - } + mp_get_buffer_raise(args[ARG_ssid].u_obj, &ssid, MP_BUFFER_READ); mp_buffer_info_t password; password.len = 0; if (args[ARG_password].u_obj != MP_OBJ_NULL) { mp_get_buffer_raise(args[ARG_password].u_obj, &password, MP_BUFFER_READ); if (password.len > 0 && (password.len < 8 || password.len > 63)) { - mp_raise_ValueError(translate("WiFi password must be between 8 and 63 characters.")); + mp_raise_ValueError(translate("WiFi password must be between 8 and 63 characters")); } } diff --git a/shared-module/ipaddress/__init__.c b/shared-module/ipaddress/__init__.c index 2fce9d8f51..a8f8e1caf8 100644 --- a/shared-module/ipaddress/__init__.c +++ b/shared-module/ipaddress/__init__.c @@ -31,5 +31,5 @@ mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value) { ipaddress_ipv4address_obj_t* self = m_new_obj(ipaddress_ipv4address_obj_t); self->base.type = &ipaddress_ipv4address_type; common_hal_ipaddress_ipv4address_construct(self, (uint8_t*) &value, 4); - return self; + return MP_OBJ_FROM_PTR(self); } From f7714649eeb1b8be97099e848a800a4dea941867 Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Fri, 4 Sep 2020 14:15:15 -0500 Subject: [PATCH 35/78] Add dirty rectangle tracking to Shape display element --- shared-module/displayio/Shape.c | 74 ++++++++++++++++++++++++++++++ shared-module/displayio/Shape.h | 5 ++ shared-module/displayio/TileGrid.c | 8 +++- 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/shared-module/displayio/Shape.c b/shared-module/displayio/Shape.c index ab9ca735bc..b8412ed9a3 100644 --- a/shared-module/displayio/Shape.c +++ b/shared-module/displayio/Shape.c @@ -49,10 +49,16 @@ void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t widt self->half_height = height; self->data = m_malloc(height * sizeof(uint32_t), false); + //for (uint16_t i = 0; i < height; i++) { for (uint16_t i = 0; i <= height; i++) { self->data[2 * i] = 0; self->data[2 * i + 1] = width; } + + self->dirty_area.x1=0; + self->dirty_area.x2=width; + self->dirty_area.y1=0; + self->dirty_area.y2=height; } void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y, uint16_t start_x, uint16_t end_x) { @@ -66,8 +72,58 @@ void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y if (self->mirror_x && (start_x > half_width || end_x > half_width)) { mp_raise_ValueError_varg(translate("Maximum x value when mirrored is %d"), half_width); } + + uint16_t lower_x, upper_x; + + // find x-boundaries for updating based on current data and start_x, end_x + if (start_x < self->data[2 * y]) { + lower_x = start_x; + } else { + lower_x = self->data[2 * y]; + } + + if (self->mirror_x) { + upper_x = self->width-lower_x; + } else { + if (end_x > self->data[2 * y + 1]) { + upper_x = end_x + 1; + } else { + upper_x = self->data[2 * y + 1] + 1; + } + } + self->data[2 * y] = start_x; self->data[2 * y + 1] = end_x; + + if (self->dirty_area.x1 == self->dirty_area.x2) { // Dirty region is empty + self->dirty_area.x1=lower_x; + self->dirty_area.x2=upper_x; + self->dirty_area.y1 = y; + if (self->mirror_y) { + self->dirty_area.y2 = self->height-y; + } else { + self->dirty_area.y2 = y+1; + } + } else { // Dirty region is not empty + if (lower_x < self->dirty_area.x1) { + self->dirty_area.x1 = lower_x; + } + if (upper_x > self->dirty_area.x2) { + self->dirty_area.x2 = upper_x; + } + if (y < self->dirty_area.y1) { + self->dirty_area.y1=y; + if (self->mirror_y) { // if y is mirrored and the lower y was updated, the upper y must be updated too + self->dirty_area.y2=self->height-y; + } + } + else { + if ( !self->mirror_y && (y >= self->dirty_area.y2) ) { // y is not mirrored + self->dirty_area.y2=y+1; + } + } + } + } uint32_t common_hal_displayio_shape_get_pixel(void *obj, int16_t x, int16_t y) { @@ -88,3 +144,21 @@ uint32_t common_hal_displayio_shape_get_pixel(void *obj, int16_t x, int16_t y) { } return 1; } + +displayio_area_t* displayio_shape_get_refresh_areas(displayio_shape_t *self, displayio_area_t* tail) { + if (self->dirty_area.x1 == self->dirty_area.x2) { + return tail; + } + self->dirty_area.next = tail; + return &self->dirty_area; +} + +void displayio_shape_finish_refresh(displayio_shape_t *self) { + self->dirty_area.x1 = 0; + self->dirty_area.x2 = 0; +} + + + + + diff --git a/shared-module/displayio/Shape.h b/shared-module/displayio/Shape.h index ca054fe008..e59ad586e7 100644 --- a/shared-module/displayio/Shape.h +++ b/shared-module/displayio/Shape.h @@ -31,6 +31,7 @@ #include #include "py/obj.h" +#include "shared-module/displayio/area.h" typedef struct { mp_obj_base_t base; @@ -41,6 +42,10 @@ typedef struct { uint16_t* data; bool mirror_x; bool mirror_y; + displayio_area_t dirty_area; } displayio_shape_t; +void displayio_shape_finish_refresh(displayio_shape_t *self); +displayio_area_t* displayio_shape_get_refresh_areas(displayio_shape_t *self, displayio_area_t* tail); + #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SHAPE_H diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index 2766cbecdc..e3642107f8 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -499,7 +499,7 @@ void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) { if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { displayio_bitmap_finish_refresh(self->bitmap); } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { - // TODO: Support shape changes. + displayio_shape_finish_refresh(self->bitmap); } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { // OnDiskBitmap changes will trigger a complete reload so no need to // track changes. @@ -543,6 +543,12 @@ displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *sel self->full_change = true; } } + } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { + displayio_area_t* refresh_area = displayio_shape_get_refresh_areas(self->bitmap, tail); + if (refresh_area != tail) { + displayio_area_copy(refresh_area, &self->dirty_area); + self->partial_change = true; + } } self->full_change = self->full_change || From 9edad9ea851528b1be4ee924c49fa3ecc67f9fe1 Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Fri, 4 Sep 2020 14:21:49 -0500 Subject: [PATCH 36/78] Delete trailing blank lines from Shape.c --- shared-module/displayio/Shape.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/shared-module/displayio/Shape.c b/shared-module/displayio/Shape.c index b8412ed9a3..a0cce60b2d 100644 --- a/shared-module/displayio/Shape.c +++ b/shared-module/displayio/Shape.c @@ -156,9 +156,4 @@ displayio_area_t* displayio_shape_get_refresh_areas(displayio_shape_t *self, dis void displayio_shape_finish_refresh(displayio_shape_t *self) { self->dirty_area.x1 = 0; self->dirty_area.x2 = 0; -} - - - - - +} \ No newline at end of file From 95db456a7ea3db6b4f8047e2fe8b0351354ac7d7 Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Fri, 4 Sep 2020 14:23:53 -0500 Subject: [PATCH 37/78] Add final newline --- shared-module/displayio/Shape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/displayio/Shape.c b/shared-module/displayio/Shape.c index a0cce60b2d..ac2abd150f 100644 --- a/shared-module/displayio/Shape.c +++ b/shared-module/displayio/Shape.c @@ -156,4 +156,4 @@ displayio_area_t* displayio_shape_get_refresh_areas(displayio_shape_t *self, dis void displayio_shape_finish_refresh(displayio_shape_t *self) { self->dirty_area.x1 = 0; self->dirty_area.x2 = 0; -} \ No newline at end of file +} From ed6cc64c4988387e79ac6889e0fd7f4984a5dfc0 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 4 Sep 2020 16:59:41 -0500 Subject: [PATCH 38/78] Corrected issue with BLE not working on nrf52840 --- ports/nrf/common-hal/busio/SPI.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c index 380ec27de4..d7d0e0fe81 100644 --- a/ports/nrf/common-hal/busio/SPI.c +++ b/ports/nrf/common-hal/busio/SPI.c @@ -104,8 +104,12 @@ void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { never_reset[i] = true; never_reset_pin_number(self->clock_pin_number); - never_reset_pin_number(self->MOSI_pin_number); - never_reset_pin_number(self->MISO_pin_number); + if ( self->MOSI_pin_number != NO_PIN) { + never_reset_pin_number(self->MOSI_pin_number); + } + if ( self->MISO_pin_number != NO_PIN) { + never_reset_pin_number(self->MISO_pin_number); + } break; } } @@ -180,7 +184,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t * if (miso != NULL) { config.miso_pin = miso->number; - self->MISO_pin_number = mosi->number; + self->MISO_pin_number = miso->number; claim_pin(miso); } else { self->MISO_pin_number = NO_PIN; @@ -204,8 +208,12 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { nrfx_spim_uninit(&self->spim_peripheral->spim); reset_pin_number(self->clock_pin_number); - reset_pin_number(self->MOSI_pin_number); - reset_pin_number(self->MISO_pin_number); + if ( self->MOSI_pin_number != NO_PIN) { + reset_pin_number(self->MOSI_pin_number); + } + if ( self->MISO_pin_number != NO_PIN) { + reset_pin_number(self->MISO_pin_number); + } } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { From 297b7195b089f08cd40f97f8a244484a82d2094e Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Fri, 4 Sep 2020 22:03:57 -0500 Subject: [PATCH 39/78] Delete unnecessary comment --- shared-module/displayio/Shape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/displayio/Shape.c b/shared-module/displayio/Shape.c index ac2abd150f..a09191cce1 100644 --- a/shared-module/displayio/Shape.c +++ b/shared-module/displayio/Shape.c @@ -49,7 +49,7 @@ void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t widt self->half_height = height; self->data = m_malloc(height * sizeof(uint32_t), false); - //for (uint16_t i = 0; i < height; i++) { + for (uint16_t i = 0; i <= height; i++) { self->data[2 * i] = 0; self->data[2 * i + 1] = width; From 2690faec4313bf36d83374ccbfab02f6abbef6dc Mon Sep 17 00:00:00 2001 From: root Date: Sat, 5 Sep 2020 11:42:06 -0500 Subject: [PATCH 40/78] Moved checks for invalid pin to common-hal/microcontroller/Pin.c --- .../atmel-samd/common-hal/microcontroller/Pin.c | 4 ++++ ports/esp32s2/common-hal/microcontroller/Pin.c | 6 ++++++ ports/nrf/common-hal/busio/SPI.c | 16 ++++------------ ports/nrf/common-hal/microcontroller/Pin.c | 3 +++ ports/stm/common-hal/microcontroller/Pin.c | 7 +++++++ 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index 5ce077eb86..ef1d8fffaa 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -106,6 +106,10 @@ void reset_all_pins(void) { } void never_reset_pin_number(uint8_t pin_number) { + if (pin_number >= PORT_BITS) { + return; + } + never_reset_pins[GPIO_PORT(pin_number)] |= 1 << GPIO_PIN(pin_number); } diff --git a/ports/esp32s2/common-hal/microcontroller/Pin.c b/ports/esp32s2/common-hal/microcontroller/Pin.c index 03a83cfe67..546dca848c 100644 --- a/ports/esp32s2/common-hal/microcontroller/Pin.c +++ b/ports/esp32s2/common-hal/microcontroller/Pin.c @@ -45,6 +45,9 @@ bool apa102_mosi_in_use; bool apa102_sck_in_use; void never_reset_pin_number(gpio_num_t pin_number) { + if (pin_number == -1 ) { + return; + } never_reset_pins[pin_number / 32] |= 1 << pin_number % 32; } @@ -54,6 +57,9 @@ void common_hal_never_reset_pin(const mcu_pin_obj_t* pin) { // Mark pin as free and return it to a quiescent state. void reset_pin_number(gpio_num_t pin_number) { + if (pin_number == -1 ) { + return; + } never_reset_pins[pin_number / 32] &= ~(1 << pin_number % 32); in_use[pin_number / 32] &= ~(1 << pin_number % 32); diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c index d7d0e0fe81..1cf074955f 100644 --- a/ports/nrf/common-hal/busio/SPI.c +++ b/ports/nrf/common-hal/busio/SPI.c @@ -104,12 +104,8 @@ void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { never_reset[i] = true; never_reset_pin_number(self->clock_pin_number); - if ( self->MOSI_pin_number != NO_PIN) { - never_reset_pin_number(self->MOSI_pin_number); - } - if ( self->MISO_pin_number != NO_PIN) { - never_reset_pin_number(self->MISO_pin_number); - } + never_reset_pin_number(self->MOSI_pin_number); + never_reset_pin_number(self->MISO_pin_number); break; } } @@ -208,12 +204,8 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { nrfx_spim_uninit(&self->spim_peripheral->spim); reset_pin_number(self->clock_pin_number); - if ( self->MOSI_pin_number != NO_PIN) { - reset_pin_number(self->MOSI_pin_number); - } - if ( self->MISO_pin_number != NO_PIN) { - reset_pin_number(self->MISO_pin_number); - } + reset_pin_number(self->MOSI_pin_number); + reset_pin_number(self->MISO_pin_number); } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c index d294c1dd5d..bc7ff831a5 100644 --- a/ports/nrf/common-hal/microcontroller/Pin.c +++ b/ports/nrf/common-hal/microcontroller/Pin.c @@ -123,6 +123,9 @@ void reset_pin_number(uint8_t pin_number) { void never_reset_pin_number(uint8_t pin_number) { + if (pin_number == NO_PIN) { + return; + } never_reset_pins[nrf_pin_port(pin_number)] |= 1 << nrf_relative_pin_number(pin_number); } diff --git a/ports/stm/common-hal/microcontroller/Pin.c b/ports/stm/common-hal/microcontroller/Pin.c index 9fbdedeade..9965132703 100644 --- a/ports/stm/common-hal/microcontroller/Pin.c +++ b/ports/stm/common-hal/microcontroller/Pin.c @@ -70,6 +70,10 @@ void reset_all_pins(void) { // Mark pin as free and return it to a quiescent state. void reset_pin_number(uint8_t pin_port, uint8_t pin_number) { + if ( pin_number == NO_PIN ) { + return; + } + if (pin_port == 0x0F) { return; } @@ -88,6 +92,9 @@ void reset_pin_number(uint8_t pin_port, uint8_t pin_number) { } void never_reset_pin_number(uint8_t pin_port, uint8_t pin_number) { + if ( pin_number == NO_PIN ) { + return; + } never_reset_pins[pin_port] |= 1< Date: Sun, 6 Sep 2020 18:03:25 -0500 Subject: [PATCH 41/78] Make sure SPI lock is free initially --- shared-module/board/__init__.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 265c6517fa..903b8fa716 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -89,6 +89,8 @@ mp_obj_t common_hal_board_create_spi(void) { const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI); const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO); common_hal_busio_spi_construct(self, clock, mosi, miso); + // make sure lock is not held initially + common_hal_busio_spi_unlock(self); spi_singleton = (mp_obj_t)self; return spi_singleton; } From 99f5011d74e3d059a59f7c382974d57f03a0b6e9 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 8 Sep 2020 17:06:09 -0700 Subject: [PATCH 42/78] Fix heap without PSRAM. Never set heap_size. --- ports/esp32s2/supervisor/port.c | 15 +++++---------- supervisor/shared/safe_mode.c | 4 ++++ supervisor/shared/safe_mode.h | 1 + 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 89ab166d51..e52b7f3762 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -59,8 +59,6 @@ void tick_timer_cb(void* arg) { supervisor_tick(); } -uint32_t* heap; - safe_mode_t port_init(void) { esp_timer_create_args_t args; args.callback = &tick_timer_cb; @@ -69,7 +67,7 @@ safe_mode_t port_init(void) { args.name = "CircuitPython Tick"; esp_timer_create(&args, &_tick_timer); - heap = malloc(HEAP_SIZE); + heap = NULL; never_reset_module_internal_pins(); #ifdef CONFIG_SPIRAM @@ -81,6 +79,10 @@ safe_mode_t port_init(void) { heap = malloc(HEAP_SIZE); heap_size = HEAP_SIZE / sizeof(uint32_t); } + if (heap == NULL) { + return NO_HEAP; + } + return NO_SAFE_MODE; } @@ -142,13 +144,6 @@ supervisor_allocation* port_fixed_stack(void) { return &_fixed_stack; } -supervisor_allocation _fixed_heap; -supervisor_allocation* port_fixed_heap(void) { - _fixed_heap.ptr = port_heap_get_bottom(); - _fixed_heap.length = (port_heap_get_top() - port_heap_get_bottom()) * sizeof(uint32_t); - return &_fixed_heap; -} - // Place the word to save just after our BSS section that gets blanked. void port_set_saved_word(uint32_t value) { } diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index 3275cc66f3..29a0a6a4ff 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -133,6 +133,10 @@ void print_safe_mode_message(safe_mode_t reason) { serial_write_compressed(translate("The CircuitPython heap was corrupted because the stack was too small.\nPlease increase the stack size if you know how, or if not:")); serial_write_compressed(FILE_AN_ISSUE); return; + case NO_HEAP: + serial_write_compressed(translate("CircuitPython was unable to allocate the heap.\n")); + serial_write_compressed(FILE_AN_ISSUE); + return; default: break; } diff --git a/supervisor/shared/safe_mode.h b/supervisor/shared/safe_mode.h index c160739aec..7d3cd63b58 100644 --- a/supervisor/shared/safe_mode.h +++ b/supervisor/shared/safe_mode.h @@ -42,6 +42,7 @@ typedef enum { FLASH_WRITE_FAIL, MEM_MANAGE, WATCHDOG_RESET, + NO_HEAP, } safe_mode_t; safe_mode_t wait_for_safe_mode_reset(void); From bdb07adfccaf25576a8f1e074db7f8b7e48890b2 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 8 Sep 2020 19:07:53 -0500 Subject: [PATCH 43/78] translations: Make decompression clearer Now this gets filled in with values e.g., 128 (0x80) and 159 (0x9f). --- py/makeqstrdata.py | 9 ++++++++- supervisor/shared/translate.c | 15 +++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 40c50b7b43..721fa83206 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -159,7 +159,14 @@ def compute_huffman_coding(translations, qstrs, compression_filename): f.write("const uint8_t lengths[] = {{ {} }};\n".format(", ".join(map(str, lengths)))) f.write("const {} values[] = {{ {} }};\n".format(values_type, ", ".join(str(ord(u)) for u in values))) f.write("#define compress_max_length_bits ({})\n".format(max_translation_encoded_length.bit_length())) - f.write("const {} ngrams[] = {{ {} }};\n".format(values_type, ", ".join(str(u) for u in ngramdata))) + f.write("const {} bigrams[] = {{ {} }};\n".format(values_type, ", ".join(str(u) for u in ngramdata))) + if len(ngrams) > 32: + bigram_start = 0xe000 + else: + bigram_start = 0x80 + bigram_end = bigram_start + len(ngrams) - 1 # End is inclusive + f.write("#define bigram_start {}\n".format(bigram_start)) + f.write("#define bigram_end {}\n".format(bigram_end)) return values, lengths, ngrams def decompress(encoding_table, encoded, encoded_length_bits): diff --git a/supervisor/shared/translate.c b/supervisor/shared/translate.c index 49ee8f143f..0235293bee 100644 --- a/supervisor/shared/translate.c +++ b/supervisor/shared/translate.c @@ -47,19 +47,18 @@ STATIC int put_utf8(char *buf, int u) { if(u <= 0x7f) { *buf = u; return 1; - } else if(MP_ARRAY_SIZE(ngrams) <= 64 && u <= 0xbf) { + } else if(bigram_start <= u && u <= bigram_end) { int n = (u - 0x80) * 2; - int ret = put_utf8(buf, ngrams[n]); - return ret + put_utf8(buf + ret, ngrams[n+1]); + // (note that at present, entries in the bigrams table are + // guaranteed not to represent bigrams themselves, so this adds + // at most 1 level of recursive call + int ret = put_utf8(buf, bigrams[n]); + return ret + put_utf8(buf + ret, bigrams[n+1]); } else if(u <= 0x07ff) { *buf++ = 0b11000000 | (u >> 6); *buf = 0b10000000 | (u & 0b00111111); return 2; - } else if(MP_ARRAY_SIZE(ngrams) > 64 && u >= 0xe000 && u <= 0xf8ff) { - int n = (u - 0xe000) * 2; - int ret = put_utf8(buf, ngrams[n]); - return ret + put_utf8(buf + ret, ngrams[n+1]); - } else { // u <= 0xffff) + } else { // u <= 0xffff *buf++ = 0b11000000 | (u >> 12); *buf = 0b10000000 | ((u >> 6) & 0b00111111); *buf = 0b10000000 | (u & 0b00111111); From d600759bc808c5e78d429b6da8c824f5574cee82 Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Tue, 8 Sep 2020 20:02:34 -0500 Subject: [PATCH 44/78] Utilize MIN and MAX functions from py/misc.h --- shared-module/displayio/Shape.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/shared-module/displayio/Shape.c b/shared-module/displayio/Shape.c index a09191cce1..4f481f2244 100644 --- a/shared-module/displayio/Shape.c +++ b/shared-module/displayio/Shape.c @@ -29,6 +29,7 @@ #include #include "py/runtime.h" +#include "py/misc.h" void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t width, uint32_t height, bool mirror_x, bool mirror_y) { @@ -76,20 +77,12 @@ void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y uint16_t lower_x, upper_x; // find x-boundaries for updating based on current data and start_x, end_x - if (start_x < self->data[2 * y]) { - lower_x = start_x; - } else { - lower_x = self->data[2 * y]; - } + lower_x = MIN(start_x, self->data[2 * y]); if (self->mirror_x) { upper_x = self->width-lower_x; } else { - if (end_x > self->data[2 * y + 1]) { - upper_x = end_x + 1; - } else { - upper_x = self->data[2 * y + 1] + 1; - } + upper_x = 1 + MAX(end_x, self->data[2 * y + 1]); } self->data[2 * y] = start_x; @@ -105,12 +98,10 @@ void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y self->dirty_area.y2 = y+1; } } else { // Dirty region is not empty - if (lower_x < self->dirty_area.x1) { - self->dirty_area.x1 = lower_x; - } - if (upper_x > self->dirty_area.x2) { - self->dirty_area.x2 = upper_x; - } + + self->dirty_area.x1 = MIN(lower_x, self->dirty_area.x1); + self->dirty_area.x2 = MAX(upper_x, self->dirty_area.x2); + if (y < self->dirty_area.y1) { self->dirty_area.y1=y; if (self->mirror_y) { // if y is mirrored and the lower y was updated, the upper y must be updated too From 0eee93729a3074461c4907f03deb803c2f35a6fe Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 8 Sep 2020 20:54:47 -0500 Subject: [PATCH 45/78] Fix decompression of unicode values above 2047 Two problems: The lead byte for 3-byte sequences was wrong, and one mid-byte was not even filled in due to a missing "++"! Apparently this was broken ever since the first "Compress as unicode, not bytes" commit, but I believed I'd "tested" it by running on the Pinyin translation. This rendered at least the Korean and Japanese translations completely illegible, affecting 5.0 and all later releases. --- supervisor/shared/translate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/supervisor/shared/translate.c b/supervisor/shared/translate.c index 0235293bee..5cd7b8dd88 100644 --- a/supervisor/shared/translate.c +++ b/supervisor/shared/translate.c @@ -59,8 +59,8 @@ STATIC int put_utf8(char *buf, int u) { *buf = 0b10000000 | (u & 0b00111111); return 2; } else { // u <= 0xffff - *buf++ = 0b11000000 | (u >> 12); - *buf = 0b10000000 | ((u >> 6) & 0b00111111); + *buf++ = 0b11100000 | (u >> 12); + *buf++ = 0b10000000 | ((u >> 6) & 0b00111111); *buf = 0b10000000 | (u & 0b00111111); return 3; } From 24a18c63f9d3990661cc58888896faba9c8fad50 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 9 Sep 2020 09:32:25 -0500 Subject: [PATCH 46/78] Moved SPI unlock to reset_board_busses() --- shared-module/board/__init__.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 903b8fa716..153aa086cc 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -89,8 +89,6 @@ mp_obj_t common_hal_board_create_spi(void) { const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI); const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO); common_hal_busio_spi_construct(self, clock, mosi, miso); - // make sure lock is not held initially - common_hal_busio_spi_unlock(self); spi_singleton = (mp_obj_t)self; return spi_singleton; } @@ -153,6 +151,7 @@ void reset_board_busses(void) { #endif #if BOARD_SPI bool display_using_spi = false; + busio_spi_obj_t *self = &spi_obj; #if CIRCUITPY_DISPLAYIO for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { mp_const_obj_t bus_type = displays[i].bus_base.type; @@ -169,6 +168,8 @@ void reset_board_busses(void) { } #endif if (!display_using_spi) { + // make sure lock is not held over a soft reset + common_hal_busio_spi_unlock(self); spi_singleton = NULL; } #endif From 59165cabbe1c27260678c4e252465b11e1cf8c0e Mon Sep 17 00:00:00 2001 From: root Date: Wed, 9 Sep 2020 10:36:55 -0500 Subject: [PATCH 47/78] Removed unneeded pointer --- shared-module/board/__init__.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 153aa086cc..ae06597910 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -151,7 +151,6 @@ void reset_board_busses(void) { #endif #if BOARD_SPI bool display_using_spi = false; - busio_spi_obj_t *self = &spi_obj; #if CIRCUITPY_DISPLAYIO for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { mp_const_obj_t bus_type = displays[i].bus_base.type; @@ -169,7 +168,7 @@ void reset_board_busses(void) { #endif if (!display_using_spi) { // make sure lock is not held over a soft reset - common_hal_busio_spi_unlock(self); + common_hal_busio_spi_unlock(&spi_obj); spi_singleton = NULL; } #endif From 5322aa5fcd5c79b84781cfd62d17ad5fbeab37eb Mon Sep 17 00:00:00 2001 From: Jelle Jager Date: Tue, 8 Sep 2020 23:49:21 +0000 Subject: [PATCH 48/78] Translated using Weblate (Dutch) Currently translated at 99.2% (779 of 785 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/nl/ --- locale/nl.po | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/locale/nl.po b/locale/nl.po index 9cce2523ed..ead58bb78b 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -6,15 +6,15 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-08-30 14:38-0400\n" -"PO-Revision-Date: 2020-08-10 19:59+0000\n" -"Last-Translator: _fonzlate \n" +"PO-Revision-Date: 2020-09-09 16:05+0000\n" +"Last-Translator: Jelle Jager \n" "Language-Team: none\n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.3-dev\n" #: main.c msgid "" @@ -456,10 +456,8 @@ msgid "Buffer length must be a multiple of 512" msgstr "Buffer lengte moet een veelvoud van 512 zijn" #: ports/stm/common-hal/sdioio/SDCard.c -#, fuzzy -#| msgid "Buffer length must be a multiple of 512" msgid "Buffer must be a multiple of 512 bytes" -msgstr "Buffer lengte moet een veelvoud van 512 zijn" +msgstr "Buffer moet een veelvoud van 512 zijn" #: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c msgid "Buffer must be at least length 1" @@ -502,7 +500,7 @@ msgstr "Kan CCCD niet toewijzen aan lokaal Characteristic" #: shared-bindings/_bleio/Adapter.c msgid "Cannot create a new Adapter; use _bleio.adapter;" -msgstr "" +msgstr "Kan geen nieuwe Adapter creëren; gebruik _bleio.adapter;" #: shared-bindings/displayio/Bitmap.c #: shared-bindings/memorymonitor/AllocationSize.c @@ -662,10 +660,8 @@ msgid "Could not restart PWM" msgstr "Kan PWM niet herstarten" #: shared-bindings/_bleio/Adapter.c -#, fuzzy -#| msgid "Could not start PWM" msgid "Could not set address" -msgstr "Kan PWM niet starten" +msgstr "Kan adres niet zetten" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "Could not start PWM" @@ -778,7 +774,7 @@ msgstr "Verwachtte een Characteristic" #: shared-bindings/_bleio/Adapter.c msgid "Expected a DigitalInOut" -msgstr "" +msgstr "Verwachtte een DigitalInOut" #: shared-bindings/_bleio/Characteristic.c msgid "Expected a Service" @@ -786,7 +782,7 @@ msgstr "Verwachtte een Service" #: shared-bindings/_bleio/Adapter.c msgid "Expected a UART" -msgstr "" +msgstr "Verwachtte een UART" #: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c #: shared-bindings/_bleio/Service.c @@ -860,7 +856,7 @@ msgstr "Bestand bestaat" #: shared-module/framebufferio/FramebufferDisplay.c #, c-format msgid "Framebuffer requires %d bytes" -msgstr "" +msgstr "Framebuffer benodigd %d bytes" #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c msgid "Frequency captured is above capability. Capture Paused." @@ -957,10 +953,8 @@ msgstr "Ongeldige %q pin" #: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c #: ports/stm/common-hal/busio/UART.c ports/stm/common-hal/sdioio/SDCard.c -#, fuzzy -#| msgid "Invalid I2C pin selection" msgid "Invalid %q pin selection" -msgstr "Ongeldige I2C pin selectie" +msgstr "Ongeldige %q pin selectie" #: ports/stm/common-hal/analogio/AnalogIn.c msgid "Invalid ADC Unit value" @@ -1478,13 +1472,12 @@ msgstr "SDA of SCL hebben een pullup nodig" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format msgid "SDIO GetCardInfo Error %d" -msgstr "" +msgstr "SDIO GetCardInfo Fout %d" #: ports/stm/common-hal/sdioio/SDCard.c -#, fuzzy, c-format -#| msgid "SPI Init Error" +#, c-format msgid "SDIO Init Error %d" -msgstr "SPI Init Fout" +msgstr "SDIO Init Fout %d" #: ports/stm/common-hal/busio/SPI.c msgid "SPI Init Error" @@ -2731,7 +2724,7 @@ msgstr "max_length moet 0-%d zijn als fixed_length %s is" #: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c msgid "max_length must be > 0" -msgstr "" +msgstr "max_length moet >0 zijn" #: py/runtime.c msgid "maximum recursion depth exceeded" From 2529ee2359a6402505172a0046e491d7deb32362 Mon Sep 17 00:00:00 2001 From: Jerry Needell Date: Wed, 9 Sep 2020 14:54:20 -0400 Subject: [PATCH 49/78] freeze rfm69 and bus_device libraries int feather_m0_rfm69 --- .gitmodules | 3 +++ frozen/Adafruit_CircuitPython_RFM69 | 1 + .../boards/feather_m0_rfm69/mpconfigboard.mk | 17 +++++++++++++++++ 3 files changed, 21 insertions(+) create mode 160000 frozen/Adafruit_CircuitPython_RFM69 diff --git a/.gitmodules b/.gitmodules index f922aae1db..3603cea696 100644 --- a/.gitmodules +++ b/.gitmodules @@ -150,3 +150,6 @@ [submodule "frozen/Adafruit_CircuitPython_RFM9x"] path = frozen/Adafruit_CircuitPython_RFM9x url = https://github.com/adafruit/Adafruit_CircuitPython_RFM9x.git +[submodule "frozen/Adafruit_CircuitPython_RFM69"] + path = frozen/Adafruit_CircuitPython_RFM69 + url = https://github.com/adafruit/Adafruit_CircuitPython_RFM69.git diff --git a/frozen/Adafruit_CircuitPython_RFM69 b/frozen/Adafruit_CircuitPython_RFM69 new file mode 160000 index 0000000000..c0b9bdf229 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_RFM69 @@ -0,0 +1 @@ +Subproject commit c0b9bdf22997552396abb514a6304d33460c2912 diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk index 7556b9517f..b589ae7665 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk @@ -10,4 +10,21 @@ INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 +# A number of modules are removed for RFM69 to make room for frozen libraries. +# Many I/O functions are not available. +CIRCUITPY_ANALOGIO = 0 +CIRCUITPY_PULSEIO = 0 +CIRCUITPY_NEOPIXEL_WRITE = 1 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_SAMD = 0 +CIRCUITPY_USB_MIDI = 0 +CIRCUITPY_USB_HID = 0 +CIRCUITPY_TOUCHIO = 0 +CFLAGS_INLINE_LIMIT = 35 +# Make more room. SUPEROPT_GC = 0 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_RFM69 From f3fc7c1c72b4119112c198cfc22fb1799d9f566c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 9 Sep 2020 14:34:57 -0700 Subject: [PATCH 50/78] Add safe mode translation --- locale/circuitpython.pot | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index d0a314d0c3..af9491c042 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-03 16:33-0700\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -582,6 +582,10 @@ msgid "" "boot. Press again to exit safe mode.\n" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "" From 40f3cd3615ca7be009ba2deb37209fa4d3993bf9 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 10 Sep 2020 13:26:51 -0400 Subject: [PATCH 51/78] Change `.report` to `.last_received_report` --- shared-bindings/usb_hid/Device.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index a6c268c74d..8f28bc422d 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -58,21 +58,21 @@ STATIC mp_obj_t usb_hid_device_send_report(mp_obj_t self_in, mp_obj_t buffer) { } MP_DEFINE_CONST_FUN_OBJ_2(usb_hid_device_send_report_obj, usb_hid_device_send_report); -//| report: bytes -//| """The HID OUT report as a `bytes`. (read-only)""" +//| last_received_report: bytes +//| """The HID OUT report as a `bytes`. (read-only). `None` if nothing received.""" //| -STATIC mp_obj_t usb_hid_device_obj_get_report(mp_obj_t self_in) { +STATIC mp_obj_t usb_hid_device_obj_get_last_received_report(mp_obj_t self_in) { usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->out_report_buffer == 0) { return mp_const_none; } return mp_obj_new_bytes(self->out_report_buffer, self->out_report_length); } -MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_report_obj, usb_hid_device_obj_get_report); +MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_last_received_report_obj, usb_hid_device_obj_get_last_received_report); -const mp_obj_property_t usb_hid_device_report_obj = { +const mp_obj_property_t usb_hid_device_last_received_report_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&usb_hid_device_get_report_obj, + .proxy = {(mp_obj_t)&usb_hid_device_get_last_received_report_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; @@ -114,10 +114,10 @@ const mp_obj_property_t usb_hid_device_usage_obj = { }; STATIC const mp_rom_map_elem_t usb_hid_device_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, - { MP_ROM_QSTR(MP_QSTR_report), MP_ROM_PTR(&usb_hid_device_report_obj) }, - { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj)}, - { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj)}, + { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_last_received_report), MP_ROM_PTR(&usb_hid_device_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj)}, + { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj)}, }; STATIC MP_DEFINE_CONST_DICT(usb_hid_device_locals_dict, usb_hid_device_locals_dict_table); From f0bb9635bf311013e7b1ff69d1a0542575cf9d0a Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 10 Sep 2020 14:21:36 -0400 Subject: [PATCH 52/78] MIssed one change for .last_received_report --- shared-bindings/usb_hid/Device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index 8f28bc422d..c7c05a9749 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -115,7 +115,7 @@ const mp_obj_property_t usb_hid_device_usage_obj = { STATIC const mp_rom_map_elem_t usb_hid_device_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, - { MP_ROM_QSTR(MP_QSTR_last_received_report), MP_ROM_PTR(&usb_hid_device_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_last_received_report), MP_ROM_PTR(&usb_hid_device_last_received_report_obj) }, { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj)}, { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj)}, }; From cacb0124acc13025c8658d9e1fe57b58780105b5 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 10 Sep 2020 20:17:27 -0500 Subject: [PATCH 53/78] feather_m4_express: Use quad data mode on flash Limor confirmed that the all shipping revisions starting with Rev D had QSPI flash chips installed. Note that when neither EXTERNAL_FLASH_QSPI_SINGLE nor EXTERNAL_FLASH_QSPI_DUAL is specified quad mode is assumed, so this is addressed by removing the setting altogether. --- ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h index ba16d17ee4..a57b18e24a 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h @@ -16,8 +16,6 @@ #define MICROPY_PORT_C (0) #define MICROPY_PORT_D (0) -#define EXTERNAL_FLASH_QSPI_DUAL - #define BOARD_HAS_CRYSTAL 1 #define DEFAULT_I2C_BUS_SCL (&pin_PA13) From 37e85aebd25502e7c1213797cde8b0c02359d029 Mon Sep 17 00:00:00 2001 From: Kevin Matocha Date: Thu, 10 Sep 2020 21:34:03 -0500 Subject: [PATCH 54/78] Fix off-by-one error, simplify the logic, add comments --- shared-module/displayio/Shape.c | 68 +++++++++++++++------------------ 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/shared-module/displayio/Shape.c b/shared-module/displayio/Shape.c index 4f481f2244..b94a392bc6 100644 --- a/shared-module/displayio/Shape.c +++ b/shared-module/displayio/Shape.c @@ -38,20 +38,20 @@ void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t widt self->width = width; if (self->mirror_x) { width /= 2; - width += self->width % 2 - 1; + width += self->width % 2; } self->half_width = width; self->height = height; if (self->mirror_y) { height /= 2; - height += self->height % 2 - 1; + height += self->height % 2; } self->half_height = height; self->data = m_malloc(height * sizeof(uint32_t), false); - for (uint16_t i = 0; i <= height; i++) { + for (uint16_t i = 0; i < height; i++) { self->data[2 * i] = 0; self->data[2 * i + 1] = width; } @@ -63,58 +63,52 @@ void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t widt } void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y, uint16_t start_x, uint16_t end_x) { - if (y < 0 || y >= self->height || (self->mirror_y && y > self->half_height)) { + if (y < 0 || y >= self->height || (self->mirror_y && y >= self->half_height)) { mp_raise_ValueError(translate("y value out of bounds")); } - if (start_x < 0 || start_x > self->width || end_x < 0 || end_x > self->width) { + if (start_x < 0 || start_x >= self->width || end_x < 0 || end_x >= self->width) { mp_raise_ValueError(translate("x value out of bounds")); } - uint16_t half_width = self->width / 2 - 1 + self->width % 2; - if (self->mirror_x && (start_x > half_width || end_x > half_width)) { - mp_raise_ValueError_varg(translate("Maximum x value when mirrored is %d"), half_width); + if (self->mirror_x && (start_x >= self->half_width || end_x >= self->half_width)) { + mp_raise_ValueError_varg(translate("Maximum x value when mirrored is %d"), self->half_width); } - uint16_t lower_x, upper_x; + uint16_t lower_x, upper_x, lower_y, upper_y; - // find x-boundaries for updating based on current data and start_x, end_x + // find x-boundaries for updating based on current data and start_x, end_x, and mirror_x lower_x = MIN(start_x, self->data[2 * y]); if (self->mirror_x) { - upper_x = self->width-lower_x; + upper_x = self->width - lower_x + 1; // dirty rectangles are treated with max value exclusive } else { - upper_x = 1 + MAX(end_x, self->data[2 * y + 1]); + upper_x = MAX(end_x, self->data[2 * y + 1]) + 1; // dirty rectangles are treated with max value exclusive } - self->data[2 * y] = start_x; + // find y-boundaries based on y and mirror_y + lower_y = y; + + if (self->mirror_y) { + upper_y = self->height - lower_y + 1; // dirty rectangles are treated with max value exclusive + } else { + upper_y = y + 1; // dirty rectangles are treated with max value exclusive + } + + self->data[2 * y] = start_x; // update the data array with the new boundaries self->data[2 * y + 1] = end_x; if (self->dirty_area.x1 == self->dirty_area.x2) { // Dirty region is empty - self->dirty_area.x1=lower_x; - self->dirty_area.x2=upper_x; - self->dirty_area.y1 = y; - if (self->mirror_y) { - self->dirty_area.y2 = self->height-y; - } else { - self->dirty_area.y2 = y+1; - } - } else { // Dirty region is not empty + self->dirty_area.x1 = lower_x; + self->dirty_area.x2 = upper_x; + self->dirty_area.y1 = lower_y; + self->dirty_area.y2 = upper_y; + } else { // Dirty region is not empty self->dirty_area.x1 = MIN(lower_x, self->dirty_area.x1); self->dirty_area.x2 = MAX(upper_x, self->dirty_area.x2); - if (y < self->dirty_area.y1) { - self->dirty_area.y1=y; - if (self->mirror_y) { // if y is mirrored and the lower y was updated, the upper y must be updated too - self->dirty_area.y2=self->height-y; - } - } - else { - if ( !self->mirror_y && (y >= self->dirty_area.y2) ) { // y is not mirrored - self->dirty_area.y2=y+1; - } - } + self->dirty_area.y1 = MIN(lower_y, self->dirty_area.y1); + self->dirty_area.y2 = MAX(upper_y, self->dirty_area.y2); } - } uint32_t common_hal_displayio_shape_get_pixel(void *obj, int16_t x, int16_t y) { @@ -122,10 +116,10 @@ uint32_t common_hal_displayio_shape_get_pixel(void *obj, int16_t x, int16_t y) { if (x >= self->width || x < 0 || y >= self->height || y < 0) { return 0; } - if (self->mirror_x && x > self->half_width) { - x = self->width - 1 - x; + if (self->mirror_x && x >= self->half_width) { + x = self->width - x - 1; } - if (self->mirror_y && y > self->half_height) { + if (self->mirror_y && y >= self->half_height) { y = self->height - y - 1; } uint16_t start_x = self->data[2 * y]; From 305bed6d9e9581ed19d2043622bc77106a0c3b5b Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Fri, 11 Sep 2020 21:06:54 +0530 Subject: [PATCH 55/78] Added esp32s2 safe_mode & fixed user_safe_mode --- .../espressif_saola_1_wroom/mpconfigboard.h | 4 + .../espressif_saola_1_wrover/mpconfigboard.h | 4 + .../boards/microdev_micro_s2/mpconfigboard.h | 4 + supervisor/shared/safe_mode.c | 155 ++++++++++-------- 4 files changed, 96 insertions(+), 71 deletions(-) diff --git a/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h b/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h index a94f10ea49..6d603ba57b 100644 --- a/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h +++ b/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -31,4 +31,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO18) +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up." + #define AUTORESET_DELAY_MS 500 diff --git a/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h b/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h index 338186dc52..f5b6c7948e 100644 --- a/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h +++ b/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h @@ -31,4 +31,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO18) +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up." + #define AUTORESET_DELAY_MS 500 diff --git a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h index bb28fe16ad..d844f37d09 100644 --- a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h +++ b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h @@ -32,4 +32,8 @@ #define MICROPY_HW_LED (&pin_GPIO21) #define MICROPY_HW_NEOPIXEL (&pin_GPIO33) +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up." + #define AUTORESET_DELAY_MS 500 diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index 29a0a6a4ff..cbbdfe4276 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -60,6 +60,11 @@ safe_mode_t wait_for_safe_mode_reset(void) { common_hal_digitalio_digitalinout_construct(&status_led, MICROPY_HW_LED_STATUS); common_hal_digitalio_digitalinout_switch_to_output(&status_led, true, DRIVE_MODE_PUSH_PULL); #endif + #ifdef CIRCUITPY_BOOT_BUTTON + digitalio_digitalinout_obj_t boot_button; + common_hal_digitalio_digitalinout_construct(&boot_button, CIRCUITPY_BOOT_BUTTON); + common_hal_digitalio_digitalinout_switch_to_input(&boot_button, PULL_UP); + #endif uint64_t start_ticks = supervisor_ticks_ms64(); uint64_t diff = 0; while (diff < 700) { @@ -67,6 +72,11 @@ safe_mode_t wait_for_safe_mode_reset(void) { // Blink on for 100, off for 100, on for 100, off for 100 and on for 200 common_hal_digitalio_digitalinout_set_value(&status_led, diff > 100 && diff / 100 != 2 && diff / 100 != 4); #endif + #ifdef CIRCUITPY_BOOT_BUTTON + if (!common_hal_digitalio_digitalinout_get_value(&boot_button)) { + return USER_SAFE_MODE; + } + #endif diff = supervisor_ticks_ms64() - start_ticks; } #ifdef MICROPY_HW_LED_STATUS @@ -103,77 +113,80 @@ void print_safe_mode_message(safe_mode_t reason) { return; } serial_write("\n"); - // Output a user safe mode string if it's set. - #ifdef BOARD_USER_SAFE_MODE - if (reason == USER_SAFE_MODE) { - serial_write_compressed(translate("You requested starting safe mode by ")); - serial_write(BOARD_USER_SAFE_MODE_ACTION); - serial_write_compressed(translate("\nTo exit, please reset the board without ")); - serial_write(BOARD_USER_SAFE_MODE_ACTION); - serial_write("\n"); - } else - #endif - switch (reason) { - case MANUAL_SAFE_MODE: - serial_write_compressed(translate("CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.\n")); - return; - case PROGRAMMATIC_SAFE_MODE: - serial_write_compressed(translate("The `microcontroller` module was used to boot into safe mode. Press reset to exit safe mode.\n")); - return; - default: - break; - } - serial_write_compressed(translate("You are in safe mode: something unanticipated happened.\n")); - switch (reason) { - case BROWNOUT: - serial_write_compressed(translate("The microcontroller's power dipped. Make sure your power supply provides\nenough power for the whole circuit and press reset (after ejecting CIRCUITPY).\n")); - return; - case HEAP_OVERWRITTEN: - serial_write_compressed(translate("The CircuitPython heap was corrupted because the stack was too small.\nPlease increase the stack size if you know how, or if not:")); - serial_write_compressed(FILE_AN_ISSUE); - return; - case NO_HEAP: - serial_write_compressed(translate("CircuitPython was unable to allocate the heap.\n")); - serial_write_compressed(FILE_AN_ISSUE); - return; - default: - break; - } + switch (reason) { + case USER_SAFE_MODE: + #ifdef BOARD_USER_SAFE_MODE_ACTION + // Output a user safe mode string if it's set. + serial_write_compressed(translate("You requested starting safe mode by ")); + serial_write_compressed(translate(BOARD_USER_SAFE_MODE_ACTION)); + serial_write_compressed(translate("\nTo exit, please reset the board without ")); + serial_write_compressed(translate(BOARD_USER_SAFE_MODE_ACTION)); + serial_write("\n"); + #else + // fallthrough + #endif + return; + case MANUAL_SAFE_MODE: + serial_write_compressed(translate("CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.\n")); + return; + case PROGRAMMATIC_SAFE_MODE: + serial_write_compressed(translate("The `microcontroller` module was used to boot into safe mode. Press reset to exit safe mode.\n")); + return; + default: + break; + } - serial_write_compressed(translate("CircuitPython core code crashed hard. Whoops!\n")); - switch (reason) { - case HARD_CRASH: - serial_write_compressed(translate("Crash into the HardFault_Handler.")); - return; - case MICROPY_NLR_JUMP_FAIL: - serial_write_compressed(translate("MicroPython NLR jump failed. Likely memory corruption.")); - return; - case MICROPY_FATAL_ERROR: - serial_write_compressed(translate("MicroPython fatal error.")); - break; - case GC_ALLOC_OUTSIDE_VM: - serial_write_compressed(translate("Attempted heap allocation when MicroPython VM not running.")); - break; -#ifdef SOFTDEVICE_PRESENT - // defined in ports/nrf/bluetooth/bluetooth_common.mk - // will print "Unknown reason" if somehow encountered on other ports - case NORDIC_SOFT_DEVICE_ASSERT: - serial_write_compressed(translate("Nordic Soft Device failure assertion.")); - break; -#endif - case FLASH_WRITE_FAIL: - serial_write_compressed(translate("Failed to write internal flash.")); - break; - case MEM_MANAGE: - serial_write_compressed(translate("Invalid memory access.")); - break; - case WATCHDOG_RESET: - serial_write_compressed(translate("Watchdog timer expired.")); - break; - default: - serial_write_compressed(translate("Unknown reason.")); - break; - } - serial_write_compressed(FILE_AN_ISSUE); + serial_write_compressed(translate("You are in safe mode: something unanticipated happened.\n")); + switch (reason) { + case BROWNOUT: + serial_write_compressed(translate("The microcontroller's power dipped. Make sure your power supply provides\nenough power for the whole circuit and press reset (after ejecting CIRCUITPY).\n")); + return; + case HEAP_OVERWRITTEN: + serial_write_compressed(translate("The CircuitPython heap was corrupted because the stack was too small.\nPlease increase the stack size if you know how, or if not:")); + serial_write_compressed(FILE_AN_ISSUE); + return; + case NO_HEAP: + serial_write_compressed(translate("CircuitPython was unable to allocate the heap.\n")); + serial_write_compressed(FILE_AN_ISSUE); + return; + default: + break; + } + + serial_write_compressed(translate("CircuitPython core code crashed hard. Whoops!\n")); + switch (reason) { + case HARD_CRASH: + serial_write_compressed(translate("Crash into the HardFault_Handler.")); + return; + case MICROPY_NLR_JUMP_FAIL: + serial_write_compressed(translate("MicroPython NLR jump failed. Likely memory corruption.")); + return; + case MICROPY_FATAL_ERROR: + serial_write_compressed(translate("MicroPython fatal error.")); + break; + case GC_ALLOC_OUTSIDE_VM: + serial_write_compressed(translate("Attempted heap allocation when MicroPython VM not running.")); + break; + #ifdef SOFTDEVICE_PRESENT + // defined in ports/nrf/bluetooth/bluetooth_common.mk + // will print "Unknown reason" if somehow encountered on other ports + case NORDIC_SOFT_DEVICE_ASSERT: + serial_write_compressed(translate("Nordic Soft Device failure assertion.")); + break; + #endif + case FLASH_WRITE_FAIL: + serial_write_compressed(translate("Failed to write internal flash.")); + break; + case MEM_MANAGE: + serial_write_compressed(translate("Invalid memory access.")); + break; + case WATCHDOG_RESET: + serial_write_compressed(translate("Watchdog timer expired.")); + break; + default: + serial_write_compressed(translate("Unknown reason.")); + break; + } + serial_write_compressed(FILE_AN_ISSUE); } From 870326b2218e24a20f40c8ee72f3ec27d0f3813b Mon Sep 17 00:00:00 2001 From: root Date: Fri, 11 Sep 2020 10:54:46 -0500 Subject: [PATCH 56/78] Moved SPI unlock code --- shared-module/board/__init__.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index ae06597910..7d99f2d4e3 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -166,9 +166,9 @@ void reset_board_busses(void) { #endif } #endif + // make sure SPI lock is not held over a soft reset + common_hal_busio_spi_unlock(&spi_obj); if (!display_using_spi) { - // make sure lock is not held over a soft reset - common_hal_busio_spi_unlock(&spi_obj); spi_singleton = NULL; } #endif From 5197085d790e6d0f072fe18d0f5b742847a6d8bd Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Thu, 10 Sep 2020 20:20:55 +0200 Subject: [PATCH 57/78] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/ID.po | 36 +++++++++++++++++- locale/cs.po | 36 +++++++++++++++++- locale/de_DE.po | 36 +++++++++++++++++- locale/es.po | 36 +++++++++++++++++- locale/fil.po | 36 +++++++++++++++++- locale/fr.po | 36 +++++++++++++++++- locale/hi.po | 36 +++++++++++++++++- locale/it_IT.po | 36 +++++++++++++++++- locale/ja.po | 81 ++++++++++++++++++++++++++++++++++------ locale/ko.po | 36 +++++++++++++++++- locale/nl.po | 36 +++++++++++++++++- locale/pl.po | 36 +++++++++++++++++- locale/pt_BR.po | 36 +++++++++++++++++- locale/sv.po | 36 +++++++++++++++++- locale/zh_Latn_pinyin.po | 36 +++++++++++++++++- 15 files changed, 546 insertions(+), 39 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index dd41b740f1..6312e0e242 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2020-07-06 18:10+0000\n" "Last-Translator: oon arfiandwi \n" "Language-Team: LANGUAGE \n" @@ -279,7 +279,7 @@ msgstr "pow() 3-arg tidak didukung" msgid "A hardware interrupt channel is already in use" msgstr "Sebuah channel hardware interrupt sedang digunakan" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "Alamat harus sepanjang %d byte" @@ -377,6 +377,10 @@ msgstr "" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "Mencoba alokasi heap ketika MicroPython VM tidak berjalan." +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "Auto-reload tidak aktif.\n" @@ -596,6 +600,10 @@ msgstr "" "CircuitPython dalam mode aman karena Anda menekan tombol reset saat boot. " "Tekan lagi untuk keluar dari mode aman.\n" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "Init pin clock gagal." @@ -1244,6 +1252,10 @@ msgstr "" msgid "No more timers available on this pin." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "" @@ -1264,6 +1276,10 @@ msgstr "" msgid "Nordic Soft Device failure assertion." msgstr "" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c #, fuzzy @@ -1309,6 +1325,10 @@ msgid "" "%d bpp given" msgstr "" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "" @@ -1508,6 +1528,10 @@ msgstr "" msgid "Serializer in use" msgstr "Serializer sedang digunakan" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1703,6 +1727,10 @@ msgstr "" msgid "Unexpected nrfx uuid type" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1813,6 +1841,10 @@ msgstr "" "\n" "Untuk menampilkan modul built-in silahkan ketik `help(\"modules\")`.\n" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index 3e22ac2514..db04b0fff5 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2020-05-24 03:22+0000\n" "Last-Translator: dronecz \n" "Language-Team: LANGUAGE \n" @@ -279,7 +279,7 @@ msgstr "" msgid "A hardware interrupt channel is already in use" msgstr "" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "" @@ -377,6 +377,10 @@ msgstr "" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "" @@ -584,6 +588,10 @@ msgid "" "boot. Press again to exit safe mode.\n" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "" @@ -1227,6 +1235,10 @@ msgstr "" msgid "No more timers available on this pin." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "" @@ -1247,6 +1259,10 @@ msgstr "" msgid "Nordic Soft Device failure assertion." msgstr "" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1291,6 +1307,10 @@ msgid "" "%d bpp given" msgstr "" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "" @@ -1487,6 +1507,10 @@ msgstr "" msgid "Serializer in use" msgstr "" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1682,6 +1706,10 @@ msgstr "" msgid "Unexpected nrfx uuid type" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1785,6 +1813,10 @@ msgid "" "To list built-in modules please do `help(\"modules\")`.\n" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 3debbcb621..388f0932b6 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2020-06-16 18:24+0000\n" "Last-Translator: Andreas Buchen \n" "Language: de_DE\n" @@ -278,7 +278,7 @@ msgstr "3-arg pow() wird nicht unterstützt" msgid "A hardware interrupt channel is already in use" msgstr "Ein Hardware Interrupt Kanal wird schon benutzt" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "Die Adresse muss %d Bytes lang sein" @@ -378,6 +378,10 @@ msgstr "" "Versuch einer Heap Reservierung, wenn die MicroPython-VM nicht ausgeführt " "wird." +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "Automatisches Neuladen ist deaktiviert.\n" @@ -592,6 +596,10 @@ msgstr "" "Reset-Taste gedrückt haben. Drücken Sie erneut, um den abgesicherten Modus " "zu verlassen.\n" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "Clock pin init fehlgeschlagen." @@ -1246,6 +1254,10 @@ msgstr "Keine langen Integer (long) unterstützt" msgid "No more timers available on this pin." msgstr "An diesem Pin sind keine Timer mehr verfügbar." +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "Kein Pulldown Widerstand am Pin; 1Mohm wird vorgeschlagen" @@ -1266,6 +1278,10 @@ msgstr "Kein Timer verfügbar" msgid "Nordic Soft Device failure assertion." msgstr "Fehlerbehauptung für Nordic Soft Device." +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1316,6 +1332,10 @@ msgstr "" "Nur monochrome, indizierte 4bpp oder 8bpp, und 16bpp oder größere BMPs " "unterstützt: %d bpp wurden gegeben" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Oversample muss ein Vielfaches von 8 sein." @@ -1517,6 +1537,10 @@ msgstr "Ausgewählter RTS-Pin ungültig" msgid "Serializer in use" msgstr "Serializer wird benutzt" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Slice und Wert (value) haben unterschiedliche Längen." @@ -1726,6 +1750,10 @@ msgstr "Schreiben in nvm nicht möglich." msgid "Unexpected nrfx uuid type" msgstr "Unerwarteter nrfx uuid-Typ" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1840,6 +1868,10 @@ msgstr "" "Um die integrierten Module aufzulisten, führe bitte `help(\"modules\")` " "aus.\n" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "Schreiben nicht unterstüzt für die Characteristic" diff --git a/locale/es.po b/locale/es.po index 15b4fe7806..0f37aa1eb0 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2020-08-17 21:11+0000\n" "Last-Translator: Alvaro Figueroa \n" "Language-Team: \n" @@ -282,7 +282,7 @@ msgstr "pow() con 3 argumentos no soportado" msgid "A hardware interrupt channel is already in use" msgstr "El canal EXTINT ya está siendo utilizado" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "La dirección debe ser %d bytes de largo" @@ -384,6 +384,10 @@ msgstr "" "Se intentó asignación del montículo, sin que la VM de MicroPython esté " "ejecutando." +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "Auto-recarga deshabilitada.\n" @@ -597,6 +601,10 @@ msgstr "" "CircuitPython está en modo seguro porque presionó el botón de reinicio " "durante el arranque. Presione nuevamente para salir del modo seguro.\n" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "Iniciado de pin de reloj fallido." @@ -1245,6 +1253,10 @@ msgstr "No hay soporte de entero largo" msgid "No more timers available on this pin." msgstr "No hay más temporizadores disponibles en este pin." +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "No hay pulldown en el pin; 1Mohm recomendado" @@ -1265,6 +1277,10 @@ msgstr "No hay temporizador disponible" msgid "Nordic Soft Device failure assertion." msgstr "fallo de aserción de dispositivo Nordic Soft." +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1315,6 +1331,10 @@ msgstr "" "Solo se admiten BMP monocromáticos, indexados de 4 bpp u 8 bpp y 16 bpp o " "más: %d bpp proporcionados" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "El sobremuestreo debe ser un múltiplo de 8." @@ -1516,6 +1536,10 @@ msgstr "Pin RTS seleccionado no válido" msgid "Serializer in use" msgstr "Serializer está siendo utilizado" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Slice y value tienen tamaños diferentes." @@ -1725,6 +1749,10 @@ msgstr "Imposible escribir en nvm." msgid "Unexpected nrfx uuid type" msgstr "Tipo de uuid nrfx inesperado" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1839,6 +1867,10 @@ msgstr "" "\n" "Para listar los módulos incorporados por favor haga `help(\"modules\")`.\n" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "Escrituras no admitidas en la característica" diff --git a/locale/fil.po b/locale/fil.po index 5bb696c83b..2283dff2bb 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -274,7 +274,7 @@ msgstr "3-arg pow() hindi suportado" msgid "A hardware interrupt channel is already in use" msgstr "Isang channel ng hardware interrupt ay ginagamit na" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, fuzzy, c-format msgid "Address must be %d bytes long" msgstr "ang palette ay dapat 32 bytes ang haba" @@ -373,6 +373,10 @@ msgstr "" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "Awtomatikong pag re-reload ay OFF.\n" @@ -584,6 +588,10 @@ msgid "" "boot. Press again to exit safe mode.\n" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "Nabigo sa pag init ng Clock pin." @@ -1235,6 +1243,10 @@ msgstr "" msgid "No more timers available on this pin." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "" @@ -1255,6 +1267,10 @@ msgstr "" msgid "Nordic Soft Device failure assertion." msgstr "" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c #, fuzzy @@ -1302,6 +1318,10 @@ msgid "" "%d bpp given" msgstr "" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Oversample ay dapat multiple ng 8." @@ -1502,6 +1522,10 @@ msgstr "" msgid "Serializer in use" msgstr "Serializer ginagamit" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Slice at value iba't ibang haba." @@ -1698,6 +1722,10 @@ msgstr "Hindi ma i-sulat sa NVM." msgid "Unexpected nrfx uuid type" msgstr "hindi inaasahang indent" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1810,6 +1838,10 @@ msgstr "" "\n" "Para makita ang listahan ng modules, `help(“modules”)`.\n" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "" diff --git a/locale/fr.po b/locale/fr.po index 3ab4858020..49da4ac4e3 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2020-07-27 21:27+0000\n" "Last-Translator: Nathan \n" "Language: fr\n" @@ -283,7 +283,7 @@ msgstr "pow() non supporté avec 3 arguments" msgid "A hardware interrupt channel is already in use" msgstr "Un canal d'interruptions matérielles est déjà utilisé" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "L'adresse doit être longue de %d octets" @@ -384,6 +384,10 @@ msgstr "" "Tentative d'allocation de segments lorsque la machine virtuelle MicroPython " "n'est pas en cours d'exécution." +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "L'auto-chargement est désactivé.\n" @@ -600,6 +604,10 @@ msgstr "" "réinitialisation pendant le démarrage. Appuyez à nouveau pour quitter le " "mode sans échec.\n" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "Echec de l'init. de la broche d'horloge." @@ -1249,6 +1257,10 @@ msgstr "Pas de support entier long" msgid "No more timers available on this pin." msgstr "Plus de minuteurs disponibles sur cette broche." +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "Pas de pulldown sur la broche ; 1Mohm recommandé" @@ -1269,6 +1281,10 @@ msgstr "Pas de minuterie disponible" msgid "Nordic Soft Device failure assertion." msgstr "Affirmation de défaillance du Nordic Soft Device." +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1319,6 +1335,10 @@ msgstr "" "Prise en charge uniquement des monochromes, 4 bpp ou 8 bpp indexés et 16 bpp " "ou plus : %d bpp fournis" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Le sur-échantillonage doit être un multiple de 8." @@ -1522,6 +1542,10 @@ msgstr "Broche RTS sélectionnée non valide" msgid "Serializer in use" msgstr "Sérialiseur en cours d'utilisation" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Tranche et valeur de tailles différentes." @@ -1730,6 +1754,10 @@ msgstr "Impossible d'écrire sur la mémoire non-volatile." msgid "Unexpected nrfx uuid type" msgstr "Type inattendu pour l'uuid nrfx" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1846,6 +1874,10 @@ msgstr "" "\n" "Pour lister les modules inclus, tapez `help(\"modules\")`.\n" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "Écritures non prises en charge sur la caractéristique" diff --git a/locale/hi.po b/locale/hi.po index 3803348aa4..bf85b19d70 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -272,7 +272,7 @@ msgstr "" msgid "A hardware interrupt channel is already in use" msgstr "" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "" @@ -370,6 +370,10 @@ msgstr "" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "" @@ -577,6 +581,10 @@ msgid "" "boot. Press again to exit safe mode.\n" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "" @@ -1220,6 +1228,10 @@ msgstr "" msgid "No more timers available on this pin." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "" @@ -1240,6 +1252,10 @@ msgstr "" msgid "Nordic Soft Device failure assertion." msgstr "" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1284,6 +1300,10 @@ msgid "" "%d bpp given" msgstr "" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "" @@ -1480,6 +1500,10 @@ msgstr "" msgid "Serializer in use" msgstr "" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1675,6 +1699,10 @@ msgstr "" msgid "Unexpected nrfx uuid type" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1778,6 +1806,10 @@ msgid "" "To list built-in modules please do `help(\"modules\")`.\n" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index e9dfc0474d..cfc6b76a56 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -273,7 +273,7 @@ msgstr "pow() con tre argmomenti non supportata" msgid "A hardware interrupt channel is already in use" msgstr "Un canale di interrupt hardware è già in uso" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, fuzzy, c-format msgid "Address must be %d bytes long" msgstr "la palette deve essere lunga 32 byte" @@ -372,6 +372,10 @@ msgstr "" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "Auto-reload disattivato.\n" @@ -585,6 +589,10 @@ msgid "" "boot. Press again to exit safe mode.\n" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "Inizializzazione del pin di clock fallita." @@ -1239,6 +1247,10 @@ msgstr "" msgid "No more timers available on this pin." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "" @@ -1259,6 +1271,10 @@ msgstr "" msgid "Nordic Soft Device failure assertion." msgstr "" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c #, fuzzy @@ -1307,6 +1323,10 @@ msgid "" "%d bpp given" msgstr "" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "L'oversampling deve essere multiplo di 8." @@ -1513,6 +1533,10 @@ msgstr "" msgid "Serializer in use" msgstr "Serializer in uso" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1709,6 +1733,10 @@ msgstr "Imposibile scrivere su nvm." msgid "Unexpected nrfx uuid type" msgstr "indentazione inaspettata" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1813,6 +1841,10 @@ msgid "" "To list built-in modules please do `help(\"modules\")`.\n" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "" diff --git a/locale/ja.po b/locale/ja.po index b9fb7ce7a5..b66e9a06d9 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-27 11:21-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2020-09-01 18:44+0000\n" "Last-Translator: Jeff Epler \n" "Language-Team: none\n" @@ -282,7 +282,7 @@ msgstr "引数3つのpow()はサポートされていません" msgid "A hardware interrupt channel is already in use" msgstr "ハードウェア割り込みチャネルは使用中" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "アドレスは、%dバイト長でなければなりません" @@ -380,6 +380,10 @@ msgstr "%d個のブロックの確保を試みました" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "MicroPython VM 非実行時にヒープの確保を試みました" +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "オートリロードはオフです。\n" @@ -503,6 +507,10 @@ msgstr "" msgid "Can't set CCCD on local Characteristic" msgstr "ローカルのCharacteristicにはCCCDを設定できません" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot create a new Adapter; use _bleio.adapter;" +msgstr "" + #: shared-bindings/displayio/Bitmap.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c @@ -589,6 +597,10 @@ msgstr "" "起動中にリセットボタンを押したためCircuitPythonはセーフモードにいます。もう一" "度押すとセーフモードを終了します。\n" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "クロックピンの初期化に失敗" @@ -757,8 +769,8 @@ msgstr "EXTINTチャネルはすでに使用されています" msgid "Error in regex" msgstr "正規表現にエラーがあります" -#: shared-bindings/aesio/aes.c shared-bindings/busio/SPI.c -#: shared-bindings/microcontroller/Pin.c +#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c msgid "Expected a %q" @@ -769,10 +781,18 @@ msgstr "%qが必要" msgid "Expected a Characteristic" msgstr "" +#: shared-bindings/_bleio/Adapter.c +msgid "Expected a DigitalInOut" +msgstr "" + #: shared-bindings/_bleio/Characteristic.c msgid "Expected a Service" msgstr "" +#: shared-bindings/_bleio/Adapter.c +msgid "Expected a UART" +msgstr "" + #: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c #: shared-bindings/_bleio/Service.c msgid "Expected a UUID" @@ -900,7 +920,9 @@ msgstr "IVは%dバイト長でなければなりません" msgid "" "Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" "mpy-update for more info." -msgstr "非互換の.mpyファイルです。全ての.mpyファイルを更新してください。詳細は http://adafru.it/mpy-update を参照" +msgstr "" +"非互換の.mpyファイルです。全ての.mpyファイルを更新してください。詳細は " +"http://adafru.it/mpy-update を参照" #: shared-bindings/_pew/PewPew.c msgid "Incorrect buffer size" @@ -1224,6 +1246,10 @@ msgstr "long integerサポートがありません" msgid "No more timers available on this pin." msgstr "このピンに利用可能なタイマーがもうありません" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "ピンにプルダウンがありません。1Mオーム推奨" @@ -1244,6 +1270,10 @@ msgstr "利用できるタイマーなし" msgid "Nordic Soft Device failure assertion." msgstr "" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1258,6 +1288,10 @@ msgstr "再生していません" msgid "Not running saved code.\n" msgstr "保存されたコードは実行していません。\n" +#: shared-bindings/_bleio/__init__.c +msgid "Not settable" +msgstr "" + #: shared-bindings/util.c msgid "" "Object has been deinitialized and can no longer be used. Create a new object." @@ -1286,6 +1320,10 @@ msgid "" "%d bpp given" msgstr "" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "オーバーサンプルは8の倍数が必要" @@ -1293,7 +1331,8 @@ msgstr "オーバーサンプルは8の倍数が必要" #: shared-bindings/pwmio/PWMOut.c msgid "" "PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)" -msgstr "PWMのduty_cycle値は0から65535の間でなければなりません(16ビット解像度)" +msgstr "" +"PWMのduty_cycle値は0から65535の間でなければなりません(16ビット解像度)" #: shared-bindings/pwmio/PWMOut.c msgid "" @@ -1367,10 +1406,6 @@ msgstr "いずれかのキーを押すとREPLに入ります。リロードはCT msgid "Pull not used when direction is output." msgstr "方向がoutputのときpullは使われません" -#: ports/stm/ref/pulseout-pre-timeralloc.c -msgid "PulseOut not supported on this chip" -msgstr "PulseOutはこのチップでサポートされていません" - #: ports/stm/common-hal/os/__init__.c msgid "RNG DeInit Error" msgstr "RNG解体エラー" @@ -1487,6 +1522,10 @@ msgstr "選択されたRTSピンが正しくありません" msgid "Serializer in use" msgstr "シリアライザは使用中" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "スライスと値の長さが一致しません" @@ -1692,6 +1731,10 @@ msgstr "nvm に書き込みできません" msgid "Unexpected nrfx uuid type" msgstr "想定されていないnrfx UUID型" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1795,6 +1838,10 @@ msgid "" "To list built-in modules please do `help(\"modules\")`.\n" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "" @@ -2483,6 +2530,10 @@ msgstr "" msgid "initial values must be iterable" msgstr "" +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +msgid "initial_value length is wrong" +msgstr "" + #: py/compile.c msgid "inline assembler must be a function" msgstr "インラインアセンブラは関数でなければなりません" @@ -2675,6 +2726,10 @@ msgstr "正定値行列ではありません" msgid "max_length must be 0-%d when fixed_length is %s" msgstr "" +#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c +msgid "max_length must be > 0" +msgstr "" + #: py/runtime.c msgid "maximum recursion depth exceeded" msgstr "最大の再帰深度を超えました" @@ -3024,7 +3079,8 @@ msgstr "rsplit(None,n)" msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" -msgstr "sample_source バッファには bytearray または 'h','H','b','B'型のarrayが必要" +msgstr "" +"sample_source バッファには bytearray または 'h','H','b','B'型のarrayが必要" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3394,6 +3450,9 @@ msgstr "ziはfloat値が必要" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "PulseOut not supported on this chip" +#~ msgstr "PulseOutはこのチップでサポートされていません" + #~ msgid "Invalid I2C pin selection" #~ msgstr "I2Cピンの選択が不正です" diff --git a/locale/ko.po b/locale/ko.po index a4e088bc40..858d117f26 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2019-05-06 14:22-0700\n" "Last-Translator: \n" "Language-Team: LANGUAGE \n" @@ -273,7 +273,7 @@ msgstr "" msgid "A hardware interrupt channel is already in use" msgstr "" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "" @@ -371,6 +371,10 @@ msgstr "" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "자동 재 장전이 꺼져 있습니다\n" @@ -580,6 +584,10 @@ msgid "" "boot. Press again to exit safe mode.\n" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "" @@ -1223,6 +1231,10 @@ msgstr "" msgid "No more timers available on this pin." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "" @@ -1243,6 +1255,10 @@ msgstr "" msgid "Nordic Soft Device failure assertion." msgstr "" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1287,6 +1303,10 @@ msgid "" "%d bpp given" msgstr "" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "" @@ -1483,6 +1503,10 @@ msgstr "" msgid "Serializer in use" msgstr "" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1679,6 +1703,10 @@ msgstr "" msgid "Unexpected nrfx uuid type" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1782,6 +1810,10 @@ msgid "" "To list built-in modules please do `help(\"modules\")`.\n" msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "" diff --git a/locale/nl.po b/locale/nl.po index ead58bb78b..470e9db9c5 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2020-09-09 16:05+0000\n" "Last-Translator: Jelle Jager \n" "Language-Team: none\n" @@ -279,7 +279,7 @@ msgstr "3-arg pow() niet ondersteund" msgid "A hardware interrupt channel is already in use" msgstr "Een hardware interrupt kanaal is al in gebruik" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "Adres moet %d bytes lang zijn" @@ -377,6 +377,10 @@ msgstr "Poging om %d blokken toe te wijzen" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "heap allocatie geprobeerd terwijl MicroPython VM niet draait." +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "Auto-herlaad staat uit.\n" @@ -590,6 +594,10 @@ msgstr "" "CircuitPython is in veilige modus omdat de rest knop werd ingedrukt tijdens " "het opstarten. Druk nogmaals om veilige modus te verlaten\n" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "Clock pin init mislukt." @@ -1239,6 +1247,10 @@ msgstr "Geen lange integer ondersteuning" msgid "No more timers available on this pin." msgstr "Geen timers meer beschikbaar op deze pin." +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "Geen pulldown op pin; 1MOhm aangeraden" @@ -1259,6 +1271,10 @@ msgstr "Geen timer beschikbaar" msgid "Nordic Soft Device failure assertion." msgstr "Nordic Soft Device assertion mislukt." +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1309,6 +1325,10 @@ msgstr "" "Alleen monochrome en 4bpp of 8bpp, en 16bpp of grotere geïndiceerde BMP's " "zijn ondersteund: %d bpp is gegeven" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Oversample moet een meervoud van 8 zijn." @@ -1513,6 +1533,10 @@ msgstr "Geselecteerde RTS pin niet geldig" msgid "Serializer in use" msgstr "Serializer in gebruik" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Slice en waarde hebben verschillende lengtes." @@ -1718,6 +1742,10 @@ msgstr "Niet in staat om naar nvm te schrijven." msgid "Unexpected nrfx uuid type" msgstr "Onverwacht mrfx uuid type" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1832,6 +1860,10 @@ msgstr "" "\n" "Voor een lijst van ingebouwde modules, gebruik `help(\"modules\")`.\n" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "Schrijven niet ondersteund op Characteristic" diff --git a/locale/pl.po b/locale/pl.po index cd4b905e73..03915175a3 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2019-03-19 18:37-0700\n" "Last-Translator: Radomir Dopieralski \n" "Language-Team: pl\n" @@ -273,7 +273,7 @@ msgstr "3-argumentowy pow() jest niewspierany" msgid "A hardware interrupt channel is already in use" msgstr "Kanał przerwań sprzętowych w użyciu" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "Adres musi mieć %d bajtów" @@ -371,6 +371,10 @@ msgstr "" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "Samo-przeładowywanie wyłączone.\n" @@ -580,6 +584,10 @@ msgid "" "boot. Press again to exit safe mode.\n" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "Nie powiodło się ustawienie nóżki zegara" @@ -1225,6 +1233,10 @@ msgstr "" msgid "No more timers available on this pin." msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "" @@ -1245,6 +1257,10 @@ msgstr "" msgid "Nordic Soft Device failure assertion." msgstr "" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1289,6 +1305,10 @@ msgid "" "%d bpp given" msgstr "" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Nadpróbkowanie musi być wielokrotnością 8." @@ -1485,6 +1505,10 @@ msgstr "" msgid "Serializer in use" msgstr "Serializator w użyciu" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Fragment i wartość są różnych długości." @@ -1680,6 +1704,10 @@ msgstr "Błąd zapisu do NVM." msgid "Unexpected nrfx uuid type" msgstr "Nieoczekiwany typ nrfx uuid." +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1786,6 +1814,10 @@ msgstr "" "Podręczniki dostępne na learn.adafruit.com/category/circuitpyhon.\n" "Aby zobaczyć wbudowane moduły, wpisz `help(\"modules\")`.\n" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index b40d33f80b..408287d600 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2020-09-02 22:32+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" @@ -283,7 +283,7 @@ msgstr "3-arg pow() não compatível" msgid "A hardware interrupt channel is already in use" msgstr "Um canal de interrupção de hardware já está em uso" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "O endereço deve ter %d bytes de comprimento" @@ -383,6 +383,10 @@ msgstr "" "A tentativa da área de alocação dinâmica de variáveis (heap) quando o " "MicroPython VM não está em execução." +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "A atualização automática está desligada.\n" @@ -600,6 +604,10 @@ msgstr "" "redefinição durante a inicialização. Pressione novamente para sair do modo " "de segurança.\n" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "Inicialização do pino de Clock falhou." @@ -1248,6 +1256,10 @@ msgstr "Não há compatibilidade com inteiro longo" msgid "No more timers available on this pin." msgstr "Não há mais temporizadores disponíveis neste pino." +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "Não há pulldown no pino; É recomendável utilizar um resistor de 1M ohm" @@ -1268,6 +1280,10 @@ msgstr "Não há um temporizador disponível" msgid "Nordic Soft Device failure assertion." msgstr "Declaração de falha do dispositivo Nordic Soft." +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1317,6 +1333,10 @@ msgstr "" "São compatíveis apenas os BMPs monocromáticos, indexados em 4bpp ou 8bpp e " "16bpp ou superior: determinado %d bpp" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "A superamostragem deve ser um múltiplo de 8." @@ -1525,6 +1545,10 @@ msgstr "O pino RTS selecionado é inválido" msgid "Serializer in use" msgstr "Serializer em uso" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Fatie e avalie os diferentes comprimentos." @@ -1734,6 +1758,10 @@ msgstr "Não é possível gravar no nvm." msgid "Unexpected nrfx uuid type" msgstr "Tipo uuid nrfx inesperado" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1849,6 +1877,10 @@ msgstr "" "\n" "Para listar os módulos internos, faça `help(\"modules\")`.\n" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "A escrita não é compatível na Característica" diff --git a/locale/sv.po b/locale/sv.po index eb131ef543..8911d0334d 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2020-09-07 19:36+0000\n" "Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" @@ -279,7 +279,7 @@ msgstr "3-arguments pow() stöds inte" msgid "A hardware interrupt channel is already in use" msgstr "En kanal för hårdvaruavbrott används redan" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "Adressen måste vara %d byte lång" @@ -377,6 +377,10 @@ msgstr "Försök att tilldela %d block" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "Försökte tilldela heap när MicroPython VM inte körs." +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "Autoladdning är avstängd.\n" @@ -590,6 +594,10 @@ msgstr "" "CircuitPython är i säkert läge eftersom du tryckte på återställningsknappen " "under start. Tryck igen för att lämna säkert läge.\n" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "Initiering av klockpinne misslyckades." @@ -1238,6 +1246,10 @@ msgstr "Inget stöd för långt heltal" msgid "No more timers available on this pin." msgstr "Inga fler timers tillgängliga på denna pinne." +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "Ingen pulldown på pinnen; 1Mohm rekommenderas" @@ -1258,6 +1270,10 @@ msgstr "Ingen timer tillgänglig" msgid "Nordic Soft Device failure assertion." msgstr "Påståendet om Nordic Soft Device-fel." +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1307,6 +1323,10 @@ msgstr "" "Endast monokrom, indexerad 4 bpp eller 8 bpp och 16 bpp eller högre BMP: er " "stöds: %d bpp angiven" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Översampling måste vara multipel av 8." @@ -1511,6 +1531,10 @@ msgstr "Vald CTS-pinne är inte giltig" msgid "Serializer in use" msgstr "Serializern används redan" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Slice och värde har olika längd." @@ -1716,6 +1740,10 @@ msgstr "Det gick inte att skriva till nvm." msgid "Unexpected nrfx uuid type" msgstr "Oväntad nrfx uuid-typ" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1827,6 +1855,10 @@ msgstr "" "\n" "För att lista inbyggda moduler, ange `help(\"modules\")`.\n" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "Skrivning stöds inte på karaktäristik" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 56f9bae8c1..046bb9b754 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-30 14:38-0400\n" +"POT-Creation-Date: 2020-09-09 14:33-0700\n" "PO-Revision-Date: 2019-04-13 10:10-0700\n" "Last-Translator: hexthat\n" "Language-Team: Chinese Hanyu Pinyin\n" @@ -280,7 +280,7 @@ msgstr "bù zhīchí 3-arg pow ()" msgid "A hardware interrupt channel is already in use" msgstr "Yìngjiàn zhōngduàn tōngdào yǐ zài shǐyòng zhōng" -#: shared-bindings/_bleio/Address.c +#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" msgstr "Dìzhǐ bìxū shì %d zì jié zhǎng" @@ -378,6 +378,10 @@ msgstr "cháng shì fēn pèi %d kuài" msgid "Attempted heap allocation when MicroPython VM not running." msgstr "MicroPython VM zài wèi yùnxíng shí chángshì fēnpèi duī." +#: shared-bindings/wifi/Radio.c +msgid "Authentication failure" +msgstr "" + #: main.c msgid "Auto-reload is off.\n" msgstr "Zìdòng chóngxīn jiāzài yǐ guānbì.\n" @@ -589,6 +593,10 @@ msgstr "" "CircuitPython chǔyú ānquán móshì, yīnwèi zài yǐndǎo guòchéng zhōng àn xiàle " "chóng zhì ànniǔ. Zài àn yīcì tuìchū ānquán móshì.\n" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython was unable to allocate the heap.\n" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." msgstr "Shízhōng de yǐn jiǎo chūshǐhuà shībài." @@ -1234,6 +1242,10 @@ msgstr "Méiyǒu zhǎng zhěngshù zhīchí" msgid "No more timers available on this pin." msgstr "Gāi yǐn jiǎo shàng méiyǒu kěyòng de dìngshí qì." +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "" + #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "Yǐn jiǎo shàng méiyǒu xiàlā; 1Mohm tuījiàn" @@ -1254,6 +1266,10 @@ msgstr "Méiyǒu jìshí qì" msgid "Nordic Soft Device failure assertion." msgstr "Nordic ruǎn shèbèi gùzhàng shēngmíng." +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1303,6 +1319,10 @@ msgstr "" "Jǐn zhīchí dān sè, suǒyǐn wéi 4bpp huò 8bpp yǐjí 16bpp huò gèng gāo de BMP: " "Gěi chū %d bpp" +#: shared-bindings/ipaddress/__init__.c +msgid "Only raw int supported for ip" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Guò cǎiyàng bìxū shì 8 de bèishù." @@ -1503,6 +1523,10 @@ msgstr "Suǒ xuǎn de RTS yǐn jiǎo wúxiào" msgid "Serializer in use" msgstr "Xùliè huà yǐjīng shǐyòngguò" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Qiēpiàn hé zhí bùtóng chángdù." @@ -1707,6 +1731,10 @@ msgstr "Wúfǎ xiě rù nvm." msgid "Unexpected nrfx uuid type" msgstr "Yìwài de nrfx uuid lèixíng" +#: shared-bindings/wifi/Radio.c +msgid "Unknown failure" +msgstr "" + #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown gatt error: 0x%04x" @@ -1818,6 +1846,10 @@ msgstr "" "\n" "Ruò yào liè chū nèizài de mókuài, qǐng qǐng zuò yǐxià `help(\"modules\")`.\n" +#: shared-bindings/wifi/Radio.c +msgid "WiFi password must be between 8 and 63 characters" +msgstr "" + #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" msgstr "Tèzhēng bù zhīchí xiě rù" From 4da478382d8e428d3e702dcd8c35f67cf80cc319 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Sat, 12 Sep 2020 17:46:52 +0530 Subject: [PATCH 58/78] Fix serial console output & add more boards --- .../esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h | 4 ++++ ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h | 4 ++++ .../esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h | 2 +- .../esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h | 2 +- ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h | 2 +- .../boards/unexpectedmaker_feathers2/mpconfigboard.h | 4 ++++ supervisor/shared/safe_mode.c | 6 +++--- 7 files changed, 18 insertions(+), 6 deletions(-) diff --git a/ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h b/ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h index ed3f23a3c4..2af3515f4c 100644 --- a/ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h +++ b/ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h @@ -29,4 +29,8 @@ #define MICROPY_HW_BOARD_NAME "BastWiFi" #define MICROPY_HW_MCU_NAME "ESP32S2" +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up.\n" + #define AUTORESET_DELAY_MS 500 diff --git a/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h b/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h index 84d15ffc2b..a4c8e65762 100644 --- a/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h +++ b/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h @@ -31,4 +31,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO45) +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up.\n" + #define AUTORESET_DELAY_MS 500 diff --git a/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h b/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h index 6d603ba57b..335aaeb5e1 100644 --- a/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h +++ b/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -33,6 +33,6 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) -#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up." +#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up.\n" #define AUTORESET_DELAY_MS 500 diff --git a/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h b/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h index f5b6c7948e..d3ef8bb260 100644 --- a/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h +++ b/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h @@ -33,6 +33,6 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) -#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up." +#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up.\n" #define AUTORESET_DELAY_MS 500 diff --git a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h index d844f37d09..1a1ef7a6c7 100644 --- a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h +++ b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h @@ -34,6 +34,6 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) -#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up." +#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up.\n" #define AUTORESET_DELAY_MS 500 diff --git a/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.h b/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.h index 93fb0c573d..a65d00206d 100644 --- a/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.h +++ b/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.h @@ -29,6 +29,10 @@ #define MICROPY_HW_BOARD_NAME "FeatherS2" #define MICROPY_HW_MCU_NAME "ESP32S2" +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION "pressing boot button at start up.\n" + #define AUTORESET_DELAY_MS 500 // Doesn't work with this on. diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index cbbdfe4276..f4f23378a4 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -72,7 +72,7 @@ safe_mode_t wait_for_safe_mode_reset(void) { // Blink on for 100, off for 100, on for 100, off for 100 and on for 200 common_hal_digitalio_digitalinout_set_value(&status_led, diff > 100 && diff / 100 != 2 && diff / 100 != 4); #endif - #ifdef CIRCUITPY_BOOT_BUTTON + #ifdef CIRCUITPY_BOOT_BUTTON if (!common_hal_digitalio_digitalinout_get_value(&boot_button)) { return USER_SAFE_MODE; } @@ -120,11 +120,11 @@ void print_safe_mode_message(safe_mode_t reason) { // Output a user safe mode string if it's set. serial_write_compressed(translate("You requested starting safe mode by ")); serial_write_compressed(translate(BOARD_USER_SAFE_MODE_ACTION)); - serial_write_compressed(translate("\nTo exit, please reset the board without ")); + serial_write_compressed(translate("To exit, please reset the board without ")); serial_write_compressed(translate(BOARD_USER_SAFE_MODE_ACTION)); - serial_write("\n"); #else // fallthrough + serial_write_compressed(translate("CircuitPython is in safe mode with status being USER_SAFE_MODE but no specific reason was provided.\n")); #endif return; case MANUAL_SAFE_MODE: From e9f411bebc691182cfb8780d1929fa8c02e4fd09 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Sat, 12 Sep 2020 18:10:04 +0530 Subject: [PATCH 59/78] Add translation for safe mode --- locale/circuitpython.pot | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index af9491c042..0c6c4ac484 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-12 18:06+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -30,12 +30,6 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" - #: py/obj.c msgid " File \"%q\"" msgstr "" @@ -582,6 +576,12 @@ msgid "" "boot. Press again to exit safe mode.\n" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "" +"CircuitPython is in safe mode with status being USER_SAFE_MODE but no " +"specific reason was provided.\n" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "CircuitPython was unable to allocate the heap.\n" msgstr "" @@ -1605,6 +1605,10 @@ msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "" From 7cb60d3b69e897e5eb127e462d66894a10f2f8d5 Mon Sep 17 00:00:00 2001 From: Wellington Terumi Uemura Date: Sat, 12 Sep 2020 05:50:33 +0000 Subject: [PATCH 60/78] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (793 of 793 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/pt_BR/ --- locale/pt_BR.po | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 408287d600..d1d3b72092 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-09 14:33-0700\n" -"PO-Revision-Date: 2020-09-02 22:32+0000\n" +"PO-Revision-Date: 2020-09-12 17:32+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\n" @@ -385,7 +385,7 @@ msgstr "" #: shared-bindings/wifi/Radio.c msgid "Authentication failure" -msgstr "" +msgstr "Houve um falha na autenticação" #: main.c msgid "Auto-reload is off.\n" @@ -606,7 +606,7 @@ msgstr "" #: supervisor/shared/safe_mode.c msgid "CircuitPython was unable to allocate the heap.\n" -msgstr "" +msgstr "O CircuitPython não conseguiu alocar o heap.\n" #: shared-module/bitbangio/SPI.c msgid "Clock pin init failed." @@ -1258,7 +1258,7 @@ msgstr "Não há mais temporizadores disponíveis neste pino." #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" -msgstr "" +msgstr "Não há rede com este ssid" #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" @@ -1282,7 +1282,7 @@ msgstr "Declaração de falha do dispositivo Nordic Soft." #: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c msgid "Not a valid IP string" -msgstr "" +msgstr "Não é uma sequência válida de IP" #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c @@ -1335,7 +1335,7 @@ msgstr "" #: shared-bindings/ipaddress/__init__.c msgid "Only raw int supported for ip" -msgstr "" +msgstr "Apenas o int bruto é compatível para o ip" #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." @@ -1547,7 +1547,7 @@ msgstr "Serializer em uso" #: shared-bindings/ssl/SSLContext.c msgid "Server side context cannot have hostname" -msgstr "" +msgstr "O contexto do lado do servidor não pode ter nome de host" #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." @@ -1760,7 +1760,7 @@ msgstr "Tipo uuid nrfx inesperado" #: shared-bindings/wifi/Radio.c msgid "Unknown failure" -msgstr "" +msgstr "Falha desconhecida" #: ports/nrf/common-hal/_bleio/__init__.c #, c-format @@ -1879,7 +1879,7 @@ msgstr "" #: shared-bindings/wifi/Radio.c msgid "WiFi password must be between 8 and 63 characters" -msgstr "" +msgstr "A senha do Wi-Fi deve ter entre 8 e 63 caracteres" #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" From 54d97251fe2dd4939652a186bf703885e654b4d1 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 12 Sep 2020 13:57:31 -0500 Subject: [PATCH 61/78] modstruct: Improve compliance with python3 While checking whether we can enable -Wimplicit-fallthrough, I encountered a diagnostic in mp_binary_set_val_array_from_int which led to discovering the following bug: ``` >>> struct.pack("xb", 3) b'\x03\x03' ``` That is, the next value (3) was used as the value of a padding byte, while standard Python always fills "x" bytes with zeros. I initially thought this had to do with the unintentional fallthrough, but it doesn't. Instead, this code would relate to an array.array with a typecode of padding ('x'), which is ALSO not desktop Python compliant: ``` >>> array.array('x', (1, 2, 3)) array('x', [1, 0, 0]) ``` Possibly this is dead code that used to be shared between struct-setting and array-setting, but it no longer is. I also discovered that the argument list length for struct.pack and struct.pack_into were not checked, and that the length of binary data passed to array.array was not checked to be a multiple of the element size. I have corrected all of these to conform more closely to standard Python and revised some tests where necessary. Some tests for micropython-specific behavior that does not conform to standard Python and is not present in CircuitPython was deleted outright. --- py/binary.c | 9 +++--- py/modstruct.c | 17 ++++++----- py/objarray.c | 7 ++++- tests/basics/struct1.py | 25 ++++++++++++++++ tests/basics/struct_micropython.py | 41 -------------------------- tests/basics/struct_micropython.py.exp | 2 -- tests/misc/non_compliant.py | 6 ---- tests/misc/non_compliant.py.exp | 2 -- 8 files changed, 46 insertions(+), 63 deletions(-) delete mode 100644 tests/basics/struct_micropython.py delete mode 100644 tests/basics/struct_micropython.py.exp diff --git a/py/binary.c b/py/binary.c index cd0f1aa4df..b85edba625 100644 --- a/py/binary.c +++ b/py/binary.c @@ -126,7 +126,6 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) { break; case BYTEARRAY_TYPECODE: case 'B': - case 'x': // value will be discarded val = ((unsigned char*)p)[index]; break; case 'h': @@ -330,7 +329,11 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte ** } } - mp_binary_set_int(MIN((size_t)size, sizeof(val)), struct_type == '>', p, val); + if (val_type == 'x') { + memset(p, 0, 1); + } else { + mp_binary_set_int(MIN((size_t)size, sizeof(val)), struct_type == '>', p, val); + } } void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t val_in) { @@ -379,8 +382,6 @@ void mp_binary_set_val_array_from_int(char typecode, void *p, mp_uint_t index, m case 'B': ((unsigned char*)p)[index] = val; break; - case 'x': - ((unsigned char*)p)[index] = 0; case 'h': ((short*)p)[index] = val; break; diff --git a/py/modstruct.c b/py/modstruct.c index fe766a4deb..7675de275d 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -183,16 +183,21 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_unpack_from_obj, 2, 3, struct_unpack_ // This function assumes there is enough room in p to store all the values STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, size_t n_args, const mp_obj_t *args) { + size_t size; + size_t count = calc_size_items(mp_obj_str_get_str(fmt_in), &size); + if (count != n_args) { +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + mp_raise_ValueError(NULL); +#else + mp_raise_ValueError_varg(translate("pack expected %d items for packing (got %d)"), count, n_args); +#endif + } const char *fmt = mp_obj_str_get_str(fmt_in); char fmt_type = get_fmt_type(&fmt); size_t i; for (i = 0; i < n_args;) { mp_uint_t cnt = 1; - if (*fmt == '\0') { - // more arguments given than used by format string; CPython raises struct.error here - break; - } if (unichar_isdigit(*fmt)) { cnt = get_fmt_num(&fmt); } @@ -208,8 +213,7 @@ STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, size_t n_args, c memset(p + to_copy, 0, cnt - to_copy); p += cnt; } else { - // If we run out of args then we just finish; CPython would raise struct.error - while (cnt-- && i < n_args) { + while (cnt--) { mp_binary_set_val(fmt_type, *fmt, args[i], &p); // Pad bytes don't have a corresponding argument. if (*fmt != 'x') { @@ -222,7 +226,6 @@ STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, size_t n_args, c } STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) { - // TODO: "The arguments must match the values required by the format exactly." mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); vstr_t vstr; vstr_init_len(&vstr, size); diff --git a/py/objarray.c b/py/objarray.c index 5d83f06977..e0b4cbd55f 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -97,6 +97,9 @@ STATIC void array_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t #if MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_ARRAY STATIC mp_obj_array_t *array_new(char typecode, size_t n) { + if (typecode == 'x') { + mp_raise_ValueError(translate("bad typecode")); + } int typecode_size = mp_binary_get_size('@', typecode, NULL); mp_obj_array_t *o = m_new_obj(mp_obj_array_t); #if MICROPY_PY_BUILTINS_BYTEARRAY && MICROPY_PY_ARRAY @@ -126,8 +129,10 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) { || (MICROPY_PY_BUILTINS_BYTEARRAY && MP_OBJ_IS_TYPE(initializer, &mp_type_bytearray))))) && mp_get_buffer(initializer, &bufinfo, MP_BUFFER_READ)) { // construct array from raw bytes - // we round-down the len to make it a multiple of sz (CPython raises error) size_t sz = mp_binary_get_size('@', typecode, NULL); + if (bufinfo.len % sz) { + mp_raise_ValueError(translate("bytes length not a multiple of item size")); + } size_t len = bufinfo.len / sz; mp_obj_array_t *o = array_new(typecode, len); memcpy(o->items, bufinfo.buf, len * sz); diff --git a/tests/basics/struct1.py b/tests/basics/struct1.py index db34342a17..107006cc3f 100644 --- a/tests/basics/struct1.py +++ b/tests/basics/struct1.py @@ -39,6 +39,28 @@ print(v == (10, 100, 200, 300)) # network byte order print(struct.pack('!i', 123)) +# too short / too long arguments +buf = bytearray(b'>>>123<<<') +try: + struct.pack_into('bb', buf, 0, 3) +except: + print('struct.error') + +try: + struct.pack_into('bb', buf, 0, 3, 1, 4) +except: + print('struct.error') + +try: + struct.pack('bb', 3) +except: + print('struct.error') + +try: + struct.pack('bb', 3, 1, 4) +except: + print('struct.error') + # check that we get an error if the buffer is too small try: struct.unpack('I', b'\x00\x00\x00') @@ -96,3 +118,6 @@ try: print(struct.unpack_from(' Date: Sat, 12 Sep 2020 15:11:02 -0500 Subject: [PATCH 62/78] make translate --- locale/circuitpython.pot | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index af9491c042..78d1223a63 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-12 15:10-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1925,7 +1925,7 @@ msgstr "" msgid "bad format string" msgstr "" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "" @@ -1978,6 +1978,10 @@ msgstr "" msgid "bytes > 8 bits not supported" msgstr "" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "" @@ -2943,6 +2947,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "" From 12d826d941f705fbfa0ced667d1c7efb264d95b1 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 12 Sep 2020 14:14:30 -0500 Subject: [PATCH 63/78] Add FALLTHROUGH comments as needed I investigated these cases and confirmed that the fallthrough behavior was intentional. --- extmod/re1.5/recursiveloop.c | 1 + py/objset.c | 1 + 2 files changed, 2 insertions(+) diff --git a/extmod/re1.5/recursiveloop.c b/extmod/re1.5/recursiveloop.c index bb337decfb..5c1f37a5a1 100644 --- a/extmod/re1.5/recursiveloop.c +++ b/extmod/re1.5/recursiveloop.c @@ -22,6 +22,7 @@ recursiveloop(char *pc, const char *sp, Subject *input, const char **subp, int n case Char: if(*sp != *pc++) return 0; + /* FALLTHROUGH */ case Any: sp++; continue; diff --git a/py/objset.c b/py/objset.c index b8f0f07ede..45b5c12606 100644 --- a/py/objset.c +++ b/py/objset.c @@ -450,6 +450,7 @@ STATIC mp_obj_t set_unary_op(mp_unary_op_t op, mp_obj_t self_in) { return MP_OBJ_NEW_SMALL_INT(hash); } #endif + /* FALLTHROUGH */ default: return MP_OBJ_NULL; // op not supported } } From 5729097bc415a935b0e18b034a6313cf0b74daab Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 12 Sep 2020 14:15:32 -0500 Subject: [PATCH 64/78] atmel-samd: enable build error for implicit fallthrough If any diagnostics occur, we will want to either add `/* FALLTHROUGH */` or `break;` as appropriate. I only tested a few builds (trinket m0 and metro m4 express) --- ports/atmel-samd/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 489f3a7afb..f00366c272 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -148,7 +148,7 @@ else endif endif -CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) +CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) -Wimplicit-fallthrough=2 ifeq ($(CHIP_FAMILY), samd21) CFLAGS += \ From 2f058029e9c62761cdac3e54f326dd4d1f53cc94 Mon Sep 17 00:00:00 2001 From: Carl Karsten Date: Sat, 12 Sep 2020 15:25:04 -0500 Subject: [PATCH 65/78] doc fix: remove the text about the non-existing clock specification --- shared-bindings/time/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 0a78b377c5..44f82c62e7 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -215,7 +215,7 @@ STATIC mp_obj_t time_time(void) { MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); //| def monotonic_ns() -> int: -//| """Return the time of the specified clock clk_id in nanoseconds. +//| """Return the time of the monotonic clock, cannot go backward, in nanoseconds. //| //| :return: the current time //| :rtype: int""" From 7151ee85ce55683b95bdd19d87e08ed23c857bc6 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 12 Sep 2020 16:30:12 -0500 Subject: [PATCH 66/78] _bleio: add missing break statement --- devices/ble_hci/common-hal/_bleio/att.c | 1 + 1 file changed, 1 insertion(+) diff --git a/devices/ble_hci/common-hal/_bleio/att.c b/devices/ble_hci/common-hal/_bleio/att.c index 591e508a65..6528361cb1 100644 --- a/devices/ble_hci/common-hal/_bleio/att.c +++ b/devices/ble_hci/common-hal/_bleio/att.c @@ -1748,6 +1748,7 @@ void check_att_err(uint8_t err) { break; case BT_ATT_ERR_ENCRYPTION_KEY_SIZE: msg = translate("Encryption key size"); + break; case BT_ATT_ERR_INVALID_ATTRIBUTE_LEN: msg = translate("Invalid attribute length"); break; From 01fdd9598a83fee98b2447c50ea911d7bfe205cb Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 12 Sep 2020 17:48:42 -0500 Subject: [PATCH 67/78] disable iimplicit-fallthrough warning inside asf4 .. there is an instance of it that looks like a "true positive", but it only affects sdhc transfers that are not a multiple of 4 bytes, which I don't think happens. (sd card blocks are always 512 bytes) I can fix this in our asf4 repo but that would mean this should be deferred until after #3384 is merged, since that also touches asf4 very invasively by adding a whole new chip family. --- ports/atmel-samd/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index f00366c272..20c79de8f1 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -255,7 +255,7 @@ SRC_ASF += \ hal/src/hal_mci_sync.c \ hpl/sdhc/hpl_sdhc.c \ -$(BUILD)/asf4/$(CHIP_FAMILY)/hpl/sdhc/hpl_sdhc.o: CFLAGS += -Wno-cast-align +$(BUILD)/asf4/$(CHIP_FAMILY)/hpl/sdhc/hpl_sdhc.o: CFLAGS += -Wno-cast-align -Wno-implicit-fallthrough endif $(BUILD)/asf4/$(CHIP_FAMILY)/hpl/sercom/hpl_sercom.o: CFLAGS += -Wno-maybe-uninitialized From 6fff4ec00d7b822852bdf553075a68820482fc22 Mon Sep 17 00:00:00 2001 From: lady ada Date: Sat, 12 Sep 2020 19:00:26 -0400 Subject: [PATCH 68/78] cutie variant --- ports/atmel-samd/boards/qtpy_m0/board.c | 40 ++++++++++++++ .../atmel-samd/boards/qtpy_m0/mpconfigboard.h | 55 +++++++++++++++++++ .../boards/qtpy_m0/mpconfigboard.mk | 24 ++++++++ ports/atmel-samd/boards/qtpy_m0/pins.c | 49 +++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 ports/atmel-samd/boards/qtpy_m0/board.c create mode 100644 ports/atmel-samd/boards/qtpy_m0/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/qtpy_m0/pins.c diff --git a/ports/atmel-samd/boards/qtpy_m0/board.c b/ports/atmel-samd/boards/qtpy_m0/board.c new file mode 100644 index 0000000000..5f7b4dda80 --- /dev/null +++ b/ports/atmel-samd/boards/qtpy_m0/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "boards/board.h" + +void board_init(void) { + gpio_set_pin_function(PIN_PA18, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(PIN_PA18, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA18, true); // Turn on neopixel by default +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.h b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.h new file mode 100644 index 0000000000..a88c1992de --- /dev/null +++ b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.h @@ -0,0 +1,55 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit QT Py M0" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_NEOPIXEL (&pin_PA19) + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define IGNORE_PIN_PA00 1 +#define IGNORE_PIN_PA01 1 +#define IGNORE_PIN_PA09 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA27 1 +#define IGNORE_PIN_PA28 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 +#define IGNORE_PIN_PB00 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA17) +#define DEFAULT_I2C_BUS_SDA (&pin_PA16) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA08) +#define DEFAULT_SPI_BUS_MISO (&pin_PA10) + +#define DEFAULT_UART_BUS_RX (&pin_PA07) +#define DEFAULT_UART_BUS_TX (&pin_PA06) diff --git a/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk new file mode 100644 index 0000000000..964cbe643a --- /dev/null +++ b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk @@ -0,0 +1,24 @@ +USB_VID = 0x239A +USB_PID = 0x80CC +USB_PRODUCT = "QT Py M0" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_FULL_BUILD = 0 + +SUPEROPT_GC = 0 + +CFLAGS_BOARD = --param max-inline-insns-auto=15 +ifeq ($(TRANSLATION), zh_Latn_pinyin) +RELEASE_NEEDS_CLEAN_BUILD = 1 +CFLAGS_INLINE_LIMIT = 35 +endif +ifeq ($(TRANSLATION), de_DE) +RELEASE_NEEDS_CLEAN_BUILD = 1 +CFLAGS_INLINE_LIMIT = 35 +SUPEROPT_VM = 0 +endif diff --git a/ports/atmel-samd/boards/qtpy_m0/pins.c b/ports/atmel-samd/boards/qtpy_m0/pins.c new file mode 100644 index 0000000000..5732e9f5b3 --- /dev/null +++ b/ports/atmel-samd/boards/qtpy_m0/pins.c @@ -0,0 +1,49 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA03) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA04) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA05) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA16) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA17) }, + + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA06) }, + + { MP_ROM_QSTR(MP_QSTR_D7, MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) }, + + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA11) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA10) }, + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA08) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_PA18) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); From 2fac4851a5e6cf08688c64ce12b5918b52c610ab Mon Sep 17 00:00:00 2001 From: lady ada Date: Sat, 12 Sep 2020 19:56:13 -0400 Subject: [PATCH 69/78] fix typo, tested hardware, neopixel doesnt work tho --- ports/atmel-samd/boards/qtpy_m0/board.c | 3 +++ ports/atmel-samd/boards/qtpy_m0/pins.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/qtpy_m0/board.c b/ports/atmel-samd/boards/qtpy_m0/board.c index 5f7b4dda80..2add1867c0 100644 --- a/ports/atmel-samd/boards/qtpy_m0/board.c +++ b/ports/atmel-samd/boards/qtpy_m0/board.c @@ -25,6 +25,9 @@ */ #include "boards/board.h" +#include "common-hal/microcontroller/Pin.h" +#include "supervisor/shared/board.h" +#include "hal/include/hal_gpio.h" void board_init(void) { gpio_set_pin_function(PIN_PA18, GPIO_PIN_FUNCTION_OFF); diff --git a/ports/atmel-samd/boards/qtpy_m0/pins.c b/ports/atmel-samd/boards/qtpy_m0/pins.c index 5732e9f5b3..4ac10a7a66 100644 --- a/ports/atmel-samd/boards/qtpy_m0/pins.c +++ b/ports/atmel-samd/boards/qtpy_m0/pins.c @@ -23,7 +23,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA06) }, { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_D7, MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) }, From cc57ef8368578fb5018249cbd3c9e6b688909c90 Mon Sep 17 00:00:00 2001 From: lady ada Date: Sat, 12 Sep 2020 19:58:27 -0400 Subject: [PATCH 70/78] add to buildyml! --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6bb9612f81..360c299927 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -275,6 +275,7 @@ jobs: - "pyportal" - "pyportal_titano" - "pyruler" + - "qtpy_m0" - "raytac_mdbt50q-db-40" - "robohatmm1_m4" - "sam32" From 5deac8d2491ded0ace0ea02dc2ae5ee9becfdb14 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Sun, 13 Sep 2020 18:22:40 +0530 Subject: [PATCH 71/78] Update board specific safe mode message --- .../atmel-samd/boards/circuitplayground_express/mpconfigboard.h | 2 +- .../boards/circuitplayground_express_crickit/mpconfigboard.h | 2 +- .../boards/circuitplayground_express_displayio/mpconfigboard.h | 2 +- ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h | 2 +- ports/atmel-samd/boards/meowmeow/mpconfigboard.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h index 12c48b1e39..4a6cbad862 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h @@ -25,7 +25,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up" +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up\n" // Increase stack size slightly due to CPX library import nesting #define CIRCUITPY_DEFAULT_STACK_SIZE (4248) //divisible by 8 diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h index 95b4ec110e..5a3871b5c6 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h @@ -27,7 +27,7 @@ #define USER_NEOPIXELS_PIN (&pin_PB23) // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up" +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up\n" // Increase stack size slightly due to CPX library import nesting #define CIRCUITPY_DEFAULT_STACK_SIZE (4248) // divisible by 8 diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h index d478ea38b4..da1abfd9dc 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h @@ -25,7 +25,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up" +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up\n" // Increase stack size slightly due to CPX library import nesting. #define CIRCUITPY_DEFAULT_STACK_SIZE (4248) // divisible by 8 diff --git a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h index 3a984188fa..892d6af370 100644 --- a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h +++ b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h @@ -11,7 +11,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up" +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up\n" #define DEFAULT_I2C_BUS_SCL (&pin_PA08) #define DEFAULT_I2C_BUS_SDA (&pin_PA09) diff --git a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h index 80d3678630..224a8d7ce4 100644 --- a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h +++ b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h @@ -11,7 +11,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up" +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up\n" #define DEFAULT_I2C_BUS_SCL (&pin_PA01) #define DEFAULT_I2C_BUS_SDA (&pin_PA00) From e5122b1acf3742474f0b496a01c7180bc0f6faf0 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 13 Sep 2020 11:56:11 -0500 Subject: [PATCH 72/78] _bleio: fix markup typo --- shared-bindings/_bleio/Address.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/_bleio/Address.c b/shared-bindings/_bleio/Address.c index 1f168d31af..04c667db44 100644 --- a/shared-bindings/_bleio/Address.c +++ b/shared-bindings/_bleio/Address.c @@ -86,7 +86,7 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, //| or use `str()` on the :py:class:`~_bleio.Attribute` object itself, the address will be printed //| in the expected order. For example: //| -//| .. code-block:: pycon +//| .. code-block:: python //| //| >>> import _bleio //| >>> _bleio.adapter.address From 36da92075b6b83a6b1a998b377f340524d143f35 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Sun, 13 Sep 2020 22:57:24 +0530 Subject: [PATCH 73/78] Update safe mode reason --- locale/circuitpython.pot | 8 +------- .../boards/circuitplayground_express/mpconfigboard.h | 2 +- .../circuitplayground_express_crickit/mpconfigboard.h | 2 +- .../circuitplayground_express_displayio/mpconfigboard.h | 2 +- ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h | 2 +- ports/atmel-samd/boards/meowmeow/mpconfigboard.h | 2 +- supervisor/shared/safe_mode.c | 5 ++--- 7 files changed, 8 insertions(+), 15 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 0c6c4ac484..5814421729 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-12 18:06+0530\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -576,12 +576,6 @@ msgid "" "boot. Press again to exit safe mode.\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"CircuitPython is in safe mode with status being USER_SAFE_MODE but no " -"specific reason was provided.\n" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "CircuitPython was unable to allocate the heap.\n" msgstr "" diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h index 4a6cbad862..54789f04f9 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h @@ -25,7 +25,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up\n" +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up.\n" // Increase stack size slightly due to CPX library import nesting #define CIRCUITPY_DEFAULT_STACK_SIZE (4248) //divisible by 8 diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h index 5a3871b5c6..e377275b7a 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h @@ -27,7 +27,7 @@ #define USER_NEOPIXELS_PIN (&pin_PB23) // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up\n" +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up.\n" // Increase stack size slightly due to CPX library import nesting #define CIRCUITPY_DEFAULT_STACK_SIZE (4248) // divisible by 8 diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h index da1abfd9dc..cacbed0de7 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h @@ -25,7 +25,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up\n" +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up.\n" // Increase stack size slightly due to CPX library import nesting. #define CIRCUITPY_DEFAULT_STACK_SIZE (4248) // divisible by 8 diff --git a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h index 892d6af370..ac1add545a 100644 --- a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h +++ b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h @@ -11,7 +11,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up\n" +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up.\n" #define DEFAULT_I2C_BUS_SCL (&pin_PA08) #define DEFAULT_I2C_BUS_SDA (&pin_PA09) diff --git a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h index 224a8d7ce4..79d477cac8 100644 --- a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h +++ b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h @@ -11,7 +11,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up\n" +#define BOARD_USER_SAFE_MODE_ACTION "pressing both buttons at start up.\n" #define DEFAULT_I2C_BUS_SCL (&pin_PA01) #define DEFAULT_I2C_BUS_SDA (&pin_PA00) diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index f4f23378a4..0c7933a213 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -123,8 +123,7 @@ void print_safe_mode_message(safe_mode_t reason) { serial_write_compressed(translate("To exit, please reset the board without ")); serial_write_compressed(translate(BOARD_USER_SAFE_MODE_ACTION)); #else - // fallthrough - serial_write_compressed(translate("CircuitPython is in safe mode with status being USER_SAFE_MODE but no specific reason was provided.\n")); + break; #endif return; case MANUAL_SAFE_MODE: @@ -189,4 +188,4 @@ void print_safe_mode_message(safe_mode_t reason) { break; } serial_write_compressed(FILE_AN_ISSUE); -} +} \ No newline at end of file From 506bb097f7af5118a4e52a9471fe4599e681ba39 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Sun, 13 Sep 2020 23:17:14 +0530 Subject: [PATCH 74/78] Update safe_mode.c --- supervisor/shared/safe_mode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index 0c7933a213..1cf36e4b71 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -72,7 +72,7 @@ safe_mode_t wait_for_safe_mode_reset(void) { // Blink on for 100, off for 100, on for 100, off for 100 and on for 200 common_hal_digitalio_digitalinout_set_value(&status_led, diff > 100 && diff / 100 != 2 && diff / 100 != 4); #endif - #ifdef CIRCUITPY_BOOT_BUTTON + #ifdef CIRCUITPY_BOOT_BUTTON if (!common_hal_digitalio_digitalinout_get_value(&boot_button)) { return USER_SAFE_MODE; } @@ -188,4 +188,4 @@ void print_safe_mode_message(safe_mode_t reason) { break; } serial_write_compressed(FILE_AN_ISSUE); -} \ No newline at end of file +} From 90f7340bfc35d19fcf5e11c078c7f45399ed07e7 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 13 Sep 2020 13:12:35 -0500 Subject: [PATCH 75/78] move implicit-fallthrough warning enable to defns.mk --- ports/atmel-samd/Makefile | 2 +- py/circuitpy_defns.mk | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 20c79de8f1..72c7d96882 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -148,7 +148,7 @@ else endif endif -CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) -Wimplicit-fallthrough=2 +CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) ifeq ($(CHIP_FAMILY), samd21) CFLAGS += \ diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 04e38d81ea..0e87287c13 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -31,6 +31,7 @@ BASE_CFLAGS = \ -fsingle-precision-constant \ -fno-strict-aliasing \ -Wdouble-promotion \ + -Wimplicit-fallthrough=2 \ -Wno-endif-labels \ -Wstrict-prototypes \ -Werror-implicit-function-declaration \ From bbf2e9882738b6d599311d19ae52f32680774752 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sun, 13 Sep 2020 21:19:10 +0200 Subject: [PATCH 76/78] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/ID.po | 24 ++++++++++++------------ locale/cs.po | 21 ++++++++++++--------- locale/de_DE.po | 24 ++++++++++++------------ locale/es.po | 24 ++++++++++++------------ locale/fil.po | 15 +++++---------- locale/fr.po | 24 ++++++++++++------------ locale/hi.po | 12 +++++------- locale/it_IT.po | 15 +++++---------- locale/ja.po | 21 ++++++++++++--------- locale/ko.po | 12 +++++------- locale/nl.po | 21 ++++++++++++--------- locale/pl.po | 15 +++++---------- locale/pt_BR.po | 24 ++++++++++++------------ locale/sv.po | 21 ++++++++++++--------- locale/zh_Latn_pinyin.po | 24 ++++++++++++------------ 15 files changed, 145 insertions(+), 152 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index 6312e0e242..d27b6c2207 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2020-07-06 18:10+0000\n" "Last-Translator: oon arfiandwi \n" "Language-Team: LANGUAGE \n" @@ -34,14 +34,6 @@ msgstr "" "Harap ajukan masalah dengan konten drive CIRCUITPY Anda di\n" "https://github.com/adafruit/circuitpython/issues\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" -"\n" -"Untuk keluar, harap setel ulang papan tanpa" - #: py/obj.c msgid " File \"%q\"" msgstr " File \"%q\"" @@ -1632,6 +1624,10 @@ msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Untuk keluar, silahkan reset board tanpa " + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "Terlalu banyak channel dalam sampel" @@ -3453,6 +3449,13 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "" +#~ "\n" +#~ "To exit, please reset the board without " +#~ msgstr "" +#~ "\n" +#~ "Untuk keluar, harap setel ulang papan tanpa" + #~ msgid "%q indices must be integers, not %s" #~ msgstr "indeks %q harus bilangan bulat, bukan %s" @@ -3712,9 +3715,6 @@ msgstr "" #~ "Tegangan dari mikrokontroler turun atau mati. Pastikan sumber tegangan " #~ "memberikan daya\n" -#~ msgid "To exit, please reset the board without " -#~ msgstr "Untuk keluar, silahkan reset board tanpa " - #~ msgid "UART(%d) does not exist" #~ msgstr "UART(%d) tidak ada" diff --git a/locale/cs.po b/locale/cs.po index db04b0fff5..c1d46f1f9c 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2020-05-24 03:22+0000\n" "Last-Translator: dronecz \n" "Language-Team: LANGUAGE \n" @@ -34,14 +34,6 @@ msgstr "" "Založte prosím problém s obsahem vaší jednotky CIRCUITPY na adrese\n" "https://github.com/adafruit/circuitpython/issues\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" -"\n" -"Pro ukončení, prosím resetujte desku bez " - #: py/obj.c msgid " File \"%q\"" msgstr " Soubor \"%q\"" @@ -1611,6 +1603,10 @@ msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "" @@ -3422,5 +3418,12 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "" +#~ "\n" +#~ "To exit, please reset the board without " +#~ msgstr "" +#~ "\n" +#~ "Pro ukončení, prosím resetujte desku bez " + #~ msgid "%q indices must be integers, not %s" #~ msgstr "Indexy %q musí být celá čísla, nikoli %s" diff --git a/locale/de_DE.po b/locale/de_DE.po index 388f0932b6..2dfc715e75 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2020-06-16 18:24+0000\n" "Last-Translator: Andreas Buchen \n" "Language: de_DE\n" @@ -33,14 +33,6 @@ msgstr "" "Bitte melden Sie ein Problem mit dem Inhalt Ihres CIRCUITPY-Laufwerks unter\n" "https://github.com/adafruit/circuitpython/issues\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" -"\n" -"Zum Beenden, resete bitte das Board ohne " - #: py/obj.c msgid " File \"%q\"" msgstr " Datei \"%q\"" @@ -1653,6 +1645,10 @@ msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Zum beenden, resette bitte das board ohne " + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "Zu viele Kanäle im sample." @@ -3510,6 +3506,13 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "" +#~ "\n" +#~ "To exit, please reset the board without " +#~ msgstr "" +#~ "\n" +#~ "Zum Beenden, resete bitte das Board ohne " + #~ msgid "PulseOut not supported on this chip" #~ msgstr "PulseOut wird auf diesem Chip nicht unterstützt" @@ -3932,9 +3935,6 @@ msgstr "" #~ "Die Reset-Taste wurde beim Booten von CircuitPython gedrückt. Drücke sie " #~ "erneut um den abgesicherten Modus zu verlassen. \n" -#~ msgid "To exit, please reset the board without " -#~ msgstr "Zum beenden, resette bitte das board ohne " - #~ msgid "UART(%d) does not exist" #~ msgstr "UART(%d) existiert nicht" diff --git a/locale/es.po b/locale/es.po index 0f37aa1eb0..f72825d894 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2020-08-17 21:11+0000\n" "Last-Translator: Alvaro Figueroa \n" "Language-Team: \n" @@ -36,14 +36,6 @@ msgstr "" "Reporte un problema con el contenido de su unidad CIRCUITPY en\n" "https://github.com/adafruit/circuitpython/issues\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" -"\n" -"Para salir, favor reinicie la tarjeta sin " - #: py/obj.c msgid " File \"%q\"" msgstr " Archivo \"%q\"" @@ -1653,6 +1645,10 @@ msgstr "" "El temporizador es utilizado para uso interno - declare los pines para PWM " "más temprano en el programa" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Para salir, por favor reinicia la tarjeta sin " + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "Demasiados canales en sample." @@ -3492,6 +3488,13 @@ msgstr "zi debe ser de tipo flotante" msgid "zi must be of shape (n_section, 2)" msgstr "zi debe ser una forma (n_section,2)" +#~ msgid "" +#~ "\n" +#~ "To exit, please reset the board without " +#~ msgstr "" +#~ "\n" +#~ "Para salir, favor reinicie la tarjeta sin " + #~ msgid "PulseOut not supported on this chip" #~ msgstr "PulseOut no es compatible con este chip" @@ -3941,9 +3944,6 @@ msgstr "zi debe ser una forma (n_section,2)" #~ msgid "Tile indices must be 0 - 255" #~ msgstr "Los índices de Tile deben ser 0 - 255" -#~ msgid "To exit, please reset the board without " -#~ msgstr "Para salir, por favor reinicia la tarjeta sin " - #~ msgid "UART(%d) does not exist" #~ msgstr "UART(%d) no existe" diff --git a/locale/fil.po b/locale/fil.po index 2283dff2bb..c23d994dfa 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -28,12 +28,6 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" - #: py/obj.c msgid " File \"%q\"" msgstr " File \"%q\"" @@ -1626,6 +1620,10 @@ msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Para lumabas, paki-reset ang board na wala ang " + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "Sobra ang channels sa sample." @@ -3842,9 +3840,6 @@ msgstr "" #~ "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " #~ "ulit para lumabas sa safe mode.\n" -#~ msgid "To exit, please reset the board without " -#~ msgstr "Para lumabas, paki-reset ang board na wala ang " - #~ msgid "UART(%d) does not exist" #~ msgstr "Walang UART(%d)" diff --git a/locale/fr.po b/locale/fr.po index 49da4ac4e3..a891a2a981 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2020-07-27 21:27+0000\n" "Last-Translator: Nathan \n" "Language: fr\n" @@ -36,14 +36,6 @@ msgstr "" "l'adresse\n" "https://github.com/adafruit/circuitpython/issues\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" -"\n" -"Pour quitter, veuillez réinitialiser la carte sans " - #: py/obj.c msgid " File \"%q\"" msgstr " Fichier \"%q\"" @@ -1655,6 +1647,10 @@ msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Pour quitter, redémarrez la carte SVP sans " + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "Trop de canaux dans l'échantillon." @@ -3513,6 +3509,13 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "" +#~ "\n" +#~ "To exit, please reset the board without " +#~ msgstr "" +#~ "\n" +#~ "Pour quitter, veuillez réinitialiser la carte sans " + #~ msgid "PulseOut not supported on this chip" #~ msgstr "PulseOut non pris en charge sur cette puce" @@ -3970,9 +3973,6 @@ msgstr "" #~ msgid "Tile indices must be 0 - 255" #~ msgstr "Les indices des tuiles doivent être compris entre 0 et 255 " -#~ msgid "To exit, please reset the board without " -#~ msgstr "Pour quitter, redémarrez la carte SVP sans " - #~ msgid "UART(%d) does not exist" #~ msgstr "UART(%d) n'existe pas" diff --git a/locale/hi.po b/locale/hi.po index bf85b19d70..1c904242e5 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -29,12 +29,6 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" - #: py/obj.c msgid " File \"%q\"" msgstr "" @@ -1604,6 +1598,10 @@ msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index cfc6b76a56..24f16499cd 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -28,12 +28,6 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" - #: py/obj.c msgid " File \"%q\"" msgstr " File \"%q\"" @@ -1637,6 +1631,10 @@ msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Per uscire resettare la scheda senza " + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "" @@ -3833,9 +3831,6 @@ msgstr "" #~ "La potenza del microcontrollore è calata. Assicurati che l'alimentazione " #~ "sia attaccata correttamente\n" -#~ msgid "To exit, please reset the board without " -#~ msgstr "Per uscire resettare la scheda senza " - #~ msgid "UART(%d) does not exist" #~ msgstr "UART(%d) non esistente" diff --git a/locale/ja.po b/locale/ja.po index b66e9a06d9..0e3ce60597 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2020-09-01 18:44+0000\n" "Last-Translator: Jeff Epler \n" "Language-Team: none\n" @@ -36,14 +36,6 @@ msgstr "" "CIRCUITPYドライブの内容を添えて問題を以下で報告してください:\n" "https://github.com/adafruit/circuitpython/issues\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" -"\n" -"終了するには、次の操作をせずにリセットしてください: " - #: py/obj.c msgid " File \"%q\"" msgstr " ファイル \"%q\"" @@ -1634,6 +1626,10 @@ msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "サンプルのチャンネル数が多すぎます" @@ -3450,6 +3446,13 @@ msgstr "ziはfloat値が必要" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "" +#~ "\n" +#~ "To exit, please reset the board without " +#~ msgstr "" +#~ "\n" +#~ "終了するには、次の操作をせずにリセットしてください: " + #~ msgid "PulseOut not supported on this chip" #~ msgstr "PulseOutはこのチップでサポートされていません" diff --git a/locale/ko.po b/locale/ko.po index 858d117f26..cebf6ec2bf 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2019-05-06 14:22-0700\n" "Last-Translator: \n" "Language-Team: LANGUAGE \n" @@ -30,12 +30,6 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" - #: py/obj.c msgid " File \"%q\"" msgstr " 파일 \"%q\"" @@ -1607,6 +1601,10 @@ msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "" diff --git a/locale/nl.po b/locale/nl.po index 470e9db9c5..61571d6bc5 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2020-09-09 16:05+0000\n" "Last-Translator: Jelle Jager \n" "Language-Team: none\n" @@ -34,14 +34,6 @@ msgstr "" "Meld een probleem met de inhoud van de CIRCUITPY drive op:\n" "https://github.com/adafruit/circuitpython/issues\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" -"\n" -"Om te verlaten, herstart de module zonder " - #: py/obj.c msgid " File \"%q\"" msgstr " Bestand" @@ -1647,6 +1639,10 @@ msgstr "" "Timer is gereserveerd voor intern gebruik - wijs PWM pins eerder in het " "programma toe" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "Teveel kanalen in sample." @@ -3480,6 +3476,13 @@ msgstr "zi moet van type float zijn" msgid "zi must be of shape (n_section, 2)" msgstr "zi moet vorm (n_section, 2) hebben" +#~ msgid "" +#~ "\n" +#~ "To exit, please reset the board without " +#~ msgstr "" +#~ "\n" +#~ "Om te verlaten, herstart de module zonder " + #~ msgid "PulseOut not supported on this chip" #~ msgstr "PulseOut niet ondersteund door deze chip" diff --git a/locale/pl.po b/locale/pl.po index 03915175a3..2b7339786d 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2019-03-19 18:37-0700\n" "Last-Translator: Radomir Dopieralski \n" "Language-Team: pl\n" @@ -30,12 +30,6 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" - #: py/obj.c msgid " File \"%q\"" msgstr " Plik \"%q\"" @@ -1609,6 +1603,10 @@ msgid "" "Timer was reserved for internal use - declare PWM pins earlier in the program" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "By wyjść, proszę zresetować płytkę bez " + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "Zbyt wiele kanałów." @@ -3735,9 +3733,6 @@ msgstr "" #~ msgid "Tile indices must be 0 - 255" #~ msgstr "Indeks kafelka musi być pomiędzy 0 a 255 włącznie" -#~ msgid "To exit, please reset the board without " -#~ msgstr "By wyjść, proszę zresetować płytkę bez " - #~ msgid "UUID integer value not in range 0 to 0xffff" #~ msgstr "Wartość UUID poza zakresem 0 do 0xffff" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index d1d3b72092..33ca38a58f 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2020-09-12 17:32+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" @@ -34,14 +34,6 @@ msgstr "" "Registre um problema com o conteúdo do seu controlador no CIRCUITPY\n" "https://github.com/adafruit/circuitpython/issues\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" -"\n" -"Para encerrar, redefina a placa sem " - #: py/obj.c msgid " File \"%q\"" msgstr " Arquivo \"%q\"" @@ -1662,6 +1654,10 @@ msgstr "" "O temporizador foi reservado para uso interno - declare os pinos PWM no " "início do programa" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Para sair, por favor, reinicie a placa sem " + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "Muitos canais na amostra." @@ -3508,6 +3504,13 @@ msgstr "zi deve ser de um tipo float" msgid "zi must be of shape (n_section, 2)" msgstr "zi deve estar na forma (n_section, 2)" +#~ msgid "" +#~ "\n" +#~ "To exit, please reset the board without " +#~ msgstr "" +#~ "\n" +#~ "Para encerrar, redefina a placa sem " + #~ msgid "PulseOut not supported on this chip" #~ msgstr "O PulseOut não é compatível neste CI" @@ -3831,9 +3834,6 @@ msgstr "zi deve estar na forma (n_section, 2)" #~ msgid "STA required" #~ msgstr "STA requerido" -#~ msgid "To exit, please reset the board without " -#~ msgstr "Para sair, por favor, reinicie a placa sem " - #~ msgid "UART(%d) does not exist" #~ msgstr "UART(%d) não existe" diff --git a/locale/sv.po b/locale/sv.po index 8911d0334d..c73b24c458 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2020-09-07 19:36+0000\n" "Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" @@ -34,14 +34,6 @@ msgstr "" "Vänligen skapa ett ärende med innehållet i din CIRCUITPY-enhet på\n" "https://github.com/adafruit/circuitpython/issues\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" -"\n" -"För att avsluta, gör reset på kortet utan " - #: py/obj.c msgid " File \"%q\"" msgstr " Filen \"%q\"" @@ -1645,6 +1637,10 @@ msgstr "" "Timern är reserverad för internt bruk - deklarera PWM-pinne tidigare i " "programmet" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "För många kanaler i sampling." @@ -3475,6 +3471,13 @@ msgstr "zi måste vara av typ float" msgid "zi must be of shape (n_section, 2)" msgstr "zi måste vara i formen (n_section, 2)" +#~ msgid "" +#~ "\n" +#~ "To exit, please reset the board without " +#~ msgstr "" +#~ "\n" +#~ "För att avsluta, gör reset på kortet utan " + #~ msgid "PulseOut not supported on this chip" #~ msgstr "PulseIn stöds inte av detta chip" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 046bb9b754..41d928ff6c 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-09 14:33-0700\n" +"POT-Creation-Date: 2020-09-13 22:53+0530\n" "PO-Revision-Date: 2019-04-13 10:10-0700\n" "Last-Translator: hexthat\n" "Language-Team: Chinese Hanyu Pinyin\n" @@ -34,14 +34,6 @@ msgstr "" "Qǐng tōngguò https://github.com/adafruit/circuitpython/issues\n" "tíjiāo yǒuguān nín de CIRCUITPY qūdòngqì nèiróng de wèntí \n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"To exit, please reset the board without " -msgstr "" -"\n" -"Qǐng zài méiyǒu _ de qíngkuàng xià chóng zhì bǎn zǐ yǐ tuìchū " - #: py/obj.c msgid " File \"%q\"" msgstr " Wénjiàn \"%q\"" @@ -1636,6 +1628,10 @@ msgstr "" "Dìngshí qì bǎoliú gōng nèibù shǐyòng-zài chéngxù de qiánmiàn shēngmíng PWM " "yǐn jiǎo" +#: supervisor/shared/safe_mode.c +msgid "To exit, please reset the board without " +msgstr "Yào tuìchū, qǐng chóng zhì bǎnkuài ér bùyòng " + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." msgstr "Chōuyàng zhōng de píndào tài duō." @@ -3463,6 +3459,13 @@ msgstr "zi bìxū wèi fú diǎn xíng" msgid "zi must be of shape (n_section, 2)" msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" +#~ msgid "" +#~ "\n" +#~ "To exit, please reset the board without " +#~ msgstr "" +#~ "\n" +#~ "Qǐng zài méiyǒu _ de qíngkuàng xià chóng zhì bǎn zǐ yǐ tuìchū " + #~ msgid "tuple/list required on RHS" #~ msgstr "RHS yāoqiú de yuán zǔ/lièbiǎo" @@ -3838,9 +3841,6 @@ msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" #~ msgid "Tile indices must be 0 - 255" #~ msgstr "Píng pū zhǐshù bìxū wèi 0 - 255" -#~ msgid "To exit, please reset the board without " -#~ msgstr "Yào tuìchū, qǐng chóng zhì bǎnkuài ér bùyòng " - #~ msgid "UUID integer value not in range 0 to 0xffff" #~ msgstr "UUID zhěngshù zhí bùzài fànwéi 0 zhì 0xffff" From b3bdd4686bd5f4a7c91972b9b0f65e624a7eab95 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 13 Sep 2020 15:10:04 -0500 Subject: [PATCH 77/78] PacketBuffer: add missing 'break's, remove unneeded {} --- ports/nrf/common-hal/_bleio/PacketBuffer.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ports/nrf/common-hal/_bleio/PacketBuffer.c b/ports/nrf/common-hal/_bleio/PacketBuffer.c index a8773f961f..6d587984ca 100644 --- a/ports/nrf/common-hal/_bleio/PacketBuffer.c +++ b/ports/nrf/common-hal/_bleio/PacketBuffer.c @@ -129,14 +129,12 @@ STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) { } break; } - case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE: { + case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE: queue_next_write(self); break; - } - case BLE_GATTC_EVT_WRITE_RSP: { + case BLE_GATTC_EVT_WRITE_RSP: queue_next_write(self); break; - } default: return false; break; @@ -171,14 +169,14 @@ STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) { } break; } - case BLE_GAP_EVT_DISCONNECTED: { + case BLE_GAP_EVT_DISCONNECTED: if (self->conn_handle == ble_evt->evt.gap_evt.conn_handle) { self->conn_handle = BLE_CONN_HANDLE_INVALID; } - } - case BLE_GATTS_EVT_HVN_TX_COMPLETE: { + break; + case BLE_GATTS_EVT_HVN_TX_COMPLETE: queue_next_write(self); - } + break; default: return false; break; From 90b21ce548abb79e9ec28852f3517b373faa23b6 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 14 Sep 2020 04:29:00 +0200 Subject: [PATCH 78/78] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/ID.po | 13 +++++++++++-- locale/cs.po | 13 +++++++++++-- locale/de_DE.po | 13 +++++++++++-- locale/es.po | 13 +++++++++++-- locale/fil.po | 13 +++++++++++-- locale/fr.po | 13 +++++++++++-- locale/hi.po | 13 +++++++++++-- locale/it_IT.po | 13 +++++++++++-- locale/ja.po | 13 +++++++++++-- locale/ko.po | 13 +++++++++++-- locale/nl.po | 13 +++++++++++-- locale/pl.po | 13 +++++++++++-- locale/pt_BR.po | 13 +++++++++++-- locale/sv.po | 13 +++++++++++-- locale/zh_Latn_pinyin.po | 13 +++++++++++-- 15 files changed, 165 insertions(+), 30 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index d27b6c2207..5fd0647a14 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2020-07-06 18:10+0000\n" "Last-Translator: oon arfiandwi \n" "Language-Team: LANGUAGE \n" @@ -1955,7 +1955,7 @@ msgstr "" msgid "bad format string" msgstr "" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "typecode buruk" @@ -2009,6 +2009,10 @@ msgstr "" msgid "bytes > 8 bits not supported" msgstr "byte > 8 bit tidak didukung" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "" @@ -2975,6 +2979,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index c1d46f1f9c..8dcf08cf2a 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2020-05-24 03:22+0000\n" "Last-Translator: dronecz \n" "Language-Team: LANGUAGE \n" @@ -1927,7 +1927,7 @@ msgstr "" msgid "bad format string" msgstr "" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "" @@ -1980,6 +1980,10 @@ msgstr "" msgid "bytes > 8 bits not supported" msgstr "" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "" @@ -2945,6 +2949,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 2dfc715e75..d9f80769ea 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2020-06-16 18:24+0000\n" "Last-Translator: Andreas Buchen \n" "Language: de_DE\n" @@ -1984,7 +1984,7 @@ msgstr "schlechter Konvertierungsspezifizierer" msgid "bad format string" msgstr "Falscher Formatstring" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "Falscher Typcode" @@ -2037,6 +2037,10 @@ msgstr "Byteorder ist kein String" msgid "bytes > 8 bits not supported" msgstr "bytes mit mehr als 8 bits werden nicht unterstützt" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "Byte-Wert außerhalb des Bereichs" @@ -3026,6 +3030,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "Überlauf beim konvertieren von long int zu machine word" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "Die Palette muss 32 Byte lang sein" diff --git a/locale/es.po b/locale/es.po index f72825d894..85b4e758df 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2020-08-17 21:11+0000\n" "Last-Translator: Alvaro Figueroa \n" "Language-Team: \n" @@ -1981,7 +1981,7 @@ msgstr "especificador de conversion erroneo" msgid "bad format string" msgstr "formato de string erroneo" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "typecode erroneo" @@ -2034,6 +2034,10 @@ msgstr "byteorder no es una cadena" msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits no soportados" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "valor de bytes fuera de rango" @@ -3012,6 +3016,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "desbordamiento convirtiendo long int a palabra de máquina" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "palette debe ser 32 bytes de largo" diff --git a/locale/fil.po b/locale/fil.po index c23d994dfa..e630fddee3 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -1954,7 +1954,7 @@ msgstr "masamang pag convert na specifier" msgid "bad format string" msgstr "maling format ang string" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "masamang typecode" @@ -2008,6 +2008,10 @@ msgstr "" msgid "bytes > 8 bits not supported" msgstr "hindi sinusuportahan ang bytes > 8 bits" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "bytes value wala sa sakop" @@ -2990,6 +2994,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "overflow nagcoconvert ng long int sa machine word" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "ang palette ay dapat 32 bytes ang haba" diff --git a/locale/fr.po b/locale/fr.po index a891a2a981..1180648961 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2020-07-27 21:27+0000\n" "Last-Translator: Nathan \n" "Language: fr\n" @@ -1988,7 +1988,7 @@ msgstr "mauvaise spécification de conversion" msgid "bad format string" msgstr "chaîne mal-formée" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "mauvais code type" @@ -2041,6 +2041,10 @@ msgstr "byteorder n'est pas une chaîne" msgid "bytes > 8 bits not supported" msgstr "octets > 8 bits non supporté" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "valeur des octets hors bornes" @@ -3032,6 +3036,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "dépassement de capacité en convertissant un entier long en mot machine" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "la palette doit être longue de 32 octets" diff --git a/locale/hi.po b/locale/hi.po index 1c904242e5..c06eff81d9 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -1922,7 +1922,7 @@ msgstr "" msgid "bad format string" msgstr "" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "" @@ -1975,6 +1975,10 @@ msgstr "" msgid "bytes > 8 bits not supported" msgstr "" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "" @@ -2940,6 +2944,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 24f16499cd..5ff22f8a63 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -1957,7 +1957,7 @@ msgstr "specificatore di conversione scorretto" msgid "bad format string" msgstr "stringa di formattazione scorretta" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "" @@ -2013,6 +2013,10 @@ msgstr "" msgid "bytes > 8 bits not supported" msgstr "byte > 8 bit non supportati" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "valore byte fuori intervallo" @@ -2996,6 +3000,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "overflow convertendo long int in parola" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "la palette deve essere lunga 32 byte" diff --git a/locale/ja.po b/locale/ja.po index 0e3ce60597..db3839b402 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2020-09-01 18:44+0000\n" "Last-Translator: Jeff Epler \n" "Language-Team: none\n" @@ -1952,7 +1952,7 @@ msgstr "" msgid "bad format string" msgstr "不正な書式化文字列" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "不正なtypecode" @@ -2005,6 +2005,10 @@ msgstr "byteorderが文字列ではありません" msgid "bytes > 8 bits not supported" msgstr "" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "範囲外のバイト値" @@ -2972,6 +2976,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "long intをマシンのwordに変換する際にオーバーフローしました" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "パレットの長さは32バイトでなければなりません" diff --git a/locale/ko.po b/locale/ko.po index cebf6ec2bf..70b7985867 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2019-05-06 14:22-0700\n" "Last-Translator: \n" "Language-Team: LANGUAGE \n" @@ -1926,7 +1926,7 @@ msgstr "" msgid "bad format string" msgstr "" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "" @@ -1979,6 +1979,10 @@ msgstr "" msgid "bytes > 8 bits not supported" msgstr "" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "" @@ -2944,6 +2948,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "" diff --git a/locale/nl.po b/locale/nl.po index 61571d6bc5..04d0ede837 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2020-09-09 16:05+0000\n" "Last-Translator: Jelle Jager \n" "Language-Team: none\n" @@ -1974,7 +1974,7 @@ msgstr "slechte conversie specificatie" msgid "bad format string" msgstr "string met verkeerde indeling" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "verkeerde typecode" @@ -2027,6 +2027,10 @@ msgstr "byteorder is geen string" msgid "bytes > 8 bits not supported" msgstr "butes > 8 niet ondersteund" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "bytes waarde buiten bereik" @@ -3000,6 +3004,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "overloop bij converteren van long int naar machine word" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "palette moet 32 bytes lang zijn" diff --git a/locale/pl.po b/locale/pl.po index 2b7339786d..8b4fceee4a 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2019-03-19 18:37-0700\n" "Last-Translator: Radomir Dopieralski \n" "Language-Team: pl\n" @@ -1930,7 +1930,7 @@ msgstr "zły specyfikator konwersji" msgid "bad format string" msgstr "zła specyfikacja formatu" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "zły typecode" @@ -1983,6 +1983,10 @@ msgstr "" msgid "bytes > 8 bits not supported" msgstr "bajty większe od 8 bitów są niewspierane" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "wartość bytes poza zakresem" @@ -2949,6 +2953,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "przepełnienie przy konwersji long in to słowa maszynowego" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "paleta musi mieć 32 bajty długości" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 33ca38a58f..92e41e1fc1 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2020-09-12 17:32+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" @@ -1991,7 +1991,7 @@ msgstr "especificador de conversão incorreto" msgid "bad format string" msgstr "formato da string incorreta" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "typecode incorreto" @@ -2044,6 +2044,10 @@ msgstr "a ordem dos bytes não é uma cadeia de caracteres" msgid "bytes > 8 bits not supported" msgstr "bytes > 8 bits não suportado" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "o valor dos bytes estão fora do alcance" @@ -3029,6 +3033,11 @@ msgstr "" "houve um transbordamento durante a conversão int longo para a palavra de " "máquina" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "a paleta deve ter 32 bytes de comprimento" diff --git a/locale/sv.po b/locale/sv.po index c73b24c458..cc3cd4593e 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2020-09-07 19:36+0000\n" "Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" @@ -1969,7 +1969,7 @@ msgstr "Ogiltig konverteringsspecifikation" msgid "bad format string" msgstr "Ogiltig formatsträng" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "Ogiltig typkod" @@ -2022,6 +2022,10 @@ msgstr "byteorder är inte en sträng" msgid "bytes > 8 bits not supported" msgstr "bytes> 8 bitar stöds inte" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "bytevärde utanför intervallet" @@ -2995,6 +2999,11 @@ msgstr "utanför räckvidd för target" msgid "overflow converting long int to machine word" msgstr "Konvertering av long int till machine word överskred maxvärde" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "palette måste vara 32 bytes lång" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 41d928ff6c..9b9c1414ac 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-13 22:53+0530\n" +"POT-Creation-Date: 2020-09-13 14:21-0500\n" "PO-Revision-Date: 2019-04-13 10:10-0700\n" "Last-Translator: hexthat\n" "Language-Team: Chinese Hanyu Pinyin\n" @@ -1960,7 +1960,7 @@ msgstr "cuòwù zhuǎnhuàn biāozhù" msgid "bad format string" msgstr "géshì cuòwù zìfú chuàn" -#: py/binary.c +#: py/binary.c py/objarray.c msgid "bad typecode" msgstr "cuòwù de dàimǎ lèixíng" @@ -2013,6 +2013,10 @@ msgstr "byteorder bùshì zìfú chuàn" msgid "bytes > 8 bits not supported" msgstr "zì jié > 8 wèi" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "" + #: py/objstr.c msgid "bytes value out of range" msgstr "zì jié zhí chāochū fànwéi" @@ -2984,6 +2988,11 @@ msgstr "" msgid "overflow converting long int to machine word" msgstr "chāo gāo zhuǎnhuàn zhǎng zhěng shùzì shí" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "" + #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" msgstr "yánsè bìxū shì 32 gè zì jié"