diff --git a/.github/workflows/build-ide.yml b/.github/workflows/build-ide.yml index b97874e9d1..565b08d392 100644 --- a/.github/workflows/build-ide.yml +++ b/.github/workflows/build-ide.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: false - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ./tools/dist key: ${{ runner.os }}-${{ hashFiles('package/package_esp8266com_index.template.json', 'tests/common.sh', 'tests/build.sh') }} @@ -42,10 +42,10 @@ jobs: - uses: actions/checkout@v4 with: submodules: true - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ./tools/dist key: ${{ runner.os }}-${{ hashFiles('package/package_esp8266com_index.template.json', 'tests/common.sh', 'tests/build.sh') }} @@ -66,10 +66,10 @@ jobs: - uses: actions/checkout@v4 with: submodules: false - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ./tools/dist key: ${{ runner.os }}-${{ hashFiles('package/package_esp8266com_index.template.json', 'tests/common.sh', 'tests/build.sh') }} @@ -91,10 +91,10 @@ jobs: - uses: actions/checkout@v4 with: submodules: false - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ./tools/dist key: ${{ runner.os }}-${{ hashFiles('package/package_esp8266com_index.template.json', 'tests/common.sh', 'tests/build.sh') }} diff --git a/.github/workflows/build-platformio.yml b/.github/workflows/build-platformio.yml index 04d8b53d9e..5150a4bd29 100644 --- a/.github/workflows/build-platformio.yml +++ b/.github/workflows/build-platformio.yml @@ -21,10 +21,10 @@ jobs: - uses: actions/checkout@v4 with: submodules: true - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: | tools/dist diff --git a/.github/workflows/check-autogenerated.yml b/.github/workflows/check-autogenerated.yml index 099875f253..40f3f93e70 100644 --- a/.github/workflows/check-autogenerated.yml +++ b/.github/workflows/check-autogenerated.yml @@ -32,10 +32,10 @@ jobs: - uses: actions/checkout@v4 with: submodules: false - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ./tools/dist key: ${{ runner.os }}-${{ hashFiles('package/package_esp8266com_index.template.json', 'tests/common.sh') }} @@ -54,7 +54,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: false - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - name: Check git-diff result diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index a2d2402f34..977570aad8 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -19,10 +19,13 @@ jobs: - uses: actions/checkout@v4 with: submodules: true - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - name: Build documentation run: | - pip install --user -r doc/requirements.txt - bash ./tests/ci/build_docs.sh + pushd doc/ + python3 -mvenv _venv + ./_venv/bin/pip install -r requirements.txt + env SPHINXBUILD=$(pwd)/_venv/bin/sphinx-build ../tests/ci/build_docs.sh + popd diff --git a/.github/workflows/style-check.yml b/.github/workflows/style-check.yml index 8d6ef3ed51..c371c2f252 100644 --- a/.github/workflows/style-check.yml +++ b/.github/workflows/style-check.yml @@ -20,25 +20,14 @@ jobs: - uses: actions/checkout@v4 with: submodules: true - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - name: Style check - env: - LLVM_SNAPSHOT_KEY: "6084F3CF814B57C1CF12EFD515CF4D18AF4F7421" run: | - export GNUPGHOME=$(mktemp -d) - gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$LLVM_SNAPSHOT_KEY" - gpg --batch --armor --export "$LLVM_SNAPSHOT_KEY" | \ - sudo tee /etc/apt/trusted.gpg.d/llvm-snapshot.gpg.asc - gpgconf --kill all - rm -r $GNUPGHOME - echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main" | \ - sudo tee /etc/apt/sources.list.d/llvm.list sudo apt update - sudo apt install clang-format-13 - pip3 install pyyaml - bash ./tests/ci/style_check.sh + python ./tests/test_restyle.py --quiet + env CLANG_FORMAT="clang-format-18" bash ./tests/ci/style_check.sh # Validate orthography diff --git a/.github/workflows/tag-to-draft-release.yml b/.github/workflows/tag-to-draft-release.yml index d4b3762cac..e9311f9fce 100644 --- a/.github/workflows/tag-to-draft-release.yml +++ b/.github/workflows/tag-to-draft-release.yml @@ -22,7 +22,7 @@ jobs: with: submodules: true fetch-depth: 0 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - name: Set GIT tag name diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000000..867f3d40de --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,21 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-24.04 + tools: + python: "3.12" + +# Build documentation in the "doc/" directory with Sphinx +sphinx: + configuration: doc/conf.py + +# Install same versions as our local tools +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: doc/requirements.txt diff --git a/boards.txt b/boards.txt index 35a4b5ad71..1b44fe3310 100644 --- a/boards.txt +++ b/boards.txt @@ -24,6 +24,7 @@ menu.exception=C++ Exceptions menu.stacksmash=Stack Protection menu.wipe=Erase Flash menu.sdk=NONOS SDK Version +menu.iramfloat=Floating Point operations menu.ssl=SSL Support menu.mmu=MMU menu.non32xfer=Non-32-Bit Access @@ -496,6 +497,10 @@ generic.menu.eesz.autoflash.build.flash_size=16M generic.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld generic.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 generic.menu.eesz.autoflash.upload.maximum_size=1044464 +generic.menu.iramfloat.no=in IROM +generic.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +generic.menu.iramfloat.yes=allowed in ISR +generic.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## esp8285.name=Generic ESP8285 Module @@ -848,6 +853,10 @@ esp8285.menu.eesz.autoflash.build.flash_size=16M esp8285.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld esp8285.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 esp8285.menu.eesz.autoflash.upload.maximum_size=1044464 +esp8285.menu.iramfloat.no=in IROM +esp8285.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +esp8285.menu.iramfloat.yes=allowed in ISR +esp8285.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## gen4iod.name=4D Systems gen4 IoD Range @@ -1123,6 +1132,10 @@ gen4iod.menu.eesz.autoflash.build.flash_size=16M gen4iod.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld gen4iod.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 gen4iod.menu.eesz.autoflash.upload.maximum_size=1044464 +gen4iod.menu.iramfloat.no=in IROM +gen4iod.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +gen4iod.menu.iramfloat.yes=allowed in ISR +gen4iod.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## huzzah.name=Adafruit Feather HUZZAH ESP8266 @@ -1342,6 +1355,10 @@ huzzah.menu.eesz.autoflash.build.flash_size=16M huzzah.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld huzzah.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 huzzah.menu.eesz.autoflash.upload.maximum_size=1044464 +huzzah.menu.iramfloat.no=in IROM +huzzah.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +huzzah.menu.iramfloat.yes=allowed in ISR +huzzah.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## wifi_slot.name=Amperka WiFi Slot @@ -1655,6 +1672,10 @@ wifi_slot.menu.eesz.autoflash.build.flash_size=16M wifi_slot.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld wifi_slot.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 wifi_slot.menu.eesz.autoflash.upload.maximum_size=1044464 +wifi_slot.menu.iramfloat.no=in IROM +wifi_slot.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +wifi_slot.menu.iramfloat.yes=allowed in ISR +wifi_slot.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## arduino-esp8266.name=Arduino @@ -1886,6 +1907,10 @@ arduino-esp8266.menu.eesz.autoflash.build.flash_size=16M arduino-esp8266.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld arduino-esp8266.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 arduino-esp8266.menu.eesz.autoflash.upload.maximum_size=1044464 +arduino-esp8266.menu.iramfloat.no=in IROM +arduino-esp8266.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +arduino-esp8266.menu.iramfloat.yes=allowed in ISR +arduino-esp8266.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## espmxdevkit.name=DOIT ESP-Mx DevKit (ESP8285) @@ -2138,6 +2163,10 @@ espmxdevkit.menu.eesz.autoflash.build.flash_size=16M espmxdevkit.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld espmxdevkit.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 espmxdevkit.menu.eesz.autoflash.upload.maximum_size=1044464 +espmxdevkit.menu.iramfloat.no=in IROM +espmxdevkit.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +espmxdevkit.menu.iramfloat.yes=allowed in ISR +espmxdevkit.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## oak.name=Digistump Oak @@ -2358,6 +2387,10 @@ oak.menu.eesz.autoflash.build.flash_size=16M oak.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld oak.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 oak.menu.eesz.autoflash.upload.maximum_size=1044464 +oak.menu.iramfloat.no=in IROM +oak.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +oak.menu.iramfloat.yes=allowed in ISR +oak.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## espduino.name=ESPDuino (ESP-13 Module) @@ -2585,6 +2618,10 @@ espduino.menu.eesz.autoflash.build.flash_size=16M espduino.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld espduino.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 espduino.menu.eesz.autoflash.upload.maximum_size=1044464 +espduino.menu.iramfloat.no=in IROM +espduino.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +espduino.menu.iramfloat.yes=allowed in ISR +espduino.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## espectro.name=ESPectro Core @@ -2804,6 +2841,10 @@ espectro.menu.eesz.autoflash.build.flash_size=16M espectro.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld espectro.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 espectro.menu.eesz.autoflash.upload.maximum_size=1044464 +espectro.menu.iramfloat.no=in IROM +espectro.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +espectro.menu.iramfloat.yes=allowed in ISR +espectro.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## espino.name=ESPino (ESP-12 Module) @@ -3026,6 +3067,10 @@ espino.menu.eesz.autoflash.build.flash_size=16M espino.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld espino.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 espino.menu.eesz.autoflash.upload.maximum_size=1044464 +espino.menu.iramfloat.no=in IROM +espino.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +espino.menu.iramfloat.yes=allowed in ISR +espino.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## espresso_lite_v1.name=ESPresso Lite 1.0 @@ -3248,6 +3293,10 @@ espresso_lite_v1.menu.eesz.autoflash.build.flash_size=16M espresso_lite_v1.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld espresso_lite_v1.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 espresso_lite_v1.menu.eesz.autoflash.upload.maximum_size=1044464 +espresso_lite_v1.menu.iramfloat.no=in IROM +espresso_lite_v1.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +espresso_lite_v1.menu.iramfloat.yes=allowed in ISR +espresso_lite_v1.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## espresso_lite_v2.name=ESPresso Lite 2.0 @@ -3470,6 +3519,10 @@ espresso_lite_v2.menu.eesz.autoflash.build.flash_size=16M espresso_lite_v2.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld espresso_lite_v2.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 espresso_lite_v2.menu.eesz.autoflash.upload.maximum_size=1044464 +espresso_lite_v2.menu.iramfloat.no=in IROM +espresso_lite_v2.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +espresso_lite_v2.menu.iramfloat.yes=allowed in ISR +espresso_lite_v2.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## sonoff.name=ITEAD Sonoff @@ -3730,6 +3783,10 @@ sonoff.menu.eesz.autoflash.build.flash_size=16M sonoff.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld sonoff.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 sonoff.menu.eesz.autoflash.upload.maximum_size=1044464 +sonoff.menu.iramfloat.no=in IROM +sonoff.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +sonoff.menu.iramfloat.yes=allowed in ISR +sonoff.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## inventone.name=Invent One @@ -3949,6 +4006,10 @@ inventone.menu.eesz.autoflash.build.flash_size=16M inventone.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld inventone.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 inventone.menu.eesz.autoflash.upload.maximum_size=1044464 +inventone.menu.iramfloat.no=in IROM +inventone.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +inventone.menu.iramfloat.yes=allowed in ISR +inventone.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## d1_wroom_02.name=LOLIN(WEMOS) D1 ESP-WROOM-02 @@ -4184,6 +4245,10 @@ d1_wroom_02.menu.eesz.autoflash.build.flash_size=16M d1_wroom_02.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld d1_wroom_02.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 d1_wroom_02.menu.eesz.autoflash.upload.maximum_size=1044464 +d1_wroom_02.menu.iramfloat.no=in IROM +d1_wroom_02.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +d1_wroom_02.menu.iramfloat.yes=allowed in ISR +d1_wroom_02.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## d1_mini.name=LOLIN(WEMOS) D1 R2 & mini @@ -4403,6 +4468,10 @@ d1_mini.menu.eesz.autoflash.build.flash_size=16M d1_mini.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld d1_mini.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 d1_mini.menu.eesz.autoflash.upload.maximum_size=1044464 +d1_mini.menu.iramfloat.no=in IROM +d1_mini.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +d1_mini.menu.iramfloat.yes=allowed in ISR +d1_mini.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## d1_mini_clone.name=LOLIN(WEMOS) D1 mini (clone) @@ -4639,6 +4708,10 @@ d1_mini_clone.menu.eesz.autoflash.build.flash_size=16M d1_mini_clone.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld d1_mini_clone.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 d1_mini_clone.menu.eesz.autoflash.upload.maximum_size=1044464 +d1_mini_clone.menu.iramfloat.no=in IROM +d1_mini_clone.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +d1_mini_clone.menu.iramfloat.yes=allowed in ISR +d1_mini_clone.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## d1_mini_lite.name=LOLIN(WEMOS) D1 mini Lite @@ -4890,6 +4963,10 @@ d1_mini_lite.menu.eesz.autoflash.build.flash_size=16M d1_mini_lite.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld d1_mini_lite.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 d1_mini_lite.menu.eesz.autoflash.upload.maximum_size=1044464 +d1_mini_lite.menu.iramfloat.no=in IROM +d1_mini_lite.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +d1_mini_lite.menu.iramfloat.yes=allowed in ISR +d1_mini_lite.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## d1_mini_pro.name=LOLIN(WEMOS) D1 mini Pro @@ -5101,6 +5178,10 @@ d1_mini_pro.menu.eesz.autoflash.build.flash_size=16M d1_mini_pro.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld d1_mini_pro.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 d1_mini_pro.menu.eesz.autoflash.upload.maximum_size=1044464 +d1_mini_pro.menu.iramfloat.no=in IROM +d1_mini_pro.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +d1_mini_pro.menu.iramfloat.yes=allowed in ISR +d1_mini_pro.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## d1.name=LOLIN(WeMos) D1 R1 @@ -5320,6 +5401,10 @@ d1.menu.eesz.autoflash.build.flash_size=16M d1.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld d1.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 d1.menu.eesz.autoflash.upload.maximum_size=1044464 +d1.menu.iramfloat.no=in IROM +d1.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +d1.menu.iramfloat.yes=allowed in ISR +d1.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## agruminolemon.name=Lifely Agrumino Lemon v4 @@ -5555,6 +5640,233 @@ agruminolemon.menu.eesz.autoflash.build.flash_size=16M agruminolemon.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld agruminolemon.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 agruminolemon.menu.eesz.autoflash.upload.maximum_size=1044464 +agruminolemon.menu.iramfloat.no=in IROM +agruminolemon.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +agruminolemon.menu.iramfloat.yes=allowed in ISR +agruminolemon.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM + +############################################################## +mercury1.name=Mercury 1.0 +mercury1.build.board=mercury +mercury1.build.variant=mercury_v1 +mercury1.upload.tool=esptool +mercury1.upload.maximum_data_size=81920 +mercury1.upload.wait_for_upload_port=true +mercury1.upload.erase_cmd= +mercury1.serial.disableDTR=true +mercury1.serial.disableRTS=true +mercury1.build.mcu=esp8266 +mercury1.build.core=esp8266 +mercury1.build.spiffs_pagesize=256 +mercury1.build.debug_optim= +mercury1.build.debug_port= +mercury1.build.debug_level= +mercury1.menu.xtal.80=80 MHz +mercury1.menu.xtal.80.build.f_cpu=80000000L +mercury1.menu.xtal.160=160 MHz +mercury1.menu.xtal.160.build.f_cpu=160000000L +mercury1.menu.vt.flash=Flash +mercury1.menu.vt.flash.build.vtable_flags=-DVTABLES_IN_FLASH +mercury1.menu.vt.heap=Heap +mercury1.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM +mercury1.menu.vt.iram=IRAM +mercury1.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM +mercury1.menu.exception.disabled=Disabled (new aborts on oom) +mercury1.menu.exception.disabled.build.exception_flags=-fno-exceptions +mercury1.menu.exception.disabled.build.stdcpp_lib=-lstdc++ +mercury1.menu.exception.enabled=Enabled +mercury1.menu.exception.enabled.build.exception_flags=-fexceptions +mercury1.menu.exception.enabled.build.stdcpp_lib=-lstdc++-exc +mercury1.menu.stacksmash.disabled=Disabled +mercury1.menu.stacksmash.disabled.build.stacksmash_flags= +mercury1.menu.stacksmash.enabled=Enabled +mercury1.menu.stacksmash.enabled.build.stacksmash_flags=-fstack-protector +mercury1.menu.ssl.all=All SSL ciphers (most compatible) +mercury1.menu.ssl.all.build.sslflags= +mercury1.menu.ssl.basic=Basic SSL ciphers (lower ROM use) +mercury1.menu.ssl.basic.build.sslflags=-DBEARSSL_SSL_BASIC +mercury1.menu.mmu.3232=32KB cache + 32KB IRAM (balanced) +mercury1.menu.mmu.3232.build.mmuflags=-DMMU_IRAM_SIZE=0x8000 -DMMU_ICACHE_SIZE=0x8000 +mercury1.menu.mmu.4816=16KB cache + 48KB IRAM (IRAM) +mercury1.menu.mmu.4816.build.mmuflags=-DMMU_IRAM_SIZE=0xC000 -DMMU_ICACHE_SIZE=0x4000 +mercury1.menu.mmu.4816H=16KB cache + 48KB IRAM and 2nd Heap (shared) +mercury1.menu.mmu.4816H.build.mmuflags=-DMMU_IRAM_SIZE=0xC000 -DMMU_ICACHE_SIZE=0x4000 -DMMU_IRAM_HEAP +mercury1.menu.mmu.3216=16KB cache + 32KB IRAM + 16KB 2nd Heap (not shared) +mercury1.menu.mmu.3216.build.mmuflags=-DMMU_IRAM_SIZE=0x8000 -DMMU_ICACHE_SIZE=0x4000 -DMMU_SEC_HEAP=0x40108000 -DMMU_SEC_HEAP_SIZE=0x4000 +mercury1.menu.mmu.ext128k=128K Heap External 23LC1024 +mercury1.menu.mmu.ext128k.build.mmuflags=-DMMU_EXTERNAL_HEAP=128 -DMMU_IRAM_SIZE=0x8000 -DMMU_ICACHE_SIZE=0x8000 +mercury1.menu.mmu.ext8192k=8M w/256K Heap External 64 MBit PSRAM +mercury1.menu.mmu.ext8192k.build.mmuflags=-DMMU_EXTERNAL_HEAP=256 -DMMU_IRAM_SIZE=0x8000 -DMMU_ICACHE_SIZE=0x8000 +mercury1.menu.non32xfer.fast=Use pgm_read macros for IRAM/PROGMEM +mercury1.menu.non32xfer.fast.build.non32xferflags= +mercury1.menu.non32xfer.safe=Byte/Word access to IRAM/PROGMEM (very slow) +mercury1.menu.non32xfer.safe.build.non32xferflags=-DNON32XFER_HANDLER +mercury1.upload.resetmethod=--before default_reset --after hard_reset +mercury1.build.flash_mode=dio +mercury1.build.flash_flags=-DFLASHMODE_DIO +mercury1.build.flash_freq=40 +mercury1.menu.eesz.4M2M=4MB (FS:2MB OTA:~1019KB) +mercury1.menu.eesz.4M2M.build.flash_size=4M +mercury1.menu.eesz.4M2M.build.flash_ld=eagle.flash.4m2m.ld +mercury1.menu.eesz.4M2M.build.spiffs_pagesize=256 +mercury1.menu.eesz.4M2M.build.rfcal_addr=0x3FC000 +mercury1.menu.eesz.4M2M.build.spiffs_start=0x200000 +mercury1.menu.eesz.4M2M.build.spiffs_end=0x3FA000 +mercury1.menu.eesz.4M2M.build.spiffs_blocksize=8192 +mercury1.menu.eesz.4M3M=4MB (FS:3MB OTA:~512KB) +mercury1.menu.eesz.4M3M.build.flash_size=4M +mercury1.menu.eesz.4M3M.build.flash_ld=eagle.flash.4m3m.ld +mercury1.menu.eesz.4M3M.build.spiffs_pagesize=256 +mercury1.menu.eesz.4M3M.build.rfcal_addr=0x3FC000 +mercury1.menu.eesz.4M3M.build.spiffs_start=0x100000 +mercury1.menu.eesz.4M3M.build.spiffs_end=0x3FA000 +mercury1.menu.eesz.4M3M.build.spiffs_blocksize=8192 +mercury1.menu.eesz.4M1M=4MB (FS:1MB OTA:~1019KB) +mercury1.menu.eesz.4M1M.build.flash_size=4M +mercury1.menu.eesz.4M1M.build.flash_ld=eagle.flash.4m1m.ld +mercury1.menu.eesz.4M1M.build.spiffs_pagesize=256 +mercury1.menu.eesz.4M1M.build.rfcal_addr=0x3FC000 +mercury1.menu.eesz.4M1M.build.spiffs_start=0x300000 +mercury1.menu.eesz.4M1M.build.spiffs_end=0x3FA000 +mercury1.menu.eesz.4M1M.build.spiffs_blocksize=8192 +mercury1.menu.eesz.4M=4MB (FS:none OTA:~1019KB) +mercury1.menu.eesz.4M.build.flash_size=4M +mercury1.menu.eesz.4M.build.flash_ld=eagle.flash.4m.ld +mercury1.menu.eesz.4M.build.spiffs_pagesize=256 +mercury1.menu.eesz.4M.build.rfcal_addr=0x3FC000 +mercury1.menu.ip.lm2f=v2 Lower Memory +mercury1.menu.ip.lm2f.build.lwip_include=lwip2/include +mercury1.menu.ip.lm2f.build.lwip_lib=-llwip2-536-feat +mercury1.menu.ip.lm2f.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=536 -DLWIP_FEATURES=1 -DLWIP_IPV6=0 +mercury1.menu.ip.hb2f=v2 Higher Bandwidth +mercury1.menu.ip.hb2f.build.lwip_include=lwip2/include +mercury1.menu.ip.hb2f.build.lwip_lib=-llwip2-1460-feat +mercury1.menu.ip.hb2f.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=1460 -DLWIP_FEATURES=1 -DLWIP_IPV6=0 +mercury1.menu.ip.lm2n=v2 Lower Memory (no features) +mercury1.menu.ip.lm2n.build.lwip_include=lwip2/include +mercury1.menu.ip.lm2n.build.lwip_lib=-llwip2-536 +mercury1.menu.ip.lm2n.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=536 -DLWIP_FEATURES=0 -DLWIP_IPV6=0 +mercury1.menu.ip.hb2n=v2 Higher Bandwidth (no features) +mercury1.menu.ip.hb2n.build.lwip_include=lwip2/include +mercury1.menu.ip.hb2n.build.lwip_lib=-llwip2-1460 +mercury1.menu.ip.hb2n.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=1460 -DLWIP_FEATURES=0 -DLWIP_IPV6=0 +mercury1.menu.ip.lm6f=v2 IPv6 Lower Memory +mercury1.menu.ip.lm6f.build.lwip_include=lwip2/include +mercury1.menu.ip.lm6f.build.lwip_lib=-llwip6-536-feat +mercury1.menu.ip.lm6f.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=536 -DLWIP_FEATURES=1 -DLWIP_IPV6=1 +mercury1.menu.ip.hb6f=v2 IPv6 Higher Bandwidth +mercury1.menu.ip.hb6f.build.lwip_include=lwip2/include +mercury1.menu.ip.hb6f.build.lwip_lib=-llwip6-1460-feat +mercury1.menu.ip.hb6f.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=1460 -DLWIP_FEATURES=1 -DLWIP_IPV6=1 +mercury1.menu.dbg.Disabled=Disabled +mercury1.menu.dbg.Disabled.build.debug_port= +mercury1.menu.dbg.Serial=Serial +mercury1.menu.dbg.Serial.build.debug_port=-DDEBUG_ESP_PORT=Serial +mercury1.menu.dbg.Serial1=Serial1 +mercury1.menu.dbg.Serial1.build.debug_port=-DDEBUG_ESP_PORT=Serial1 +mercury1.menu.lvl.None____=None +mercury1.menu.lvl.None____.build.debug_level= +mercury1.menu.optim.Smallest=None +mercury1.menu.optim.Smallest.build.debug_optim=-Os +mercury1.menu.optim.Lite=Lite +mercury1.menu.optim.Lite.build.debug_optim=-Os -fno-optimize-sibling-calls +mercury1.menu.optim.Full=Optimum +mercury1.menu.optim.Full.build.debug_optim=-Og +mercury1.menu.lvl.SSL=SSL +mercury1.menu.lvl.SSL.build.debug_level= -DDEBUG_ESP_SSL +mercury1.menu.lvl.TLS_MEM=TLS_MEM +mercury1.menu.lvl.TLS_MEM.build.debug_level= -DDEBUG_ESP_TLS_MEM +mercury1.menu.lvl.HTTP_CLIENT=HTTP_CLIENT +mercury1.menu.lvl.HTTP_CLIENT.build.debug_level= -DDEBUG_ESP_HTTP_CLIENT +mercury1.menu.lvl.HTTP_SERVER=HTTP_SERVER +mercury1.menu.lvl.HTTP_SERVER.build.debug_level= -DDEBUG_ESP_HTTP_SERVER +mercury1.menu.lvl.SSLTLS_MEM=SSL+TLS_MEM +mercury1.menu.lvl.SSLTLS_MEM.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM +mercury1.menu.lvl.SSLHTTP_CLIENT=SSL+HTTP_CLIENT +mercury1.menu.lvl.SSLHTTP_CLIENT.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_HTTP_CLIENT +mercury1.menu.lvl.SSLHTTP_SERVER=SSL+HTTP_SERVER +mercury1.menu.lvl.SSLHTTP_SERVER.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_HTTP_SERVER +mercury1.menu.lvl.TLS_MEMHTTP_CLIENT=TLS_MEM+HTTP_CLIENT +mercury1.menu.lvl.TLS_MEMHTTP_CLIENT.build.debug_level= -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT +mercury1.menu.lvl.TLS_MEMHTTP_SERVER=TLS_MEM+HTTP_SERVER +mercury1.menu.lvl.TLS_MEMHTTP_SERVER.build.debug_level= -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_SERVER +mercury1.menu.lvl.HTTP_CLIENTHTTP_SERVER=HTTP_CLIENT+HTTP_SERVER +mercury1.menu.lvl.HTTP_CLIENTHTTP_SERVER.build.debug_level= -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER +mercury1.menu.lvl.SSLTLS_MEMHTTP_CLIENT=SSL+TLS_MEM+HTTP_CLIENT +mercury1.menu.lvl.SSLTLS_MEMHTTP_CLIENT.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT +mercury1.menu.lvl.SSLTLS_MEMHTTP_SERVER=SSL+TLS_MEM+HTTP_SERVER +mercury1.menu.lvl.SSLTLS_MEMHTTP_SERVER.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_SERVER +mercury1.menu.lvl.SSLHTTP_CLIENTHTTP_SERVER=SSL+HTTP_CLIENT+HTTP_SERVER +mercury1.menu.lvl.SSLHTTP_CLIENTHTTP_SERVER.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER +mercury1.menu.lvl.TLS_MEMHTTP_CLIENTHTTP_SERVER=TLS_MEM+HTTP_CLIENT+HTTP_SERVER +mercury1.menu.lvl.TLS_MEMHTTP_CLIENTHTTP_SERVER.build.debug_level= -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER +mercury1.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVER=SSL+TLS_MEM+HTTP_CLIENT+HTTP_SERVER +mercury1.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVER.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER +mercury1.menu.lvl.CORE=CORE +mercury1.menu.lvl.CORE.build.debug_level= -DDEBUG_ESP_CORE +mercury1.menu.lvl.WIFI=WIFI +mercury1.menu.lvl.WIFI.build.debug_level= -DDEBUG_ESP_WIFI +mercury1.menu.lvl.HTTP_UPDATE=HTTP_UPDATE +mercury1.menu.lvl.HTTP_UPDATE.build.debug_level= -DDEBUG_ESP_HTTP_UPDATE +mercury1.menu.lvl.UPDATER=UPDATER +mercury1.menu.lvl.UPDATER.build.debug_level= -DDEBUG_ESP_UPDATER +mercury1.menu.lvl.OTA=OTA +mercury1.menu.lvl.OTA.build.debug_level= -DDEBUG_ESP_OTA +mercury1.menu.lvl.OOM=OOM +mercury1.menu.lvl.OOM.build.debug_level= -DDEBUG_ESP_OOM +mercury1.menu.lvl.MDNS=MDNS +mercury1.menu.lvl.MDNS.build.debug_level= -DDEBUG_ESP_MDNS +mercury1.menu.lvl.HWDT=HWDT +mercury1.menu.lvl.HWDT.build.debug_level= -DDEBUG_ESP_HWDT +mercury1.menu.lvl.HWDT_NOEXTRA4K=HWDT_NOEXTRA4K +mercury1.menu.lvl.HWDT_NOEXTRA4K.build.debug_level= -DDEBUG_ESP_HWDT_NOEXTRA4K +mercury1.menu.lvl.COREWIFIHTTP_UPDATEUPDATEROTAOOMMDNS=CORE+WIFI+HTTP_UPDATE+UPDATER+OTA+OOM+MDNS +mercury1.menu.lvl.COREWIFIHTTP_UPDATEUPDATEROTAOOMMDNS.build.debug_level= -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_ESP_OOM -DDEBUG_ESP_MDNS +mercury1.menu.lvl.COREWIFIHTTP_UPDATEUPDATEROTAOOMMDNSHWDT=CORE+WIFI+HTTP_UPDATE+UPDATER+OTA+OOM+MDNS+HWDT +mercury1.menu.lvl.COREWIFIHTTP_UPDATEUPDATEROTAOOMMDNSHWDT.build.debug_level= -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_ESP_OOM -DDEBUG_ESP_MDNS -DDEBUG_ESP_HWDT +mercury1.menu.lvl.COREWIFIHTTP_UPDATEUPDATEROTAOOMMDNSHWDT_NOEXTRA4K=CORE+WIFI+HTTP_UPDATE+UPDATER+OTA+OOM+MDNS+HWDT_NOEXTRA4K +mercury1.menu.lvl.COREWIFIHTTP_UPDATEUPDATEROTAOOMMDNSHWDT_NOEXTRA4K.build.debug_level= -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_ESP_OOM -DDEBUG_ESP_MDNS -DDEBUG_ESP_HWDT_NOEXTRA4K +mercury1.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVERCOREWIFIHTTP_UPDATEUPDATEROTAOOMMDNS=SSL+TLS_MEM+HTTP_CLIENT+HTTP_SERVER+CORE+WIFI+HTTP_UPDATE+UPDATER+OTA+OOM+MDNS +mercury1.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVERCOREWIFIHTTP_UPDATEUPDATEROTAOOMMDNS.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_ESP_OOM -DDEBUG_ESP_MDNS +mercury1.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVERCOREWIFIHTTP_UPDATEUPDATEROTAOOMMDNSHWDT=SSL+TLS_MEM+HTTP_CLIENT+HTTP_SERVER+CORE+WIFI+HTTP_UPDATE+UPDATER+OTA+OOM+MDNS+HWDT +mercury1.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVERCOREWIFIHTTP_UPDATEUPDATEROTAOOMMDNSHWDT.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_ESP_OOM -DDEBUG_ESP_MDNS -DDEBUG_ESP_HWDT +mercury1.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVERCOREWIFIHTTP_UPDATEUPDATEROTAOOMMDNSHWDT_NOEXTRA4K=SSL+TLS_MEM+HTTP_CLIENT+HTTP_SERVER+CORE+WIFI+HTTP_UPDATE+UPDATER+OTA+OOM+MDNS+HWDT_NOEXTRA4K +mercury1.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVERCOREWIFIHTTP_UPDATEUPDATEROTAOOMMDNSHWDT_NOEXTRA4K.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_ESP_OOM -DDEBUG_ESP_MDNS -DDEBUG_ESP_HWDT_NOEXTRA4K +mercury1.menu.lvl.NoAssert-NDEBUG=NoAssert-NDEBUG +mercury1.menu.lvl.NoAssert-NDEBUG.build.debug_level= -DNDEBUG +mercury1.menu.wipe.none=Only Sketch +mercury1.menu.wipe.none.upload.erase_cmd= +mercury1.menu.wipe.sdk=Sketch + WiFi Settings +mercury1.menu.wipe.sdk.upload.erase_cmd=erase_region "{build.rfcal_addr}" 0x4000 +mercury1.menu.wipe.all=All Flash Contents +mercury1.menu.wipe.all.upload.erase_cmd=erase_flash +mercury1.menu.baud.115200=115200 +mercury1.menu.baud.115200.upload.speed=115200 +mercury1.menu.baud.57600=57600 +mercury1.menu.baud.57600.upload.speed=57600 +mercury1.menu.baud.230400.linux=230400 +mercury1.menu.baud.230400.macosx=230400 +mercury1.menu.baud.230400.upload.speed=230400 +mercury1.menu.baud.256000.windows=256000 +mercury1.menu.baud.256000.upload.speed=256000 +mercury1.menu.baud.460800.linux=460800 +mercury1.menu.baud.460800.macosx=460800 +mercury1.menu.baud.460800.upload.speed=460800 +mercury1.menu.baud.512000.windows=512000 +mercury1.menu.baud.512000.upload.speed=512000 +mercury1.menu.baud.921600=921600 +mercury1.menu.baud.921600.upload.speed=921600 +mercury1.menu.baud.3000000=3000000 +mercury1.menu.baud.3000000.upload.speed=3000000 +mercury1.menu.eesz.autoflash=Mapping defined by Hardware and Sketch +mercury1.menu.eesz.autoflash.build.flash_size=16M +mercury1.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld +mercury1.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 +mercury1.menu.eesz.autoflash.upload.maximum_size=1044464 +mercury1.menu.iramfloat.no=in IROM +mercury1.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +mercury1.menu.iramfloat.yes=allowed in ISR +mercury1.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## nodemcu.name=NodeMCU 0.9 (ESP-12 Module) @@ -5774,6 +6086,10 @@ nodemcu.menu.eesz.autoflash.build.flash_size=16M nodemcu.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld nodemcu.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 nodemcu.menu.eesz.autoflash.upload.maximum_size=1044464 +nodemcu.menu.iramfloat.no=in IROM +nodemcu.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +nodemcu.menu.iramfloat.yes=allowed in ISR +nodemcu.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## nodemcuv2.name=NodeMCU 1.0 (ESP-12E Module) @@ -5997,6 +6313,10 @@ nodemcuv2.menu.eesz.autoflash.build.flash_size=16M nodemcuv2.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld nodemcuv2.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 nodemcuv2.menu.eesz.autoflash.upload.maximum_size=1044464 +nodemcuv2.menu.iramfloat.no=in IROM +nodemcuv2.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +nodemcuv2.menu.iramfloat.yes=allowed in ISR +nodemcuv2.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## modwifi.name=Olimex MOD-WIFI-ESP8266(-DEV) @@ -6247,6 +6567,10 @@ modwifi.menu.eesz.autoflash.build.flash_size=16M modwifi.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld modwifi.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 modwifi.menu.eesz.autoflash.upload.maximum_size=1044464 +modwifi.menu.iramfloat.no=in IROM +modwifi.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +modwifi.menu.iramfloat.yes=allowed in ISR +modwifi.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## phoenix_v1.name=Phoenix 1.0 @@ -6469,6 +6793,10 @@ phoenix_v1.menu.eesz.autoflash.build.flash_size=16M phoenix_v1.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld phoenix_v1.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 phoenix_v1.menu.eesz.autoflash.upload.maximum_size=1044464 +phoenix_v1.menu.iramfloat.no=in IROM +phoenix_v1.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +phoenix_v1.menu.iramfloat.yes=allowed in ISR +phoenix_v1.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## phoenix_v2.name=Phoenix 2.0 @@ -6691,6 +7019,10 @@ phoenix_v2.menu.eesz.autoflash.build.flash_size=16M phoenix_v2.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld phoenix_v2.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 phoenix_v2.menu.eesz.autoflash.upload.maximum_size=1044464 +phoenix_v2.menu.iramfloat.no=in IROM +phoenix_v2.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +phoenix_v2.menu.iramfloat.yes=allowed in ISR +phoenix_v2.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## eduinowifi.name=Schirmilabs Eduino WiFi @@ -6910,6 +7242,10 @@ eduinowifi.menu.eesz.autoflash.build.flash_size=16M eduinowifi.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld eduinowifi.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 eduinowifi.menu.eesz.autoflash.upload.maximum_size=1044464 +eduinowifi.menu.iramfloat.no=in IROM +eduinowifi.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +eduinowifi.menu.iramfloat.yes=allowed in ISR +eduinowifi.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## wiolink.name=Seeed Wio Link @@ -7129,6 +7465,10 @@ wiolink.menu.eesz.autoflash.build.flash_size=16M wiolink.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld wiolink.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 wiolink.menu.eesz.autoflash.upload.maximum_size=1044464 +wiolink.menu.iramfloat.no=in IROM +wiolink.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +wiolink.menu.iramfloat.yes=allowed in ISR +wiolink.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## blynk.name=SparkFun Blynk Board @@ -7348,6 +7688,10 @@ blynk.menu.eesz.autoflash.build.flash_size=16M blynk.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld blynk.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 blynk.menu.eesz.autoflash.upload.maximum_size=1044464 +blynk.menu.iramfloat.no=in IROM +blynk.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +blynk.menu.iramfloat.yes=allowed in ISR +blynk.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## thing.name=SparkFun ESP8266 Thing @@ -7567,6 +7911,10 @@ thing.menu.eesz.autoflash.build.flash_size=16M thing.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld thing.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 thing.menu.eesz.autoflash.upload.maximum_size=1044464 +thing.menu.iramfloat.no=in IROM +thing.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +thing.menu.iramfloat.yes=allowed in ISR +thing.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## thingdev.name=SparkFun ESP8266 Thing Dev @@ -7786,6 +8134,10 @@ thingdev.menu.eesz.autoflash.build.flash_size=16M thingdev.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld thingdev.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 thingdev.menu.eesz.autoflash.upload.maximum_size=1044464 +thingdev.menu.iramfloat.no=in IROM +thingdev.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +thingdev.menu.iramfloat.yes=allowed in ISR +thingdev.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## esp210.name=SweetPea ESP-210 @@ -8005,6 +8357,10 @@ esp210.menu.eesz.autoflash.build.flash_size=16M esp210.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld esp210.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 esp210.menu.eesz.autoflash.upload.maximum_size=1044464 +esp210.menu.iramfloat.no=in IROM +esp210.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +esp210.menu.iramfloat.yes=allowed in ISR +esp210.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## espinotee.name=ThaiEasyElec's ESPino @@ -8224,6 +8580,10 @@ espinotee.menu.eesz.autoflash.build.flash_size=16M espinotee.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld espinotee.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 espinotee.menu.eesz.autoflash.upload.maximum_size=1044464 +espinotee.menu.iramfloat.no=in IROM +espinotee.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +espinotee.menu.iramfloat.yes=allowed in ISR +espinotee.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## wifi_kit_8.name=WiFi Kit 8 @@ -8443,6 +8803,10 @@ wifi_kit_8.menu.eesz.autoflash.build.flash_size=16M wifi_kit_8.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld wifi_kit_8.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 wifi_kit_8.menu.eesz.autoflash.upload.maximum_size=1044464 +wifi_kit_8.menu.iramfloat.no=in IROM +wifi_kit_8.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +wifi_kit_8.menu.iramfloat.yes=allowed in ISR +wifi_kit_8.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## wifiduino.name=WiFiduino @@ -8662,6 +9026,10 @@ wifiduino.menu.eesz.autoflash.build.flash_size=16M wifiduino.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld wifiduino.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 wifiduino.menu.eesz.autoflash.upload.maximum_size=1044464 +wifiduino.menu.iramfloat.no=in IROM +wifiduino.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +wifiduino.menu.iramfloat.yes=allowed in ISR +wifiduino.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## wifinfo.name=WifInfo @@ -8937,6 +9305,10 @@ wifinfo.menu.eesz.autoflash.build.flash_size=16M wifinfo.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld wifinfo.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 wifinfo.menu.eesz.autoflash.upload.maximum_size=1044464 +wifinfo.menu.iramfloat.no=in IROM +wifinfo.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +wifinfo.menu.iramfloat.yes=allowed in ISR +wifinfo.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM ############################################################## cw01.name=XinaBox CW01 @@ -9159,4 +9531,8 @@ cw01.menu.eesz.autoflash.build.flash_size=16M cw01.menu.eesz.autoflash.build.flash_ld=eagle.flash.auto.ld cw01.menu.eesz.autoflash.build.extra_flags=-DFLASH_MAP_SUPPORT=1 cw01.menu.eesz.autoflash.upload.maximum_size=1044464 +cw01.menu.iramfloat.no=in IROM +cw01.menu.iramfloat.no.build.iramfloat=-DFP_IN_IROM +cw01.menu.iramfloat.yes=allowed in ISR +cw01.menu.iramfloat.yes.build.iramfloat=-DFP_IN_IRAM diff --git a/cores/esp8266/LwipIntf.cpp b/cores/esp8266/LwipIntf.cpp index e142730df0..675063cd62 100644 --- a/cores/esp8266/LwipIntf.cpp +++ b/cores/esp8266/LwipIntf.cpp @@ -43,7 +43,7 @@ extern "C" // can return nullptr when STA is down // - Because WiFi is started in off mode at boot time, // wifi_station_set/get_hostname() is now no more used -// because setting hostname firt does not work anymore +// because setting hostname first does not work anymore // - wifi_station_hostname is overwritten by SDK when wifi is // woken up in WiFi::mode() // diff --git a/cores/esp8266/LwipIntfDev.h b/cores/esp8266/LwipIntfDev.h index 389376c976..d69e2d73d8 100644 --- a/cores/esp8266/LwipIntfDev.h +++ b/cores/esp8266/LwipIntfDev.h @@ -63,17 +63,31 @@ class LwipIntfDev: public LwipIntf, public RawDev memset(&_netif, 0, sizeof(_netif)); } + //The argument order for ESP is not the same as for Arduino. However, there is compatibility code under the hood + //to detect Arduino arg order, and handle it correctly. boolean config(const IPAddress& local_ip, const IPAddress& arg1, const IPAddress& arg2, const IPAddress& arg3 = IPADDR_NONE, const IPAddress& dns2 = IPADDR_NONE); + // two and one parameter version. 2nd parameter is DNS like in Arduino. IPv4 only + [[deprecated("It is discouraged to use this 1 or 2 parameters network configuration legacy " + "function config(ip[,dns]) as chosen defaults may not match the local network " + "configuration")]] boolean + config(IPAddress local_ip, IPAddress dns = INADDR_ANY); + // default mac-address is inferred from esp8266's STA interface boolean begin(const uint8_t* macAddress = nullptr, const uint16_t mtu = DEFAULT_MTU); + void end(); const netif* getNetIf() const { return &_netif; } + uint8_t* macAddress(uint8_t* mac) + { + memcpy(mac, &_netif.hwaddr, 6); + return mac; + } IPAddress localIP() const { return IPAddress(ip4_addr_get_u32(ip_2_ip4(&_netif.ip_addr))); @@ -86,6 +100,21 @@ class LwipIntfDev: public LwipIntf, public RawDev { return IPAddress(ip4_addr_get_u32(ip_2_ip4(&_netif.gw))); } + IPAddress dnsIP(int n = 0) const + { + return IPAddress(dns_getserver(n)); + } + void setDNS(IPAddress dns1, IPAddress dns2 = INADDR_ANY) + { + if (dns1.isSet()) + { + dns_setserver(0, dns1); + } + if (dns2.isSet()) + { + dns_setserver(1, dns2); + } + } // 1. Currently when no default is set, esp8266-Arduino uses the first // DHCP client interface receiving a valid address and gateway to @@ -138,6 +167,7 @@ class LwipIntfDev: public LwipIntf, public RawDev int8_t _intrPin; uint8_t _macAddress[6]; bool _started; + bool _scheduled; bool _default; }; @@ -175,6 +205,24 @@ boolean LwipIntfDev::config(const IPAddress& localIP, const IPAddress& g return true; } +template +boolean LwipIntfDev::config(IPAddress local_ip, IPAddress dns) +{ + if (!local_ip.isSet()) + return config(INADDR_ANY, INADDR_ANY, INADDR_ANY); + + if (!local_ip.isV4()) + return false; + + IPAddress gw(local_ip); + gw[3] = 1; + if (!dns.isSet()) + { + dns = gw; + } + return config(local_ip, gw, IPAddress(255, 255, 255, 0), dns); +} + template boolean LwipIntfDev::begin(const uint8_t* macAddress, const uint16_t mtu) { @@ -229,6 +277,7 @@ boolean LwipIntfDev::begin(const uint8_t* macAddress, const uint16_t mtu if (!netif_add(&_netif, ip_2_ip4(&ip_addr), ip_2_ip4(&netmask), ip_2_ip4(&gw), this, netif_init_s, ethernet_input)) { + RawDev::end(); return false; } @@ -242,10 +291,11 @@ boolean LwipIntfDev::begin(const uint8_t* macAddress, const uint16_t mtu break; case ERR_IF: + RawDev::end(); return false; default: - netif_remove(&_netif); + end(); return false; } } @@ -272,22 +322,41 @@ boolean LwipIntfDev::begin(const uint8_t* macAddress, const uint16_t mtu } } - if (_intrPin < 0 - && !schedule_recurrent_function_us( + if (_intrPin < 0 && !_scheduled) + { + _scheduled = schedule_recurrent_function_us( [&]() { + if (!_started) + { + _scheduled = false; + return false; + } this->handlePackets(); return true; }, - 100)) - { - netif_remove(&_netif); - return false; + 100); + if (!_scheduled) + { + end(); + return false; + } } return true; } +template +void LwipIntfDev::end() +{ + if (_started) + { + netif_remove(&_netif); + _started = false; + RawDev::end(); + } +} + template wl_status_t LwipIntfDev::status() { diff --git a/cores/esp8266/StackThunk.cpp b/cores/esp8266/StackThunk.cpp index 0d2a8a3541..baa793bdc5 100644 --- a/cores/esp8266/StackThunk.cpp +++ b/cores/esp8266/StackThunk.cpp @@ -27,18 +27,26 @@ #include #include #include -#include "pgmspace.h" + #include "debug.h" #include "StackThunk.h" + +#include #include + #include #include extern "C" { +extern void optimistic_yield(uint32_t); + uint32_t *stack_thunk_ptr = NULL; uint32_t *stack_thunk_top = NULL; + uint32_t *stack_thunk_save = NULL; /* Saved A1 while in BearSSL */ +uint32_t *stack_thunk_yield_save = NULL; /* Saved A1 when yielding from within BearSSL */ + uint32_t stack_thunk_refcnt = 0; /* Largest stack usage seen in the wild at 6120 */ @@ -150,4 +158,37 @@ void stack_thunk_fatal_smashing() __stack_chk_fail(); } +/* Called within bearssl code instead of optimistic_yield(...) */ +void stack_thunk_yield(); +asm( + ".section .text.stack_thunk_yield,\"ax\",@progbits\n\t" + ".literal_position\n\t" + ".align 4\n\t" + ".global stack_thunk_yield\n\t" + ".type stack_thunk_yield, @function\n\t" + "\n" +"stack_thunk_yield:\n\t" +/* Keep the original caller */ + "addi a1, a1, -16\n\t" + "s32i.n a0, a1, 12\n\t" +/* Swap bearssl <-> cont stacks */ + "movi a2, stack_thunk_yield_save\n\t" + "s32i.n a1, a2, 0\n\t" + "movi a2, stack_thunk_save\n\t" + "l32i.n a1, a2, 0\n\t" +/* optimistic_yield(10000) without extra l32r */ + "movi a2, 0x10\n\t" + "addmi a2, a2, 0x2700\n\t" + "call0 optimistic_yield\n\t" +/* Swap bearssl <-> cont stacks, again */ + "movi a2, stack_thunk_yield_save\n\t" + "l32i.n a1, a2, 0\n\t" + "\n" +/* Restore caller */ + "l32i.n a0, a1, 12\n\t" + "addi a1, a1, 16\n\t" + "ret.n\n\t" + ".size stack_thunk_yield, .-stack_thunk_yield\n\t" +); + } diff --git a/cores/esp8266/StackThunk.h b/cores/esp8266/StackThunk.h index e72e0efb9f..350775ec24 100644 --- a/cores/esp8266/StackThunk.h +++ b/cores/esp8266/StackThunk.h @@ -31,6 +31,8 @@ extern "C" { #endif +extern void stack_thunk_yield(void); + extern void stack_thunk_add_ref(); extern void stack_thunk_del_ref(); extern void stack_thunk_repaint(); diff --git a/cores/esp8266/Stream.cpp b/cores/esp8266/Stream.cpp index a901c8d437..b9b5b95f65 100644 --- a/cores/esp8266/Stream.cpp +++ b/cores/esp8266/Stream.cpp @@ -262,6 +262,32 @@ String Stream::readStringUntil(char terminator) { return ret; } +String Stream::readStringUntil(const char* terminator, uint32_t untilTotalNumberOfOccurrences) { + String ret; + int c; + uint32_t occurrences = 0; + size_t termLen = strlen(terminator); + size_t termIndex = 0; + size_t index = 0; + + while ((c = timedRead()) > 0) { + ret += (char) c; + index++; + + if (terminator[termIndex] == c) { + if (++termIndex == termLen && ++occurrences == untilTotalNumberOfOccurrences) { + // don't include terminator in returned string + ret.remove(index - termIndex, termLen); + break; + } + } else { + termIndex = 0; + } + } + + return ret; +} + // read what can be read, immediate exit on unavailable data // prototype similar to Arduino's `int Client::read(buf, len)` int Stream::read (uint8_t* buffer, size_t maxLen) diff --git a/cores/esp8266/Stream.h b/cores/esp8266/Stream.h index f39bb423f2..0706bec001 100644 --- a/cores/esp8266/Stream.h +++ b/cores/esp8266/Stream.h @@ -115,6 +115,7 @@ class Stream: public Print { // Arduino String functions to be added here virtual String readString(); String readStringUntil(char terminator); + String readStringUntil(const char* terminator, uint32_t untilTotalNumberOfOccurrences = 1); virtual int read (uint8_t* buffer, size_t len); int read (char* buffer, size_t len) { return read((uint8_t*)buffer, len); } @@ -195,21 +196,25 @@ class Stream: public Print { // returns number of transferred bytes size_t sendAvailable (Stream* to) { return sendGeneric(to, -1, -1, oneShotMs::alwaysExpired); } size_t sendAvailable (Stream& to) { return sendAvailable(&to); } + size_t sendAvailable (Stream&& to) { return sendAvailable(&to); } // transfers data until timeout // returns number of transferred bytes size_t sendAll (Stream* to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, -1, timeoutMs); } size_t sendAll (Stream& to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendAll(&to, timeoutMs); } + size_t sendAll (Stream&& to, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendAll(&to, timeoutMs); } // transfers data until a char is encountered (the char is swallowed but not transferred) with timeout // returns number of transferred bytes size_t sendUntil (Stream* to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, -1, readUntilChar, timeoutMs); } size_t sendUntil (Stream& to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendUntil(&to, readUntilChar, timeoutMs); } + size_t sendUntil (Stream&& to, const int readUntilChar, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendUntil(&to, readUntilChar, timeoutMs); } // transfers data until requested size or timeout // returns number of transferred bytes size_t sendSize (Stream* to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendGeneric(to, maxLen, -1, timeoutMs); } size_t sendSize (Stream& to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendSize(&to, maxLen, timeoutMs); } + size_t sendSize (Stream&& to, const ssize_t maxLen, const oneShotMs::timeType timeoutMs = oneShotMs::neverExpires) { return sendSize(&to, maxLen, timeoutMs); } // remaining size (-1 by default = unknown) virtual ssize_t streamRemaining () { return -1; } diff --git a/cores/esp8266/StreamString.h b/cores/esp8266/StreamString.h index 2331a3c51a..dced5aee80 100644 --- a/cores/esp8266/StreamString.h +++ b/cores/esp8266/StreamString.h @@ -29,7 +29,7 @@ #include "WString.h" /////////////////////////////////////////////////////////////// -// S2Stream points to a String and makes it a Stream +// S2Stream ("String to Stream") points to a String and makes it a Stream // (it is also the helper for StreamString) class S2Stream: public Stream @@ -184,19 +184,18 @@ class S2Stream: public Stream return peekPointer < 0 ? string->length() : string->length() - peekPointer; } - // calling setConsume() will consume bytes as the stream is read - // (enabled by default) + // calling setConsume() will make the string consumed as the stream is read. + // (default behaviour) void setConsume() { peekPointer = -1; } - // Reading this stream will mark the string as read without consuming - // (not enabled by default) - // Calling resetPointer() resets the read state and allows rereading. - void resetPointer(int pointer = 0) + // Calling resetPointer() resets the read cursor and allows rereading. + // (this is the opposite of default mode set by setConsume()) + void resetPointer(size_t pointer = 0) { - peekPointer = pointer; + peekPointer = std::min(pointer, (size_t)string->length()); } protected: @@ -204,6 +203,7 @@ class S2Stream: public Stream int peekPointer; // -1:String is consumed / >=0:resettable pointer }; +/////////////////////////////////////////////////////////////// // StreamString is a S2Stream holding the String class StreamString: public String, public S2Stream diff --git a/cores/esp8266/TZ.h b/cores/esp8266/TZ.h index b0fb312ba3..478abb16c0 100644 --- a/cores/esp8266/TZ.h +++ b/cores/esp8266/TZ.h @@ -1,22 +1,16 @@ +// ! ! ! DO NOT EDIT, AUTOMATICALLY GENERATED ! ! ! +// File created 2024-02-05 00:00:00.000000+00:00 +// Based on IANA database 2023d +// Re-run /tools/tools/format_tzdata.py to update -// autogenerated from https://raw.githubusercontent.com/nayarsystems/posix_tz_db/master/zones.csv -// by script /tools/TZupdate.sh -// Mon Mar 20 22:00:17 UTC 2023 -// -// This database is autogenerated from IANA timezone database -// https://raw.githubusercontent.com/nayarsystems/posix_tz_db/master/zones.csv -// (using https://www.iana.org/time-zones) -// and can be updated on demand in this repository -// or by yourself using the above script - -#ifndef TZDB_H -#define TZDB_H +#pragma once #define TZ_Africa_Abidjan PSTR("GMT0") #define TZ_Africa_Accra PSTR("GMT0") #define TZ_Africa_Addis_Ababa PSTR("EAT-3") #define TZ_Africa_Algiers PSTR("CET-1") #define TZ_Africa_Asmara PSTR("EAT-3") +#define TZ_Africa_Asmera PSTR("EAT-3") #define TZ_Africa_Bamako PSTR("GMT0") #define TZ_Africa_Bangui PSTR("WAT-1") #define TZ_Africa_Banjul PSTR("GMT0") @@ -24,7 +18,7 @@ #define TZ_Africa_Blantyre PSTR("CAT-2") #define TZ_Africa_Brazzaville PSTR("WAT-1") #define TZ_Africa_Bujumbura PSTR("CAT-2") -#define TZ_Africa_Cairo PSTR("EET-2") +#define TZ_Africa_Cairo PSTR("EET-2EEST,M4.5.5/0,M10.5.4/24") #define TZ_Africa_Casablanca PSTR("<+01>-1") #define TZ_Africa_Ceuta PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Africa_Conakry PSTR("GMT0") @@ -61,6 +55,7 @@ #define TZ_Africa_Ouagadougou PSTR("GMT0") #define TZ_Africa_PortomNovo PSTR("WAT-1") #define TZ_Africa_Sao_Tome PSTR("GMT0") +#define TZ_Africa_Timbuktu PSTR("GMT0") #define TZ_Africa_Tripoli PSTR("EET-2") #define TZ_Africa_Tunis PSTR("CET-1") #define TZ_Africa_Windhoek PSTR("CAT-2") @@ -71,6 +66,7 @@ #define TZ_America_Araguaina PSTR("<-03>3") #define TZ_America_Argentina_Buenos_Aires PSTR("<-03>3") #define TZ_America_Argentina_Catamarca PSTR("<-03>3") +#define TZ_America_Argentina_ComodRivadavia PSTR("<-03>3") #define TZ_America_Argentina_Cordoba PSTR("<-03>3") #define TZ_America_Argentina_Jujuy PSTR("<-03>3") #define TZ_America_Argentina_La_Rioja PSTR("<-03>3") @@ -84,6 +80,7 @@ #define TZ_America_Aruba PSTR("AST4") #define TZ_America_Asuncion PSTR("<-04>4<-03>,M10.1.0/0,M3.4.0/0") #define TZ_America_Atikokan PSTR("EST5") +#define TZ_America_Atka PSTR("HST10HDT,M3.2.0,M11.1.0") #define TZ_America_Bahia PSTR("<-03>3") #define TZ_America_Bahia_Banderas PSTR("CST6") #define TZ_America_Barbados PSTR("AST4") @@ -93,14 +90,19 @@ #define TZ_America_Boa_Vista PSTR("<-04>4") #define TZ_America_Bogota PSTR("<-05>5") #define TZ_America_Boise PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_America_Buenos_Aires PSTR("<-03>3") #define TZ_America_Cambridge_Bay PSTR("MST7MDT,M3.2.0,M11.1.0") #define TZ_America_Campo_Grande PSTR("<-04>4") #define TZ_America_Cancun PSTR("EST5") #define TZ_America_Caracas PSTR("<-04>4") +#define TZ_America_Catamarca PSTR("<-03>3") #define TZ_America_Cayenne PSTR("<-03>3") #define TZ_America_Cayman PSTR("EST5") #define TZ_America_Chicago PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Chihuahua PSTR("CST6") +#define TZ_America_Ciudad_Juarez PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_America_Coral_Harbour PSTR("EST5") +#define TZ_America_Cordoba PSTR("<-03>3") #define TZ_America_Costa_Rica PSTR("CST6") #define TZ_America_Creston PSTR("MST7") #define TZ_America_Cuiaba PSTR("<-04>4") @@ -114,10 +116,12 @@ #define TZ_America_Edmonton PSTR("MST7MDT,M3.2.0,M11.1.0") #define TZ_America_Eirunepe PSTR("<-05>5") #define TZ_America_El_Salvador PSTR("CST6") -#define TZ_America_Fortaleza PSTR("<-03>3") +#define TZ_America_Ensenada PSTR("PST8PDT,M3.2.0,M11.1.0") #define TZ_America_Fort_Nelson PSTR("MST7") +#define TZ_America_Fort_Wayne PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_America_Fortaleza PSTR("<-03>3") #define TZ_America_Glace_Bay PSTR("AST4ADT,M3.2.0,M11.1.0") -#define TZ_America_Godthab PSTR("<-02>2") +#define TZ_America_Godthab PSTR("<-02>2<-01>,M3.5.0/-1,M10.5.0/0") #define TZ_America_Goose_Bay PSTR("AST4ADT,M3.2.0,M11.1.0") #define TZ_America_Grand_Turk PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Grenada PSTR("AST4") @@ -136,16 +140,20 @@ #define TZ_America_Indiana_Vevay PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Indiana_Vincennes PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Indiana_Winamac PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_America_Indianapolis PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Inuvik PSTR("MST7MDT,M3.2.0,M11.1.0") #define TZ_America_Iqaluit PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Jamaica PSTR("EST5") +#define TZ_America_Jujuy PSTR("<-03>3") #define TZ_America_Juneau PSTR("AKST9AKDT,M3.2.0,M11.1.0") #define TZ_America_Kentucky_Louisville PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Kentucky_Monticello PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_America_Knox_IN PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Kralendijk PSTR("AST4") #define TZ_America_La_Paz PSTR("<-04>4") #define TZ_America_Lima PSTR("<-05>5") #define TZ_America_Los_Angeles PSTR("PST8PDT,M3.2.0,M11.1.0") +#define TZ_America_Louisville PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Lower_Princes PSTR("AST4") #define TZ_America_Maceio PSTR("<-03>3") #define TZ_America_Managua PSTR("CST6") @@ -154,6 +162,7 @@ #define TZ_America_Martinique PSTR("AST4") #define TZ_America_Matamoros PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Mazatlan PSTR("MST7") +#define TZ_America_Mendoza PSTR("<-03>3") #define TZ_America_Menominee PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Merida PSTR("CST6") #define TZ_America_Metlakatla PSTR("AKST9AKDT,M3.2.0,M11.1.0") @@ -172,7 +181,7 @@ #define TZ_America_North_Dakota_Beulah PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_North_Dakota_Center PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_North_Dakota_New_Salem PSTR("CST6CDT,M3.2.0,M11.1.0") -#define TZ_America_Nuuk PSTR("<-02>2") +#define TZ_America_Nuuk PSTR("<-02>2<-01>,M3.5.0/-1,M10.5.0/0") #define TZ_America_Ojinaga PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Panama PSTR("EST5") #define TZ_America_Pangnirtung PSTR("EST5EDT,M3.2.0,M11.1.0") @@ -180,6 +189,7 @@ #define TZ_America_Phoenix PSTR("MST7") #define TZ_America_PortmaumPrince PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Port_of_Spain PSTR("AST4") +#define TZ_America_Porto_Acre PSTR("<-05>5") #define TZ_America_Porto_Velho PSTR("<-04>4") #define TZ_America_Puerto_Rico PSTR("AST4") #define TZ_America_Punta_Arenas PSTR("<-03>3") @@ -189,11 +199,14 @@ #define TZ_America_Regina PSTR("CST6") #define TZ_America_Resolute PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Rio_Branco PSTR("<-05>5") +#define TZ_America_Rosario PSTR("<-03>3") +#define TZ_America_Santa_Isabel PSTR("PST8PDT,M3.2.0,M11.1.0") #define TZ_America_Santarem PSTR("<-03>3") #define TZ_America_Santiago PSTR("<-04>4<-03>,M9.1.6/24,M4.1.6/24") #define TZ_America_Santo_Domingo PSTR("AST4") #define TZ_America_Sao_Paulo PSTR("<-03>3") -#define TZ_America_Scoresbysund PSTR("<-01>1<+00>,M3.5.0/0,M10.5.0/1") +#define TZ_America_Scoresbysund PSTR("<-02>2<-01>,M3.5.0/-1,M10.5.0/0") +#define TZ_America_Shiprock PSTR("MST7MDT,M3.2.0,M11.1.0") #define TZ_America_Sitka PSTR("AKST9AKDT,M3.2.0,M11.1.0") #define TZ_America_St_Barthelemy PSTR("AST4") #define TZ_America_St_Johns PSTR("NST3:30NDT,M3.2.0,M11.1.0") @@ -209,11 +222,12 @@ #define TZ_America_Toronto PSTR("EST5EDT,M3.2.0,M11.1.0") #define TZ_America_Tortola PSTR("AST4") #define TZ_America_Vancouver PSTR("PST8PDT,M3.2.0,M11.1.0") +#define TZ_America_Virgin PSTR("AST4") #define TZ_America_Whitehorse PSTR("MST7") #define TZ_America_Winnipeg PSTR("CST6CDT,M3.2.0,M11.1.0") #define TZ_America_Yakutat PSTR("AKST9AKDT,M3.2.0,M11.1.0") #define TZ_America_Yellowknife PSTR("MST7MDT,M3.2.0,M11.1.0") -#define TZ_Antarctica_Casey PSTR("<+11>-11") +#define TZ_Antarctica_Casey PSTR("<+08>-8") #define TZ_Antarctica_Davis PSTR("<+07>-7") #define TZ_Antarctica_DumontDUrville PSTR("<+10>-10") #define TZ_Antarctica_Macquarie PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") @@ -221,9 +235,10 @@ #define TZ_Antarctica_McMurdo PSTR("NZST-12NZDT,M9.5.0,M4.1.0/3") #define TZ_Antarctica_Palmer PSTR("<-03>3") #define TZ_Antarctica_Rothera PSTR("<-03>3") +#define TZ_Antarctica_South_Pole PSTR("NZST-12NZDT,M9.5.0,M4.1.0/3") #define TZ_Antarctica_Syowa PSTR("<+03>-3") #define TZ_Antarctica_Troll PSTR("<+00>0<+02>-2,M3.5.0/1,M10.5.0/3") -#define TZ_Antarctica_Vostok PSTR("<+06>-6") +#define TZ_Antarctica_Vostok PSTR("<+05>-5") #define TZ_Arctic_Longyearbyen PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Asia_Aden PSTR("<+03>-3") #define TZ_Asia_Almaty PSTR("<+06>-6") @@ -232,6 +247,7 @@ #define TZ_Asia_Aqtau PSTR("<+05>-5") #define TZ_Asia_Aqtobe PSTR("<+05>-5") #define TZ_Asia_Ashgabat PSTR("<+05>-5") +#define TZ_Asia_Ashkhabad PSTR("<+05>-5") #define TZ_Asia_Atyrau PSTR("<+05>-5") #define TZ_Asia_Baghdad PSTR("<+03>-3") #define TZ_Asia_Bahrain PSTR("<+03>-3") @@ -241,9 +257,13 @@ #define TZ_Asia_Beirut PSTR("EET-2EEST,M3.5.0/0,M10.5.0/0") #define TZ_Asia_Bishkek PSTR("<+06>-6") #define TZ_Asia_Brunei PSTR("<+08>-8") +#define TZ_Asia_Calcutta PSTR("IST-5:30") #define TZ_Asia_Chita PSTR("<+09>-9") #define TZ_Asia_Choibalsan PSTR("<+08>-8") +#define TZ_Asia_Chongqing PSTR("CST-8") +#define TZ_Asia_Chungking PSTR("CST-8") #define TZ_Asia_Colombo PSTR("<+0530>-5:30") +#define TZ_Asia_Dacca PSTR("<+06>-6") #define TZ_Asia_Damascus PSTR("<+03>-3") #define TZ_Asia_Dhaka PSTR("<+06>-6") #define TZ_Asia_Dili PSTR("<+09>-9") @@ -251,24 +271,29 @@ #define TZ_Asia_Dushanbe PSTR("<+05>-5") #define TZ_Asia_Famagusta PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Asia_Gaza PSTR("EET-2EEST,M3.4.4/50,M10.4.4/50") +#define TZ_Asia_Harbin PSTR("CST-8") #define TZ_Asia_Hebron PSTR("EET-2EEST,M3.4.4/50,M10.4.4/50") #define TZ_Asia_Ho_Chi_Minh PSTR("<+07>-7") #define TZ_Asia_Hong_Kong PSTR("HKT-8") #define TZ_Asia_Hovd PSTR("<+07>-7") #define TZ_Asia_Irkutsk PSTR("<+08>-8") +#define TZ_Asia_Istanbul PSTR("<+03>-3") #define TZ_Asia_Jakarta PSTR("WIB-7") #define TZ_Asia_Jayapura PSTR("WIT-9") #define TZ_Asia_Jerusalem PSTR("IST-2IDT,M3.4.4/26,M10.5.0") #define TZ_Asia_Kabul PSTR("<+0430>-4:30") #define TZ_Asia_Kamchatka PSTR("<+12>-12") #define TZ_Asia_Karachi PSTR("PKT-5") +#define TZ_Asia_Kashgar PSTR("<+06>-6") #define TZ_Asia_Kathmandu PSTR("<+0545>-5:45") +#define TZ_Asia_Katmandu PSTR("<+0545>-5:45") #define TZ_Asia_Khandyga PSTR("<+09>-9") #define TZ_Asia_Kolkata PSTR("IST-5:30") #define TZ_Asia_Krasnoyarsk PSTR("<+07>-7") #define TZ_Asia_Kuala_Lumpur PSTR("<+08>-8") #define TZ_Asia_Kuching PSTR("<+08>-8") #define TZ_Asia_Kuwait PSTR("<+03>-3") +#define TZ_Asia_Macao PSTR("CST-8") #define TZ_Asia_Macau PSTR("CST-8") #define TZ_Asia_Magadan PSTR("<+11>-11") #define TZ_Asia_Makassar PSTR("WITA-8") @@ -283,8 +308,11 @@ #define TZ_Asia_Pontianak PSTR("WIB-7") #define TZ_Asia_Pyongyang PSTR("KST-9") #define TZ_Asia_Qatar PSTR("<+03>-3") +#define TZ_Asia_Qostanay PSTR("<+06>-6") #define TZ_Asia_Qyzylorda PSTR("<+05>-5") +#define TZ_Asia_Rangoon PSTR("<+0630>-6:30") #define TZ_Asia_Riyadh PSTR("<+03>-3") +#define TZ_Asia_Saigon PSTR("<+07>-7") #define TZ_Asia_Sakhalin PSTR("<+11>-11") #define TZ_Asia_Samarkand PSTR("<+05>-5") #define TZ_Asia_Seoul PSTR("KST-9") @@ -295,10 +323,14 @@ #define TZ_Asia_Tashkent PSTR("<+05>-5") #define TZ_Asia_Tbilisi PSTR("<+04>-4") #define TZ_Asia_Tehran PSTR("<+0330>-3:30") +#define TZ_Asia_Tel_Aviv PSTR("IST-2IDT,M3.4.4/26,M10.5.0") +#define TZ_Asia_Thimbu PSTR("<+06>-6") #define TZ_Asia_Thimphu PSTR("<+06>-6") #define TZ_Asia_Tokyo PSTR("JST-9") #define TZ_Asia_Tomsk PSTR("<+07>-7") +#define TZ_Asia_Ujung_Pandang PSTR("WITA-8") #define TZ_Asia_Ulaanbaatar PSTR("<+08>-8") +#define TZ_Asia_Ulan_Bator PSTR("<+08>-8") #define TZ_Asia_Urumqi PSTR("<+06>-6") #define TZ_Asia_UstmNera PSTR("<+10>-10") #define TZ_Asia_Vientiane PSTR("<+07>-7") @@ -311,28 +343,99 @@ #define TZ_Atlantic_Bermuda PSTR("AST4ADT,M3.2.0,M11.1.0") #define TZ_Atlantic_Canary PSTR("WET0WEST,M3.5.0/1,M10.5.0") #define TZ_Atlantic_Cape_Verde PSTR("<-01>1") +#define TZ_Atlantic_Faeroe PSTR("WET0WEST,M3.5.0/1,M10.5.0") #define TZ_Atlantic_Faroe PSTR("WET0WEST,M3.5.0/1,M10.5.0") +#define TZ_Atlantic_Jan_Mayen PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Atlantic_Madeira PSTR("WET0WEST,M3.5.0/1,M10.5.0") #define TZ_Atlantic_Reykjavik PSTR("GMT0") #define TZ_Atlantic_South_Georgia PSTR("<-02>2") -#define TZ_Atlantic_Stanley PSTR("<-03>3") #define TZ_Atlantic_St_Helena PSTR("GMT0") +#define TZ_Atlantic_Stanley PSTR("<-03>3") +#define TZ_Australia_ACT PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") #define TZ_Australia_Adelaide PSTR("ACST-9:30ACDT,M10.1.0,M4.1.0/3") #define TZ_Australia_Brisbane PSTR("AEST-10") #define TZ_Australia_Broken_Hill PSTR("ACST-9:30ACDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_Canberra PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") #define TZ_Australia_Currie PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") #define TZ_Australia_Darwin PSTR("ACST-9:30") #define TZ_Australia_Eucla PSTR("<+0845>-8:45") #define TZ_Australia_Hobart PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_LHI PSTR("<+1030>-10:30<+11>-11,M10.1.0,M4.1.0") #define TZ_Australia_Lindeman PSTR("AEST-10") #define TZ_Australia_Lord_Howe PSTR("<+1030>-10:30<+11>-11,M10.1.0,M4.1.0") #define TZ_Australia_Melbourne PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_NSW PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_North PSTR("ACST-9:30") #define TZ_Australia_Perth PSTR("AWST-8") +#define TZ_Australia_Queensland PSTR("AEST-10") +#define TZ_Australia_South PSTR("ACST-9:30ACDT,M10.1.0,M4.1.0/3") #define TZ_Australia_Sydney PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_Tasmania PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_Victoria PSTR("AEST-10AEDT,M10.1.0,M4.1.0/3") +#define TZ_Australia_West PSTR("AWST-8") +#define TZ_Australia_Yancowinna PSTR("ACST-9:30ACDT,M10.1.0,M4.1.0/3") +#define TZ_Brazil_Acre PSTR("<-05>5") +#define TZ_Brazil_DeNoronha PSTR("<-02>2") +#define TZ_Brazil_East PSTR("<-03>3") +#define TZ_Brazil_West PSTR("<-04>4") +#define TZ_CET PSTR("CET-1CEST,M3.5.0,M10.5.0/3") +#define TZ_CST6CDT PSTR("CST6CDT,M3.2.0,M11.1.0") +#define TZ_Canada_Atlantic PSTR("AST4ADT,M3.2.0,M11.1.0") +#define TZ_Canada_Central PSTR("CST6CDT,M3.2.0,M11.1.0") +#define TZ_Canada_Eastern PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_Canada_Mountain PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_Canada_Newfoundland PSTR("NST3:30NDT,M3.2.0,M11.1.0") +#define TZ_Canada_Pacific PSTR("PST8PDT,M3.2.0,M11.1.0") +#define TZ_Canada_Saskatchewan PSTR("CST6") +#define TZ_Canada_Yukon PSTR("MST7") +#define TZ_Chile_Continental PSTR("<-04>4<-03>,M9.1.6/24,M4.1.6/24") +#define TZ_Chile_EasterIsland PSTR("<-06>6<-05>,M9.1.6/22,M4.1.6/22") +#define TZ_Cuba PSTR("CST5CDT,M3.2.0/0,M11.1.0/1") +#define TZ_EET PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") +#define TZ_EST PSTR("EST5") +#define TZ_EST5EDT PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_Egypt PSTR("EET-2EEST,M4.5.5/0,M10.5.4/24") +#define TZ_Eire PSTR("IST-1GMT0,M10.5.0,M3.5.0/1") +#define TZ_Etc_GMT PSTR("GMT0") +#define TZ_Etc_GMTp0 PSTR("GMT0") +#define TZ_Etc_GMTp1 PSTR("<-01>1") +#define TZ_Etc_GMTp10 PSTR("<-10>10") +#define TZ_Etc_GMTp11 PSTR("<-11>11") +#define TZ_Etc_GMTp12 PSTR("<-12>12") +#define TZ_Etc_GMTp2 PSTR("<-02>2") +#define TZ_Etc_GMTp3 PSTR("<-03>3") +#define TZ_Etc_GMTp4 PSTR("<-04>4") +#define TZ_Etc_GMTp5 PSTR("<-05>5") +#define TZ_Etc_GMTp6 PSTR("<-06>6") +#define TZ_Etc_GMTp7 PSTR("<-07>7") +#define TZ_Etc_GMTp8 PSTR("<-08>8") +#define TZ_Etc_GMTp9 PSTR("<-09>9") +#define TZ_Etc_GMTm0 PSTR("GMT0") +#define TZ_Etc_GMTm1 PSTR("<+01>-1") +#define TZ_Etc_GMTm10 PSTR("<+10>-10") +#define TZ_Etc_GMTm11 PSTR("<+11>-11") +#define TZ_Etc_GMTm12 PSTR("<+12>-12") +#define TZ_Etc_GMTm13 PSTR("<+13>-13") +#define TZ_Etc_GMTm14 PSTR("<+14>-14") +#define TZ_Etc_GMTm2 PSTR("<+02>-2") +#define TZ_Etc_GMTm3 PSTR("<+03>-3") +#define TZ_Etc_GMTm4 PSTR("<+04>-4") +#define TZ_Etc_GMTm5 PSTR("<+05>-5") +#define TZ_Etc_GMTm6 PSTR("<+06>-6") +#define TZ_Etc_GMTm7 PSTR("<+07>-7") +#define TZ_Etc_GMTm8 PSTR("<+08>-8") +#define TZ_Etc_GMTm9 PSTR("<+09>-9") +#define TZ_Etc_GMT0 PSTR("GMT0") +#define TZ_Etc_Greenwich PSTR("GMT0") +#define TZ_Etc_UCT PSTR("UTC0") +#define TZ_Etc_UTC PSTR("UTC0") +#define TZ_Etc_Universal PSTR("UTC0") +#define TZ_Etc_Zulu PSTR("UTC0") #define TZ_Europe_Amsterdam PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Andorra PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Astrakhan PSTR("<+04>-4") #define TZ_Europe_Athens PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") +#define TZ_Europe_Belfast PSTR("GMT0BST,M3.5.0/1,M10.5.0") #define TZ_Europe_Belgrade PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Berlin PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Bratislava PSTR("CET-1CEST,M3.5.0,M10.5.0/3") @@ -351,7 +454,8 @@ #define TZ_Europe_Jersey PSTR("GMT0BST,M3.5.0/1,M10.5.0") #define TZ_Europe_Kaliningrad PSTR("EET-2") #define TZ_Europe_Kiev PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") -#define TZ_Europe_Kirov PSTR("<+03>-3") +#define TZ_Europe_Kirov PSTR("MSK-3") +#define TZ_Europe_Kyiv PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Lisbon PSTR("WET0WEST,M3.5.0/1,M10.5.0") #define TZ_Europe_Ljubljana PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_London PSTR("GMT0BST,M3.5.0/1,M10.5.0") @@ -362,6 +466,7 @@ #define TZ_Europe_Minsk PSTR("<+03>-3") #define TZ_Europe_Monaco PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Moscow PSTR("MSK-3") +#define TZ_Europe_Nicosia PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Oslo PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Paris PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Podgorica PSTR("CET-1CEST,M3.5.0,M10.5.0/3") @@ -378,17 +483,31 @@ #define TZ_Europe_Stockholm PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Tallinn PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Tirane PSTR("CET-1CEST,M3.5.0,M10.5.0/3") +#define TZ_Europe_Tiraspol PSTR("EET-2EEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Ulyanovsk PSTR("<+04>-4") #define TZ_Europe_Uzhgorod PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") +#define TZ_Europe_Uzhhorod PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Vaduz PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Vatican PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Vienna PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Vilnius PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") -#define TZ_Europe_Volgograd PSTR("<+03>-3") +#define TZ_Europe_Volgograd PSTR("MSK-3") #define TZ_Europe_Warsaw PSTR("CET-1CEST,M3.5.0,M10.5.0/3") #define TZ_Europe_Zagreb PSTR("CET-1CEST,M3.5.0,M10.5.0/3") +#define TZ_Europe_Zaporizhzhia PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Zaporozhye PSTR("EET-2EEST,M3.5.0/3,M10.5.0/4") #define TZ_Europe_Zurich PSTR("CET-1CEST,M3.5.0,M10.5.0/3") +#define TZ_Factory PSTR("<-00>0") +#define TZ_GB PSTR("GMT0BST,M3.5.0/1,M10.5.0") +#define TZ_GBmEire PSTR("GMT0BST,M3.5.0/1,M10.5.0") +#define TZ_GMT PSTR("GMT0") +#define TZ_GMTp0 PSTR("GMT0") +#define TZ_GMTm0 PSTR("GMT0") +#define TZ_GMT0 PSTR("GMT0") +#define TZ_Greenwich PSTR("GMT0") +#define TZ_HST PSTR("HST10") +#define TZ_Hongkong PSTR("HKT-8") +#define TZ_Iceland PSTR("GMT0") #define TZ_Indian_Antananarivo PSTR("EAT-3") #define TZ_Indian_Chagos PSTR("<+06>-6") #define TZ_Indian_Christmas PSTR("<+07>-7") @@ -400,6 +519,23 @@ #define TZ_Indian_Mauritius PSTR("<+04>-4") #define TZ_Indian_Mayotte PSTR("EAT-3") #define TZ_Indian_Reunion PSTR("<+04>-4") +#define TZ_Iran PSTR("<+0330>-3:30") +#define TZ_Israel PSTR("IST-2IDT,M3.4.4/26,M10.5.0") +#define TZ_Jamaica PSTR("EST5") +#define TZ_Japan PSTR("JST-9") +#define TZ_Kwajalein PSTR("<+12>-12") +#define TZ_Libya PSTR("EET-2") +#define TZ_MET PSTR("MET-1MEST,M3.5.0,M10.5.0/3") +#define TZ_MST PSTR("MST7") +#define TZ_MST7MDT PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_Mexico_BajaNorte PSTR("PST8PDT,M3.2.0,M11.1.0") +#define TZ_Mexico_BajaSur PSTR("MST7") +#define TZ_Mexico_General PSTR("CST6") +#define TZ_NZ PSTR("NZST-12NZDT,M9.5.0,M4.1.0/3") +#define TZ_NZmCHAT PSTR("<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45") +#define TZ_Navajo PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_PRC PSTR("CST-8") +#define TZ_PST8PDT PSTR("PST8PDT,M3.2.0,M11.1.0") #define TZ_Pacific_Apia PSTR("<+13>-13") #define TZ_Pacific_Auckland PSTR("NZST-12NZDT,M9.5.0,M4.1.0/3") #define TZ_Pacific_Bougainville PSTR("<+11>-11") @@ -416,6 +552,8 @@ #define TZ_Pacific_Guadalcanal PSTR("<+11>-11") #define TZ_Pacific_Guam PSTR("ChST-10") #define TZ_Pacific_Honolulu PSTR("HST10") +#define TZ_Pacific_Johnston PSTR("HST10") +#define TZ_Pacific_Kanton PSTR("<+13>-13") #define TZ_Pacific_Kiritimati PSTR("<+14>-14") #define TZ_Pacific_Kosrae PSTR("<+11>-11") #define TZ_Pacific_Kwajalein PSTR("<+12>-12") @@ -430,48 +568,39 @@ #define TZ_Pacific_Palau PSTR("<+09>-9") #define TZ_Pacific_Pitcairn PSTR("<-08>8") #define TZ_Pacific_Pohnpei PSTR("<+11>-11") +#define TZ_Pacific_Ponape PSTR("<+11>-11") #define TZ_Pacific_Port_Moresby PSTR("<+10>-10") #define TZ_Pacific_Rarotonga PSTR("<-10>10") #define TZ_Pacific_Saipan PSTR("ChST-10") +#define TZ_Pacific_Samoa PSTR("SST11") #define TZ_Pacific_Tahiti PSTR("<-10>10") #define TZ_Pacific_Tarawa PSTR("<+12>-12") #define TZ_Pacific_Tongatapu PSTR("<+13>-13") +#define TZ_Pacific_Truk PSTR("<+10>-10") #define TZ_Pacific_Wake PSTR("<+12>-12") #define TZ_Pacific_Wallis PSTR("<+12>-12") -#define TZ_Etc_GMT PSTR("GMT0") -#define TZ_Etc_GMTm0 PSTR("GMT0") -#define TZ_Etc_GMTm1 PSTR("<+01>-1") -#define TZ_Etc_GMTm2 PSTR("<+02>-2") -#define TZ_Etc_GMTm3 PSTR("<+03>-3") -#define TZ_Etc_GMTm4 PSTR("<+04>-4") -#define TZ_Etc_GMTm5 PSTR("<+05>-5") -#define TZ_Etc_GMTm6 PSTR("<+06>-6") -#define TZ_Etc_GMTm7 PSTR("<+07>-7") -#define TZ_Etc_GMTm8 PSTR("<+08>-8") -#define TZ_Etc_GMTm9 PSTR("<+09>-9") -#define TZ_Etc_GMTm10 PSTR("<+10>-10") -#define TZ_Etc_GMTm11 PSTR("<+11>-11") -#define TZ_Etc_GMTm12 PSTR("<+12>-12") -#define TZ_Etc_GMTm13 PSTR("<+13>-13") -#define TZ_Etc_GMTm14 PSTR("<+14>-14") -#define TZ_Etc_GMT0 PSTR("GMT0") -#define TZ_Etc_GMTp0 PSTR("GMT0") -#define TZ_Etc_GMTp1 PSTR("<-01>1") -#define TZ_Etc_GMTp2 PSTR("<-02>2") -#define TZ_Etc_GMTp3 PSTR("<-03>3") -#define TZ_Etc_GMTp4 PSTR("<-04>4") -#define TZ_Etc_GMTp5 PSTR("<-05>5") -#define TZ_Etc_GMTp6 PSTR("<-06>6") -#define TZ_Etc_GMTp7 PSTR("<-07>7") -#define TZ_Etc_GMTp8 PSTR("<-08>8") -#define TZ_Etc_GMTp9 PSTR("<-09>9") -#define TZ_Etc_GMTp10 PSTR("<-10>10") -#define TZ_Etc_GMTp11 PSTR("<-11>11") -#define TZ_Etc_GMTp12 PSTR("<-12>12") -#define TZ_Etc_UCT PSTR("UTC0") -#define TZ_Etc_UTC PSTR("UTC0") -#define TZ_Etc_Greenwich PSTR("GMT0") -#define TZ_Etc_Universal PSTR("UTC0") -#define TZ_Etc_Zulu PSTR("UTC0") - -#endif // TZDB_H +#define TZ_Pacific_Yap PSTR("<+10>-10") +#define TZ_Poland PSTR("CET-1CEST,M3.5.0,M10.5.0/3") +#define TZ_Portugal PSTR("WET0WEST,M3.5.0/1,M10.5.0") +#define TZ_ROC PSTR("CST-8") +#define TZ_ROK PSTR("KST-9") +#define TZ_Singapore PSTR("<+08>-8") +#define TZ_Turkey PSTR("<+03>-3") +#define TZ_UCT PSTR("UTC0") +#define TZ_US_Alaska PSTR("AKST9AKDT,M3.2.0,M11.1.0") +#define TZ_US_Aleutian PSTR("HST10HDT,M3.2.0,M11.1.0") +#define TZ_US_Arizona PSTR("MST7") +#define TZ_US_Central PSTR("CST6CDT,M3.2.0,M11.1.0") +#define TZ_US_EastmIndiana PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_US_Eastern PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_US_Hawaii PSTR("HST10") +#define TZ_US_IndianamStarke PSTR("CST6CDT,M3.2.0,M11.1.0") +#define TZ_US_Michigan PSTR("EST5EDT,M3.2.0,M11.1.0") +#define TZ_US_Mountain PSTR("MST7MDT,M3.2.0,M11.1.0") +#define TZ_US_Pacific PSTR("PST8PDT,M3.2.0,M11.1.0") +#define TZ_US_Samoa PSTR("SST11") +#define TZ_UTC PSTR("UTC0") +#define TZ_Universal PSTR("UTC0") +#define TZ_WmSU PSTR("MSK-3") +#define TZ_WET PSTR("WET0WEST,M3.5.0/1,M10.5.0") +#define TZ_Zulu PSTR("UTC0") diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index 91f2a9e6ae..ef79a5cbf3 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -70,6 +70,7 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) { #ifdef DEBUG_UPDATER DEBUG_UPDATER.println(F("[begin] already running")); #endif + _setError(UPDATE_ERROR_RUNNING_ALREADY); return false; } @@ -86,7 +87,7 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) { _setError(UPDATE_ERROR_BOOTSTRAP); return false; } - + #ifdef DEBUG_UPDATER if (command == U_FS) { DEBUG_UPDATER.println(F("[begin] Update Filesystem.")); @@ -133,7 +134,7 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) { //make sure that the size of both sketches is less than the total space (updateEndAddress) if(updateStartAddress < currentSketchSize) { - _setError(UPDATE_ERROR_SPACE); + _setError(UPDATE_ERROR_SPACE); return false; } } @@ -162,6 +163,7 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) { #ifdef DEBUG_UPDATER DEBUG_UPDATER.println(F("[begin] Unknown update command.")); #endif + _setError(UPDATE_ERROR_UNKNOWN_COMMAND); return false; } @@ -282,7 +284,7 @@ bool UpdaterClass::end(bool evenIfRemaining){ _hash->begin(); for (uint32_t offset = 0; offset < binSize; offset += sizeof(buff)) { auto len = std::min(sizeof(buff), binSize - offset); - ESP.flashRead(_startAddress + offset, reinterpret_cast(&buff[0]), len); + ESP.flashRead(_startAddress + offset, buff, len); _hash->add(buff, len); } _hash->end(); @@ -404,7 +406,7 @@ bool UpdaterClass::_writeBuffer(){ modifyFlashMode = true; } } - + if (eraseResult) { if(!_async) yield(); writeResult = ESP.flashWrite(_currentAddress, _buffer, _bufferLen); @@ -488,7 +490,7 @@ bool UpdaterClass::_verifyEnd() { uint8_t buf[4] __attribute__((aligned(4))); if(!ESP.flashRead(_startAddress, (uint32_t *) &buf[0], 4)) { _currentAddress = (_startAddress); - _setError(UPDATE_ERROR_READ); + _setError(UPDATE_ERROR_READ); return false; } @@ -500,7 +502,7 @@ bool UpdaterClass::_verifyEnd() { return true; } else if (buf[0] != 0xE9) { _currentAddress = (_startAddress); - _setError(UPDATE_ERROR_MAGIC_BYTE); + _setError(UPDATE_ERROR_MAGIC_BYTE); return false; } @@ -512,7 +514,7 @@ bool UpdaterClass::_verifyEnd() { // check if new bin fits to SPI flash if(bin_flash_size > ESP.getFlashChipRealSize()) { _currentAddress = (_startAddress); - _setError(UPDATE_ERROR_NEW_FLASH_CONFIG); + _setError(UPDATE_ERROR_NEW_FLASH_CONFIG); return false; } #endif @@ -649,6 +651,12 @@ String UpdaterClass::getErrorString() const { case UPDATE_ERROR_OOM: out = F("Out of memory"); break; + case UPDATE_ERROR_RUNNING_ALREADY: + out = F("Update already running"); + break; + case UPDATE_ERROR_UNKNOWN_COMMAND: + out = F("Unknown update command"); + break; default: out = F("UNKNOWN"); break; diff --git a/cores/esp8266/Updater.h b/cores/esp8266/Updater.h index ad652d3806..7ee1d28311 100644 --- a/cores/esp8266/Updater.h +++ b/cores/esp8266/Updater.h @@ -21,6 +21,8 @@ #define UPDATE_ERROR_SIGN (12) #define UPDATE_ERROR_NO_DATA (13) #define UPDATE_ERROR_OOM (14) +#define UPDATE_ERROR_RUNNING_ALREADY (15) +#define UPDATE_ERROR_UNKNOWN_COMMAND (16) #define U_FLASH 0 #define U_FS 100 @@ -55,7 +57,7 @@ class UpdaterClass { using THandlerFunction_Progress = std::function; using THandlerFunction_Error = std::function; using THandlerFunction = std::function; - + UpdaterClass(); ~UpdaterClass(); @@ -69,7 +71,7 @@ class UpdaterClass { bool begin(size_t size, int command = U_FLASH, int ledPin = -1, uint8_t ledOn = LOW); /* - Run Updater from asynchronous callbacs + Run Updater from asynchronous callbacks */ void runAsync(bool async){ _async = async; } @@ -216,7 +218,7 @@ class UpdaterClass { bool _verifyHeader(uint8_t data); bool _verifyEnd(); - void _setError(int error); + void _setError(int error); bool _async = false; uint8_t _error = 0; diff --git a/cores/esp8266/WString.h b/cores/esp8266/WString.h index 47a9177534..1a2aebb298 100644 --- a/cores/esp8266/WString.h +++ b/cores/esp8266/WString.h @@ -33,7 +33,7 @@ #include #include -// an abstract class used as a means to proide a unique pointer type +// an abstract class used as a means to provide a unique pointer type // but really has no body class __FlashStringHelper; #define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer)) @@ -204,7 +204,7 @@ class String { bool concat(double num); // if there's not enough memory for the concatenated value, the string - // will be left unchanged (but this isn't signalled in any way) + // will be left unchanged (but this isn't signaled in any way) template String &operator +=(const T &rhs) { concat(rhs); @@ -343,7 +343,7 @@ class String { char *wbuffer() { return const_cast(buffer()); } // Writable version of buffer // concatenation is done via non-member functions - // make sure we still have access to internal methods, since we optimize based on capacity of both sides and want to manipulate internal buffers directly + // make sure we still have access to internal methods, since we optimize based on the capacity of both sides and want to manipulate internal buffers directly friend String operator +(const String &lhs, String &&rhs); friend String operator +(String &&lhs, String &&rhs); friend String operator +(char lhs, String &&rhs); diff --git a/cores/esp8266/cont.S b/cores/esp8266/cont.S index 4832b39170..ee049d46f5 100644 --- a/cores/esp8266/cont.S +++ b/cores/esp8266/cont.S @@ -26,8 +26,14 @@ cont_suspend: /* a1: sp */ /* a2: void* cont_ctx */ - /* adjust stack and save registers */ + /* adjust stack */ addi a1, a1, -24 + + /* make sure that a1 points after cont_ctx.stack[] */ + addi a4, a2, 32 + bltu a1, a4, cont_overflow + + /* save registers */ s32i a12, a1, 0 s32i a13, a1, 4 s32i a14, a1, 8 @@ -47,6 +53,11 @@ cont_suspend: l32i a1, a2, 4 jx a0 +cont_overflow: + mov.n a3, a1 + movi a4, __stack_overflow + jx a4 + cont_continue: l32i a12, a1, 0 l32i a13, a1, 4 @@ -113,7 +124,7 @@ cont_run: bnez a4, cont_resume /* else */ /* set new stack*/ - l32i a1, a2, 16; + l32i a1, a2, 16 /* goto pfn */ movi a2, cont_wrapper jx a2 @@ -121,12 +132,15 @@ cont_run: cont_resume: /* a1 <- cont_ctx.sp_suspend */ l32i a1, a2, 12 + /* make sure that a1 points after cont_ctx.stack[] */ + addi a5, a2, 32 + bltu a1, a5, cont_overflow /* reset yield flag, 0 -> cont_ctx.pc_suspend */ movi a3, 0 s32i a3, a2, 8 /* jump to saved cont_ctx.pc_suspend */ movi a0, cont_ret - jx a4 + jx a4 cont_norm: /* calculate pointer to cont_ctx.struct_start from sp */ diff --git a/cores/esp8266/cont.h b/cores/esp8266/cont.h index ba6d432a88..4c9578851b 100644 --- a/cores/esp8266/cont.h +++ b/cores/esp8266/cont.h @@ -22,11 +22,16 @@ #define CONT_H_ #include +#include #ifndef CONT_STACKSIZE #define CONT_STACKSIZE 4096 #endif +#ifndef CONT_STACKGUARD +#define CONT_STACKGUARD 0xfeefeffe +#endif + #ifdef __cplusplus extern "C" { #endif @@ -62,8 +67,11 @@ void cont_run(cont_t*, void (*pfn)(void)); // execution state (registers and stack) void cont_suspend(cont_t*); +// Check that cont resume state is valid. Immediately panics on failure. +void cont_check_overflow(cont_t*); + // Check guard bytes around the stack. Immediately panics on failure. -void cont_check(cont_t*); +void cont_check_guard(cont_t*); // Go through stack and check how many bytes are most probably still unchanged // and thus weren't used by the user code. i.e. that stack space is free. (high water mark) @@ -78,7 +86,6 @@ bool cont_can_suspend(cont_t* cont); // free, running the routine, then checking the max free void cont_repaint_stack(cont_t *cont); - #ifdef __cplusplus } #endif diff --git a/cores/esp8266/cont_util.cpp b/cores/esp8266/cont_util.cpp index 746dcccbfd..6c49a38fcf 100644 --- a/cores/esp8266/cont_util.cpp +++ b/cores/esp8266/cont_util.cpp @@ -23,38 +23,45 @@ #include #include -#include "cont.h" +#include "core_esp8266_features.h" #include "debug.h" +#include "cont.h" + extern "C" { -static constexpr unsigned int CONT_STACKGUARD { 0xfeefeffe }; +static constexpr uint32_t CONT_STACKSIZE_U32 { sizeof(cont_t::stack) / sizeof(*cont_t::stack) }; void cont_init(cont_t* cont) { memset(cont, 0, sizeof(cont_t)); cont->stack_guard1 = CONT_STACKGUARD; cont->stack_guard2 = CONT_STACKGUARD; - cont->stack_end = cont->stack + (sizeof(cont->stack) / 4); + cont->stack_end = &cont->stack[0] + CONT_STACKSIZE_U32; cont->struct_start = (unsigned*) cont; // fill stack with magic values to check high water mark - for(int pos = 0; pos < (int)(sizeof(cont->stack) / 4); pos++) + for(int pos = 0; pos < (int)(CONT_STACKSIZE_U32); pos++) { cont->stack[pos] = CONT_STACKGUARD; } } -void IRAM_ATTR cont_check(cont_t* cont) { - if ((cont->stack_guard1 == CONT_STACKGUARD) - && (cont->stack_guard2 == CONT_STACKGUARD)) +void IRAM_ATTR cont_check_guard(cont_t* cont) { + if ((cont->stack_guard1 != CONT_STACKGUARD) + || (cont->stack_guard2 != CONT_STACKGUARD)) { - return; + __stack_chk_fail(); + __builtin_unreachable(); } +} - __stack_chk_fail(); - __builtin_unreachable(); +void IRAM_ATTR cont_check_overflow(cont_t* cont) { + if (cont->sp_suspend && (cont->sp_suspend < &cont->stack[0])) { + __stack_overflow(cont, cont->sp_suspend); + __builtin_unreachable(); + } } // No need for this to be in IRAM, not expected to be IRQ called diff --git a/cores/esp8266/core_esp8266_flash_quirks.cpp b/cores/esp8266/core_esp8266_flash_quirks.cpp index 7128fcfe2d..2ae3a39050 100644 --- a/cores/esp8266/core_esp8266_flash_quirks.cpp +++ b/cores/esp8266/core_esp8266_flash_quirks.cpp @@ -66,12 +66,13 @@ void initFlashQuirks() { newSR3=SR3; if (get_flash_mhz()>26) { // >26Mhz? // Set the output drive to 100% + // These definitions are for the XM25QH32B part. On a XM25QH32C + // part, the XM25QH32B's 100% is C's 25% driver strength. newSR3 &= ~(SPI_FLASH_SR3_XMC_DRV_MASK << SPI_FLASH_SR3_XMC_DRV_S); newSR3 |= (SPI_FLASH_SR3_XMC_DRV_100 << SPI_FLASH_SR3_XMC_DRV_S); } if (newSR3 != SR3) { // only write if changed - if (SPI0Command(SPI_FLASH_CMD_WEVSR,NULL,0,0)==SPI_RESULT_OK) // write enable volatile SR - SPI0Command(SPI_FLASH_CMD_WSR3,&newSR3,8,0); // write to SR3 + SPI0Command(SPI_FLASH_CMD_WSR3,&newSR3,8,0,SPI_FLASH_CMD_WEVSR); // write to SR3, use write enable volatile prefix SPI0Command(SPI_FLASH_CMD_WRDI,NULL,0,0); // write disable - probably not needed } } diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index d0309cc71f..d7f14b02c8 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -24,6 +24,7 @@ //#define CONT_STACKSIZE 4096 #include +#include #include #include "Schedule.h" @@ -261,7 +262,7 @@ static void loop_wrapper() { } loop(); loop_end(); - cont_check(g_pcont); + cont_check_guard(g_pcont); if (serialEventRun) { serialEventRun(); } diff --git a/cores/esp8266/core_esp8266_noniso.cpp b/cores/esp8266/core_esp8266_noniso.cpp index f15fdc0860..fb5d8f573a 100644 --- a/cores/esp8266/core_esp8266_noniso.cpp +++ b/cores/esp8266/core_esp8266_noniso.cpp @@ -28,19 +28,12 @@ #include #include #include + #include "stdlib_noniso.h" extern "C" { -char* ltoa(long value, char* result, int base) { - return itoa((int)value, result, base); -} - -char* ultoa(unsigned long value, char* result, int base) { - return utoa((unsigned int)value, result, base); -} - -char * dtostrf(double number, signed char width, unsigned char prec, char *s) { +char* dtostrf(double number, signed char width, unsigned char prec, char *s) noexcept { bool negative = false; if (isnan(number)) { @@ -125,7 +118,7 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) { */ const char* strrstr(const char*__restrict p_pcString, - const char*__restrict p_pcPattern) + const char*__restrict p_pcPattern) noexcept { const char* pcResult = 0; @@ -149,4 +142,4 @@ const char* strrstr(const char*__restrict p_pcString, return pcResult; } -}; +} // extern "C" diff --git a/cores/esp8266/core_esp8266_postmortem.cpp b/cores/esp8266/core_esp8266_postmortem.cpp index 9f5594d148..95844534e8 100644 --- a/cores/esp8266/core_esp8266_postmortem.cpp +++ b/cores/esp8266/core_esp8266_postmortem.cpp @@ -48,7 +48,7 @@ static const char* s_unhandled_exception = NULL; // Common way to notify about where the stack smashing happened // (but, **only** if caller uses our handler function) -static uint32_t s_stacksmash_addr = 0; +static uint32_t s_stack_chk_addr = 0; void abort() __attribute__((noreturn)); static void uart_write_char_d(char c); @@ -59,6 +59,7 @@ static void print_stack(uint32_t start, uint32_t end); // using numbers different from "REASON_" in user_interface.h (=0..6) enum rst_reason_sw { + REASON_USER_STACK_OVERFLOW = 252, REASON_USER_STACK_SMASH = 253, REASON_USER_SWEXCEPTION_RST = 254 }; @@ -99,7 +100,9 @@ static void ets_printf_P(const char *str, ...) { } static void cut_here() { - ets_putc('\n'); + // https://tinyurl.com/8266dcdr => https://arduino-esp8266.readthedocs.io/en/latest/faq/a02-my-esp-crashes.html#exception + ets_printf_P(PSTR("\nTo make this dump useful, DECODE IT - https://tinyurl.com/8266dcdr\n")); + for (auto i = 0; i < 15; i++ ) { ets_putc('-'); } @@ -186,7 +189,7 @@ static void postmortem_report(uint32_t sp_dump) { } else if (rst_info.reason == REASON_SOFT_WDT_RST) { ets_printf_P(PSTR("\nSoft WDT reset")); - const char infinite_loop[] = { 0x06, 0xff, 0xff }; // loop: j loop + const uint8_t infinite_loop[] = { 0x06, 0xff, 0xff }; // loop: j loop if (is_pc_valid(rst_info.epc1) && 0 == memcmp_P(infinite_loop, (PGM_VOID_P)rst_info.epc1, 3u)) { // The SDK is riddled with these. They are usually preceded by an ets_printf. ets_printf_P(PSTR(" - deliberate infinite loop detected")); @@ -196,17 +199,23 @@ static void postmortem_report(uint32_t sp_dump) { rst_info.exccause, /* Address executing at time of Soft WDT level-1 interrupt */ rst_info.epc1, 0, 0, 0, 0); } else if (rst_info.reason == REASON_USER_STACK_SMASH) { - ets_printf_P(PSTR("\nStack smashing detected.\n")); - ets_printf_P(PSTR("\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n"), - 5 /* Alloca exception, closest thing to stack fault*/, s_stacksmash_addr, 0, 0, 0, 0); - } + ets_printf_P(PSTR("\nStack smashing detected at 0x%08x\n"), s_stack_chk_addr); + } + else if (rst_info.reason == REASON_USER_STACK_OVERFLOW) { + ets_printf_P(PSTR("\nStack overflow detected\n")); + } else { ets_printf_P(PSTR("\nGeneric Reset\n")); } - uint32_t cont_stack_start = (uint32_t) &(g_pcont->stack); - uint32_t cont_stack_end = (uint32_t) g_pcont->stack_end; - uint32_t stack_end; + uint32_t cont_stack_start; + if (rst_info.reason == REASON_USER_STACK_SMASH) { + cont_stack_start = s_stack_chk_addr; + } else { + cont_stack_start = (uint32_t) (&g_pcont->stack[0]); + } + + uint32_t cont_stack_end = cont_stack_start + CONT_STACKSIZE; // amount of stack taken by interrupt or exception handler // and everything up to __wrap_system_restart_local @@ -247,15 +256,21 @@ static void postmortem_report(uint32_t sp_dump) { sp_dump = stack_thunk_get_cont_sp(); } - if (sp_dump > cont_stack_start && sp_dump < cont_stack_end) { + uint32_t stack_end; + + // above and inside of cont, dump from the sp to the bottom of the stack + if ((rst_info.reason == REASON_USER_STACK_OVERFLOW) + || ((sp_dump > cont_stack_start) && (sp_dump < cont_stack_end))) + { ets_printf_P(PSTR("\nctx: cont\n")); stack_end = cont_stack_end; } + // in system, reposition to a known address + // it's actually 0x3ffffff0, but the stuff below ets_run + // is likely not really relevant to the crash else { ets_printf_P(PSTR("\nctx: sys\n")); stack_end = 0x3fffffb0; - // it's actually 0x3ffffff0, but the stuff below ets_run - // is likely not really relevant to the crash } ets_printf_P(PSTR("sp: %08x end: %08x offset: %04x\n"), sp_dump, stack_end, offset); @@ -294,11 +309,20 @@ static void print_stack(uint32_t start, uint32_t end) { for (uint32_t pos = start; pos < end; pos += 0x10) { uint32_t* values = (uint32_t*)(pos); + // avoid printing irrelevant data + if ((values[0] == CONT_STACKGUARD) + && (values[0] == values[1]) + && (values[1] == values[2]) + && (values[2] == values[3])) + { + continue; + } + // rough indicator: stack frames usually have SP saved as the second word - bool looksLikeStackFrame = (values[2] == pos + 0x10); + const bool looksLikeStackFrame = (values[2] == pos + 0x10); ets_printf_P(PSTR("%08x: %08x %08x %08x %08x %c\n"), - pos, values[0], values[1], values[2], values[3], (looksLikeStackFrame)?'<':' '); + pos, values[0], values[1], values[2], values[3], (looksLikeStackFrame) ? '<' : ' '); } } @@ -368,7 +392,7 @@ void __panic_func(const char* file, int line, const char* func) { uintptr_t __stack_chk_guard = 0x08675309 ^ RANDOM_REG32; void __stack_chk_fail(void) { s_user_reset_reason = REASON_USER_STACK_SMASH; - s_stacksmash_addr = (uint32_t)__builtin_return_address(0); + s_stack_chk_addr = (uint32_t)__builtin_return_address(0); if (gdb_present()) __asm__ __volatile__ ("syscall"); // triggers GDB when enabled @@ -380,4 +404,16 @@ void __stack_chk_fail(void) { __builtin_unreachable(); // never reached, needed to satisfy "noreturn" attribute } +void __stack_overflow(cont_t* cont, uint32_t* sp) { + s_user_reset_reason = REASON_USER_STACK_OVERFLOW; + s_stack_chk_addr = (uint32_t)&cont->stack[0]; + + if (gdb_present()) + __asm__ __volatile__ ("syscall"); // triggers GDB when enabled + + postmortem_report((uint32_t)sp); + + __builtin_unreachable(); // never reached, needed to satisfy "noreturn" attribute +} + } // extern "C" diff --git a/cores/esp8266/core_esp8266_spi_utils.cpp b/cores/esp8266/core_esp8266_spi_utils.cpp index 5f2ea25f92..cd5e153c27 100644 --- a/cores/esp8266/core_esp8266_spi_utils.cpp +++ b/cores/esp8266/core_esp8266_spi_utils.cpp @@ -32,6 +32,7 @@ #include "core_esp8266_features.h" #include "spi_utils.h" +#include "spi_flash_defs.h" extern "C" uint32_t Wait_SPI_Idle(SpiFlashChip *fc); @@ -51,12 +52,12 @@ namespace experimental { static SpiOpResult PRECACHE_ATTR _SPICommand(volatile uint32_t spiIfNum, uint32_t spic,uint32_t spiu,uint32_t spiu1,uint32_t spiu2, - uint32_t *data,uint32_t writeWords,uint32_t readWords) + uint32_t *data,uint32_t writeWords,uint32_t readWords, uint32_t pre_cmd) { if (spiIfNum>1) return SPI_RESULT_ERR; - // force SPI register access via base+offset. + // force SPI register access via base+offset. // Prevents loading individual address constants from flash. uint32_t *spibase = (uint32_t*)(spiIfNum ? &(SPI1CMD) : &(SPI0CMD)); #define SPIREG(reg) (*((volatile uint32_t *)(spibase+(&(reg) - &(SPI0CMD))))) @@ -65,6 +66,7 @@ _SPICommand(volatile uint32_t spiIfNum, // Everything defined here must be volatile or the optimizer can // treat them as constants, resulting in the flash reads we're // trying to avoid + SpiFlashOpResult (* volatile SPI_write_enablep)(SpiFlashChip *) = SPI_write_enable; uint32_t (* volatile Wait_SPI_Idlep)(SpiFlashChip *) = Wait_SPI_Idle; volatile SpiFlashChip *fchip=flashchip; volatile uint32_t spicmdusr=SPICMDUSR; @@ -77,15 +79,30 @@ _SPICommand(volatile uint32_t spiIfNum, PRECACHE_START(); Wait_SPI_Idlep((SpiFlashChip *)fchip); } - + // preserve essential controller state such as incoming/outgoing // data lengths and IO mode. uint32_t oldSPI0U = SPIREG(SPI0U); uint32_t oldSPI0U2= SPIREG(SPI0U2); uint32_t oldSPI0C = SPIREG(SPI0C); - //SPI0S &= ~(SPISE|SPISBE|SPISSE|SPISCD); SPIREG(SPI0C) = spic; + + if (SPI_FLASH_CMD_WREN == pre_cmd) { + // See SPI_write_enable comments in esp8266_undocumented.h + SPI_write_enablep((SpiFlashChip *)fchip); + } else + if (pre_cmd) { + // Send prefix cmd w/o data - sends 8 bits. eg. Volatile SR Write Enable, 0x50 + SPIREG(SPI0U) = (spiu & ~(SPIUMOSI|SPIUMISO)); + SPIREG(SPI0U1) = 0; + SPIREG(SPI0U2) = (spiu2 & ~0xFFFFu) | pre_cmd; + + SPIREG(SPI0CMD) = spicmdusr; //Send cmd + while ((SPIREG(SPI0CMD) & spicmdusr)); + } + + //SPI0S &= ~(SPISE|SPISBE|SPISSE|SPISCD); SPIREG(SPI0U) = spiu; SPIREG(SPI0U1)= spiu1; SPIREG(SPI0U2)= spiu2; @@ -117,11 +134,22 @@ _SPICommand(volatile uint32_t spiIfNum, SPIREG(SPI0U) = oldSPI0U; SPIREG(SPI0U2)= oldSPI0U2; SPIREG(SPI0C) = oldSPI0C; - - PRECACHE_END(); + if (!spiIfNum) { + // w/o a call to Wait_SPI_Idlep, 'Exception 0' or other exceptions (saw + // 28) may occur later after returning to iCache code. This issue was + // observed with non-volatile status register writes. + // + // My guess is: Returning too soon to uncached iCache executable space. An + // iCache read may not complete properly because the Flash or SPI + // interface is still busy with the last write operation. In such a case, + // I expect new reads from iROM to result in zeros. This would explain + // the Exception 0 for code, and Exception 20, 28, and 29 where a literal + // was misread as 0 and then used as a pointer. + Wait_SPI_Idlep((SpiFlashChip *)fchip); xt_wsr_ps(saved_ps); } + PRECACHE_END(); return (timeout>0 ? SPI_RESULT_OK : SPI_RESULT_TIMEOUT); } @@ -139,12 +167,37 @@ _SPICommand(volatile uint32_t spiIfNum, * miso_bits * Number of bits to read from the SPI bus after the outgoing * data has been sent. + * pre_cmd + * A few SPI Flash commands require enable commands to immediately preceed + * them. Since two calls to SPI0Command from ICACHE memory most likely would + * be separated by SPI Flash read request for iCache, use this option to + * supply a prefix command, 8-bits w/o read or write data. + * + * Case in point from the GD25Q32E datasheet: "The Write Enable for Volatile + * Status Register command must be issued prior to a Write Status Register + * command and any other commands can’t be inserted between them." * * Note: This code has only been tested with SPI bus 0, but should work * equally well with other buses. The ESP8266 has bus 0 and 1, * newer chips may have more one day. + * + * Supplemental Notes: + * + * SPI Bus wire view: Think of *data as an array of bytes, byte[0] goes out + * first with the most significant bit shifted out first and so on. When + * thinking of the data as an array of 32bit-words, the least significant byte + * of the first 32bit-word goes out first on the SPI bus with the most + * significant bit of that byte shifted out first onto the wire. + * + * When presenting a 3 or 4-byte address, the byte order will need to be + * reversed. Don't overthink it. For a 3-byte address, view *data as a byte + * array and set the first 3-bytes to the address. eg. byteData[0] MSB, + * byteData[1] middle, and byteData[2] LSB. + * + * When sending a fractional byte, fill in the most significant bit positions + * of the byte first. */ -SpiOpResult SPI0Command(uint8_t cmd, uint32_t *data, uint32_t mosi_bits, uint32_t miso_bits) { +SpiOpResult SPI0Command(uint8_t cmd, uint32_t *data, uint32_t mosi_bits, uint32_t miso_bits, uint32_t pre_cmd) { if (mosi_bits>(64*8)) return SPI_RESULT_ERR; if (miso_bits>(64*8)) @@ -159,8 +212,16 @@ SpiOpResult SPI0Command(uint8_t cmd, uint32_t *data, uint32_t mosi_bits, uint32_ if (miso_bits % 32 != 0) miso_words++; + // Use SPI_CS_SETUP to add time for #CS to settle (ringing) before SPI CLK + // begins. The BootROM does not do this; however, RTOS SDK and NONOS SDK do + // as part of flash init/configuration. + // + // One SPI bus clock cycle time inserted between #CS active and the 1st SPI + // bus clock cycle. The number of clock cycles is in SPI_CNTRL2 + // SPI_SETUP_TIME, which defaults to 1. + // // Select user defined command mode in the controller - uint32_t spiu=SPIUCOMMAND; //SPI_USR_COMMAND + uint32_t spiu=SPIUCOMMAND | SPIUCSSETUP; //SPI_USR_COMMAND | SPI_CS_SETUP // Set the command byte to send uint32_t spiu2 = ((7 & SPIMCOMMAND)<> (miso_bits % 8u)) & 0xFFu) << whole_byte_bits; + } + data[miso_bits/32u] &= mask; } } return rc; diff --git a/cores/esp8266/core_esp8266_vm.cpp b/cores/esp8266/core_esp8266_vm.cpp index 3a63d65f7a..00f50e3981 100644 --- a/cores/esp8266/core_esp8266_vm.cpp +++ b/cores/esp8266/core_esp8266_vm.cpp @@ -161,20 +161,21 @@ static struct cache_line *__vm_cache; // Always points to MRU (hence the line be constexpr int addrmask = ~(sizeof(__vm_cache[0].w)-1); // Helper to mask off bits present in cache entry - static void spi_init(spi_regs *spi1) { pinMode(sck, SPECIAL); pinMode(miso, SPECIAL); pinMode(mosi, SPECIAL); pinMode(cs, SPECIAL); - spi1->spi_cmd = 0; + // spi_ctrl appears to need setting before other SPI registers + spi1->spi_ctrl = 0; // MSB first + plain SPI mode + asm("" ::: "memory"); GPMUX &= ~(1 << 9); spi1->spi_clock = spi_clkval; - spi1->spi_ctrl = 0 ; // MSB first + plain SPI mode spi1->spi_ctrl1 = 0; // undocumented, clear for safety? spi1->spi_ctrl2 = 0; // No add'l delays on signals spi1->spi_user2 = 0; // No insn or insn_bits to set + spi1->spi_cmd = 0; } // Note: GCC optimization -O2 and -O3 tried and returned *slower* code than the default diff --git a/cores/esp8266/debug.h b/cores/esp8266/debug.h index 0e30000c53..437479748c 100644 --- a/cores/esp8266/debug.h +++ b/cores/esp8266/debug.h @@ -4,6 +4,8 @@ #include #include +#include "cont.h" + #define _DEBUG_LEAF_FUNCTION(...) __asm__ __volatile__("" ::: "a0", "memory") #ifdef DEBUG_ESP_CORE @@ -32,6 +34,7 @@ extern "C" { #endif void __stack_chk_fail(void) __attribute__((noreturn)); + void __stack_overflow(cont_t*, uint32_t*) __attribute__((noreturn)); void __unhandled_exception(const char* str) __attribute__((noreturn)); void __panic_func(const char* file, int line, const char* func) __attribute__((noreturn)); #define panic() __panic_func(PSTR(__FILE__), __LINE__, __func__) diff --git a/cores/esp8266/esp8266_undocumented.h b/cores/esp8266/esp8266_undocumented.h index 5e68e53fa1..d7924333a8 100644 --- a/cores/esp8266/esp8266_undocumented.h +++ b/cores/esp8266/esp8266_undocumented.h @@ -241,6 +241,17 @@ extern fn_c_exception_handler_t _xtos_c_handler_table[XCHAL_EXCCAUSE_NUM]; extern fn_c_exception_handler_t _xtos_set_exception_handler(int cause, fn_c_exception_handler_t fn); #endif +/* + BootROM function that sends the SPI Flash "Write Enable" command, 0x06. + The function internally calls Wait_SPI_Idle before enabling. + Polls status register forever waiting for WEL bit to set. + This function always returns 0; however, most examples test for 0. + + Every function I find that needs WEL set, call this function. I suspect the + waiting for the WEL bit to set is a Flash chip anomaly workaround. +*/ +extern SpiFlashOpResult SPI_write_enable(SpiFlashChip *fc); + extern uint32_t Wait_SPI_Idle(SpiFlashChip *fc); extern void Cache_Read_Disable(); extern int32_t system_func1(uint32_t); diff --git a/cores/esp8266/spi_utils.h b/cores/esp8266/spi_utils.h index bf0928f288..181554a55a 100644 --- a/cores/esp8266/spi_utils.h +++ b/cores/esp8266/spi_utils.h @@ -35,7 +35,7 @@ typedef enum { SPI_RESULT_TIMEOUT } SpiOpResult; -SpiOpResult SPI0Command(uint8_t cmd, uint32_t *data, uint32_t mosi_bits, uint32_t miso_bits); +SpiOpResult SPI0Command(uint8_t cmd, uint32_t *data, uint32_t mosi_bits, uint32_t miso_bits, uint32_t pre_cmd=0); } #ifdef __cplusplus diff --git a/cores/esp8266/stdlib_noniso.cpp b/cores/esp8266/stdlib_noniso.cpp index 693dfda850..4fed9b615d 100644 --- a/cores/esp8266/stdlib_noniso.cpp +++ b/cores/esp8266/stdlib_noniso.cpp @@ -21,11 +21,13 @@ #include "stdlib_noniso.h" +extern "C" { + // ulltoa() is slower than std::to_char() (1.6 times) // but is smaller by ~800B/flash and ~250B/rodata // ulltoa fills str backwards and can return a pointer different from str -char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix) +char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix) noexcept { str += --slen; *str = 0; @@ -39,7 +41,7 @@ char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix) } // lltoa fills str backwards and can return a pointer different from str -char* lltoa (long long val, char* str, int slen, unsigned int radix) +char* lltoa(long long val, char* str, int slen, unsigned int radix) noexcept { bool neg; if (val < 0) @@ -60,3 +62,13 @@ char* lltoa (long long val, char* str, int slen, unsigned int radix) } return ret; } + +char* ltoa(long value, char* result, int base) noexcept { + return itoa((int)value, result, base); +} + +char* ultoa(unsigned long value, char* result, int base) noexcept { + return utoa((unsigned int)value, result, base); +} + +} // extern "C" diff --git a/cores/esp8266/stdlib_noniso.h b/cores/esp8266/stdlib_noniso.h index f86f78befc..0c8c488ed1 100644 --- a/cores/esp8266/stdlib_noniso.h +++ b/cores/esp8266/stdlib_noniso.h @@ -22,38 +22,35 @@ #ifndef STDLIB_NONISO_H #define STDLIB_NONISO_H +#include + #ifdef __cplusplus -extern "C"{ +extern "C" { #endif -int atoi(const char *s); - -long atol(const char* s); - -double atof(const char* s); - -char* itoa (int val, char *s, int radix); - -char* ltoa (long val, char *s, int radix); +#ifdef __cplusplus +#define __STDLIB_NONISO_NOEXCEPT noexcept +#else +#define __STDLIB_NONISO_NOEXCEPT +#endif -char* lltoa (long long val, char* str, int slen, unsigned int radix); +char* ltoa (long val, char *s, int radix) __STDLIB_NONISO_NOEXCEPT; -char* utoa (unsigned int val, char *s, int radix); +char* lltoa (long long val, char* str, int slen, unsigned int radix) __STDLIB_NONISO_NOEXCEPT; -char* ultoa (unsigned long val, char *s, int radix); +char* ultoa (unsigned long val, char *s, int radix) __STDLIB_NONISO_NOEXCEPT; -char* ulltoa (unsigned long long val, char* str, int slen, unsigned int radix); +char* ulltoa (unsigned long long val, char* str, int slen, unsigned int radix) __STDLIB_NONISO_NOEXCEPT; -char* dtostrf (double val, signed char width, unsigned char prec, char *s); +char* dtostrf (double val, signed char width, unsigned char prec, char *s) __STDLIB_NONISO_NOEXCEPT; -void reverse(char* begin, char* end); +const char* strrstr (const char*__restrict p_pcString, + const char*__restrict p_pcPattern) __STDLIB_NONISO_NOEXCEPT; -const char* strrstr(const char*__restrict p_pcString, - const char*__restrict p_pcPattern); +#undef __STDLIB_NONISO_NOEXCEPT #ifdef __cplusplus } // extern "C" #endif - #endif diff --git a/doc/Makefile b/doc/Makefile index 36b4923488..61d3e40b3c 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -2,7 +2,7 @@ # # You can set these variables from the command line. -SPHINXOPTS = +SPHINXOPTS = --fail-on-warning --nitpicky SPHINXBUILD = sphinx-build SPHINXPROJ = ESP8266ArduinoCore SOURCEDIR = . @@ -17,4 +17,4 @@ help: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/doc/boards.rst b/doc/boards.rst index c8cd3d6bdb..99421d86b9 100644 --- a/doc/boards.rst +++ b/doc/boards.rst @@ -39,25 +39,30 @@ Minimal Hardware Setup for Bootloading and Usage +-----------------+------------+------------------+ | GND | | GND | +-----------------+------------+------------------+ -| TX or GPIO2\* | | RX | +| TX or GPIO2 | | | +| [#tx_or_gpio2]_ | RX | | +-----------------+------------+------------------+ | RX | | TX | +-----------------+------------+------------------+ | GPIO0 | PullUp | DTR | +-----------------+------------+------------------+ -| Reset\* | PullUp | RTS | +| Reset | | | +| [#reset]_ | PullUp | RTS | +-----------------+------------+------------------+ -| GPIO15\* | PullDown | | +| GPIO15 | | | +| [#gpio15]_ | PullDown | | +-----------------+------------+------------------+ -| CH\_PD | PullUp | | +| CH\_PD | | | +| [#ch_pd]_ | PullUp | | +-----------------+------------+------------------+ -- Note -- GPIO15 is also named MTDO -- Reset is also named RSBT or REST (adding PullUp improves the +.. rubric:: Notes + +.. [#tx_or_gpio2] GPIO15 is also named MTDO +.. [#reset] Reset is also named RSBT or REST (adding PullUp improves the stability of the module) -- GPIO2 is alternative TX for the boot loader mode -- **Directly connecting a pin to VCC or GND is not a substitute for a +.. [#gpio15] GPIO2 is alternative TX for the boot loader mode +.. [#ch_pd] **Directly connecting a pin to VCC or GND is not a substitute for a PullUp or PullDown resistor, doing this can break upload management and the serial console, instability has also been noted in some cases.** @@ -88,15 +93,16 @@ ESPxx Hardware +---------------+------------+------------------+ | GPIO0 | | GND | +---------------+------------+------------------+ -| Reset | | RTS\* | +| Reset | | RTS [#rts]_ | +---------------+------------+------------------+ | GPIO15 | PullDown | | +---------------+------------+------------------+ | CH\_PD | PullUp | | +---------------+------------+------------------+ -- Note -- if no RTS is used a manual power toggle is needed +.. rubric:: Notes + +.. [#rts] if no RTS is used a manual power toggle is needed Minimal Hardware Setup for Running only ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -176,7 +182,11 @@ rst cause boot mode ~~~~~~~~~ -the first value respects the pin setup of the Pins 0, 2 and 15. +the first value respects the pin setup of the Pins 0, 2 and 15 + +.. code-block:: + + Number = (GPIO15 << 2) | (GPIO0 << 1) | GPIO2 +----------+----------+---------+---------+-------------+ | Number | GPIO15 | GPIO0 | GPIO2 | Mode | @@ -198,7 +208,6 @@ the first value respects the pin setup of the Pins 0, 2 and 15. | 7 | 3.3V | 3.3V | 3.3V | SDIO | +----------+----------+---------+---------+-------------+ -note: - number = ((GPIO15 << 2) \| (GPIO0 << 1) \| GPIO2); Generic ESP8285 Module ---------------------- @@ -262,6 +271,13 @@ ESPresso Lite 2.0 ESPresso Lite 2.0 is an Arduino-compatible Wi-Fi development board based on an earlier V1 (beta version). Re-designed together with Cytron Technologies, the newly-revised ESPresso Lite V2.0 features the auto-load/auto-program function, eliminating the previous need to reset the board manually before flashing a new program. It also feature two user programmable side buttons and a reset button. The special distinctive features of on-board pads for I2C sensor and actuator is retained. +Mercury 1.0 +----------- + +Based on ESP8266, Mercury is board developed by Ralio Technologies. Board supports on motor drivers and direct-connect feature for various endpoints. + +Product page: https://www.raliotech.com + Phoenix 1.0 ----------- @@ -413,14 +429,10 @@ ThaiEasyElec's ESPino ESPino by ThaiEasyElec using WROOM-02 module from Espressif Systems with 4 MB Flash. -We will update an English description soon. - Product page: -http://thaieasyelec.com/products/wireless-modules/wifi-modules/espino-wifi-development-board-detail.html -- Schematics: -www.thaieasyelec.com/downloads/ETEE052/ETEE052\_ESPino\_Schematic.pdf - -Dimensions: -http://thaieasyelec.com/downloads/ETEE052/ETEE052\_ESPino\_Dimension.pdf -- Pinouts: -http://thaieasyelec.com/downloads/ETEE052/ETEE052\_ESPino\_User\_Manual\_TH\_v1\_0\_20160204.pdf (Please see pg. 8) +* Product page (retired product): https://www.thaieasyelec.com/product/%E0%B8%A2%E0%B8%81%E0%B9%80%E0%B8%A5%E0%B8%B4%E0%B8%81%E0%B8%88%E0%B8%B3%E0%B8%AB%E0%B8%99%E0%B9%88%E0%B8%B2%E0%B8%A2-retired-espino-wifi-development-board/11000833173001086 +* Schematics: https://downloads.thaieasyelec.com/ETEE052/ETEE052\_ESPino\_Schematic.pdf +* Dimensions: https://downloads.thaieasyelec.com/ETEE052/ETEE052\_ESPino\_Dimension.pdf +* Pinouts (Please see pg.8): https://downloads.thaieasyelec.com/ETEE052/ETEE052\_ESPino\_User\_Manual\_TH\_v1\_0\_20160204.pdf WifInfo ------- diff --git a/doc/conf.py b/doc/conf.py index 3b05ae5617..0eef82bc24 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -66,12 +66,12 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'en' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['_venv', '_build', 'Thumbs.db', '.DS_Store'] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' @@ -162,11 +162,7 @@ # # on_rtd is whether we are on readthedocs.org env_readthedocs = os.environ.get('READTHEDOCS', None) -print(env_readthedocs) if not env_readthedocs: # only import and set the theme if we're building docs locally import sphinx_rtd_theme html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] - - diff --git a/doc/esp8266wifi/generic-examples.rst b/doc/esp8266wifi/generic-examples.rst index bbac0cd839..98ccf6c47b 100644 --- a/doc/esp8266wifi/generic-examples.rst +++ b/doc/esp8266wifi/generic-examples.rst @@ -38,23 +38,39 @@ Register the Events To get events to work we need to complete just two steps: -1. Declare the event handler: +1. Declare the event handler in global scope. -``cpp WiFiEventHandler disconnectedEventHandler;`` +.. code-block:: cpp -2. Select particular event (in this case ``onStationModeDisconnected``) - and add the code to be executed when event is fired. + WiFiEventHandler disconnectedEventHandler; -``cpp disconnectedEventHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected& event) { Serial.println("Station disconnected"); });`` If this event is fired the code will print out information that station has been disconnected. +Alternatively, it can be declared as ``static`` in both function and global scopes. -That's it. It is all we need to do. + +2. Select particular event (in this case ``onStationModeDisconnected``). + When this event is fired the code will print out information that station has been disconnected: + +.. code-block:: cpp + + disconnectedEventHandler = WiFi.onStationModeDisconnected( + [](auto&& event) { + Serial.println("Station disconnected"); + }); + +3. Disable ``disconnectedEventHandler``, so the event is no longer handled by our callback: + +.. code-block:: cpp + + disconnectedEventHandler = nullptr; + +Take note that lifetime of the callback handler is up to the app. e.g. if ``onStationModeDisconnected`` is declared in the function scope, it would be discarded immediately after the function exits. The Code ~~~~~~~~ The complete code, including both methods discussed at the beginning, is provided below. -.. code:: cpp +.. code-block:: cpp #include diff --git a/doc/esp8266wifi/server-class.rst b/doc/esp8266wifi/server-class.rst index 8b8bc0e6c1..8bcce99944 100644 --- a/doc/esp8266wifi/server-class.rst +++ b/doc/esp8266wifi/server-class.rst @@ -18,6 +18,11 @@ For most use cases the basic WiFiServer class of the ESP8266WiFi library is suit Methods and properties described further down are specific to ESP8266. They are not covered in `Arduino WiFi library `__ documentation. Before they are fully documented please refer to information below. +begin(port) +~~~~~~~~~~~ + +Additionally to ``begin()`` without parameter and a constructor with parameter ``port``, ESP8266WiFi library has ``begin(uint16_t port)`` and a constructor without parameters. If port is not specified with constructor and ``begin`` without parameter is used, the server is started on port 23. + accept ~~~~~~ diff --git a/doc/esp8266wifi/server-examples.rst b/doc/esp8266wifi/server-examples.rst index cbe5c1abf7..c10b5f7eba 100644 --- a/doc/esp8266wifi/server-examples.rst +++ b/doc/esp8266wifi/server-examples.rst @@ -16,7 +16,6 @@ Table of Contents - `The Page is Served <#the-page-is-served>`__ - `Get it Together <#put-it-together>`__ - `Get it Run <#get-it-run>`__ -- `What Else? <#what-else>`__ - `Conclusion <#conclusion>`__ The Object diff --git a/doc/esp8266wifi/soft-access-point-examples.rst b/doc/esp8266wifi/soft-access-point-examples.rst index c4cf39c6c2..2c9fee762c 100644 --- a/doc/esp8266wifi/soft-access-point-examples.rst +++ b/doc/esp8266wifi/soft-access-point-examples.rst @@ -79,7 +79,9 @@ Sketch is small so analysis shouldn't be difficult. In first line we are includi Setting up of the access point ``ESPsoftAP_01`` is done by executing: -``cpp boolean result = WiFi.softAP("ESPsoftAP_01", "pass-to-soft-AP");`` +.. code:: cpp + + boolean result = WiFi.softAP("ESPsoftAP_01", "pass-to-soft-AP"); If this operation is successful then ``result`` will be ``true`` or ``false`` if otherwise. Basing on that either ``Ready`` or ``Failed!`` will be printed out by the following ``if - else`` conditional statement. diff --git a/doc/esp8266wifi/station-class.rst b/doc/esp8266wifi/station-class.rst index 787de49684..06e072adc6 100644 --- a/doc/esp8266wifi/station-class.rst +++ b/doc/esp8266wifi/station-class.rst @@ -7,6 +7,8 @@ The number of features provided by ESP8266 in the station mode is far more exten Description of station class has been broken down into four parts. First discusses methods to establish connection to an access point. Second provides methods to manage connection like e.g. ``reconnect`` or ``isConnected``. Third covers properties to obtain information about connection like MAC or IP address. Finally the fourth section provides alternate methods to connect like e.g. Wi-Fi Protected Setup (WPS). +An effort to unify such network device class accross several Arduino core implementations has been made. Recommandations are located at `Arduino-Networking-API `__ and tested with `NetApiHelpers `__. Esp8266 Arduino core's station class is also following these guidelines. + Table of Contents ----------------- @@ -97,8 +99,12 @@ config Disable `DHCP `__ client (Dynamic Host Configuration Protocol) and set the IP configuration of station interface to user defined arbitrary values. The interface will be a static IP configuration instead of values provided by DHCP. +Note that to reenable DHCP, all three parameters (local_ip, gateway and subnet) as IPv4 ``0U`` (= 0.0.0.0) must be passed back to config() and re-connecting is needed. + .. code:: cpp + WiFi.config(local_ip, gateway, subnet) (for Arduino API portability, discouraged as chosen defaults may not match the local network configuration) + WiFi.config(local_ip, gateway, subnet, dns1) WiFi.config(local_ip, gateway, subnet, dns1, dns2) Function will return ``true`` if configuration change is applied successfully. If configuration can not be applied, because e.g. module is not in station or station + soft access point mode, then ``false`` will be returned. @@ -116,6 +122,21 @@ The following IP configuration may be provided: (like e.g. *www.google.co.uk*) and translate them for us to IP addresses +For Arduino networking API compatibility, the ESP8266WiFi library supports IPv4-only additional versions of the ``config`` function: + +.. code:: cpp + + WiFi.config(local_ip) (for Arduino API portability, discouraged as chosen defaults may not match the local network configuration) + WiFi.config(local_ip, dns) (for Arduino API portability, discouraged as chosen defaults may not match the local network configuration) + WiFi.config(local_ip, dns, gateway) (for Arduino API portability, discouraged as chosen defaults may not match the local network configuration) + WiFi.config(local_ip, dns, gateway, subnet) + +Versions where some of ``dns``, ``gateway`` and ``subnet`` parameters are not specified use a default value. Default ``subnet`` is 255.255.255.0. Default ``gateway`` and ``dns`` are derived from ``local_ip`` by changing the last number to 1. It is discouraged to use these default values as they may not apply to every network configuration. + +Reminder : To reenable DHCP you can use ``WiFi.config(0U, 0U, 0U);``. + +**Warning: The default values for dns, gateway and subnet may not match your router's settings.** Also please note, that ``config(local_ip, gateway)`` is not supported and ``WiFi.config(local_ip, gateway, subnet)`` doesn't set the DNS server IP. + *Example code:* .. code:: cpp @@ -157,8 +178,7 @@ The following IP configuration may be provided: . Connected, IP address: 192.168.1.22 -Please note that station with static IP configuration usually connects to the network faster. In the above example it took about 500ms (one dot `.` displayed). This is because obtaining of IP configuration by DHCP client takes time and in this case this step is skipped. If you pass all three parameter as 0.0.0.0 (local_ip, gateway and subnet), it will re enable DHCP. You need to re-connect the device to get new IPs. - +Please note that station with static IP configuration usually connects to the network faster. In the above example it took about 500ms (one dot `.` displayed). This is because obtaining of IP configuration by DHCP client takes time and in this case this step is skipped. Reminder: If you pass all three parameters as 0.0.0.0 (local_ip, gateway and subnet), it will re enable DHCP. You need to re-connect the device to get new IPs. Manage Connection ~~~~~~~~~~~~~~~~~ @@ -453,7 +473,7 @@ Function returns one of the following connection statuses: - ``WL_IDLE_STATUS`` when Wi-Fi is in process of changing between statuses - ``WL_DISCONNECTED`` if module is not configured in station mode -Returned value is type of ``wl_status_t`` defined in `wl\_definitions.h `__ +Returned value is type of ``wl_status_t`` defined in `wl\_definitions.h `__ *Example code:* @@ -491,7 +511,7 @@ Returned value is type of ``wl_status_t`` defined in `wl\_definitions.h `__ as follows: +Particular connection statuses 6 and 3 may be looked up in `wl\_definitions.h `__ as follows: :: diff --git a/doc/faq/a01-espcomm_sync-failed.rst b/doc/faq/a01-espcomm_sync-failed.rst index df4d0aa177..d47a5d2eeb 100644 --- a/doc/faq/a01-espcomm_sync-failed.rst +++ b/doc/faq/a01-espcomm_sync-failed.rst @@ -9,7 +9,7 @@ I am getting "espcomm\_sync failed" error when trying to upload my ESP. How to r - `Reset Methods <#reset-methods>`__ - `Ck <#ck>`__ - `Nodemcu <#nodemcu>`__ -- `I'm Stuck <#im-stuck>`__ +- `I'm Stuck <#i-m-stuck>`__ - `Conclusion <#conclusion>`__ Introduction diff --git a/doc/faq/a02-my-esp-crashes.rst b/doc/faq/a02-my-esp-crashes.rst index 0134dda666..ec6340e8c7 100644 --- a/doc/faq/a02-my-esp-crashes.rst +++ b/doc/faq/a02-my-esp-crashes.rst @@ -5,7 +5,7 @@ My ESP crashes running some code. How to troubleshoot it? - `Introduction <#introduction>`__ - `What ESP has to Say <#what-esp-has-to-say>`__ -- `Get Your H/W Right <#get-your-hw-right>`__ +- `Get Your H/W Right <#get-your-h-w-right>`__ - `Enable compilation warnings <#enable-compilation-warnings>`__ - `What is the Cause of Restart? <#what-is-the-cause-of-restart>`__ - `Exception <#exception>`__ @@ -148,8 +148,8 @@ table to understand what kind of issue it is. If you have no clues what it's about and where it happens, then use `Arduino ESP8266/ESP32 Exception Stack Trace Decoder `__ to find -out in which line of application it is triggered. Please refer to `Check -Where the Code Crashes <#check-where-the-code-crashes>`__ point below +out in which line of application it is triggered. Please refer to +`Exception decoder <#exception-decoder>`__ point below for a quick example how to do it. **NOTE:** When decoding exceptions be sure to include all lines between diff --git a/doc/faq/a03-library-does-not-work.rst b/doc/faq/a03-library-does-not-work.rst index 8b9b2d6910..6597c1a1dc 100644 --- a/doc/faq/a03-library-does-not-work.rst +++ b/doc/faq/a03-library-does-not-work.rst @@ -7,7 +7,7 @@ This Arduino library doesn't work on ESP. How do I make it working? - `Identify the Issues <#identify-the-issues>`__ - `Fix it Yourself <#fix-it-yourself>`__ - `Compilation Errors <#compilation-errors>`__ -- `Exceptions / Watchdog Resets <#exceptions--watchdog-resets>`__ +- `Exceptions / Watchdog Resets <#exceptions-watchdog-resets>`__ - `Functionality Issues <#functionality-issues>`__ - `Conclusion <#conclusion>`__ diff --git a/doc/ideoptions.rst b/doc/ideoptions.rst index f591772548..25fd08defa 100644 --- a/doc/ideoptions.rst +++ b/doc/ideoptions.rst @@ -263,6 +263,12 @@ See our issue tracker in regards to default version selection. Notice that 3.x.x is provided **as-is** and remains **experimental**. +Floating Point operations +~~~~~~~~~~~~~~~~~~~~~~~~~ + +- ``in IROM``: This provides more free space in IRAM but disallows using floating operations inside ISRs. +- ``allowed in ISR``: Floats can be used in ISRs, cost is ~1KB IRAM when floats are used. + SSL Support ~~~~~~~~~~~ diff --git a/doc/mmu.rst b/doc/mmu.rst index 3846bc3f81..27ea4d4d7d 100644 --- a/doc/mmu.rst +++ b/doc/mmu.rst @@ -250,5 +250,3 @@ address range of IRAM or DRAM. uint8_t mmu_set_uint8(void *p8, const uint8_t val); uint16_t mmu_set_uint16(uint16_t *p16, const uint16_t val); int16_t mmu_set_int16(int16_t *p16, const int16_t val); - -:: diff --git a/doc/ota_updates/readme.rst b/doc/ota_updates/readme.rst index 373327fe8c..de351fe3f2 100755 --- a/doc/ota_updates/readme.rst +++ b/doc/ota_updates/readme.rst @@ -216,7 +216,7 @@ Requirements Application Example ~~~~~~~~~~~~~~~~~~~ -Instructions below show configuration of OTA on a NodeMCU 1.0 (ESP-12E Module) board. You can use any other board that meets the `requirements <#basic-requirements>`__ described above. This instruction is valid for all operating systems supported by the Arduino IDE. Screen captures have been made on Windows 7 and you may see small differences (like name of the serial port), if you are using Linux or MacOS. +Instructions below show configuration of OTA on a NodeMCU 1.0 (ESP-12E Module) board. You can use any other board that meets the `requirements <#ota-basic-requirements>`__ described above. This instruction is valid for all operating systems supported by the Arduino IDE. Screen captures have been made on Windows 7 and you may see small differences (like name of the serial port), if you are using Linux or MacOS. 1. Before you begin, please make sure that you have the following software installed: @@ -336,7 +336,7 @@ Select COM port and baud rate on external terminal program as if you were using :alt: Termite settings -Then run OTA from IDE and look what is displayed on terminal. Successful `ArduinoOTA <#arduinoota>`__ process using BasicOTA.ino sketch looks like below (IP address depends on your network configuration): +Then run OTA from IDE and look what is displayed on terminal. Successful `ArduinoOTA <#arduino-ide>`__ process using BasicOTA.ino sketch looks like below (IP address depends on your network configuration): .. figure:: a-ota-external-serial-terminal-output.png :alt: OTA upload successful - output on an external serial terminal @@ -407,7 +407,7 @@ The sample implementation provided below has been done using: ``ESP8266HTTPUpdateServer`` library, - NodeMCU 1.0 (ESP-12E Module). -You can use another module if it meets previously described `requirements <#basic-requirements>`__. +You can use another module if it meets previously described `requirements <#ota-basic-requirements>`__. 1. Before you begin, please make sure that you have the following software installed: @@ -592,34 +592,42 @@ With this information the script now can check if an update is needed. It is als "DOOR-7-g14f53a19", - "18:FE:AA:AA:AA:BB" => "TEMP-1.0.0" - ); - - if(!isset($db[$_SERVER['x-ESP8266-STA-MAC']])) { - header($_SERVER["SERVER_PROTOCOL"].' 500 ESP MAC not configured for updates', true, 500); + + $db_string = '{ + "18:FE:AA:AA:AA:AA": {"file": "DOOR-7-g14f53a19.bin", "version": 1}, + "18:FE:AA:AA:AA:BB": {"file": "TEMP-1.0.0".bin", "version": 1}}'; + // $db_string = file_get_contents("arduino-db.json"); + $db = json_decode($db_string, true); + $mode = $headers['x-ESP8266-mode']; + $mac = $headers['x-ESP8266-STA-MAC']; + + if (!isset($db[$mac])) { + header($_SERVER["SERVER_PROTOCOL"].' 404 ESP MAC not configured for updates', true, 404); + echo "MAC ".$mac." not configured for updates\n"; + exit(); } - - $localBinary = "./bin/".$db[$_SERVER['x-ESP8266-STA-MAC']].".bin"; - - // Check if version has been set and does not match, if not, check if - // MD5 hash between local binary and ESP8266 binary do not match if not. - // then no update has been found. - if((!check_header('x-ESP8266-sdk-version') && $db[$_SERVER['x-ESP8266-STA-MAC']] != $_SERVER['x-ESP8266-version']) - || $_SERVER["x-ESP8266-sketch-md5"] != md5_file($localBinary)) { - sendFile($localBinary); + + $localBinary = $db[$mac]['file']; + $localVersion = $db[$mac]['version']; + + if (!is_readable($localBinary)) { + header($_SERVER["SERVER_PROTOCOL"].' 404 File not found', true, 404); + echo "File ".$localBinary." not found\n"; + exit(); + } + + if ($mode == 'sketch') { + // Check if version has been set and does not match, if not, check if + // MD5 hash between local binary and ESP8266 binary do not match if not. + // then no update has been found. + if ((check_header('x-ESP8266-version') && $headers['x-ESP8266-version'] != $localVersion)) { + // || $headers["x-ESP8266-sketch-md5"] != md5_file($localBinary)) { + sendFile($localBinary, $localVersion); + } else { + header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304); + echo "File ".$localBinary." not modified\n"; + } + } else if ($mode == 'version') { + header($_SERVER["SERVER_PROTOCOL"].' 200 OK', true, 200); + header('x-MD5: '.md5_file($localBinary), true); + header('x-version: '.$localVersion, true); } else { - header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304); + header($_SERVER["SERVER_PROTOCOL"].' 404 Mode not supported', true, 404); + echo "mode: ".$mode." not supported\n"; + exit(); } - - header($_SERVER["SERVER_PROTOCOL"].' 500 no version for ESP MAC', true, 500); + ?> Stream Interface ---------------- diff --git a/doc/requirements.txt b/doc/requirements.txt index 8d90d8f59a..6b2684762d 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,10 +1,8 @@ # Requirements file for pip # list of Python packages used in documentation build -sphinx -sphinx-rtd-theme -breathe -nbsphinx -docutils<0.17 -testresources -#at the time of writing, requirement is pygments<3,>=2.4.1 -pygments>=2.4.1 +sphinx>=8.1.2,<9.0.0 +sphinx-rtd-theme>=3.0.2,<4.0.0 +breathe>=4.36.0,<5.0.0 +nbsphinx>=0.9.7,<1.0.0 +testresources>=2.0.1,<3.0.0 +pygments>=2.19.1,<3.0.0 diff --git a/libraries/ArduinoOTA/ArduinoOTA.cpp b/libraries/ArduinoOTA/ArduinoOTA.cpp index 1ef83b895f..4ee31e3751 100644 --- a/libraries/ArduinoOTA/ArduinoOTA.cpp +++ b/libraries/ArduinoOTA/ArduinoOTA.cpp @@ -359,9 +359,14 @@ void ArduinoOTAClass::_runUpdate() { } void ArduinoOTAClass::end() { + if (!_initialized) + return; + _initialized = false; - _udp_ota->unref(); - _udp_ota = 0; + if(_udp_ota){ + _udp_ota->unref(); + _udp_ota = 0; + } #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS) if(_useMDNS){ MDNS.end(); diff --git a/libraries/DNSServer/examples/CaptivePortalAdvanced/CaptivePortalAdvanced.ino b/libraries/DNSServer/examples/CaptivePortalAdvanced/CaptivePortalAdvanced.ino index 55222fbc7b..1aef1afd20 100644 --- a/libraries/DNSServer/examples/CaptivePortalAdvanced/CaptivePortalAdvanced.ino +++ b/libraries/DNSServer/examples/CaptivePortalAdvanced/CaptivePortalAdvanced.ino @@ -4,6 +4,7 @@ #include #include #include +#include /* This example serves a "hello world" on a WLAN and a SoftAP at the same time. @@ -74,8 +75,8 @@ void setup() { server.on("/", handleRoot); server.on("/wifi", handleWifi); server.on("/wifisave", handleWifiSave); - server.on("/generate_204", handleRoot); // Android captive portal. Maybe not needed. Might be handled by notFound handler. - server.on("/fwlink", handleRoot); // Microsoft captive portal. Maybe not needed. Might be handled by notFound handler. + server.on(UriGlob("/generate_204*"), handleRoot); // Android captive portal. Handle "/generate_204_"-like requests. Might be handled by notFound handler. + server.on("/fwlink", handleRoot); // Microsoft captive portal. Maybe not needed. Might be handled by notFound handler. server.onNotFound(handleNotFound); server.begin(); // Web server start Serial.println("HTTP server started"); diff --git a/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino b/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino index aec2556a48..c7380017d1 100644 --- a/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino +++ b/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino @@ -27,9 +27,7 @@ void handleRoot() { boolean captivePortal() { if (!isIp(server.hostHeader()) && server.hostHeader() != (String(myHostname) + ".local")) { Serial.println("Request redirected to captive portal"); - server.sendHeader("Location", String("http://") + toStringIp(server.client().localIP()), true); - server.send(302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves. - server.client().stop(); // Stop is needed because we sent no content length + server.redirect(String("http://") + toStringIp(server.client().localIP())); return true; } return false; @@ -91,12 +89,7 @@ void handleWifiSave() { Serial.println("wifi save"); server.arg("n").toCharArray(ssid, sizeof(ssid) - 1); server.arg("p").toCharArray(password, sizeof(password) - 1); - server.sendHeader("Location", "wifi", true); - server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); - server.sendHeader("Pragma", "no-cache"); - server.sendHeader("Expires", "-1"); - server.send(302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves. - server.client().stop(); // Stop is needed because we sent no content length + server.redirect("wifi"); saveCredentials(); connect = strlen(ssid) > 0; // Request WLAN connect with new credentials if there is a SSID } diff --git a/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino b/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino index 286490772d..5de12229a5 100644 --- a/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino +++ b/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino @@ -36,13 +36,11 @@ void sendPortalRedirect(String path, String targetName) { If the "Location" header element works the HTML stuff is never seen. */ // https://tools.ietf.org/html/rfc7231#section-6.4.3 - server.sendHeader("Location", path, true); - addNoCacheHeader(); String reply = FPSTR(portalRedirectHTML); reply.reserve(reply.length() + 2 * path.length() + 80); reply.replace("{t}", targetName); reply.replace("{1}", path); - server.send(302, "text/html", reply); + server.redirect(path, reply); } #endif // LWIP_FEATURES && !LWIP_IPV6 diff --git a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino index 62bfc93a9a..0e174c2790 100644 --- a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino +++ b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino @@ -39,10 +39,15 @@ void loop() { // wait for WiFi connection if ((WiFiMulti.run() == WL_CONNECTED)) { - std::unique_ptr client(new BearSSL::WiFiClientSecure); + auto certs = std::make_unique(cert_Cloudflare_Inc_ECC_CA_3); + auto client = std::make_unique(); - client->setFingerprint(fingerprint_sni_cloudflaressl_com); - // Or, if you happy to ignore the SSL certificate, then use the following line instead: + client->setTrustAnchors(certs.get()); + // Or, if you prefer to use fingerprinting: + // client->setFingerprint(fingerprint_w3_org); + // This is *not* a recommended option, as fingerprint changes with the host certificate + + // Or, if you are *absolutely* sure it is ok to ignore the SSL certificate: // client->setInsecure(); HTTPClient https; diff --git a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/certs.h b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/certs.h index 0263070421..76451ff76a 100644 --- a/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/certs.h +++ b/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/certs.h @@ -1,7 +1,7 @@ // this file is autogenerated - any modification will be overwritten // unused symbols will not be linked in the final binary -// generated on 2023-03-20 23:02:42 +// generated on 2024-07-30 22:46:21 // by ['../../../../tools/cert.py', '-s', 'jigsaw.w3.org', '-n', 'jigsaw'] #pragma once @@ -12,21 +12,21 @@ const char* jigsaw_host = "jigsaw.w3.org"; const uint16_t jigsaw_port = 443; -// CN: sni.cloudflaressl.com => name: sni_cloudflaressl_com -// not valid before: 2023-02-14 00:00:00 -// not valid after: 2024-02-14 23:59:59 -const char fingerprint_sni_cloudflaressl_com [] PROGMEM = "70:7c:82:07:f3:58:18:87:25:42:31:83:45:86:bd:17:86:71:4e:1f"; -const char pubkey_sni_cloudflaressl_com [] PROGMEM = R"PUBKEY( +// CN: w3.org => name: w3_org +// not valid before: 2024-01-26 00:00:00+00:00 +// not valid after: 2024-12-31 23:59:59+00:00 +const char fingerprint_w3_org [] PROGMEM = "07:f2:bd:4c:d0:ce:58:da:13:03:9d:a9:0d:df:e9:5b:60:5f:7f:a5"; +const char pubkey_w3_org [] PROGMEM = R"PUBKEY( -----BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/NU/7vfdymScyhfx81ieO8XiwGqq -TU4tjeWzSosWSpmQwnGmRqiU2h2wyT9uYxRme6uQ0yLedf4nz9ks+4OxtA== +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPwx1EbG8lugJ74owfhQChFkoxc9R +EZ9D7g5JfO7TUZH+nxWxCT7njoKgD9yvJZYTy/oijTdhB7o7knUsBLRj8A== -----END PUBLIC KEY----- )PUBKEY"; // http://cacerts.digicert.com/CloudflareIncECCCA-3.crt // CN: Cloudflare Inc ECC CA-3 => name: Cloudflare_Inc_ECC_CA_3 -// not valid before: 2020-01-27 12:48:08 -// not valid after: 2024-12-31 23:59:59 +// not valid before: 2020-01-27 12:48:08+00:00 +// not valid after: 2024-12-31 23:59:59+00:00 const char cert_Cloudflare_Inc_ECC_CA_3 [] PROGMEM = R"CERT( -----BEGIN CERTIFICATE----- MIIDzTCCArWgAwIBAgIQCjeHZF5ftIwiTv0b7RQMPDANBgkqhkiG9w0BAQsFADBa diff --git a/libraries/ESP8266HTTPClient/examples/PostHttpClient/PostHttpClient.ino b/libraries/ESP8266HTTPClient/examples/PostHttpClient/PostHttpClient.ino index 72d51142c7..bb248d35ed 100644 --- a/libraries/ESP8266HTTPClient/examples/PostHttpClient/PostHttpClient.ino +++ b/libraries/ESP8266HTTPClient/examples/PostHttpClient/PostHttpClient.ino @@ -15,7 +15,7 @@ bin/PostServer/PostServer then put your PC's IP address in SERVER_IP below, port 9080 (instead of default 80): */ -//#define SERVER_IP "10.0.1.7:9080" // PC address with emulation on host +// #define SERVER_IP "10.0.1.7:9080" // PC address with emulation on host #define SERVER_IP "192.168.1.42" #ifndef STASSID diff --git a/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/StreamHttpsClient.ino b/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/StreamHttpsClient.ino index 5c80a1eeb8..df3b2f233f 100644 --- a/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/StreamHttpsClient.ino +++ b/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/StreamHttpsClient.ino @@ -1,7 +1,5 @@ /** - StreamHTTPClient.ino - - Created on: 24.05.2015 + Based on StreamHTTPClient.ino */ @@ -9,9 +7,10 @@ #include #include - #include +#include "certs.h" + ESP8266WiFiMulti WiFiMulti; void setup() { @@ -37,23 +36,27 @@ void loop() { // wait for WiFi connection if ((WiFiMulti.run() == WL_CONNECTED)) { - std::unique_ptr client(new BearSSL::WiFiClientSecure); + auto certs = std::make_unique(cert_Amazon_RSA_2048_M02); + auto client = std::make_unique(); + + client->setTrustAnchors(certs.get()); + // Or, if you prefer to use fingerprinting: + // client->setFingerprint(fingerprint___mbed_com); + // This is *not* a recommended option, as fingerprint changes with the host certificate - bool mfln = client->probeMaxFragmentLength("tls.mbed.org", 443, 1024); - Serial.printf("\nConnecting to https://tls.mbed.org\n"); + // Or, if you are *absolutely* sure it is ok to ignore the SSL certificate: + // client->setInsecure(); + + bool mfln = client->probeMaxFragmentLength(mbed_host, mbed_port, 1024); + Serial.printf("\nConnecting to %s:%hu...\n", mbed_host, mbed_port); Serial.printf("Maximum fragment Length negotiation supported: %s\n", mfln ? "yes" : "no"); if (mfln) { client->setBufferSizes(1024, 1024); } Serial.print("[HTTPS] begin...\n"); - // configure server and url - const uint8_t fingerprint[20] = { 0x15, 0x77, 0xdc, 0x04, 0x7c, 0x00, 0xf8, 0x70, 0x09, 0x34, 0x24, 0xf4, 0xd3, 0xa1, 0x7a, 0x6c, 0x1e, 0xa3, 0xe0, 0x2a }; - - client->setFingerprint(fingerprint); - HTTPClient https; - if (https.begin(*client, "https://tls.mbed.org/")) { + if (https.begin(*client, mbed_host, mbed_port)) { Serial.print("[HTTPS] GET...\n"); // start connection and send HTTP header diff --git a/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/certUpdate b/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/certUpdate new file mode 100755 index 0000000000..cb11cef93c --- /dev/null +++ b/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/certUpdate @@ -0,0 +1,2 @@ +cd ${0%/*} 2>/dev/null +python3 ../../../../tools/cert.py -s tls.mbed.org -n mbed > certs.h diff --git a/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/certs.h b/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/certs.h new file mode 100644 index 0000000000..c06f2d2154 --- /dev/null +++ b/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/certs.h @@ -0,0 +1,173 @@ + +// this file is autogenerated - any modification will be overwritten +// unused symbols will not be linked in the final binary +// generated on 2024-07-30 22:46:02 +// by ['../../../../tools/cert.py', '-s', 'tls.mbed.org', '-n', 'mbed'] + +#pragma once + +//////////////////////////////////////////////////////////// +// certificate chain for tls.mbed.org:443 + +const char* mbed_host = "tls.mbed.org"; +const uint16_t mbed_port = 443; + +// CN: *.mbed.com => name: __mbed_com +// not valid before: 2023-12-15 00:00:00 +// not valid after: 2025-01-12 23:59:59 +const char fingerprint___mbed_com [] PROGMEM = "cf:a3:3a:98:de:77:ee:a0:d8:2d:b1:0e:c9:eb:d3:5d:71:5c:4d:1c"; +const char pubkey___mbed_com [] PROGMEM = R"PUBKEY( +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnte0NyyUAM7CJHORnzqZ +0vYhz9K1wdi0Fkc11gypDgyaEXmLY3m0X+mXayEbhw/Xkn04uQ0/6WyK/pWTeTeu +MPKD1Gr5xjBNELs0GLdRdfZGhUyFkTgQLtDrbEpD8gNO2bfVOiJh/tMZ43NNmJUj +lJftSW3ZivBO5621NC9gbfqAQJZNkMoSV1c9JNIPzZCv4aPR/XuZVeKNWQKzAULf +wRsfz5Ti37EWUQ2BNPUOIYQQvOqI0y4FETIUmA4UhjUmb3/KsOTIUx0HML0MYkxe +SCfSzO8zjJaFujrC82LQvwFfIfRbGCK63GREzT4B5SGUgIgOGe1NSfEBqioRNtig +SwIDAQAB +-----END PUBLIC KEY----- +)PUBKEY"; + +// http://crt.r2m02.amazontrust.com/r2m02.cer +// CN: Amazon RSA 2048 M02 => name: Amazon_RSA_2048_M02 +// not valid before: 2022-08-23 22:25:30 +// not valid after: 2030-08-23 22:25:30 +const char cert_Amazon_RSA_2048_M02 [] PROGMEM = R"CERT( +-----BEGIN CERTIFICATE----- +MIIEXjCCA0agAwIBAgITB3MSSkvL1E7HtTvq8ZSELToPoTANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTIyMDgyMzIyMjUzMFoXDTMwMDgyMzIyMjUzMFowPDEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEcMBoGA1UEAxMTQW1hem9uIFJT +QSAyMDQ4IE0wMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALtDGMZa +qHneKei1by6+pUPPLljTB143Si6VpEWPc6mSkFhZb/6qrkZyoHlQLbDYnI2D7hD0 +sdzEqfnuAjIsuXQLG3A8TvX6V3oFNBFVe8NlLJHvBseKY88saLwufxkZVwk74g4n +WlNMXzla9Y5F3wwRHwMVH443xGz6UtGSZSqQ94eFx5X7Tlqt8whi8qCaKdZ5rNak ++r9nUThOeClqFd4oXych//Rc7Y0eX1KNWHYSI1Nk31mYgiK3JvH063g+K9tHA63Z +eTgKgndlh+WI+zv7i44HepRZjA1FYwYZ9Vv/9UkC5Yz8/yU65fgjaE+wVHM4e/Yy +C2osrPWE7gJ+dXMCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD +VR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNV +HQ4EFgQUwDFSzVpQw4J8dHHOy+mc+XrrguIwHwYDVR0jBBgwFoAUhBjMhTTsvAyU +lC4IWZzHshBOCggwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8v +b2NzcC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDov +L2NydC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8E +ODA2MDSgMqAwhi5odHRwOi8vY3JsLnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jv +b3RjYTEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IB +AQAtTi6Fs0Azfi+iwm7jrz+CSxHH+uHl7Law3MQSXVtR8RV53PtR6r/6gNpqlzdo +Zq4FKbADi1v9Bun8RY8D51uedRfjsbeodizeBB8nXmeyD33Ep7VATj4ozcd31YFV +fgRhvTSxNrrTlNpWkUk0m3BMPv8sg381HhA6uEYokE5q9uws/3YkKqRiEz3TsaWm +JqIRZhMbgAfp7O7FUwFIb7UIspogZSKxPIWJpxiPo3TcBambbVtQOcNRWz5qCQdD +slI2yayq0n2TXoHyNCLEH8rpsJRVILFsg0jc7BaFrMnF462+ajSehgj12IidNeRN +4zl+EoNaWdpnWndvSpAEkq2P +-----END CERTIFICATE----- +)CERT"; + +// http://crt.rootca1.amazontrust.com/rootca1.cer +// CN: Amazon Root CA 1 => name: Amazon_Root_CA_1 +// not valid before: 2015-05-25 12:00:00 +// not valid after: 2037-12-31 01:00:00 +const char cert_Amazon_Root_CA_1 [] PROGMEM = R"CERT( +-----BEGIN CERTIFICATE----- +MIIEkjCCA3qgAwIBAgITBn+USionzfP6wq4rAfkI7rnExjANBgkqhkiG9w0BAQsF +ADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNj +b3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4x +OzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1 +dGhvcml0eSAtIEcyMB4XDTE1MDUyNTEyMDAwMFoXDTM3MTIzMTAxMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaOCATEwggEtMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBSEGMyFNOy8DJSULghZnMeyEE4KCDAfBgNVHSMEGDAW +gBScXwDfqgHXMCs4iKK4bUqc8hGRgzB4BggrBgEFBQcBAQRsMGowLgYIKwYBBQUH +MAGGImh0dHA6Ly9vY3NwLnJvb3RnMi5hbWF6b250cnVzdC5jb20wOAYIKwYBBQUH +MAKGLGh0dHA6Ly9jcnQucm9vdGcyLmFtYXpvbnRydXN0LmNvbS9yb290ZzIuY2Vy +MD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwucm9vdGcyLmFtYXpvbnRydXN0 +LmNvbS9yb290ZzIuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsF +AAOCAQEAYjdCXLwQtT6LLOkMm2xF4gcAevnFWAu5CIw+7bMlPLVvUOTNNWqnkzSW +MiGpSESrnO09tKpzbeR/FoCJbM8oAxiDR3mjEH4wW6w7sGDgd9QIpuEdfF7Au/ma +eyKdpwAJfqxGF4PcnCZXmTA5YpaP7dreqsXMGz7KQ2hsVxa81Q4gLv7/wmpdLqBK +bRRYh5TmOTFffHPLkIhqhBGWJ6bt2YFGpn6jcgAKUj6DiAdjd4lpFw85hdKrCEVN +0FE6/V1dN2RMfjCyVSRCnTawXZwXgWHxyvkQAiSr6w10kY17RSlQOYiypok1JR4U +akcjMS9cmvqtmg5iUaQqqcT5NJ0hGA== +-----END CERTIFICATE----- +)CERT"; + +// http://crt.rootg2.amazontrust.com/rootg2.cer +// CN: Starfield Services Root Certificate Authority - G2 => name: Starfield_Services_Root_Certificate_Authority___G2 +// not valid before: 2009-09-02 00:00:00 +// not valid after: 2034-06-28 17:39:16 +const char cert_Starfield_Services_Root_Certificate_Authority___G2 [] PROGMEM = R"CERT( +-----BEGIN CERTIFICATE----- +MIIEdTCCA12gAwIBAgIJAKcOSkw0grd/MA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV +BAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIw +MAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTAeFw0wOTA5MDIwMDAwMDBaFw0zNDA2MjgxNzM5MTZaMIGYMQswCQYDVQQGEwJV +UzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjE7MDkGA1UEAxMyU3RhcmZp +ZWxkIFNlcnZpY2VzIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVDDrEKvlO4vW+GZdfjohTsR8/ +y8+fIBNtKTrID30892t2OGPZNmCom15cAICyL1l/9of5JUOG52kbUpqQ4XHj2C0N +Tm/2yEnZtvMaVq4rtnQU68/7JuMauh2WLmo7WJSJR1b/JaCTcFOD2oR0FMNnngRo +Ot+OQFodSk7PQ5E751bWAHDLUu57fa4657wx+UX2wmDPE1kCK4DMNEffud6QZW0C +zyyRpqbn3oUYSXxmTqM6bam17jQuug0DuDPfR+uxa40l2ZvOgdFFRjKWcIfeAg5J +Q4W2bHO7ZOphQazJ1FTfhy/HIrImzJ9ZVGif/L4qL8RVHHVAYBeFAlU5i38FAgMB +AAGjgfAwge0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0O +BBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMB8GA1UdIwQYMBaAFL9ft9HO3R+G9FtV +rNzXEMIOqYjnME8GCCsGAQUFBwEBBEMwQTAcBggrBgEFBQcwAYYQaHR0cDovL28u +c3MyLnVzLzAhBggrBgEFBQcwAoYVaHR0cDovL3guc3MyLnVzL3guY2VyMCYGA1Ud +HwQfMB0wG6AZoBeGFWh0dHA6Ly9zLnNzMi51cy9yLmNybDARBgNVHSAECjAIMAYG +BFUdIAAwDQYJKoZIhvcNAQELBQADggEBACMd44pXyn3pF3lM8R5V/cxTbj5HD9/G +VfKyBDbtgB9TxF00KGu+x1X8Z+rLP3+QsjPNG1gQggL4+C/1E2DUBc7xgQjB3ad1 +l08YuW3e95ORCLp+QCztweq7dp4zBncdDQh/U90bZKuCJ/Fp1U1ervShw3WnWEQt +8jxwmKy6abaVd38PMV4s/KCHOkdp8Hlf9BRUpJVeEXgSYCfOn8J3/yNTd126/+pZ +59vPr5KW7ySaNRB6nJHGDn2Z9j8Z3/VyVOEVqQdZe4O/Ui5GjLIAZHYcSNPYeehu +VsyuLAOQ1xk4meTKCRlb/weWsKh/NEnfVqn3sF/tM+2MR7cwA130A4w= +-----END CERTIFICATE----- +)CERT"; + +// http://x.ss2.us/x.cer +// CN: => name: +// not valid before: 2004-06-29 17:39:16 +// not valid after: 2024-06-29 17:39:16 +const char cert_ [] PROGMEM = R"CERT( +-----BEGIN CERTIFICATE----- +MIIFEjCCBHugAwIBAgICAQwwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh +bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu +Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g +QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe +BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MzkxNloX +DTI0MDYyOTE3MzkxNlowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVs +ZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAy +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0A +MIIBCAKCAQEAtzLI/ulxpgSFrQwRZN/OTe/IAxiHP6Gr+zymn/DDodrU2G4rU5D7 +JKQ+hPCe6F/s5SdE9SimP3ve4CrwyK9TL57KBQGTHo9mHDmnTfpatnMEJWbrd3/n +WcZKmSUUVOsmx/N/GdUwcI+vsEYq/63rKe3Xn6oEh6PU+YmlNF/bQ5GCNtlmPLG4 +uYL9nDo+EMg77wZlZnqbGRg9/3FRPDAuX749d3OyXQZswyNWmiuFJpIcpwKz5D8N +rwh5grg2Peqc0zWzvGnK9cyd6P1kjReAM25eSl2ZyR6HtJ0awNVuEzUjXt+bXz3v +1vd2wuo+u3gNHEJnawTY+Nbab4vyRKABqwIBA6OCAfMwggHvMB0GA1UdDgQWBBS/ +X7fRzt0fhvRbVazc1xDCDqmI5zCB0gYDVR0jBIHKMIHHoYHBpIG+MIG7MSQwIgYD +VQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNVBAoTDlZhbGlD +ZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAyIFBvbGljeSBWYWxp +ZGF0aW9uIEF1dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52YWxpY2VydC5j +b20vMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHZhbGljZXJ0LmNvbYIBATAPBgNVHRMB +Af8EBTADAQH/MDkGCCsGAQUFBwEBBC0wKzApBggrBgEFBQcwAYYdaHR0cDovL29j +c3Auc3RhcmZpZWxkdGVjaC5jb20wSgYDVR0fBEMwQTA/oD2gO4Y5aHR0cDovL2Nl +cnRpZmljYXRlcy5zdGFyZmllbGR0ZWNoLmNvbS9yZXBvc2l0b3J5L3Jvb3QuY3Js +MFEGA1UdIARKMEgwRgYEVR0gADA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY2VydGlm +aWNhdGVzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkwDgYDVR0PAQH/BAQD +AgEGMA0GCSqGSIb3DQEBBQUAA4GBAKVi8afCXSWlcD284ipxs33kDTcdVWptobCr +mADkhWBKIMuh8D1195TaQ39oXCUIuNJ9MxB73HZn8bjhU3zhxoNbKXuNSm8uf0So +GkVrMgfHeMpkksK0hAzc3S1fTbvdiuo43NlmouxBulVtWmQ9twPMHOKRUJ7jCUSV +FxdzPcwl +-----END CERTIFICATE----- +)CERT"; + + + + +// end of certificate chain for tls.mbed.org:443 +//////////////////////////////////////////////////////////// + diff --git a/libraries/ESP8266SdFat b/libraries/ESP8266SdFat index 46151c90a4..eaab1369d5 160000 --- a/libraries/ESP8266SdFat +++ b/libraries/ESP8266SdFat @@ -1 +1 @@ -Subproject commit 46151c90a410a6f983f2f8c147e13086aaecdd8e +Subproject commit eaab1369d5b988d844888bc560967ae143847d5d diff --git a/libraries/ESP8266WebServer/README.rst b/libraries/ESP8266WebServer/README.rst index 94bb6c5865..c37c6d5e64 100644 --- a/libraries/ESP8266WebServer/README.rst +++ b/libraries/ESP8266WebServer/README.rst @@ -54,8 +54,10 @@ Client request handlers .. code:: cpp - void on(); + RequestHandler& on(); + bool removeRoute(); void addHandler(); + bool removeHandler(); void onNotFound(); void onFileUpload(); @@ -64,9 +66,26 @@ Client request handlers .. code:: cpp server.on("/", handlerFunction); + server.removeRoute("/"); // Removes any route which points to "/" and has HTTP_ANY attribute + server.removeRoute("/", HTTP_GET); // Removes any route which points to "/" and has HTTP_GET attribute server.onNotFound(handlerFunction); // called when handler is not assigned server.onFileUpload(handlerFunction); // handle file uploads +Client request filters +^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: cpp + + RequestHandler& setFilter(); + +*Example:* + +More details about this in `Filters.ino` example. + +.. code:: cpp + + server.on("/", handlerFunction).setFilter(ON_AP_FILTER) + Sending responses to the client ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino b/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino index 5a0937df0c..5469f48184 100644 --- a/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino +++ b/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino @@ -25,15 +25,15 @@ // Select the FileSystem by uncommenting one of the lines below -//#define USE_SPIFFS +// #define USE_SPIFFS #define USE_LITTLEFS -//#define USE_SDFS +// #define USE_SDFS // Uncomment the following line to embed a version of the web page in the code // (program code will be larger, but no file will have to be written to the filesystem). // Note: the source file "extras/index_htm.h" must have been generated by "extras/reduce_index.sh" -//#define INCLUDE_FALLBACK_INDEX_HTM +// #define INCLUDE_FALLBACK_INDEX_HTM //////////////////////////////// diff --git a/libraries/ESP8266WebServer/examples/Filters/Filters.ino b/libraries/ESP8266WebServer/examples/Filters/Filters.ino new file mode 100644 index 0000000000..24c26fc276 --- /dev/null +++ b/libraries/ESP8266WebServer/examples/Filters/Filters.ino @@ -0,0 +1,101 @@ +#include +#include +#include +#include + +// Your STA WiFi Credentials +// ( This is the AP your ESP will connect to ) +const char *ssid = "..."; +const char *password = "..."; + +// Your AP WiFi Credentials +// ( This is the AP your ESP will broadcast ) +const char *ap_ssid = "ESP8266_Demo"; +const char *ap_password = ""; + +ESP8266WebServer server(80); + +const int led = 13; + +// ON_STA_FILTER - Only accept requests coming from STA interface +bool ON_STA_FILTER(ESP8266WebServer &server) { + return WiFi.localIP() == server.client().localIP(); +} + +// ON_AP_FILTER - Only accept requests coming from AP interface +bool ON_AP_FILTER(ESP8266WebServer &server) { + return WiFi.softAPIP() == server.client().localIP(); +} + +void handleNotFound() { + digitalWrite(led, 1); + String message = "File Not Found\n\n"; + message += "URI: "; + message += server.uri(); + message += "\nMethod: "; + message += (server.method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += server.args(); + message += "\n"; + for (uint8_t i = 0; i < server.args(); i++) { + message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; + } + server.send(404, "text/plain", message); + digitalWrite(led, 0); +} + +void setup(void) { + pinMode(led, OUTPUT); + digitalWrite(led, 0); + Serial.begin(115200); + WiFi.mode(WIFI_AP_STA); + // Connect to STA + WiFi.begin(ssid, password); + // Start AP + WiFi.softAP(ap_ssid, ap_password); + Serial.println(""); + + // Wait for connection + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + Serial.print("Connected to "); + Serial.println(ssid); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + + if (MDNS.begin("esp8266")) { + Serial.println("MDNS responder started"); + } + + // This route will be accessible by STA clients only + server.on("/", [&]() { + digitalWrite(led, 1); + server.send(200, "text/plain", "Hi!, This route is accessible for STA clients only"); + digitalWrite(led, 0); + }) + .setFilter(ON_STA_FILTER); + + // This route will be accessible by AP clients only + server.on("/", [&]() { + digitalWrite(led, 1); + server.send(200, "text/plain", "Hi!, This route is accessible for AP clients only"); + digitalWrite(led, 0); + }) + .setFilter(ON_AP_FILTER); + + server.on("/inline", []() { + server.send(200, "text/plain", "this works as well"); + }); + + server.onNotFound(handleNotFound); + + server.begin(); + Serial.println("HTTP server started"); +} + +void loop(void) { + server.handleClient(); +} diff --git a/libraries/ESP8266WebServer/examples/Graph/Graph.ino b/libraries/ESP8266WebServer/examples/Graph/Graph.ino index 0d6f724bae..224eccf0fb 100644 --- a/libraries/ESP8266WebServer/examples/Graph/Graph.ino +++ b/libraries/ESP8266WebServer/examples/Graph/Graph.ino @@ -24,9 +24,9 @@ // Select the FileSystem by uncommenting one of the lines below -//#define USE_SPIFFS +// #define USE_SPIFFS #define USE_LITTLEFS -//#define USE_SDFS +// #define USE_SDFS //////////////////////////////// diff --git a/libraries/ESP8266WebServer/examples/WebServer/README.md b/libraries/ESP8266WebServer/examples/WebServer/README.md index 68999100ab..0c7b1143da 100644 --- a/libraries/ESP8266WebServer/examples/WebServer/README.md +++ b/libraries/ESP8266WebServer/examples/WebServer/README.md @@ -21,8 +21,6 @@ It features * Only files in the root folder are supported for simplicity - no directories. - - ## Implementing a web server The ESP8266WebServer library offers a simple path to implement a web server on a ESP8266 board. @@ -90,7 +88,7 @@ that actually has only one line of functionality by sending a string as result t > }); > ``` -Here the text from a static String with html code is returned instead of a file from the filesystem. +Here the text from a static string with html code is returned instead of a file from the filesystem. The content of this string can be found in the file `builtinfiles.h`. It contains a small html+javascript implementation that allows uploading new files into the empty filesystem. @@ -100,14 +98,14 @@ Just open and drag some files from the data folde ## Registering a function to handle requests to the server without a path Often servers are addressed by using the base URL like where no further path details is given. -Of course we like the user to be redirected to something usable. Therefore the `handleRoot()` function is registered: +Of course we like the user to be redirected to something usable. Therefore the `handleRedirect()` function is registered: > ```CPP -> server.on("/$upload.htm", handleRoot); +> server.on("/", HTTP_GET, handleRedirect); > ``` -The `handleRoot()` function checks the filesystem for the file named **/index.htm** and creates a redirect to this file when the file exists. -Otherwise the redirection goes to the built-in **/$upload.htm** web page. +The `handleRedirect()` function checks the filesystem for the file named **/index.htm** and creates a redirect +response to this file when the file exists. Otherwise the redirection goes to the built-in **/$upload.htm** web page. @@ -122,7 +120,7 @@ The **serveStatic** plug in is part of the library and handles delivering files > ``` -### Cross-Origin Ressource Sharing (CORS) +### Cross-Origin Resource Sharing (CORS) The `enableCORS(true)` function adds a `Access-Control-Allow-Origin: *` http-header to all responses to the client to inform that it is allowed to call URLs and services on this server from other web sites. diff --git a/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino b/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino index 81a58478f9..9e88e96f1f 100644 --- a/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino +++ b/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino @@ -41,10 +41,9 @@ void handleRedirect() { TRACE("Redirect..."); String url = "/index.htm"; - if (!LittleFS.exists(url)) { url = "/$update.htm"; } + if (!LittleFS.exists(url)) { url = "/$upload.htm"; } - server.sendHeader("Location", url, true); - server.send(302); + server.redirect(url); } // handleRedirect() @@ -105,7 +104,7 @@ public: // @brief check incoming request. Can handle POST for uploads and DELETE. // @param requestMethod method of the http request line. - // @param requestUri request ressource from the http request line. + // @param requestUri request resource from the http request line. // @return true when method can be handled. bool canHandle(HTTPMethod requestMethod, const String UNUSED &_uri) override { return ((requestMethod == HTTP_POST) || (requestMethod == HTTP_DELETE)); @@ -154,7 +153,7 @@ public: // Close the file if (_fsUploadFile) { _fsUploadFile.close(); } } // if - } // upload() + } // upload() protected: File _fsUploadFile; diff --git a/libraries/ESP8266WebServer/examples/WebServer/builtinfiles.h b/libraries/ESP8266WebServer/examples/WebServer/builtinfiles.h index 210b18c1a5..2daf9e3819 100644 --- a/libraries/ESP8266WebServer/examples/WebServer/builtinfiles.h +++ b/libraries/ESP8266WebServer/examples/WebServer/builtinfiles.h @@ -54,10 +54,10 @@ R"==( static const char notFoundContent[] PROGMEM = R"==( - Ressource not found + Resource not found -

The ressource was not found.

+

The resource was not found.

Start again

)=="; diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index 817d323cbf..dbcb251135 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -230,18 +230,61 @@ void ESP8266WebServerTemplate::requestAuthentication(HTTPAuthMethod } template -void ESP8266WebServerTemplate::on(const Uri &uri, ESP8266WebServerTemplate::THandlerFunction handler) { - on(uri, HTTP_ANY, handler); +RequestHandler& ESP8266WebServerTemplate::on(const Uri &uri, ESP8266WebServerTemplate::THandlerFunction handler) { + return on(uri, HTTP_ANY, handler); } template -void ESP8266WebServerTemplate::on(const Uri &uri, HTTPMethod method, ESP8266WebServerTemplate::THandlerFunction fn) { - on(uri, method, fn, _fileUploadHandler); +RequestHandler& ESP8266WebServerTemplate::on(const Uri &uri, HTTPMethod method, ESP8266WebServerTemplate::THandlerFunction fn) { + return on(uri, method, fn, _fileUploadHandler); } template -void ESP8266WebServerTemplate::on(const Uri &uri, HTTPMethod method, ESP8266WebServerTemplate::THandlerFunction fn, ESP8266WebServerTemplate::THandlerFunction ufn) { - _addRequestHandler(new FunctionRequestHandler(fn, ufn, uri, method)); +RequestHandler& ESP8266WebServerTemplate::on(const Uri &uri, HTTPMethod method, ESP8266WebServerTemplate::THandlerFunction fn, ESP8266WebServerTemplate::THandlerFunction ufn) { + RequestHandler *handler = new FunctionRequestHandler(fn, ufn, uri, method); + _addRequestHandler(handler); + return *handler; +} + +template +bool ESP8266WebServerTemplate::removeRoute(const char *uri) { + return removeRoute(String(uri), HTTP_ANY); +} + +template +bool ESP8266WebServerTemplate::removeRoute(const char *uri, HTTPMethod method) { + return removeRoute(String(uri), method); +} + +template +bool ESP8266WebServerTemplate::removeRoute(const String &uri) { + return removeRoute(uri, HTTP_ANY); +} + +template +bool ESP8266WebServerTemplate::removeRoute(const String &uri, HTTPMethod method) { + bool anyHandlerRemoved = false; + RequestHandlerType *handler = _firstHandler; + RequestHandlerType *previousHandler = nullptr; + + while (handler) { + if (handler->canHandle(method, uri)) { + if (_removeRequestHandler(handler)) { + anyHandlerRemoved = true; + // Move to the next handler + if (previousHandler) { + handler = previousHandler->next(); + } else { + handler = _firstHandler; + } + continue; + } + } + previousHandler = handler; + handler = handler->next(); + } + + return anyHandlerRemoved; } template @@ -249,6 +292,11 @@ void ESP8266WebServerTemplate::addHandler(RequestHandlerType* handle _addRequestHandler(handler); } +template +bool ESP8266WebServerTemplate::removeHandler(RequestHandlerType *handler) { + return _removeRequestHandler(handler); +} + template void ESP8266WebServerTemplate::_addRequestHandler(RequestHandlerType* handler) { if (!_lastHandler) { @@ -261,6 +309,33 @@ void ESP8266WebServerTemplate::_addRequestHandler(RequestHandlerType } } +template +bool ESP8266WebServerTemplate::_removeRequestHandler(RequestHandlerType *handler) { + RequestHandlerType *current = _firstHandler; + RequestHandlerType *previous = nullptr; + + while (current != nullptr) { + if (current == handler) { + if (previous == nullptr) { + _firstHandler = current->next(); + } else { + previous->next(current->next()); + } + + if (current == _lastHandler) { + _lastHandler = previous; + } + + // Delete 'matching' handler + delete current; + return true; + } + previous = current; + current = current->next(); + } + return false; +} + template void ESP8266WebServerTemplate::serveStatic(const char* uri, FS& fs, const char* path, const char* cache_header) { bool is_file = false; @@ -590,10 +665,6 @@ const String& ESP8266WebServerTemplate::pathArg(unsigned int i) cons template const String& ESP8266WebServerTemplate::arg(const String& name) const { - for (int j = 0; j < _postArgsLen; ++j) { - if ( _postArgs[j].key == name ) - return _postArgs[j].value; - } for (int i = 0; i < _currentArgCount + _currentArgsHavePlain; ++i) { if ( _currentArgs[i].key == name ) return _currentArgs[i].value; @@ -622,10 +693,6 @@ int ESP8266WebServerTemplate::args() const { template bool ESP8266WebServerTemplate::hasArg(const String& name) const { - for (int j = 0; j < _postArgsLen; ++j) { - if (_postArgs[j].key == name) - return true; - } for (int i = 0; i < _currentArgCount + _currentArgsHavePlain; ++i) { if (_currentArgs[i].key == name) return true; @@ -734,9 +801,11 @@ void ESP8266WebServerTemplate::_handleRequest() { _finalizeResponse(); } _currentUri = ""; + delete[] _currentArgs; + _currentArgs = nullptr; + _currentArgCount = 0; } - template void ESP8266WebServerTemplate::_finalizeResponse() { if (_chunked) { diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index e0dba27a90..f9eca1c8bc 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -116,11 +116,17 @@ class ESP8266WebServerTemplate typedef std::function THandlerFunction; typedef std::function ETagFunction; - - void on(const Uri &uri, THandlerFunction handler); - void on(const Uri &uri, HTTPMethod method, THandlerFunction fn); - void on(const Uri &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn); + typedef std::function &server)> FilterFunction; + + RequestHandler& on(const Uri &uri, THandlerFunction handler); + RequestHandler& on(const Uri &uri, HTTPMethod method, THandlerFunction fn); + RequestHandler& on(const Uri &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn); + bool removeRoute(const char *uri); + bool removeRoute(const char *uri, HTTPMethod method); + bool removeRoute(const String &uri); + bool removeRoute(const String &uri, HTTPMethod method); void addHandler(RequestHandlerType* handler); + bool removeHandler(RequestHandlerType* handler); void serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_header = NULL ); void onNotFound(THandlerFunction fn); //called when handler is not assigned void onFileUpload(THandlerFunction fn); //handle file uploads @@ -207,6 +213,30 @@ class ESP8266WebServerTemplate sendContent(emptyString); } + /** + * @brief Redirect to another URL, e.g. + * webserver.on("/index.html", HTTP_GET, []() { webserver.redirect("/"); }); + * There are 3 points of redirection here: + * 1) "Location" element in the header + * 2) Disable client caching + * 3) HTML "content" element to redirect + * If the "Location" header element works the HTML content is never seen. + * https://tools.ietf.org/html/rfc7231#section-6.4.3 + * @param url URL to redirect to + * @param content Optional redirect content + */ + void redirect(const String& url, const String& content = emptyString) { + sendHeader(F("Location"), url, true); + sendHeader(F("Cache-Control"), F("no-cache, no-store, must-revalidate")); + sendHeader(F("Pragma"), F("no-cache")); + sendHeader(F("Expires"), F("-1")); + send(302, F("text/html"), content); // send 302: "Found" + if (content.isEmpty()) { + // Empty content inhibits Content-length header so we have to close the socket ourselves. + client().stop(); // Stop is needed because we sent no content length + } + } + // Whether other requests should be accepted from the client on the // same socket after a response is sent. // This will automatically configure the "Connection" header of the response. @@ -282,6 +312,7 @@ class ESP8266WebServerTemplate protected: void _addRequestHandler(RequestHandlerType* handler); + bool _removeRequestHandler(RequestHandlerType *handler); void _handleRequest(); void _finalizeResponse(); ClientFuture _parseRequest(ClientType& client); @@ -323,8 +354,6 @@ class ESP8266WebServerTemplate RequestArgument* _currentArgs = nullptr; int _currentArgsHavePlain = 0; std::unique_ptr _currentUpload; - int _postArgsLen = 0; - RequestArgument* _postArgs = nullptr; int _headerKeysCount = 0; RequestArgument* _currentHeaders = nullptr; @@ -352,4 +381,4 @@ class ESP8266WebServerTemplate using ESP8266WebServer = esp8266webserver::ESP8266WebServerTemplate; using RequestHandler = esp8266webserver::RequestHandler; -#endif //ESP8266WEBSERVER_H \ No newline at end of file +#endif //ESP8266WEBSERVER_H diff --git a/libraries/ESP8266WebServer/src/Parsing-impl.h b/libraries/ESP8266WebServer/src/Parsing-impl.h index 83762a03c2..672682706e 100644 --- a/libraries/ESP8266WebServer/src/Parsing-impl.h +++ b/libraries/ESP8266WebServer/src/Parsing-impl.h @@ -106,7 +106,7 @@ typename ESP8266WebServerTemplate::ClientFuture ESP8266WebServerTemp //attach handler RequestHandlerType* handler; for (handler = _firstHandler; handler; handler = handler->next()) { - if (handler->canHandle(_currentMethod, _currentUri)) + if (handler->canHandle(*this, _currentMethod, _currentUri)) break; } _currentHandler = handler; @@ -324,7 +324,7 @@ int ESP8266WebServerTemplate::_parseArgumentsPrivate(const String& d template void ESP8266WebServerTemplate::_uploadWriteByte(uint8_t b){ if (_currentUpload->currentSize == HTTP_UPLOAD_BUFLEN){ - if(_currentHandler && _currentHandler->canUpload(_currentUri)) + if(_currentHandler && _currentHandler->canUpload(*this, _currentUri)) _currentHandler->upload(*this, _currentUri, *_currentUpload); _currentUpload->totalSize += _currentUpload->currentSize; _currentUpload->currentSize = 0; @@ -358,9 +358,8 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const client.readStringUntil('\n'); //start reading the form if (line == ("--"+boundary)){ - if(_postArgs) delete[] _postArgs; - _postArgs = new RequestArgument[WEBSERVER_MAX_POST_ARGS]; - _postArgsLen = 0; + std::unique_ptr postArgs(new RequestArgument[WEBSERVER_MAX_POST_ARGS]); + int postArgsLen = 0; while(1){ String argName; String argValue; @@ -408,7 +407,7 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const } DBGWS("PostArg Value: %s\n\n", argValue.c_str()); - RequestArgument& arg = _postArgs[_postArgsLen++]; + RequestArgument& arg = postArgs[postArgsLen++]; arg.key = argName; arg.value = argValue; @@ -426,7 +425,7 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const _currentUpload->currentSize = 0; _currentUpload->contentLength = len; DBGWS("Start File: %s Type: %s\n", _currentUpload->filename.c_str(), _currentUpload->type.c_str()); - if(_currentHandler && _currentHandler->canUpload(_currentUri)) + if(_currentHandler && _currentHandler->canUpload(*this, _currentUri)) _currentHandler->upload(*this, _currentUri, *_currentUpload); _currentUpload->status = UPLOAD_FILE_WRITE; @@ -464,11 +463,11 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const } } // Found the boundary string, finish processing this file upload - if (_currentHandler && _currentHandler->canUpload(_currentUri)) + if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) _currentHandler->upload(*this, _currentUri, *_currentUpload); _currentUpload->totalSize += _currentUpload->currentSize; _currentUpload->status = UPLOAD_FILE_END; - if (_currentHandler && _currentHandler->canUpload(_currentUri)) + if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) _currentHandler->upload(*this, _currentUri, *_currentUpload); DBGWS("End File: %s Type: %s Size: %d\n", _currentUpload->filename.c_str(), @@ -488,25 +487,20 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const } int iarg; - int totalArgs = ((WEBSERVER_MAX_POST_ARGS - _postArgsLen) < _currentArgCount)?(WEBSERVER_MAX_POST_ARGS - _postArgsLen):_currentArgCount; + int totalArgs = ((WEBSERVER_MAX_POST_ARGS - postArgsLen) < _currentArgCount)?(WEBSERVER_MAX_POST_ARGS - postArgsLen):_currentArgCount; for (iarg = 0; iarg < totalArgs; iarg++){ - RequestArgument& arg = _postArgs[_postArgsLen++]; + RequestArgument& arg = postArgs[postArgsLen++]; arg.key = _currentArgs[iarg].key; arg.value = _currentArgs[iarg].value; } - if (_currentArgs) delete[] _currentArgs; - _currentArgs = new RequestArgument[_postArgsLen]; - for (iarg = 0; iarg < _postArgsLen; iarg++){ + delete[] _currentArgs; + _currentArgs = new RequestArgument[postArgsLen]; + for (iarg = 0; iarg < postArgsLen; iarg++){ RequestArgument& arg = _currentArgs[iarg]; - arg.key = _postArgs[iarg].key; - arg.value = _postArgs[iarg].value; + arg.key = postArgs[iarg].key; + arg.value = postArgs[iarg].value; } _currentArgCount = iarg; - if (_postArgs) { - delete[] _postArgs; - _postArgs = nullptr; - _postArgsLen = 0; - } return true; } DBGWS("Error: line: %s\n", line.c_str()); @@ -548,7 +542,7 @@ String ESP8266WebServerTemplate::urlDecode(const String& text) template bool ESP8266WebServerTemplate::_parseFormUploadAborted(){ _currentUpload->status = UPLOAD_FILE_ABORTED; - if(_currentHandler && _currentHandler->canUpload(_currentUri)) + if(_currentHandler && _currentHandler->canUpload(*this, _currentUri)) _currentHandler->upload(*this, _currentUri, *_currentUpload); return false; } diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandler.h b/libraries/ESP8266WebServer/src/detail/RequestHandler.h index 4195f0ff3f..c373c58f1b 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandler.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandler.h @@ -12,13 +12,60 @@ class RequestHandler { using WebServerType = ESP8266WebServerTemplate; public: virtual ~RequestHandler() { } - virtual bool canHandle(HTTPMethod method, const String& uri) { (void) method; (void) uri; return false; } - virtual bool canUpload(const String& uri) { (void) uri; return false; } - virtual bool handle(WebServerType& server, HTTPMethod requestMethod, const String& requestUri) { (void) server; (void) requestMethod; (void) requestUri; return false; } - virtual void upload(WebServerType& server, const String& requestUri, HTTPUpload& upload) { (void) server; (void) requestUri; (void) upload; } - RequestHandler* next() { return _next; } - void next(RequestHandler* r) { _next = r; } + /* + note: old handler API for backward compatibility + */ + + virtual bool canHandle(HTTPMethod method, const String& uri) { + (void) method; + (void) uri; + return false; + } + virtual bool canUpload(const String& uri) { + (void) uri; + return false; + } + + /* + note: new handler API with support for filters etc. + */ + + virtual bool canHandle(WebServerType& server, HTTPMethod method, const String& uri) { + (void) server; + (void) method; + (void) uri; + return false; + } + virtual bool canUpload(WebServerType& server, const String& uri) { + (void) server; + (void) uri; + return false; + } + virtual bool handle(WebServerType& server, HTTPMethod requestMethod, const String& requestUri) { + (void) server; + (void) requestMethod; + (void) requestUri; + return false; + } + virtual void upload(WebServerType& server, const String& requestUri, HTTPUpload& upload) { + (void) server; + (void) requestUri; + (void) upload; + } + + RequestHandler* next() { + return _next; + } + + void next(RequestHandler* r) { + _next = r; + } + + virtual RequestHandler& setFilter(std::function&)> filter) { + (void)filter; + return *this; + } private: RequestHandler* _next = nullptr; diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h index bb06033dea..fb36c5aba4 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h @@ -59,9 +59,22 @@ class FunctionRequestHandler : public RequestHandler { return true; } + bool canHandle(WebServerType& server, HTTPMethod requestMethod, const String& requestUri) override { + if (_method != HTTP_ANY && _method != requestMethod) + return false; + + return _uri->canHandle(requestUri, RequestHandler::pathArgs) && (_filter != NULL ? _filter(server) : true); + } + + bool canUpload(WebServerType& server, const String& requestUri) override { + if (!_ufn || !canHandle(server, HTTP_POST, requestUri)) + return false; + + return true; + } + bool handle(WebServerType& server, HTTPMethod requestMethod, const String& requestUri) override { - (void) server; - if (!canHandle(requestMethod, requestUri)) + if (!canHandle(server, requestMethod, requestUri)) return false; _fn(); @@ -69,15 +82,22 @@ class FunctionRequestHandler : public RequestHandler { } void upload(WebServerType& server, const String& requestUri, HTTPUpload& upload) override { - (void) server; (void) upload; - if (canUpload(requestUri)) + if (canUpload(server, requestUri)) _ufn(); } + FunctionRequestHandler& setFilter(typename WebServerType::FilterFunction filter) { + _filter = filter; + return *this; + } + protected: typename WebServerType::THandlerFunction _fn; typename WebServerType::THandlerFunction _ufn; + // _filter should return 'true' when the request should be handled + // and 'false' when the request should be ignored + typename WebServerType::FilterFunction _filter; Uri *_uri; HTTPMethod _method; }; @@ -115,7 +135,6 @@ class StaticRequestHandler : public RequestHandler { // serve all files within a given directory template class StaticDirectoryRequestHandler : public StaticRequestHandler { - using SRH = StaticRequestHandler; using WebServerType = ESP8266WebServerTemplate; @@ -130,9 +149,12 @@ class StaticDirectoryRequestHandler : public StaticRequestHandler { return SRH::validMethod(requestMethod) && requestUri.startsWith(SRH::_uri); } - bool handle(WebServerType& server, HTTPMethod requestMethod, const String& requestUri) override { + bool canHandle(WebServerType& server, HTTPMethod requestMethod, const String& requestUri) override { + return SRH::validMethod(requestMethod) && requestUri.startsWith(SRH::_uri) && (_filter != NULL ? _filter(server) : true); + } - if (!canHandle(requestMethod, requestUri)) + bool handle(WebServerType& server, HTTPMethod requestMethod, const String& requestUri) override { + if (!canHandle(server, requestMethod, requestUri)) return false; DEBUGV("DirectoryRequestHandler::handle: request=%s _uri=%s\r\n", requestUri.c_str(), SRH::_uri.c_str()); @@ -203,8 +225,14 @@ class StaticDirectoryRequestHandler : public StaticRequestHandler { return true; } + StaticDirectoryRequestHandler& setFilter(typename WebServerType::FilterFunction filter) { + _filter = filter; + return *this; + } + protected: size_t _baseUriLength; + typename WebServerType::FilterFunction _filter; }; @@ -228,8 +256,12 @@ public StaticRequestHandler { return SRH::validMethod(requestMethod) && requestUri == SRH::_uri; } + bool canHandle(WebServerType& server, HTTPMethod requestMethod, const String& requestUri) override { + return SRH::validMethod(requestMethod) && requestUri == SRH::_uri && (_filter != NULL ? _filter(server) : true); + } + bool handle(WebServerType& server, HTTPMethod requestMethod, const String & requestUri) override { - if (!canHandle(requestMethod, requestUri)) + if (!canHandle(server, requestMethod, requestUri)) return false; if (server._eTagEnabled) { @@ -266,8 +298,14 @@ public StaticRequestHandler { return true; } + StaticFileRequestHandler& setFilter(typename WebServerType::FilterFunction filter) { + _filter = filter; + return *this; + } + protected: String _eTagCode; // ETag code calculated for this file as used in http header include quotes. + typename WebServerType::FilterFunction _filter; }; } // namespace diff --git a/libraries/ESP8266WebServer/src/uri/UriRegex.h b/libraries/ESP8266WebServer/src/uri/UriRegex.h index eef1b516d4..e29eeb5cd6 100644 --- a/libraries/ESP8266WebServer/src/uri/UriRegex.h +++ b/libraries/ESP8266WebServer/src/uri/UriRegex.h @@ -2,8 +2,9 @@ #define URI_REGEX_H #include "Uri.h" + +#include #include -#include #ifndef REGEX_MAX_GROUPS #define REGEX_MAX_GROUPS 10 @@ -12,13 +13,20 @@ class UriRegex : public Uri { private: - regex_t _regexCompiled; + regex_t _regexCompiled{}; + int _regexErr{REG_EMPTY}; public: - explicit UriRegex(const char *uri) : Uri(uri) { - assert(regcomp(&_regexCompiled, uri, REG_EXTENDED) == 0); - }; - explicit UriRegex(const String &uri) : UriRegex(uri.c_str()) {}; + UriRegex() = delete; + + explicit UriRegex(const char *uri) : + Uri(uri), + _regexErr(regcomp(&_regexCompiled, uri, REG_EXTENDED)) + { + assert(_regexErr == 0); + } + + explicit UriRegex(const String &uri) : UriRegex(uri.c_str()) {} ~UriRegex() { regfree(&_regexCompiled); @@ -26,15 +34,17 @@ class UriRegex : public Uri { Uri* clone() const override final { return new UriRegex(_uri); - }; + } bool canHandle(const String &requestUri, std::vector &pathArgs) override final { if (Uri::canHandle(requestUri, pathArgs)) return true; + if (_regexErr != 0) + return false; + regmatch_t groupArray[REGEX_MAX_GROUPS]; if (regexec(&_regexCompiled, requestUri.c_str(), REGEX_MAX_GROUPS, groupArray, 0) == 0) { - // matches pathArgs.clear(); unsigned int g = 1; diff --git a/libraries/ESP8266WiFi/examples/BearSSL_Server/BearSSL_Server.ino b/libraries/ESP8266WiFi/examples/BearSSL_Server/BearSSL_Server.ino index 5795a7362c..598a0adc77 100644 --- a/libraries/ESP8266WiFi/examples/BearSSL_Server/BearSSL_Server.ino +++ b/libraries/ESP8266WiFi/examples/BearSSL_Server/BearSSL_Server.ino @@ -48,7 +48,7 @@ const char *pass = STAPSK; // The HTTPS server BearSSL::WiFiServerSecure server(443); -//#define USE_EC // Enable Elliptic Curve signed cert +// #define USE_EC // Enable Elliptic Curve signed cert #define USING_INSECURE_CERTS_AND_KEYS_AND_CAS 1 #include @@ -58,7 +58,7 @@ BearSSL::WiFiServerSecure server(443); // Caching SSL sessions shortens the length of the SSL handshake. // You can see the performance improvement by looking at the // Network tab of the developer tools of your browser. -//#define DYNAMIC_CACHE // Whether to dynamically allocate the cache. +// #define DYNAMIC_CACHE // Whether to dynamically allocate the cache. #if defined(USE_CACHE) && defined(DYNAMIC_CACHE) // Dynamically allocated cache. diff --git a/libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino b/libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino index cc76e5d24e..2f6c08a51a 100644 --- a/libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino +++ b/libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino @@ -12,7 +12,7 @@ #define FINGERPRINT fingerprint_www_example_org #define PUBKEY pubkey_www_example_org -#define CERT cert_DigiCert_TLS_RSA_SHA256_2020_CA1 +#define CERT cert_DigiCert_Global_G2_TLS_RSA_SHA256_2020_CA1 #ifndef STASSID #define STASSID "your-ssid" diff --git a/libraries/ESP8266WiFi/examples/BearSSL_Validation/certs.h b/libraries/ESP8266WiFi/examples/BearSSL_Validation/certs.h index 74f244c4eb..c6b99041a4 100644 --- a/libraries/ESP8266WiFi/examples/BearSSL_Validation/certs.h +++ b/libraries/ESP8266WiFi/examples/BearSSL_Validation/certs.h @@ -1,7 +1,7 @@ // this file is autogenerated - any modification will be overwritten // unused symbols will not be linked in the final binary -// generated on 2023-03-20 23:02:42 +// generated on 2024-07-30 23:28:11 // by ['../../../../tools/cert.py', '-s', 'www.example.com', '-n', 'SSL'] #pragma once @@ -13,82 +13,82 @@ const char* SSL_host = "www.example.com"; const uint16_t SSL_port = 443; // CN: www.example.org => name: www_example_org -// not valid before: 2023-01-13 00:00:00 -// not valid after: 2024-02-13 23:59:59 -const char fingerprint_www_example_org [] PROGMEM = "f2:aa:d7:3d:32:68:3b:71:6d:2a:7d:61:b5:1c:6d:57:64:ab:38:99"; +// not valid before: 2024-01-30 00:00:00+00:00 +// not valid after: 2025-03-01 23:59:59+00:00 +const char fingerprint_www_example_org [] PROGMEM = "4d:a2:5a:6d:5e:f6:2c:5f:95:c7:bd:0a:73:ea:3c:17:7b:36:99:9d"; const char pubkey_www_example_org [] PROGMEM = R"PUBKEY( -----BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwoB3iVm4RW+6StkR+nut -x1fQevu2+t0Fu6KBcbvhfyHSXy7w0nJOdTT4jWLjStpRkNQBPZwMwHH35i+21gdn -JtDe/xfO8IX9McFmyodlBUcqX8CruIzDv9AXf2OjXPBG+4aq+03XKl5/muATl32+ -+301Vw1dXoGYNeoWQqLTsHT3WS3tOOf+ehuzNuZ+rj+ephaD3lMBToEArrtC9R91 -KTTN6YSAOK48NxTA8CfOMFK5itxfIqB5+E9OSQTidXyqLyoeA+xxTKMqYfxvypEe -k1oueAhY9u67NCBdmuavxtfyvwp7+o6Sd+NsewxAhmRKFexw13KOYzDhC+9aMJcu -JQIDAQAB +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhoUPuw75yl/Z9eAKMiwz +2aoOBymoLwiteL3CBr/3LSumpyc9U6ZMw0uyJ3cg1sFUSbgI2vlwqWH2skmdaVfa ++20kNHIuR/AEP52xW+K8ZjFZMuapfr/UsNRk9WvKe/9yW16a2D/UBrLzyNyPZlpG +hGaoGBV5pwjOBTz7OYnvbfpOcVJ7t+SgpJyWwGE9pApwTcOOzW6zMmzyx0QJBN2g +Vf0jpSB4soVe2DutF/+Fxbl0jTO5uFdutbxpZdsLPJJVmfRztGQkymdMKJnM3Gc9 +eccWnCvmq6qqNXI39oEqSOg/Thmav55GqjKT/6WyWrSxLx5phJIdsLmNr/IxbJWG +8wIDAQAB -----END PUBLIC KEY----- )PUBKEY"; -// http://cacerts.digicert.com/DigiCertTLSRSASHA2562020CA1-1.crt -// CN: DigiCert TLS RSA SHA256 2020 CA1 => name: DigiCert_TLS_RSA_SHA256_2020_CA1 -// not valid before: 2021-04-14 00:00:00 -// not valid after: 2031-04-13 23:59:59 -const char cert_DigiCert_TLS_RSA_SHA256_2020_CA1 [] PROGMEM = R"CERT( +// http://cacerts.digicert.com/DigiCertGlobalG2TLSRSASHA2562020CA1-1.crt +// CN: DigiCert Global G2 TLS RSA SHA256 2020 CA1 => name: DigiCert_Global_G2_TLS_RSA_SHA256_2020_CA1 +// not valid before: 2021-03-30 00:00:00+00:00 +// not valid after: 2031-03-29 23:59:59+00:00 +const char cert_DigiCert_Global_G2_TLS_RSA_SHA256_2020_CA1 [] PROGMEM = R"CERT( -----BEGIN CERTIFICATE----- -MIIEvjCCA6agAwIBAgIQBtjZBNVYQ0b2ii+nVCJ+xDANBgkqhkiG9w0BAQsFADBh +MIIEyDCCA7CgAwIBAgIQDPW9BitWAvR6uFAsI8zwZjANBgkqhkiG9w0BAQsFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0yMTA0MTQwMDAwMDBaFw0zMTA0MTMyMzU5NTlaME8xCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxKTAnBgNVBAMTIERpZ2lDZXJ0IFRMUyBS -U0EgU0hBMjU2IDIwMjAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAwUuzZUdwvN1PWNvsnO3DZuUfMRNUrUpmRh8sCuxkB+Uu3Ny5CiDt3+PE0J6a -qXodgojlEVbbHp9YwlHnLDQNLtKS4VbL8Xlfs7uHyiUDe5pSQWYQYE9XE0nw6Ddn -g9/n00tnTCJRpt8OmRDtV1F0JuJ9x8piLhMbfyOIJVNvwTRYAIuE//i+p1hJInuW -raKImxW8oHzf6VGo1bDtN+I2tIJLYrVJmuzHZ9bjPvXj1hJeRPG/cUJ9WIQDgLGB -Afr5yjK7tI4nhyfFK3TUqNaX3sNk+crOU6JWvHgXjkkDKa77SU+kFbnO8lwZV21r -eacroicgE7XQPUDTITAHk+qZ9QIDAQABo4IBgjCCAX4wEgYDVR0TAQH/BAgwBgEB -/wIBADAdBgNVHQ4EFgQUt2ui6qiqhIx56rTaD5iyxZV2ufQwHwYDVR0jBBgwFoAU -A95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQG -CCsGAQUFBwMBBggrBgEFBQcDAjB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGG -GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2Nh -Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNydDBCBgNV -HR8EOzA5MDegNaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRH -bG9iYWxSb290Q0EuY3JsMD0GA1UdIAQ2MDQwCwYJYIZIAYb9bAIBMAcGBWeBDAEB -MAgGBmeBDAECATAIBgZngQwBAgIwCAYGZ4EMAQIDMA0GCSqGSIb3DQEBCwUAA4IB -AQCAMs5eC91uWg0Kr+HWhMvAjvqFcO3aXbMM9yt1QP6FCvrzMXi3cEsaiVi6gL3z -ax3pfs8LulicWdSQ0/1s/dCYbbdxglvPbQtaCdB73sRD2Cqk3p5BJl+7j5nL3a7h -qG+fh/50tx8bIKuxT8b1Z11dmzzp/2n3YWzW2fP9NsarA4h20ksudYbj/NhVfSbC -EXffPgK2fPOre3qGNm+499iTcc+G33Mw+nur7SpZyEKEOxEXGlLzyQ4UfaJbcme6 -ce1XR2bFuAJKZTRei9AqPCCcUZlM51Ke92sRKw2Sfh3oius2FkOH6ipjv3U/697E -A7sKPPcw7+uvTPyLNhBzPvOk +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0yMTAzMzAwMDAwMDBaFw0zMTAzMjkyMzU5NTlaMFkxCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMzAxBgNVBAMTKkRpZ2lDZXJ0IEdsb2Jh +bCBHMiBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMz3EGJPprtjb+2QUlbFbSd7ehJWivH0+dbn4Y+9lavyYEEV +cNsSAPonCrVXOFt9slGTcZUOakGUWzUb+nv6u8W+JDD+Vu/E832X4xT1FE3LpxDy +FuqrIvAxIhFhaZAmunjZlx/jfWardUSVc8is/+9dCopZQ+GssjoP80j812s3wWPc +3kbW20X+fSP9kOhRBx5Ro1/tSUZUfyyIxfQTnJcVPAPooTncaQwywa8WV0yUR0J8 +osicfebUTVSvQpmowQTCd5zWSOTOEeAqgJnwQ3DPP3Zr0UxJqyRewg2C/Uaoq2yT +zGJSQnWS+Jr6Xl6ysGHlHx+5fwmY6D36g39HaaECAwEAAaOCAYIwggF+MBIGA1Ud +EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFHSFgMBmx9833s+9KTeqAx2+7c0XMB8G +A1UdIwQYMBaAFE4iVCAYlebjbuYP+vq5Eu0GF485MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYIKwYBBQUHAQEEajBoMCQG +CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQAYIKwYBBQUHMAKG +NGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RH +Mi5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29t +L0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDA9BgNVHSAENjA0MAsGCWCGSAGG/WwC +ATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgGBmeBDAECAzANBgkqhkiG +9w0BAQsFAAOCAQEAkPFwyyiXaZd8dP3A+iZ7U6utzWX9upwGnIrXWkOH7U1MVl+t +wcW1BSAuWdH/SvWgKtiwla3JLko716f2b4gp/DA/JIS7w7d7kwcsr4drdjPtAFVS +slme5LnQ89/nD/7d+MS5EHKBCQRfz5eeLjJ1js+aWNJXMX43AYGyZm0pGrFmCW3R +bpD0ufovARTFXFZkAdl9h6g4U5+LXUZtXMYnhIHUfoyMo5tS58aI7Dd8KvvwVVo4 +chDYABPPTHPbqjc1qCmBaZx2vN4Ye5DUys/vZwP9BFohFrH/6j/f3IL16/RZkiMN +JCqVJUzKoZHm1Lesh3Sz8W2jmdv51b2EQJ8HmA== -----END CERTIFICATE----- )CERT"; -// http://cacerts.digicert.com/DigiCertGlobalRootCA.crt -// CN: DigiCert Global Root CA => name: DigiCert_Global_Root_CA -// not valid before: 2006-11-10 00:00:00 -// not valid after: 2031-11-10 00:00:00 -const char cert_DigiCert_Global_Root_CA [] PROGMEM = R"CERT( +// http://cacerts.digicert.com/DigiCertGlobalRootG2.crt +// CN: DigiCert Global Root G2 => name: DigiCert_Global_Root_G2 +// not valid before: 2013-08-01 12:00:00+00:00 +// not valid after: 2038-01-15 12:00:00+00:00 +const char cert_DigiCert_Global_Root_G2 [] PROGMEM = R"CERT( -----BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB -CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 -nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt -43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P -T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 -gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR -TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw -DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr -hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg -06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF -PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls -YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= -----END CERTIFICATE----- )CERT"; diff --git a/libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino b/libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino index 696d513b52..750abfa733 100644 --- a/libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino +++ b/libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino @@ -13,6 +13,7 @@ #include #include + #include "certs.h" #ifndef STASSID @@ -23,7 +24,7 @@ const char* ssid = STASSID; const char* password = STAPSK; -X509List cert(cert_DigiCert_Global_Root_CA); +X509List cert(cert_Sectigo_ECC_Domain_Validation_Secure_Server_CA); void setup() { Serial.begin(115200); @@ -62,7 +63,7 @@ void setup() { Serial.print("Connecting to "); Serial.println(github_host); - Serial.printf("Using certificate: %s\n", cert_DigiCert_Global_Root_CA); + Serial.printf("Using certificate: %s\n", cert_Sectigo_ECC_Domain_Validation_Secure_Server_CA); client.setTrustAnchors(&cert); if (!client.connect(github_host, github_port)) { diff --git a/libraries/ESP8266WiFi/examples/HTTPSRequest/certs.h b/libraries/ESP8266WiFi/examples/HTTPSRequest/certs.h index f59ae673b3..97012d7a59 100644 --- a/libraries/ESP8266WiFi/examples/HTTPSRequest/certs.h +++ b/libraries/ESP8266WiFi/examples/HTTPSRequest/certs.h @@ -1,7 +1,7 @@ // this file is autogenerated - any modification will be overwritten // unused symbols will not be linked in the final binary -// generated on 2023-03-20 23:02:43 +// generated on 2024-07-30 23:28:12 // by ['../../../../tools/cert.py', '-s', 'api.github.com', '-n', 'github'] #pragma once @@ -13,73 +13,72 @@ const char* github_host = "api.github.com"; const uint16_t github_port = 443; // CN: *.github.com => name: __github_com -// not valid before: 2023-02-16 00:00:00 -// not valid after: 2024-03-15 23:59:59 -const char fingerprint___github_com [] PROGMEM = "2d:79:6c:90:2d:ad:8a:2e:4f:d1:e2:99:ed:e8:91:29:36:40:f8:58"; +// not valid before: 2024-03-07 00:00:00+00:00 +// not valid after: 2025-03-07 23:59:59+00:00 +const char fingerprint___github_com [] PROGMEM = "0d:f6:ec:50:fa:ed:ae:6e:13:af:82:94:52:f7:11:1b:0a:cf:7c:20"; const char pubkey___github_com [] PROGMEM = R"PUBKEY( -----BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVB9Da7ntQj93REi9YoUrTvO/wrkz -xLleXrDjJGe1OI3tsrk+cWbZYAbwL6unbhZsAqbyBcr5BHK5M3vxZVSGRg== +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcAMYSUSbAQpBM6MJN5kRD5gVpxvK +QgpD4jQ4jY1CqNOeWP7fOkn+PxdiJq76Qv5bPmv3tTxD6plhoNDYDohvMg== -----END PUBLIC KEY----- )PUBKEY"; -// http://cacerts.digicert.com/DigiCertTLSHybridECCSHA3842020CA1-1.crt -// CN: DigiCert TLS Hybrid ECC SHA384 2020 CA1 => name: DigiCert_TLS_Hybrid_ECC_SHA384_2020_CA1 -// not valid before: 2021-04-14 00:00:00 -// not valid after: 2031-04-13 23:59:59 -const char cert_DigiCert_TLS_Hybrid_ECC_SHA384_2020_CA1 [] PROGMEM = R"CERT( +// http://crt.sectigo.com/SectigoECCDomainValidationSecureServerCA.crt +// CN: Sectigo ECC Domain Validation Secure Server CA => name: Sectigo_ECC_Domain_Validation_Secure_Server_CA +// not valid before: 2018-11-02 00:00:00+00:00 +// not valid after: 2030-12-31 23:59:59+00:00 +const char cert_Sectigo_ECC_Domain_Validation_Secure_Server_CA [] PROGMEM = R"CERT( -----BEGIN CERTIFICATE----- -MIIEFzCCAv+gAwIBAgIQB/LzXIeod6967+lHmTUlvTANBgkqhkiG9w0BAQwFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0yMTA0MTQwMDAwMDBaFw0zMTA0MTMyMzU5NTlaMFYxCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMDAuBgNVBAMTJ0RpZ2lDZXJ0IFRMUyBI -eWJyaWQgRUNDIFNIQTM4NCAyMDIwIENBMTB2MBAGByqGSM49AgEGBSuBBAAiA2IA -BMEbxppbmNmkKaDp1AS12+umsmxVwP/tmMZJLwYnUcu/cMEFesOxnYeJuq20ExfJ -qLSDyLiQ0cx0NTY8g3KwtdD3ImnI8YDEe0CPz2iHJlw5ifFNkU3aiYvkA8ND5b8v -c6OCAYIwggF+MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAq8CCkXjKU5 -bXoOzjPHLrPt+8N6MB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA4G -A1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYI -KwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j -b20wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp -Q2VydEdsb2JhbFJvb3RDQS5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2Ny -bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA9BgNVHSAE -NjA0MAsGCWCGSAGG/WwCATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgG -BmeBDAECAzANBgkqhkiG9w0BAQwFAAOCAQEAR1mBf9QbH7Bx9phdGLqYR5iwfnYr -6v8ai6wms0KNMeZK6BnQ79oU59cUkqGS8qcuLa/7Hfb7U7CKP/zYFgrpsC62pQsY -kDUmotr2qLcy/JUjS8ZFucTP5Hzu5sn4kL1y45nDHQsFfGqXbbKrAjbYwrwsAZI/ -BKOLdRHHuSm8EdCGupK8JvllyDfNJvaGEwwEqonleLHBTnm8dqMLUeTF0J5q/hos -Vq4GNiejcxwIfZMy0MJEGdqN9A57HSgDKwmKdsp33Id6rHtSJlWncg+d0ohP/rEh -xRqhqjn1VtvChMQ1H3Dau0bwhr9kAMQ+959GG50jBbl9s08PqUU643QwmA== +MIIDqDCCAy6gAwIBAgIRAPNkTmtuAFAjfglGvXvh9R0wCgYIKoZIzj0EAwMwgYgx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJz +ZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQD +EyVVU0VSVHJ1c3QgRUNDIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MTEw +MjAwMDAwMFoXDTMwMTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAkdCMRswGQYDVQQI +ExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoT +D1NlY3RpZ28gTGltaXRlZDE3MDUGA1UEAxMuU2VjdGlnbyBFQ0MgRG9tYWluIFZh +bGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEH +A0IABHkYk8qfbZ5sVwAjBTcLXw9YWsTef1Wj6R7W2SUKiKAgSh16TwUwimNJE4xk +IQeV/To14UrOkPAY9z2vaKb71EijggFuMIIBajAfBgNVHSMEGDAWgBQ64QmG1M8Z +wpZ2dEl23OA1xmNjmjAdBgNVHQ4EFgQU9oUKOxGG4QR9DqoLLNLuzGR7e64wDgYD +VR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0lBBYwFAYIKwYB +BQUHAwEGCCsGAQUFBwMCMBsGA1UdIAQUMBIwBgYEVR0gADAIBgZngQwBAgEwUAYD +VR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJUcnVz +dEVDQ0NlcnRpZmljYXRpb25BdXRob3JpdHkuY3JsMHYGCCsGAQUFBwEBBGowaDA/ +BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdEVD +Q0FkZFRydXN0Q0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1 +c3QuY29tMAoGCCqGSM49BAMDA2gAMGUCMEvnx3FcsVwJbZpCYF9z6fDWJtS1UVRs +cS0chWBNKPFNpvDKdrdKRe+oAkr2jU+ubgIxAODheSr2XhcA7oz9HmedGdMhlrd9 +4ToKFbZl+/OnFFzqnvOhcjHvClECEQcKmc8fmA== -----END CERTIFICATE----- )CERT"; -// http://cacerts.digicert.com/DigiCertGlobalRootCA.crt -// CN: DigiCert Global Root CA => name: DigiCert_Global_Root_CA -// not valid before: 2006-11-10 00:00:00 -// not valid after: 2031-11-10 00:00:00 -const char cert_DigiCert_Global_Root_CA [] PROGMEM = R"CERT( +// http://crt.usertrust.com/USERTrustECCAddTrustCA.crt +// CN: USERTrust ECC Certification Authority => name: USERTrust_ECC_Certification_Authority +// not valid before: 2019-03-12 00:00:00+00:00 +// not valid after: 2028-12-31 23:59:59+00:00 +const char cert_USERTrust_ECC_Certification_Authority [] PROGMEM = R"CERT( -----BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB -CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 -nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt -43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P -T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 -gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR -TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw -DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr -hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg -06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF -PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls -YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +MIID0zCCArugAwIBAgIQVmcdBOpPmUxvEIFHWdJ1lDANBgkqhkiG9w0BAQwFADB7 +MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD +VQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UE +AwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4 +MTIzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5 +MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBO +ZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgRUNDIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEGqxUWqn5aCPnetUkb1PGWthL +q8bVttHmc3Gu3ZzWDGH926CJA7gFFOxXzu5dP+Ihs8731Ip54KODfi2X0GHE8Znc +JZFjq38wo7Rw4sehM5zzvy5cU7Ffs30yf4o043l5o4HyMIHvMB8GA1UdIwQYMBaA +FKARCiM+lvEH7OKvKe+CpX/QMKS0MB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1 +xmNjmjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zARBgNVHSAECjAI +MAYGBFUdIAAwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5j +b20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEEKDAmMCQG +CCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZIhvcNAQEM +BQADggEBABns652JLCALBIAdGN5CmXKZFjK9Dpx1WywV4ilAbe7/ctvbq5AfjJXy +ij0IckKJUAfiORVsAYfZFhr1wHUrxeZWEQff2Ji8fJ8ZOd+LygBkc7xGEJuTI42+ +FsMuCIKchjN0djsoTI0DQoWz4rIjQtUfenVqGtF8qmchxDM6OW1TyaLtYiKou+JV +bJlsQ2uRl9EMC5MCHdK8aXdJ5htN978UeAOwproLtOGFfy/cQjutdAFI3tZs4RmY +CV4Ks2dH/hzg1cEo70qLRDEmBDeNiXQ2Lu+lIg+DdEmSx/cQwgwp+7e9un/jX9Wf +8qn0dNW44bOwgeThpWOjzOoEeJBuv/c= -----END CERTIFICATE----- )CERT"; diff --git a/libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino b/libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino index dddfde9f5b..7d66553b61 100644 --- a/libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino +++ b/libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino @@ -24,6 +24,9 @@ const char* ssid = APSSID; const char* password = APPSK; +// WiFi.on* methods **must** only be called **after** entering setup(). +// Assigning immediately in global scope is not adviced, neither is assigning them within any other object constructors. +// These variables **may** exist in function block, but **only** if they are declared as `static` WiFiEventHandler stationConnectedHandler; WiFiEventHandler stationDisconnectedHandler; WiFiEventHandler probeRequestPrintHandler; @@ -43,12 +46,12 @@ void setup() { WiFi.mode(WIFI_AP); WiFi.softAP(ssid, password); - // Register event handlers. - // Callback functions will be called as long as these handler objects exist. // Call "onStationConnected" each time a station connects stationConnectedHandler = WiFi.onSoftAPModeStationConnected(&onStationConnected); + // Call "onStationDisconnected" each time a station disconnects stationDisconnectedHandler = WiFi.onSoftAPModeStationDisconnected(&onStationDisconnected); + // Call "onProbeRequestPrint" and "onProbeRequestBlink" each time // a probe request is received. // Former will print MAC address of the station and RSSI to Serial, diff --git a/libraries/ESP8266WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino b/libraries/ESP8266WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino index b31c552e35..15c0cd38bd 100644 --- a/libraries/ESP8266WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino +++ b/libraries/ESP8266WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino @@ -29,7 +29,7 @@ /* SWAP_PINS: - 0: use Serial1 for logging (legacy example) + 0: use Serial1 for logging 1: configure Hardware Serial port on RX:GPIO13 TX:GPIO15 and use EspSoftwareSerial for logging on standard Serial pins RX:GPIO3 and TX:GPIO1 @@ -90,6 +90,8 @@ void setup() { logger->enableIntTx(false); logger->println("\n\nUsing EspSoftwareSerial for logging"); #else + // Hardware serial0 is on RX(3)/TX(1) + // Hardware serial1 is on (no RX)/TX(2) logger->begin(BAUD_LOGGER); logger->println("\n\nUsing Serial1 for logging"); #endif diff --git a/libraries/ESP8266WiFi/src/ArduinoWiFiServer.h b/libraries/ESP8266WiFi/src/ArduinoWiFiServer.h index 21dec5f62c..45e5e59d6e 100644 --- a/libraries/ESP8266WiFi/src/ArduinoWiFiServer.h +++ b/libraries/ESP8266WiFi/src/ArduinoWiFiServer.h @@ -32,7 +32,7 @@ class ArduinoCompatibleWiFiServerTemplate : public TServer, public Print { public: ArduinoCompatibleWiFiServerTemplate(const IPAddress& addr, uint16_t port) : TServer(addr, port) {} - ArduinoCompatibleWiFiServerTemplate(uint16_t port) : TServer(port) {} + ArduinoCompatibleWiFiServerTemplate(uint16_t port = 23) : TServer(port) {} virtual ~ArduinoCompatibleWiFiServerTemplate() {} // https://www.arduino.cc/en/Reference/WiFiServerAvailable diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h index d0525176bd..e0ad560d0e 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h @@ -71,15 +71,15 @@ class ESP8266WiFiGenericClass { void onEvent(WiFiEventCb cb, WiFiEvent_t event = WIFI_EVENT_ANY) __attribute__((deprecated)); // Subscribe to specific event and get event information as an argument to the callback - WiFiEventHandler onStationModeConnected(std::function); - WiFiEventHandler onStationModeDisconnected(std::function); - WiFiEventHandler onStationModeAuthModeChanged(std::function); - WiFiEventHandler onStationModeGotIP(std::function); - WiFiEventHandler onStationModeDHCPTimeout(std::function); - WiFiEventHandler onSoftAPModeStationConnected(std::function); - WiFiEventHandler onSoftAPModeStationDisconnected(std::function); - WiFiEventHandler onSoftAPModeProbeRequestReceived(std::function); - WiFiEventHandler onWiFiModeChange(std::function); + [[nodiscard]] WiFiEventHandler onStationModeConnected(std::function); + [[nodiscard]] WiFiEventHandler onStationModeDisconnected(std::function); + [[nodiscard]] WiFiEventHandler onStationModeAuthModeChanged(std::function); + [[nodiscard]] WiFiEventHandler onStationModeGotIP(std::function); + [[nodiscard]] WiFiEventHandler onStationModeDHCPTimeout(std::function); + [[nodiscard]] WiFiEventHandler onSoftAPModeStationConnected(std::function); + [[nodiscard]] WiFiEventHandler onSoftAPModeStationDisconnected(std::function); + [[nodiscard]] WiFiEventHandler onSoftAPModeProbeRequestReceived(std::function); + [[nodiscard]] WiFiEventHandler onWiFiModeChange(std::function); uint8_t channel(void); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h index fab5829afd..3c77df02d4 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h @@ -69,7 +69,7 @@ class ESP8266WiFiMulti wl_status_t run(uint32_t connectTimeoutMs=WIFI_CONNECT_TIMEOUT_MS); void cleanAPlist(); - + int count() { return _APlist.size(); } private: WifiAPlist _APlist; bool _firstRun; diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index bfba96457d..dfea41298b 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -339,6 +339,45 @@ bool ESP8266WiFiSTAClass::config(IPAddress local_ip, IPAddress arg1, IPAddress a return true; } +bool ESP8266WiFiSTAClass::config(IPAddress local_ip, IPAddress dns) { + + if (!local_ip.isSet()) + return config(INADDR_ANY, INADDR_ANY, INADDR_ANY); + + if (!local_ip.isV4()) + return false; + + IPAddress gw(local_ip); + gw[3] = 1; + if (!dns.isSet()) { + dns = gw; + } + return config(local_ip, dns, gw); +} + +/** + * Change DNS for static IP configuration + * @param dns1 Static DNS server 1 + * @param dns2 Static DNS server 2 (optional) + */ +bool ESP8266WiFiSTAClass::setDNS(IPAddress dns1, IPAddress dns2) { + + if((WiFi.getMode() & WIFI_STA) == 0) + return false; + + if(dns1.isSet()) { + // Set DNS1-Server + dns_setserver(0, dns1); + } + + if(dns2.isSet()) { + // Set DNS2-Server + dns_setserver(1, dns2); + } + + return true; +} + /** * will force a disconnect an then start reconnecting to AP * @return ok @@ -607,6 +646,18 @@ uint8_t* ESP8266WiFiSTAClass::BSSID(void) { return reinterpret_cast(conf.bssid); } +/** + * Fill the current bssid / mac associated with the network if configured + * @param bssid pointer to uint8_t array with length WL_MAC_ADDR_LENGTH + * @return bssid uint8_t * + */ +uint8_t* ESP8266WiFiSTAClass::BSSID(uint8_t* bssid) { + struct station_config conf; + wifi_station_get_config(&conf); + memcpy(bssid, conf.bssid, WL_MAC_ADDR_LENGTH); + return bssid; +} + /** * Return the current bssid / mac associated with the network if configured * @return String bssid mac diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h index 0c1150a8e4..ad1b655a55 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h @@ -45,7 +45,14 @@ class ESP8266WiFiSTAClass: public LwipIntf { //The argument order for ESP is not the same as for Arduino. However, there is compatibility code under the hood //to detect Arduino arg order, and handle it correctly. Be aware that the Arduino default value handling doesn't //work here (see Arduino docs for gway/subnet defaults). In other words: at least 3 args must always be given. - bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); + bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = INADDR_ANY, IPAddress dns2 = INADDR_ANY); + + // two and one parameter version. 2nd parameter is DNS like in Arduino + // IPv4 only + [[deprecated("It is discouraged to use this 1 or 2 parameters network configuration legacy function config(ip[,dns]) as chosen defaults may not match the local network configuration")]] + bool config(IPAddress local_ip, IPAddress dns = INADDR_ANY); + + bool setDNS(IPAddress dns1, IPAddress dns2 = INADDR_ANY); bool reconnect(); @@ -79,6 +86,7 @@ class ESP8266WiFiSTAClass: public LwipIntf { String psk() const; uint8_t * BSSID(); + uint8_t * BSSID(uint8_t* bssid); String BSSIDstr(); int8_t RSSI(); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp index 5331c7bac8..1fdc6e04c7 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp @@ -259,6 +259,21 @@ uint8_t * ESP8266WiFiScanClass::BSSID(uint8_t i) { return it->bssid; } +/** + * fill MAC / BSSID of scanned wifi + * @param i specify from which network item want to get the information + * @param bssid pointer to uint8_t array with length WL_MAC_ADDR_LENGTH + * @return uint8_t * MAC / BSSID of scanned wifi + */ +uint8_t * ESP8266WiFiScanClass::BSSID(uint8_t i, uint8_t* bssid) { + struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); + if(!it) { + return 0; + } + memcpy(bssid, it->bssid, WL_MAC_ADDR_LENGTH); + return bssid; +} + /** * return MAC / BSSID of scanned wifi * @param i specify from which network item want to get the information diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.h b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.h index 36d159aca0..1c9c3a7408 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.h @@ -48,6 +48,7 @@ class ESP8266WiFiScanClass { uint8_t encryptionType(uint8_t networkItem); int32_t RSSI(uint8_t networkItem); uint8_t * BSSID(uint8_t networkItem); + uint8_t * BSSID(uint8_t networkItem, uint8_t* bssid); String BSSIDstr(uint8_t networkItem); int32_t channel(uint8_t networkItem); bool isHidden(uint8_t networkItem); diff --git a/libraries/ESP8266WiFi/src/WiFi.h b/libraries/ESP8266WiFi/src/WiFi.h new file mode 100644 index 0000000000..379989252d --- /dev/null +++ b/libraries/ESP8266WiFi/src/WiFi.h @@ -0,0 +1,2 @@ + +#include "ESP8266WiFi.h" \ No newline at end of file diff --git a/libraries/ESP8266WiFi/src/WiFiServer.cpp b/libraries/ESP8266WiFi/src/WiFiServer.cpp index 884065920c..462dbd7f74 100644 --- a/libraries/ESP8266WiFi/src/WiFiServer.cpp +++ b/libraries/ESP8266WiFi/src/WiFiServer.cpp @@ -173,6 +173,14 @@ void WiFiServer::stop() { close(); } +void WiFiServer::end() { + close(); +} + +WiFiServer::operator bool() { + return (status() != CLOSED); +} + err_t WiFiServer::_accept(tcp_pcb* apcb, err_t err) { (void) err; DEBUGV("WS:ac\r\n"); diff --git a/libraries/ESP8266WiFi/src/WiFiServer.h b/libraries/ESP8266WiFi/src/WiFiServer.h index ac6ad40aaf..b0f51b02f0 100644 --- a/libraries/ESP8266WiFi/src/WiFiServer.h +++ b/libraries/ESP8266WiFi/src/WiFiServer.h @@ -79,7 +79,7 @@ class WiFiServer { public: WiFiServer(const IPAddress& addr, uint16_t port); - WiFiServer(uint16_t port); + WiFiServer(uint16_t port = 23); virtual ~WiFiServer() {} WiFiClient accept(); // https://www.arduino.cc/en/Reference/EthernetServerAccept WiFiClient available(uint8_t* status = NULL) __attribute__((deprecated("Renamed to accept()."))); @@ -100,6 +100,8 @@ class WiFiServer { uint16_t port() const; void close(); void stop(); + void end(); + explicit operator bool(); using ClientType = WiFiClient; diff --git a/libraries/ESP8266WiFi/src/enable_wifi_at_boot_time.cpp b/libraries/ESP8266WiFi/src/enable_wifi_at_boot_time.cpp index 5eb62eec15..a8589c4d25 100644 --- a/libraries/ESP8266WiFi/src/enable_wifi_at_boot_time.cpp +++ b/libraries/ESP8266WiFi/src/enable_wifi_at_boot_time.cpp @@ -21,7 +21,7 @@ extern "C" void __disableWiFiAtBootTime() // Does (almost) nothing: WiFi is enabled by default in nonos-sdk // ... but restores legacy WiFi credentials persistence to true at boot time - // (can be still overrisden by user before setting up WiFi, like before) + // (can be still overridden by user before setting up WiFi, like before) // (note: c++ ctors not called yet at this point) ESP8266WiFiClass::persistent(true); diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp index 9cd5d62801..af45852e5f 100755 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp @@ -235,6 +235,7 @@ HTTPUpdateResult ESP8266HTTPUpdate::handleUpdate(HTTPClient& http, const String& DEBUG_HTTP_UPDATE("[httpUpdate] ESP8266 info:\n"); DEBUG_HTTP_UPDATE("[httpUpdate] - free Space: %d\n", ESP.getFreeSketchSpace()); DEBUG_HTTP_UPDATE("[httpUpdate] - current Sketch Size: %d\n", ESP.getSketchSize()); + DEBUG_HTTP_UPDATE("[httpUpdate] - current Sketch MD5: %s\n", ESP.getSketchMD5().c_str()); if(currentVersion && currentVersion[0] != 0x00) { DEBUG_HTTP_UPDATE("[httpUpdate] - current version: %s\n", currentVersion.c_str() ); @@ -440,6 +441,115 @@ bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, const String& md5, return true; } +/** + * @brief Get avialable firmware version from update server + * @author Holger Mueller + * @date 2023-08-03 + * + * @param client WiFiClient to use (see HTTPClient::begin) + * @param host Update host name or IP (see HTTPClient::begin) + * @param port Port on host (see HTTPClient::begin) + * @param uri Update URI on server (see HTTPClient::begin) + * @param current_version Current firmware version + * @param available_version Firmware version available on update server + * @return ESP8266HTTPUpdate::HTTPUpdateResult, HTTP_UPDATE_OK in case of success + */ +HTTPUpdateResult ESP8266HTTPUpdate::getAvailableVersion(WiFiClient& client, const String& host, uint16_t port, const String& uri, const String& current_version, String& available_version) { + HTTPUpdateResult ret = HTTP_UPDATE_FAILED; + HTTPClient http; + http.begin(client, host, port, uri); + + // use HTTP/1.0 for update since the update handler not support any transfer Encoding + http.useHTTP10(true); + http.setTimeout(_httpClientTimeout); + http.setFollowRedirects(_followRedirects); + http.setUserAgent(F("ESP8266-http-Update")); + http.addHeader(F("x-ESP8266-Chip-ID"), String(ESP.getChipId())); + http.addHeader(F("x-ESP8266-STA-MAC"), WiFi.macAddress()); + http.addHeader(F("x-ESP8266-AP-MAC"), WiFi.softAPmacAddress()); + http.addHeader(F("x-ESP8266-free-space"), String(ESP.getFreeSketchSpace())); + http.addHeader(F("x-ESP8266-sketch-size"), String(ESP.getSketchSize())); + http.addHeader(F("x-ESP8266-sketch-md5"), String(ESP.getSketchMD5())); + http.addHeader(F("x-ESP8266-chip-size"), String(ESP.getFlashChipRealSize())); + http.addHeader(F("x-ESP8266-sdk-version"), ESP.getSdkVersion()); + + http.addHeader(F("x-ESP8266-mode"), F("version")); + + if (current_version && current_version[0] != 0x00) { + http.addHeader(F("x-ESP8266-version"), current_version); + } + + if (!_user.isEmpty() && !_password.isEmpty()) { + http.setAuthorization(_user.c_str(), _password.c_str()); + } + + if (!_auth.isEmpty()) { + http.setAuthorization(_auth.c_str()); + } + + const char* headerkeys[] = {"x-MD5", "x-version"}; + size_t headerkeyssize = sizeof(headerkeys) / sizeof(char*); + + // track these headers + http.collectHeaders(headerkeys, headerkeyssize); + + int code = http.GET(); + + if (code <= 0) { + DEBUG_HTTP_UPDATE("[httpUpdate] HTTP error: %s\n", http.errorToString(code).c_str()); + _setLastError(code); + http.end(); + return HTTP_UPDATE_FAILED; + } + + DEBUG_HTTP_UPDATE("[httpUpdate] Header read fin.\n"); + DEBUG_HTTP_UPDATE("[httpUpdate] Server header:\n"); + DEBUG_HTTP_UPDATE("[httpUpdate] - code: %d\n", code); + DEBUG_HTTP_UPDATE("[httpUpdate] - len: %d\n", http.getSize()); + if (code != HTTP_CODE_OK) { + DEBUG_HTTP_UPDATE("[httpUpdate] - payload: %s\n", http.getString().c_str()); + } + + switch (code) { + case HTTP_CODE_OK: ///< OK (check for version) + if (http.hasHeader("x-version")) { + available_version = http.header("x-version"); + ret = HTTP_UPDATE_OK; + DEBUG_HTTP_UPDATE("[httpUpdate] - current version: %s\n", current_version.c_str()); + DEBUG_HTTP_UPDATE("[httpUpdate] - server version: %s\n", available_version.c_str()); + } else { + _setLastError(HTTP_UE_SERVER_NOT_REPORT_VERSION); + ret = HTTP_UPDATE_FAILED; + DEBUG_HTTP_UPDATE("[httpUpdate] Server did not respond with a firmware version\n"); + } + if (http.hasHeader("x-MD5")) { + DEBUG_HTTP_UPDATE("[httpUpdate] - current Sketch MD5: %s\n", ESP.getSketchMD5().c_str()); + DEBUG_HTTP_UPDATE("[httpUpdate] - server Sketch MD5: %s\n", http.header("x-MD5").c_str()); + } + break; + case HTTP_CODE_NOT_FOUND: + _setLastError(HTTP_UE_SERVER_FILE_NOT_FOUND); + ret = HTTP_UPDATE_FAILED; + break; + case HTTP_CODE_FORBIDDEN: + _setLastError(HTTP_UE_SERVER_FORBIDDEN); + ret = HTTP_UPDATE_FAILED; + break; + case HTTP_CODE_UNAUTHORIZED: + _setLastError(HTTP_UE_SERVER_UNAUTHORIZED); + ret = HTTP_UPDATE_FAILED; + break; + default: + _setLastError(HTTP_UE_SERVER_WRONG_HTTP_CODE); + ret = HTTP_UPDATE_FAILED; + DEBUG_HTTP_UPDATE("[httpUpdate] HTTP Code is (%d)\n", code); + break; + } + + http.end(); + return ret; +} + #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_HTTPUPDATE) ESP8266HTTPUpdate ESPhttpUpdate; #endif diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h index 803988d3be..28e90bad23 100755 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h @@ -43,16 +43,18 @@ #endif /// note we use HTTP client errors too so we start at 100 -//TODO - in v3.0.0 make this an enum -constexpr int HTTP_UE_TOO_LESS_SPACE = (-100); -constexpr int HTTP_UE_SERVER_NOT_REPORT_SIZE = (-101); -constexpr int HTTP_UE_SERVER_FILE_NOT_FOUND = (-102); -constexpr int HTTP_UE_SERVER_FORBIDDEN = (-103); -constexpr int HTTP_UE_SERVER_WRONG_HTTP_CODE = (-104); -constexpr int HTTP_UE_SERVER_FAULTY_MD5 = (-105); -constexpr int HTTP_UE_BIN_VERIFY_HEADER_FAILED = (-106); -constexpr int HTTP_UE_BIN_FOR_WRONG_FLASH = (-107); -constexpr int HTTP_UE_SERVER_UNAUTHORIZED = (-108); +enum HTTPUpdateError { + HTTP_UE_SERVER_NOT_REPORT_VERSION = -109, // server did not respond with a firmware version + HTTP_UE_SERVER_UNAUTHORIZED, // -108 + HTTP_UE_BIN_FOR_WRONG_FLASH, // -107 + HTTP_UE_BIN_VERIFY_HEADER_FAILED, // -106 + HTTP_UE_SERVER_FAULTY_MD5, // -105 + HTTP_UE_SERVER_WRONG_HTTP_CODE, // -104 + HTTP_UE_SERVER_FORBIDDEN, // -103 + HTTP_UE_SERVER_FILE_NOT_FOUND, // -102 + HTTP_UE_SERVER_NOT_REPORT_SIZE, // -101 + HTTP_UE_TOO_LESS_SPACE // -100 +}; enum HTTPUpdateResult { HTTP_UPDATE_FAILED, @@ -122,7 +124,9 @@ class ESP8266HTTPUpdate t_httpUpdate_return updateFS(WiFiClient& client, const String& url, const String& currentVersion = ""); t_httpUpdate_return update(HTTPClient& httpClient, const String& currentVersion = ""); t_httpUpdate_return updateFS(HTTPClient& httpClient, const String& currentVersion = ""); - + + t_httpUpdate_return getAvailableVersion(WiFiClient& client, const String& host, uint16_t port, const String& uri, const String& current_version, String& available_version); + // Notification callbacks void onStart(HTTPUpdateStartCB cbOnStart) { _cbStart = cbOnStart; } void onEnd(HTTPUpdateEndCB cbOnEnd) { _cbEnd = cbOnEnd; } @@ -153,10 +157,9 @@ class ESP8266HTTPUpdate String _password; String _auth; String _md5Sum; -private: int _httpClientTimeout; followRedirects_t _followRedirects = HTTPC_DISABLE_FOLLOW_REDIRECTS; - +private: // Callbacks HTTPUpdateStartCB _cbStart; HTTPUpdateEndCB _cbEnd; diff --git a/libraries/ESP8266mDNS/examples/OTA-mDNS-LittleFS/OTA-mDNS-LittleFS.ino b/libraries/ESP8266mDNS/examples/OTA-mDNS-LittleFS/OTA-mDNS-LittleFS.ino index d94d96077c..78d4aa6c30 100644 --- a/libraries/ESP8266mDNS/examples/OTA-mDNS-LittleFS/OTA-mDNS-LittleFS.ino +++ b/libraries/ESP8266mDNS/examples/OTA-mDNS-LittleFS/OTA-mDNS-LittleFS.ino @@ -47,7 +47,7 @@ const char *ap_default_psk = APPSK; ///< Default PSK. /// @} /// Uncomment the next line for verbose output over UART. -//#define SERIAL_VERBOSE +// #define SERIAL_VERBOSE /** @brief Read WiFi connection information from file system. diff --git a/libraries/ESP8266mDNS/src/LEAmDNS.h b/libraries/ESP8266mDNS/src/LEAmDNS.h index 092fcd5cf2..3fc4dd98da 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS.h +++ b/libraries/ESP8266mDNS/src/LEAmDNS.h @@ -492,8 +492,7 @@ namespace MDNSImplementation { MDNSServiceInfo(MDNSResponder& p_pM, MDNSResponder::hMDNSServiceQuery p_hS, uint32_t p_u32A) : - p_pMDNSResponder(p_pM), - p_hServiceQuery(p_hS), p_u32AnswerIndex(p_u32A) {}; + p_pMDNSResponder(p_pM), p_hServiceQuery(p_hS), p_u32AnswerIndex(p_u32A) {}; struct CompareKey { bool operator()(char const* a, char const* b) const diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp index f575983ef7..2cc32b053b 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp @@ -631,8 +631,8 @@ namespace MDNSImplementation } } } // service tiebreak possibility - } // for services - } // ANY answers + } // for services + } // ANY answers } else { @@ -955,7 +955,7 @@ namespace MDNSImplementation } pRRAnswer = pRRAnswer->m_pNext; // Next collected answer - } // while (answers) + } // while (answers) } while ((bFoundNewKeyAnswer) && (bResult)); } // else: No answers provided DEBUG_EX_ERR(if (!bResult) { @@ -1110,7 +1110,7 @@ namespace MDNSImplementation } pServiceQuery = pServiceQuery->m_pNext; } // while(service query) - } // else: No p_pSRVAnswer + } // else: No p_pSRVAnswer DEBUG_EX_ERR(if (!bResult) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processSRVAnswer: FAILED!\n")); }); @@ -1173,7 +1173,7 @@ namespace MDNSImplementation } pServiceQuery = pServiceQuery->m_pNext; } // while(service query) - } // else: No p_pTXTAnswer + } // else: No p_pTXTAnswer DEBUG_EX_ERR(if (!bResult) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processTXTAnswer: FAILED!\n")); }); @@ -1261,7 +1261,7 @@ namespace MDNSImplementation } pServiceQuery = pServiceQuery->m_pNext; } // while(service query) - } // else: No p_pAAnswer + } // else: No p_pAAnswer DEBUG_EX_ERR(if (!bResult) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processAAnswer: FAILED!\n")); }); @@ -1349,7 +1349,7 @@ namespace MDNSImplementation } pServiceQuery = pServiceQuery->m_pNext; } // while(service query) - } // else: No p_pAAAAAnswer + } // else: No p_pAAAAAnswer return bResult; } @@ -2121,7 +2121,7 @@ namespace MDNSImplementation } // IP4 flagged pIP4Address = pNextIP4Address; // Next - } // while + } // while #endif #ifdef MDNS_IP6_SUPPORT // IP6Address (from AAAA) @@ -2185,7 +2185,7 @@ namespace MDNSImplementation } // IP6 flagged pIP6Address = pNextIP6Address; // Next - } // while + } // while #endif pSQAnswer = pNextSQAnswer; } diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Structs.cpp b/libraries/ESP8266mDNS/src/LEAmDNS_Structs.cpp index 977a924394..637f62869a 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Structs.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Structs.cpp @@ -55,8 +55,7 @@ namespace MDNSImplementation MDNSResponder::stcMDNSServiceTxt::stcMDNSServiceTxt(const char* p_pcKey /*= 0*/, const char* p_pcValue /*= 0*/, bool p_bTemp /*= false*/) : - m_pNext(0), - m_pcKey(0), m_pcValue(0), m_bTemp(p_bTemp) + m_pNext(0), m_pcKey(0), m_pcValue(0), m_bTemp(p_bTemp) { setKey(p_pcKey); setValue(p_pcValue); @@ -67,8 +66,7 @@ namespace MDNSImplementation */ MDNSResponder::stcMDNSServiceTxt::stcMDNSServiceTxt( const MDNSResponder::stcMDNSServiceTxt& p_Other) : - m_pNext(0), - m_pcKey(0), m_pcValue(0), m_bTemp(false) + m_pNext(0), m_pcKey(0), m_pcValue(0), m_bTemp(false) { operator=(p_Other); } @@ -614,9 +612,8 @@ namespace MDNSImplementation bool p_bRA /*= false*/, unsigned char p_ucRCode /*= 0*/, uint16_t p_u16QDCount /*= 0*/, uint16_t p_u16ANCount /*= 0*/, uint16_t p_u16NSCount /*= 0*/, uint16_t p_u16ARCount /*= 0*/) : - m_u16ID(p_u16ID), - m_1bQR(p_bQR), m_4bOpcode(p_ucOpcode), m_1bAA(p_bAA), m_1bTC(p_bTC), m_1bRD(p_bRD), - m_1bRA(p_bRA), m_3bZ(0), m_4bRCode(p_ucRCode), m_u16QDCount(p_u16QDCount), + m_u16ID(p_u16ID), m_1bQR(p_bQR), m_4bOpcode(p_ucOpcode), m_1bAA(p_bAA), m_1bTC(p_bTC), + m_1bRD(p_bRD), m_1bRA(p_bRA), m_3bZ(0), m_4bRCode(p_ucRCode), m_u16QDCount(p_u16QDCount), m_u16ANCount(p_u16ANCount), m_u16NSCount(p_u16NSCount), m_u16ARCount(p_u16ARCount) { } @@ -813,8 +810,7 @@ namespace MDNSImplementation */ MDNSResponder::stcMDNS_RRAttributes::stcMDNS_RRAttributes( uint16_t p_u16Type /*= 0*/, uint16_t p_u16Class /*= 1 DNS_RRCLASS_IN Internet*/) : - m_u16Type(p_u16Type), - m_u16Class(p_u16Class) + m_u16Type(p_u16Type), m_u16Class(p_u16Class) { } @@ -910,8 +906,7 @@ namespace MDNSImplementation MDNSResponder::stcMDNS_RRAnswer::stcMDNS_RRAnswer( enuAnswerType p_AnswerType, const MDNSResponder::stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL) : - m_pNext(0), - m_AnswerType(p_AnswerType), m_Header(p_Header), m_u32TTL(p_u32TTL) + m_pNext(0), m_AnswerType(p_AnswerType), m_Header(p_Header), m_u32TTL(p_u32TTL) { // Extract 'cache flush'-bit m_bCacheFlush = (m_Header.m_Attributes.m_u16Class & 0x8000); @@ -955,8 +950,7 @@ namespace MDNSImplementation */ MDNSResponder::stcMDNS_RRAnswerA::stcMDNS_RRAnswerA( const MDNSResponder::stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL) : - stcMDNS_RRAnswer(AnswerType_A, p_Header, p_u32TTL), - m_IPAddress(0, 0, 0, 0) + stcMDNS_RRAnswer(AnswerType_A, p_Header, p_u32TTL), m_IPAddress(0, 0, 0, 0) { } @@ -1094,8 +1088,8 @@ namespace MDNSImplementation */ MDNSResponder::stcMDNS_RRAnswerSRV::stcMDNS_RRAnswerSRV( const MDNSResponder::stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL) : - stcMDNS_RRAnswer(AnswerType_SRV, p_Header, p_u32TTL), - m_u16Priority(0), m_u16Weight(0), m_u16Port(0) + stcMDNS_RRAnswer(AnswerType_SRV, p_Header, p_u32TTL), m_u16Priority(0), m_u16Weight(0), + m_u16Port(0) { } @@ -1132,8 +1126,7 @@ namespace MDNSImplementation */ MDNSResponder::stcMDNS_RRAnswerGeneric::stcMDNS_RRAnswerGeneric( const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL) : - stcMDNS_RRAnswer(AnswerType_Generic, p_Header, p_u32TTL), - m_u16RDLength(0), m_pu8RDData(0) + stcMDNS_RRAnswer(AnswerType_Generic, p_Header, p_u32TTL), m_u16RDLength(0), m_pu8RDData(0) { } @@ -1212,8 +1205,7 @@ namespace MDNSImplementation MDNSResponder::stcMDNSService::stcMDNSService(const char* p_pcName /*= 0*/, const char* p_pcService /*= 0*/, const char* p_pcProtocol /*= 0*/) : - m_pNext(0), - m_pcName(0), m_bAutoName(false), m_pcService(0), m_pcProtocol(0), m_u16Port(0), + m_pNext(0), m_pcName(0), m_bAutoName(false), m_pcService(0), m_pcProtocol(0), m_u16Port(0), m_u8ReplyMask(0), m_fnTxtCallback(0) { setName(p_pcName); @@ -1538,9 +1530,7 @@ namespace MDNSImplementation MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address::stcIP4Address constructor */ MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address::stcIP4Address( - IPAddress p_IPAddress, uint32_t p_u32TTL /*= 0*/) : - m_pNext(0), - m_IPAddress(p_IPAddress) + IPAddress p_IPAddress, uint32_t p_u32TTL /*= 0*/) : m_pNext(0), m_IPAddress(p_IPAddress) { m_TTL.set(p_u32TTL); } @@ -2172,9 +2162,8 @@ namespace MDNSImplementation */ MDNSResponder::stcMDNSSendParameter::stcDomainCacheItem::stcDomainCacheItem( const void* p_pHostnameOrService, bool p_bAdditionalData, uint32_t p_u16Offset) : - m_pNext(0), - m_pHostnameOrService(p_pHostnameOrService), m_bAdditionalData(p_bAdditionalData), - m_u16Offset(p_u16Offset) + m_pNext(0), m_pHostnameOrService(p_pHostnameOrService), + m_bAdditionalData(p_bAdditionalData), m_u16Offset(p_u16Offset) { } diff --git a/libraries/I2S/examples/InputSerialPlotter/InputSerialPlotter.ino b/libraries/I2S/examples/InputSerialPlotter/InputSerialPlotter.ino index 50b3206cc7..18f1cad1f9 100644 --- a/libraries/I2S/examples/InputSerialPlotter/InputSerialPlotter.ino +++ b/libraries/I2S/examples/InputSerialPlotter/InputSerialPlotter.ino @@ -21,8 +21,7 @@ void setup() { // start I2S at 8 kHz with 24-bits per sample if (!I2S.begin(I2S_PHILIPS_MODE, 8000, 24)) { Serial.println("Failed to initialize I2S!"); - while (1) - ; // do nothing + while (1); // do nothing } } diff --git a/libraries/I2S/examples/SimpleTone/SimpleTone.ino b/libraries/I2S/examples/SimpleTone/SimpleTone.ino index 689a50d579..e2dcb7b3f6 100644 --- a/libraries/I2S/examples/SimpleTone/SimpleTone.ino +++ b/libraries/I2S/examples/SimpleTone/SimpleTone.ino @@ -26,8 +26,7 @@ void setup() { // start I2S at the sample rate with 16-bits per sample if (!I2S.begin(I2S_PHILIPS_MODE, sampleRate, 16)) { Serial.println("Failed to initialize I2S!"); - while (1) - ; // do nothing + while (1); // do nothing } } diff --git a/libraries/LittleFS/examples/SpeedTest/SpeedTest.ino b/libraries/LittleFS/examples/SpeedTest/SpeedTest.ino index 5b0870b37b..c3dd6b2c1f 100644 --- a/libraries/LittleFS/examples/SpeedTest/SpeedTest.ino +++ b/libraries/LittleFS/examples/SpeedTest/SpeedTest.ino @@ -8,8 +8,8 @@ // WARNING: The filesystem will be formatted at the start of the test! #define TESTFS LittleFS -//#define TESTFS SPIFFS -//#define TESTFS SDFS +// #define TESTFS SPIFFS +// #define TESTFS SDFS // How large of a file to test #define TESTSIZEKB 512 diff --git a/libraries/LittleFS/src/LittleFS.h b/libraries/LittleFS/src/LittleFS.h index a3afbfe77f..d5203ae6e0 100644 --- a/libraries/LittleFS/src/LittleFS.h +++ b/libraries/LittleFS/src/LittleFS.h @@ -167,6 +167,14 @@ class LittleFSImpl : public FSImpl return false; } int rc = lfs_mkdir(&_lfs, path); + if ((rc == 0) && _timeCallback) { + time_t now = _timeCallback(); + // Add metadata with creation time to the directory marker + int rc = lfs_setattr(&_lfs, path, 'c', (const void *)&now, sizeof(now)); + if (rc < 0) { + DEBUGV("Unable to set creation time on '%s' to %ld\n", path, (long)now); + } + } return (rc==0); } diff --git a/libraries/Netdump/examples/Netdump/Netdump.ino b/libraries/Netdump/examples/Netdump/Netdump.ino index 37210a8a0a..35ffc6b493 100644 --- a/libraries/Netdump/examples/Netdump/Netdump.ino +++ b/libraries/Netdump/examples/Netdump/Netdump.ino @@ -4,7 +4,7 @@ #include #include #include -//#include +// #include #include #include diff --git a/libraries/SD/examples/listfilesEnhanced/listfilesEnhanced.ino b/libraries/SD/examples/listfilesEnhanced/listfilesEnhanced.ino new file mode 100644 index 0000000000..5daa3294ad --- /dev/null +++ b/libraries/SD/examples/listfilesEnhanced/listfilesEnhanced.ino @@ -0,0 +1,134 @@ +/* + Listfiles Enhanced + + This example demonstrates how to list files on an SDcard in the following way: + 1) collect all directories + 2) build full path of directories and keep in mind + 3) then print all files with the help of the directorie pathes + + Wiring: + SDcard attached to SPI bus as follows: + - MOSI: pin 11 + - MISO: pin 12 + - CLK : pin 13 + - CS : pin 4 + + Created: + 18. Nov 2024 by Frank Häfele + + This example code is in the public domain. + +*/ +#include +#include +#include + +#define SD_CS_PIN 4 + + +void dir(String path) { + std::vector directories; + collectDirectories(path, directories); + for (auto directory : directories) { + printDirectoryName(directory.c_str(), 1); + File fs = SD.open(directory); + printFilesInDirectory(fs); + Serial.println("\n==============="); + fs.close(); + } +} + +void setup() { + // Open serial communications and wait for port to open: + Serial.begin(115200); + + Serial.print("\n\n==== List Directory ====\n\n"); + listDirectory(); + + Serial.println("done!"); +} + +void loop() { + // nothing happens after setup finishes. +} + +void listDirectory() { + Serial.print("\n\nInitializing SD card..."); + if (!SD.begin(SD_CS_PIN)) { + Serial.println("initialization failed!"); + return; + } + Serial.print("initialization successful.\n"); + Serial.print("List Files:\n"); + dir("/"); +} + + +void printDirectoryName(const char *name, uint8_t level) { + for (uint8_t i = 0; i < level; ++i) { + Serial.print(" "); + } + Serial.println(name); +} + + + +// helper function: combine path +String joinPath(const String &base, const String &name) { + if (base.endsWith("/")) { + return base + name; + } + return base + "/" + name; +} + +// recusive function to collect directory names +void collectDirectories(const String &dirname, std::vector &directories) { + File root = SD.open(dirname); + if (!root || !root.isDirectory()) { + Serial.printf("Error: Cannot open %s\n", dirname.c_str()); + return; + } + directories.push_back(dirname); + + File file = root.openNextFile(); + while (file) { + if (file.isDirectory()) { + String fullPath = joinPath(dirname, file.name()); + collectDirectories(fullPath, directories); + } + file = root.openNextFile(); + } + root.close(); +} + +// print filenames +void printFileName(File file) { + Serial.print("\t"); + Serial.printf("%30s", file.name()); + // files have sizes, directories do not + Serial.print(" - "); + Serial.print(file.size(), DEC); + time_t cr = file.getCreationTime(); + time_t lw = file.getLastWrite(); + struct tm *tmstruct = localtime(&cr); + Serial.printf("\tCREATION: %d-%02d-%02d %02d:%02d:%02d", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec); + tmstruct = localtime(&lw); + Serial.printf("\tLAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec); +} + + +// print files in directories +void printFilesInDirectory(File dir) { + while (true) { + auto file = dir.openNextFile(); + if (!file) { + // no more files + break; + } + if (file.isDirectory()) { + continue; + } else { + printFileName(file); + } + } +} diff --git a/libraries/TFT_Touch_Shield_V2/examples/tftbmp/tftbmp.ino b/libraries/TFT_Touch_Shield_V2/examples/tftbmp/tftbmp.ino index 691f5be7ca..55e4981df9 100644 --- a/libraries/TFT_Touch_Shield_V2/examples/tftbmp/tftbmp.ino +++ b/libraries/TFT_Touch_Shield_V2/examples/tftbmp/tftbmp.ino @@ -55,8 +55,7 @@ void setup() { if (!SD.begin(PIN_SD_CS)) { Serial.println("failed!"); - while (1) - ; // init fail, die here + while (1); // init fail, die here } Serial.println("SD OK!"); @@ -69,8 +68,7 @@ void loop() { bmpFile = SD.open(__Gsbmp_files[i]); if (!bmpFile) { Serial.println("didn't find image"); - while (1) - ; + while (1); } if (!bmpReadHeader(bmpFile)) { diff --git a/libraries/TFT_Touch_Shield_V2/examples/tftbmp2/tftbmp2.ino b/libraries/TFT_Touch_Shield_V2/examples/tftbmp2/tftbmp2.ino index 0a698fb150..8e24600481 100644 --- a/libraries/TFT_Touch_Shield_V2/examples/tftbmp2/tftbmp2.ino +++ b/libraries/TFT_Touch_Shield_V2/examples/tftbmp2/tftbmp2.ino @@ -99,8 +99,7 @@ void setup() { if (!SD.begin(PIN_SD_CS)) { Serial.println("failed!"); - while (1) - ; // init fail, die here + while (1); // init fail, die here } Serial.println("SD OK!"); @@ -141,8 +140,7 @@ void loop() { if (!bmpFile) { Serial.println("didn't find image"); - while (1) - ; + while (1); } if (!bmpReadHeader(bmpFile)) { @@ -153,8 +151,7 @@ void loop() { bmpdraw(bmpFile, 0, 0, 1); bmpFile.close(); - while (1) - ; + while (1); } /*********************************************/ diff --git a/libraries/esp8266/examples/LowPowerDemo/LowPowerDemo.ino b/libraries/esp8266/examples/LowPowerDemo/LowPowerDemo.ino index 5d1fb2fb44..27dbb77184 100644 --- a/libraries/esp8266/examples/LowPowerDemo/LowPowerDemo.ino +++ b/libraries/esp8266/examples/LowPowerDemo/LowPowerDemo.ino @@ -42,7 +42,7 @@ #include #include // WiFiState structure details -//#define DEBUG // prints WiFi connection info to serial, uncomment if you want WiFi messages +// #define DEBUG // prints WiFi connection info to serial, uncomment if you want WiFi messages #ifdef DEBUG #define DEBUG_PRINTLN(x) Serial.println(x) #define DEBUG_PRINT(x) Serial.print(x) @@ -56,8 +56,8 @@ // uncomment one of the two lines below for your LED connection (optional) #define LED 5 // D1/GPIO5 external LED for modules with built-in LEDs so it doesn't add amperage -//#define LED 2 // D4/GPIO2 LED for ESP-01,07 modules; D4 is LED_BUILTIN on most other modules -// you can use LED_BUILTIN, but it adds to the measured amperage by 0.3mA to 6mA. +// #define LED 2 // D4/GPIO2 LED for ESP-01,07 modules; D4 is LED_BUILTIN on most other modules +// you can use LED_BUILTIN, but it adds to the measured amperage by 0.3mA to 6mA. ADC_MODE(ADC_VCC); // allows you to monitor the internal VCC level; it varies with WiFi load // don't connect anything to the analog input pin(s)! @@ -72,7 +72,7 @@ IPAddress dns1(0, 0, 0, 0); IPAddress dns2(0, 0, 0, 0); uint32_t timeout = 30E3; // 30 second timeout on the WiFi connection -//#define TESTPOINT // used to track the timing of several test cycles (optional) +// #define TESTPOINT // used to track the timing of several test cycles (optional) #ifdef TESTPOINT #define testPointPin 4 // D2/GPIO4, you can use any pin that supports interrupts #define testPoint_HIGH digitalWrite(testPointPin, HIGH) diff --git a/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino b/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino index 6388c1a9cf..8a9ea0e82c 100644 --- a/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino +++ b/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino @@ -31,11 +31,11 @@ // check for your nearest city in TZ.h // espressif headquarter TZ -//#define MYTZ TZ_Asia_Shanghai +// #define MYTZ TZ_Asia_Shanghai // example for "Not Only Whole Hours" timezones: // Kolkata/Calcutta is shifted by 30mn -//#define MYTZ TZ_Asia_Kolkata +// #define MYTZ TZ_Asia_Kolkata // example of a timezone with a variable Daylight-Saving-Time: // demo: watch automatic time adjustment on Summer/Winter change (DST) diff --git a/libraries/esp8266/examples/SerialStress/SerialStress.ino b/libraries/esp8266/examples/SerialStress/SerialStress.ino index 5d6aaf2366..f491ba04e5 100644 --- a/libraries/esp8266/examples/SerialStress/SerialStress.ino +++ b/libraries/esp8266/examples/SerialStress/SerialStress.ino @@ -1,17 +1,16 @@ /* Serial read/write/verify/benchmark - Using internal loopback - Using EspSoftwareSerial library for logging + Using Serial0 for internal loopback + Using Serial1 for logging Sketch meant for debugging only Released to public domain */ #include -#include -#define SSBAUD 115200 // logger on console for humans +#define LOGBAUD 115200 // logger on console for humans #define BAUD 3000000 // hardware serial stress test #define BUFFER_SIZE 4096 // may be useless to use more than 2*SERIAL_SIZE_RX #define SERIAL_SIZE_RX 1024 // Serial.setRxBufferSize() @@ -21,6 +20,9 @@ #define TIMEOUT 5000 #define DEBUG(x...) // x +#define READING_PIN 4 +#define TIMEOUT_PIN 5 + uint8_t buf[BUFFER_SIZE]; uint8_t temp[BUFFER_SIZE]; bool reading = true; @@ -51,18 +53,18 @@ void error(const char* what) { void setup() { pinMode(LED_BUILTIN, OUTPUT); + pinMode(READING_PIN, INPUT); + pinMode(TIMEOUT_PIN, INPUT); + Serial.begin(BAUD); Serial.swap(); // RX=GPIO13 TX=GPIO15 Serial.setRxBufferSize(SERIAL_SIZE_RX); - // using HardwareSerial0 pins, - // so we can still log to the regular usbserial chips - SoftwareSerial* ss = new SoftwareSerial(3, 1); - ss->begin(SSBAUD); - ss->enableIntTx(false); - logger = ss; + Serial1.begin(LOGBAUD); // RX=NONE TX=GPIO2 + logger = &Serial1; + logger->println(); - logger->printf("\n\nOn Software Serial for logging\n"); + logger->printf("\n\nOn Serial1 for logging\n"); int baud = Serial.baudRate(); logger->printf(ESP.getFullVersion().c_str()); @@ -79,8 +81,7 @@ void setup() { // bind RX and TX USC0(0) |= (1 << UCLBE); - while (Serial.read() == -1) - ; + while (Serial.read() == -1); if (Serial.hasOverrun()) { logger->print("overrun?\n"); } timeout = (start_ms = last_ms = millis()) + TIMEOUT; @@ -140,15 +141,13 @@ void loop() { timeout = (last_ms = now_ms) + TIMEOUT; } - if (logger->available()) switch (logger->read()) { - case 's': - logger->println("now stopping reading, keeping writing"); - reading = false; - break; - case 't': - testReadBytesTimeout ^= FAKE_INCREASED_AVAILABLE; - logger->printf("testing readBytes timeout: %d\n", !!testReadBytesTimeout); - break; - default:; - } + if (reading && (digitalRead(READING_PIN) == 0)) { + logger->println("now stopping reading, keeping writing"); + reading = false; + } + + if (digitalRead(TIMEOUT_PIN) == 0) { + testReadBytesTimeout ^= FAKE_INCREASED_AVAILABLE; + logger->printf("testing readBytes timeout: %d\n", !!testReadBytesTimeout); + } } diff --git a/libraries/esp8266/examples/StreamString/StreamString.ino b/libraries/esp8266/examples/StreamString/StreamString.ino index f177b53edc..73512cf2af 100644 --- a/libraries/esp8266/examples/StreamString/StreamString.ino +++ b/libraries/esp8266/examples/StreamString/StreamString.ino @@ -54,7 +54,7 @@ void testStreamString() { { // We use a a lighter StreamConstPtr(input) to make a read-only Stream out of // a String that obviously should not be modified during the time the - // StreamConstPtr instance is used. It is used as a source to be sent to + // StreamConstPtr instance is used. It is used as a read-only source to be sent to // 'result'. result.clear(); @@ -77,7 +77,7 @@ void testStreamString() { // Now inputString is made into a Stream using S2Stream, // and set in non-consume mode (using ::resetPointer()). - // Then, after that input is read once, it won't be anymore readable + // Then, after input is read once, it won't be anymore readable // until the pointer is reset. S2Stream input(inputString); @@ -87,7 +87,7 @@ void testStreamString() { input.sendAll(result); input.sendAll(result); check("S2Stream.sendAll(StreamString)", result.c_str(), "hello"); - check("unmodified String given to S2Stream", inputString.c_str(), "hello"); + check("String given to S2Stream is unmodified", inputString.c_str(), "hello"); } { @@ -103,6 +103,17 @@ void testStreamString() { check("S2Stream.resetPointer(2):", result.c_str(), "llo"); } + { + // Streaming to a regular String + + String someSource{ F("hello") }; + String someDestString; + + StreamConstPtr(someSource).sendAll(S2Stream(someDestString)); + StreamConstPtr(someSource).sendAll(S2Stream(someDestString)); + check("StreamConstPtr(someSource).sendAll(S2Stream(someDestString))", someDestString.c_str(), "hellohello"); + } + { // inputString made into a Stream // reading the Stream consumes the String @@ -181,7 +192,8 @@ void setup() { testStreamString(); - Serial.printf("sizeof: String:%d Stream:%d StreamString:%d SStream:%d\n", (int)sizeof(String), (int)sizeof(Stream), (int)sizeof(StreamString), (int)sizeof(S2Stream)); + Serial.printf("sizeof: String:%zu Stream:%zu StreamString:%zu S2Stream:%zu StreamConstPtr:%zu\n", + sizeof(String), sizeof(Stream), sizeof(StreamString), sizeof(S2Stream), sizeof(StreamConstPtr)); } #endif diff --git a/libraries/esp8266/examples/TestEspApi/TestEspApi.ino b/libraries/esp8266/examples/TestEspApi/TestEspApi.ino index 903306a1dd..38e443f3ca 100644 --- a/libraries/esp8266/examples/TestEspApi/TestEspApi.ino +++ b/libraries/esp8266/examples/TestEspApi/TestEspApi.ino @@ -15,8 +15,8 @@ extern "C" { } #endif -// Set up output serial port (could be a SoftwareSerial -// if really wanted). +// Set up output on the first serial port +// (can be any Stream, if needed) Stream& ehConsolePort(Serial); diff --git a/libraries/lwIP_Ethernet/src/EthernetCompat.h b/libraries/lwIP_Ethernet/src/EthernetCompat.h index 99dca03e67..9ebd75ca15 100644 --- a/libraries/lwIP_Ethernet/src/EthernetCompat.h +++ b/libraries/lwIP_Ethernet/src/EthernetCompat.h @@ -38,10 +38,29 @@ class ArduinoEthernet: public LwipIntfDev // Arduino-Ethernet API compatibility, order can be either: // mac, ip, gateway, netmask, dns (esp8266 or natural order) // mac, ip, dns, gateway, netmask (Arduino legacy) - boolean begin(const uint8_t* macAddress, const IPAddress& local_ip = IPADDR_NONE, - const IPAddress& arg1 = IPADDR_NONE, const IPAddress& arg2 = IPADDR_NONE, - const IPAddress& arg3 = IPADDR_NONE) + boolean begin(const uint8_t* macAddress, IPAddress local_ip = IPADDR_NONE, + IPAddress arg1 = IPADDR_NONE, IPAddress arg2 = IPADDR_NONE, + IPAddress arg3 = IPADDR_NONE) { + if (local_ip.isSet() && local_ip.isV4()) + { + // setting auto values using arduino ordering of parameters + if (arg1 == IPADDR_NONE) // else dns or gw + { + arg1 = local_ip; + arg1[3] = 1; + } + if (arg2 == IPADDR_NONE) // else gw or mask + { + arg2 = local_ip; + arg2[3] = 1; + } + // if arg2 is mask (esp ordering), let DNS IP unconfigured + if (arg3 == IPADDR_NONE && arg2[0] != 255) // else mask or dns + { + arg3 = IPAddress(255, 255, 255, 0); + } + } SPI4EthInit(); // Arduino Ethernet self-initializes SPI bool ret = true; if (local_ip.isSet()) @@ -67,6 +86,13 @@ class ArduinoEthernet: public LwipIntfDev return ret; } + void end() + { + ip_addr_copy(LwipIntfDev::_netif.ip_addr, + ip_addr_any); // to allow DHCP at next begin + LwipIntfDev::end(); + } + HardwareStatus hardwareStatus() const { return _hardwareStatus; @@ -77,6 +103,21 @@ class ArduinoEthernet: public LwipIntfDev return DHCP_CHECK_NONE; } + void MACAddress(uint8_t* mac) + { + LwipIntfDev::macAddress(mac); + } + + IPAddress dnsServerIP() const + { + return LwipIntfDev::dnsIP(0); + } + + void setDnsServerIP(const IPAddress dnsIP) + { + LwipIntfDev::setDNS(dnsIP); + } + protected: HardwareStatus _hardwareStatus; }; diff --git a/libraries/lwIP_PPP/examples/PPPServer/PPPServer.ino b/libraries/lwIP_PPP/examples/PPPServer/PPPServer.ino index baa499721e..da15844ff3 100644 --- a/libraries/lwIP_PPP/examples/PPPServer/PPPServer.ino +++ b/libraries/lwIP_PPP/examples/PPPServer/PPPServer.ino @@ -20,7 +20,6 @@ #include #include #include -#include #ifndef STASSID #define STASSID "your-ssid" @@ -36,8 +35,8 @@ #define RX 13 // d1mini D7 #define TX 15 // d1mini D8 -SoftwareSerial ppplink(RX, TX); -HardwareSerial& logger = Serial; +HardwareSerial& ppplink = Serial; +HardwareSerial& logger = Serial1; PPPServer ppp(&ppplink); void PPPConnectedCallback(netif* nif) { @@ -74,7 +73,8 @@ void setup() { logger.printf("\nSTA: %s (dns: %s / %s)\n", WiFi.localIP().toString().c_str(), WiFi.dnsIP(0).toString().c_str(), WiFi.dnsIP(1).toString().c_str()); ppplink.begin(PPPLINKBAUD); - ppplink.enableIntTx(true); + ppplink.swap(); // RX=GPIO13 TX=GPIO15 + logger.println(); logger.printf("\n\nhey, trying to be a PPP server here\n\n"); logger.printf("Now try this on your linux host:\n\n"); diff --git a/libraries/lwIP_enc28j60/src/utility/enc28j60.cpp b/libraries/lwIP_enc28j60/src/utility/enc28j60.cpp index 09f8ae0fe2..0ee3096486 100644 --- a/libraries/lwIP_enc28j60/src/utility/enc28j60.cpp +++ b/libraries/lwIP_enc28j60/src/utility/enc28j60.cpp @@ -398,7 +398,9 @@ bool ENC28J60::reset(void) /* Wait for OST */ PRINTF("waiting for ESTAT_CLKRDY\n"); - while ((readreg(ESTAT) & ESTAT_CLKRDY) == 0) { }; + while ((readreg(ESTAT) & ESTAT_CLKRDY) == 0) + { + }; PRINTF("ESTAT_CLKRDY\n"); setregbank(ERXTX_BANK); diff --git a/package/README.md b/package/README.md index de6f8382ab..b2d64ef76e 100644 --- a/package/README.md +++ b/package/README.md @@ -111,8 +111,8 @@ The following points assume work in a direct clone of the repository, and not in * [platform.txt](https://github.com/esp8266/Arduino/blob/master/platform.txt) and [package.json](https://github.com/esp8266/Arduino/blob/master/package.json): update `version` to the release E.g. `3.0.0`, - * [cores/esp8266/TZ.h](https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h): import the latest database with the following shell command:\ - `$ cd tools; sh TZupdate.sh` + * [cores/esp8266/TZ.h](https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h): import the latest database:\ + `$ pip install -U tzdata; python tools/format_tzdata.py --output cores/esp8266/TZ.h` * Update SSL/TLS certificates and public keys in examples:\ `$ cd tools; sh certsUpdate.sh` @@ -173,7 +173,7 @@ The following points assume work in a direct clone of the repository, and not in * [platform.txt](https://github.com/esp8266/Arduino/blob/master/platform.txt) * [package.json](https://github.com/esp8266/Arduino/blob/master/package.json) - * [TZ.h](https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h) (<= `cd tools; sh ./TZupdate.sh`) + * [TZ.h](https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h) (<= `pip install -U tzdata; python tools/format_tzdata.py --output cores/esp8266/TZ.h`) * Certificates (<= `cd tools; sh certsUpdate.sh`) - [ ] 5. Wait until the release notes have been checked by other maintainers (can be changed afterwards anyway) diff --git a/package/package_esp8266com_index.template.json b/package/package_esp8266com_index.template.json index e87c6f66ca..3c8d1bed39 100644 --- a/package/package_esp8266com_index.template.json +++ b/package/package_esp8266com_index.template.json @@ -47,6 +47,9 @@ { "name": "ESPresso Lite 2.0" }, + { + "name": "Mercury 1.0" + }, { "name": "Phoenix 1.0" }, @@ -383,4 +386,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/platform.txt b/platform.txt index 7e88e48db5..3ca4ffae29 100644 --- a/platform.txt +++ b/platform.txt @@ -62,6 +62,9 @@ build.spiffs_start= build.spiffs_end= build.spiffs_blocksize= +# soft float location +build.iramfloat=-DFP_IN_IROM + # Fully qualified file names for processing sketch global options globals.h.source.fqfn={build.source.path}/{build.project_name}.globals.h commonhfile.fqfn={build.core.path}/CommonHFile.h @@ -79,7 +82,7 @@ compiler.cpreprocessor.flags=-D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ -D_GNU_S compiler.libraries.ldflags= compiler.c.cmd=xtensa-lx106-elf-gcc -compiler.c.flags=-c "{compiler.warning_flags}-cflags" -std=gnu17 {build.stacksmash_flags} -g -free -fipa-pta -Werror=return-type -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -MMD -ffunction-sections -fdata-sections {build.exception_flags} {build.sslflags} {build.mmuflags} {build.non32xferflags} +compiler.c.flags=-c "{compiler.warning_flags}-cflags" -std=gnu17 {build.stacksmash_flags} -g -free -fipa-pta -Werror=return-type -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -MMD -ffunction-sections -fdata-sections {build.exception_flags} {build.sslflags} {build.mmuflags} {build.non32xferflags} {build.iramfloat} compiler.S.cmd=xtensa-lx106-elf-gcc compiler.S.flags=-c -g -x assembler-with-cpp -MMD -mlongcalls "-I{runtime.tools.xtensa-lx106-elf-gcc.path}/include/" @@ -90,7 +93,7 @@ compiler.c.elf.cmd=xtensa-lx106-elf-gcc compiler.c.elf.libs=-lhal -lphy -lpp -lnet80211 {build.lwip_lib} -lwpa -lcrypto -lmain -lwps -lbearssl -lespnow -lsmartconfig -lairkiss -lwpa2 {build.stdcpp_lib} -lm -lc -lgcc compiler.cpp.cmd=xtensa-lx106-elf-g++ -compiler.cpp.flags=-c "{compiler.warning_flags}-cppflags" {build.stacksmash_flags} -g -free -fipa-pta -Werror=return-type -mlongcalls -mtext-section-literals -fno-rtti -falign-functions=4 {build.stdcpp_level} -MMD -ffunction-sections -fdata-sections {build.exception_flags} {build.sslflags} {build.mmuflags} {build.non32xferflags} +compiler.cpp.flags=-c "{compiler.warning_flags}-cppflags" {build.stacksmash_flags} -g -free -fipa-pta -Werror=return-type -mlongcalls -mtext-section-literals -fno-rtti -falign-functions=4 {build.stdcpp_level} -MMD -ffunction-sections -fdata-sections {build.exception_flags} {build.sslflags} {build.mmuflags} {build.non32xferflags} {build.iramfloat} compiler.as.cmd=xtensa-lx106-elf-as @@ -128,7 +131,7 @@ recipe.hooks.prebuild.2.pattern="{runtime.tools.python3.path}/python3" -I "{runt recipe.hooks.linking.prelink.1.pattern="{runtime.tools.python3.path}/python3" -I "{runtime.tools.mkdir}" -p "{build.path}/ld_h/" recipe.hooks.linking.prelink.2.pattern="{runtime.tools.python3.path}/python3" -I "{runtime.tools.cp}" "{runtime.platform.path}/tools/sdk/ld/{build.flash_ld}" "{build.path}/ld_h/local.eagle.flash.ld.h" recipe.hooks.linking.prelink.3.pattern="{compiler.path}{compiler.c.cmd}" -CC -E -P {build.vtable_flags} {build.mmuflags} "{build.path}/ld_h/local.eagle.flash.ld.h" -o "{build.path}/local.eagle.flash.ld" -recipe.hooks.linking.prelink.4.pattern="{compiler.path}{compiler.c.cmd}" -CC -E -P {build.vtable_flags} {build.mmuflags} "{runtime.platform.path}/tools/sdk/ld/eagle.app.v6.common.ld.h" -o "{build.path}/local.eagle.app.v6.common.ld" +recipe.hooks.linking.prelink.4.pattern="{compiler.path}{compiler.c.cmd}" {build.iramfloat} -CC -E -P {build.vtable_flags} {build.mmuflags} "{runtime.platform.path}/tools/sdk/ld/eagle.app.v6.common.ld.h" -o "{build.path}/local.eagle.app.v6.common.ld" ## Compile c files recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.cpreprocessor.flags} {compiler.c.flags} -D{build.sdk}=1 -DF_CPU={build.f_cpu} {build.lwip_flags} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_BOARD="{build.board}" -DARDUINO_BOARD_ID="{_id}" {build.led} {build.flash_flags} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" diff --git a/tests/ci/build_docs.sh b/tests/ci/build_docs.sh index b26852e553..7a5ae2a632 100755 --- a/tests/ci/build_docs.sh +++ b/tests/ci/build_docs.sh @@ -5,4 +5,4 @@ set -ev root=$(git rev-parse --show-toplevel) -env SPHINXOPTS="-W" make -C $root/doc html +make SPHINXOPTS="--fail-on-warning" SPHINXBUILD="${SPHINXBUILD:?sphinx-build}" -C $root/doc html diff --git a/tests/clang-format-core.yaml b/tests/clang-format-core.yaml index 5a72d62beb..0df633d245 100644 --- a/tests/clang-format-core.yaml +++ b/tests/clang-format-core.yaml @@ -6,7 +6,6 @@ KeepEmptyLinesAtTheStartOfBlocks: false SpaceAfterTemplateKeyword: false SpaceBeforeInheritanceColon: false SpacesBeforeTrailingComments: 2 -AlignTrailingComments: true AllowShortBlocksOnASingleLine: Empty AllowShortFunctionsOnASingleLine: Empty AllowShortIfStatementsOnASingleLine: false @@ -28,3 +27,4 @@ BreakBeforeBraces: Allman IndentWidth: 4 IndentCaseLabels: false ReflowComments: false +SkipMacroDefinitionBody: true diff --git a/tests/common.sh b/tests/common.sh index 1799f7b481..f05eb6b37a 100755 --- a/tests/common.sh +++ b/tests/common.sh @@ -45,7 +45,9 @@ function skip_ino() *"/TeensySdioDemo/"* | \ *"/TeensySdioLogger/"* | \ *"/UserChipSelectFunction/"* | \ - *"/UserSPIDriver/"*) + *"/UserSPIDriver/"* | \ + *"/onewiretest/"* | \ + *"/debug/"*) return 0 ;; *"Teensy"*) diff --git a/tests/device/libraries/BSTest/src/BSTest.h b/tests/device/libraries/BSTest/src/BSTest.h index f73de3e471..ba3c9a5c0d 100644 --- a/tests/device/libraries/BSTest/src/BSTest.h +++ b/tests/device/libraries/BSTest/src/BSTest.h @@ -27,8 +27,7 @@ class TestCase public: TestCase(TestCase* prev, test_case_func_t func, const char* file, size_t line, const char* name, const char* desc) : - m_func(func), - m_file(file), m_line(line), m_name(name), m_desc(desc) + m_func(func), m_file(file), m_line(line), m_name(name), m_desc(desc) { if (prev) { diff --git a/tests/host/Makefile b/tests/host/Makefile index f819047891..97a4c671fb 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -30,6 +30,7 @@ GENHTML ?= genhtml CXXFLAGS += -std=gnu++17 CFLAGS += -std=gnu17 +# 32-bit mode is prefered, but not required ifeq ($(FORCE32),1) SIZEOFLONG = $(shell echo 'int main(){return sizeof(long);}'|$(CXX) -m32 -x c++ - -o sizeoflong 2>/dev/null && ./sizeoflong; echo $$?; rm -f sizeoflong;) ifneq ($(SIZEOFLONG),4) @@ -50,6 +51,7 @@ endif OUTPUT_BINARY := $(BINDIR)/host_tests LCOV_DIRECTORY := $(BINDIR)/../lcov +# Hide full build commands by default ifeq ($(V), 0) VERBC = @echo "C $@"; VERBCXX = @echo "C++ $@"; @@ -66,6 +68,30 @@ endif $(shell mkdir -p $(BINDIR)) +# Core files sometimes override libc functions, check when necessary to hide them +# TODO proper configure script / other build system? +ifeq (,$(wildcard $(BINDIR)/.have_strlcpy)) +$(shell printf '#include \nint main(){char a[4]{}; char b[4]{}; strlcpy(&a[0], &b[0], sizeof(a)); return 0;}\n' | \ + $(CXX) -x c++ - -o $(BINDIR)/.have_strlcpy 2>/dev/null || ( printf '#!/bin/sh\nexit 1\n' > $(BINDIR)/.have_strlcpy ; chmod +x $(BINDIR)/.have_strlcpy; )) +endif + +$(shell $(BINDIR)/.have_strlcpy) +ifneq ($(.SHELLSTATUS), 0) +FLAGS += -DSTRLCPY_MISSING +endif + +ifeq (,$(wildcard $(BINDIR)/.have_strlcat)) +$(shell printf '#include \nint main(){char a[4]{}; strlcat(&a[0], "test", sizeof(a)); return 0;}\n' | \ + $(CXX) -x c++ - -o $(BINDIR)/.have_strlcat 2>/dev/null || ( printf '#!/bin/sh\nexit 1\n' > $(BINDIR)/.have_strlcat ; chmod +x $(BINDIR)/.have_strlcat; )) +endif + +$(shell $(BINDIR)/.have_strlcat) +ifneq ($(.SHELLSTATUS), 0) +FLAGS += -DSTRLCAT_MISSING +endif + +# Actual build recipes + CORE_CPP_FILES := \ $(addprefix $(abspath $(CORE_PATH))/,\ debug.cpp \ diff --git a/tests/host/common/ArduinoCatch.hpp b/tests/host/common/ArduinoCatch.hpp index 8cb81afb7c..d30d30e4ec 100644 --- a/tests/host/common/ArduinoCatch.hpp +++ b/tests/host/common/ArduinoCatch.hpp @@ -24,13 +24,15 @@ std::ostream& operator<<(std::ostream&, const String&); -namespace Catch { +namespace Catch +{ std::string toString(const String&); template<> -struct StringMaker { +struct StringMaker +{ static std::string convert(const String&); }; -} // namespace Catch +} // namespace Catch diff --git a/tests/host/common/mock.h b/tests/host/common/mock.h index b3308282f0..344ce6b10c 100644 --- a/tests/host/common/mock.h +++ b/tests/host/common/mock.h @@ -56,18 +56,23 @@ #define D8 8 #include +#include +#include + +#include #ifdef __cplusplus extern "C" { #endif - // TODO: #include ? - char* itoa(int val, char* s, int radix); - char* ltoa(long val, char* s, int radix); - + char* utoa(unsigned value, char* result, int base); + char* itoa(int value, char* result, int base); +#ifdef STRLCAT_MISSING size_t strlcat(char* dst, const char* src, size_t size); +#endif +#ifdef STRLCPY_MISSING size_t strlcpy(char* dst, const char* src, size_t size); - +#endif #ifdef __cplusplus } #endif diff --git a/tests/host/common/noniso.c b/tests/host/common/noniso.c index 5c4e14b306..20fd3d1d5a 100644 --- a/tests/host/common/noniso.c +++ b/tests/host/common/noniso.c @@ -18,9 +18,10 @@ #include #include #include -#include "stdlib_noniso.h" -void reverse(char* begin, char* end) +#include + +static void reverse(char* begin, char* end) { char* is = begin; char* ie = end - 1; @@ -84,20 +85,3 @@ char* itoa(int value, char* result, int base) utoa(uvalue, result, base); return out; } - -int atoi(const char* s) -{ - return (int)atol(s); -} - -long atol(const char* s) -{ - char* tmp; - return strtol(s, &tmp, 10); -} - -double atof(const char* s) -{ - char* tmp; - return strtod(s, &tmp); -} diff --git a/tests/host/common/queue.h b/tests/host/common/queue.h index 0bc4ee7bd5..4919ae9fc4 100644 --- a/tests/host/common/queue.h +++ b/tests/host/common/queue.h @@ -184,7 +184,7 @@ struct name \ { \ struct type* stqh_first; /* first element */ \ - struct type** stqh_last; /* addr of last next element */ \ + struct type** stqh_last; /* addr of last next element */ \ } #define STAILQ_HEAD_INITIALIZER(head) \ @@ -371,7 +371,7 @@ struct name \ { \ struct type* tqh_first; /* first element */ \ - struct type** tqh_last; /* addr of last next element */ \ + struct type** tqh_last; /* addr of last next element */ \ } #define TAILQ_HEAD_INITIALIZER(head) \ diff --git a/tests/host/common/strl.cpp b/tests/host/common/strl.cpp index 0b0725b046..b01f6652a8 100644 --- a/tests/host/common/strl.cpp +++ b/tests/host/common/strl.cpp @@ -1,84 +1,78 @@ // https://gist.github.com/Fonger/98cc95ac39fbe1a7e4d9 -#ifndef HAVE_STRLCAT -/* - '_cups_strlcat()' - Safely concatenate two strings. -*/ - -size_t /* O - Length of string */ -strlcat(char* dst, /* O - Destination string */ - const char* src, /* I - Source string */ - size_t size) /* I - Size of destination string buffer */ +#include +#include +#include + +extern "C" { - size_t srclen; /* Length of source string */ - size_t dstlen; /* Length of destination string */ +#ifdef STRLCAT_MISSING + // '_cups_strlcat()' - Safely concatenate two strings. - /* - Figure out how much room is left... - */ + size_t /* O - Length of string */ + strlcat(char* dst, /* O - Destination string */ + const char* src, /* I - Source string */ + size_t size) /* I - Size of destination string buffer */ + { + size_t srclen; /* Length of source string */ + size_t dstlen; /* Length of destination string */ - dstlen = strlen(dst); - size -= dstlen + 1; + // Figure out how much room is left... - if (!size) - { - return (dstlen); /* No room, return immediately... */ - } + dstlen = strlen(dst); + size -= dstlen + 1; - /* - Figure out how much room is needed... - */ + if (!size) + { + return (dstlen); /* No room, return immediately... */ + } - srclen = strlen(src); + // Figure out how much room is needed... - /* - Copy the appropriate amount... - */ + srclen = strlen(src); - if (srclen > size) - { - srclen = size; + // Copy the appropriate amount... + + if (srclen > size) + { + srclen = size; + } + + memcpy(dst + dstlen, src, srclen); + dst[dstlen + srclen] = '\0'; + + return (dstlen + srclen); } +#endif /* STRLCAT_MISSING */ - memcpy(dst + dstlen, src, srclen); - dst[dstlen + srclen] = '\0'; +#ifdef STRLCPY_MISSING + // '_cups_strlcpy()' - Safely copy two strings. - return (dstlen + srclen); -} -#endif /* !HAVE_STRLCAT */ + size_t /* O - Length of string */ + strlcpy(char* dst, /* O - Destination string */ + const char* src, /* I - Source string */ + size_t size) /* I - Size of destination string buffer */ + { + size_t srclen; /* Length of source string */ -#ifndef HAVE_STRLCPY -/* - '_cups_strlcpy()' - Safely copy two strings. -*/ + // Figure out how much room is needed... -size_t /* O - Length of string */ -strlcpy(char* dst, /* O - Destination string */ - const char* src, /* I - Source string */ - size_t size) /* I - Size of destination string buffer */ -{ - size_t srclen; /* Length of source string */ + size--; - /* - Figure out how much room is needed... - */ + srclen = strlen(src); - size--; + // Copy the appropriate amount... - srclen = strlen(src); + if (srclen > size) + { + srclen = size; + } - /* - Copy the appropriate amount... - */ + memcpy(dst, src, srclen); + dst[srclen] = '\0'; - if (srclen > size) - { - srclen = size; + return (srclen); } +#endif /* STRLCPY_MISSING */ - memcpy(dst, src, srclen); - dst[srclen] = '\0'; - - return (srclen); -} -#endif /* !HAVE_STRLCPY */ +} // extern "C" diff --git a/tests/host/sys/pgmspace.h b/tests/host/sys/pgmspace.h index ef878eaaff..ac60cb15be 100644 --- a/tests/host/sys/pgmspace.h +++ b/tests/host/sys/pgmspace.h @@ -82,5 +82,6 @@ inline int vsnprintf_P(char* str, size_t size, const char* format, va_list ap) #define strncmp_P strncmp #define strncasecmp_P strncasecmp #define strcat_P strcat +#define memcmp_P memcmp #endif diff --git a/tests/restyle.py b/tests/restyle.py new file mode 100755 index 0000000000..78a8816000 --- /dev/null +++ b/tests/restyle.py @@ -0,0 +1,290 @@ +#!/usr/bin/env python + +import argparse +import os +import sys +import pathlib +import subprocess +import contextlib + +from dataclasses import dataclass + + +GIT_ROOT = pathlib.Path( + subprocess.check_output( + ["git", "rev-parse", "--show-toplevel"], universal_newlines=True + ).strip() +) + + +def clang_format(clang_format, config, files): + if not files: + raise ValueError("Files list cannot be empty") + + cmd = [clang_format, "--verbose", f"--style=file:{config.as_posix()}", "-i"] + cmd.extend(files) + + subprocess.run(cmd, check=True) + + +def ls_files(patterns): + """Git-only search, but rather poor at matching complex patterns (at least w/ <=py3.12)""" + proc = subprocess.run( + ["git", "--no-pager", "ls-files"], + capture_output=True, + check=True, + universal_newlines=True, + ) + + out = [] + for line in proc.stdout.split("\n"): + path = pathlib.Path(line.strip()) + if any(path.match(pattern) for pattern in patterns): + out.append(path) + + return out + + +def diff_lines(): + proc = subprocess.run( + ["git", "--no-pager", "diff", "--ignore-submodules"], + capture_output=True, + check=True, + universal_newlines=True, + ) + + return proc.stdout.split("\n") + + +def find_files(patterns): + """Filesystem search, matches both git and non-git files""" + return [ + file + for pattern in patterns + for file in [found for found in GIT_ROOT.rglob(pattern)] + ] + + +def find_core_files(): + """Returns a subset of Core files that should be formatted""" + return [ + file + for file in find_files( + ( + "cores/esp8266/Lwip*", + "libraries/ESP8266mDNS/**/*", + "libraries/Wire/**/*", + "libraries/lwIP*/**/*", + "cores/esp8266/debug*", + "cores/esp8266/core_esp8266_si2c*", + "cores/esp8266/StreamString*", + "cores/esp8266/StreamSend*", + "libraries/Netdump/**/*", + "tests/**/*", + ) + ) + if file.is_file() + and file.suffix in (".c", ".cpp", ".h", ".hpp") + and not GIT_ROOT / "tests/host/bin" in file.parents + and not GIT_ROOT / "tests/host/common/catch.hpp" == file + ] + + +def find_arduino_files(): + """Returns every .ino file available in the repository, excluding submodule ones""" + return [ + ino + for library in find_files(("libraries/*",)) + if library.is_dir() and not (library / ".git").exists() + for ino in library.rglob("**/*.ino") + ] + + +FILES_PRESETS = { + "core": find_core_files, + "arduino": find_arduino_files, +} + + +@dataclass +class Changed: + file: str + hunk: str + lines: list[int] + + +class Context: + def __init__(self): + self.append_hunk = False + self.deleted = False + self.file = "" + self.hunk = [] + self.markers = [] + + def reset(self): + self.__init__() + + def reset_with_line(self, line): + self.reset() + self.hunk.append(line) + + def pop(self, out, line): + if self.file and self.hunk and self.markers: + out.append( + Changed(file=self.file, hunk="\n".join(self.hunk), lines=self.markers) + ) + + self.reset_with_line(line) + + +def changed_files_for_diff(lines: list[str] | str) -> list[Changed]: + """ + Naive git-diff output parser. Generates list of objects for every file changed after clang-format. + """ + match lines: + case str(): + lines = lines.split("\n") + case list(): + pass + case _: + raise ValueError("Unknown 'lines' type, can be either list[str] or str") + + ctx = Context() + out = [] + + # TODO: pygit2? + # ref. https://github.com/cpp-linter/cpp-linter/blob/main/cpp_linter/git/__init__.py ::parse_diff + # ref. https://github.com/libgit2/pygit2/blob/master/src/diff.c ::parse_diff + for line in lines: + # '--- a/path/to/changed/file' most likely + # '--- /dev/null' aka created file. should be ignored, same as removed ones + if line.startswith("---"): + ctx.pop(out, line) + + _, file = line.split(" ") + ctx.deleted = "/dev/null" in file + + # '+++ b/path/to/changed/file' most likely + # '+++ /dev/null' aka removed file + elif not ctx.deleted and line.startswith("+++"): + ctx.hunk.append(line) + + _, file = line.split(" ") + ctx.deleted = "/dev/null" in file + if not ctx.deleted: + ctx.file = file[2:] + + # @@ from-file-line-numbers to-file-line-numbers @@ + elif not ctx.deleted and line.startswith("@@"): + ctx.hunk.append(line) + + _, _, numbers, _ = line.split(" ", 3) + if "," in numbers: + numbers, _ = numbers.split(",") # drop count + + numbers = numbers.replace("+", "") + numbers = numbers.replace("-", "") + + ctx.markers.append(int(numbers)) + ctx.append_hunk = True + + # capture diff for the summary + elif ctx.append_hunk and line.startswith(("+", "-", " ")): + ctx.hunk.append(line) + + ctx.pop(out, line) + + return out + + +def changed_files() -> list[Changed]: + return changed_files_for_diff(diff_lines()) + + +def errors_changed(changed: Changed): + all_lines = ", ".join(str(x) for x in changed.lines) + for line in changed.lines: + print( + f"::error file={changed.file},title=Run tests/restyle.sh and re-commit {changed.file},line={line}::File {changed.file} failed clang-format style check. (lines {all_lines})" + ) + + +SUMMARY_PATH = pathlib.Path(os.environ.get("GITHUB_STEP_SUMMARY", os.devnull)) +SUMMARY_OUTPUT = SUMMARY_PATH.open("a") + + +def summary_diff(changed: Changed): + with contextlib.redirect_stdout(SUMMARY_OUTPUT): + print(f"# {changed.file} (suggested change)") + print("```diff") + print(changed.hunk) + print("```") + + +def stdout_diff(): + subprocess.run(["git", "--no-pager", "diff", "--ignore-submodules"]) + + +def assert_unchanged(): + subprocess.run( + ["git", "diff", "--ignore-submodules", "--exit-code"], + check=True, + stdout=subprocess.DEVNULL, + ) + + +def run_format(args): + targets = [] + + for include in args.include: + targets.append( + (GIT_ROOT / f"tests/clang-format-{include}.yaml", FILES_PRESETS[include]()) + ) + + if not targets: + targets.append((args.config, args.files)) + + for target in targets: + clang_format(args.clang_format, *target) + + +def run_assert(args): + for changed in changed_files(): + if args.with_errors: + errors_changed(changed) + if args.with_summary: + summary_diff(changed) + + if args.with_diff: + stdout_diff() + + assert_unchanged() + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + cmd = parser.add_subparsers(required=True) + format_ = cmd.add_parser("format") + format_.set_defaults(func=run_format) + format_.add_argument("--clang-format", default="clang-format") + + fmt = format_.add_subparsers(required=True) + + preset = fmt.add_parser("preset") + preset.add_argument( + "--include", action="append", required=True, choices=tuple(FILES_PRESETS.keys()) + ) + + files = fmt.add_parser("files") + files.add_argument("--config", type=pathlib.Path, required=True) + files.add_argument("files", type=pathlib.Path, nargs="+") + + assert_ = cmd.add_parser("assert") + assert_.set_defaults(func=run_assert) + assert_.add_argument("--with-diff", action="store_true") + assert_.add_argument("--with-errors", action="store_true") + assert_.add_argument("--with-summary", action="store_true") + + args = parser.parse_args() + args.func(args) diff --git a/tests/restyle.sh b/tests/restyle.sh index fb3df24dba..3bc90e52f0 100755 --- a/tests/restyle.sh +++ b/tests/restyle.sh @@ -1,5 +1,5 @@ #!/bin/sh -# requires clang-format, git, python3 with pyyaml +# requires python3, git, and runnable clang-format (specified below) set -e -x @@ -7,60 +7,14 @@ root=$(git rev-parse --show-toplevel) test -d ${root}/cores/esp8266 test -d ${root}/libraries -# allow `env CLANG_FORMAT=clang-format-13`, or some other version -# default to v13, latest stable version from https://apt.llvm.org -CLANG_FORMAT=${CLANG_FORMAT:-clang-format-13} - -# TODO: waiting for llvm-14 to allow --style=file: -makeClangFormatStyle() { - python3 -c 'import sys,yaml; sys.stdout.write(yaml.dump(yaml.safe_load(open(sys.argv[1], "r")), default_flow_style=True)); sys.stdout.flush();' $1 -} - -######################################### -# 'all' variable should be "cores/esp8266 libraries" - -all=${1:-" -cores/esp8266/Lwip* -libraries/ESP8266mDNS -libraries/Wire -libraries/lwIP* -cores/esp8266/debug* -cores/esp8266/core_esp8266_si2c.cpp -cores/esp8266/StreamString.* -cores/esp8266/StreamSend.* -libraries/Netdump -tests -"} - -######################################### -# restyling core & libraries +# allow `env CLANG_FORMAT=clang-format-N`, or some other version +CLANG_FORMAT=${CLANG_FORMAT:-clang-format} cd $root +python $root/tests/restyle.py format --clang-format=$CLANG_FORMAT preset --include core --include arduino -style=$(makeClangFormatStyle ${root}/tests/clang-format-core.yaml) -for target in $all; do - if [ -d "$target" ]; then - find $target \ - '(' -name "*.cpp" -o -name "*.c" -o -name "*.h" ')' \ - -exec $CLANG_FORMAT --verbose --style="$style" -i {} \; - else - $CLANG_FORMAT --verbose --style="$style" -i $target - fi -done - -######################################### -# restyling arduino examples - -# TODO should not be matched, these are formatted externally -# exclude=$(git submodule --quiet foreach git rev-parse --show-toplevel | grep libraries) - -if [ -z $1 ] ; then - style=$(makeClangFormatStyle ${root}/tests/clang-format-arduino.yaml) - find libraries \ - -path libraries/ESP8266SdFat -prune -o \ - -path libraries/Ethernet -prune -o \ - -path libraries/SoftwareSerial -prune -o \ - -name '*.ino' -exec $CLANG_FORMAT --verbose --style="$style" -i {} \; +if [ "$CI" = "true" ] ; then + python $root/tests/restyle.py assert --with-summary --with-errors +else + python $root/tests/restyle.py assert --with-diff fi - -######################################### diff --git a/tests/test_restyle.py b/tests/test_restyle.py new file mode 100644 index 0000000000..7264f1c09e --- /dev/null +++ b/tests/test_restyle.py @@ -0,0 +1,182 @@ +import unittest + +from restyle import changed_files_for_diff + +# small git-diff samples from https://queirozf.com/entries/git-diff-reference-and-examples + + +class BaseTest(unittest.TestCase): + def testNewLine(self): + diff = """ +diff --git a/file.txt b/file.txt +index 257cc56..3bd1f0e 100644 +--- a/file.txt ++++ b/file.txt +@@ -1 +1,2 @@ + foo ++bar +""" + changed = changed_files_for_diff(diff) + self.assertEqual(1, len(changed)) + self.assertEqual("file.txt", changed[0].file) + self.assertEqual(1, len(changed[0].lines)) + self.assertEqual(1, changed[0].lines[0]) + + expected = """ +--- a/file.txt ++++ b/file.txt +@@ -1 +1,2 @@ + foo ++bar +""".strip() + self.assertEqual(expected, changed[0].hunk.strip()) + + def testNewLines(self): + diff = """ +diff --git a/file.txt b/file.txt +index 257cc56..3bd1f0e 100644 +--- a/file2.txt ++++ b/file2.txt +@@ -1 +1,2 @@ + foo ++bar + baz +@@ -1 +10,2 @@ + 222 +-222 + 333 +@@ -1 +100,3 @@ + aaa ++bbb ++ccc + ddd +""" + changed = changed_files_for_diff(diff) + self.assertEqual(1, len(changed)) + self.assertEqual("file2.txt", changed[0].file) + + lines = changed[0].lines + self.assertEqual(3, len(lines)) + + first, second, third = lines + self.assertEqual(1, first) + self.assertEqual(10, second) + self.assertEqual(100, third) + + expected = """ +--- a/file2.txt ++++ b/file2.txt +@@ -1 +1,2 @@ + foo ++bar + baz +@@ -1 +10,2 @@ + 222 +-222 + 333 +@@ -1 +100,3 @@ + aaa ++bbb ++ccc + ddd +""".strip() + self.assertEqual(expected, changed[0].hunk.strip()) + + def testRemovedLineAndDeletedFile(self): + diff = """ +diff --git a/file.txt b/file.txt +index 3bd1f0e..257cc56 100644 +--- a/file.txt ++++ b/file.txt +@@ -1,2 +1 @@ + foo +-bar +diff --git a/file2.txt b/file2.txt +deleted file mode 100644 +index 85553e8..0000000 +--- a/file2.txt ++++ /dev/null +@@ -1,2 +0,0 @@ +-aaaaaa +-bbbbbb +""" + changed = changed_files_for_diff(diff) + self.assertEqual(1, len(changed)) + self.assertEqual("file.txt", changed[0].file) + self.assertEqual(1, len(changed[0].lines)) + self.assertEqual(1, changed[0].lines[0]) + + expected = """ +--- a/file.txt ++++ b/file.txt +@@ -1,2 +1 @@ + foo +-bar +""".strip() + self.assertEqual(expected, changed[0].hunk.strip()) + + def testNewLineAndDeletedFile(self): + diff = """ +diff --git a/file.txt b/file.txt +index 3bd1f0e..86e041d 100644 +--- a/file.txt ++++ b/file.txt +@@ -1,2 +1,3 @@ + foo + bar ++baz +diff --git a/file2.txt b/file2.txt +deleted file mode 100644 +index 85553e8..0000000 +--- a/file2.txt ++++ /dev/null +@@ -1,2 +0,0 @@ +-aaaaaa +-bbbbbb +""" + changed = changed_files_for_diff(diff) + self.assertEqual(1, len(changed)) + self.assertEqual("file.txt", changed[0].file) + self.assertEqual(1, len(changed[0].lines)) + self.assertEqual(1, changed[0].lines[0]) + + expected = """ +--- a/file.txt ++++ b/file.txt +@@ -1,2 +1,3 @@ + foo + bar ++baz +""".strip() + self.assertEqual(expected, changed[0].hunk.strip()) + + def testDeletedFile(self): + diff = """ +diff --git a/file2.txt b/file2.txt +deleted file mode 100644 +index 85553e8..0000000 +--- a/file2.txt ++++ /dev/null +@@ -1,2 +0,0 @@ +-aaaaaa +-bbbbbb +""" + changed = changed_files_for_diff(diff) + self.assertEqual(0, len(changed)) + + def testNewFile(self): + diff = """ +diff --git a/file3.txt b/file3.txt +new file mode 100644 +index 0000000..a309e46 +--- /dev/null ++++ b/file3.txt +@@ -0,0 +1 @@ ++this is file3 +""" + changed = changed_files_for_diff(diff) + self.assertEqual(0, len(changed)) + + +if __name__ == '__main__': + unittest.main() diff --git a/tools/TZupdate.sh b/tools/TZupdate.sh deleted file mode 100755 index 3c6f41e156..0000000000 --- a/tools/TZupdate.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh - -# this shell script refreshes world timezone definitions in -# cores/esp8266/TZ.h -# -# to run it, use: -# /path/to/TZupdate.sh -# tools/TZupdate.sh -# ./TZupdate.sh - -dir=$(cd ${0%/*} 2>/dev/null; pwd) -base=${0##*/} - -csv=https://raw.githubusercontent.com/nayarsystems/posix_tz_db/master/zones.csv - -set -e - -tz_tmpdir=$(mktemp -d) -trap 'rm -r $tz_tmpdir' EXIT - -input=$tz_tmpdir/zones.csv -names=$tz_tmpdir/names.txt -values=$tz_tmpdir/values.txt - -wget -O $input $csv || curl $csv > $input - -sed -e 's/^[^,]*,//g' -e 's,^,PSTR(,g' -e 's,$,),g' < $input > $values -sed -e 's/^\([^,]*\),.*/#define TZ_\1/g' -e 's,["],,g' < $input | tr '/\-+' '_mp' > $names - -( - -cat << EOF - -// autogenerated from $csv -// by script /tools/${base} -// $(date -u) -// -// This database is autogenerated from IANA timezone database -// ${csv} -// (using https://www.iana.org/time-zones) -// and can be updated on demand in this repository -// or by yourself using the above script - -#ifndef TZDB_H -#define TZDB_H - -EOF - -paste $names $values - -cat << EOF - -#endif // TZDB_H -EOF - -) > $tz_tmpdir/TZ.h - -backup=$(date +%s) -mv ${dir}/../cores/esp8266/TZ.h ${dir}/../cores/esp8266/TZ.h.$backup -mv $tz_tmpdir/TZ.h ${dir}/../cores/esp8266/TZ.h - -cat << EOF - -Done: - '${dir}/../cores/esp8266/TZ.h' is updated - -Diff: -----8<-------8<------8<--- -$(diff -u ${dir}/../cores/esp8266/TZ.h.$backup ${dir}/../cores/esp8266/TZ.h) ---->8----->8------>8------ - -EOF diff --git a/tools/boards.txt.py b/tools/boards.txt.py index 9524bd57c2..0ccfa8f4d9 100755 --- a/tools/boards.txt.py +++ b/tools/boards.txt.py @@ -112,25 +112,30 @@ '+-----------------+------------+------------------+', '| GND | | GND |', '+-----------------+------------+------------------+', - '| TX or GPIO2\* | | RX |', + '| TX or GPIO2 | | |', + '| [#tx_or_gpio2]_ | RX | |', '+-----------------+------------+------------------+', '| RX | | TX |', '+-----------------+------------+------------------+', '| GPIO0 | PullUp | DTR |', '+-----------------+------------+------------------+', - '| Reset\* | PullUp | RTS |', + '| Reset | | |', + '| [#reset]_ | PullUp | RTS |', '+-----------------+------------+------------------+', - '| GPIO15\* | PullDown | |', + '| GPIO15 | | |', + '| [#gpio15]_ | PullDown | |', '+-----------------+------------+------------------+', - '| CH\_PD | PullUp | |', + '| CH\\_PD | | |', + '| [#ch_pd]_ | PullUp | |', '+-----------------+------------+------------------+', '', - '- Note', - '- GPIO15 is also named MTDO', - '- Reset is also named RSBT or REST (adding PullUp improves the', + '.. rubric:: Notes', + '', + '.. [#tx_or_gpio2] GPIO15 is also named MTDO', + '.. [#reset] Reset is also named RSBT or REST (adding PullUp improves the', ' stability of the module)', - '- GPIO2 is alternative TX for the boot loader mode', - '- **Directly connecting a pin to VCC or GND is not a substitute for a', + '.. [#gpio15] GPIO2 is alternative TX for the boot loader mode', + '.. [#ch_pd] **Directly connecting a pin to VCC or GND is not a substitute for a', ' PullUp or PullDown resistor, doing this can break upload management', ' and the serial console, instability has also been noted in some', ' cases.**', @@ -161,15 +166,16 @@ '+---------------+------------+------------------+', '| GPIO0 | | GND |', '+---------------+------------+------------------+', - '| Reset | | RTS\* |', + '| Reset | | RTS [#rts]_ |', '+---------------+------------+------------------+', '| GPIO15 | PullDown | |', '+---------------+------------+------------------+', - '| CH\_PD | PullUp | |', + '| CH\\_PD | PullUp | |', '+---------------+------------+------------------+', '', - '- Note', - '- if no RTS is used a manual power toggle is needed', + '.. rubric:: Notes', + '', + '.. [#rts] if no RTS is used a manual power toggle is needed', '', 'Minimal Hardware Setup for Running only', '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~', @@ -187,7 +193,7 @@ '+----------+------------+----------------+', '| GPIO15 | PullDown | |', '+----------+------------+----------------+', - '| CH\_PD | PullUp | |', + '| CH\\_PD | PullUp | |', '+----------+------------+----------------+', '', 'Minimal', @@ -249,7 +255,11 @@ 'boot mode', '~~~~~~~~~', '', - 'the first value respects the pin setup of the Pins 0, 2 and 15.', + 'the first value respects the pin setup of the Pins 0, 2 and 15', + '', + '.. code-block::', + '', + ' Number = (GPIO15 << 2) | (GPIO0 << 1) | GPIO2', '', '+----------+----------+---------+---------+-------------+', '| Number | GPIO15 | GPIO0 | GPIO2 | Mode |', @@ -271,7 +281,6 @@ '| 7 | 3.3V | 3.3V | 3.3V | SDIO |', '+----------+----------+---------+---------+-------------+', '', - 'note: - number = ((GPIO15 << 2) \| (GPIO0 << 1) \| GPIO2);', ], }), ( 'esp8285', { @@ -436,6 +445,23 @@ ], 'desc': [ 'ESPresso Lite 2.0 is an Arduino-compatible Wi-Fi development board based on an earlier V1 (beta version). Re-designed together with Cytron Technologies, the newly-revised ESPresso Lite V2.0 features the auto-load/auto-program function, eliminating the previous need to reset the board manually before flashing a new program. It also feature two user programmable side buttons and a reset button. The special distinctive features of on-board pads for I2C sensor and actuator is retained.', ] }), +( 'mercury1', { + 'name': 'Mercury 1.0', + 'opts': { + '.build.board': 'mercury', + '.build.variant': 'mercury_v1', + }, + 'macro': [ + 'resetmethod_nodemcu', + 'flashmode_dio', + 'flashfreq_40', + '4M', + ], + 'desc': [ 'Based on ESP8266, Mercury is board developed by Ralio Technologies. Board supports on motor drivers and direct-connect feature for various endpoints.', + '', + 'Product page: https://www.raliotech.com', + ], + }), ( 'phoenix_v1', { 'name': 'Phoenix 1.0', 'opts': { @@ -756,14 +782,10 @@ ], 'desc': [ 'ESPino by ThaiEasyElec using WROOM-02 module from Espressif Systems with 4 MB Flash.', '', - 'We will update an English description soon. - Product page:', - 'http://thaieasyelec.com/products/wireless-modules/wifi-modules/espino-wifi-development-board-detail.html', - '- Schematics:', - 'www.thaieasyelec.com/downloads/ETEE052/ETEE052\_ESPino\_Schematic.pdf -', - 'Dimensions:', - 'http://thaieasyelec.com/downloads/ETEE052/ETEE052\_ESPino\_Dimension.pdf', - '- Pinouts:', - 'http://thaieasyelec.com/downloads/ETEE052/ETEE052\_ESPino\_User\_Manual\_TH\_v1\_0\_20160204.pdf (Please see pg. 8)', + '* Product page (retired product): https://www.thaieasyelec.com/product/%E0%B8%A2%E0%B8%81%E0%B9%80%E0%B8%A5%E0%B8%B4%E0%B8%81%E0%B8%88%E0%B8%B3%E0%B8%AB%E0%B8%99%E0%B9%88%E0%B8%B2%E0%B8%A2-retired-espino-wifi-development-board/11000833173001086', + '* Schematics: https://downloads.thaieasyelec.com/ETEE052/ETEE052\\_ESPino\\_Schematic.pdf', + '* Dimensions: https://downloads.thaieasyelec.com/ETEE052/ETEE052\\_ESPino\\_Dimension.pdf', + '* Pinouts (Please see pg.8): https://downloads.thaieasyelec.com/ETEE052/ETEE052\\_ESPino\\_User\\_Manual\\_TH\\_v1\\_0\\_20160204.pdf', ], }), ( 'wifinfo', { @@ -1626,13 +1648,13 @@ def all_flash_map (): print("generated: flash map config file (in cores/esp8266/FlashMap.h)") return { - 'autoflash': { - '.menu.eesz.autoflash': 'Mapping defined by Hardware and Sketch', - '.menu.eesz.autoflash.build.flash_size': '16M', - '.menu.eesz.autoflash.build.flash_ld': 'eagle.flash.auto.ld', - '.menu.eesz.autoflash.build.extra_flags': '-DFLASH_MAP_SUPPORT=1', - '.menu.eesz.autoflash.upload.maximum_size': '1044464', - }, + 'autoflash': collections.OrderedDict([ + ('.menu.eesz.autoflash', 'Mapping defined by Hardware and Sketch'), + ('.menu.eesz.autoflash.build.flash_size', '16M'), + ('.menu.eesz.autoflash.build.flash_ld', 'eagle.flash.auto.ld'), + ('.menu.eesz.autoflash.build.extra_flags', '-DFLASH_MAP_SUPPORT=1'), + ('.menu.eesz.autoflash.upload.maximum_size', '1044464') + ]), '512K': f512, '1M': f1m, '2M': f2m, @@ -1682,6 +1704,17 @@ def sdk (): ################################################################ +def float_in_iram (): + return { 'iramfloat': collections.OrderedDict([ + ('.menu.iramfloat.no', 'in IROM'), + ('.menu.iramfloat.no.build.iramfloat', '-DFP_IN_IROM'), + ('.menu.iramfloat.yes', 'allowed in ISR'), + ('.menu.iramfloat.yes.build.iramfloat', '-DFP_IN_IRAM'), + ]) + } + +################################################################ + def all_boards (): if boardsgen or boardslocalgen: @@ -1709,6 +1742,7 @@ def all_boards (): macros.update(led('led', led_default, range(0,led_max+1))) macros.update(led('led216', 2, { 16 })) macros.update(sdk()) + macros.update(float_in_iram()) if boardfilteropt or excludeboards: print('#') @@ -1754,6 +1788,7 @@ def all_boards (): print('menu.stacksmash=Stack Protection') print('menu.wipe=Erase Flash') print('menu.sdk=NONOS SDK Version') + print('menu.iramfloat=Floating Point operations') print('menu.ssl=SSL Support') print('menu.mmu=MMU') print('menu.non32xfer=Non-32-Bit Access') @@ -1791,6 +1826,7 @@ def all_boards (): macrolist += speeds[default_speed] macrolist += [ 'autoflash' ] + macrolist += [ 'iramfloat' ] for block in macrolist: for optname in macros[block]: diff --git a/tools/cert.py b/tools/cert.py index 7498d5ee62..f319ef0f30 100755 --- a/tools/cert.py +++ b/tools/cert.py @@ -41,8 +41,8 @@ def printData(data, showPub = True): name = re.sub('[^a-zA-Z0-9_]', '_', cn) print('// CN: {} => name: {}'.format(cn, name)) - print('// not valid before:', xcert.not_valid_before) - print('// not valid after: ', xcert.not_valid_after) + print('// not valid before:', xcert.not_valid_before_utc) + print('// not valid after: ', xcert.not_valid_after_utc) if showPub: @@ -114,7 +114,7 @@ def main(): print() print('// this file is autogenerated - any modification will be overwritten') print('// unused symbols will not be linked in the final binary') - print('// generated on {}'.format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) + print('// generated on {}'.format(datetime.datetime.now(datetime.UTC).strftime("%Y-%m-%d %H:%M:%S"))) print('// by {}'.format(sys.argv)) print() print('#pragma once') diff --git a/tools/decoder.py b/tools/decoder.py index 1ed3dcf8ed..b1f1706767 100755 --- a/tools/decoder.py +++ b/tools/decoder.py @@ -10,6 +10,7 @@ import sys import re import subprocess +import shutil # https://github.com/me-no-dev/EspExceptionDecoder/blob/349d17e4c9896306e2c00b4932be3ba510cad208/src/EspExceptionDecoder.java#L59-L90 EXCEPTION_CODES = ( @@ -52,6 +53,7 @@ "permit stores", ) + # similar to java version, which used `list` and re-formatted it # instead, simply use an already short-format `info line` # TODO `info symbol`? revert to `list`? @@ -96,14 +98,17 @@ def addresses_addr2line(addr2line, elf, addresses): def decode_lines(format_addresses, elf, lines): - STACK_RE = re.compile(r"^[0-9a-f]{8}:\s+([0-9a-f]{8} ?)+ *$") + ANY_ADDR_RE = re.compile(r"0x[0-9a-fA-F]{8}|[0-9a-fA-F]{8}") + HEX_ADDR_RE = re.compile(r"0x[0-9a-f]{8}") - LAST_ALLOC_RE = re.compile( - r"last failed alloc call: ([0-9a-fA-F]{8})\(([0-9]+)\).*" - ) - LAST_ALLOC = "last failed alloc" + MEM_ERR_LINE_RE = re.compile(r"^(Stack|last failed alloc call)") + + STACK_LINE_RE = re.compile(r"^[0-9a-f]{8}:\s\s+") + + IGNORE_FIRMWARE_RE = re.compile(r"^(epc1=0x........, |Fatal exception )") CUT_HERE_STRING = "CUT HERE FOR EXCEPTION DECODER" + DECODE_IT = "DECODE IT" EXCEPTION_STRING = "Exception (" EPC_STRING = "epc1=" @@ -131,13 +136,13 @@ def format_address(address): stack_addresses = print_all_addresses(stack_addresses) last_stack = line.strip() # 3fffffb0: feefeffe feefeffe 3ffe85d8 401004ed - elif in_stack and STACK_RE.match(line): - stack, addrs = line.split(":") - addrs = addrs.strip() - addrs = addrs.split(" ") + elif IGNORE_FIRMWARE_RE.match(line): + continue + elif in_stack and STACK_LINE_RE.match(line): + _, addrs = line.split(":") + addrs = ANY_ADDR_RE.findall(addrs) stack_addresses.setdefault(last_stack, []) - for addr in addrs: - stack_addresses[last_stack].append(addr) + stack_addresses[last_stack].extend(addrs) # epc1=0xfffefefe epc2=0xfefefefe epc3=0xefefefef excvaddr=0xfefefefe depc=0xfefefefe elif EPC_STRING in line: pairs = line.split() @@ -152,20 +157,22 @@ def format_address(address): elif EXCEPTION_STRING in line: number = line.strip()[len(EXCEPTION_STRING) : -2] print(f"Exception ({number}) - {EXCEPTION_CODES[int(number)]}") + # stack smashing detected at # last failed alloc call: ()[@] - elif LAST_ALLOC in line: - values = LAST_ALLOC_RE.match(line) - if values: - addr, size = values.groups() - print() - print(f"Allocation of {size} bytes failed: {format_address(addr)}") + elif MEM_ERR_LINE_RE.match(line): + for addr in ANY_ADDR_RE.findall(line): + line = line.replace(addr, format_address(addr)) + print() + print(line.strip()) # postmortem guards our actual stack dump values with these elif ">>>stack>>>" in line: in_stack = True # ignore elif "<</tools/{sys.argv[0]} to update") + print() + print("#pragma once") + print() + for name, value in zones: + print(f'#define TZ_{fix_name(name)}\tPSTR("{value}")') + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument( + "--output", + type=argparse.FileType("w", encoding="utf-8"), + default=sys.stdout, + ) + parser.add_argument( + "--format", + default="header", + choices=["header", "markdown"], + ) + parser.add_argument( + "--zones", + type=argparse.FileType("r", encoding="utf-8"), + help="Zone names file, one per line", + default=os.path.join(os.path.dirname(tzdata.__file__), "zones"), + ) + parser.add_argument( + "--root", + help="Where do we get raw zoneinfo files from", + type=pathlib.Path, + ) + + args = parser.parse_args() + zones = make_zones(args) + + with contextlib.redirect_stdout(args.output): + if args.format == "markdown": + markdown(zones) + elif args.format == "header": + header(zones) diff --git a/tools/platformio-build.py b/tools/platformio-build.py index 83b7d7830a..20fe8c77fb 100644 --- a/tools/platformio-build.py +++ b/tools/platformio-build.py @@ -275,17 +275,23 @@ def scons_patched_match_splitext(path, suffixes=None): # current_vtables = None -fp_in_irom = "" +current_fp = None for d in flatten_cppdefines: if str(d).startswith("VTABLES_IN_"): current_vtables = d - if str(d) == "FP_IN_IROM": - fp_in_irom = "-DFP_IN_IROM" + if str(d).startswith("FP_IN_"): + current_fp = d + if not current_vtables: current_vtables = "VTABLES_IN_FLASH" env.Append(CPPDEFINES=[current_vtables]) assert current_vtables +if not current_fp: + current_fp = "FP_IN_IROM" + env.Append(CPPDEFINES=[current_fp]) +assert current_fp + # # MMU # @@ -363,9 +369,10 @@ def scons_patched_match_splitext(path, suffixes=None): join("$BUILD_DIR", "ld", "local.eagle.app.v6.common.ld"), join(FRAMEWORK_DIR, "tools", "sdk", "ld", "eagle.app.v6.common.ld.h"), env.VerboseAction( - "$CC -CC -E -P -D%s %s %s $SOURCE -o $TARGET" + "$CC -CC -E -P -D%s -D%s %s $SOURCE -o $TARGET" % ( current_vtables, + current_fp, # String representation of MMU flags " ".join( [ @@ -373,7 +380,6 @@ def scons_patched_match_splitext(path, suffixes=None): for f in mmu_flags ] ), - fp_in_irom, ), "Generating LD script $TARGET", ), diff --git a/tools/sdk/include/bearssl/bearssl_git.h b/tools/sdk/include/bearssl/bearssl_git.h index abdd61ac02..37fe2a0d36 100644 --- a/tools/sdk/include/bearssl/bearssl_git.h +++ b/tools/sdk/include/bearssl/bearssl_git.h @@ -1,2 +1,2 @@ // Do not edit -- Automatically generated by tools/sdk/ssl/bearssl/Makefile -#define BEARSSL_GIT b024386 +#define BEARSSL_GIT 5166f2b diff --git a/tools/sdk/include/ets_sys.h b/tools/sdk/include/ets_sys.h index 7908f127c3..a199469e0d 100644 --- a/tools/sdk/include/ets_sys.h +++ b/tools/sdk/include/ets_sys.h @@ -208,7 +208,6 @@ void *ets_memset(void *s, int c, size_t n); void ets_timer_arm_new(ETSTimer *a, int b, int c, int isMstimer); void ets_timer_setfn(ETSTimer *t, ETSTimerFunc *fn, void *parg); void ets_timer_disarm(ETSTimer *a); -int atoi(const char *nptr); int ets_strncmp(const char *s1, const char *s2, int len); int ets_strcmp(const char *s1, const char *s2); int ets_strlen(const char *s); diff --git a/tools/sdk/ld/eagle.app.v6.common.ld.h b/tools/sdk/ld/eagle.app.v6.common.ld.h index 051ce170e7..e6b415c50b 100644 --- a/tools/sdk/ld/eagle.app.v6.common.ld.h +++ b/tools/sdk/ld/eagle.app.v6.common.ld.h @@ -142,6 +142,16 @@ SECTIONS /* all functional callers are placed in IRAM (including SPI/IRQ callbacks/etc) here */ *(.text._ZNKSt8functionIF*EE*) /* std::function::operator()() const */ + +#ifdef FP_IN_IRAM + *libgcc.a:*f2.o(.literal .text) + *libgcc.a:*f3.o(.literal .text) + *libgcc.a:*fsi.o(.literal .text) + *libgcc.a:*fdi.o(.literal .text) + *libgcc.a:*ifs.o(.literal .text) + *libgcc.a:*idf.o(.literal .text) +#endif + } >iram1_0_seg :iram1_0_phdr .irom0.text : ALIGN(4) diff --git a/tools/sdk/lib/libbearssl.a b/tools/sdk/lib/libbearssl.a index 70352ab2fc..6b9a77e3f6 100644 Binary files a/tools/sdk/lib/libbearssl.a and b/tools/sdk/lib/libbearssl.a differ diff --git a/tools/sdk/lib/liblwip2-1460-feat.a b/tools/sdk/lib/liblwip2-1460-feat.a index a0eedede39..e22ff31ad7 100644 Binary files a/tools/sdk/lib/liblwip2-1460-feat.a and b/tools/sdk/lib/liblwip2-1460-feat.a differ diff --git a/tools/sdk/lib/liblwip2-1460.a b/tools/sdk/lib/liblwip2-1460.a index 61b8f7854b..3eed8274b1 100644 Binary files a/tools/sdk/lib/liblwip2-1460.a and b/tools/sdk/lib/liblwip2-1460.a differ diff --git a/tools/sdk/lib/liblwip2-536-feat.a b/tools/sdk/lib/liblwip2-536-feat.a index ec2fd58ff7..33fcdb32c5 100644 Binary files a/tools/sdk/lib/liblwip2-536-feat.a and b/tools/sdk/lib/liblwip2-536-feat.a differ diff --git a/tools/sdk/lib/liblwip2-536.a b/tools/sdk/lib/liblwip2-536.a index 801e6dabc1..41904c209a 100644 Binary files a/tools/sdk/lib/liblwip2-536.a and b/tools/sdk/lib/liblwip2-536.a differ diff --git a/tools/sdk/lib/liblwip6-1460-feat.a b/tools/sdk/lib/liblwip6-1460-feat.a index 70e5a8ae1f..9c17f87448 100644 Binary files a/tools/sdk/lib/liblwip6-1460-feat.a and b/tools/sdk/lib/liblwip6-1460-feat.a differ diff --git a/tools/sdk/lib/liblwip6-536-feat.a b/tools/sdk/lib/liblwip6-536-feat.a index 6f89478598..6a5ebbf2e4 100644 Binary files a/tools/sdk/lib/liblwip6-536-feat.a and b/tools/sdk/lib/liblwip6-536-feat.a differ diff --git a/tools/sdk/lwip2/builder b/tools/sdk/lwip2/builder index 8e3c4eec00..4087efd9d2 160000 --- a/tools/sdk/lwip2/builder +++ b/tools/sdk/lwip2/builder @@ -1 +1 @@ -Subproject commit 8e3c4eec00ec7f3962705ee095a310642953b5fb +Subproject commit 4087efd9d2a8e1cee9a159e0796d831dc1e0c497 diff --git a/tools/sdk/lwip2/include/lwip-git-hash.h b/tools/sdk/lwip2/include/lwip-git-hash.h index ee87f08b02..c8a92967ba 100644 --- a/tools/sdk/lwip2/include/lwip-git-hash.h +++ b/tools/sdk/lwip2/include/lwip-git-hash.h @@ -1,5 +1,5 @@ // generated by makefiles/make-lwip2-hash #ifndef LWIP_HASH_H #define LWIP_HASH_H -#define LWIP_HASH_STR "STABLE-2_1_3_RELEASE/glue:1.2-67-g8e3c4ee" +#define LWIP_HASH_STR "STABLE-2_1_3_RELEASE/glue:1.2-70-g4087efd" #endif // LWIP_HASH_H diff --git a/tools/sdk/lwip2/include/lwipopts.h b/tools/sdk/lwip2/include/lwipopts.h index 508245e6c0..1f05c83f9f 100644 --- a/tools/sdk/lwip2/include/lwipopts.h +++ b/tools/sdk/lwip2/include/lwipopts.h @@ -3,11 +3,10 @@ #define __CUSTOM_EXTRA_DEFINES__ #endif - #ifndef MYLWIPOPTS_H #define MYLWIPOPTS_H -// opt.h version lwip-2.1.0rc1 for esp8266 +/* opt.h version lwip-2.1.3 for esp8266 */ /** * @file @@ -996,7 +995,7 @@ #if !LWIP_IPV4 /* disable AUTOIP when IPv4 is disabled */ #undef LWIP_AUTOIP -#define LWIP_AUTOIP 0 +#define LWIP_AUTOIP 0 #endif /* !LWIP_IPV4 */ /** @@ -1564,7 +1563,7 @@ * LWIP_PBUF_REF_T: Refcount type in pbuf. * Default width of u8_t can be increased if 255 refs are not enough for you. */ -#ifndef LWIP_PBUF_REF_T +#if !defined LWIP_PBUF_REF_T || defined __DOXYGEN__ #define LWIP_PBUF_REF_T u8_t #endif @@ -2447,7 +2446,7 @@ * LWIP_IPV6_FORWARD==1: Forward IPv6 packets across netifs */ #if !defined LWIP_IPV6_FORWARD || defined __DOXYGEN__ -#define LWIP_IPV6_FORWARD 0 // 0 +#define LWIP_IPV6_FORWARD 0 #endif /** @@ -2683,7 +2682,7 @@ * servers to the DNS module. */ #if !defined LWIP_ND6_RDNSS_MAX_DNS_SERVERS || defined __DOXYGEN__ -#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0 // 0 +#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0 #endif /** * @} @@ -2722,7 +2721,7 @@ * void dhcp6_set_ntp_servers(u8_t num_ntp_servers, ip_addr_t* ntp_server_addrs); */ #if !defined LWIP_DHCP6_GET_NTP_SRV || defined __DOXYGEN__ -#define LWIP_DHCP6_GET_NTP_SRV 1 // with 1: dhcp6_set_ntp_servers() must be implemented +#define LWIP_DHCP6_GET_NTP_SRV 1 #endif /** @@ -3509,9 +3508,6 @@ #if !defined DHCP6_DEBUG || defined __DOXYGEN__ #define DHCP6_DEBUG LWIP_DBG_OFF #endif -/** - * @} - */ /** * NAPT_DEBUG: Enable debugging for NAPT. @@ -3520,6 +3516,10 @@ #define NAPT_DEBUG LWIP_DBG_OFF #endif +/** + * @} + */ + /** * LWIP_TESTMODE: Changes to make unit test possible */ @@ -3566,9 +3566,13 @@ #define PPPOS_SUPPORT IP_NAPT // because we don't have proxyarp yet #define PPP_SUPPORT PPPOS_SUPPORT #define PPP_SERVER 1 -#define PPP_DEBUG ULWIPDEBUG #define PRINTPKT_SUPPORT ULWIPDEBUG +#if ULWIPDEBUG +#define PPP_DEBUG LWIP_DBG_ON +#define PING_DEBUG LWIP_DBG_ON +#endif + #ifdef __cplusplus extern "C" { #endif @@ -3710,4 +3714,4 @@ void tcp_kill_timewait (void); } // extern "C" #endif -#endif // MYLWIPOPTS_H +#endif /* MYLWIPOPTS_H */ diff --git a/tools/sdk/ssl/bearssl b/tools/sdk/ssl/bearssl index b024386d46..5166f2bb03 160000 --- a/tools/sdk/ssl/bearssl +++ b/tools/sdk/ssl/bearssl @@ -1 +1 @@ -Subproject commit b024386d461abd1b7b9be3117e2516b7541f1201 +Subproject commit 5166f2bb03fb03597b0f2c8c7fbcf01616df67c9 diff --git a/variants/mercury_v1/pins_arduino.h b/variants/mercury_v1/pins_arduino.h new file mode 100644 index 0000000000..747afb5913 --- /dev/null +++ b/variants/mercury_v1/pins_arduino.h @@ -0,0 +1,71 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + Modified for ESP8266 platform by Ivan Grokhotkov, 2014-2015. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include "../generic/common.h" + +#define LED_BUILTIN 0 +#define BUILTIN_LED LED_BUILTIN + +#define A0 (17) + +static const uint8_t D0 = 0; +static const uint8_t D1 = 12; +static const uint8_t D2 = 4; +static const uint8_t D3 = 16; +static const uint8_t D4 = 5; +static const uint8_t D5 = 13; +static const uint8_t D6 = 15; +static const uint8_t D7 = 2; +static const uint8_t D8 = 14; +static const uint8_t D9 = 9; +static const uint8_t D10 = 10; + +#define PIN_WIRE_SDA (2) +#define PIN_WIRE_SCL (14) + +// Brushed DC Motors +#define MOTOR_1_DIR (16) +#define MOTOR_1_PWM (12) +#define MOTOR_2_DIR (5) +#define MOTOR_2_PWM (4) + +//Ultrasonic Sensor +static const uint8_t USST = D7; +static const uint8_t USSE = D8; + +//Servo +static const uint8_t SERVO1 = D4; +static const uint8_t SERVO2 = D6; +static const uint8_t SERVO3 = D3; +static const uint8_t SERVO4 = D5; + +//IR +static const uint8_t IR1 = D9; +static const uint8_t IR2 = D10; + +#endif /* Pins_Arduino_h */