commit
72bda346db
|
@ -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
|
||||
|
|
1
conf.py
1
conf.py
|
@ -146,6 +146,7 @@ version = release = final_version
|
|||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ["**/build*",
|
||||
".git",
|
||||
".env",
|
||||
".venv",
|
||||
".direnv",
|
||||
"docs/autoapi",
|
||||
|
|
|
@ -43,8 +43,8 @@ def get_circuitpython_root_dir():
|
|||
def get_shared_bindings():
|
||||
""" Get a list of modules in shared-bindings based on folder names
|
||||
"""
|
||||
shared_bindings_dir = get_circuitpython_root_dir() / "circuitpython-stubs"
|
||||
return [item.name for item in shared_bindings_dir.iterdir()]
|
||||
shared_bindings_dir = get_circuitpython_root_dir() / "shared-bindings"
|
||||
return [item.name for item in shared_bindings_dir.iterdir()] + ["ulab"]
|
||||
|
||||
|
||||
def read_mpconfig():
|
||||
|
@ -159,6 +159,8 @@ def support_matrix_by_board(use_branded_name=True):
|
|||
board_contents)
|
||||
if board_name_re:
|
||||
board_name = board_name_re.group(1).strip('"')
|
||||
else:
|
||||
board_name = entry.name
|
||||
|
||||
board_modules = []
|
||||
for module in base:
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit c0b9bdf22997552396abb514a6304d33460c2912
|
|
@ -1 +1 @@
|
|||
Subproject commit 22100b252fc2eb8f51ed407949645653c4880fd9
|
||||
Subproject commit e90cf7a676eddcbd9c35d2d99a0a9cd14686e2ce
|
|
@ -8,7 +8,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: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\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 ""
|
||||
|
@ -578,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 ""
|
||||
|
@ -1221,6 +1229,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 ""
|
||||
|
@ -1241,6 +1253,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"
|
||||
|
@ -1285,6 +1301,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 ""
|
||||
|
@ -1481,6 +1501,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 ""
|
||||
|
@ -1676,6 +1700,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"
|
||||
|
@ -1779,6 +1807,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 ""
|
||||
|
|
|
@ -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
|
||||
|
|
35
locale/nl.po
35
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 <vooralfred@gmail.com>\n"
|
||||
"PO-Revision-Date: 2020-09-09 16:05+0000\n"
|
||||
"Last-Translator: Jelle Jager <jell@jjc.id.au>\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"
|
||||
|
|
|
@ -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"
|
||||
|
|
26
locale/sv.po
26
locale/sv.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-30 20:02+0000\n"
|
||||
"Last-Translator: Jeff Epler <jepler@gmail.com>\n"
|
||||
"PO-Revision-Date: 2020-09-07 19:36+0000\n"
|
||||
"Last-Translator: Jonny Bergdahl <jonny@bergdahl.it>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: sv\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.1-dev\n"
|
||||
"X-Generator: Weblate 4.3-dev\n"
|
||||
|
||||
#: main.c
|
||||
msgid ""
|
||||
|
@ -500,7 +500,7 @@ msgstr "Kan inte ställa in CCCD på lokal karaktäristik"
|
|||
|
||||
#: shared-bindings/_bleio/Adapter.c
|
||||
msgid "Cannot create a new Adapter; use _bleio.adapter;"
|
||||
msgstr ""
|
||||
msgstr "Det går inte att skapa en ny Adapter; använd _bleio.adapter;"
|
||||
|
||||
#: shared-bindings/displayio/Bitmap.c
|
||||
#: shared-bindings/memorymonitor/AllocationSize.c
|
||||
|
@ -774,7 +774,7 @@ msgstr "Förväntade en karaktäristik"
|
|||
|
||||
#: shared-bindings/_bleio/Adapter.c
|
||||
msgid "Expected a DigitalInOut"
|
||||
msgstr ""
|
||||
msgstr "Förväntar en DigitalInOut"
|
||||
|
||||
#: shared-bindings/_bleio/Characteristic.c
|
||||
msgid "Expected a Service"
|
||||
|
@ -782,7 +782,7 @@ msgstr "Förväntade en tjänst"
|
|||
|
||||
#: shared-bindings/_bleio/Adapter.c
|
||||
msgid "Expected a UART"
|
||||
msgstr ""
|
||||
msgstr "Förväntar en UART"
|
||||
|
||||
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
|
||||
#: shared-bindings/_bleio/Service.c
|
||||
|
@ -1274,7 +1274,7 @@ msgstr "Kör inte sparad kod.\n"
|
|||
|
||||
#: shared-bindings/_bleio/__init__.c
|
||||
msgid "Not settable"
|
||||
msgstr ""
|
||||
msgstr "Går inte sätta"
|
||||
|
||||
#: shared-bindings/util.c
|
||||
msgid ""
|
||||
|
@ -1379,6 +1379,8 @@ msgid ""
|
|||
"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier "
|
||||
"instead"
|
||||
msgstr ""
|
||||
"Porten accepterar inte pinne eller frekvens. Skapa och skicka en PWMOut "
|
||||
"Carrier istället"
|
||||
|
||||
#: shared-bindings/_bleio/Adapter.c
|
||||
msgid "Prefix buffer must be on the heap"
|
||||
|
@ -2518,7 +2520,7 @@ msgstr "initialvärden måste vara iterable"
|
|||
|
||||
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
|
||||
msgid "initial_value length is wrong"
|
||||
msgstr ""
|
||||
msgstr "initial_value-längd är fel"
|
||||
|
||||
#: py/compile.c
|
||||
msgid "inline assembler must be a function"
|
||||
|
@ -2717,7 +2719,7 @@ msgstr "max_length måste vara 0-%d när fixed_length är %s"
|
|||
|
||||
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
|
||||
msgid "max_length must be > 0"
|
||||
msgstr ""
|
||||
msgstr "max_length måste vara > 0"
|
||||
|
||||
#: py/runtime.c
|
||||
msgid "maximum recursion depth exceeded"
|
||||
|
@ -2955,11 +2957,11 @@ msgstr "ord() förväntade sig ett tecken, men en sträng med längden %d hittad
|
|||
|
||||
#: shared-bindings/displayio/Bitmap.c
|
||||
msgid "out of range of source"
|
||||
msgstr ""
|
||||
msgstr "utanför räckvidd för source"
|
||||
|
||||
#: shared-bindings/displayio/Bitmap.c
|
||||
msgid "out of range of target"
|
||||
msgstr ""
|
||||
msgstr "utanför räckvidd för target"
|
||||
|
||||
#: py/objint_mpz.c
|
||||
msgid "overflow converting long int to machine word"
|
||||
|
@ -3143,7 +3145,7 @@ msgstr "sosfilt kräver iterable argument"
|
|||
|
||||
#: shared-bindings/displayio/Bitmap.c
|
||||
msgid "source palette too large"
|
||||
msgstr ""
|
||||
msgstr "källpalett för stor"
|
||||
|
||||
#: py/objstr.c
|
||||
msgid "start/end indices"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -78,10 +78,19 @@ 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/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
|
||||
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
|
||||
|
@ -125,11 +134,12 @@ 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 \
|
||||
-Tesp32s2.rom.spiflash.ld
|
||||
LIBS := -lgcc -lc
|
||||
LIBS := -lgcc -lc -lstdc++
|
||||
|
||||
#
|
||||
|
||||
|
@ -156,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 \
|
||||
|
@ -238,20 +249,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_netif lwip esp_rom esp-tls
|
||||
|
||||
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 +281,27 @@ 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/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 \
|
||||
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 \
|
||||
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
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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 "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
|
||||
//| 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);
|
||||
|
||||
//| 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_ROM_QSTR(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);
|
||||
|
||||
const mp_obj_module_t espidf_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&espidf_module_globals,
|
||||
};
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -34,8 +34,16 @@
|
|||
|
||||
#include "soc/efuse_reg.h"
|
||||
|
||||
#include "esp-idf/components/driver/esp32s2/include/driver/temp_sensor.h"
|
||||
|
||||
float common_hal_mcu_processor_get_temperature(void) {
|
||||
return NAN;
|
||||
float tsens_out;
|
||||
temp_sensor_config_t temp_sensor = TSENS_CONFIG_DEFAULT(); // DEFAULT: range:-10℃ ~ 80℃, error < 1℃.
|
||||
temp_sensor_set_config(temp_sensor);
|
||||
temp_sensor_start();
|
||||
temp_sensor_read_celsius(&tsens_out);
|
||||
temp_sensor_stop();
|
||||
return tsens_out;
|
||||
}
|
||||
|
||||
float common_hal_mcu_processor_get_voltage(void) {
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* 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/Socket.h"
|
||||
|
||||
#include "bindings/espidf/__init__.h"
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/runtime.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
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_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);
|
||||
self->connected = result >= 0;
|
||||
if (result < 0) {
|
||||
int esp_tls_code;
|
||||
int flags;
|
||||
esp_err_t err = esp_tls_get_and_clear_last_error(self->tcp->error_handle, &esp_tls_code, &flags);
|
||||
|
||||
if (err == ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) {
|
||||
mp_raise_espidf_MemoryError();
|
||||
} else if (ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
mp_raise_OSError(MP_ENOTCONN);
|
||||
}
|
||||
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 = 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);
|
||||
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) {
|
||||
last_read = status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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);
|
||||
received += last_read;
|
||||
}
|
||||
}
|
||||
|
||||
if (last_read == 0) {
|
||||
// socket closed
|
||||
common_hal_socketpool_socket_close(self);
|
||||
}
|
||||
if (last_read < 0) {
|
||||
mp_raise_BrokenPipeError();
|
||||
}
|
||||
return received;
|
||||
}
|
||||
|
||||
void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) {
|
||||
self->connected = false;
|
||||
if (self->tcp != NULL) {
|
||||
esp_tls_conn_destroy(self->tcp);
|
||||
self->tcp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t* self) {
|
||||
return self->tcp == NULL;
|
||||
}
|
||||
|
||||
|
||||
mp_uint_t common_hal_socketpool_socket_get_hash(socketpool_socket_obj_t* self) {
|
||||
return self->num;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
#include "common-hal/socketpool/SocketPool.h"
|
||||
#include "common-hal/ssl/SSLContext.h"
|
||||
|
||||
#include "esp-idf/components/esp-tls/esp_tls.h"
|
||||
|
||||
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;
|
||||
mp_uint_t timeout_ms;
|
||||
} socketpool_socket_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKET_H
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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 "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) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
} 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"));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
|
@ -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_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;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKETPOOL_H
|
|
@ -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.
|
||||
*/
|
|
@ -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
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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/ssl/SSLContext.h"
|
||||
|
||||
#include "py/runtime.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;
|
||||
}
|
|
@ -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.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL_SSLCONTEXT_H
|
||||
#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL_SSLCONTEXT_H
|
||||
|
||||
#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;
|
||||
} ssl_sslcontext_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL_SSL_CONTEXT_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.
|
||||
*/
|
||||
|
||||
#include "shared-bindings/ssl/SSLContext.h"
|
||||
|
||||
#include "esp-idf/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.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;
|
||||
}
|
|
@ -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_SSL___INIT___H
|
||||
#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL___INIT___H
|
||||
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SSL___INIT___H
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
mp_obj_t common_hal_wifi_network_get_ssid(wifi_network_obj_t *self) {
|
||||
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);
|
||||
}
|
|
@ -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.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_NETWORK_H
|
||||
#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_NETWORK_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
#include "esp-idf/components/esp_wifi/include/esp_wifi_types.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
wifi_ap_record_t record;
|
||||
} wifi_network_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_NETWORK_H
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "common-hal/wifi/__init__.h"
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
#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"
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAC_ADDRESS_LENGTH 6
|
||||
|
||||
mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) {
|
||||
uint8_t mac[MAC_ADDRESS_LENGTH];
|
||||
esp_wifi_get_mac(ESP_IF_WIFI_STA, mac);
|
||||
return mp_obj_new_bytes(mac, MAC_ADDRESS_LENGTH);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
config->sta.ssid[ssid_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);
|
||||
self->starting_retries = 5;
|
||||
self->retries_left = 5;
|
||||
esp_wifi_connect();
|
||||
|
||||
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) {
|
||||
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 WIFI_RADIO_ERROR_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_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) {
|
||||
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 && !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));
|
||||
}
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
#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
|
||||
#define WIFI_CONNECTED_BIT BIT1
|
||||
#define WIFI_DISCONNECTED_BIT BIT2
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
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;
|
||||
wifi_config_t sta_config;
|
||||
esp_netif_t *netif;
|
||||
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
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
#include "py/gc.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;
|
||||
if (self->results != NULL) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
self->scanning = false;
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
wifi_scan_config_t config = { 0 };
|
||||
config.channel = next_channel;
|
||||
if (next_channel == sizeof(scan_pattern)) {
|
||||
wifi_scannednetworks_done(self);
|
||||
} else {
|
||||
esp_err_t result = esp_wifi_scan_start(&config, false);
|
||||
if (result != 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)) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
wifi_scannednetworks_done(self);
|
||||
}
|
|
@ -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 <stdint.h>
|
||||
|
||||
#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
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* 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 "common-hal/wifi/__init__.h"
|
||||
|
||||
#include "shared-bindings/ipaddress/IPv4Address.h"
|
||||
#include "shared-bindings/wifi/Radio.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
#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;
|
||||
|
||||
#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;
|
||||
if (event_base == WIFI_EVENT) {
|
||||
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);
|
||||
}
|
||||
|
||||
// Cases to handle later.
|
||||
// case WIFI_EVENT_STA_START:
|
||||
// case WIFI_EVENT_STA_STOP:
|
||||
// case WIFI_EVENT_STA_AUTHMODE_CHANGE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static bool wifi_inited;
|
||||
|
||||
void common_hal_wifi_init(void) {
|
||||
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());
|
||||
|
||||
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,
|
||||
&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) {
|
||||
mp_raise_RuntimeError(translate("Failed to init wifi"));
|
||||
}
|
||||
common_hal_wifi_radio_set_enabled(self, true);
|
||||
}
|
||||
|
||||
void wifi_reset(void) {
|
||||
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_ERROR_CHECK(esp_wifi_deinit());
|
||||
esp_netif_destroy(radio->netif);
|
||||
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]);
|
||||
}
|
|
@ -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_ESP32S2_COMMON_HAL_WIFI___INIT___H
|
||||
#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI___INIT___H
|
||||
|
||||
#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
|
|
@ -1 +1 @@
|
|||
Subproject commit 160ba4924d8b588e718f76e3a0d0e92c11052fa3
|
||||
Subproject commit de733cdab556c5713c94ba95078f4024dd56fd87
|
|
@ -28,18 +28,19 @@
|
|||
#ifndef ESP32S2_MPCONFIGPORT_H__
|
||||
#define ESP32S2_MPCONFIGPORT_H__
|
||||
|
||||
#define CIRCUITPY_INTERNAL_NVM_SIZE (0)
|
||||
#define MICROPY_NLR_THUMB (0)
|
||||
#define CIRCUITPY_INTERNAL_NVM_SIZE (0)
|
||||
#define MICROPY_NLR_THUMB (0)
|
||||
|
||||
#define MICROPY_PY_UJSON (0)
|
||||
#define MICROPY_USE_INTERNAL_PRINTF (0)
|
||||
#define MICROPY_PY_UJSON (1)
|
||||
#define MICROPY_USE_INTERNAL_PRINTF (0)
|
||||
|
||||
#include "py/circuitpy_mpconfig.h"
|
||||
|
||||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
CIRCUITPY_COMMON_ROOT_POINTERS
|
||||
#define MICROPY_NLR_SETJMP (1)
|
||||
#define CIRCUITPY_DEFAULT_STACK_SIZE (0x6000)
|
||||
#define MICROPY_NLR_SETJMP (1)
|
||||
#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000
|
||||
|
||||
|
||||
#endif // __INCLUDED_ESP32S2_MPCONFIGPORT_H
|
||||
|
|
|
@ -13,21 +13,19 @@ USB_SERIAL_NUMBER_LENGTH = 12
|
|||
LONGINT_IMPL = MPZ
|
||||
|
||||
# These modules are implemented in ports/<port>/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.
|
||||
# Requires USB
|
||||
CIRCUITPY_ROTARYIO = 0
|
||||
CIRCUITPY_RTC = 0
|
||||
CIRCUITPY_NVM = 0
|
||||
# We don't have enough endpoints to include MIDI.
|
||||
CIRCUITPY_USB_MIDI = 0
|
||||
# Too large for the partition table!
|
||||
CIRCUITPY_ULAB = 0
|
||||
CIRCUITPY_WIFI = 1
|
||||
CIRCUITPY_ESPIDF = 1
|
||||
|
||||
CIRCUITPY_MODULE ?= none
|
||||
|
|
|
@ -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,
|
||||
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,
|
||||
# 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,
|
||||
|
|
|
|
@ -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
|
||||
|
@ -122,8 +128,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
|
||||
|
@ -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
|
||||
|
@ -279,9 +298,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 +316,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
|
||||
|
||||
#
|
||||
|
@ -309,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
|
||||
|
||||
#
|
||||
|
@ -333,7 +351,7 @@ 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
|
||||
|
@ -389,7 +407,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
|
||||
|
@ -432,12 +449,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_SO_RCVBUF=y
|
||||
# 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
|
||||
|
@ -478,6 +498,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
|
||||
|
||||
#
|
||||
|
@ -492,6 +513,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
|
||||
|
@ -514,6 +536,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
|
||||
|
||||
#
|
||||
|
@ -578,8 +614,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
|
||||
|
@ -677,6 +713,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
|
||||
|
@ -710,7 +747,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 is not set
|
||||
# CONFIG_WPA_WPS_WARS is not set
|
||||
# end of Supplicant
|
||||
# end of Component config
|
||||
|
@ -745,8 +781,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
|
||||
|
@ -767,10 +803,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
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "common-hal/busio/UART.h"
|
||||
#include "common-hal/pulseio/PulseIn.h"
|
||||
#include "common-hal/pwmio/PWMOut.h"
|
||||
#include "common-hal/wifi/__init__.h"
|
||||
#include "supervisor/memory.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
|
@ -65,6 +66,8 @@ safe_mode_t port_init(void) {
|
|||
args.dispatch_method = ESP_TIMER_TASK;
|
||||
args.name = "CircuitPython Tick";
|
||||
esp_timer_create(&args, &_tick_timer);
|
||||
|
||||
heap = NULL;
|
||||
never_reset_module_internal_pins();
|
||||
|
||||
#ifdef CONFIG_SPIRAM
|
||||
|
@ -76,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;
|
||||
}
|
||||
|
||||
|
@ -99,6 +106,9 @@ void reset_port(void) {
|
|||
spi_reset();
|
||||
uart_reset();
|
||||
#endif
|
||||
#if CIRCUITPY_WIFI
|
||||
wifi_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
void reset_to_bootloader(void) {
|
||||
|
|
|
@ -180,7 +180,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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<<pin_number;
|
||||
// Make sure never reset pins are also always claimed
|
||||
claimed_pins[pin_port] |= 1<<pin_number;
|
||||
|
|
|
@ -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
|
||||
|
@ -228,6 +231,12 @@ endif
|
|||
ifeq ($(CIRCUITPY_SHARPDISPLAY),1)
|
||||
SRC_PATTERNS += sharpdisplay/%
|
||||
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
|
||||
|
@ -264,6 +273,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
|
||||
|
@ -332,11 +344,20 @@ SRC_COMMON_HAL_ALL = \
|
|||
rtc/__init__.c \
|
||||
sdioio/SDCard.c \
|
||||
sdioio/__init__.c \
|
||||
socketpool/__init__.c \
|
||||
socketpool/SocketPool.c \
|
||||
socketpool/Socket.c \
|
||||
ssl/__init__.c \
|
||||
ssl/SSLContext.c \
|
||||
supervisor/Runtime.c \
|
||||
supervisor/__init__.c \
|
||||
watchdog/WatchDogMode.c \
|
||||
watchdog/WatchDogTimer.c \
|
||||
watchdog/__init__.c \
|
||||
wifi/Network.c \
|
||||
wifi/Radio.c \
|
||||
wifi/ScannedNetworks.c \
|
||||
wifi/__init__.c \
|
||||
|
||||
ifeq ($(CIRCUITPY_BLEIO_HCI),1)
|
||||
# Helper code for _bleio HCI.
|
||||
|
@ -414,6 +435,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 \
|
||||
|
|
|
@ -185,6 +185,7 @@ typedef long mp_off_t;
|
|||
// Turning off FULL_BUILD removes some functionality to reduce flash size on tiny SAMD21s
|
||||
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (CIRCUITPY_FULL_BUILD)
|
||||
#define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD)
|
||||
#define MICROPY_PY_BUILTINS_POW3 (CIRCUITPY_FULL_BUILD)
|
||||
#define MICROPY_COMP_FSTRING_LITERAL (MICROPY_CPYTHON_COMPAT)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (CIRCUITPY_FULL_BUILD)
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD)
|
||||
|
@ -363,6 +364,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 },
|
||||
|
@ -420,6 +428,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 },
|
||||
|
@ -573,6 +588,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 +596,20 @@ 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_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 },
|
||||
|
@ -690,6 +720,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 \
|
||||
|
@ -728,12 +765,14 @@ extern const struct _mp_obj_module_t watchdog_module;
|
|||
TERMINALIO_MODULE \
|
||||
VECTORIO_MODULE \
|
||||
ERRNO_MODULE \
|
||||
ESPIDF_MODULE \
|
||||
FRAMEBUFFERIO_MODULE \
|
||||
FREQUENCYIO_MODULE \
|
||||
GAMEPAD_MODULE \
|
||||
GAMEPADSHIFT_MODULE \
|
||||
GNSS_MODULE \
|
||||
I2CPERIPHERAL_MODULE \
|
||||
IPADDRESS_MODULE \
|
||||
JSON_MODULE \
|
||||
MATH_MODULE \
|
||||
_EVE_MODULE \
|
||||
|
@ -757,6 +796,8 @@ extern const struct _mp_obj_module_t watchdog_module;
|
|||
SDCARDIO_MODULE \
|
||||
SDIOIO_MODULE \
|
||||
SHARPDISPLAY_MODULE \
|
||||
SOCKETPOOL_MODULE \
|
||||
SSL_MODULE \
|
||||
STAGE_MODULE \
|
||||
STORAGE_MODULE \
|
||||
STRUCT_MODULE \
|
||||
|
@ -767,6 +808,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.
|
||||
|
|
|
@ -99,6 +99,12 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO)
|
|||
CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD)
|
||||
CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO)
|
||||
|
||||
# CIRCUITPY_ESPIDF is handled in the esp32s2 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
|
||||
|
@ -124,6 +130,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)
|
||||
|
||||
|
@ -191,6 +200,12 @@ CFLAGS += -DCIRCUITPY_SDIOIO=$(CIRCUITPY_SDIOIO)
|
|||
CIRCUITPY_SHARPDISPLAY ?= $(CIRCUITPY_FRAMEBUFFERIO)
|
||||
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)
|
||||
|
@ -263,6 +278,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)
|
||||
|
|
|
@ -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 encode_ngrams(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 decode_ngrams(compressed, ngrams):
|
||||
if len(ngrams) > 32:
|
||||
start, end = 0xe000, 0xf8ff
|
||||
else:
|
||||
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):
|
||||
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 = encode_ngrams(all_strings_concat, ngrams)
|
||||
counts = collections.Counter(all_strings_concat)
|
||||
cb = huffman.codebook(counts.items())
|
||||
values = []
|
||||
|
@ -125,10 +146,12 @@ 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)
|
||||
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 +159,18 @@ 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 {} 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):
|
||||
values, lengths = encoding_table
|
||||
values, lengths, ngrams = encoding_table
|
||||
dec = []
|
||||
this_byte = 0
|
||||
this_bit = 7
|
||||
|
@ -187,6 +218,7 @@ def decompress(encoding_table, encoded, encoded_length_bits):
|
|||
searched_length += lengths[bit_length]
|
||||
|
||||
v = values[searched_length + bits - max_code]
|
||||
v = decode_ngrams(v, ngrams)
|
||||
i += len(v.encode('utf-8'))
|
||||
dec.append(v)
|
||||
return ''.join(dec)
|
||||
|
@ -194,7 +226,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 = encode_ngrams(decompressed, ngrams)
|
||||
enc = bytearray(len(decompressed) * 3)
|
||||
#print(decompressed)
|
||||
#print(lengths)
|
||||
|
|
|
@ -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
|
||||
|
|
3
py/mpz.h
3
py/mpz.h
|
@ -135,6 +135,9 @@ void mpz_xor_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs);
|
|||
void mpz_divmod_inpl(mpz_t *dest_quo, mpz_t *dest_rem, const mpz_t *lhs, const mpz_t *rhs);
|
||||
|
||||
static inline size_t mpz_max_num_bits(const mpz_t *z) { return z->len * MPZ_DIG_SIZE; }
|
||||
static inline size_t mpz_num_bits(const mpz_t *z) {
|
||||
size_t last_bits = (8 * (sizeof(long) - sizeof(mpz_dig_t))) - __builtin_clzl(z->dig[z->len-1]);
|
||||
return z->len * MPZ_DIG_SIZE + last_bits; }
|
||||
mp_int_t mpz_hash(const mpz_t *z);
|
||||
bool mpz_as_int_checked(const mpz_t *z, mp_int_t *value);
|
||||
bool mpz_as_uint_checked(const mpz_t *z, mp_uint_t *value);
|
||||
|
|
2
py/obj.h
2
py/obj.h
|
@ -627,6 +627,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;
|
||||
|
|
|
@ -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)
|
||||
|
|
25
py/objint.c
25
py/objint.c
|
@ -457,6 +457,28 @@ mp_obj_t mp_obj_int_binary_op_extra_cases(mp_binary_op_t op, mp_obj_t lhs_in, mp
|
|||
return MP_OBJ_NULL; // op not supported
|
||||
}
|
||||
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
STATIC mp_obj_t int_bit_length(mp_obj_t self_in) {
|
||||
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
|
||||
if (!MP_OBJ_IS_SMALL_INT(self_in)) {
|
||||
return mp_obj_int_bit_length_impl(self_in);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
mp_int_t int_val = MP_OBJ_SMALL_INT_VALUE(self_in);
|
||||
mp_uint_t value =
|
||||
(int_val == 0) ? 0 :
|
||||
(int_val == MP_SMALL_INT_MIN) ? 8 * sizeof(mp_int_t) :
|
||||
(int_val < 0) ? 8 * sizeof(long) - __builtin_clzl(-int_val) :
|
||||
8 * sizeof(long) - __builtin_clzl(int_val);
|
||||
return mp_obj_new_int_from_uint(value);
|
||||
}
|
||||
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(int_bit_length_obj, int_bit_length);
|
||||
#endif
|
||||
|
||||
// this is a classmethod
|
||||
STATIC mp_obj_t int_from_bytes(size_t n_args, const mp_obj_t *args) {
|
||||
// TODO: Support signed param (assumes signed=False at the moment)
|
||||
|
@ -537,6 +559,9 @@ STATIC mp_obj_t int_to_bytes(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
|
|||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(int_to_bytes_obj, 3, int_to_bytes);
|
||||
|
||||
STATIC const mp_rom_map_elem_t int_locals_dict_table[] = {
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
{ MP_ROM_QSTR(MP_QSTR_bit_length), MP_ROM_PTR(&int_bit_length_obj) },
|
||||
#endif
|
||||
{ MP_ROM_QSTR(MP_QSTR_from_bytes), MP_ROM_PTR(&int_from_bytes_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_to_bytes), MP_ROM_PTR(&int_to_bytes_obj) },
|
||||
};
|
||||
|
|
|
@ -60,6 +60,7 @@ void mp_obj_int_buffer_overflow_check(mp_obj_t self_in, size_t nbytes, bool is_s
|
|||
void mp_small_int_buffer_overflow_check(mp_int_t val, size_t nbytes, bool is_signed);
|
||||
|
||||
mp_int_t mp_obj_int_hash(mp_obj_t self_in);
|
||||
mp_obj_t mp_obj_int_bit_length_impl(mp_obj_t self_in);
|
||||
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf);
|
||||
void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf);
|
||||
int mp_obj_int_sign(mp_obj_t self_in);
|
||||
|
|
|
@ -45,6 +45,17 @@
|
|||
const mp_obj_int_t mp_maxsize_obj = {{&mp_type_int}, MP_SSIZE_MAX};
|
||||
#endif
|
||||
|
||||
mp_obj_t mp_obj_int_bit_length_impl(mp_obj_t self_in) {
|
||||
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int));
|
||||
mp_obj_int_t *self = self_in;
|
||||
long long val = self->val;
|
||||
return MP_OBJ_NEW_SMALL_INT(
|
||||
(val == 0) ? 0 :
|
||||
(val == MP_SMALL_INT_MIN) ? 8 * sizeof(long long) :
|
||||
(val < 0) ? 8 * sizeof(long long) - __builtin_clzll(-val) :
|
||||
8 * sizeof(long long) - __builtin_clzll(val));
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf) {
|
||||
int delta = 1;
|
||||
if (!big_endian) {
|
||||
|
|
|
@ -107,6 +107,12 @@ char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size,
|
|||
return str;
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_int_bit_length_impl(mp_obj_t self_in) {
|
||||
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int));
|
||||
mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return MP_OBJ_NEW_SMALL_INT(mpz_num_bits(&self->mpz));
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf) {
|
||||
mp_obj_int_t *o = mp_obj_int_new_mpz();
|
||||
mpz_set_from_bytes(&o->mpz, big_endian, len, buf);
|
||||
|
|
|
@ -1602,6 +1602,14 @@ 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)));
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg) {
|
||||
mp_raise_msg(&mp_type_NotImplementedError, msg);
|
||||
}
|
||||
|
|
|
@ -166,6 +166,8 @@ 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, ...);
|
||||
NORETURN void mp_raise_OverflowError_varg(const compressed_string_t *fmt, ...);
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* 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 "shared-bindings/ipaddress/IPv4Address.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/objproperty.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/ipaddress/__init__.h"
|
||||
|
||||
//| class IPv4Address:
|
||||
//| """Encapsulates an IPv4 address."""
|
||||
//|
|
||||
|
||||
//| 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."""
|
||||
//| ...
|
||||
//|
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
common_hal_ipaddress_ipv4address_construct(self, buf, 4);
|
||||
|
||||
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: IPv4Address) -> 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 IPv4Address 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
|
||||
};
|
|
@ -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(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_IPADDRESS_IPV4ADDRESS_H
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* 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/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.
|
||||
//| """
|
||||
//|
|
||||
|
||||
|
||||
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."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t ipaddress_ip_address(mp_obj_t ip_in) {
|
||||
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);
|
||||
if (!ipaddress_parse_ipv4address((const char*) str_data, str_len, &value)) {
|
||||
mp_raise_ValueError(translate("Not a valid IP string"));
|
||||
}
|
||||
} else {
|
||||
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,
|
||||
};
|
|
@ -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_BINDINGS_IPADDRESS___INIT___H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_IPADDRESS___INIT___H
|
||||
|
||||
#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
|
|
@ -0,0 +1,468 @@
|
|||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/utils/context_manager_helpers.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objlist.h"
|
||||
#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()`.
|
||||
//|
|
||||
//| 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_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__);
|
||||
|
||||
// //| 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) {
|
||||
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);
|
||||
|
||||
//| 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) {
|
||||
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
mp_obj_t *addr_items;
|
||||
mp_obj_get_array_fixed_n(addr_in, 2, &addr_items);
|
||||
|
||||
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]);
|
||||
|
||||
bool ok = common_hal_socketpool_socket_connect(self, host, hostlen, port);
|
||||
if (!ok) {
|
||||
ESP_EARLY_LOGW(TAG, "socket connect failed");
|
||||
mp_raise_OSError(0);
|
||||
}
|
||||
|
||||
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) {
|
||||
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (common_hal_socketpool_socket_get_closed(self)) {
|
||||
// Bad file number.
|
||||
mp_raise_OSError(MP_EBADF);
|
||||
}
|
||||
if (!common_hal_socketpool_socket_get_connected(self)) {
|
||||
mp_raise_BrokenPipeError();
|
||||
}
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
||||
mp_int_t ret = common_hal_socketpool_socket_send(self, bufinfo.buf, bufinfo.len);
|
||||
if (ret == -1) {
|
||||
mp_raise_BrokenPipeError();
|
||||
}
|
||||
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) {
|
||||
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
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;
|
||||
if (n_args == 3) {
|
||||
mp_int_t given_len = mp_obj_get_int(args[2]);
|
||||
if (given_len < len) {
|
||||
len = given_len;
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return MP_OBJ_NEW_SMALL_INT(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)"""
|
||||
// //| ...
|
||||
// //|
|
||||
|
||||
// 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) {
|
||||
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."""
|
||||
// //| ...
|
||||
// //|
|
||||
|
||||
// // 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);
|
||||
|
||||
//| 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) },
|
||||
{ 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,
|
||||
.unary_op = socketpool_socket_unary_op,
|
||||
};
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
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);
|
||||
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
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objlist.h"
|
||||
#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"
|
||||
|
||||
#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.
|
||||
//|
|
||||
//| 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, 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[0];
|
||||
|
||||
common_hal_socketpool_socketpool_construct(s, radio);
|
||||
|
||||
return MP_OBJ_FROM_PTR(s);
|
||||
}
|
||||
|
||||
|
||||
//| 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
|
||||
//| :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, 5, false);
|
||||
|
||||
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, 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
|
||||
//| address information to call socket.socket() and socket.connect() with,
|
||||
//| as a tuple."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socketpool_socketpool_getaddrinfo(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_host, ARG_port, ARG_family, ARG_type, ARG_proto, ARG_flags };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ 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]);
|
||||
|
||||
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 *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 (strlen(host) > 0 && ipaddress_parse_ipv4address(host, strlen(host), NULL)) {
|
||||
ip_str = args[ARG_host].u_obj;
|
||||
}
|
||||
|
||||
if (ip_str == mp_const_none) {
|
||||
ip_str = common_hal_socketpool_socketpool_gethostbyname(self, host);
|
||||
}
|
||||
|
||||
if (ip_str == mp_const_none) {
|
||||
ESP_EARLY_LOGW(TAG, "no ip str");
|
||||
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_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) },
|
||||
{ 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,
|
||||
};
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
#include "shared-bindings/socketpool/Socket.h"
|
||||
|
||||
extern const mp_obj_type_t socketpool_socketpool_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_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);
|
||||
|
||||
mp_obj_t common_hal_socketpool_socketpool_gethostbyname(socketpool_socketpool_obj_t* self,
|
||||
const char* host);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKETPOOL_H
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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/socketpool/__init__.h"
|
||||
#include "shared-bindings/socketpool/Socket.h"
|
||||
#include "shared-bindings/socketpool/SocketPool.h"
|
||||
|
||||
//| """
|
||||
//| The `socketpool` module provides sockets through a pool. The pools themselves
|
||||
//| act like CPython's `socket` module.
|
||||
//| """
|
||||
//|
|
||||
|
||||
STATIC const mp_rom_map_elem_t socketpool_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_socketpool) },
|
||||
|
||||
{ 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(socketpool_globals, socketpool_globals_table);
|
||||
|
||||
const mp_obj_module_t socketpool_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&socketpool_globals,
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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___INIT___H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL___INIT___H
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL___INIT___H
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* 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
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objlist.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
|
||||
#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) {
|
||||
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,
|
||||
};
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
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
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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) },
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
//| 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_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_last_received_report_obj, usb_hid_device_obj_get_last_received_report);
|
||||
|
||||
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_last_received_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)"""
|
||||
//|
|
||||
|
@ -95,9 +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_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_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)},
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(usb_hid_device_locals_dict, usb_hid_device_locals_dict_table);
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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 <string.h>
|
||||
|
||||
#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
|
||||
//| """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);
|
||||
|
||||
}
|
||||
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 },
|
||||
};
|
||||
|
||||
|
||||
//| 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);
|
||||
|
||||
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,
|
||||
};
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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 <stdint.h>
|
||||
|
||||
#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);
|
||||
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
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* 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 <string.h>
|
||||
|
||||
#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: bytes
|
||||
//| """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, *, 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) {
|
||||
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"", *, 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_channel, ARG_timeout };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ 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} },
|
||||
};
|
||||
|
||||
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;
|
||||
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"));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
//| 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_ipv4_address(mp_obj_t self) {
|
||||
return common_hal_wifi_radio_get_ipv4_address(self);
|
||||
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_address_obj, wifi_radio_get_ipv4_address);
|
||||
|
||||
const mp_obj_property_t wifi_radio_ipv4_address_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = { (mp_obj_t)&wifi_radio_get_ipv4_address_obj,
|
||||
(mp_obj_t)&mp_const_none_obj,
|
||||
(mp_obj_t)&mp_const_none_obj },
|
||||
};
|
||||
|
||||
//| def ping(self, ip, *, timeout: float = 0.5) -> float:
|
||||
//| """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) {
|
||||
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} },
|
||||
};
|
||||
|
||||
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.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);
|
||||
if (time_ms == -1) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
return mp_obj_new_float(time_ms / 1000.0);
|
||||
}
|
||||
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) },
|
||||
{ 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_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) },
|
||||
|
||||
{ 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,
|
||||
};
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 <stdint.h>
|
||||
|
||||
#include "common-hal/wifi/Radio.h"
|
||||
|
||||
#include "py/objstr.h"
|
||||
|
||||
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);
|
||||
|
||||
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 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);
|
||||
|
||||
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
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "py/objproperty.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/wifi/ScannedNetworks.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
static const char *TAG = "cp iternext";
|
||||
|
||||
//| class ScannedNetworks:
|
||||
//| """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) {
|
||||
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;
|
||||
}
|
||||
|
||||
ESP_EARLY_LOGI(TAG, "stop iteration");
|
||||
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,
|
||||
};
|
|
@ -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
|
|
@ -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 "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."""
|
||||
//|
|
||||
//| radio: 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,
|
||||
};
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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(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 MP_OBJ_FROM_PTR(self);
|
||||
}
|
|
@ -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 <stdint.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
mp_obj_t common_hal_ipaddress_new_ipv4(uint32_t value);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_MODULE_IPADDRESS___INIT___H
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,13 +47,20 @@ STATIC int put_utf8(char *buf, int u) {
|
|||
if(u <= 0x7f) {
|
||||
*buf = u;
|
||||
return 1;
|
||||
} else if(bigram_start <= u && u <= bigram_end) {
|
||||
int n = (u - 0x80) * 2;
|
||||
// (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 { // u <= 0xffff)
|
||||
*buf++ = 0b11000000 | (u >> 12);
|
||||
*buf = 0b10000000 | ((u >> 6) & 0b00111111);
|
||||
} else { // u <= 0xffff
|
||||
*buf++ = 0b11100000 | (u >> 12);
|
||||
*buf++ = 0b10000000 | ((u >> 6) & 0b00111111);
|
||||
*buf = 0b10000000 | (u & 0b00111111);
|
||||
return 3;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
for i in range(129):
|
||||
j = (1 << i)
|
||||
print(i, (j-1).bit_length(), (j).bit_length(), (j+1).bit_length())
|
||||
print(i, (-j-1).bit_length(), (-j).bit_length(), (-j+1).bit_length())
|
|
@ -1,14 +1,14 @@
|
|||
########
|
||||
object <function> is of type function
|
||||
object <class 'int'> is of type type
|
||||
bit_length -- <function>
|
||||
from_bytes -- <classmethod>
|
||||
to_bytes -- <function>
|
||||
object 1 is of type int
|
||||
bit_length -- <function>
|
||||
from_bytes -- <classmethod>
|
||||
to_bytes -- <function>
|
||||
object <module 'micropython'> is of type module
|
||||
__name__ -- micropython
|
||||
const -- <function>
|
||||
opt_level -- <function>
|
||||
########
|
||||
done
|
||||
|
|
|
@ -12,7 +12,7 @@ Use \.\+
|
|||
'abc'
|
||||
>>> x = 5
|
||||
>>> x.
|
||||
from_bytes to_bytes
|
||||
bit_length from_bytes to_bytes
|
||||
>>> x.[K[K
|
||||
>>> x.__class__
|
||||
<class 'int'>
|
||||
|
|
|
@ -546,7 +546,7 @@ c_file.write("""
|
|||
};
|
||||
""")
|
||||
|
||||
c_file.write("\n");
|
||||
c_file.write("\n")
|
||||
|
||||
hid_descriptor_length = len(bytes(combined_hid_report_descriptor))
|
||||
|
||||
|
@ -604,12 +604,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 }},
|
||||
|
@ -618,11 +624,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("""\
|
||||
};
|
||||
""")
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue