mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-27 19:57:38 +00:00
Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into feature/Metrics-add-network-tx-rx-data
This commit is contained in:
@@ -67,6 +67,7 @@ collection_F | Normal + plugin collection F | Stable + Collection b
|
||||
collection_G | Normal + plugin collection G | Stable + Collection base + set G |
|
||||
collection_H | Normal + plugin collection H | Stable + Collection base + set H |
|
||||
max | All available plugins | All available |
|
||||
max32 | All available plugins, 32MB Flash | All available, large file system |
|
||||
energy | All plugins related to energy measurement | Stable + Energy measurement |
|
||||
display A | All plugins related to displays A | Stable + Displays A |
|
||||
display B | All plugins related to displays B | Stable + Displays B |
|
||||
@@ -101,6 +102,10 @@ ESP32c3 | Espressif ESP32-C3 generic boards |
|
||||
ESP32s3 | Espressif ESP32-S3 generic boards |
|
||||
ESP32c2 | Espressif ESP32-C2 generic boards |
|
||||
ESP32c6 | Espressif ESP32-C6 generic boards |
|
||||
ESP32c61 | Espressif ESP32-C61 generic boards (experimental) |
|
||||
ESP32c5 | Espressif ESP32-C5 generic boards (experimental) |
|
||||
ESP32p4 | Espressif ESP32-P4 (Rev.1) generic boards |
|
||||
ESP32p4r3 | Espressif ESP32-P4 (Rev.3/P4X) generic boards |
|
||||
ESP32-wrover-kit | Espressif ESP32 wrover-kit boards |
|
||||
SONOFF | Sonoff hardware specific |
|
||||
other_POW | Switch with power measurement |
|
||||
@@ -124,10 +129,10 @@ Flash size | Description |
|
||||
16M | 16 MB with 14 MB filesystem |
|
||||
4M316k | 4 MB with 316 kB filesystem |
|
||||
8M1M | 8 MB with 1 MB filesystem |
|
||||
16M1M | 16 MB with 1 MB filesystem |
|
||||
16M8M | 16 MB with 8 MB filesystem |
|
||||
32M20M | 32 MB with 20 MB filesystem |
|
||||
|
||||
N.B. Starting with release 2023/12/25, All ESP32 LittleFS builds use IDF 5.3, to support newer ESP32 chips like ESP32-C2 and ESP32-C6, and SPI Ethernet. Other SPIFFS based ESP32 builds will be migrated to LittleFS as SPIFFS is no longer officially available in IDF 5 and later. As a temporary solution, a specially crafted IDF 5.1 build that still includes SPIFFS, is used for the SPIFFS builds. A migration plan will be made available in 2025.
|
||||
N.B. Starting with release 2023/12/25, All ESP32 LittleFS builds use IDF 5.3, to support newer ESP32 chips like ESP32-C2 and ESP32-C6, and SPI Ethernet. Other SPIFFS based ESP32 builds will be migrated to LittleFS as SPIFFS is no longer officially available in IDF 5 and later. As a temporary solution, a specially crafted IDF 5.1 build that still includes SPIFFS, is used for the SPIFFS builds. A migration plan is available, [here](https://espeasy.readthedocs.io/en/latest/Reference/Migrate_SPIFFS_to_LittleFS.html).
|
||||
|
||||
N.B.2 Starting with builds made after 2025/11/04, ESP32 builds will no longer have ``_LittleFS`` in the name as all ESP32 builds use LittleFS. Also the suffix ``_ETH`` has been removed since all builds will have Ethernet support, except for ESP32C2 builds.
|
||||
|
||||
@@ -142,7 +147,7 @@ Domoticz_MQTT | Only Domoticz controllers (MQTT) and plugins included
|
||||
FHEM_HA | Only FHEM/OpenHAB/Home Assistant (MQTT) controllers and plugins included |
|
||||
ETH | Ethernet support enabled (ESP32 and IDF 5.x based builds) |
|
||||
OPI_PSRAM | Specific configuration to enable PSRAM detection, ESP32-S3 only |
|
||||
CDC | Support USBCDC/HWCDC-serial console on ESP32-C3, ESP32-S2, ESP32-S3 and ESP32-C6 |
|
||||
CDC | Support USBCDC/HWCDC-serial console on ESP32-C3, ESP32-S2, ESP32-S3, ESP32-C6, ESP32-C61 and ESP32-C5 |
|
||||
noOTA/NO_OTA | Does not support OTA (Over The Air-updating of the firmware) Use [the flash page](https://td-er.nl/ESPEasy/) or ESPTool via USB Serial |
|
||||
|
||||
N.B. Starting ca. 2025/02/27, many ESP32 builds are *only* available with _ETH suffix, indicating that Ethernet support is enabled, to reduce the (rather high) number of builds.
|
||||
@@ -150,18 +155,17 @@ N.B. Starting ca. 2025/02/27, many ESP32 builds are *only* available with _ETH s
|
||||
Some example firmware names:
|
||||
Firmware name | Hardware | Included plugins |
|
||||
--------------------------------------------------------|-------------------------------------------------|----------------------------------|
|
||||
ESPEasy_mega-20230822_normal_ESP8266_1M.bin | ESP8266/ESP8285 with 1MB flash | Stable |
|
||||
ESPEasy_mega-20230822_normal_ESP8266_4M1M.bin | ESP8266 with 4MB flash | Stable |
|
||||
ESPEasy_mega-20230822_collection_A_ESP8266_4M1M.bin | ESP8266 with 4MB flash | Stable + Collection base + set A |
|
||||
ESPEasy_mega-20230822_normal_ESP32_4M316k_ETH.bin | ESP32 with 4MB flash | Stable |
|
||||
ESPEasy_mega-20230822_collection_A_ESP32_4M316k_ETH.bin | ESP32 with 4MB flash | Stable + Collection base + set A |
|
||||
ESPEasy_mega-20230822_collection_B_ESP32_4M316k_ETH.bin | ESP32 with 4MB flash | Stable + Collection base + set B |
|
||||
ESPEasy_mega-20230822_max_ESP32s3_8M1M.bin | ESP32-S3 with 8MB flash, CDC-serial, Ethernet | All available plugins |
|
||||
ESPEasy_mega-20230822_max_ESP32s3_8M1M_OPI_PSRAM.bin | ESP32-S3 8MB flash, PSRAM, CDC-serial, Ethernet | All available plugins |
|
||||
ESPEasy_mega-20230822_max_ESP32_16M1M_ETH.bin | ESP32 with 16MB flash, SPIFFS, Ethernet | All available plugins |
|
||||
ESPEasy_mega-20230822_max_ESP32_16M8M.bin | ESP32 with 16MB flash, LittleFS, Ethernet | All available plugins |
|
||||
ESPEasy_mega-20260121_normal_ESP8266_1M.bin | ESP8266/ESP8285 with 1MB flash | Stable |
|
||||
ESPEasy_mega-20260121_normal_ESP8266_4M1M.bin | ESP8266 with 4MB flash | Stable |
|
||||
ESPEasy_mega-20260121_collection_A_ESP8266_4M1M.bin | ESP8266 with 4MB flash | Stable + Collection base + set A |
|
||||
ESPEasy_mega-20260121_normal_ESP32_4M316k.bin | ESP32 with 4MB flash | Stable |
|
||||
ESPEasy_mega-20260121_collection_A_ESP32_4M316k.bin | ESP32 with 4MB flash | Stable + Collection base + set A |
|
||||
ESPEasy_mega-20260121_collection_B_ESP32_4M316k.bin | ESP32 with 4MB flash | Stable + Collection base + set B |
|
||||
ESPEasy_mega-20260121_max_ESP32s3_8M1M.bin | ESP32-S3 with 8MB flash, CDC-serial, Ethernet | All available plugins |
|
||||
ESPEasy_mega-20260121_max_ESP32s3_8M1M_OPI_PSRAM.bin | ESP32-S3 8MB flash, PSRAM, CDC-serial, Ethernet | All available plugins |
|
||||
ESPEasy_mega-20260121_max_ESP32_16M8M.bin | ESP32 with 16MB flash, LittleFS, Ethernet | All available plugins |
|
||||
|
||||
The binary files for the different ESP32 variants (S2, C3, S3, C2, C6, Solo1, 'Classic') are available in separate archives.
|
||||
The binary files for the different ESP32 variants (S2, C3, S3, C2, C6/C61, C5, P4, Solo1, 'Classic') are available in separate archives.
|
||||
|
||||
To see what plugins are included in which collection set, you can find that on the [ESPEasy Plugin overview page](https://espeasy.readthedocs.io/en/latest/Plugin/_Plugin.html)
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino":{
|
||||
"ldscript": "esp32c5_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": "-DARDUINO_TASMOTA -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DUSE_USB_CDC_CONSOLE -DESP32_16M -DESP32C5 -DARDUINO_USB_CDC_ON_BOOT=0",
|
||||
"f_cpu": "160000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"mcu": "esp32c5",
|
||||
"variant": "esp32c5",
|
||||
"partitions": "boards/partitions/esp32_partition_app4096k_spiffs8124k.csv"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth"
|
||||
],
|
||||
"debug": {
|
||||
"default_tool": "esp-builtin",
|
||||
"onboard_tools": [
|
||||
"esp-builtin"
|
||||
],
|
||||
"openocd_target": "esp32c5.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "Espressif Generic ESP32-C5 16M Flash, ESPEasy 4096k Code/OTA 8M FS",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 16777216,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32c5/esp32-c5-devkitc-1/index.html",
|
||||
"vendor": "Espressif"
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino":{
|
||||
"ldscript": "esp32c5_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": "-DARDUINO_TASMOTA -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DUSE_USB_CDC_CONSOLE -DESP32_32M -DESP32C5 -DARDUINO_USB_CDC_ON_BOOT=0",
|
||||
"f_cpu": "160000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"mcu": "esp32c5",
|
||||
"variant": "esp32c5",
|
||||
"partitions": "boards/partitions/esp32_partition_app6144k_spiffs20412k.csv"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth"
|
||||
],
|
||||
"debug": {
|
||||
"default_tool": "esp-builtin",
|
||||
"onboard_tools": [
|
||||
"esp-builtin"
|
||||
],
|
||||
"openocd_target": "esp32c5.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "Espressif Generic ESP32-C5 32M Flash, ESPEasy 6144k Code/OTA 20M FS",
|
||||
"upload": {
|
||||
"flash_size": "32MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 33554432,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32c5/esp32-c5-devkitc-1/index.html",
|
||||
"vendor": "Espressif"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DARDUINO_TASMOTA -DESP32P4 -DESP32_32M -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DUSE_USB_CDC_CONSOLE"
|
||||
],
|
||||
"f_cpu": "360000000L",
|
||||
"f_flash": "80000000L",
|
||||
"f_psram": "200000000L",
|
||||
"flash_mode": "qio",
|
||||
"mcu": "esp32p4",
|
||||
"chip_variant": "esp32p4_es",
|
||||
"variant": "esp32p4",
|
||||
"partitions": "boards/partitions/esp32_partition_app6144k_spiffs20412k.csv"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"openthread",
|
||||
"ethernet"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_target": "esp32p4.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "Espressif ESP32-P4 Function EV Board 32M Flash, ESPEasy 6144k Code/OTA 20M FS",
|
||||
"upload": {
|
||||
"flash_size": "32MB",
|
||||
"maximum_ram_size": 768000,
|
||||
"maximum_size": 33554432,
|
||||
"require_upload_port": true,
|
||||
"speed": 1500000
|
||||
},
|
||||
"url": "https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/index.html",
|
||||
"vendor": "Espressif"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DARDUINO_TASMOTA -DESP32P4R3 -DESP32_32M -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DUSE_USB_CDC_CONSOLE"
|
||||
],
|
||||
"f_cpu": "400000000L",
|
||||
"f_flash": "80000000L",
|
||||
"f_psram": "200000000L",
|
||||
"flash_mode": "qio",
|
||||
"mcu": "esp32p4",
|
||||
"chip_variant": "esp32p4",
|
||||
"variant": "esp32p4",
|
||||
"partitions": "boards/partitions/esp32_partition_app6144k_spiffs20412k.csv"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"openthread",
|
||||
"ethernet"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_target": "esp32p4.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "Espressif Generic ESP32-P4 rev.3 32M Flash, ESPEasy 6144k Code/OTA 20M FS",
|
||||
"upload": {
|
||||
"flash_size": "32MB",
|
||||
"maximum_ram_size": 768000,
|
||||
"maximum_size": 33554432,
|
||||
"require_upload_port": true,
|
||||
"speed": 1500000
|
||||
},
|
||||
"url": "https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4x-function-ev-board/index.html",
|
||||
"vendor": "Espressif"
|
||||
}
|
||||
@@ -34,6 +34,6 @@
|
||||
"require_upload_port": true,
|
||||
"speed": 1500000
|
||||
},
|
||||
"url": "https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/index.html",
|
||||
"url": "https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4x-function-ev-board/index.html",
|
||||
"vendor": "Espressif"
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino":{
|
||||
"ldscript": "esp32s2_out.ld",
|
||||
"memory_type": "dio_qspi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": "-DARDUINO_TASMOTA -DBOARD_HAS_PSRAM -DESP32_8M -DESP32S2 -DCONFIG_IDF_TARGET_ESP32S2=1 -DUSE_USB_CDC_CONSOLE -DARDUINO_USB_CDC_ON_BOOT=1 -DCONFIG_TINYUSB_CDC_ENABLED=1",
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32s2",
|
||||
"variant": "esp32s2",
|
||||
"filesystem": "littlefs",
|
||||
"partitions": "boards/partitions/esp32_partition_app3520k_spiffs1088k.csv"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s2.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"espidf",
|
||||
"arduino"
|
||||
],
|
||||
"name": "Espressif Generic ESP32-S2 USB CDC 8M Flash ESPEasy 3520k Code/OTA 1088k FS",
|
||||
"upload": {
|
||||
"flash_size": "8MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"before_reset": "usb_reset",
|
||||
"after_reset": "hard_reset",
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html",
|
||||
"vendor": "Espressif"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x5000,
|
||||
otadata, data, ota, 0xe000, 0x2000,
|
||||
app0, app, ota_0, 0x10000, 0x600000,
|
||||
app1, app, ota_1, 0x610000,0x600000,
|
||||
eeprom, data, 0x99, 0xC10000,0x1000,
|
||||
spiffs, data, spiffs, 0xC11000,0x13EF000,
|
||||
|
Vendored
+2
-2
@@ -66,10 +66,10 @@ ESP32 now has a number of builds:
|
||||
- custom_ESP32_4M316k Build template using either the plugin set defined in ``Custom.h`` or ``tools/pio/pre_custom_esp32.py``
|
||||
- test_ESP32_4M316k Build using the "testing" set of plugins for ESP32
|
||||
- test_ESP32-wrover-kit_4M316k A build for ESP32 including build flags for the official WRover test kit.
|
||||
- max_ESP32_16M1M A build for ESP32 with larger flash size including all plugins.
|
||||
- max_ESP32_16M8M A build for ESP32 with larger flash size including all plugins.
|
||||
|
||||
ESP32 also supports Ethernet.
|
||||
Ethernet support is included in similar builds as mentioned before, only ending with "_ETH" in the file name.
|
||||
Ethernet support is included in nearly all ESP32 builds, only ESP32-C2 doesn't have support for Ethernet.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,9 +10,14 @@ ESPEasy Project Directories
|
||||
|
||||
Below a list of the most important directories and files used in this project.
|
||||
|
||||
* ``.pio/`` Working dir for PlatformIO (Ignored by Git)
|
||||
* ``build_output/`` The output directory where all built files are collected.
|
||||
* ``dist/`` Files also includd in the nightly builds (e.g. blank flash files and ESPEasy flasher)
|
||||
* ``.github/`` Buildscripts used by the Github Actions build and release CI jobs.
|
||||
* ``.pio/`` Working dir for pioarduino (Ignored by Git)
|
||||
* ``.platformio/`` Working dir for pioarduino (Ignored by Git)
|
||||
* ``.platformio/penv/`` Directory to store the used Python Virtual Environment.
|
||||
* ``boards/`` Used board definitions.
|
||||
* ``boards/partitions/`` Used partition layout in ESP32 builds.
|
||||
* ``build_output/`` The output directory where all built files are collected. (Ignored by Git)
|
||||
* ``dist/`` Files also includd in the nightly builds (e.g. blank flash files and Espressif flash download tool)
|
||||
* ``docs/`` Documentation tree using Sphinx to build the documents.
|
||||
* ``hooks/`` Used for the continous integration process, used by Travis CI.
|
||||
* ``include/`` PlatformIO's suggested folder for .h files (not yet used)
|
||||
@@ -20,16 +25,14 @@ Below a list of the most important directories and files used in this project.
|
||||
* ``misc/`` Additional files needed for some use cases, like specialized a firmware for some boards or decoder files for the TTN project.
|
||||
* ``patches/`` Patches we apply during build for core libraries.
|
||||
* ``src/`` The source code of ESPeasy
|
||||
* ``src/ESPEasy/`` Parts of ESPeasy use C++ namespaces, and are placed in this directory, matching the namespace structure.
|
||||
* ``static/`` Static files we use in ESPEasy, like CSS/JS/ICO files.
|
||||
* ``test/`` Test scripts to be used in the continous integration process.
|
||||
* ``tools/`` Tools to help build ESPeasy.
|
||||
* ``tools/pio/pre_custom_esp32.py`` Python helper script for building custom ESP32 binary.
|
||||
* ``tools/pio/pre_custom_esp8266.py`` Python helper script for building custom ESP8266 binary.
|
||||
* ``venv/`` Directory to store the used Python Virtual Environment. (Ignored by Git)
|
||||
* ``platformio.ini`` Configuration file for PlatformIO to define various build setups.
|
||||
* ``uncrustify.cfg`` Configuration file for Uncrustify, to format source code using some uniform formatting rules.
|
||||
* ``tools/pio/pre_custom_esp*.py`` Python helper scripts for building custom ESP binaries.
|
||||
* ``platformio.ini`` Configuration file for pioarduino to define various build setups.
|
||||
* ``requirements.txt`` List of used Python libraries and their version (result of ``pip freeze`` with Virtual env active)
|
||||
* ``boards/partitions/esp32_partition_app1810k_spiffs316k.csv`` Used partition layout in ESP32 4M builds.
|
||||
* ``uncrustify.cfg`` Configuration file for Uncrustify, to format source code using some uniform formatting rules.
|
||||
|
||||
|
||||
ESPEasy src dir
|
||||
@@ -107,14 +110,17 @@ There is also a number of special builds:
|
||||
ESP Chip Type
|
||||
-------------
|
||||
|
||||
* ``ESP8266`` Most likely option.
|
||||
* ``ESP8266`` Deprecated for new projects, as support from Espressif has been stopped, even though new chips are still being produced.
|
||||
* ``ESP8285`` Supported in ``ESP8266`` builds. Used in some Sonoff modules. This chip has embedded flash, so no extra flash chip.
|
||||
* ``ESP32`` Allows for more memory and more GPIO pins.
|
||||
* ``ESP32-S2`` Newer version of ESP32. Has even more GPIO pins, but some specific features of ESP32 were removed.
|
||||
* ``ESP32-S3`` Newer version of ESP32 and ESP32-S2. Has even more GPIO pins, some specific features of ESP32 were removed, and some design choices of ESP32-S2 are reverted and implemented differently.
|
||||
* ``ESP32-C2`` Preliminary supported. Cheaper variant of ESP32-C3, and also an ESP8266 replacement. Available as pin-compatible module for ESP8266. Single core, and max 120 MHz clock speed.
|
||||
* ``ESP32-C2`` Cheaper variant of ESP32-C3, and also an ESP8266 replacement. Available as pin-compatible module for ESP8266. Single core, and max 120 MHz clock speed.
|
||||
* ``ESP32-C3`` Intended as a replacement for ESP8266, using ESP32 technology, though single-core and with limited clock speed (160 MHz, some models 120 MHz).
|
||||
* ``ESP32-C6`` Preliminary supported. Will allow connectivity with IEEE 802.15.4 (Thread/Zigbee) wireless protocol.
|
||||
* ``ESP32-C6`` Will allow connectivity with IEEE 802.15.4 (Thread/Zigbee) wireless protocol.
|
||||
* ``ESP32-C61`` Preliminary supported. Will allow connectivity with IEEE 802.15.4 (Thread/Zigbee) wireless protocol.
|
||||
* ``ESP32-C5`` Will allow connectivity with WiFi 2.4GHz and 5GHz support.
|
||||
* ``ESP32-P4`` High-end dual-core MCU, with many GPIO pins and support for camera, display, RMII Ethernet and many other protocols. No on-chip WiFi support. Often has an additional ESP32-C6 with ESP-HostedMCU to provide wireless support via an SDIO connection.
|
||||
|
||||
Memory Size and Partitioning
|
||||
----------------------------
|
||||
@@ -123,12 +129,12 @@ Memory Size and Partitioning
|
||||
* ``2M`` 2 MB flash modules (e.g. Shelly1/WROOM02)
|
||||
* ``4M`` 4 MB flash modules (e.g. NodeMCU/ESP32)
|
||||
* ``16M`` 16 MB flash modules (e.g. Wemos D1 mini pro) (has 14 MB LittleFS filesystem, as SPIFFS is unstable > 2 MB)
|
||||
* ``4M1M`` 4 MB flash modules with 1 MB filesystem (usually SPIFFS)
|
||||
* ``4M2M`` 4 MB flash modules with 2 MB filesystem (usually SPIFFS)
|
||||
* ``4M316k`` 4 MB flash modules using 1.8 MB sketch size, with 316 kB filesystem (usually SPIFFS) (for ESP32)
|
||||
* ``8M1M`` 8 MB flash modules using 3.5MB sketch size, with 1 MB filesystem (LittleFS) (ESP32 only a.t.m.)
|
||||
* ``16M1M`` 16 MB flash modules using 4MB sketch size, with 1 MB filesystem (usually SPIFFS) (ESP32 only a.t.m.)
|
||||
* ``16M8M`` 16 MB flash modules using 4MB sketch size, with 8 MB filesystem (LittleFS) (ESP32 only a.t.m.)
|
||||
* ``4M1M`` 4 MB flash modules with 1 MB filesystem (SPIFFS)
|
||||
* ``4M2M`` 4 MB flash modules with 2 MB filesystem (SPIFFS)
|
||||
* ``4M316k`` 4 MB flash modules using 1.8 MB sketch size, with 316 kB filesystem (LittleFS) (for ESP32)
|
||||
* ``8M1M`` 8 MB flash modules using 3.5MB sketch size, with 1 MB filesystem (LittleFS) (ESP32 only)
|
||||
* ``16M8M`` 16 MB flash modules using 4MB sketch size, with 8 MB filesystem (LittleFS) (ESP32 only)
|
||||
* ``32M20M`` 32 MB flash modules using 6MB sketch size, with 20 MB filesystem (LittleFS) (ESP32 only)
|
||||
|
||||
Optional build options
|
||||
----------------------
|
||||
@@ -143,7 +149,7 @@ Optional build options
|
||||
* ``OPI`` Flash via OPI protocol support (ESP32 only)
|
||||
* ``QIO`` Flash via QIO protocol support (ESP32 only)
|
||||
* ``CDC`` CDC Serial (built-in USB) support (ESP32 only)
|
||||
* ``ETH`` Ethernet interface enabled (ESP32 only)
|
||||
* ``ETH`` Ethernet interface enabled (ESP32 only, no longer used, as all ESP32, except for ESP32-C2, have support for Ethernet included)
|
||||
|
||||
|
||||
Please note that the performance of 14MB SPIFFS (16M flash ESP8266 modules) is really slow.
|
||||
@@ -183,17 +189,15 @@ This also means we still need to update the 2-step updater to support .bin.gz fi
|
||||
ESP32 builds
|
||||
------------
|
||||
|
||||
There are several builds for ESP32:
|
||||
There are several builds for ESP32, this is just a selection:
|
||||
|
||||
* ``normal_ESP32_4M316k`` Build using the "stable" set of plugins for ESP32
|
||||
* ``normal_ESP32_4M316k_ETH`` Build using the "stable" set of plugins for ESP32, with support for an on-board Ethernet controller
|
||||
* ``normal_ESP32_4M316k`` Build using the "stable" set of plugins for ESP32, with support for an on-board Ethernet controller
|
||||
* ``custom_ESP32_4M316k`` Build template using either the plugin set defined in ``Custom.h`` or ``tools/pio/pre_custom_esp32.py``
|
||||
* ``collection_A_ESP32_4M316k`` Build using the "Collection" set "A" of plugins for ESP32
|
||||
* ``collection_B_ESP32_4M316k`` Build using the "Collection" set "B" of plugins for ESP32
|
||||
* ``collection_C_ESP32_4M316k`` Build using the "Collection" set "C" of plugins for ESP32
|
||||
* ``collection_D_ESP32_4M316k`` Build using the "Collection" set "D" of plugins for ESP32
|
||||
* ``collection_A_ESP32-wrover-kit_4M316k`` A build for ESP32 including build flags for the official WRover test kit.
|
||||
* ``max_ESP32_16M8M_LittleFS`` Build using all available plugins and controllers for ESP32 with 16 MB flash (some lolin_d32_pro boards)
|
||||
* ``max_ESP32_16M8M`` Build using all available plugins and controllers for ESP32 with 16 MB flash (like lolin_d32_pro boards)
|
||||
|
||||
Since ESP32 does have its flash partitioned in several blocks, we have 2 bin files of each ESP32 build, f.e.:
|
||||
|
||||
|
||||
@@ -10,7 +10,12 @@
|
||||
|
||||
Port_ESPEasySerial_HardwareSerial_t::Port_ESPEasySerial_HardwareSerial_t() {}
|
||||
|
||||
Port_ESPEasySerial_HardwareSerial_t::~Port_ESPEasySerial_HardwareSerial_t() {}
|
||||
Port_ESPEasySerial_HardwareSerial_t::~Port_ESPEasySerial_HardwareSerial_t() {
|
||||
if (_serial != nullptr) {
|
||||
_serial->flush();
|
||||
_serial->end();
|
||||
}
|
||||
}
|
||||
|
||||
void Port_ESPEasySerial_HardwareSerial_t::resetConfig(const ESPEasySerialConfig& config)
|
||||
{
|
||||
@@ -153,7 +158,7 @@ void Port_ESPEasySerial_HardwareSerial_t::begin(unsigned long baud)
|
||||
}
|
||||
|
||||
if (_config.txBuffSize > 256) {
|
||||
_config.txBuffSize = _serial->setRxBufferSize(_config.txBuffSize);
|
||||
_config.txBuffSize = _serial->setTxBufferSize(_config.txBuffSize);
|
||||
}
|
||||
|
||||
_serial->begin(baud, _config.config, _config.receivePin, _config.transmitPin, _config.inverse_logic);
|
||||
|
||||
@@ -128,6 +128,7 @@ Port_ESPEasySerial_USBCDC_t::Port_ESPEasySerial_USBCDC_t(const ESPEasySerialConf
|
||||
Port_ESPEasySerial_USBCDC_t::~Port_ESPEasySerial_USBCDC_t()
|
||||
{
|
||||
if (_serial != nullptr) {
|
||||
_serial->flush();
|
||||
_serial->end();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,10 +31,11 @@ void DIRECT_pinWrite(IO_REG_TYPE pin, bool pinstate)
|
||||
digitalWrite(pin, pinstate);
|
||||
return;
|
||||
}
|
||||
# endif // ifdef ARDUINO_ARCH_ESP8266
|
||||
|
||||
if (pinstate) { DIRECT_WRITE_HIGH(reg, PIN_TO_BITMASK(pin)); }
|
||||
else { DIRECT_WRITE_LOW(reg, PIN_TO_BITMASK(pin)); }
|
||||
#else
|
||||
directWrite(pin, pinstate ? 1u : 0u);
|
||||
# endif // ifdef ARDUINO_ARCH_ESP8266
|
||||
}
|
||||
|
||||
void DIRECT_PINMODE_OUTPUT(IO_REG_TYPE pin)
|
||||
|
||||
@@ -134,147 +134,52 @@ void DIRECT_PINMODE_INPUT_ISR(IO_REG_TYPE pin);
|
||||
int32_t DIRECT_measureWaitForPinState_ISR(IO_REG_TYPE gpio_pin_rx, uint32_t start_usec, int32_t timeout_usec, bool newState);
|
||||
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
#if ESP_IDF_VERSION_MAJOR < 5
|
||||
#include <esp32-hal-gpio.h>
|
||||
#include <driver/rtc_io.h>
|
||||
#else
|
||||
#include <soc/gpio_struct.h>
|
||||
#include <driver/rtc_io.h>
|
||||
#include <esp_idf_version.h>
|
||||
#include <soc/soc_caps.h>
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
|
||||
#include <driver/gpio.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <hal/gpio_ll.h>
|
||||
#define PIN_TO_BASEREG(pin) (0)
|
||||
#define PIN_TO_BITMASK(pin) (pin)
|
||||
#define IO_REG_TYPE uint32_t
|
||||
#define IO_REG_BASE_ATTR
|
||||
#define IO_REG_MASK_ATTR
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
IO_REG_TYPE directRead(IO_REG_TYPE pin)
|
||||
__attribute__((always_inline))
|
||||
static inline IO_REG_TYPE directRead(IO_REG_TYPE pin)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5
|
||||
return (GPIO.in.val >> pin) & 0x1;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61 || CONFIG_IDF_TARGET_ESP32P4
|
||||
if ( pin < 32 )
|
||||
return (GPIO.in.val >> pin) & 0x1;
|
||||
else if ( pin < SOC_GPIO_PIN_COUNT )
|
||||
return (GPIO.in1.val >> (pin - 32)) & 0x1;
|
||||
#else // plain ESP32
|
||||
if ( pin < 32 )
|
||||
return (GPIO.in >> pin) & 0x1;
|
||||
else if ( pin < SOC_GPIO_PIN_COUNT )
|
||||
return (GPIO.in1.val >> (pin - 32)) & 0x1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return gpio_ll_get_level(&GPIO, pin);
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
void directWriteLow(IO_REG_TYPE pin)
|
||||
__attribute__((always_inline))
|
||||
static inline void directWrite(IO_REG_TYPE pin, IO_REG_TYPE level)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5
|
||||
GPIO.out_w1tc.val = ((uint32_t)1 << pin);
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61 || CONFIG_IDF_TARGET_ESP32P4
|
||||
if ( pin < 32 )
|
||||
GPIO.out_w1tc.val = ((uint32_t)1 << pin);
|
||||
else if ( pin < SOC_GPIO_PIN_COUNT )
|
||||
GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
|
||||
|
||||
#else // plain ESP32
|
||||
if ( pin < 32 )
|
||||
GPIO.out_w1tc = ((uint32_t)1 << pin);
|
||||
else if ( pin < SOC_GPIO_PIN_COUNT )
|
||||
GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
|
||||
#endif
|
||||
gpio_ll_set_level(&GPIO, pin, level);
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
void directWriteHigh(IO_REG_TYPE pin)
|
||||
__attribute__((always_inline))
|
||||
static inline void directWriteLow(IO_REG_TYPE pin)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5
|
||||
GPIO.out_w1ts.val = ((uint32_t)1 << pin);
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61 || CONFIG_IDF_TARGET_ESP32P4
|
||||
if ( pin < 32 )
|
||||
GPIO.out_w1ts.val = ((uint32_t)1 << pin);
|
||||
else if ( pin < SOC_GPIO_PIN_COUNT )
|
||||
GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
|
||||
|
||||
#else // plain ESP32
|
||||
if ( pin < 32 )
|
||||
GPIO.out_w1ts = ((uint32_t)1 << pin);
|
||||
else if ( pin < SOC_GPIO_PIN_COUNT )
|
||||
GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
|
||||
#endif
|
||||
gpio_ll_set_level(&GPIO, pin, 0u);
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
void directModeInput(IO_REG_TYPE pin)
|
||||
__attribute__((always_inline))
|
||||
static inline void directWriteHigh(IO_REG_TYPE pin)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5
|
||||
GPIO.enable_w1tc.val = ((uint32_t)1 << (pin));
|
||||
#else
|
||||
if ( GPIO_IS_VALID_GPIO(pin) )
|
||||
{
|
||||
#if ESP_IDF_VERSION_MAJOR < 4 // IDF 3.x ESP32/PICO-D4
|
||||
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
|
||||
|
||||
if ( rtc_reg ) // RTC pins PULL settings
|
||||
{
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
|
||||
}
|
||||
#endif
|
||||
// Input
|
||||
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61 || CONFIG_IDF_TARGET_ESP32P4
|
||||
if ( pin < 32 )
|
||||
GPIO.enable_w1tc.val = ((uint32_t)1 << pin);
|
||||
else
|
||||
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
|
||||
#else
|
||||
if ( pin < 32 )
|
||||
GPIO.enable_w1tc = ((uint32_t)1 << pin);
|
||||
else
|
||||
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
gpio_ll_set_level(&GPIO, pin, 1u);
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
void directModeOutput(IO_REG_TYPE pin)
|
||||
__attribute__((always_inline))
|
||||
static inline void directModeInput(IO_REG_TYPE pin)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5
|
||||
GPIO.enable_w1ts.val = ((uint32_t)1 << (pin));
|
||||
#else
|
||||
if ( GPIO_IS_VALID_GPIO(pin) && pin <= 33 ) // pins above 33 can be only inputs
|
||||
{
|
||||
#if ESP_IDF_VERSION_MAJOR < 4 // IDF 3.x ESP32/PICO-D4
|
||||
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
|
||||
gpio_ll_output_disable(&GPIO, pin);
|
||||
}
|
||||
|
||||
if ( rtc_reg ) // RTC pins PULL settings
|
||||
{
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
|
||||
}
|
||||
#endif
|
||||
// Output
|
||||
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61 || CONFIG_IDF_TARGET_ESP32P4
|
||||
if ( pin < 32 )
|
||||
GPIO.enable_w1ts.val = ((uint32_t)1 << pin);
|
||||
else // already validated to pins <= 33
|
||||
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
|
||||
|
||||
#else
|
||||
if ( pin < 32 )
|
||||
GPIO.enable_w1ts = ((uint32_t)1 << pin);
|
||||
else // already validated to pins <= 33
|
||||
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
__attribute__((always_inline))
|
||||
static inline void directModeOutput(IO_REG_TYPE pin)
|
||||
{
|
||||
gpio_ll_output_enable(&GPIO, pin);
|
||||
}
|
||||
|
||||
#define DIRECT_READ(base, pin) directRead(pin)
|
||||
|
||||
@@ -187,8 +187,11 @@ extra_scripts = ${esp82xx_common.extra_scripts}
|
||||
;platform = https://github.com/Jason2866/platform-espressif32.git#IDF6
|
||||
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2403-0020-6.0/framework-arduinoespressif32-release_v6.0-1a97ddaa.tar.xz
|
||||
|
||||
platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152
|
||||
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1204-1214-5.5/framework-arduinoespressif32-release_v5.5-f2a3fa2b.tar.xz
|
||||
;platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152
|
||||
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2904-2115-5.5/framework-arduinoespressif32-release_v5.5-f2a3fa2b.tar.xz
|
||||
|
||||
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.04.50/platform-espressif32.zip
|
||||
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/0405-1702-5.5/framework-arduinoespressif32-release_v5.5-f2a3fa2b.tar.xz
|
||||
|
||||
custom_remove_include = true
|
||||
|
||||
|
||||
@@ -14,6 +14,15 @@ lib_ignore = ${esp32_base_idf5_5.lib_ignore}
|
||||
board = esp32c5cdc
|
||||
|
||||
|
||||
[env:custom_ESP32c5_4M316k]
|
||||
extends = esp32c5_common_LittleFS
|
||||
build_flags = ${esp32c5_common_LittleFS.build_flags}
|
||||
-DPLUGIN_BUILD_CUSTOM
|
||||
extra_scripts = ${esp32c5_common_LittleFS.extra_scripts}
|
||||
pre:tools/pio/pre_custom_esp32.py
|
||||
|
||||
|
||||
|
||||
[env:max_ESP32c5_8M1M]
|
||||
extends = esp32c5_common_LittleFS
|
||||
board = esp32c5cdc-8M
|
||||
@@ -26,4 +35,22 @@ build_flags = ${esp32c5_common_LittleFS.build_flags}
|
||||
-D P116_EXTRA_ST7789=1
|
||||
extra_scripts = ${esp32c5_common_LittleFS.extra_scripts}
|
||||
|
||||
[env:max_ESP32c5_16M8M]
|
||||
extends = esp32c5_common_LittleFS
|
||||
board = esp32c5cdc-16M
|
||||
build_flags = ${esp32c5_common_LittleFS.build_flags}
|
||||
-DFEATURE_ETHERNET=1
|
||||
-DFEATURE_ARDUINO_OTA=1
|
||||
-DPLUGIN_BUILD_MAX_ESP32
|
||||
-DPLUGIN_BUILD_IR_EXTENDED
|
||||
-D ST7789_EXTRA_INIT=1
|
||||
-D P116_EXTRA_ST7789=1
|
||||
extra_scripts = ${esp32c5_common_LittleFS.extra_scripts}
|
||||
|
||||
[env:max32_ESP32c5_32M20M]
|
||||
extends = env:max_ESP32c5_16M8M
|
||||
board = esp32c5cdc-32M
|
||||
build_flags = ${env:max_ESP32c5_16M8M.build_flags}
|
||||
-DPLUGIN_BUILD_MAX32_ESP32
|
||||
|
||||
|
||||
|
||||
@@ -27,4 +27,10 @@ build_flags = ${esp32p4_common_LittleFS.build_flags}
|
||||
-D P116_EXTRA_ST7789=1
|
||||
extra_scripts = ${esp32p4_common_LittleFS.extra_scripts}
|
||||
|
||||
[env:max32_ESP32p4_32M20M]
|
||||
extends = env:max_ESP32p4_16M8M
|
||||
board = esp32p4_ev-32M
|
||||
build_flags = ${env:max_ESP32p4_16M8M.build_flags}
|
||||
-DPLUGIN_BUILD_MAX32_ESP32
|
||||
|
||||
|
||||
|
||||
@@ -11,4 +11,10 @@ board = esp32p4r3
|
||||
extends = env:max_ESP32p4_16M8M
|
||||
board = esp32p4r3
|
||||
|
||||
[env:max32_ESP32p4r3_32M20M]
|
||||
extends = env:max_ESP32p4_16M8M
|
||||
board = esp32p4r3-32M
|
||||
build_flags = ${env:max_ESP32p4r3_16M8M.build_flags}
|
||||
-DPLUGIN_BUILD_MAX32_ESP32
|
||||
|
||||
|
||||
|
||||
@@ -148,3 +148,14 @@ board = esp32s2cdc
|
||||
build_flags = ${esp32s2_common_LittleFS.build_flags}
|
||||
-D PLUGIN_CLIMATE_B_COLLECTION
|
||||
|
||||
|
||||
[env:max_ESP32s2_8M1M]
|
||||
extends = esp32s2_common_LittleFS
|
||||
board = esp32s2cdc_8M
|
||||
build_flags = ${esp32s2_common_LittleFS.build_flags}
|
||||
-DFEATURE_ARDUINO_OTA=1
|
||||
-DPLUGIN_BUILD_MAX_ESP32
|
||||
-DPLUGIN_BUILD_IR_EXTENDED
|
||||
-D ST7789_EXTRA_INIT=1
|
||||
-D P116_EXTRA_ST7789=1
|
||||
extra_scripts = ${esp32s2_common_LittleFS.extra_scripts}
|
||||
|
||||
+20
-20
@@ -328,26 +328,26 @@ lib_ignore = ${normal_beta_2ndheap.lib_ignore}
|
||||
|
||||
; NORMAL: 16M version --- LittleFS --------------
|
||||
; LittleFS is determined by using "LittleFS" in the pio env name
|
||||
[env:normal_beta_ESP8266_16M_LittleFS]
|
||||
extends = esp8266_16M
|
||||
platform = ${normal_beta.platform}
|
||||
platform_packages = ${normal_beta.platform_packages}
|
||||
build_flags = ${normal_beta.build_flags}
|
||||
${esp8266_16M.build_flags}
|
||||
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22y
|
||||
lib_ignore = ESP32_ping
|
||||
ESP32WebServer
|
||||
ESP32HTTPUpdateServer
|
||||
ServoESP32
|
||||
${no_ir.lib_ignore}
|
||||
TinyWireM
|
||||
ESP8266SdFat
|
||||
SD(esp8266)
|
||||
SD
|
||||
SDFS
|
||||
ArduinoOTA
|
||||
ESP8266mDNS
|
||||
I2C AXP192 Power management
|
||||
;[env:normal_beta_ESP8266_16M_LittleFS]
|
||||
;extends = esp8266_16M
|
||||
;platform = ${normal_beta.platform}
|
||||
;platform_packages = ${normal_beta.platform_packages}
|
||||
;build_flags = ${normal_beta.build_flags}
|
||||
; ${esp8266_16M.build_flags}
|
||||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22y
|
||||
;lib_ignore = ESP32_ping
|
||||
; ESP32WebServer
|
||||
; ESP32HTTPUpdateServer
|
||||
; ServoESP32
|
||||
; ${no_ir.lib_ignore}
|
||||
; TinyWireM
|
||||
; ESP8266SdFat
|
||||
; SD(esp8266)
|
||||
; SD
|
||||
; SDFS
|
||||
; ArduinoOTA
|
||||
; ESP8266mDNS
|
||||
; I2C AXP192 Power management
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "../../../src/DataStructs/ESPEasy_EventStruct.h"
|
||||
#include "../../../src/Helpers/StringConverter.h"
|
||||
#include "../../../src/Helpers/Misc.h"
|
||||
#include "../../../src/Helpers/Networking.h"
|
||||
#if FEATURE_STORE_NETWORK_INTERFACE_SETTINGS
|
||||
# include "../../../src/Helpers/_ESPEasy_key_value_store.h"
|
||||
#include "../_NWPlugin_Helper.h"
|
||||
@@ -65,6 +67,15 @@ bool NWPluginData_base::isDefaultRoute() const {
|
||||
|
||||
#endif
|
||||
|
||||
bool NWPluginData_base::getStaticIPAddresses(IPAddress & ip, IPAddress & gateway, IPAddress & subnetmask, IPAddress & dns ) const
|
||||
{
|
||||
getStaticIPAddress(IPAddressType::IP, ip);
|
||||
getStaticIPAddress(IPAddressType::Gateway, gateway);
|
||||
getStaticIPAddress(IPAddressType::Subnetmask, subnetmask);
|
||||
getStaticIPAddress(IPAddressType::DNS, dns);
|
||||
|
||||
return IPAddressSet(ip) && IPAddressSet(gateway) && IPAddressSet(subnetmask);
|
||||
}
|
||||
|
||||
bool NWPluginData_base::hasPluginStats() const {
|
||||
#if FEATURE_NETWORK_STATS
|
||||
@@ -333,7 +344,7 @@ bool NWPluginData_base::handle_priority_route_changed()
|
||||
for (size_t i = 0; i < NR_ELEMENTS(cache->_dns_cache); ++i) {
|
||||
auto tmp = _netif->dnsIP(i);
|
||||
|
||||
if ((cache->_dns_cache[i] != INADDR_NONE) && (cache->_dns_cache[i] != tmp)) {
|
||||
if (valid_DNS_address(cache->_dns_cache[i]) && (cache->_dns_cache[i] != tmp)) {
|
||||
addLog(LOG_LEVEL_INFO, strformat(
|
||||
F("%s: Restore cached DNS server %d from %s to %s"),
|
||||
_netif->desc(),
|
||||
@@ -409,7 +420,7 @@ bool NWPluginData_base::_restore_DNS_cache()
|
||||
for (size_t i = 0; i < NR_ELEMENTS(cache->_dns_cache); ++i) {
|
||||
auto tmp = _netif->dnsIP(i);
|
||||
|
||||
if ((cache->_dns_cache[i] != INADDR_NONE) && (cache->_dns_cache[i] != tmp)) {
|
||||
if (valid_DNS_address(cache->_dns_cache[i]) && (cache->_dns_cache[i] != tmp)) {
|
||||
addLog(LOG_LEVEL_INFO, strformat(
|
||||
F("NW%03%d: Restore cached DNS server %d from %s to %s"),
|
||||
_nw_data_pluginID,
|
||||
|
||||
@@ -33,6 +33,13 @@ struct NWPluginData_base {
|
||||
#endif // ifdef ESP32
|
||||
);
|
||||
|
||||
enum class IPAddressType {
|
||||
IP,
|
||||
Gateway,
|
||||
Subnetmask,
|
||||
DNS
|
||||
};
|
||||
|
||||
virtual ~NWPluginData_base();
|
||||
|
||||
virtual bool init(EventStruct *event) = 0;
|
||||
@@ -110,6 +117,10 @@ struct NWPluginData_base {
|
||||
|
||||
virtual NWPluginData_static_runtime* getNWPluginData_static_runtime() = 0;
|
||||
|
||||
virtual bool getStaticIPAddress(IPAddressType addressType, IPAddress & ip) const = 0;
|
||||
|
||||
bool getStaticIPAddresses(IPAddress & ip, IPAddress & gateway, IPAddress & subnetmask, IPAddress & dns ) const;
|
||||
|
||||
|
||||
#if FEATURE_NETWORK_STATS
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "../../../src/Globals/EventQueue.h"
|
||||
#include "../../../src/Globals/Settings.h"
|
||||
|
||||
#include "../../../src/Helpers/Networking.h"
|
||||
#include "../../../src/Helpers/NetworkStatusLED.h"
|
||||
#include "../../../src/Helpers/StringConverter.h"
|
||||
|
||||
@@ -98,12 +99,12 @@ bool NWPluginData_static_runtime::getTrafficCount(TX_RX_traffic_count& traffic)
|
||||
|
||||
void NWPluginData_static_runtime::clear(networkIndex_t networkIndex)
|
||||
{
|
||||
_connectedStats.clear();
|
||||
_gotIPStats.clear();
|
||||
_connectedStats.reset();
|
||||
_gotIPStats.reset();
|
||||
#if FEATURE_USE_IPV6
|
||||
_gotIP6Stats.clear();
|
||||
_gotIP6Stats.reset();
|
||||
#endif
|
||||
_operationalStats.clear();
|
||||
_operationalStats.reset();
|
||||
#if FEATURE_NETWORK_TRAFFIC_COUNT
|
||||
|
||||
if (_netif) {
|
||||
@@ -125,7 +126,7 @@ void NWPluginData_static_runtime::clear(networkIndex_t networkIndex)
|
||||
|
||||
_connectionFailures = 0;
|
||||
|
||||
// FIXME TD-er: Should also clear dns cache?
|
||||
// FIXME TD-er: Should also clear dns cache and/or static IP?
|
||||
}
|
||||
|
||||
void NWPluginData_static_runtime::processEvent_and_clear()
|
||||
@@ -171,7 +172,7 @@ void NWPluginData_static_runtime::processEvents()
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO) && _netif) {
|
||||
auto ip = _netif->localIP();
|
||||
|
||||
if (ip != INADDR_NONE) {
|
||||
if (IPAddressSet(ip)) {
|
||||
addLog(LOG_LEVEL_INFO, strformat(
|
||||
F("%s: Got IP: %s/%d GW: %s"),
|
||||
_eventInterfaceName.c_str(),
|
||||
@@ -267,17 +268,17 @@ void NWPluginData_static_runtime::processEvents()
|
||||
{
|
||||
if (_operationalStats.isOn()) {
|
||||
if (_isAP) {
|
||||
eventQueue.add(F("WiFi#APmodeConnected"));
|
||||
eventQueue.addDeDup(F("WiFi#APmodeConnected"));
|
||||
}
|
||||
else {
|
||||
eventQueue.add(concat(_eventInterfaceName, F("#Connected")));
|
||||
eventQueue.addDeDup(concat(_eventInterfaceName, F("#Connected")));
|
||||
}
|
||||
} else if (_operationalStats.isOff()) {
|
||||
if (_isAP) {
|
||||
eventQueue.add(F("WiFi#APmodeDisconnected"));
|
||||
eventQueue.addDeDup(F("WiFi#APmodeDisconnected"));
|
||||
}
|
||||
else {
|
||||
eventQueue.add(concat(_eventInterfaceName, F("#Disconnected")));
|
||||
eventQueue.addDeDup(concat(_eventInterfaceName, F("#Disconnected")));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,22 +288,31 @@ void NWPluginData_static_runtime::processEvents()
|
||||
if (_startStopStats.changedSinceLastCheck_and_clear() && Settings.UseRules) {
|
||||
if (_startStopStats.isOn()) {
|
||||
if (_isAP) {
|
||||
eventQueue.add(F("WiFi#APmodeEnabled"));
|
||||
eventQueue.addDeDup(F("WiFi#APmodeEnabled"));
|
||||
}
|
||||
else {
|
||||
eventQueue.add(concat(_eventInterfaceName, F("#Enabled")));
|
||||
eventQueue.addDeDup(concat(_eventInterfaceName, F("#Enabled")));
|
||||
}
|
||||
} else if (_startStopStats.isOff()) {
|
||||
if (_isAP) {
|
||||
eventQueue.add(F("WiFi#APmodeDisabled"));
|
||||
eventQueue.addDeDup(F("WiFi#APmodeDisabled"));
|
||||
}
|
||||
else {
|
||||
eventQueue.add(concat(_eventInterfaceName, F("#Disabled")));
|
||||
eventQueue.addDeDup(concat(_eventInterfaceName, F("#Disabled")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NWPluginData_static_runtime::setStaticIP(const IPAddress & ip, const IPAddress & gateway, const IPAddress & subnetmask, const IPAddress & dns)
|
||||
{
|
||||
_useStaticIP = IPAddressSet(ip) && IPAddressSet(gateway) && IPAddressSet(subnetmask);
|
||||
_ip = ip;
|
||||
_gateway = gateway;
|
||||
_sn = subnetmask;
|
||||
_dns = dns;
|
||||
}
|
||||
|
||||
String NWPluginData_static_runtime::statusToString() const
|
||||
{
|
||||
String log;
|
||||
@@ -313,6 +323,7 @@ String NWPluginData_static_runtime::statusToString() const
|
||||
|
||||
if (hasIP()) {
|
||||
log += F("IP ");
|
||||
if (_useStaticIP) log += F("(static) ");
|
||||
}
|
||||
|
||||
if (operational()) {
|
||||
|
||||
@@ -127,6 +127,8 @@ struct NWPluginData_static_runtime {
|
||||
|
||||
void processEvents();
|
||||
|
||||
void setStaticIP(const IPAddress & ip, const IPAddress & gateway, const IPAddress & subnetmask, const IPAddress & dns);
|
||||
|
||||
// =============================================
|
||||
// OnOffTimers for keeping track of:
|
||||
// - start/stop of interface
|
||||
@@ -157,6 +159,9 @@ struct NWPluginData_static_runtime {
|
||||
bool _enableIPv6{}; // Cached enableIPv6 flag as it is being used from callbacks
|
||||
#endif
|
||||
|
||||
IPAddress _ip, _gateway, _sn, _dns;
|
||||
bool _useStaticIP{}; // Added to make sure we don't have to re-check IP from a callback
|
||||
|
||||
private:
|
||||
|
||||
#ifdef ESP32
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
# include "../ESPEasyNetwork.h"
|
||||
|
||||
# include "../../../src/Helpers/StringConverter.h"
|
||||
# include "../../../src/Helpers/Networking.h"
|
||||
# include "../../../src/Globals/Settings.h"
|
||||
|
||||
# include "../Globals/NetworkState.h"
|
||||
@@ -95,6 +96,16 @@ void NWPluginData_static_runtime::mark_start()
|
||||
|
||||
if (!_netif) { return; }
|
||||
|
||||
if (_useStaticIP) {
|
||||
_netif->config(
|
||||
_ip,
|
||||
_gateway,
|
||||
_sn,
|
||||
_dns);
|
||||
} else {
|
||||
_netif->config((uint32_t)0, (uint32_t)0, (uint32_t)0);
|
||||
}
|
||||
|
||||
const String hostname = strformat(
|
||||
F("%s-%s"),
|
||||
NetworkCreateRFCCompliantHostname().c_str(),
|
||||
@@ -147,11 +158,10 @@ void NWPluginData_static_runtime::mark_got_IP()
|
||||
|
||||
for (size_t i = 0; i < NR_ELEMENTS(_dns_cache); ++i) {
|
||||
auto tmp = _netif->dnsIP(i);
|
||||
|
||||
_dns_cache[i] = tmp; // Also set the 'empty' ones so we won't set left-over DNS server from when another interface was active.
|
||||
# if NW_PLUGIN_LOG_EVENTS
|
||||
|
||||
if ((tmp != INADDR_NONE) && loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
if (valid_DNS_address(tmp) && loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
addLog(LOG_LEVEL_INFO, strformat(
|
||||
F("%s: DNS Cache %d set to %s"),
|
||||
_eventInterfaceName.c_str(),
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
# include "../ESPEasyNetwork.h"
|
||||
# include "../../../src/Helpers/StringConverter.h"
|
||||
# include "../wifi/ESPEasyWifi.h"
|
||||
|
||||
namespace ESPEasy {
|
||||
namespace net {
|
||||
@@ -71,9 +72,23 @@ void NWPluginData_static_runtime::mark_lost_IP()
|
||||
|
||||
void NWPluginData_static_runtime::mark_begin_establish_connection()
|
||||
{
|
||||
_establishConnectStats.forceSet(true);
|
||||
_connectedStats.setOff();
|
||||
_operationalStats.setOff();
|
||||
|
||||
if (!_isAP) {
|
||||
ESPEasy::net::wifi::setUseStaticIP(_useStaticIP);
|
||||
if (_useStaticIP) {
|
||||
WiFi.config(
|
||||
_ip,
|
||||
_gateway,
|
||||
_sn,
|
||||
_dns);
|
||||
} else {
|
||||
WiFi.config((uint32_t)0, (uint32_t)0, (uint32_t)0);
|
||||
}
|
||||
}
|
||||
|
||||
_establishConnectStats.forceSet(true);
|
||||
WiFi.hostname(NetworkCreateRFCCompliantHostname().c_str());
|
||||
}
|
||||
|
||||
@@ -81,6 +96,10 @@ void NWPluginData_static_runtime::mark_connected()
|
||||
{
|
||||
_establishConnectStats.setOff();
|
||||
_connectedStats.setOn();
|
||||
if (_useStaticIP) {
|
||||
// Since we won't get an event stating we got an IP, we need to trigger it here
|
||||
mark_got_IP();
|
||||
}
|
||||
}
|
||||
|
||||
void NWPluginData_static_runtime::log_connected()
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "../../../src/Helpers/StringConverter.h"
|
||||
#include "../../../src/Helpers/StringGenerator_WiFi.h"
|
||||
|
||||
#include "../wifi/ESPEasyWifi.h"
|
||||
|
||||
#if defined(ESP8266)
|
||||
# include <ESP8266WiFi.h>
|
||||
#endif // if defined(ESP8266)
|
||||
@@ -73,15 +75,9 @@ WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t index_c, const String& ssid_c) :
|
||||
{
|
||||
_allBits = 0u;
|
||||
|
||||
const size_t ssid_length = ssid_c.length();
|
||||
|
||||
if ((ssid_length == 0) || equals(ssid_c, F("ssid"))) {
|
||||
return;
|
||||
if (validWiFiSSID(ssid_c)) {
|
||||
ssid = ssid_c;
|
||||
}
|
||||
|
||||
if (ssid_length > 32) { return; }
|
||||
|
||||
ssid = ssid_c;
|
||||
}
|
||||
|
||||
WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t networkItem) : index(0) {
|
||||
|
||||
@@ -79,14 +79,14 @@ String makeRFCCompliantName(const String& name, const char replaceChar, const ch
|
||||
return hostname;
|
||||
}
|
||||
|
||||
void CheckRunningServices() {
|
||||
void CheckRunningServices(bool force) {
|
||||
// First try to get the time, since that may be used in logs
|
||||
if (Settings.UseNTP() && (node_time.getTimeSource() > timeSource_t::NTP_time_source)) {
|
||||
node_time.lastNTPSyncTime_ms = 0;
|
||||
node_time.initTime();
|
||||
}
|
||||
#if FEATURE_ESPEASY_P2P
|
||||
updateUDPport(true);
|
||||
updateUDPport(force);
|
||||
#endif
|
||||
|
||||
#if FEATURE_WIFI
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "../../ESPEasy_common.h"
|
||||
|
||||
#include "../net/DataStructs/MAC_address.h"
|
||||
#include "../net/DataTypes/NetworkIndex.h"
|
||||
|
||||
#include <IPAddress.h>
|
||||
|
||||
@@ -23,6 +24,9 @@ namespace net {
|
||||
|
||||
void setNetworkMedium(NetworkMedium_t medium);
|
||||
|
||||
|
||||
ESPEasy::net::networkIndex_t getNetworkIndex_defaultNetwork();
|
||||
|
||||
// void NetworkConnectRelaxed();
|
||||
bool NetworkConnected(bool force = false);
|
||||
IPAddress NetworkLocalIP();
|
||||
@@ -63,7 +67,7 @@ MAC_address WifiSoftAPmacAddress();
|
||||
MAC_address WifiSTAmacAddress();
|
||||
#endif // if FEATURE_WIFI
|
||||
|
||||
void CheckRunningServices();
|
||||
void CheckRunningServices(bool force = false);
|
||||
|
||||
#if FEATURE_ETHERNET
|
||||
bool EthFullDuplex();
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
|
||||
#include "../net/ESPEasyNetwork.h"
|
||||
|
||||
#include "../../ESPEasy/net/Globals/NetworkState.h"
|
||||
#include "../net/Globals/NetworkState.h"
|
||||
#include "../net/eth/ESPEasyEth.h"
|
||||
#include "../net/Globals/NWPlugins.h"
|
||||
#include "../../src/ESPEasyCore/ESPEasy_Log.h"
|
||||
#include "../../src/Helpers/NetworkStatusLED.h"
|
||||
#include "../../src/Helpers/StringConverter.h"
|
||||
#include "../net/eth/ESPEasyEth.h"
|
||||
#include "../net/Globals/NWPlugins.h"
|
||||
#include "../../src/Globals/Settings.h"
|
||||
|
||||
|
||||
#include <NetworkManager.h>
|
||||
|
||||
@@ -116,13 +118,35 @@ NetworkInterface* getDefaultNonAP_interface()
|
||||
return network_if;
|
||||
}
|
||||
|
||||
ESPEasy::net::networkIndex_t getNetworkIndex_defaultNetwork()
|
||||
{
|
||||
auto network_if = getDefaultNonAP_interface();
|
||||
if (network_if == nullptr) {
|
||||
return ESPEasy::net::INVALID_NETWORK_INDEX;
|
||||
}
|
||||
for (ESPEasy::net::networkIndex_t x = 0; x < NETWORK_MAX; ++x) {
|
||||
if (Settings.getNetworkEnabled(x)) {
|
||||
struct EventStruct TempEvent;
|
||||
TempEvent.NetworkIndex = x;
|
||||
String str;
|
||||
|
||||
if (ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_GET_INTERFACE, &TempEvent, str))
|
||||
{
|
||||
if (TempEvent.networkInterface->netif() == network_if->netif()) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ESPEasy::net::INVALID_NETWORK_INDEX;
|
||||
}
|
||||
|
||||
bool NetworkConnected(bool force) {
|
||||
static bool last_result = false;
|
||||
static uint32_t last_check_millis = 0;
|
||||
|
||||
if (force || (timePassedSince(last_check_millis) > 50) || (last_check_millis == 0)) {
|
||||
last_check_millis = millis();
|
||||
last_result = Network.isOnline();
|
||||
|
||||
// FIXME TD-er: This is checking for NonAP interfaces, however we also have
|
||||
// ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_WEBSERVER_SHOULD_RUN);
|
||||
@@ -136,6 +160,7 @@ bool NetworkConnected(bool force) {
|
||||
// - Webserver
|
||||
|
||||
processNetworkEvents();
|
||||
last_result = Network.isOnline();
|
||||
}
|
||||
return last_result;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,12 @@ void setNetworkMedium(NetworkMedium_t new_medium) {
|
||||
// ESPEasy::net::wifi::WiFiConnectRelaxed();
|
||||
// }
|
||||
|
||||
ESPEasy::net::networkIndex_t getNetworkIndex_defaultNetwork()
|
||||
{
|
||||
if (NetworkConnected()) return NETWORK_INDEX_WIFI_STA;
|
||||
return ESPEasy::net::INVALID_NETWORK_INDEX;
|
||||
}
|
||||
|
||||
bool NetworkConnected(bool force) {
|
||||
static bool last_result = false;
|
||||
static uint32_t last_check_millis = 0;
|
||||
|
||||
@@ -181,7 +181,7 @@ bool NWPluginCall(NWPlugin::Function Function, EventStruct *event, String& str)
|
||||
}
|
||||
|
||||
if (Function == NWPlugin::Function::NWPLUGIN_PRIORITY_ROUTE_CHANGED) {
|
||||
CheckRunningServices();
|
||||
CheckRunningServices(success);
|
||||
}
|
||||
|
||||
return success;
|
||||
@@ -493,7 +493,7 @@ bool NWPluginCall(NWPlugin::Function Function, EventStruct *event, String& str)
|
||||
}
|
||||
#endif // ifdef ESP32
|
||||
}
|
||||
#ifdef ESP32
|
||||
//#ifdef ESP32
|
||||
|
||||
if (Function == NWPlugin::Function::NWPLUGIN_EXIT) {
|
||||
// Cache.clearNetworkSettings(networkIndex);
|
||||
@@ -505,7 +505,7 @@ bool NWPluginCall(NWPlugin::Function Function, EventStruct *event, String& str)
|
||||
}
|
||||
clearNWPluginData(event->NetworkIndex);
|
||||
}
|
||||
#endif // ifdef ESP32
|
||||
//#endif // ifdef ESP32
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../../../src/DataStructs/TimingStats.h"
|
||||
#include "../../../src/DataTypes/ESPEasy_plugin_functions.h"
|
||||
#include "../../../src/Globals/Settings.h"
|
||||
#include "../../../src/Globals/ESPEasy_Scheduler.h"
|
||||
//#include "../../../src/Helpers/Misc.h"
|
||||
#include "../../../src/Helpers/StringConverter.h"
|
||||
#include "../Globals/NWPlugins.h"
|
||||
@@ -2130,20 +2131,24 @@ bool do_NWPluginCall(networkDriverIndex_t networkDriverIndex, NWPlugin::
|
||||
addLog(LOG_LEVEL_ERROR, strformat(F("Network %d was already initialized"), event->NetworkIndex + 1));
|
||||
return false;
|
||||
}
|
||||
bitSet(networkIndex_initialized, event->NetworkIndex);
|
||||
} else if (Function == NWPlugin::Function::NWPLUGIN_EXIT) {
|
||||
if (!bitRead(networkIndex_initialized, event->NetworkIndex)) {
|
||||
// FIXME TD-er: What to do here? Was not (yet) initialized
|
||||
// addLog(LOG_LEVEL_ERROR, strformat(F("Network %d was not (yet) initialized"), event->NetworkIndex + 1));
|
||||
return false;
|
||||
}
|
||||
bitClear(networkIndex_initialized, event->NetworkIndex);
|
||||
}
|
||||
|
||||
|
||||
START_TIMER;
|
||||
NWPlugin_ptr_t nwplugin_call = (NWPlugin_ptr_t)pgm_read_ptr(NWPlugin_ptr + networkDriverIndex.value);
|
||||
const bool res = nwplugin_call(Function, event, string);
|
||||
if (res && Function == NWPlugin::Function::NWPLUGIN_INIT) {
|
||||
bitSet(networkIndex_initialized, event->NetworkIndex);
|
||||
} else if (Function == NWPlugin::Function::NWPLUGIN_EXIT) {
|
||||
bitClear(networkIndex_initialized, event->NetworkIndex);
|
||||
}
|
||||
|
||||
STOP_TIMER_NETWORK(networkDriverIndex, Function);
|
||||
return res;
|
||||
}
|
||||
@@ -2200,10 +2205,10 @@ void NWPlugin_Exit_Init(networkIndex_t networkIndex)
|
||||
String dummy;
|
||||
|
||||
// May need to call init later, so make sure exit is called first
|
||||
NWPluginCall(NWPlugin::Function::NWPLUGIN_EXIT, &TempEvent, dummy);
|
||||
Scheduler.setNetworkExitTimer(0, networkIndex);
|
||||
|
||||
if (Settings.getNetworkEnabled(networkIndex)) {
|
||||
NWPluginCall(NWPlugin::Function::NWPLUGIN_INIT, &TempEvent, dummy);
|
||||
Scheduler.setNetworkInitTimer(0, networkIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
# include "../../../src/DataTypes/ESPEasy_plugin_functions.h"
|
||||
# include "../../../src/WebServer/HTML_wrappers.h"
|
||||
# include "../../../src/WebServer/Markup.h"
|
||||
# include "../../../src/Globals/Settings.h"
|
||||
# include "../../../src/Helpers/Networking.h"
|
||||
|
||||
# include "../wifi/ESPEasyWifi.h"
|
||||
|
||||
@@ -42,9 +44,9 @@ void NW001_data_struct_WiFi_STA::webform_load(EventStruct *event)
|
||||
|
||||
}
|
||||
|
||||
void NW001_data_struct_WiFi_STA::webform_save(EventStruct *event) {}
|
||||
void NW001_data_struct_WiFi_STA::webform_save(EventStruct *event) {}
|
||||
|
||||
bool NW001_data_struct_WiFi_STA::webform_getPort(KeyValueWriter *writer) { return true; }
|
||||
bool NW001_data_struct_WiFi_STA::webform_getPort(KeyValueWriter *writer) { return true; }
|
||||
|
||||
bool NW001_data_struct_WiFi_STA::init(EventStruct *event)
|
||||
{
|
||||
@@ -95,6 +97,16 @@ bool NW001_data_struct_WiFi_STA::init(EventStruct *event)
|
||||
// ESPEasy::net::wifi::setWifiMode(WIFI_OFF);
|
||||
*/
|
||||
|
||||
{
|
||||
auto runtime_data = getNWPluginData_static_runtime();
|
||||
if (runtime_data) {
|
||||
IPAddress ip, gateway, sn, dns;
|
||||
getStaticIPAddresses(ip, gateway, sn, dns);
|
||||
runtime_data->setStaticIP(ip, gateway, sn, dns);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ESPEasy::net::wifi::initWiFi();
|
||||
return true;
|
||||
}
|
||||
@@ -108,6 +120,30 @@ NWPluginData_static_runtime * NW001_data_struct_WiFi_STA::getNWPluginData_static
|
||||
return _WiFiEventHandler.getNWPluginData_static_runtime();
|
||||
}
|
||||
|
||||
bool NW001_data_struct_WiFi_STA::getStaticIPAddress(IPAddressType addressType, IPAddress& ip) const
|
||||
{
|
||||
IPAddress res;
|
||||
|
||||
switch (addressType)
|
||||
{
|
||||
case IPAddressType::IP:
|
||||
res = IPAddress(Settings.IP);
|
||||
break;
|
||||
case IPAddressType::Gateway:
|
||||
res = IPAddress(Settings.Gateway);
|
||||
break;
|
||||
case IPAddressType::Subnetmask:
|
||||
res = IPAddress(Settings.Subnet);
|
||||
break;
|
||||
case IPAddressType::DNS:
|
||||
res = IPAddress(Settings.DNS);
|
||||
break;
|
||||
}
|
||||
ip = res;
|
||||
|
||||
return IPAddressSet(ip);
|
||||
}
|
||||
|
||||
const __FlashStringHelper * NW001_data_struct_WiFi_STA::getWiFi_encryptionType() const
|
||||
{
|
||||
return _WiFiEventHandler.getWiFi_encryptionType();
|
||||
|
||||
@@ -41,6 +41,7 @@ struct NW001_data_struct_WiFi_STA : public NWPluginData_base {
|
||||
# endif // if FEATURE_NETWORK_STATS
|
||||
|
||||
NWPluginData_static_runtime* getNWPluginData_static_runtime() override;
|
||||
bool getStaticIPAddress(IPAddressType addressType, IPAddress & ip) const override;
|
||||
const __FlashStringHelper* getWiFi_encryptionType() const;
|
||||
|
||||
WiFiDisconnectReason getWiFi_disconnectReason() const;
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
#ifdef USES_NW002
|
||||
|
||||
# ifdef ESP32
|
||||
# include "../../../src/Globals/Settings.h"
|
||||
#endif
|
||||
# include "../../../src/Globals/Settings.h"
|
||||
# endif
|
||||
|
||||
# include "../wifi/ESPEasyWifi.h"
|
||||
|
||||
# include "../../../src/Helpers/Networking.h"
|
||||
|
||||
# ifdef ESP32
|
||||
# include <esp_wifi.h>
|
||||
# include <esp_wifi_ap_get_sta_list.h>
|
||||
@@ -89,6 +91,15 @@ bool NW002_data_struct_WiFi_AP::webform_getPort(KeyValueWriter *writer) { return
|
||||
|
||||
bool NW002_data_struct_WiFi_AP::init(EventStruct *event)
|
||||
{
|
||||
{
|
||||
auto runtime_data = getNWPluginData_static_runtime();
|
||||
if (runtime_data) {
|
||||
IPAddress ip, gateway, sn, dns;
|
||||
getStaticIPAddresses(ip, gateway, sn, dns);
|
||||
runtime_data->setStaticIP(ip, gateway, sn, dns);
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef ESP32
|
||||
nw002_enable_NAPT = Settings.WiFi_AP_enable_NAPT();
|
||||
# endif
|
||||
@@ -97,13 +108,13 @@ bool NW002_data_struct_WiFi_AP::init(EventStruct *event)
|
||||
# ifdef ESP32
|
||||
NW002_update_NAPT();
|
||||
# endif
|
||||
# if FEATURE_MDNS
|
||||
# ifdef ESP8266
|
||||
# if FEATURE_MDNS
|
||||
# ifdef ESP8266
|
||||
|
||||
// notifyAPChange() is not present in the ESP32 MDNSResponder
|
||||
MDNS.notifyAPChange();
|
||||
# endif // ifdef ESP8266
|
||||
# endif // if FEATURE_MDNS
|
||||
# endif // ifdef ESP8266
|
||||
# endif // if FEATURE_MDNS
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -132,6 +143,32 @@ NWPluginData_static_runtime * NW002_data_struct_WiFi_AP::getNWPluginData_static_
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool NW002_data_struct_WiFi_AP::getStaticIPAddress(IPAddressType addressType, IPAddress& ip) const
|
||||
{
|
||||
// TODO TD-er: Implement for AP
|
||||
/*
|
||||
IPAddress res;
|
||||
|
||||
switch (addressType)
|
||||
{
|
||||
case IPAddressType::IP: res = IPAddress(Settings.IP);
|
||||
break;
|
||||
case IPAddressType::Gateway: res = IPAddress(Settings.Gateway);
|
||||
break;
|
||||
case IPAddressType::Subnetmask: res = IPAddress(Settings.Subnet);
|
||||
break;
|
||||
case IPAddressType::DNS: res = IPAddress(Settings.DNS);
|
||||
break;
|
||||
}
|
||||
|
||||
if (IPAddressSet(res)) {
|
||||
ip = res;
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
# ifdef ESP32
|
||||
|
||||
bool NW002_data_struct_WiFi_AP::handle_priority_route_changed() { return NW002_update_NAPT(); }
|
||||
|
||||
@@ -35,6 +35,8 @@ struct NW002_data_struct_WiFi_AP : public NWPluginData_base {
|
||||
|
||||
NWPluginData_static_runtime* getNWPluginData_static_runtime() override;
|
||||
|
||||
bool getStaticIPAddress(IPAddressType addressType, IPAddress & ip) const override;
|
||||
|
||||
private:
|
||||
|
||||
# ifdef ESP32
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
# include "../../../src/Globals/Settings.h"
|
||||
|
||||
# include "../../../src/Helpers/Hardware_GPIO.h"
|
||||
# include "../../../src/Helpers/Networking.h"
|
||||
# include "../../../src/Helpers/StringConverter.h"
|
||||
|
||||
# include "../../../src/WebServer/Markup.h"
|
||||
@@ -55,16 +56,16 @@ const __FlashStringHelper * NW003_data_struct_ETH_RMII::getLabelString(uint32_t
|
||||
case NW003_KEY_ETH_PIN_POWER: return displayString ? F("Ethernet Power pin") : F("pwr");
|
||||
case NW003_KEY_CLOCK_MODE: return displayString ? F("Ethernet Clock") : F("clock");
|
||||
case NW003_KEY_IP:
|
||||
storageType = KVS_StorageType::Enum::string_type;
|
||||
storageType = KVS_StorageType::Enum::ip_type;
|
||||
return F("IP");
|
||||
case NW003_KEY_GW:
|
||||
storageType = KVS_StorageType::Enum::string_type;
|
||||
storageType = KVS_StorageType::Enum::ip_type;
|
||||
return displayString ? F("Gateway") : F("gw");
|
||||
case NW003_KEY_SN:
|
||||
storageType = KVS_StorageType::Enum::string_type;
|
||||
storageType = KVS_StorageType::Enum::ip_type;
|
||||
return displayString ? F("Subnetmask") : F("sn");
|
||||
case NW003_KEY_DNS:
|
||||
storageType = KVS_StorageType::Enum::string_type;
|
||||
storageType = KVS_StorageType::Enum::ip_type;
|
||||
return F("DNS");
|
||||
}
|
||||
return F("");
|
||||
@@ -144,7 +145,18 @@ void NW003_data_struct_ETH_RMII::loadDefaults(ESPEasy_key_value_store *kvs,
|
||||
kvs->setValue(NW003_KEY_ETH_PIN_POWER, static_cast<int8_t>(Settings.ETH_Pin_power_rst));
|
||||
kvs->setValue(NW003_KEY_CLOCK_MODE, static_cast<int8_t>(Settings.ETH_Clock_Mode));
|
||||
|
||||
// TODO TD-er: Copy IP info
|
||||
const IPAddress ip = Settings.ETH_IP;
|
||||
const IPAddress gw = Settings.ETH_Gateway;
|
||||
const IPAddress subnet = Settings.ETH_Subnet;
|
||||
const IPAddress dns = Settings.ETH_DNS;
|
||||
|
||||
// TODO TD-er: Must clear the previous ETH IP settings, once converted
|
||||
|
||||
kvs->setValue(NW003_KEY_IP, ip);
|
||||
kvs->setValue(NW003_KEY_GW, gw);
|
||||
kvs->setValue(NW003_KEY_SN, subnet);
|
||||
kvs->setValue(NW003_KEY_DNS, dns);
|
||||
|
||||
|
||||
store_nwpluginTaskData_KVS(kvs, networkIndex, nwPluginID);
|
||||
}
|
||||
@@ -176,12 +188,18 @@ void NW003_data_struct_ETH_RMII::webform_load(EventStruct *event)
|
||||
NW003_data_struct_ETH_RMII::loadDefaults(_kvs, event->NetworkIndex, nwpluginID_t(3));
|
||||
|
||||
addFormSubHeader(F("Ethernet IP Settings"));
|
||||
{
|
||||
const int keys[] = {
|
||||
NW003_KEY_IP,
|
||||
NW003_KEY_GW,
|
||||
NW003_KEY_SN,
|
||||
NW003_KEY_DNS
|
||||
};
|
||||
|
||||
addFormIPBox(F("ESP Ethernet IP"), F("espethip"), Settings.ETH_IP);
|
||||
addFormIPBox(F("ESP Ethernet Gateway"), F("espethgateway"), Settings.ETH_Gateway);
|
||||
addFormIPBox(F("ESP Ethernet Subnetmask"), F("espethsubnet"), Settings.ETH_Subnet);
|
||||
addFormIPBox(F("ESP Ethernet DNS"), F("espethdns"), Settings.ETH_DNS);
|
||||
addFormNote(F("Leave empty for DHCP"));
|
||||
for (uint32_t i = 0; i < NR_ELEMENTS(keys); ++i) {
|
||||
showWebformItem(*_kvs, NW003_makeWebFormItemParams(keys[i]));
|
||||
}
|
||||
}
|
||||
|
||||
addFormSubHeader(F("Ethernet"));
|
||||
|
||||
@@ -276,19 +294,21 @@ void NW003_data_struct_ETH_RMII::webform_load(EventStruct *event)
|
||||
// toString(EthClockMode_t::Default),
|
||||
toString(EthClockMode_t::Ext_crystal),
|
||||
toString(EthClockMode_t::Int_50MHz)
|
||||
// , toString(EthClockMode_t::Ext_crystal_GPIO_32)
|
||||
// , toString(EthClockMode_t::Int_50MHz_GPIO_32)
|
||||
// , toString(EthClockMode_t::Ext_crystal_GPIO_44)
|
||||
// , toString(EthClockMode_t::Int_50MHz_GPIO_44)
|
||||
|
||||
// , toString(EthClockMode_t::Ext_crystal_GPIO_32)
|
||||
// , toString(EthClockMode_t::Int_50MHz_GPIO_32)
|
||||
// , toString(EthClockMode_t::Ext_crystal_GPIO_44)
|
||||
// , toString(EthClockMode_t::Int_50MHz_GPIO_44)
|
||||
};
|
||||
const int indices[] = {
|
||||
// static_cast<int>(EthClockMode_t::Default),
|
||||
static_cast<int>(EthClockMode_t::Ext_crystal),
|
||||
static_cast<int>(EthClockMode_t::Int_50MHz)
|
||||
// ,static_cast<int>(EthClockMode_t::Ext_crystal_GPIO_32)
|
||||
// ,static_cast<int>(EthClockMode_t::Int_50MHz_GPIO_32)
|
||||
// ,static_cast<int>(EthClockMode_t::Ext_crystal_GPIO_44)
|
||||
// ,static_cast<int>(EthClockMode_t::Int_50MHz_GPIO_44)
|
||||
|
||||
// ,static_cast<int>(EthClockMode_t::Ext_crystal_GPIO_32)
|
||||
// ,static_cast<int>(EthClockMode_t::Int_50MHz_GPIO_32)
|
||||
// ,static_cast<int>(EthClockMode_t::Ext_crystal_GPIO_44)
|
||||
// ,static_cast<int>(EthClockMode_t::Int_50MHz_GPIO_44)
|
||||
};
|
||||
# endif // if CONFIG_IDF_TARGET_ESP32P4
|
||||
const FormSelectorOptions selector(
|
||||
@@ -298,10 +318,10 @@ void NW003_data_struct_ETH_RMII::webform_load(EventStruct *event)
|
||||
auto params = NW003_makeWebFormItemParams(NW003_KEY_CLOCK_MODE);
|
||||
# if CONFIG_IDF_TARGET_ESP32
|
||||
params._defaultIntValue = static_cast<int>(EthClockMode_t::Ext_crystal_osc);
|
||||
#endif
|
||||
# endif
|
||||
# if CONFIG_IDF_TARGET_ESP32P4
|
||||
params._defaultIntValue = static_cast<int>(EthClockMode_t::Ext_crystal);
|
||||
#endif
|
||||
# endif
|
||||
|
||||
showFormSelector(*_kvs, selector, params);
|
||||
|
||||
@@ -327,6 +347,15 @@ bool NW003_data_struct_ETH_RMII::webform_getPort(KeyValueWriter *writer) { retur
|
||||
bool NW003_data_struct_ETH_RMII::init(EventStruct *event)
|
||||
{
|
||||
_load();
|
||||
{
|
||||
auto runtime_data = getNWPluginData_static_runtime();
|
||||
if (runtime_data) {
|
||||
IPAddress ip, gateway, sn, dns;
|
||||
getStaticIPAddresses(ip, gateway, sn, dns);
|
||||
runtime_data->setStaticIP(ip, gateway, sn, dns);
|
||||
}
|
||||
}
|
||||
|
||||
ETHConnectRelaxed();
|
||||
|
||||
return true;
|
||||
@@ -338,6 +367,36 @@ NWPluginData_static_runtime * NW003_data_struct_ETH_RMII::getNWPluginData_static
|
||||
return ESPEasy::net::eth::ETH_NWPluginData_static_runtime::getNWPluginData_static_runtime(_networkIndex);
|
||||
}
|
||||
|
||||
bool NW003_data_struct_ETH_RMII::getStaticIPAddress(IPAddressType addressType, IPAddress& ip) const
|
||||
{
|
||||
ip = IPAddress();
|
||||
|
||||
if (!_kvs) { return false; }
|
||||
uint32_t key = NW003_MAX_KEY;
|
||||
|
||||
switch (addressType)
|
||||
{
|
||||
case IPAddressType::IP:
|
||||
key = NW003_KEY_IP;
|
||||
break;
|
||||
case IPAddressType::Gateway:
|
||||
key = NW003_KEY_GW;
|
||||
break;
|
||||
case IPAddressType::Subnetmask:
|
||||
key = NW003_KEY_SN;
|
||||
break;
|
||||
case IPAddressType::DNS:
|
||||
key = NW003_KEY_DNS;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((key == NW003_MAX_KEY) || !_kvs->getValue(key, ip)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return IPAddressSet(ip);
|
||||
}
|
||||
|
||||
bool NW003_data_struct_ETH_RMII::write_Eth_HW_Address(KeyValueWriter *writer)
|
||||
{
|
||||
if (writer == nullptr) { return false; }
|
||||
@@ -447,6 +506,7 @@ void NW003_data_struct_ETH_RMII::ethPower(bool enable)
|
||||
|
||||
if (!enable) {
|
||||
const EthClockMode_t ETH_ClockMode = static_cast<EthClockMode_t>(_kvs->getValueAsInt(NW003_KEY_CLOCK_MODE));
|
||||
|
||||
if (isExternalCrystal(ETH_ClockMode)) {
|
||||
delay(600); // Give some time to discharge any capacitors
|
||||
// Delay is needed to make sure no clock signal remains present which may cause the ESP to boot into flash mode.
|
||||
@@ -503,7 +563,7 @@ bool NW003_data_struct_ETH_RMII::ETHConnectRelaxed() {
|
||||
if (!(data && iface)) { return false; }
|
||||
|
||||
if (data->started() && data->connected()) {
|
||||
if (EthLinkUp()) return true;
|
||||
if (EthLinkUp()) { return true; }
|
||||
data->mark_connect_failed();
|
||||
return false;
|
||||
}
|
||||
@@ -541,6 +601,18 @@ bool NW003_data_struct_ETH_RMII::ETHConnectRelaxed() {
|
||||
# ifndef ESP32P4
|
||||
ethResetGPIOpins();
|
||||
# endif
|
||||
|
||||
IPAddress ip, gateway, sn, dns;
|
||||
if (getStaticIPAddresses(ip, gateway, sn, dns)) {
|
||||
addLog(LOG_LEVEL_INFO, strformat(
|
||||
F("ETH: static IP: %s, GW: %s, SN: %s, DNS:%s"),
|
||||
ip.toString().c_str(),
|
||||
gateway.toString().c_str(),
|
||||
sn.toString().c_str(),
|
||||
dns.toString().c_str()));
|
||||
iface->config(ip, gateway, sn, dns);
|
||||
}
|
||||
|
||||
success = iface->begin(
|
||||
to_ESP_phy_type(phyType),
|
||||
phy_addr,
|
||||
@@ -548,7 +620,8 @@ bool NW003_data_struct_ETH_RMII::ETHConnectRelaxed() {
|
||||
mdioPin,
|
||||
powerPin,
|
||||
(eth_clock_mode_t)ETH_ClockMode);
|
||||
// TODO TD-er: When we can set the clock GPIO pin on ESP32-P4, this should also be matched to the Espressif eth_clock_mode_t enum.
|
||||
|
||||
// TODO TD-er: When we can set the clock GPIO pin on ESP32-P4, this should also be matched to the Espressif eth_clock_mode_t enum.
|
||||
}
|
||||
|
||||
if (success) {
|
||||
|
||||
@@ -39,6 +39,8 @@ struct NW003_data_struct_ETH_RMII : public NWPluginData_base {
|
||||
|
||||
NWPluginData_static_runtime* getNWPluginData_static_runtime() override;
|
||||
|
||||
bool getStaticIPAddress(IPAddressType addressType, IPAddress & ip) const override;
|
||||
|
||||
bool write_Eth_HW_Address(KeyValueWriter *writer);
|
||||
|
||||
bool write_Eth_port(KeyValueWriter *writer);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
# include "../../../src/Helpers/Hardware_GPIO.h"
|
||||
# include "../../../src/Helpers/Hardware_SPI.h"
|
||||
# include "../../../src/Helpers/Networking.h"
|
||||
# include "../../../src/Helpers/SPI_Helper.h"
|
||||
# include "../../../src/Helpers/StringConverter.h"
|
||||
|
||||
@@ -53,16 +54,16 @@ const __FlashStringHelper * NW004_data_struct_ETH_SPI::getLabelString(uint32_t k
|
||||
case NW004_KEY_ETH_PIN_RST: return displayString ? F("Ethernet RST pin") : F("RST");
|
||||
case NW004_KEY_SPI_BUS: return displayString ? F("SPI Bus") : F("ethspibus");
|
||||
case NW004_KEY_IP:
|
||||
storageType = KVS_StorageType::Enum::string_type;
|
||||
storageType = KVS_StorageType::Enum::ip_type;
|
||||
return F("IP");
|
||||
case NW004_KEY_GW:
|
||||
storageType = KVS_StorageType::Enum::string_type;
|
||||
storageType = KVS_StorageType::Enum::ip_type;
|
||||
return displayString ? F("Gateway") : F("gw");
|
||||
case NW004_KEY_SN:
|
||||
storageType = KVS_StorageType::Enum::string_type;
|
||||
storageType = KVS_StorageType::Enum::ip_type;
|
||||
return displayString ? F("Subnetmask") : F("sn");
|
||||
case NW004_KEY_DNS:
|
||||
storageType = KVS_StorageType::Enum::string_type;
|
||||
storageType = KVS_StorageType::Enum::ip_type;
|
||||
return F("DNS");
|
||||
}
|
||||
return F("");
|
||||
@@ -141,7 +142,17 @@ void NW004_data_struct_ETH_SPI::loadDefaults(ESPEasy_key_value_store *kvs,
|
||||
kvs->setValue(NW004_KEY_ETH_PIN_IRQ, static_cast<int8_t>(Settings.ETH_Pin_mdio_irq));
|
||||
kvs->setValue(NW004_KEY_ETH_PIN_RST, static_cast<int8_t>(Settings.ETH_Pin_power_rst));
|
||||
|
||||
// TODO TD-er: Copy IP info
|
||||
const IPAddress ip = Settings.ETH_IP;
|
||||
const IPAddress gw = Settings.ETH_Gateway;
|
||||
const IPAddress subnet = Settings.ETH_Subnet;
|
||||
const IPAddress dns = Settings.ETH_DNS;
|
||||
|
||||
// TODO TD-er: Must clear the previous ETH IP settings, once converted
|
||||
|
||||
kvs->setValue(NW004_KEY_IP, ip);
|
||||
kvs->setValue(NW004_KEY_GW, gw);
|
||||
kvs->setValue(NW004_KEY_SN, subnet);
|
||||
kvs->setValue(NW004_KEY_DNS, dns);
|
||||
|
||||
store_nwpluginTaskData_KVS(kvs, networkIndex, nwPluginID);
|
||||
}
|
||||
@@ -157,8 +168,6 @@ void NW004_data_struct_ETH_SPI::loadDefaults(ESPEasy_key_value_store *kvs,
|
||||
kvs->setValue(NW004_KEY_ETH_PIN_IRQ, static_cast<int8_t>(DEFAULT_ETH_PIN_MDIO));
|
||||
kvs->setValue(NW004_KEY_ETH_PIN_RST, static_cast<int8_t>(DEFAULT_ETH_PIN_POWER));
|
||||
|
||||
// TODO TD-er: Copy IP info
|
||||
|
||||
store_nwpluginTaskData_KVS(kvs, networkIndex, nwPluginID);
|
||||
}
|
||||
# endif // if defined(DEFAULT_ETH_PHY_TYPE) && defined(DEFAULT_ETH_CLOCK_MODE) && defined(DEFAULT_ETH_PHY_ADDR) &&
|
||||
@@ -171,11 +180,18 @@ void NW004_data_struct_ETH_SPI::webform_load(EventStruct *event)
|
||||
_load();
|
||||
NW004_data_struct_ETH_SPI::loadDefaults(_kvs, event->NetworkIndex, nwpluginID_t(4));
|
||||
addFormSubHeader(F("Ethernet IP Settings"));
|
||||
{
|
||||
const int keys[] = {
|
||||
NW004_KEY_IP,
|
||||
NW004_KEY_GW,
|
||||
NW004_KEY_SN,
|
||||
NW004_KEY_DNS
|
||||
};
|
||||
|
||||
addFormIPBox(F("ESP Ethernet IP"), F("espethip"), Settings.ETH_IP);
|
||||
addFormIPBox(F("ESP Ethernet Gateway"), F("espethgateway"), Settings.ETH_Gateway);
|
||||
addFormIPBox(F("ESP Ethernet Subnetmask"), F("espethsubnet"), Settings.ETH_Subnet);
|
||||
addFormIPBox(F("ESP Ethernet DNS"), F("espethdns"), Settings.ETH_DNS);
|
||||
for (uint32_t i = 0; i < NR_ELEMENTS(keys); ++i) {
|
||||
showWebformItem(*_kvs, NW004_makeWebFormItemParams(keys[i]));
|
||||
}
|
||||
}
|
||||
addFormNote(F("Leave empty for DHCP"));
|
||||
|
||||
addFormSubHeader(F("Ethernet"));
|
||||
@@ -277,6 +293,15 @@ bool NW004_data_struct_ETH_SPI::webform_getPort(KeyValueWriter *writer) { return
|
||||
bool NW004_data_struct_ETH_SPI::init(EventStruct *event)
|
||||
{
|
||||
_load();
|
||||
{
|
||||
auto runtime_data = getNWPluginData_static_runtime();
|
||||
if (runtime_data) {
|
||||
IPAddress ip, gateway, sn, dns;
|
||||
getStaticIPAddresses(ip, gateway, sn, dns);
|
||||
runtime_data->setStaticIP(ip, gateway, sn, dns);
|
||||
}
|
||||
}
|
||||
|
||||
ETHConnectRelaxed();
|
||||
|
||||
return true;
|
||||
@@ -288,6 +313,37 @@ NWPluginData_static_runtime * NW004_data_struct_ETH_SPI::getNWPluginData_static_
|
||||
return ESPEasy::net::eth::ETH_NWPluginData_static_runtime::getNWPluginData_static_runtime(_networkIndex);
|
||||
}
|
||||
|
||||
bool NW004_data_struct_ETH_SPI::getStaticIPAddress(IPAddressType addressType, IPAddress& ip) const
|
||||
{
|
||||
ip = IPAddress();
|
||||
|
||||
if (!_kvs) { return false; }
|
||||
uint32_t key = NW004_MAX_KEY;
|
||||
|
||||
switch (addressType)
|
||||
{
|
||||
case IPAddressType::IP:
|
||||
key = NW004_KEY_IP;
|
||||
break;
|
||||
case IPAddressType::Gateway:
|
||||
key = NW004_KEY_GW;
|
||||
break;
|
||||
case IPAddressType::Subnetmask:
|
||||
key = NW004_KEY_SN;
|
||||
break;
|
||||
case IPAddressType::DNS:
|
||||
key = NW004_KEY_DNS;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((key == NW004_MAX_KEY) || !_kvs->getValue(key, ip)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return IPAddressSet(ip);
|
||||
|
||||
}
|
||||
|
||||
bool NW004_data_struct_ETH_SPI::write_Eth_HW_Address(KeyValueWriter *writer)
|
||||
{
|
||||
if (writer == nullptr) { return false; }
|
||||
@@ -448,6 +504,12 @@ bool NW004_data_struct_ETH_SPI::ETHConnectRelaxed() {
|
||||
// else
|
||||
if (spi_instance)
|
||||
{
|
||||
IPAddress ip, gateway, sn, dns;
|
||||
|
||||
if (getStaticIPAddresses(ip, gateway, sn, dns)) {
|
||||
iface->config(ip, gateway, sn, dns);
|
||||
}
|
||||
|
||||
// TODO TD-er: Do we need to include the CLK, MISO, MOSI pins in the call or do we need to start the SPI bus first?
|
||||
# if ETH_SPI_SUPPORTS_CUSTOM
|
||||
success = iface->begin(
|
||||
|
||||
@@ -40,6 +40,8 @@ struct NW004_data_struct_ETH_SPI : public NWPluginData_base {
|
||||
|
||||
NWPluginData_static_runtime* getNWPluginData_static_runtime() override;
|
||||
|
||||
bool getStaticIPAddress(IPAddressType addressType, IPAddress & ip) const override;
|
||||
|
||||
bool write_Eth_HW_Address(KeyValueWriter *writer);
|
||||
bool write_Eth_port(KeyValueWriter *writer);
|
||||
|
||||
|
||||
@@ -926,12 +926,12 @@ bool NW005_data_struct_PPP_modem::init(EventStruct *event)
|
||||
}
|
||||
{
|
||||
String apn;
|
||||
_kvs->getValue(NW005_KEY_APN, apn);
|
||||
_kvs->getValue(NW005_KEY_APN, apn, KVS_StorageType::Enum::string_type);
|
||||
NW_PLUGIN_INTERFACE.setApn(apn.c_str());
|
||||
}
|
||||
{
|
||||
String pin;
|
||||
_kvs->getValue(NW005_KEY_SIM_PIN, pin);
|
||||
_kvs->getValue(NW005_KEY_SIM_PIN, pin, KVS_StorageType::Enum::string_type);
|
||||
|
||||
if (pin.length() >= 4) {
|
||||
NW_PLUGIN_INTERFACE.setPin(pin.c_str());
|
||||
@@ -1108,6 +1108,12 @@ bool NW005_data_struct_PPP_modem::record_stats()
|
||||
|
||||
NWPluginData_static_runtime * NW005_data_struct_PPP_modem::getNWPluginData_static_runtime() { return &stats_and_cache; }
|
||||
|
||||
bool NW005_data_struct_PPP_modem::getStaticIPAddress(IPAddressType addressType, IPAddress & ip) const
|
||||
{
|
||||
// No static IP for PPP modem
|
||||
return false;
|
||||
}
|
||||
|
||||
void NW005_data_struct_PPP_modem::onEvent(arduino_event_id_t event, arduino_event_info_t info) {
|
||||
// TODO TD-er: Must store flags from events in static (or global) object to act on it later.
|
||||
switch (event)
|
||||
|
||||
@@ -80,6 +80,8 @@ static int32_t getNextKey_noCredentials(int32_t key);
|
||||
|
||||
NWPluginData_static_runtime* getNWPluginData_static_runtime() override;
|
||||
|
||||
bool getStaticIPAddress(IPAddressType addressType, IPAddress & ip) const override;
|
||||
|
||||
private:
|
||||
|
||||
static void onEvent(arduino_event_id_t event,
|
||||
|
||||
@@ -57,17 +57,11 @@ bool NWPlugin_001(NWPlugin::Function function, EventStruct *event, String& strin
|
||||
{
|
||||
case NWPlugin::Function::NWPLUGIN_DRIVER_ADD:
|
||||
{
|
||||
NetworkDriverStruct& nw = getNetworkDriverStruct(networkDriverIndex_t::toNetworkDriverIndex(event->idx));
|
||||
nw.onlySingleInstance = true;
|
||||
nw.alwaysPresent = true;
|
||||
# ifdef ESP32P4
|
||||
nw.enabledOnFactoryReset = false;
|
||||
|
||||
// ESPEasy::net::wifi::GetHostedMCUFwVersion() > 0x00020600;
|
||||
# else // ifdef ESP32P4
|
||||
NetworkDriverStruct& nw = getNetworkDriverStruct(networkDriverIndex_t::toNetworkDriverIndex(event->idx));
|
||||
nw.onlySingleInstance = true;
|
||||
nw.alwaysPresent = true;
|
||||
nw.enabledOnFactoryReset = true;
|
||||
# endif // ifdef ESP32P4
|
||||
nw.fixedNetworkIndex = NWPLUGIN_ID_001 - 1; // Start counting at 0
|
||||
nw.fixedNetworkIndex = NWPLUGIN_ID_001 - 1; // Start counting at 0
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -488,7 +482,7 @@ bool NWPlugin_001(NWPlugin::Function function, EventStruct *event, String& strin
|
||||
|
||||
addFormNumericBox(LabelType::WIFI_NR_RECONNECT_ATTEMPTS, 0, 255);
|
||||
{
|
||||
LabelType::Enum labels[]{
|
||||
LabelType::Enum labels[]{
|
||||
LabelType::RESTART_WIFI_LOST_CONN
|
||||
, LabelType::WIFI_USE_LAST_CONN_FROM_RTC
|
||||
# ifndef ESP32
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
# include "../../../src/DataTypes/ESPEasyTimeSource.h"
|
||||
# include "../../../src/ESPEasyCore/ESPEasy_Log.h"
|
||||
# include "../../../src/Helpers/Networking.h"
|
||||
# include "../../../src/Helpers/StringConverter.h"
|
||||
# include "../../../src/Helpers/StringGenerator_WiFi.h"
|
||||
# include "../DataStructs/NWPluginData_static_runtime.h"
|
||||
@@ -65,7 +66,7 @@ bool ESPEasyWiFi_STA_EventHandler::restore_dns_from_cac
|
||||
for (size_t i = 0; i < NR_ELEMENTS(stats_and_cache._dns_cache); ++i) {
|
||||
auto tmp = WiFi.STA.dnsIP(i);
|
||||
|
||||
if ((stats_and_cache._dns_cache[i] != INADDR_NONE) && (stats_and_cache._dns_cache[i] != tmp)) {
|
||||
if (valid_DNS_address(stats_and_cache._dns_cache[i]) && (stats_and_cache._dns_cache[i] != tmp)) {
|
||||
addLog(LOG_LEVEL_INFO, strformat(
|
||||
F("WiFi STA: Restore cached DNS server %d from %s to %s"),
|
||||
i,
|
||||
|
||||
@@ -86,7 +86,7 @@ void ESPEasyWiFi_STA_EventHandler::onDisconnect(const WiFiEventStationModeDiscon
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
// See https://github.com/esp8266/Arduino/issues/5912
|
||||
WiFi.persistent(false);
|
||||
WiFi.disconnect(false);
|
||||
WiFi.disconnect(true);
|
||||
delay(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ void ESPEasyWiFi_t::begin() {
|
||||
setState(WiFiState_e::IdleWaiting, 100);
|
||||
} else {
|
||||
if (WiFi_AP_Candidates.hasScanned()) {
|
||||
// Has no candidates, but scan was performed.
|
||||
if (shouldStartAP_fallback()) {
|
||||
setState(WiFiState_e::AP_only, WIFI_STATE_MACHINE_AP_ONLY_TIMEOUT);
|
||||
}
|
||||
@@ -153,7 +154,12 @@ void ESPEasyWiFi_t::loop()
|
||||
// && !WiFiEventData.warnedNoValidWiFiSettings
|
||||
)
|
||||
{
|
||||
addLog(LOG_LEVEL_ERROR, F("WIFI : No valid wifi settings"));
|
||||
// Check for whether No Valid WiFi settings was already logged
|
||||
static uint32_t lastTimeLoggedNoWiFiCredentials = 0;
|
||||
if (timePassedSince(lastTimeLoggedNoWiFiCredentials) > 5000) {
|
||||
addLog(LOG_LEVEL_ERROR, F("WIFI : No valid wifi settings"));
|
||||
lastTimeLoggedNoWiFiCredentials = millis();
|
||||
}
|
||||
|
||||
// WiFiEventData.warnedNoValidWiFiSettings = true;
|
||||
}
|
||||
@@ -299,7 +305,7 @@ void ESPEasyWiFi_t::loop()
|
||||
/*
|
||||
if (Settings.UseRules)
|
||||
{
|
||||
eventQueue.add(F("WiFi#Disconnected"));
|
||||
eventQueue.addDeDup(F("WiFi#Disconnected"));
|
||||
}
|
||||
statusLED(false);
|
||||
*/
|
||||
@@ -330,7 +336,7 @@ void ESPEasyWiFi_t::disconnect() { doWiFiDisconnect(); }
|
||||
|
||||
void ESPEasyWiFi_t::setState(WiFiState_e newState, uint32_t timeout) {
|
||||
if (newState == _state) { return; }
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
//# ifndef BUILD_NO_DEBUG
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
addLog(
|
||||
@@ -339,7 +345,7 @@ void ESPEasyWiFi_t::setState(WiFiState_e newState, uint32_t timeout) {
|
||||
concat(F(" to: "), toString(newState)) +
|
||||
concat(F(" timeout: "), timeout));
|
||||
}
|
||||
# endif // ifndef BUILD_NO_DEBUG
|
||||
//# endif // ifndef BUILD_NO_DEBUG
|
||||
|
||||
if ((_state == WiFiState_e::AP_only) ||
|
||||
(_state == WiFiState_e::AP_Fallback)) {
|
||||
@@ -355,7 +361,7 @@ void ESPEasyWiFi_t::setState(WiFiState_e newState, uint32_t timeout) {
|
||||
wifi_STA_data->mark_disconnected();
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
WiFi.disconnect();
|
||||
WiFi.disconnect(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -461,7 +467,7 @@ void ESPEasyWiFi_t::setState(WiFiState_e newState, uint32_t timeout) {
|
||||
/*
|
||||
if (Settings.UseRules)
|
||||
{
|
||||
eventQueue.add(F("WiFi#Connected"));
|
||||
eventQueue.addDeDup(F("WiFi#Connected"));
|
||||
}
|
||||
statusLED(true);
|
||||
*/
|
||||
@@ -469,6 +475,12 @@ void ESPEasyWiFi_t::setState(WiFiState_e newState, uint32_t timeout) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
auto wifi_STA_data = getWiFi_STA_NWPluginData_static_runtime();
|
||||
|
||||
if (wifi_STA_data) {
|
||||
wifi_STA_data->processEvents();
|
||||
}
|
||||
}
|
||||
|
||||
void ESPEasyWiFi_t::checkConnectProgress() {}
|
||||
@@ -536,7 +548,6 @@ bool ESPEasyWiFi_t::connectSTA()
|
||||
// WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
||||
# endif // if defined(ESP32)
|
||||
doSetConnectionSpeed();
|
||||
setupStaticIPconfig();
|
||||
|
||||
// Start the process of connecting or starting AP
|
||||
if (!WiFi_AP_Candidates.getNext(true))
|
||||
@@ -655,6 +666,16 @@ bool ESPEasyWiFi_t::shouldStartAP_fallback() const
|
||||
(_connect_attempt > Settings.ConnectFailRetryCount);
|
||||
}
|
||||
|
||||
bool ESPEasyWiFi_t::shouldRedirectTo_setup() const
|
||||
{
|
||||
if (!Settings.ApCaptivePortal()) return false;
|
||||
if (Settings.StartAPfallback_NoCredentials() && !SecuritySettings.hasWiFiCredentials()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !Settings.DoNotStartAPfallback_ConnectFail();
|
||||
}
|
||||
|
||||
} // namespace wifi
|
||||
} // namespace net
|
||||
} // namespace ESPEasy
|
||||
|
||||
@@ -100,6 +100,8 @@ public:
|
||||
|
||||
bool shouldStartAP_fallback() const;
|
||||
|
||||
bool shouldRedirectTo_setup() const;
|
||||
|
||||
private:
|
||||
|
||||
// WiFi_AP_Candidate _active_sta;
|
||||
|
||||
@@ -11,15 +11,15 @@
|
||||
# include "../../../src/Helpers/ESPEasy_time_calc.h"
|
||||
# include "../../../src/Helpers/StringConverter.h"
|
||||
|
||||
#if FEATURE_TASKVALUE_UNIT_OF_MEASURE
|
||||
# include "../../../src/Helpers/ESPEasy_UnitOfMeasure.h"
|
||||
#endif
|
||||
# if FEATURE_TASKVALUE_UNIT_OF_MEASURE
|
||||
# include "../../../src/Helpers/ESPEasy_UnitOfMeasure.h"
|
||||
# endif
|
||||
|
||||
#ifdef ESP8266
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
#include "../../../src/Helpers/StringGenerator_WiFi.h"
|
||||
#endif
|
||||
#endif
|
||||
# ifdef ESP8266
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
# include "../../../src/Helpers/StringGenerator_WiFi.h"
|
||||
# endif
|
||||
# endif // ifdef ESP8266
|
||||
|
||||
# ifdef ESP32
|
||||
# include <WiFiGeneric.h>
|
||||
@@ -39,6 +39,10 @@ extern "C" {
|
||||
# endif // ifdef ESP32
|
||||
|
||||
|
||||
# ifdef BOARD_HAS_SDIO_ESP_HOSTED
|
||||
# define MIN_REQUIRED_ESP_HOSTED_FW 0x00020600
|
||||
# endif
|
||||
|
||||
namespace ESPEasy {
|
||||
namespace net {
|
||||
namespace wifi {
|
||||
@@ -101,6 +105,34 @@ namespace wifi {
|
||||
- Connection stable (connected for > 5 minutes)
|
||||
|
||||
*/
|
||||
bool validWiFiSSID(const String& ssid) {
|
||||
// Can be any char upto 32 characters not being a null-char.
|
||||
// Some implementations, like Cisco, suggest some invalid characters:
|
||||
// - '+'
|
||||
// - ']'
|
||||
// - '/'
|
||||
// - '*'
|
||||
// - TAB
|
||||
// - Trailing spaces
|
||||
// And the first character cannot contain:
|
||||
// - '!'
|
||||
// - '#'
|
||||
// - ';'
|
||||
// Source: https://community.cisco.com/t5/networking-knowledge-base/characteristics-of-ssids/ta-p/3131765
|
||||
//
|
||||
// However this seems to be Cisco specific and not a limitation of the standard
|
||||
if (ssid.length() > 32) { return false; }
|
||||
|
||||
// "ssid" is an internal ESPEasy limitation, to signal an 'unset' value.
|
||||
return !ssid.isEmpty() && !ssid.equalsIgnoreCase(F("ssid"));
|
||||
}
|
||||
|
||||
bool validWiFiCredentials(const String& ssid, const String& pass) {
|
||||
if (!validWiFiSSID(ssid)) { return false; }
|
||||
const auto pass_length = pass.length();
|
||||
return (pass_length >= 8 && pass_length <= 63)
|
||||
|| pass_length == 0; // Empty password is possible
|
||||
}
|
||||
|
||||
// ********************************************************************************
|
||||
// Check WiFi connected status
|
||||
@@ -158,16 +190,19 @@ void resetWiFi() {
|
||||
*/
|
||||
}
|
||||
|
||||
void initWiFi() { ESPEasyWiFi.setup(); }
|
||||
void initWiFi() { ESPEasyWiFi.setup(); }
|
||||
|
||||
void exitWiFi() { ESPEasyWiFi.disable(); }
|
||||
|
||||
void loopWiFi() { ESPEasyWiFi.loop(); }
|
||||
|
||||
bool shouldStartAP_fallback() {
|
||||
return ESPEasyWiFi.shouldStartAP_fallback();
|
||||
void exitWiFi() {
|
||||
ESPEasyWiFi.disable();
|
||||
WiFi_AP_Candidates.force_reload();
|
||||
}
|
||||
|
||||
void loopWiFi() { ESPEasyWiFi.loop(); }
|
||||
|
||||
bool shouldStartAP_fallback() { return ESPEasyWiFi.shouldStartAP_fallback(); }
|
||||
|
||||
bool shouldRedirectTo_setup() { return ESPEasyWiFi.shouldRedirectTo_setup(); }
|
||||
|
||||
# ifdef BOARD_HAS_SDIO_ESP_HOSTED
|
||||
|
||||
// ********************************************************************************
|
||||
@@ -225,13 +260,14 @@ String GetHostedFwVersion(EspHostTypes hostType)
|
||||
String GetHostedMCU()
|
||||
{
|
||||
// Function is not yet implemented in Arduino Core so emulate it here
|
||||
#if defined(CONFIG_ESP_HOSTED_CP_TARGET_ESP32C6) && CONFIG_ESP_HOSTED_CP_TARGET_ESP32C6==1
|
||||
# if defined(CONFIG_ESP_HOSTED_CP_TARGET_ESP32C6) && CONFIG_ESP_HOSTED_CP_TARGET_ESP32C6 == 1
|
||||
return String("ESP32-C6");
|
||||
#else
|
||||
# else
|
||||
|
||||
if (equals(F(CONFIG_ESP_HOSTED_IDF_SLAVE_TARGET), F("esp32c6"))) {
|
||||
return String("ESP32-C6");
|
||||
}
|
||||
#endif
|
||||
# endif // if defined(CONFIG_ESP_HOSTED_CP_TARGET_ESP32C6) && CONFIG_ESP_HOSTED_CP_TARGET_ESP32C6 == 1
|
||||
return String("Unknown");
|
||||
}
|
||||
|
||||
@@ -309,9 +345,9 @@ bool write_WiFi_Hosted_MCU_pins(KeyValueWriter*writer)
|
||||
writer->write(kv);
|
||||
} else {
|
||||
KeyValueStruct freq(F("SDIO Freq"), psdio_config->clock_freq_khz / 1000);
|
||||
#if FEATURE_TASKVALUE_UNIT_OF_MEASURE
|
||||
# if FEATURE_TASKVALUE_UNIT_OF_MEASURE
|
||||
freq.setUnit(UOM_MHz);
|
||||
#endif
|
||||
# endif
|
||||
writer->write(freq);
|
||||
writer->write({ F("SDIO D0"), psdio_config->pin_d0.pin });
|
||||
writer->write({ F("SDIO D1"), psdio_config->pin_d1.pin });
|
||||
@@ -320,9 +356,10 @@ bool write_WiFi_Hosted_MCU_pins(KeyValueWriter*writer)
|
||||
writer->write({ F("SDIO CLK"), psdio_config->pin_clk.pin });
|
||||
writer->write({ F("SDIO CMD"), psdio_config->pin_cmd.pin });
|
||||
writer->write({ F("SDIO RST"), psdio_config->pin_reset.pin });
|
||||
|
||||
// Hide TX/RX queue size for now as it is unclear what these mean
|
||||
//writer->write({ F("SDIO TX queue"), psdio_config->tx_queue_size });
|
||||
//writer->write({ F("SDIO RX queue"), psdio_config->rx_queue_size });
|
||||
// writer->write({ F("SDIO TX queue"), psdio_config->tx_queue_size });
|
||||
// writer->write({ F("SDIO RX queue"), psdio_config->rx_queue_size });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -345,6 +382,12 @@ bool write_WiFi_Hosted_MCU_info(KeyValueWriter*writer)
|
||||
} else {
|
||||
writer->write({ F("ESP-Host Fw Version"), GetHostedFwVersion(EspHostTypes::ESP_HOST) });
|
||||
writer->write({ F("ESP-Hosted-MCU Fw Version"), GetHostedFwVersion(EspHostTypes::ESP_HOSTED) });
|
||||
if (GetHostedMCUFwVersion() < MIN_REQUIRED_ESP_HOSTED_FW) {
|
||||
writer->writeNote(F("ESP-Hosted-MCU firmware is too old, run <tt>wifiotahostedmcu</tt> via ESPEasy console"));
|
||||
} else if (hostedHasUpdate()) {
|
||||
writer->writeNote(F("ESP-Hosted-MCU firmware update available, run <tt>wifiotahostedmcu</tt> via ESPEasy console"));
|
||||
}
|
||||
|
||||
writer->write({ F("ESP-Hosted-MCU Chip"), GetHostedMCU() });
|
||||
writer->write({
|
||||
F("MAC"),
|
||||
@@ -471,37 +514,20 @@ bool wifiAPmodeActivelyUsed()
|
||||
// AP not active or soon to be disabled in processDisableAPmode()
|
||||
return false;
|
||||
}
|
||||
#ifdef BOARD_HAS_SDIO_ESP_HOSTED
|
||||
if (GetHostedMCUFwVersion() < MIN_REQUIRED_ESP_HOSTED_FW) {
|
||||
// Hosted fw is too old, function below is not yet implemented
|
||||
// When calling that function the ESP32-P4 will crash.
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return SOFTAP_STATION_COUNT != 0;
|
||||
|
||||
// FIXME TD-er: is effectively checking for AP active enough or must really check for connected clients to prevent automatic wifi
|
||||
// reconnect?
|
||||
}
|
||||
|
||||
void setupStaticIPconfig() {
|
||||
setUseStaticIP(WiFiUseStaticIP());
|
||||
|
||||
if (!WiFiUseStaticIP()) { return; }
|
||||
const IPAddress ip(Settings.IP);
|
||||
const IPAddress gw(Settings.Gateway);
|
||||
const IPAddress subnet(Settings.Subnet);
|
||||
const IPAddress dns(Settings.DNS);
|
||||
|
||||
// WiFiEventData.dns0_cache = dns;
|
||||
|
||||
WiFi.config(ip, gw, subnet, dns);
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
addLogMove(LOG_LEVEL_INFO, strformat(
|
||||
F("IP : Static IP : %s GW: %s SN: %s DNS: %s"),
|
||||
formatIP(ip).c_str(),
|
||||
formatIP(gw).c_str(),
|
||||
formatIP(subnet).c_str(),
|
||||
getValue(LabelType::DNS).c_str()));
|
||||
}
|
||||
# endif // ifndef BUILD_NO_DEBUG
|
||||
}
|
||||
|
||||
// ********************************************************************************
|
||||
// Formatting WiFi related strings
|
||||
// ********************************************************************************
|
||||
|
||||
@@ -36,10 +36,14 @@ namespace wifi {
|
||||
# else
|
||||
# define WIFI_CONNECTION_CONSIDERED_STABLE 60000 // in milliSeconds
|
||||
# endif // if FEATURE_CUSTOM_PROVISIONING
|
||||
# define WIFI_ALLOW_AP_AFTERBOOT_PERIOD 5 // in minutes
|
||||
//# define WIFI_ALLOW_AP_AFTERBOOT_PERIOD 5 // in minutes
|
||||
# define WIFI_SCAN_INTERVAL_AP_USED 125000 // in milliSeconds
|
||||
# define WIFI_SCAN_INTERVAL_MINIMAL 60000 // in milliSeconds
|
||||
|
||||
bool validWiFiSSID(const String& ssid);
|
||||
|
||||
bool validWiFiCredentials(const String& ssid, const String& pass);
|
||||
|
||||
|
||||
bool WiFiConnected();
|
||||
|
||||
@@ -52,6 +56,7 @@ void exitWiFi();
|
||||
void loopWiFi();
|
||||
|
||||
bool shouldStartAP_fallback();
|
||||
bool shouldRedirectTo_setup();
|
||||
|
||||
# ifdef BOARD_HAS_SDIO_ESP_HOSTED
|
||||
|
||||
@@ -108,7 +113,6 @@ bool setAPinternal(bool enable); // FIXME TD-er: Move to ESPEasyWifi_abstract
|
||||
void setUseStaticIP(bool enabled);
|
||||
bool WiFiUseStaticIP();
|
||||
bool wifiAPmodeActivelyUsed();
|
||||
void setupStaticIPconfig();
|
||||
String formatScanResult(int i,
|
||||
const String& separator);
|
||||
String formatScanResult(int i,
|
||||
|
||||
@@ -167,7 +167,15 @@ bool doSetAPinternal(bool enable)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Settings.ApCaptivePortal()) {
|
||||
if (ESPEasy::net::wifi::shouldRedirectTo_setup()) {
|
||||
# if FEATURE_DNS_SERVER
|
||||
|
||||
if (dnsServerActive) {
|
||||
dnsServerActive = false;
|
||||
dnsServer.stop();
|
||||
}
|
||||
# endif // if FEATURE_DNS_SERVER
|
||||
|
||||
# ifdef ESP32
|
||||
# if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2)
|
||||
|
||||
|
||||
@@ -47,7 +47,13 @@ bool WiFi_pre_STA_setup()
|
||||
void doWiFiDisconnect() {
|
||||
uint8_t retry = 3;
|
||||
|
||||
while (!WiFi.disconnect(Settings.WiFiRestart_connection_lost()) && retry) {
|
||||
#ifdef BOARD_HAS_SDIO_ESP_HOSTED
|
||||
bool wifioff = true;
|
||||
#else
|
||||
bool wifioff = Settings.WiFiRestart_connection_lost();
|
||||
#endif
|
||||
|
||||
while (!WiFi.disconnect(wifioff) && retry) {
|
||||
--retry;
|
||||
delay(100);
|
||||
}
|
||||
@@ -207,7 +213,7 @@ bool doSetWifiMode(WiFiMode_t new_mode)
|
||||
const bool new_mode_AP_enabled = doWifiIsAP(new_mode);
|
||||
|
||||
if (doWifiIsAP(cur_mode) && !new_mode_AP_enabled) {
|
||||
eventQueue.add(F("WiFi#APmodeDisabled"));
|
||||
eventQueue.addDeDup(F("WiFi#APmodeDisabled"));
|
||||
}
|
||||
|
||||
if (doWifiIsAP(cur_mode) != new_mode_AP_enabled) {
|
||||
|
||||
@@ -42,13 +42,16 @@ bool WiFi_pre_STA_setup() {
|
||||
void doWiFiDisconnect() {
|
||||
// Only call disconnect when STA is active
|
||||
if (doWifiIsSTA(WiFi.getMode())) {
|
||||
wifi_station_disconnect();
|
||||
WiFi.disconnect(true);
|
||||
// wifi_station_disconnect();
|
||||
}
|
||||
/*
|
||||
station_config conf{};
|
||||
memset(&conf, 0, sizeof(conf));
|
||||
ETS_UART_INTR_DISABLE();
|
||||
wifi_station_set_config_current(&conf);
|
||||
ETS_UART_INTR_ENABLE();
|
||||
*/
|
||||
}
|
||||
|
||||
bool doWifiIsAP(WiFiMode_t wifimode) { return (wifimode == WIFI_AP) || (wifimode == WIFI_AP_STA); }
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "../Globals/Settings.h"
|
||||
|
||||
#include "../Helpers/DeepSleep.h"
|
||||
#include "../Helpers/ESPEasy_Storage.h"
|
||||
#include "../Helpers/Misc.h"
|
||||
|
||||
const __FlashStringHelper * Command_System_NoSleep(struct EventStruct *event, const char* Line)
|
||||
|
||||
@@ -206,11 +206,21 @@ String Command_Wifi_OTA_hosted_mcu(
|
||||
return return_command_failed_flashstr();
|
||||
}
|
||||
|
||||
const String url = hostedGetUpdateURL();
|
||||
uint32_t major, minor, patch;
|
||||
hostedGetHostVersion(&major, &minor, &patch);
|
||||
|
||||
// https://pioarduino.github.io/esp-hosted-mcu-firmware/v2.12.7/network_adapter_esp32c6.bin
|
||||
const String url = strformat(
|
||||
F("https://pioarduino.github.io/esp-hosted-mcu-firmware/v%u.%u.%u/network_adapter_%s.bin"),
|
||||
major, minor, patch,
|
||||
CONFIG_ESP_HOSTED_IDF_SLAVE_TARGET);
|
||||
|
||||
|
||||
// Step 4: Begin the update process - display update URL
|
||||
addLog(LOG_LEVEL_INFO, concat(F("Updating esp-hosted co-processor from "), url));
|
||||
|
||||
processLogs();
|
||||
|
||||
/*
|
||||
// Step 5: Create a secure network client for HTTPS communication
|
||||
BearSSL::WiFiClientSecure_light secureClient(4096, 4096);
|
||||
@@ -264,6 +274,7 @@ String Command_Wifi_OTA_hosted_mcu(
|
||||
|
||||
// Step 11: Initialize the ESP-Hosted update process
|
||||
addLog(LOG_LEVEL_INFO, F("Beginning update process..."));
|
||||
processLogs();
|
||||
|
||||
// FIXME TD-er: Block actual update to see how far we get with making connection
|
||||
// goto finish_ota;
|
||||
@@ -343,6 +354,7 @@ String Command_Wifi_OTA_hosted_mcu(
|
||||
// Small delay to prevent overwhelming the system
|
||||
delay(1);
|
||||
}
|
||||
processLogs(true);
|
||||
|
||||
// Step 15: Clean up allocated buffer
|
||||
free(buff);
|
||||
@@ -352,6 +364,7 @@ String Command_Wifi_OTA_hosted_mcu(
|
||||
} else {
|
||||
addLog(LOG_LEVEL_ERROR, strformat(F("ERROR: HTTP request failed with code %d!"), httpCode));
|
||||
}
|
||||
processLogs(true);
|
||||
|
||||
// Step 16: Close HTTP connection
|
||||
https.end();
|
||||
@@ -361,6 +374,8 @@ finish_ota:
|
||||
// Step 17: Clean up network client
|
||||
// delete client;
|
||||
|
||||
processLogs(true);
|
||||
|
||||
if (updateSuccess) { return return_command_success_flashstr(); }
|
||||
return return_command_failed_flashstr();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(PLUGIN_BUILD_MAX32_ESP32) && !defined(PLUGIN_BUILD_MAX_ESP32)
|
||||
#define PLUGIN_BUILD_MAX_ESP32
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
#################################################
|
||||
This is the place where plugins are registered
|
||||
|
||||
@@ -33,6 +33,17 @@ void EventQueueStruct::add(const __FlashStringHelper *event, bool deduplicate)
|
||||
add(str, deduplicate);
|
||||
}
|
||||
|
||||
void EventQueueStruct::addDeDup(const String& event)
|
||||
{
|
||||
add(event, true);
|
||||
}
|
||||
|
||||
void EventQueueStruct::addDeDup(const __FlashStringHelper *event)
|
||||
{
|
||||
add(event, true);
|
||||
}
|
||||
|
||||
|
||||
void EventQueueStruct::addMove(String&& event, bool deduplicate)
|
||||
{
|
||||
if (!event.length()) { return; }
|
||||
|
||||
@@ -17,6 +17,11 @@ struct EventQueueStruct {
|
||||
void add(const __FlashStringHelper *event,
|
||||
bool deduplicate = false);
|
||||
|
||||
void addDeDup(const String& event);
|
||||
|
||||
void addDeDup(const __FlashStringHelper *event);
|
||||
|
||||
|
||||
void addMove(String&& event,
|
||||
bool deduplicate = false);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "../Globals/Settings.h"
|
||||
#include "../Helpers/ESPEasy_time_calc.h"
|
||||
#include "../Helpers/Misc.h"
|
||||
#include "../Helpers/Networking.h"
|
||||
#include "../Helpers/StringConverter.h"
|
||||
#include "../Helpers/StringGenerator_System.h"
|
||||
|
||||
@@ -503,7 +504,7 @@ void NodesHandler::updateThisNode() {
|
||||
thisNode.distance = _distance;
|
||||
|
||||
#if FEATURE_USE_IPV6
|
||||
thisNode.hasIPv4 = thisNode.IP() != INADDR_NONE;
|
||||
thisNode.hasIPv4 = IPAddressSet(thisNode.IP()) && thisNode.IP().type() == IPv4;
|
||||
thisNode.hasIPv6_mac_based_link_local = ESPEasy::net::is_IPv6_link_local_from_MAC(thisNode.sta_mac);
|
||||
thisNode.hasIPv6_mac_based_link_global = ESPEasy::net::is_IPv6_global_from_MAC(thisNode.sta_mac);
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "../Globals/SecuritySettings.h"
|
||||
|
||||
#include "../../ESPEasy/net/wifi/ESPEasyWifi.h"
|
||||
|
||||
|
||||
SecurityStruct::SecurityStruct() {
|
||||
ZERO_FILL(WifiSSID);
|
||||
@@ -90,10 +92,12 @@ bool SecurityStruct::hasWiFiCredentials() const {
|
||||
}
|
||||
|
||||
bool SecurityStruct::hasWiFiCredentials(SecurityStruct::WiFiCredentialsSlot slot) const {
|
||||
|
||||
|
||||
if (slot == SecurityStruct::WiFiCredentialsSlot::first)
|
||||
return (WifiSSID[0] != 0 && !String(WifiSSID).equalsIgnoreCase(F("ssid")));
|
||||
return ESPEasy::net::wifi::validWiFiSSID(WifiSSID);
|
||||
if (slot == SecurityStruct::WiFiCredentialsSlot::second)
|
||||
return (WifiSSID2[0] != 0 && !String(WifiSSID2).equalsIgnoreCase(F("ssid")));
|
||||
return ESPEasy::net::wifi::validWiFiSSID(WifiSSID2);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#if FEATURE_STORE_CREDENTIALS_SEPARATE_FILE
|
||||
|
||||
# include "../../ESPEasy/net/wifi/ESPEasyWifi.h"
|
||||
|
||||
int SecurityStruct_deviceSpecific::maxLength(KeyType keyType)
|
||||
{
|
||||
switch (keyType)
|
||||
@@ -75,19 +77,83 @@ bool SecurityStruct_deviceSpecific::hasWiFiCredentials() const
|
||||
{
|
||||
for (uint8_t i = 0; i < MAX_EXTRA_WIFI_CREDENTIALS_SEPARATE_FILE; ++i)
|
||||
{
|
||||
if (hasWiFiCredentials(i)) return true;
|
||||
if (hasWiFiCredentials(i)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SecurityStruct_deviceSpecific::hasWiFiCredentials(uint8_t index) const
|
||||
{
|
||||
if (index >= MAX_EXTRA_WIFI_CREDENTIALS_SEPARATE_FILE) { return false; }
|
||||
String ssid, pass;
|
||||
|
||||
if (!_kvs.getValue(createKey(KeyType::WiFi_SSID, index), ssid, KVS_StorageType::Enum::string_type) ||
|
||||
!_kvs.getValue(createKey(KeyType::WiFi_Password, index), pass, KVS_StorageType::Enum::string_type)) {
|
||||
return false;
|
||||
}
|
||||
return ESPEasy::net::wifi::validWiFiCredentials(ssid, pass);
|
||||
}
|
||||
|
||||
bool SecurityStruct_deviceSpecific::getWiFiCredentials(uint8_t index,
|
||||
String& ssid,
|
||||
String& passwd) const
|
||||
{
|
||||
return
|
||||
(index < MAX_EXTRA_WIFI_CREDENTIALS_SEPARATE_FILE) &&
|
||||
_kvs.hasKey(KVS_StorageType::Enum::string_type,
|
||||
createKey(KeyType::WiFi_SSID, index)) &&
|
||||
_kvs.hasKey(KVS_StorageType::Enum::string_type,
|
||||
createKey(KeyType::WiFi_Password, index));
|
||||
index < MAX_EXTRA_WIFI_CREDENTIALS_SEPARATE_FILE &&
|
||||
getCredentials(KeyType::WiFi_SSID, KeyType::WiFi_Password, index, ssid, passwd);
|
||||
}
|
||||
|
||||
void SecurityStruct_deviceSpecific::setWiFiCredentials(
|
||||
uint8_t index,
|
||||
const String& ssid,
|
||||
const String& passwd)
|
||||
{
|
||||
if (index < MAX_EXTRA_WIFI_CREDENTIALS_SEPARATE_FILE)
|
||||
{
|
||||
if (ESPEasy::net::wifi::validWiFiCredentials(ssid, passwd)) {
|
||||
setCredentials(
|
||||
KeyType::WiFi_SSID,
|
||||
KeyType::WiFi_Password,
|
||||
index,
|
||||
ssid,
|
||||
passwd);
|
||||
}
|
||||
else {
|
||||
_kvs.clearKey(
|
||||
KVS_StorageType::Enum::string_type,
|
||||
createKey(KeyType::WiFi_SSID, index));
|
||||
_kvs.clearKey(
|
||||
KVS_StorageType::Enum::string_type,
|
||||
createKey(KeyType::WiFi_Password, index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SecurityStruct_deviceSpecific::getControllerCredentials(uint8_t index,
|
||||
String& user,
|
||||
String& passwd) const
|
||||
{
|
||||
return
|
||||
(index < CONTROLLER_MAX) && getCredentials(
|
||||
KeyType::Controller_User,
|
||||
KeyType::Controller_Password,
|
||||
index,
|
||||
user,
|
||||
passwd);
|
||||
}
|
||||
|
||||
void SecurityStruct_deviceSpecific::setControllerCredentials(uint8_t index,
|
||||
const String& user,
|
||||
const String& passwd)
|
||||
{
|
||||
if (index < CONTROLLER_MAX) {
|
||||
setCredentials(
|
||||
KeyType::Controller_User,
|
||||
KeyType::Controller_Password,
|
||||
index,
|
||||
user,
|
||||
passwd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -103,12 +169,12 @@ bool SecurityStruct_deviceSpecific::hasWiFiCredentials(uint8_t index) const
|
||||
bool SecurityStruct_deviceSpecific::getValue(
|
||||
KeyType keytype, uint8_t index, String& value) const
|
||||
{
|
||||
return _kvs.getValue(createKey(keytype, index), value);
|
||||
return _kvs.getValue(createKey(keytype, index), value, KVS_StorageType::Enum::string_type);
|
||||
}
|
||||
|
||||
void SecurityStruct_deviceSpecific::setValue(KeyType keytype, uint8_t index, const String& value)
|
||||
{
|
||||
_kvs.setValue(createKey(keytype, index), value);
|
||||
_kvs.setValue(createKey(keytype, index), value, KVS_StorageType::Enum::string_type);
|
||||
}
|
||||
|
||||
uint32_t SecurityStruct_deviceSpecific::createKey(KeyType keytype, uint16_t index)
|
||||
@@ -123,8 +189,8 @@ bool SecurityStruct_deviceSpecific::getCredentials(KeyType keytype_key,
|
||||
String& secret) const
|
||||
{
|
||||
return
|
||||
_kvs.getValue(createKey(keytype_key, index), key) &&
|
||||
_kvs.getValue(createKey(keytype_secret, index), secret);
|
||||
_kvs.getValue(createKey(keytype_key, index), key, KVS_StorageType::Enum::string_type) &&
|
||||
_kvs.getValue(createKey(keytype_secret, index), secret, KVS_StorageType::Enum::string_type);
|
||||
}
|
||||
|
||||
void SecurityStruct_deviceSpecific::setCredentials(KeyType keytype_key,
|
||||
@@ -133,8 +199,8 @@ void SecurityStruct_deviceSpecific::setCredentials(KeyType keytype_key,
|
||||
const String& key,
|
||||
const String& secret)
|
||||
{
|
||||
_kvs.setValue(createKey(keytype_key, index), key);
|
||||
_kvs.setValue(createKey(keytype_secret, index), secret);
|
||||
_kvs.setValue(createKey(keytype_key, index), key, KVS_StorageType::Enum::string_type);
|
||||
_kvs.setValue(createKey(keytype_secret, index), secret, KVS_StorageType::Enum::string_type);
|
||||
}
|
||||
|
||||
#endif // if FEATURE_STORE_CREDENTIALS_SEPARATE_FILE
|
||||
|
||||
@@ -53,63 +53,29 @@ public:
|
||||
|
||||
// Move all set WiFi credentials to free up first entry
|
||||
// Typically used for setup page.
|
||||
// void freeUpFirstWiFiCredentials(uint8_t index = 0);
|
||||
// void freeUpFirstWiFiCredentials(uint8_t index = 0);
|
||||
|
||||
bool getWiFiCredentials(uint8_t index,
|
||||
String& ssid,
|
||||
String& passwd) const
|
||||
{
|
||||
return
|
||||
index < MAX_EXTRA_WIFI_CREDENTIALS_SEPARATE_FILE &&
|
||||
getCredentials(KeyType::WiFi_SSID, KeyType::WiFi_Password, index, ssid, passwd);
|
||||
}
|
||||
String& passwd) const;
|
||||
|
||||
void setWiFiCredentials(
|
||||
uint8_t index,
|
||||
const String& ssid,
|
||||
const String& passwd)
|
||||
{
|
||||
if (index < MAX_EXTRA_WIFI_CREDENTIALS_SEPARATE_FILE)
|
||||
{
|
||||
setCredentials(
|
||||
KeyType::WiFi_SSID,
|
||||
KeyType::WiFi_Password,
|
||||
index,
|
||||
ssid,
|
||||
passwd);
|
||||
}
|
||||
}
|
||||
const String& passwd);
|
||||
|
||||
bool getControllerCredentials(uint8_t index,
|
||||
String& user,
|
||||
String& passwd) const
|
||||
{
|
||||
return
|
||||
(index < CONTROLLER_MAX) && getCredentials(
|
||||
KeyType::Controller_User,
|
||||
KeyType::Controller_Password,
|
||||
index,
|
||||
user,
|
||||
passwd);
|
||||
}
|
||||
String& passwd) const;
|
||||
|
||||
void setControllerCredentials(uint8_t index,
|
||||
const String& user,
|
||||
const String& passwd)
|
||||
{
|
||||
if (index < CONTROLLER_MAX) {
|
||||
setCredentials(
|
||||
KeyType::Controller_User,
|
||||
KeyType::Controller_Password,
|
||||
index,
|
||||
user,
|
||||
passwd);
|
||||
}
|
||||
}
|
||||
const String& passwd);
|
||||
|
||||
bool getValue(KeyType keytype,
|
||||
uint8_t index,
|
||||
String& value) const;
|
||||
|
||||
void setValue(KeyType keytype,
|
||||
uint8_t index,
|
||||
const String& value);
|
||||
|
||||
@@ -29,6 +29,7 @@ size_t KVS_StorageType::getStorageSizePerType(KVS_StorageType::Enum storageType)
|
||||
{
|
||||
case KVS_StorageType::Enum::not_set: break;
|
||||
case KVS_StorageType::Enum::string_type: break;
|
||||
case KVS_StorageType::Enum::ip_type: break;
|
||||
case KVS_StorageType::Enum::int8_type: return 4 + 1;
|
||||
case KVS_StorageType::Enum::uint8_type: return 4 + 1;
|
||||
case KVS_StorageType::Enum::int16_type: return 4 + 2;
|
||||
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
float_type = 10,
|
||||
double_type = 11,
|
||||
bool_type = 12,
|
||||
ip_type = 13,
|
||||
|
||||
MAX_Type, // Leave this one after the generic type and before 'special' types
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#ifdef ESP32
|
||||
|
||||
# include "../Helpers/StringConverter.h"
|
||||
# include "../Helpers/Networking.h"
|
||||
|
||||
# include <esp_netif.h>
|
||||
|
||||
@@ -154,7 +155,7 @@ bool NWPlugin::get_subnet(NWPlugin::IP_type ip_type, NetworkInterface*networkInt
|
||||
if (!networkInterface) { return false; }
|
||||
IPAddress ip = get_IP_address(ip_type, networkInterface);
|
||||
|
||||
if (ip == INADDR_NONE) { return false; }
|
||||
if (!IPAddressSet(ip)) { return false; }
|
||||
|
||||
# if CONFIG_LWIP_IPV6
|
||||
|
||||
|
||||
@@ -127,8 +127,6 @@ void EspEasy_Console_t::reInit()
|
||||
|
||||
if (!mustHaveFallback) {
|
||||
if (_fallbackSerial._serial != nullptr) {
|
||||
_fallbackSerial._serial->flush();
|
||||
_fallbackSerial._serial->end();
|
||||
delete _fallbackSerial._serial;
|
||||
_fallbackSerial._serial = nullptr;
|
||||
somethingChanged = true;
|
||||
@@ -142,8 +140,6 @@ void EspEasy_Console_t::reInit()
|
||||
(_console_serial_txpin != Settings.console_serial_txpin) ||
|
||||
!mustHaveSerial) {
|
||||
if (_mainSerial._serial != nullptr) {
|
||||
_mainSerial._serial->flush();
|
||||
_mainSerial._serial->end();
|
||||
delete _mainSerial._serial;
|
||||
_mainSerial._serial = nullptr;
|
||||
somethingChanged = true;
|
||||
@@ -444,13 +440,3 @@ void EspEasy_Console_t::endPort()
|
||||
#endif // if USES_ESPEASY_CONSOLE_FALLBACK_PORT
|
||||
delay(10);
|
||||
}
|
||||
|
||||
int EspEasy_Console_t::availableForWrite()
|
||||
{
|
||||
auto serial = getPort();
|
||||
|
||||
if (serial != nullptr) {
|
||||
return serial->availableForWrite();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -47,8 +47,6 @@ private:
|
||||
|
||||
void endPort();
|
||||
|
||||
int availableForWrite();
|
||||
|
||||
uint32_t _baudrate = 115200u;
|
||||
EspEasy_Console_Port _mainSerial;
|
||||
|
||||
|
||||
@@ -148,6 +148,10 @@ bool EspEasy_Console_Port::process_serialWriteBuffer()
|
||||
|
||||
bool EspEasy_Console_Port::process_consoleInput(uint8_t SerialInByte)
|
||||
{
|
||||
if (!InputBuffer_Serial) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isprint(SerialInByte))
|
||||
{
|
||||
if (SerialInByteCounter < CONSOLE_INPUT_BUFFER_SIZE) { // add char to string if it still fits
|
||||
@@ -163,14 +167,16 @@ bool EspEasy_Console_Port::process_consoleInput(uint8_t SerialInByte)
|
||||
{
|
||||
// Ignore empty command
|
||||
if (SerialInByteCounter != 0) {
|
||||
InputBuffer_Serial[SerialInByteCounter] = 0; // serial data completed
|
||||
if (SerialInByteCounter < CONSOLE_INPUT_BUFFER_SIZE) {
|
||||
InputBuffer_Serial[SerialInByteCounter] = 0; // serial data completed
|
||||
|
||||
String cmd(InputBuffer_Serial);
|
||||
String cmd(InputBuffer_Serial);
|
||||
#if !FEATURE_COLORIZE_CONSOLE_LOGS
|
||||
Logging.consolePrintln(concat('>', cmd));
|
||||
Logging.consolePrintln(concat('>', cmd));
|
||||
#endif
|
||||
|
||||
ExecuteCommand_all({ EventValueSource::Enum::VALUE_SOURCE_SERIAL, std::move(cmd) }, true);
|
||||
ExecuteCommand_all({ EventValueSource::Enum::VALUE_SOURCE_SERIAL, std::move(cmd) }, true);
|
||||
}
|
||||
SerialInByteCounter = 0;
|
||||
InputBuffer_Serial[0] = 0; // serial data processed, clear buffer
|
||||
return true;
|
||||
|
||||
@@ -219,6 +219,7 @@ void addLog(uint8_t logLevel, const __FlashStringHelper *str)
|
||||
}
|
||||
#endif // ifdef ESP32
|
||||
Logging.addLogEntry(LogEntry_t(logLevel, str));
|
||||
processLogs();
|
||||
}
|
||||
|
||||
void addLog(uint8_t logLevel, const char *line) {
|
||||
@@ -233,6 +234,7 @@ void addLog(uint8_t logLevel, const char *line) {
|
||||
}
|
||||
#endif // ifdef ESP32
|
||||
Logging.addLogEntry(LogEntry_t(logLevel, line));
|
||||
processLogs();
|
||||
}
|
||||
|
||||
void addLog(uint8_t logLevel, String&& str) { addToLogMove(logLevel, std::move(str)); }
|
||||
@@ -250,6 +252,7 @@ void addLog(uint8_t logLevel, const String& str)
|
||||
}
|
||||
#endif // ifdef ESP32
|
||||
Logging.addLogEntry(LogEntry_t(logLevel, str));
|
||||
processLogs();
|
||||
}
|
||||
|
||||
void addToLogMove(uint8_t logLevel, String&& str)
|
||||
@@ -265,4 +268,16 @@ void addToLogMove(uint8_t logLevel, String&& str)
|
||||
}
|
||||
#endif // ifdef ESP32
|
||||
Logging.addLogEntry(LogEntry_t(logLevel, std::move(str)));
|
||||
processLogs();
|
||||
}
|
||||
|
||||
void processLogs(bool serialOnly)
|
||||
{
|
||||
process_serialWriteBuffer();
|
||||
Logging.loop(serialOnly);
|
||||
#if FEATURE_SYSLOG
|
||||
if (!serialOnly) {
|
||||
syslogWriter.process();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -47,3 +47,7 @@ void addLog(uint8_t logLevel,
|
||||
|
||||
void addToLogMove(uint8_t logLevel,
|
||||
String&& str);
|
||||
|
||||
|
||||
void processLogs(bool serialOnly = false);
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
* run background tasks
|
||||
\*********************************************************************************************/
|
||||
bool runningBackgroundTasks = false;
|
||||
|
||||
void backgroundtasks()
|
||||
{
|
||||
// checkRAM(F("backgroundtasks"));
|
||||
@@ -74,11 +75,8 @@ void backgroundtasks()
|
||||
}
|
||||
*/
|
||||
|
||||
process_serialWriteBuffer();
|
||||
#if FEATURE_SYSLOG
|
||||
syslogWriter.process();
|
||||
#endif
|
||||
Logging.loop();
|
||||
|
||||
processLogs();
|
||||
|
||||
if (!UseRTOSMultitasking) {
|
||||
serial();
|
||||
|
||||
@@ -582,7 +582,9 @@ void fileSystemCheck()
|
||||
#ifndef BUILD_NO_RAM_TRACKER
|
||||
checkRAM(F("fileSystemCheck"));
|
||||
#endif // ifndef BUILD_NO_RAM_TRACKER
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
addLog(LOG_LEVEL_INFO, F("FS : Mounting..."));
|
||||
#endif
|
||||
#if defined(ESP32) && defined(USE_LITTLEFS)
|
||||
|
||||
if ((getPartionCount(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS) != 0)
|
||||
@@ -593,7 +595,7 @@ void fileSystemCheck()
|
||||
#endif // if defined(ESP32) && defined(USE_LITTLEFS)
|
||||
{
|
||||
clearAllCaches();
|
||||
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
addLogMove(LOG_LEVEL_INFO, strformat(
|
||||
F("FS : "
|
||||
@@ -605,6 +607,7 @@ void fileSystemCheck()
|
||||
" mount successful, used %u bytes of %u"),
|
||||
SpiffsUsedBytes(), SpiffsTotalBytes()));
|
||||
}
|
||||
# endif
|
||||
|
||||
// Run garbage collection before any file is open.
|
||||
uint8_t retries = 3;
|
||||
@@ -711,7 +714,7 @@ bool Erase_WiFi_Calibration() {
|
||||
ESPEasy::net::wifi::setWifiMode(WIFI_OFF);
|
||||
if (!ESP.eraseConfig())
|
||||
return false;
|
||||
#ifndef LIMIT_BUILD_SIZE
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : Erased WiFi calibration data"));
|
||||
#endif
|
||||
#endif
|
||||
@@ -991,7 +994,7 @@ void afterloadSettings() {
|
||||
#ifdef ESP32
|
||||
// FIXME TD-er: Must also update hostname on other interfaces for ESP32
|
||||
#endif
|
||||
ESPEasy::net::CheckRunningServices(); // To update changes in hostname.
|
||||
ESPEasy::net::CheckRunningServices(true); // To update changes in hostname.
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
@@ -1064,8 +1067,6 @@ String LoadSettings()
|
||||
SecuritySettings_deviceSpecific.load();
|
||||
#endif
|
||||
|
||||
|
||||
// setupStaticIPconfig();
|
||||
// FIXME TD-er: Must check if static/dynamic IP was changed and trigger a reconnect? Or is a reboot better when changing those settings?
|
||||
afterloadSettings();
|
||||
SecuritySettings.validate();
|
||||
@@ -1446,7 +1447,7 @@ String SaveTaskSettings(taskIndex_t TaskIndex)
|
||||
reinterpret_cast<const uint8_t *>(&ExtraTaskSettings),
|
||||
sizeof(struct ExtraTaskSettingsStruct));
|
||||
|
||||
#ifndef LIMIT_BUILD_SIZE
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
if (err.isEmpty()) {
|
||||
err = checkTaskSettings(TaskIndex);
|
||||
}
|
||||
@@ -1455,7 +1456,7 @@ String SaveTaskSettings(taskIndex_t TaskIndex)
|
||||
// FIXME TD-er: Is this still needed as it is also cleared on PLUGIN_INIT and PLUGIN_EXIT?
|
||||
UserVar.clear_computed(ExtraTaskSettings.TaskIndex);
|
||||
}
|
||||
#ifndef LIMIT_BUILD_SIZE
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
else {
|
||||
addLog(LOG_LEVEL_INFO, F("Skip saving task settings, not changed"));
|
||||
}
|
||||
|
||||
@@ -140,8 +140,8 @@ uint32_t getFlashRealSizeInBytes() {
|
||||
if (res == 0) {
|
||||
#if defined(ESP32)
|
||||
#ifdef ESP32P4
|
||||
// TODO TD-er: Implement
|
||||
res = 1 << 24;
|
||||
const int32_t flash_cap_MB = getEmbeddedFlashSize();
|
||||
res = flash_cap_MB << 20;
|
||||
#else
|
||||
res = (1 << ((getFlashChipId() >> 16) & 0xFF));
|
||||
#endif
|
||||
|
||||
@@ -118,7 +118,8 @@ size_t LogStreamWriter::write_part(String& str, Print& stream, size_t nrBytesTo
|
||||
const size_t bytesLeft = str.length() - _readpos;
|
||||
bytesWritten = stream.write(&str[_readpos], bytesLeft);
|
||||
_readpos += bytesWritten;
|
||||
} else {
|
||||
}
|
||||
if (_readpos >= str.length()) {
|
||||
// Clear str
|
||||
str.clear();
|
||||
_readpos = 0;
|
||||
|
||||
@@ -52,7 +52,7 @@ void LogHelper::addLogEntry(LogEntry_t&& logEntry)
|
||||
|
||||
_logBuffer.add(std::move(logEntry));
|
||||
|
||||
loop();
|
||||
loop(false);
|
||||
}
|
||||
|
||||
bool LogHelper::getNext(LogDestination logDestination, uint32_t& timestamp, String& message, uint8_t& loglevel)
|
||||
@@ -65,9 +65,10 @@ uint32_t LogHelper::getNrMessages(LogDestination logDestination) const
|
||||
return _logBuffer.getNrMessages(logDestination);
|
||||
}
|
||||
|
||||
void LogHelper::loop()
|
||||
void LogHelper::loop(bool serialOnly)
|
||||
{
|
||||
#if FEATURE_SD
|
||||
if (!serialOnly) {
|
||||
String message;
|
||||
uint32_t timestamp{};
|
||||
uint8_t loglevel{};
|
||||
@@ -76,6 +77,7 @@ void LogHelper::loop()
|
||||
{
|
||||
addToSDLog(loglevel, message);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
_logBuffer.clearExpiredEntries();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
|
||||
uint32_t getNrMessages(LogDestination logDestination) const;
|
||||
|
||||
void loop();
|
||||
void loop(bool serialOnly);
|
||||
|
||||
bool logActiveRead(LogDestination logDestination);
|
||||
|
||||
|
||||
@@ -9,6 +9,12 @@ void LongTermOnOffTimer::clear()
|
||||
resetCount();
|
||||
}
|
||||
|
||||
void LongTermOnOffTimer::reset()
|
||||
{
|
||||
clear();
|
||||
_changedSinceLastCheck = false;
|
||||
}
|
||||
|
||||
bool LongTermOnOffTimer::setOn()
|
||||
{
|
||||
if (isOn()) { return false; }
|
||||
@@ -43,7 +49,12 @@ bool LongTermOnOffTimer::set(bool onState)
|
||||
|
||||
bool LongTermOnOffTimer::forceSet(bool onState)
|
||||
{
|
||||
set(!onState);
|
||||
/*
|
||||
// TODO TD-er: Should we also change the timestamp?
|
||||
if (onState) _onTimer.setNow();
|
||||
else _offTimer.setNow();
|
||||
*/
|
||||
_changedSinceLastCheck = true;
|
||||
return set(onState);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,14 @@ class LongTermOnOffTimer
|
||||
{
|
||||
public:
|
||||
|
||||
// Clear all timers and counts
|
||||
// _changedSinceLastCheck will be set when values were set before calling clear()
|
||||
void clear();
|
||||
|
||||
// Reset to default
|
||||
// _changedSinceLastCheck is also set to false
|
||||
void reset();
|
||||
|
||||
void resetCount() { _changeToOffCount = 0; _changeToOnCount = 0; }
|
||||
|
||||
// Return true when state changed
|
||||
|
||||
@@ -167,7 +167,7 @@ void updateUDPport(bool force)
|
||||
// Or we may need to look into AsyncUDP as that allows to send to specific interfaces.
|
||||
const bool connected = ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_WEBSERVER_SHOULD_RUN);
|
||||
//const bool connected = ESPEasy::net::NetworkConnected();
|
||||
if (!connected || lastUsedUDPPort != 0) {
|
||||
if (!connected || (Settings.UDPPort != lastUsedUDPPort)) {
|
||||
if (lastUsedUDPPort != 0) {
|
||||
portUDP.stop();
|
||||
lastUsedUDPPort = 0;
|
||||
@@ -180,7 +180,7 @@ void updateUDPport(bool force)
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.UDPPort != 0) {
|
||||
if ((Settings.UDPPort != lastUsedUDPPort) && Settings.UDPPort != 0) {
|
||||
if (portUDP.begin(Settings.UDPPort) == 0) {
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
|
||||
@@ -1124,6 +1124,24 @@ void scrubDNS() {
|
||||
*/
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
bool IPAddressSet(const IPAddress& ip)
|
||||
{
|
||||
return !(ip == INADDR_NONE
|
||||
# if CONFIG_LWIP_IPV6
|
||||
|| ip == IN6ADDR_ANY
|
||||
# endif
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
bool IPAddressSet(const IPAddress& ip)
|
||||
{
|
||||
return !(ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool valid_DNS_address(const IPAddress& dns) {
|
||||
return /*dns.v4() != (uint32_t)0x00000000 && */
|
||||
dns != IPAddress((uint32_t)0xFD000000) &&
|
||||
@@ -1133,7 +1151,7 @@ bool valid_DNS_address(const IPAddress& dns) {
|
||||
// Global IPv6 prefixes currently start with 2xxx::
|
||||
(dns[0] & 0xF0) != 0x20 &&
|
||||
#endif // ifdef ESP32
|
||||
dns != INADDR_NONE;
|
||||
IPAddressSet(dns);
|
||||
}
|
||||
|
||||
bool setDNS(int index, const IPAddress& dns) {
|
||||
|
||||
@@ -196,6 +196,8 @@ bool connectClient(WiFiClient& client, IPAddress ip, uint16_t port, uint32_t tim
|
||||
|
||||
void scrubDNS();
|
||||
|
||||
bool IPAddressSet(const IPAddress& ip);
|
||||
|
||||
bool valid_DNS_address(const IPAddress& dns);
|
||||
|
||||
bool setDNS(int index, const IPAddress& dns);
|
||||
|
||||
@@ -43,7 +43,8 @@ void ESPEasy_Scheduler::setNetworkTimer(unsigned long msecFromNow
|
||||
{
|
||||
if (!validNetworkIndex(networkIndex)) { return; }
|
||||
|
||||
if (!Settings.getNetworkEnabled(networkIndex)) { return; }
|
||||
if (function != NWPlugin::Function::NWPLUGIN_EXIT &&
|
||||
!Settings.getNetworkEnabled(networkIndex)) { return; }
|
||||
|
||||
const NWPluginTimerID timerID(networkIndex, Par1, function);
|
||||
|
||||
|
||||
@@ -407,7 +407,7 @@ KeyValueStruct getKeyValue(LabelType::Enum label, bool extendedValue)
|
||||
}
|
||||
case LabelType::ENABLE_SERIAL_PORT_CONSOLE:
|
||||
{
|
||||
return KeyValueStruct(F("Enable Serial Port Console"), !!Settings.UseSerial);
|
||||
return KeyValueStruct(F("Enable Serial Port Console"), !!Settings.UseSerial); // Cast to bool to make sure it is shown as a checkmark
|
||||
}
|
||||
case LabelType::CONSOLE_SERIAL_PORT:
|
||||
{
|
||||
@@ -416,7 +416,7 @@ KeyValueStruct getKeyValue(LabelType::Enum label, bool extendedValue)
|
||||
#if USES_ESPEASY_CONSOLE_FALLBACK_PORT
|
||||
case LabelType::CONSOLE_FALLBACK_TO_SERIAL0:
|
||||
{
|
||||
return KeyValueStruct(F("Fallback to Serial 0"), Settings.console_serial0_fallback);
|
||||
return KeyValueStruct(F("Fallback to Serial 0"), !!Settings.console_serial0_fallback); // Cast to bool to make sure it is shown as a checkmark
|
||||
}
|
||||
case LabelType::CONSOLE_FALLBACK_PORT:
|
||||
{
|
||||
@@ -752,7 +752,10 @@ KeyValueStruct getKeyValue(LabelType::Enum label, bool extendedValue)
|
||||
}
|
||||
case LabelType::RESTART_WIFI_LOST_CONN:
|
||||
{
|
||||
#ifndef BOARD_HAS_SDIO_ESP_HOSTED
|
||||
// Disable option for ESP-hosted WiFi as this always needs to restart when forcing disconnect.
|
||||
return KeyValueStruct(F("Restart WiFi Lost Conn"), Settings.WiFiRestart_connection_lost());
|
||||
#endif
|
||||
}
|
||||
case LabelType::FORCE_WIFI_NOSLEEP:
|
||||
{
|
||||
@@ -1041,10 +1044,19 @@ KeyValueStruct getKeyValue(LabelType::Enum label, bool extendedValue)
|
||||
uint32_t maxSketchSize;
|
||||
bool use2step;
|
||||
OTA_possible(maxSketchSize, use2step);
|
||||
str += strformat(
|
||||
F("%d [kB] (%d kB not used)"),
|
||||
(getSketchSize() >> 10),
|
||||
(maxSketchSize - getSketchSize()) >> 10);
|
||||
const uint32_t sketchsize_kB = getSketchSize() >> 10;
|
||||
maxSketchSize >>= 10;
|
||||
|
||||
if (maxSketchSize >= sketchsize_kB)
|
||||
str += strformat(
|
||||
F("%d [kB] (%d kB not used)"),
|
||||
sketchsize_kB,
|
||||
(maxSketchSize - sketchsize_kB));
|
||||
else
|
||||
str += strformat(
|
||||
F("%d [kB]"),
|
||||
sketchsize_kB);
|
||||
|
||||
} else {
|
||||
str = (getSketchSize() >> 10);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# include "../Helpers/KeyValueWriter.h"
|
||||
# include "../Helpers/StringConverter.h"
|
||||
# include "../Helpers/StringConverter_Numerical.h"
|
||||
|
||||
# include "../Helpers/Networking.h"
|
||||
|
||||
bool ESPEasy_key_value_store::isEmpty() const
|
||||
{
|
||||
@@ -138,7 +138,7 @@ bool ESPEasy_key_value_store::load(
|
||||
sizePerType = KVS_StorageType::getStorageSizePerType(storageType);
|
||||
key = KVS_StorageType::getKey_from_combined_key(combined_key.getUint32());
|
||||
|
||||
if ((sizePerType < 4) && (storageType != KVS_StorageType::Enum::string_type)) {
|
||||
if ((sizePerType < 4) && ((storageType != KVS_StorageType::Enum::string_type) && (storageType != KVS_StorageType::Enum::ip_type))) {
|
||||
// Should not happen as those should not be stored in the file
|
||||
_state = State::ErrorOnLoad;
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
@@ -165,6 +165,7 @@ bool ESPEasy_key_value_store::load(
|
||||
}
|
||||
|
||||
case KVS_StorageType::Enum::string_type:
|
||||
case KVS_StorageType::Enum::ip_type:
|
||||
{
|
||||
if (bytesLeftPartialString == 0) {
|
||||
// Found new string type
|
||||
@@ -211,7 +212,7 @@ bool ESPEasy_key_value_store::load(
|
||||
}
|
||||
|
||||
if ((bytesLeftPartialString == 0) && (partialString.length() > 0)) {
|
||||
setValue(key, std::move(partialString));
|
||||
setValue(key, std::move(partialString), storageType);
|
||||
partialString.clear();
|
||||
|
||||
// ++bufPos; // Skip over nul-termination char
|
||||
@@ -427,10 +428,10 @@ bool ESPEasy_key_value_store::store(
|
||||
|
||||
} else if (it_4byte != _4byte_data.end()) {
|
||||
// Write 4-byte data
|
||||
uint32_t combined_key = it_4byte->first;
|
||||
uint32_t combined_key = it_4byte->first;
|
||||
KVS_StorageType::Enum storageType = KVS_StorageType::get_StorageType_from_combined_key(combined_key);
|
||||
const uint32_t key = KVS_StorageType::getKey_from_combined_key(combined_key);
|
||||
const size_t sizePerType = KVS_StorageType::getStorageSizePerType(storageType);
|
||||
const uint32_t key = KVS_StorageType::getKey_from_combined_key(combined_key);
|
||||
const size_t sizePerType = KVS_StorageType::getStorageSizePerType(storageType);
|
||||
|
||||
if (sizePerType >= 4) {
|
||||
if ((buffer.size() - bufPos) < sizePerType) {
|
||||
@@ -552,7 +553,7 @@ bool ESPEasy_key_value_store::hasKey(KVS_StorageType::Enum storageType, uint32_t
|
||||
|
||||
const uint32_t combined_key = KVS_StorageType::combine_StorageType_and_key(storageType, key);
|
||||
|
||||
if (storageType == KVS_StorageType::Enum::string_type)
|
||||
if ((storageType == KVS_StorageType::Enum::string_type) || (storageType == KVS_StorageType::Enum::ip_type))
|
||||
{
|
||||
return _string_data.find(combined_key) != _string_data.end();
|
||||
}
|
||||
@@ -569,6 +570,46 @@ bool ESPEasy_key_value_store::hasKey(KVS_StorageType::Enum storageType, uint32_t
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ESPEasy_key_value_store::clearKey(KVS_StorageType::Enum storageType, uint32_t key)
|
||||
{
|
||||
if (!hasKey(storageType, key)) { return false; }
|
||||
|
||||
const uint32_t combined_key = KVS_StorageType::combine_StorageType_and_key(storageType, key);
|
||||
|
||||
if ((storageType == KVS_StorageType::Enum::string_type) || (storageType == KVS_StorageType::Enum::ip_type))
|
||||
{
|
||||
auto it = _string_data.find(combined_key);
|
||||
|
||||
if (it != _string_data.end()) {
|
||||
_state = State::Changed;
|
||||
_string_data.erase(it);
|
||||
updateHasStorageType(storageType);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const size_t size = KVS_StorageType::getStorageSizePerType(storageType);
|
||||
|
||||
if (size == 12)
|
||||
{
|
||||
auto it = _8byte_data.find(combined_key);
|
||||
|
||||
if (it != _8byte_data.end()) {
|
||||
_state = State::Changed;
|
||||
_8byte_data.erase(it);
|
||||
updateHasStorageType(storageType);
|
||||
}
|
||||
} else if (size >= 4) {
|
||||
auto it = _4byte_data.find(combined_key);
|
||||
|
||||
if (it != _4byte_data.end()) {
|
||||
_state = State::Changed;
|
||||
_4byte_data.erase(it);
|
||||
updateHasStorageType(storageType);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
KVS_StorageType::Enum ESPEasy_key_value_store::getStorageType(uint32_t key) const
|
||||
{
|
||||
uint32_t cached_bitmap = _storage_type_present_cache;
|
||||
@@ -586,21 +627,26 @@ KVS_StorageType::Enum ESPEasy_key_value_store::getStorageType(uint32_t key) cons
|
||||
}
|
||||
return KVS_StorageType::Enum::not_set;
|
||||
}
|
||||
#define KVS_STRINGPAIR_SEPARATOR ((char)1)
|
||||
|
||||
# define KVS_STRINGPAIR_SEPARATOR ((char)1)
|
||||
|
||||
bool ESPEasy_key_value_store::getValue(uint32_t key, StringPair& stringPair) const
|
||||
{
|
||||
String str;
|
||||
if (!getValue(key, str)) {
|
||||
|
||||
if (!getValue(key, str, KVS_StorageType::Enum::string_type)) {
|
||||
return false;
|
||||
}
|
||||
const int separatorPos = str.indexOf(KVS_STRINGPAIR_SEPARATOR);
|
||||
if (separatorPos < 0) return false;
|
||||
stringPair.first = str.substring(0, separatorPos);
|
||||
|
||||
if (separatorPos < 0) { return false; }
|
||||
stringPair.first = str.substring(0, separatorPos);
|
||||
stringPair.second = str.substring(separatorPos + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ESPEasy_key_value_store::setValue(uint32_t key, const StringPair& stringPair)
|
||||
void ESPEasy_key_value_store::setValue(
|
||||
uint32_t key, const StringPair& stringPair)
|
||||
{
|
||||
String str;
|
||||
str.reserve(stringPair.first.length() + 1 + stringPair.second.length());
|
||||
@@ -609,12 +655,14 @@ void ESPEasy_key_value_store::setValue(uint32_t key, const StringPair& stringPai
|
||||
str += stringPair.second;
|
||||
setValue(key, str);
|
||||
}
|
||||
#undef KVS_STRINGPAIR_SEPARATOR
|
||||
|
||||
bool ESPEasy_key_value_store::getValue(uint32_t key, String& value) const
|
||||
# undef KVS_STRINGPAIR_SEPARATOR
|
||||
|
||||
bool ESPEasy_key_value_store::getValue(
|
||||
uint32_t key, String& value, KVS_StorageType::Enum storageType) const
|
||||
{
|
||||
const uint32_t combined_key = KVS_StorageType::combine_StorageType_and_key(
|
||||
KVS_StorageType::Enum::string_type,
|
||||
storageType,
|
||||
key);
|
||||
|
||||
auto it = _string_data.find(combined_key);
|
||||
@@ -624,15 +672,20 @@ bool ESPEasy_key_value_store::getValue(uint32_t key, String& value) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void ESPEasy_key_value_store::setValue(uint32_t key, const String& value) { setValue(key, String(value)); }
|
||||
void ESPEasy_key_value_store::setValue(
|
||||
uint32_t key, const String& value,
|
||||
KVS_StorageType::Enum storageType) { setValue(key, String(value), storageType); }
|
||||
|
||||
void ESPEasy_key_value_store::setValue(uint32_t key,
|
||||
const __FlashStringHelper*value) { setValue(key, String(value)); }
|
||||
void ESPEasy_key_value_store::setValue(
|
||||
uint32_t key,
|
||||
const __FlashStringHelper*value,
|
||||
KVS_StorageType::Enum storageType) { setValue(key, String(value), storageType); }
|
||||
|
||||
void ESPEasy_key_value_store::setValue(uint32_t key, String&& value)
|
||||
void ESPEasy_key_value_store::setValue(
|
||||
uint32_t key, String&& value, KVS_StorageType::Enum storageType)
|
||||
{
|
||||
const uint32_t combined_key = KVS_StorageType::combine_StorageType_and_key(
|
||||
KVS_StorageType::Enum::string_type,
|
||||
storageType,
|
||||
key);
|
||||
auto it = _string_data.find(combined_key);
|
||||
|
||||
@@ -646,12 +699,26 @@ void ESPEasy_key_value_store::setValue(uint32_t key, String&& value)
|
||||
_state = State::Changed;
|
||||
}
|
||||
}
|
||||
setHasStorageType(KVS_StorageType::Enum::string_type);
|
||||
setHasStorageType(storageType);
|
||||
}
|
||||
|
||||
bool ESPEasy_key_value_store::getValue(uint32_t key, IPAddress& value) const
|
||||
{
|
||||
String ip_str;
|
||||
|
||||
if (!getValue(key, ip_str, KVS_StorageType::Enum::ip_type)) { return false; }
|
||||
return value.fromString(ip_str);
|
||||
}
|
||||
|
||||
void ESPEasy_key_value_store::setValue(uint32_t key, const IPAddress& value)
|
||||
{
|
||||
if (IPAddressSet(value)) { setValue(key, value.toString(), KVS_StorageType::Enum::ip_type); }
|
||||
else { clearKey(KVS_StorageType::Enum::ip_type, key); }
|
||||
}
|
||||
|
||||
ESPEasy_key_value_store::map_4byte_data::const_iterator ESPEasy_key_value_store::get4byteIterator(
|
||||
KVS_StorageType::Enum storageType,
|
||||
uint32_t key) const
|
||||
uint32_t key) const
|
||||
{
|
||||
if (!hasStorageType(storageType)) { return _4byte_data.end(); }
|
||||
const uint32_t combined_key = KVS_StorageType::combine_StorageType_and_key(storageType, key);
|
||||
@@ -660,37 +727,37 @@ ESPEasy_key_value_store::map_4byte_data::const_iterator ESPEasy_key_value_store:
|
||||
|
||||
ESPEasy_key_value_store::map_8byte_data::const_iterator ESPEasy_key_value_store::get8byteIterator(
|
||||
KVS_StorageType::Enum storageType,
|
||||
uint32_t key) const
|
||||
uint32_t key) const
|
||||
{
|
||||
if (!hasStorageType(storageType)) { return _8byte_data.end(); }
|
||||
const uint32_t combined_key = KVS_StorageType::combine_StorageType_and_key(storageType, key);
|
||||
return _8byte_data.find(combined_key);
|
||||
}
|
||||
|
||||
# define GET_4BYTE_TYPE(T, GF) \
|
||||
# define GET_4BYTE_TYPE(T, GF) \
|
||||
auto it = get4byteIterator(KVS_StorageType::Enum::T, key); \
|
||||
if (it == _4byte_data.end()) return false; \
|
||||
value = it->second.GF(); \
|
||||
return true; \
|
||||
if (it == _4byte_data.end()) return false; \
|
||||
value = it->second.GF(); \
|
||||
return true; \
|
||||
|
||||
# define GET_8BYTE_TYPE(T, GF) \
|
||||
# define GET_8BYTE_TYPE(T, GF) \
|
||||
auto it = get8byteIterator(KVS_StorageType::Enum::T, key); \
|
||||
if (it == _8byte_data.end()) return false; \
|
||||
value = it->second.GF(); \
|
||||
return true; \
|
||||
if (it == _8byte_data.end()) return false; \
|
||||
value = it->second.GF(); \
|
||||
return true; \
|
||||
|
||||
|
||||
# define SET_4BYTE_TYPE(T, SF) \
|
||||
const uint32_t combined_key = KVS_StorageType::combine_StorageType_and_key( \
|
||||
KVS_StorageType::Enum::T, key); \
|
||||
if (_4byte_data[combined_key].SF(value)) _state = State::Changed; \
|
||||
# define SET_4BYTE_TYPE(T, SF) \
|
||||
const uint32_t combined_key = KVS_StorageType::combine_StorageType_and_key( \
|
||||
KVS_StorageType::Enum::T, key); \
|
||||
if (_4byte_data[combined_key].SF(value)) _state = State::Changed; \
|
||||
setHasStorageType(KVS_StorageType::Enum::T);
|
||||
|
||||
|
||||
# define SET_8BYTE_TYPE(T, SF) \
|
||||
const uint32_t combined_key = KVS_StorageType::combine_StorageType_and_key( \
|
||||
KVS_StorageType::Enum::T, key); \
|
||||
if (_8byte_data[combined_key].SF(value)) _state = State::Changed; \
|
||||
# define SET_8BYTE_TYPE(T, SF) \
|
||||
const uint32_t combined_key = KVS_StorageType::combine_StorageType_and_key( \
|
||||
KVS_StorageType::Enum::T, key); \
|
||||
if (_8byte_data[combined_key].SF(value)) _state = State::Changed; \
|
||||
setHasStorageType(KVS_StorageType::Enum::T);
|
||||
|
||||
bool ESPEasy_key_value_store::getValue(uint32_t key, int8_t& value) const
|
||||
@@ -788,7 +855,8 @@ bool ESPEasy_key_value_store::getValueAsString(const KVS_StorageType::Enum& stor
|
||||
switch (storageType)
|
||||
{
|
||||
case KVS_StorageType::Enum::string_type:
|
||||
return getValue(key, value);
|
||||
case KVS_StorageType::Enum::ip_type:
|
||||
return getValue(key, value, storageType);
|
||||
|
||||
case KVS_StorageType::Enum::bool_type:
|
||||
case KVS_StorageType::Enum::int8_type:
|
||||
@@ -856,15 +924,15 @@ bool ESPEasy_key_value_store::getValueAsString(uint32_t key, String& value) cons
|
||||
return getValueAsString(getStorageType(key), key, value);
|
||||
}
|
||||
|
||||
# define GET_TYPE_AS_INT64(T, CT) \
|
||||
# define GET_TYPE_AS_INT64(T, CT) \
|
||||
case KVS_StorageType::Enum::T: \
|
||||
{ \
|
||||
CT v{}; \
|
||||
if (getValue(key, v)) { \
|
||||
value = v; \
|
||||
return true; \
|
||||
} \
|
||||
break; \
|
||||
{ \
|
||||
CT v{}; \
|
||||
if (getValue(key, v)) { \
|
||||
value = v; \
|
||||
return true; \
|
||||
} \
|
||||
break; \
|
||||
}
|
||||
|
||||
bool ESPEasy_key_value_store::getValueAsInt(
|
||||
@@ -920,12 +988,12 @@ int64_t ESPEasy_key_value_store::getValueAsInt(uint32_t key) const
|
||||
return getValueAsInt_or_default(key, 0);
|
||||
}
|
||||
|
||||
# define GET_4BYTE_INT_TYPE_FROM_STRING(T, CT) \
|
||||
case KVS_StorageType::Enum::T: \
|
||||
{ \
|
||||
CT v(value.toInt()); \
|
||||
setValue(key, v); \
|
||||
break; \
|
||||
# define GET_4BYTE_INT_TYPE_FROM_STRING(T, CT) \
|
||||
case KVS_StorageType::Enum::T: \
|
||||
{ \
|
||||
CT v(value.toInt()); \
|
||||
setValue(key, v); \
|
||||
break; \
|
||||
}
|
||||
|
||||
void ESPEasy_key_value_store::setValue(const KVS_StorageType::Enum& storageType, uint32_t key, const String& value)
|
||||
@@ -933,8 +1001,15 @@ void ESPEasy_key_value_store::setValue(const KVS_StorageType::Enum& storageType,
|
||||
switch (storageType)
|
||||
{
|
||||
case KVS_StorageType::Enum::string_type:
|
||||
setValue(key, value);
|
||||
setValue(key, value, storageType);
|
||||
break;
|
||||
case KVS_StorageType::Enum::ip_type:
|
||||
{
|
||||
IPAddress ip;
|
||||
ip.fromString(value);
|
||||
setValue(key, ip);
|
||||
break;
|
||||
}
|
||||
GET_4BYTE_INT_TYPE_FROM_STRING(int8_type, int8_t)
|
||||
GET_4BYTE_INT_TYPE_FROM_STRING(uint8_type, uint8_t)
|
||||
GET_4BYTE_INT_TYPE_FROM_STRING(int16_type, int16_t)
|
||||
@@ -972,7 +1047,7 @@ void ESPEasy_key_value_store::setValue(const KVS_StorageType::Enum& storageType,
|
||||
}
|
||||
|
||||
bool ESPEasy_key_value_store::getValue(
|
||||
KVS_StorageType::Enum & storageType,
|
||||
KVS_StorageType::Enum & storageType,
|
||||
uint32_t key,
|
||||
ESPEasy_key_value_store_4byte_data_t& value) const
|
||||
{
|
||||
@@ -984,7 +1059,7 @@ bool ESPEasy_key_value_store::getValue(
|
||||
}
|
||||
|
||||
void ESPEasy_key_value_store::setValue(
|
||||
KVS_StorageType::Enum & storageType,
|
||||
KVS_StorageType::Enum & storageType,
|
||||
uint32_t key,
|
||||
const ESPEasy_key_value_store_4byte_data_t& value)
|
||||
{
|
||||
@@ -1002,7 +1077,7 @@ void ESPEasy_key_value_store::setValue(
|
||||
}
|
||||
|
||||
bool ESPEasy_key_value_store::getValue(
|
||||
KVS_StorageType::Enum & storageType,
|
||||
KVS_StorageType::Enum & storageType,
|
||||
uint32_t key,
|
||||
ESPEasy_key_value_store_8byte_data_t& value) const
|
||||
{
|
||||
@@ -1014,7 +1089,7 @@ bool ESPEasy_key_value_store::getValue(
|
||||
}
|
||||
|
||||
void ESPEasy_key_value_store::setValue(
|
||||
KVS_StorageType::Enum & storageType,
|
||||
KVS_StorageType::Enum & storageType,
|
||||
uint32_t key,
|
||||
const ESPEasy_key_value_store_8byte_data_t& value)
|
||||
{
|
||||
@@ -1065,6 +1140,59 @@ void ESPEasy_key_value_store::setHasStorageType(KVS_StorageType::Enum storageTyp
|
||||
// TODO TD-er: Whenever this is called, there has been a change, so invalidate checksum
|
||||
}
|
||||
|
||||
void ESPEasy_key_value_store::updateHasStorageType(KVS_StorageType::Enum storageType)
|
||||
{
|
||||
if ((storageType == KVS_StorageType::Enum::bool_true) ||
|
||||
(storageType == KVS_StorageType::Enum::bool_false)) {
|
||||
storageType = KVS_StorageType::Enum::bool_type;
|
||||
}
|
||||
const uint32_t bitnr = static_cast<uint32_t>(storageType);
|
||||
constexpr uint32_t max_bitnr = static_cast<uint32_t>(KVS_StorageType::Enum::MAX_Type);
|
||||
|
||||
if (bitnr >= max_bitnr) { return; }
|
||||
|
||||
const uint32_t old_cache = _storage_type_present_cache;
|
||||
bitClear(_storage_type_present_cache, bitnr);
|
||||
|
||||
if ((storageType == KVS_StorageType::Enum::string_type) || (storageType == KVS_StorageType::Enum::ip_type))
|
||||
{
|
||||
bool done = false;
|
||||
|
||||
for (auto it = _string_data.begin(); !done && it != _string_data.end(); ++it) {
|
||||
if (storageType == KVS_StorageType::get_StorageType_from_combined_key(it->first)) {
|
||||
bitSet(_storage_type_present_cache, bitnr);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const size_t size = KVS_StorageType::getStorageSizePerType(storageType);
|
||||
|
||||
if (size == 12) {
|
||||
bool done = false;
|
||||
|
||||
for (auto it = _8byte_data.begin(); !done && it != _8byte_data.end(); ++it) {
|
||||
if (storageType == KVS_StorageType::get_StorageType_from_combined_key(it->first)) {
|
||||
bitSet(_storage_type_present_cache, bitnr);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool done = false;
|
||||
|
||||
for (auto it = _4byte_data.begin(); !done && it != _4byte_data.end(); ++it) {
|
||||
if (storageType == KVS_StorageType::get_StorageType_from_combined_key(it->first)) {
|
||||
bitSet(_storage_type_present_cache, bitnr);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (old_cache != _storage_type_present_cache) {
|
||||
_state = State::Changed;
|
||||
}
|
||||
}
|
||||
|
||||
void ESPEasy_key_value_store::dump() const
|
||||
{
|
||||
addLog(LOG_LEVEL_INFO, strformat(F("KVS: Payload Storage size : %d"), getPayloadStorageSize()));
|
||||
@@ -1144,5 +1272,4 @@ void ESPEasy_key_value_store::dump() const
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // if FEATURE_ESPEASY_KEY_VALUE_STORE
|
||||
|
||||
@@ -43,17 +43,17 @@ public:
|
||||
|
||||
};
|
||||
|
||||
State getState() const { return _state; }
|
||||
State getState() const { return _state; }
|
||||
|
||||
bool isEmpty() const;
|
||||
bool isEmpty() const;
|
||||
|
||||
void clear();
|
||||
void clear();
|
||||
|
||||
|
||||
bool load(SettingsType::Enum settingsType,
|
||||
int index,
|
||||
uint32_t offset_in_block,
|
||||
uint16_t id_to_match);
|
||||
bool load(SettingsType::Enum settingsType,
|
||||
int index,
|
||||
uint32_t offset_in_block,
|
||||
uint16_t id_to_match);
|
||||
bool store(SettingsType::Enum settingsType,
|
||||
int index,
|
||||
uint32_t offset_in_block,
|
||||
@@ -64,7 +64,10 @@ public:
|
||||
|
||||
// Check to see if there is a key stored with given storage type
|
||||
bool hasKey(KVS_StorageType::Enum storageType,
|
||||
uint32_t key) const;
|
||||
uint32_t key) const;
|
||||
|
||||
bool clearKey(KVS_StorageType::Enum storageType,
|
||||
uint32_t key);
|
||||
|
||||
// Try to find a key and get its storage type or 'not_set' if the key is not present
|
||||
KVS_StorageType::Enum getStorageType(uint32_t key) const;
|
||||
@@ -81,14 +84,24 @@ public:
|
||||
void setValue(uint32_t key,
|
||||
const StringPair& stringPair);
|
||||
|
||||
bool getValue(uint32_t key,
|
||||
String & value) const;
|
||||
void setValue(uint32_t key,
|
||||
const String& value);
|
||||
bool getValue(uint32_t key,
|
||||
String & value,
|
||||
KVS_StorageType::Enum storageType) const;
|
||||
void setValue(uint32_t key,
|
||||
const String & value,
|
||||
KVS_StorageType::Enum storageType);
|
||||
void setValue(uint32_t key,
|
||||
const __FlashStringHelper*value);
|
||||
void setValue(uint32_t key,
|
||||
String&& value);
|
||||
const __FlashStringHelper*value,
|
||||
KVS_StorageType::Enum storageType);
|
||||
void setValue(uint32_t key,
|
||||
String && value,
|
||||
KVS_StorageType::Enum storageType);
|
||||
|
||||
bool getValue(uint32_t key,
|
||||
IPAddress& value) const;
|
||||
void setValue(uint32_t key,
|
||||
const IPAddress& value);
|
||||
|
||||
|
||||
bool getValue(uint32_t key,
|
||||
int8_t & value) const;
|
||||
@@ -149,8 +162,8 @@ public:
|
||||
// Generic get function for any given storageType/key and represent its value as a string.
|
||||
// Return false when storageType/key is not present.
|
||||
bool getValueAsString(const KVS_StorageType::Enum& storageType,
|
||||
uint32_t key,
|
||||
String & value) const;
|
||||
uint32_t key,
|
||||
String & value) const;
|
||||
|
||||
bool getValueAsString(uint32_t key,
|
||||
String & value) const;
|
||||
@@ -166,8 +179,8 @@ public:
|
||||
// Given value is a string representation of that storage type.
|
||||
// TODO TD-er: Implement
|
||||
void setValue(const KVS_StorageType::Enum& storageType,
|
||||
uint32_t key,
|
||||
const String & value);
|
||||
uint32_t key,
|
||||
const String & value);
|
||||
|
||||
String getLastError() const { return _lastError; }
|
||||
|
||||
@@ -175,19 +188,19 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
bool getValue(KVS_StorageType::Enum & storageType,
|
||||
bool getValue(KVS_StorageType::Enum & storageType,
|
||||
uint32_t key,
|
||||
ESPEasy_key_value_store_4byte_data_t& value) const;
|
||||
|
||||
void setValue(KVS_StorageType::Enum & storageType,
|
||||
void setValue(KVS_StorageType::Enum & storageType,
|
||||
uint32_t key,
|
||||
const ESPEasy_key_value_store_4byte_data_t& value);
|
||||
|
||||
bool getValue(KVS_StorageType::Enum & storageType,
|
||||
bool getValue(KVS_StorageType::Enum & storageType,
|
||||
uint32_t key,
|
||||
ESPEasy_key_value_store_8byte_data_t& value) const;
|
||||
|
||||
void setValue(KVS_StorageType::Enum & storageType,
|
||||
void setValue(KVS_StorageType::Enum & storageType,
|
||||
uint32_t key,
|
||||
const ESPEasy_key_value_store_8byte_data_t& value);
|
||||
|
||||
@@ -198,15 +211,17 @@ private:
|
||||
// Update cache to indicate we have at least one of the given storage type
|
||||
void setHasStorageType(KVS_StorageType::Enum storageType);
|
||||
|
||||
void updateHasStorageType(KVS_StorageType::Enum storageType);
|
||||
|
||||
typedef std::map<uint32_t, ESPEasy_key_value_store_4byte_data_t> map_4byte_data;
|
||||
typedef std::map<uint32_t, ESPEasy_key_value_store_8byte_data_t> map_8byte_data;
|
||||
|
||||
map_4byte_data::const_iterator get4byteIterator(
|
||||
KVS_StorageType::Enum storageType,
|
||||
uint32_t key) const;
|
||||
uint32_t key) const;
|
||||
map_8byte_data::const_iterator get8byteIterator(
|
||||
KVS_StorageType::Enum storageType,
|
||||
uint32_t key) const;
|
||||
uint32_t key) const;
|
||||
|
||||
String _lastError;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ void handleNotFound() {
|
||||
if (captivePortal()) { // If captive portal redirect instead of displaying the error page.
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
// if Wifi setup, launch setup wizard if AP_DONT_FORCE_SETUP is not set.
|
||||
if (//WiFiEventData.wifiSetup &&
|
||||
Settings.ApCaptivePortal())
|
||||
@@ -35,6 +35,7 @@ void handleNotFound() {
|
||||
web_server.send_P(200, (PGM_P)F("text/html"), (PGM_P)F("<meta HTTP-EQUIV='REFRESH' content='0; url=/setup'>"));
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef WEBSERVER_RULES
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
|
||||
#include "../Helpers/ESPEasy_Storage.h"
|
||||
#include "../Helpers/Hardware_device_info.h"
|
||||
#include "../Helpers/Networking.h"
|
||||
#include "../Helpers/OTA.h"
|
||||
#include "../Helpers/StringConverter.h"
|
||||
|
||||
@@ -126,6 +127,7 @@ void sendHeadandTail_stdtemplate(bool Tail, bool rebooting) {
|
||||
sendHeadandTail(F("TmplStd"), Tail, rebooting);
|
||||
|
||||
if (!Tail) {
|
||||
// TODO TD-er: Must check clientConnectedToAP()?
|
||||
if (!clientIPinSubnetDefaultNetwork() && ESPEasy::net::wifi::wifiAPmodeActivelyUsed()) {
|
||||
addHtmlError(F("Warning: Connected via AP"));
|
||||
}
|
||||
@@ -169,14 +171,16 @@ void sendHeadandTail_stdtemplate(bool Tail, bool rebooting) {
|
||||
}
|
||||
|
||||
bool captivePortal() {
|
||||
if (!Settings.ApCaptivePortal()) return false;
|
||||
const IPAddress client_localIP = web_server.client().localIP();
|
||||
const bool fromAP = client_localIP == apIP;
|
||||
const bool hasWiFiCredentials = SecuritySettings.hasWiFiCredentials();
|
||||
// We only need to check if a client connected here via AP
|
||||
// as currently we don't have any interface which allows forwarding
|
||||
// packets and thus acting as a gateway for others.
|
||||
if (!Settings.ApCaptivePortal() || !clientConnectedToAP()) return false;
|
||||
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
addLog(LOG_LEVEL_DEBUG, concat(F("CaptivePortal: hostHeader: "), web_server.hostHeader()));
|
||||
#endif
|
||||
if (hasWiFiCredentials || !fromAP) {
|
||||
if (!ESPEasy::net::NetworkConnected())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -185,10 +189,11 @@ bool captivePortal() {
|
||||
&& !getValue(LabelType::M_DNS).equalsIgnoreCase(web_server.hostHeader())
|
||||
#endif
|
||||
) {
|
||||
const IPAddress client_localIP = web_server.client().localIP();
|
||||
String redirectURL = concat(F("http://"), formatIP(client_localIP));
|
||||
#ifdef WEBSERVER_SETUP
|
||||
|
||||
if (fromAP && !hasWiFiCredentials) {
|
||||
if (ESPEasy::net::wifi::shouldRedirectTo_setup()) {
|
||||
redirectURL += F("/setup");
|
||||
}
|
||||
#endif // ifdef WEBSERVER_SETUP
|
||||
@@ -201,6 +206,60 @@ bool captivePortal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool clientConnectedToAP()
|
||||
{
|
||||
const IPAddress client_localIP = web_server.client().localIP();
|
||||
return IPAddressSet(client_localIP) && client_localIP == apIP;
|
||||
}
|
||||
|
||||
ESPEasy::net::networkIndex_t getNetworkIndex_ClientConnectsTo()
|
||||
{
|
||||
const IPAddress client_localIP = web_server.client().localIP();
|
||||
if (!IPAddressSet(client_localIP))
|
||||
return ESPEasy::net::INVALID_NETWORK_INDEX;
|
||||
if (client_localIP == apIP) {
|
||||
// Easy to check as this is a global variable
|
||||
return NETWORK_INDEX_WIFI_AP;
|
||||
}
|
||||
#ifdef ESP8266
|
||||
if (client_localIP == WiFi.localIP()) {
|
||||
return NETWORK_INDEX_WIFI_STA;
|
||||
}
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
for (ESPEasy::net::networkIndex_t x = 0; x < NETWORK_MAX; ++x) {
|
||||
if (Settings.getNetworkEnabled(x)) {
|
||||
struct EventStruct TempEvent;
|
||||
TempEvent.NetworkIndex = x;
|
||||
String str;
|
||||
|
||||
if (ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_GET_INTERFACE, &TempEvent, str))
|
||||
{
|
||||
const NWPlugin::IP_type ip_types[] = {
|
||||
NWPlugin::IP_type::inet,
|
||||
# if CONFIG_LWIP_IPV6
|
||||
NWPlugin::IP_type::ipv6_unknown,
|
||||
NWPlugin::IP_type::ipv6_global,
|
||||
NWPlugin::IP_type::ipv6_link_local,
|
||||
NWPlugin::IP_type::ipv6_site_local,
|
||||
NWPlugin::IP_type::ipv6_unique_local,
|
||||
NWPlugin::IP_type::ipv4_mapped_ipv6,
|
||||
# endif // if CONFIG_LWIP_IPV6
|
||||
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < NR_ELEMENTS(ip_types); ++i) {
|
||||
const IPAddress ip(NWPlugin::get_IP_address(ip_types[i], TempEvent.networkInterface));
|
||||
if (client_localIP == ip) return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return ESPEasy::net::INVALID_NETWORK_INDEX;
|
||||
}
|
||||
|
||||
// ********************************************************************************
|
||||
// Web Interface init
|
||||
// ********************************************************************************
|
||||
@@ -447,7 +506,7 @@ void setWebserverRunning(bool state) {
|
||||
#endif
|
||||
}
|
||||
webserverRunning = state;
|
||||
ESPEasy::net::CheckRunningServices(); // Uses webserverRunning state.
|
||||
ESPEasy::net::CheckRunningServices(true); // Uses webserverRunning state.
|
||||
}
|
||||
|
||||
void getWebPageTemplateDefault(const String& tmplName, WebTemplateParser& parser)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "../DataTypes/SettingsType.h"
|
||||
#include "../WebServer/WebTemplateParser.h"
|
||||
#include "../../ESPEasy/net/DataTypes/NetworkIndex.h"
|
||||
|
||||
|
||||
// Uncrustify must not be used on macros, so turn it off.
|
||||
@@ -33,6 +34,13 @@ void WebServerInit();
|
||||
// ********************************************************************************
|
||||
bool captivePortal();
|
||||
|
||||
bool clientConnectedToAP();
|
||||
|
||||
// Determine which network interface is being used by the client to access this ESPEasy node
|
||||
ESPEasy::net::networkIndex_t getNetworkIndex_ClientConnectsTo();
|
||||
|
||||
|
||||
|
||||
void setWebserverRunning(bool state);
|
||||
|
||||
void getWebPageTemplateDefault(const String& tmplName,
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
# include "../WebServer/Markup_Forms.h"
|
||||
|
||||
WebFormItemParams::WebFormItemParams(
|
||||
const String & label,
|
||||
const String & id,
|
||||
const String & label,
|
||||
const String & id,
|
||||
KVS_StorageType::Enum storageType,
|
||||
uint32_t key)
|
||||
uint32_t key)
|
||||
: _label(label), _id(id), _storageType(storageType), _key(key) {}
|
||||
|
||||
WebFormItemParams::WebFormItemParams(
|
||||
const __FlashStringHelper *label,
|
||||
const __FlashStringHelper *id,
|
||||
KVS_StorageType::Enum storageType,
|
||||
uint32_t key)
|
||||
const __FlashStringHelper *label,
|
||||
const __FlashStringHelper *id,
|
||||
KVS_StorageType::Enum storageType,
|
||||
uint32_t key)
|
||||
: _label(label), _id(id), _storageType(storageType), _key(key) {}
|
||||
|
||||
# define CORRECT_RANGE(T, CT) \
|
||||
case KVS_StorageType::Enum::T: \
|
||||
case KVS_StorageType::Enum::T: \
|
||||
if (_max > std::numeric_limits<CT>::max()) _max = std::numeric_limits<CT>::max(); \
|
||||
if (_min < std::numeric_limits<CT>::min()) _min = std::numeric_limits<CT>::min(); \
|
||||
break;
|
||||
@@ -29,15 +29,15 @@ void WebFormItemParams::checkRanges()
|
||||
{
|
||||
switch (_storageType)
|
||||
{
|
||||
CORRECT_RANGE(int8_type, int8_t)
|
||||
CORRECT_RANGE(uint8_type, uint8_t)
|
||||
CORRECT_RANGE(int16_type, int16_t)
|
||||
CORRECT_RANGE(uint16_type, uint16_t)
|
||||
CORRECT_RANGE(int32_type, int32_t)
|
||||
CORRECT_RANGE(uint32_type, uint32_t)
|
||||
CORRECT_RANGE(float_type, float)
|
||||
CORRECT_RANGE(uint64_type, uint64_t)
|
||||
CORRECT_RANGE(int64_type, int64_t)
|
||||
CORRECT_RANGE(int8_type, int8_t)
|
||||
CORRECT_RANGE(uint8_type, uint8_t)
|
||||
CORRECT_RANGE(int16_type, int16_t)
|
||||
CORRECT_RANGE(uint16_type, uint16_t)
|
||||
CORRECT_RANGE(int32_type, int32_t)
|
||||
CORRECT_RANGE(uint32_type, uint32_t)
|
||||
CORRECT_RANGE(float_type, float)
|
||||
CORRECT_RANGE(uint64_type, uint64_t)
|
||||
CORRECT_RANGE(int64_type, int64_t)
|
||||
|
||||
// CORRECT_RANGE(double_type, double)
|
||||
default: break;
|
||||
@@ -52,6 +52,21 @@ bool showWebformItem(const ESPEasy_key_value_store& store,
|
||||
|
||||
switch (params._storageType)
|
||||
{
|
||||
case KVS_StorageType::Enum::ip_type:
|
||||
{
|
||||
IPAddress value;
|
||||
|
||||
if (!store.getValue(params._key, value) && !params._defaultStringValue.isEmpty())
|
||||
{
|
||||
value.fromString(params._defaultStringValue);
|
||||
}
|
||||
addFormIPBox(
|
||||
params._label,
|
||||
id,
|
||||
value);
|
||||
return true;
|
||||
}
|
||||
|
||||
case KVS_StorageType::Enum::string_type:
|
||||
{
|
||||
String value;
|
||||
@@ -175,15 +190,15 @@ void showFormSelector(const ESPEasy_key_value_store& store,
|
||||
selector.addFormSelector(params._label, params._id, value);
|
||||
}
|
||||
|
||||
void storeWebformItem(ESPEasy_key_value_store & store,
|
||||
uint32_t key,
|
||||
KVS_StorageType::Enum storageType,
|
||||
const __FlashStringHelper *id) { storeWebformItem(store, key, storageType, String(id)); }
|
||||
void storeWebformItem(ESPEasy_key_value_store & store,
|
||||
uint32_t key,
|
||||
KVS_StorageType::Enum storageType,
|
||||
const __FlashStringHelper *id) { storeWebformItem(store, key, storageType, String(id)); }
|
||||
|
||||
void storeWebformItem(ESPEasy_key_value_store & store,
|
||||
uint32_t key,
|
||||
KVS_StorageType::Enum storageType,
|
||||
const String & id)
|
||||
void storeWebformItem(ESPEasy_key_value_store& store,
|
||||
uint32_t key,
|
||||
KVS_StorageType::Enum storageType,
|
||||
const String & id)
|
||||
{
|
||||
String _id = id.isEmpty() ? concat(F("KVS_ID_"), key) : id;
|
||||
|
||||
@@ -193,7 +208,13 @@ void storeWebformItem(ESPEasy_key_value_store & store,
|
||||
}
|
||||
|
||||
if (hasArg(_id)) {
|
||||
store.setValue(storageType, key, webArg(_id));
|
||||
if (storageType == KVS_StorageType::Enum::ip_type) {
|
||||
IPAddress ip;
|
||||
ip.fromString(webArg(_id));
|
||||
store.setValue(key, ip);
|
||||
} else {
|
||||
store.setValue(storageType, key, webArg(_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "../Helpers/Hardware_GPIO.h"
|
||||
#include "../Helpers/Hardware_device_info.h"
|
||||
#include "../Helpers/Networking.h"
|
||||
#include "../Helpers/Numerical.h"
|
||||
#include "../Helpers/StringConverter.h"
|
||||
#include "../Helpers/StringGenerator_GPIO.h"
|
||||
@@ -380,35 +381,64 @@ bool getFormPassword(const String& id, String& password)
|
||||
return !equals(password, F(MARKUP_FORMS_PASSWORD_MASK_ASTERISKS));
|
||||
}
|
||||
|
||||
// ********************************************************************************
|
||||
// Add a IP Box form
|
||||
// ********************************************************************************
|
||||
void addFormIPBox(const __FlashStringHelper *label,
|
||||
const __FlashStringHelper *id,
|
||||
const uint8_t ip[4])
|
||||
{
|
||||
addFormIPBox(String(label), String(id), ip);
|
||||
}
|
||||
|
||||
void addFormTextBox(const String& label, const String& id, const String& value)
|
||||
{
|
||||
addRowLabel_tr_id(label, id);
|
||||
|
||||
addHtml(strformat(
|
||||
F("<input class='wide' type='text' name='%s' id='%s' value='%s'>"),
|
||||
id.c_str(),
|
||||
id.c_str(),
|
||||
value.c_str()
|
||||
));
|
||||
F("<input class='wide' type='text' name='%s' id='%s' value='%s'>"),
|
||||
id.c_str(),
|
||||
id.c_str(),
|
||||
value.c_str()
|
||||
));
|
||||
}
|
||||
|
||||
void addFormIPBox(const String& label, const String& id, const uint8_t ip[4])
|
||||
// ********************************************************************************
|
||||
// Add a IP Box form
|
||||
// ********************************************************************************
|
||||
void addFormIPBox(const __FlashStringHelper *label,
|
||||
const __FlashStringHelper *id,
|
||||
const uint8_t ip[4]) { addFormIPBox(String(label), String(id), IPAddress(ip)); }
|
||||
|
||||
void addFormIPBox(const String& label, const String& id, const uint8_t ip[4]) { addFormIPBox(label, id, IPAddress(ip)); }
|
||||
|
||||
void addFormIPBox(const __FlashStringHelper *label,
|
||||
const __FlashStringHelper *id,
|
||||
const IPAddress & ip) { addFormIPBox(String(label), String(id), ip); }
|
||||
|
||||
void addFormIPBox(const String & label,
|
||||
const String & id,
|
||||
const IPAddress& ip)
|
||||
{
|
||||
const bool empty_IP = (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0);
|
||||
const bool empty_IP = !IPAddressSet(ip);
|
||||
|
||||
addFormTextBox(label, id, (empty_IP) ? EMPTY_STRING : formatIP(ip));
|
||||
|
||||
/*
|
||||
// TODO TD-er: Option to validate IP in HTML
|
||||
//
|
||||
// IP input HTML validation from:
|
||||
// Source - https://stackoverflow.com/a/54796814
|
||||
// Posted by ptay, modified by community. See post 'Timeline' for change history
|
||||
// Retrieved 2026-04-30, License - CC BY-SA 4.0
|
||||
//
|
||||
// <input type="text" minlength="7" maxlength="15" size="15" pattern="^(?>(\d|[1-9]\d{2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?1)$">
|
||||
|
||||
const String value = (empty_IP) ? EMPTY_STRING : formatIP(ip);
|
||||
addRowLabel_tr_id(label, id);
|
||||
|
||||
// Validation only for IPv4 address
|
||||
addHtml(strformat(
|
||||
F("<input class='wide' type='text' minlength='7' maxlength='15' size='15'
|
||||
pattern='^(?>(\\d|[1-9]\\d{2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?1)$' name='%s' id='%s' value='%s'>"),
|
||||
id.c_str(),
|
||||
id.c_str(),
|
||||
value.c_str()
|
||||
));
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// ********************************************************************************
|
||||
// Add a MAC Box form
|
||||
// ********************************************************************************
|
||||
|
||||
@@ -233,6 +233,14 @@ void addFormIPBox(const String& label,
|
||||
const String& id,
|
||||
const uint8_t ip[4]);
|
||||
|
||||
void addFormIPBox(const __FlashStringHelper *label,
|
||||
const __FlashStringHelper *id,
|
||||
const IPAddress& ip);
|
||||
|
||||
void addFormIPBox(const String& label,
|
||||
const String& id,
|
||||
const IPAddress& ip);
|
||||
|
||||
// ********************************************************************************
|
||||
// Add a MAC address Box form
|
||||
// ********************************************************************************
|
||||
|
||||
@@ -64,7 +64,7 @@ void handle_root() {
|
||||
if (captivePortal()) { // If captive portal redirect instead of displaying the page.
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
// if Wifi setup, launch setup wizard if AP_FORCE_SETUP is set.
|
||||
if (!ESPEasy::net::NetworkConnected() &&
|
||||
Settings.ApCaptivePortal())
|
||||
@@ -72,7 +72,7 @@ void handle_root() {
|
||||
web_server.send_P(200, (PGM_P)F("text/html"), (PGM_P)F("<meta HTTP-EQUIV='REFRESH' content='0; url=/setup'>"));
|
||||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
if (!MAIN_PAGE_SHOW_BASIC_INFO_NOT_LOGGED_IN) {
|
||||
if (!isLoggedIn()) { return; }
|
||||
}
|
||||
|
||||
@@ -25,10 +25,13 @@ def get_max_bin_size(env_name, file_suffix):
|
||||
if "_8M1M" in env_name:
|
||||
# ESP32 with 3520k of sketch space.
|
||||
max_bin_size = 3604480
|
||||
if "_ESP32_" in env_name or "_ESP32c3_" in env_name or "_ESP32c5_" in env_name or "_ESP32c6_" in env_name or "_ESP32p4_" in env_name or "_ESP32p4r3_" in env_name or "_ESP32s2_" in env_name or "_ESP32s3_" in env_name:
|
||||
if "_ESP32_" in env_name or "_ESP32c3_" in env_name or "_ESP32c5_" in env_name or "_ESP32c6_" in env_name or "_ESP32c61_" in env_name or "_ESP32p4_" in env_name or "_ESP32p4r3_" in env_name or "_ESP32s2_" in env_name or "_ESP32s3_" in env_name:
|
||||
if "_16M8M" in env_name or "_16M2M" in env_name or "_16M1M" in env_name:
|
||||
# ESP32 with 4096k of sketch space.
|
||||
max_bin_size = 4194304
|
||||
if "_32M20M" in env_name:
|
||||
# ESP32 with 6144k of sketch space.
|
||||
max_bin_size = 6291456
|
||||
if "factory" in file_suffix:
|
||||
# Factory bin files include a part which is not overwritten via OTA
|
||||
max_bin_size = max_bin_size + 65536
|
||||
|
||||
@@ -28,7 +28,7 @@ def create_display_text(description, version, families):
|
||||
esp32_split.append('S2')
|
||||
if 'ESP32-S31' in families:
|
||||
esp32_split.append('S31')
|
||||
elif 'ESP32-S3' in families:
|
||||
if 'ESP32-S3' in families:
|
||||
esp32_split.append('S3')
|
||||
if 'ESP32-C2' in families:
|
||||
esp32_split.append('C2')
|
||||
@@ -38,7 +38,7 @@ def create_display_text(description, version, families):
|
||||
esp32_split.append('C5')
|
||||
if 'ESP32-C61' in families:
|
||||
esp32_split.append('C61')
|
||||
elif 'ESP32-C6' in families:
|
||||
if 'ESP32-C6' in families:
|
||||
esp32_split.append('C6')
|
||||
if 'ESP32-H2' in families:
|
||||
esp32_split.append('H2')
|
||||
@@ -46,12 +46,13 @@ def create_display_text(description, version, families):
|
||||
esp32_split.append('H21')
|
||||
if 'ESP32-P4R3' in families:
|
||||
esp32_split.append('P4R3')
|
||||
elif 'ESP32-P4' in families:
|
||||
if 'ESP32-P4' in families:
|
||||
esp32_split.append('P4')
|
||||
|
||||
|
||||
if len(esp32_split) > 0:
|
||||
fam_split.append('ESP32-' + '/'.join(esp32_split))
|
||||
res = list(set(esp32_split)) # Make list unique
|
||||
res.sort(key=str.lower)
|
||||
fam_split.append('ESP32-' + '/'.join(res))
|
||||
|
||||
fam_str = ','.join(fam_split)
|
||||
|
||||
@@ -59,11 +60,11 @@ def create_display_text(description, version, families):
|
||||
|
||||
|
||||
def parse_filename(file, version, variant, file_suffix):
|
||||
#print("{} : {} {} {}".format(file, version, variant, file_suffix))
|
||||
# print("{} : {} {} {}".format(file, version, variant, file_suffix))
|
||||
|
||||
chipFamily = 'NotSet'
|
||||
chipVariant = ''
|
||||
manifest_suff = ''
|
||||
chip_family = 'NotSet'
|
||||
chip_variant = ''
|
||||
manifest_suffix = ''
|
||||
add_improv = True
|
||||
|
||||
main_group = 'Misc' # e.g. "4M Flash" or "Device Specific"
|
||||
@@ -71,6 +72,7 @@ def parse_filename(file, version, variant, file_suffix):
|
||||
description = 'NotSet'
|
||||
sub_group = 'NotSet'
|
||||
flash_size = 'NotSet'
|
||||
flash_size_mb = 0 # For separating different "MAX" builds
|
||||
|
||||
build_flags = ''
|
||||
|
||||
@@ -78,53 +80,59 @@ def parse_filename(file, version, variant, file_suffix):
|
||||
|
||||
if ".factory.bin" in file_suffix:
|
||||
if 'ESP32' in variant:
|
||||
manifest_suff = '.manifest.json'
|
||||
manifest_suffix = '.manifest.json'
|
||||
if 'ESP32s2' in variant:
|
||||
chipFamily = 'ESP32-S2'
|
||||
chip_family = 'ESP32-S2'
|
||||
elif 'ESP32s31' in variant:
|
||||
chipFamily = 'ESP32-S31'
|
||||
chip_family = 'ESP32-S31'
|
||||
elif 'ESP32s3' in variant:
|
||||
chipFamily = 'ESP32-S3'
|
||||
chip_family = 'ESP32-S3'
|
||||
elif 'ESP32c2' in variant:
|
||||
chipFamily = 'ESP32-C2'
|
||||
chip_family = 'ESP32-C2'
|
||||
elif 'ESP32c3' in variant:
|
||||
chipFamily = 'ESP32-C3'
|
||||
chip_family = 'ESP32-C3'
|
||||
elif 'ESP32c5' in variant:
|
||||
chipFamily = 'ESP32-C5'
|
||||
chip_family = 'ESP32-C5'
|
||||
elif 'ESP32c61' in variant:
|
||||
chipFamily = 'ESP32-C61'
|
||||
chip_family = 'ESP32-C61'
|
||||
elif 'ESP32c6' in variant:
|
||||
chipFamily = 'ESP32-C6'
|
||||
chip_family = 'ESP32-C6'
|
||||
elif 'ESP32h21' in variant:
|
||||
chipFamily = 'ESP32-H21'
|
||||
chip_family = 'ESP32-H21'
|
||||
elif 'ESP32h2' in variant:
|
||||
chipFamily = 'ESP32-H2'
|
||||
chip_family = 'ESP32-H2'
|
||||
elif 'ESP32p4' in variant:
|
||||
chipFamily = 'ESP32-P4'
|
||||
chip_family = 'ESP32-P4'
|
||||
if 'rev300' in variant or 'r3' in variant:
|
||||
chipVariant = 'rev300'
|
||||
chip_variant = 'rev300'
|
||||
else:
|
||||
chipVariant = 'rev0'
|
||||
chip_variant = 'rev0'
|
||||
else:
|
||||
chipFamily = 'ESP32'
|
||||
chip_family = 'ESP32'
|
||||
|
||||
if '_4M316k' in variant:
|
||||
flash_size = '4M'
|
||||
main_group = '4M Flash'
|
||||
elif '_8M1M' in variant:
|
||||
flash_size = '8M1M'
|
||||
main_group = '8M Flash'
|
||||
flash_size_mb = 8
|
||||
main_group = '8M/16M/32M Flash MAX Builds'
|
||||
elif '_16M1M' in variant:
|
||||
flash_size = '16M1M'
|
||||
main_group = '16M Flash'
|
||||
elif '_16M8M' in variant:
|
||||
flash_size = '16M8M'
|
||||
main_group = '16M Flash'
|
||||
flash_size_mb = 16
|
||||
main_group = '8M/16M/32M Flash MAX Builds'
|
||||
elif '_32M20M' in variant:
|
||||
flash_size = '32M20M'
|
||||
flash_size_mb = 32
|
||||
main_group = '8M/16M/32M Flash MAX Builds'
|
||||
|
||||
else:
|
||||
if ".bin" in file_suffix and ".gz" not in file_suffix and 'ESP32' not in variant:
|
||||
chipFamily = 'ESP8266'
|
||||
manifest_suff = '.manifest.json'
|
||||
chip_family = 'ESP8266'
|
||||
manifest_suffix = '.manifest.json'
|
||||
add_improv = False
|
||||
|
||||
if '_4M1M' in variant:
|
||||
@@ -140,8 +148,7 @@ def parse_filename(file, version, variant, file_suffix):
|
||||
flash_size = '1M'
|
||||
main_group = '1M Flash'
|
||||
|
||||
|
||||
if 'NotSet' not in chipFamily:
|
||||
if 'NotSet' not in chip_family:
|
||||
for special in ['minimal_', 'core', '_302_', 'Domoticz', 'FHEM', 'hard_', 'beta', 'alt_wifi', 'OTA']:
|
||||
if special in variant:
|
||||
sub_group = variant
|
||||
@@ -160,7 +167,7 @@ def parse_filename(file, version, variant, file_suffix):
|
||||
group = 'NeoPixel'
|
||||
elif 'normal_' in variant:
|
||||
group = 'Normal'
|
||||
elif 'max_' in variant:
|
||||
elif 'max_' in variant or 'max32_' in variant or 'max8_' in variant:
|
||||
group = 'MAX'
|
||||
elif 'custom_' in variant:
|
||||
group = 'Custom'
|
||||
@@ -172,14 +179,14 @@ def parse_filename(file, version, variant, file_suffix):
|
||||
if '_4M1M' in variant:
|
||||
main_group = '4M Flash Collection Builds'
|
||||
|
||||
|
||||
if 'NotSet' not in group:
|
||||
sub_group_spit = group.split('_')
|
||||
|
||||
# Add some flags to differentiate the groups
|
||||
# but also use this to sort the items per main group.
|
||||
specials = []
|
||||
specials.append(flash_size)
|
||||
if 'MAX' not in group:
|
||||
specials.append(flash_size)
|
||||
if '_PSRAM' in variant:
|
||||
specials.append('PSRAM')
|
||||
if 'LittleFS' in variant and 'ESP32' not in variant:
|
||||
@@ -193,7 +200,6 @@ def parse_filename(file, version, variant, file_suffix):
|
||||
if 'solo1' in variant:
|
||||
specials.append('Solo1')
|
||||
|
||||
|
||||
for sp in specials:
|
||||
sub_group_spit.append(sp)
|
||||
|
||||
@@ -229,58 +235,43 @@ def parse_filename(file, version, variant, file_suffix):
|
||||
main_group = '4M Flash ESP32-solo1'
|
||||
|
||||
if ".factory.bin" in file_suffix or 'ESP32' not in file:
|
||||
#print('{:10s}: {:34s}\t{:10s} {} / {}'.format(state, sub_group, chipFamily, version, file))
|
||||
# print('{:10s}: {:34s}\t{:10s} {} / {}'.format(state, sub_group, chipFamily, version, file))
|
||||
|
||||
print('{:10s}: {:34s}\t{:10s} {} / {}'.format(state, description, chipFamily, version, file))
|
||||
print('{:10s}: {:34s}\t{:10s} {} / {}'.format(state, description, chip_family, version, file))
|
||||
|
||||
if main_group not in manifest_binfiles:
|
||||
manifest_binfiles[main_group] = {}
|
||||
|
||||
builds = dict([('chipFamily', chip_family)])
|
||||
if flash_size_mb > 0:
|
||||
builds['flashSizeMB'] = flash_size_mb
|
||||
if add_improv:
|
||||
builds['improv'] = True
|
||||
if chip_variant:
|
||||
builds['chipVariant'] = chip_variant
|
||||
builds['parts'] = [dict([('path', file), ('offset', 0)])]
|
||||
|
||||
if sub_group not in manifest_binfiles[main_group]:
|
||||
manifest = {}
|
||||
|
||||
manifest['name'] = description
|
||||
families = []
|
||||
families.append(chipFamily)
|
||||
manifest['displaytext'] = description
|
||||
manifest['families'] = families
|
||||
manifest['families'] = [chip_family]
|
||||
manifest['version'] = version
|
||||
manifest['new_install_prompt_erase'] = True
|
||||
manifest['build_flags'] = build_flags
|
||||
parts = dict([('path', file), ('offset', 0)])
|
||||
if not chipVariant:
|
||||
if add_improv:
|
||||
builds = dict([('chipFamily', chipFamily), ('improv', True), ('parts', [parts])])
|
||||
else:
|
||||
builds = dict([('chipFamily', chipFamily), ('parts', [parts])])
|
||||
else:
|
||||
if add_improv:
|
||||
builds = dict([('chipFamily', chipFamily), ('chipVariant', chipVariant), ('improv', False), ('parts', [parts])])
|
||||
else:
|
||||
builds = dict([('chipFamily', chipFamily), ('chipVariant', chipVariant), ('parts', [parts])])
|
||||
manifest['builds'] = [builds]
|
||||
manifest_binfiles[main_group][sub_group] = manifest
|
||||
else:
|
||||
parts = dict([('path', file), ('offset', 0)])
|
||||
if not chipVariant:
|
||||
if add_improv:
|
||||
builds = dict([('chipFamily', chipFamily), ('improv', True), ('parts', [parts])])
|
||||
else:
|
||||
builds = dict([('chipFamily', chipFamily), ('parts', [parts])])
|
||||
else:
|
||||
if add_improv:
|
||||
builds = dict([('chipFamily', chipFamily), ('chipVariant', chipVariant), ('improv', True), ('parts', [parts])])
|
||||
else:
|
||||
builds = dict([('chipFamily', chipFamily), ('chipVariant', chipVariant), ('parts', [parts])])
|
||||
|
||||
manifest_binfiles[main_group][sub_group]['builds'].append(builds)
|
||||
manifest_binfiles[main_group][sub_group]['families'].append(chipFamily)
|
||||
manifest_binfiles[main_group][sub_group]['families'].append(chip_family)
|
||||
|
||||
display_string = create_display_text(description, version, manifest_binfiles[main_group][sub_group]['families'])
|
||||
manifest_binfiles[main_group][sub_group]['displaytext'] = display_string
|
||||
if 'ESP8266' in main_group:
|
||||
manifest_binfiles[main_group][sub_group]['manifestfilename'] = '{}_ESP8266{}'.format(sub_group, manifest_suff)
|
||||
manifest_binfiles[main_group][sub_group]['manifestfilename'] = '{}_ESP8266{}'.format(sub_group, manifest_suffix)
|
||||
else:
|
||||
manifest_binfiles[main_group][sub_group]['manifestfilename'] = '{}{}'.format(sub_group, manifest_suff)
|
||||
manifest_binfiles[main_group][sub_group]['manifestfilename'] = '{}{}'.format(sub_group, manifest_suffix)
|
||||
|
||||
|
||||
|
||||
@@ -312,11 +303,10 @@ def generate_manifest_files(bin_folder, output_prefix):
|
||||
|
||||
# the main grouping in the combo box on the web flasher page
|
||||
main_group_list = [
|
||||
'8M/16M/32M Flash MAX Builds',
|
||||
'4M Flash',
|
||||
'4M Flash ESP32-solo1',
|
||||
'4M Flash Collection Builds',
|
||||
'8M Flash',
|
||||
'16M Flash',
|
||||
'2M Flash',
|
||||
'1M Flash',
|
||||
'Device Specific',
|
||||
@@ -324,7 +314,6 @@ def generate_manifest_files(bin_folder, output_prefix):
|
||||
'Custom Misc',
|
||||
'Misc']
|
||||
|
||||
|
||||
for main_group in main_group_list:
|
||||
if main_group in manifest_binfiles:
|
||||
html_options_group = []
|
||||
@@ -389,7 +378,7 @@ def generate_manifest_files(bin_folder, output_prefix):
|
||||
' </style>\n',
|
||||
' <script\n',
|
||||
' type="module"\n',
|
||||
' src="https://unpkg.com/tasmota-esp-web-tools@12.0.0/dist/web/install-button.js?module"\n',
|
||||
' src="https://unpkg.com/tasmota-esp-web-tools@12.2.2/dist/web/install-button.js?module"\n',
|
||||
' ></script>\n',
|
||||
' </head>\n',
|
||||
' <body>\n',
|
||||
@@ -409,7 +398,7 @@ def generate_manifest_files(bin_folder, output_prefix):
|
||||
lines_tail = [
|
||||
' </select>\n',
|
||||
' </div>\n',
|
||||
' <esp-web-install-button></esp-web-install-button>\n',
|
||||
' <esp-web-install-button baud-rate="460800"></esp-web-install-button>\n',
|
||||
|
||||
' <br>\n',
|
||||
' <br>\n',
|
||||
|
||||
Reference in New Issue
Block a user