diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 926cb65d8..72b03a091 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -251,9 +251,16 @@ jobs: - uses: actions/setup-python@v2 with: python-version: '3.x' + - name: Cache Linux toolchain + id: cache-linux + uses: actions/cache@v2 + with: + path: ./tools/dist + key: key-linux-toolchain - name: Boards.txt diff env: TRAVIS_BUILD_DIR: ${{ github.workspace }} TRAVIS_TAG: ${{ github.ref }} run: | bash ./tests/ci/build_boards.sh + bash ./tests/ci/eboot_test.sh diff --git a/boards.txt b/boards.txt index ba4c7e6e0..fee7b23c8 100644 --- a/boards.txt +++ b/boards.txt @@ -49,11 +49,8 @@ generic.menu.vt.heap=Heap generic.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM generic.menu.vt.iram=IRAM generic.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -generic.menu.exception.legacy=Legacy (new can return nullptr) -generic.menu.exception.legacy.build.exception_flags=-fno-exceptions -generic.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -generic.menu.exception.disabled=Disabled (new can abort) -generic.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +generic.menu.exception.disabled=Disabled (new aborts on oom) +generic.menu.exception.disabled.build.exception_flags=-fno-exceptions generic.menu.exception.disabled.build.stdcpp_lib=-lstdc++ generic.menu.exception.enabled=Enabled generic.menu.exception.enabled.build.exception_flags=-fexceptions @@ -521,11 +518,8 @@ esp8285.menu.vt.heap=Heap esp8285.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM esp8285.menu.vt.iram=IRAM esp8285.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -esp8285.menu.exception.legacy=Legacy (new can return nullptr) -esp8285.menu.exception.legacy.build.exception_flags=-fno-exceptions -esp8285.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -esp8285.menu.exception.disabled=Disabled (new can abort) -esp8285.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +esp8285.menu.exception.disabled=Disabled (new aborts on oom) +esp8285.menu.exception.disabled.build.exception_flags=-fno-exceptions esp8285.menu.exception.disabled.build.stdcpp_lib=-lstdc++ esp8285.menu.exception.enabled=Enabled esp8285.menu.exception.enabled.build.exception_flags=-fexceptions @@ -718,6 +712,18 @@ esp8285.menu.led.15=15 esp8285.menu.led.15.build.led=-DLED_BUILTIN=15 esp8285.menu.led.16=16 esp8285.menu.led.16.build.led=-DLED_BUILTIN=16 +esp8285.menu.sdk.nonosdk_190703=nonos-sdk 2.2.1+100 (190703) +esp8285.menu.sdk.nonosdk_190703.build.sdk=NONOSDK22x_190703 +esp8285.menu.sdk.nonosdk_191122=nonos-sdk 2.2.1+119 (191122) +esp8285.menu.sdk.nonosdk_191122.build.sdk=NONOSDK22x_191122 +esp8285.menu.sdk.nonosdk_191105=nonos-sdk 2.2.1+113 (191105) +esp8285.menu.sdk.nonosdk_191105.build.sdk=NONOSDK22x_191105 +esp8285.menu.sdk.nonosdk_191024=nonos-sdk 2.2.1+111 (191024) +esp8285.menu.sdk.nonosdk_191024.build.sdk=NONOSDK22x_191024 +esp8285.menu.sdk.nonosdk221=nonos-sdk 2.2.1 (legacy) +esp8285.menu.sdk.nonosdk221.build.sdk=NONOSDK221 +esp8285.menu.sdk.nonosdk3v0=nonos-sdk pre-3 (180626 known issues) +esp8285.menu.sdk.nonosdk3v0.build.sdk=NONOSDK3V0 esp8285.menu.ip.lm2f=v2 Lower Memory esp8285.menu.ip.lm2f.build.lwip_include=lwip2/include esp8285.menu.ip.lm2f.build.lwip_lib=-llwip2-536-feat @@ -859,11 +865,8 @@ espduino.menu.vt.heap=Heap espduino.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM espduino.menu.vt.iram=IRAM espduino.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -espduino.menu.exception.legacy=Legacy (new can return nullptr) -espduino.menu.exception.legacy.build.exception_flags=-fno-exceptions -espduino.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -espduino.menu.exception.disabled=Disabled (new can abort) -espduino.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +espduino.menu.exception.disabled=Disabled (new aborts on oom) +espduino.menu.exception.disabled.build.exception_flags=-fno-exceptions espduino.menu.exception.disabled.build.stdcpp_lib=-lstdc++ espduino.menu.exception.enabled=Enabled espduino.menu.exception.enabled.build.exception_flags=-fexceptions @@ -1048,11 +1051,8 @@ huzzah.menu.vt.heap=Heap huzzah.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM huzzah.menu.vt.iram=IRAM huzzah.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -huzzah.menu.exception.legacy=Legacy (new can return nullptr) -huzzah.menu.exception.legacy.build.exception_flags=-fno-exceptions -huzzah.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -huzzah.menu.exception.disabled=Disabled (new can abort) -huzzah.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +huzzah.menu.exception.disabled=Disabled (new aborts on oom) +huzzah.menu.exception.disabled.build.exception_flags=-fno-exceptions huzzah.menu.exception.disabled.build.stdcpp_lib=-lstdc++ huzzah.menu.exception.enabled=Enabled huzzah.menu.exception.enabled.build.exception_flags=-fexceptions @@ -1238,11 +1238,8 @@ inventone.menu.vt.heap=Heap inventone.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM inventone.menu.vt.iram=IRAM inventone.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -inventone.menu.exception.legacy=Legacy (new can return nullptr) -inventone.menu.exception.legacy.build.exception_flags=-fno-exceptions -inventone.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -inventone.menu.exception.disabled=Disabled (new can abort) -inventone.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +inventone.menu.exception.disabled=Disabled (new aborts on oom) +inventone.menu.exception.disabled.build.exception_flags=-fno-exceptions inventone.menu.exception.disabled.build.stdcpp_lib=-lstdc++ inventone.menu.exception.enabled=Enabled inventone.menu.exception.enabled.build.exception_flags=-fexceptions @@ -1428,11 +1425,8 @@ cw01.menu.vt.heap=Heap cw01.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM cw01.menu.vt.iram=IRAM cw01.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -cw01.menu.exception.legacy=Legacy (new can return nullptr) -cw01.menu.exception.legacy.build.exception_flags=-fno-exceptions -cw01.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -cw01.menu.exception.disabled=Disabled (new can abort) -cw01.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +cw01.menu.exception.disabled=Disabled (new aborts on oom) +cw01.menu.exception.disabled.build.exception_flags=-fno-exceptions cw01.menu.exception.disabled.build.stdcpp_lib=-lstdc++ cw01.menu.exception.enabled=Enabled cw01.menu.exception.enabled.build.exception_flags=-fexceptions @@ -1621,11 +1615,8 @@ espresso_lite_v1.menu.vt.heap=Heap espresso_lite_v1.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM espresso_lite_v1.menu.vt.iram=IRAM espresso_lite_v1.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -espresso_lite_v1.menu.exception.legacy=Legacy (new can return nullptr) -espresso_lite_v1.menu.exception.legacy.build.exception_flags=-fno-exceptions -espresso_lite_v1.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -espresso_lite_v1.menu.exception.disabled=Disabled (new can abort) -espresso_lite_v1.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +espresso_lite_v1.menu.exception.disabled=Disabled (new aborts on oom) +espresso_lite_v1.menu.exception.disabled.build.exception_flags=-fno-exceptions espresso_lite_v1.menu.exception.disabled.build.stdcpp_lib=-lstdc++ espresso_lite_v1.menu.exception.enabled=Enabled espresso_lite_v1.menu.exception.enabled.build.exception_flags=-fexceptions @@ -1814,11 +1805,8 @@ espresso_lite_v2.menu.vt.heap=Heap espresso_lite_v2.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM espresso_lite_v2.menu.vt.iram=IRAM espresso_lite_v2.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -espresso_lite_v2.menu.exception.legacy=Legacy (new can return nullptr) -espresso_lite_v2.menu.exception.legacy.build.exception_flags=-fno-exceptions -espresso_lite_v2.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -espresso_lite_v2.menu.exception.disabled=Disabled (new can abort) -espresso_lite_v2.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +espresso_lite_v2.menu.exception.disabled=Disabled (new aborts on oom) +espresso_lite_v2.menu.exception.disabled.build.exception_flags=-fno-exceptions espresso_lite_v2.menu.exception.disabled.build.stdcpp_lib=-lstdc++ espresso_lite_v2.menu.exception.enabled=Enabled espresso_lite_v2.menu.exception.enabled.build.exception_flags=-fexceptions @@ -2007,11 +1995,8 @@ phoenix_v1.menu.vt.heap=Heap phoenix_v1.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM phoenix_v1.menu.vt.iram=IRAM phoenix_v1.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -phoenix_v1.menu.exception.legacy=Legacy (new can return nullptr) -phoenix_v1.menu.exception.legacy.build.exception_flags=-fno-exceptions -phoenix_v1.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -phoenix_v1.menu.exception.disabled=Disabled (new can abort) -phoenix_v1.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +phoenix_v1.menu.exception.disabled=Disabled (new aborts on oom) +phoenix_v1.menu.exception.disabled.build.exception_flags=-fno-exceptions phoenix_v1.menu.exception.disabled.build.stdcpp_lib=-lstdc++ phoenix_v1.menu.exception.enabled=Enabled phoenix_v1.menu.exception.enabled.build.exception_flags=-fexceptions @@ -2200,11 +2185,8 @@ phoenix_v2.menu.vt.heap=Heap phoenix_v2.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM phoenix_v2.menu.vt.iram=IRAM phoenix_v2.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -phoenix_v2.menu.exception.legacy=Legacy (new can return nullptr) -phoenix_v2.menu.exception.legacy.build.exception_flags=-fno-exceptions -phoenix_v2.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -phoenix_v2.menu.exception.disabled=Disabled (new can abort) -phoenix_v2.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +phoenix_v2.menu.exception.disabled=Disabled (new aborts on oom) +phoenix_v2.menu.exception.disabled.build.exception_flags=-fno-exceptions phoenix_v2.menu.exception.disabled.build.stdcpp_lib=-lstdc++ phoenix_v2.menu.exception.enabled=Enabled phoenix_v2.menu.exception.enabled.build.exception_flags=-fexceptions @@ -2393,11 +2375,8 @@ nodemcu.menu.vt.heap=Heap nodemcu.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM nodemcu.menu.vt.iram=IRAM nodemcu.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -nodemcu.menu.exception.legacy=Legacy (new can return nullptr) -nodemcu.menu.exception.legacy.build.exception_flags=-fno-exceptions -nodemcu.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -nodemcu.menu.exception.disabled=Disabled (new can abort) -nodemcu.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +nodemcu.menu.exception.disabled=Disabled (new aborts on oom) +nodemcu.menu.exception.disabled.build.exception_flags=-fno-exceptions nodemcu.menu.exception.disabled.build.stdcpp_lib=-lstdc++ nodemcu.menu.exception.enabled=Enabled nodemcu.menu.exception.enabled.build.exception_flags=-fexceptions @@ -2583,11 +2562,8 @@ nodemcuv2.menu.vt.heap=Heap nodemcuv2.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM nodemcuv2.menu.vt.iram=IRAM nodemcuv2.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -nodemcuv2.menu.exception.legacy=Legacy (new can return nullptr) -nodemcuv2.menu.exception.legacy.build.exception_flags=-fno-exceptions -nodemcuv2.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -nodemcuv2.menu.exception.disabled=Disabled (new can abort) -nodemcuv2.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +nodemcuv2.menu.exception.disabled=Disabled (new aborts on oom) +nodemcuv2.menu.exception.disabled.build.exception_flags=-fno-exceptions nodemcuv2.menu.exception.disabled.build.stdcpp_lib=-lstdc++ nodemcuv2.menu.exception.enabled=Enabled nodemcuv2.menu.exception.enabled.build.exception_flags=-fexceptions @@ -2777,11 +2753,8 @@ modwifi.menu.vt.heap=Heap modwifi.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM modwifi.menu.vt.iram=IRAM modwifi.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -modwifi.menu.exception.legacy=Legacy (new can return nullptr) -modwifi.menu.exception.legacy.build.exception_flags=-fno-exceptions -modwifi.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -modwifi.menu.exception.disabled=Disabled (new can abort) -modwifi.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +modwifi.menu.exception.disabled=Disabled (new aborts on oom) +modwifi.menu.exception.disabled.build.exception_flags=-fno-exceptions modwifi.menu.exception.disabled.build.stdcpp_lib=-lstdc++ modwifi.menu.exception.enabled=Enabled modwifi.menu.exception.enabled.build.exception_flags=-fexceptions @@ -2987,11 +2960,8 @@ thing.menu.vt.heap=Heap thing.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM thing.menu.vt.iram=IRAM thing.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -thing.menu.exception.legacy=Legacy (new can return nullptr) -thing.menu.exception.legacy.build.exception_flags=-fno-exceptions -thing.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -thing.menu.exception.disabled=Disabled (new can abort) -thing.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +thing.menu.exception.disabled=Disabled (new aborts on oom) +thing.menu.exception.disabled.build.exception_flags=-fno-exceptions thing.menu.exception.disabled.build.stdcpp_lib=-lstdc++ thing.menu.exception.enabled=Enabled thing.menu.exception.enabled.build.exception_flags=-fexceptions @@ -3177,11 +3147,8 @@ thingdev.menu.vt.heap=Heap thingdev.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM thingdev.menu.vt.iram=IRAM thingdev.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -thingdev.menu.exception.legacy=Legacy (new can return nullptr) -thingdev.menu.exception.legacy.build.exception_flags=-fno-exceptions -thingdev.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -thingdev.menu.exception.disabled=Disabled (new can abort) -thingdev.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +thingdev.menu.exception.disabled=Disabled (new aborts on oom) +thingdev.menu.exception.disabled.build.exception_flags=-fno-exceptions thingdev.menu.exception.disabled.build.stdcpp_lib=-lstdc++ thingdev.menu.exception.enabled=Enabled thingdev.menu.exception.enabled.build.exception_flags=-fexceptions @@ -3367,11 +3334,8 @@ blynk.menu.vt.heap=Heap blynk.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM blynk.menu.vt.iram=IRAM blynk.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -blynk.menu.exception.legacy=Legacy (new can return nullptr) -blynk.menu.exception.legacy.build.exception_flags=-fno-exceptions -blynk.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -blynk.menu.exception.disabled=Disabled (new can abort) -blynk.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +blynk.menu.exception.disabled=Disabled (new aborts on oom) +blynk.menu.exception.disabled.build.exception_flags=-fno-exceptions blynk.menu.exception.disabled.build.stdcpp_lib=-lstdc++ blynk.menu.exception.enabled=Enabled blynk.menu.exception.enabled.build.exception_flags=-fexceptions @@ -3557,11 +3521,8 @@ esp210.menu.vt.heap=Heap esp210.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM esp210.menu.vt.iram=IRAM esp210.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -esp210.menu.exception.legacy=Legacy (new can return nullptr) -esp210.menu.exception.legacy.build.exception_flags=-fno-exceptions -esp210.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -esp210.menu.exception.disabled=Disabled (new can abort) -esp210.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +esp210.menu.exception.disabled=Disabled (new aborts on oom) +esp210.menu.exception.disabled.build.exception_flags=-fno-exceptions esp210.menu.exception.disabled.build.stdcpp_lib=-lstdc++ esp210.menu.exception.enabled=Enabled esp210.menu.exception.enabled.build.exception_flags=-fexceptions @@ -3747,11 +3708,8 @@ d1_mini.menu.vt.heap=Heap d1_mini.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM d1_mini.menu.vt.iram=IRAM d1_mini.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -d1_mini.menu.exception.legacy=Legacy (new can return nullptr) -d1_mini.menu.exception.legacy.build.exception_flags=-fno-exceptions -d1_mini.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -d1_mini.menu.exception.disabled=Disabled (new can abort) -d1_mini.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +d1_mini.menu.exception.disabled=Disabled (new aborts on oom) +d1_mini.menu.exception.disabled.build.exception_flags=-fno-exceptions d1_mini.menu.exception.disabled.build.stdcpp_lib=-lstdc++ d1_mini.menu.exception.enabled=Enabled d1_mini.menu.exception.enabled.build.exception_flags=-fexceptions @@ -3937,11 +3895,8 @@ d1_mini_pro.menu.vt.heap=Heap d1_mini_pro.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM d1_mini_pro.menu.vt.iram=IRAM d1_mini_pro.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -d1_mini_pro.menu.exception.legacy=Legacy (new can return nullptr) -d1_mini_pro.menu.exception.legacy.build.exception_flags=-fno-exceptions -d1_mini_pro.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -d1_mini_pro.menu.exception.disabled=Disabled (new can abort) -d1_mini_pro.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +d1_mini_pro.menu.exception.disabled=Disabled (new aborts on oom) +d1_mini_pro.menu.exception.disabled.build.exception_flags=-fno-exceptions d1_mini_pro.menu.exception.disabled.build.stdcpp_lib=-lstdc++ d1_mini_pro.menu.exception.enabled=Enabled d1_mini_pro.menu.exception.enabled.build.exception_flags=-fexceptions @@ -4110,11 +4065,8 @@ d1_mini_lite.menu.vt.heap=Heap d1_mini_lite.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM d1_mini_lite.menu.vt.iram=IRAM d1_mini_lite.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -d1_mini_lite.menu.exception.legacy=Legacy (new can return nullptr) -d1_mini_lite.menu.exception.legacy.build.exception_flags=-fno-exceptions -d1_mini_lite.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -d1_mini_lite.menu.exception.disabled=Disabled (new can abort) -d1_mini_lite.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +d1_mini_lite.menu.exception.disabled=Disabled (new aborts on oom) +d1_mini_lite.menu.exception.disabled.build.exception_flags=-fno-exceptions d1_mini_lite.menu.exception.disabled.build.stdcpp_lib=-lstdc++ d1_mini_lite.menu.exception.enabled=Enabled d1_mini_lite.menu.exception.enabled.build.exception_flags=-fexceptions @@ -4340,11 +4292,8 @@ d1.menu.vt.heap=Heap d1.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM d1.menu.vt.iram=IRAM d1.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -d1.menu.exception.legacy=Legacy (new can return nullptr) -d1.menu.exception.legacy.build.exception_flags=-fno-exceptions -d1.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -d1.menu.exception.disabled=Disabled (new can abort) -d1.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +d1.menu.exception.disabled=Disabled (new aborts on oom) +d1.menu.exception.disabled.build.exception_flags=-fno-exceptions d1.menu.exception.disabled.build.stdcpp_lib=-lstdc++ d1.menu.exception.enabled=Enabled d1.menu.exception.enabled.build.exception_flags=-fexceptions @@ -4530,11 +4479,8 @@ espino.menu.vt.heap=Heap espino.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM espino.menu.vt.iram=IRAM espino.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -espino.menu.exception.legacy=Legacy (new can return nullptr) -espino.menu.exception.legacy.build.exception_flags=-fno-exceptions -espino.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -espino.menu.exception.disabled=Disabled (new can abort) -espino.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +espino.menu.exception.disabled=Disabled (new aborts on oom) +espino.menu.exception.disabled.build.exception_flags=-fno-exceptions espino.menu.exception.disabled.build.stdcpp_lib=-lstdc++ espino.menu.exception.enabled=Enabled espino.menu.exception.enabled.build.exception_flags=-fexceptions @@ -4723,11 +4669,8 @@ espinotee.menu.vt.heap=Heap espinotee.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM espinotee.menu.vt.iram=IRAM espinotee.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -espinotee.menu.exception.legacy=Legacy (new can return nullptr) -espinotee.menu.exception.legacy.build.exception_flags=-fno-exceptions -espinotee.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -espinotee.menu.exception.disabled=Disabled (new can abort) -espinotee.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +espinotee.menu.exception.disabled=Disabled (new aborts on oom) +espinotee.menu.exception.disabled.build.exception_flags=-fno-exceptions espinotee.menu.exception.disabled.build.stdcpp_lib=-lstdc++ espinotee.menu.exception.enabled=Enabled espinotee.menu.exception.enabled.build.exception_flags=-fexceptions @@ -4930,11 +4873,8 @@ wifinfo.menu.vt.heap=Heap wifinfo.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM wifinfo.menu.vt.iram=IRAM wifinfo.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -wifinfo.menu.exception.legacy=Legacy (new can return nullptr) -wifinfo.menu.exception.legacy.build.exception_flags=-fno-exceptions -wifinfo.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -wifinfo.menu.exception.disabled=Disabled (new can abort) -wifinfo.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +wifinfo.menu.exception.disabled=Disabled (new aborts on oom) +wifinfo.menu.exception.disabled.build.exception_flags=-fno-exceptions wifinfo.menu.exception.disabled.build.stdcpp_lib=-lstdc++ wifinfo.menu.exception.enabled=Enabled wifinfo.menu.exception.enabled.build.exception_flags=-fexceptions @@ -5179,11 +5119,8 @@ arduino-esp8266.menu.vt.heap=Heap arduino-esp8266.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM arduino-esp8266.menu.vt.iram=IRAM arduino-esp8266.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -arduino-esp8266.menu.exception.legacy=Legacy (new can return nullptr) -arduino-esp8266.menu.exception.legacy.build.exception_flags=-fno-exceptions -arduino-esp8266.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -arduino-esp8266.menu.exception.disabled=Disabled (new can abort) -arduino-esp8266.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +arduino-esp8266.menu.exception.disabled=Disabled (new aborts on oom) +arduino-esp8266.menu.exception.disabled.build.exception_flags=-fno-exceptions arduino-esp8266.menu.exception.disabled.build.stdcpp_lib=-lstdc++ arduino-esp8266.menu.exception.enabled=Enabled arduino-esp8266.menu.exception.enabled.build.exception_flags=-fexceptions @@ -5370,11 +5307,8 @@ gen4iod.menu.vt.heap=Heap gen4iod.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM gen4iod.menu.vt.iram=IRAM gen4iod.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -gen4iod.menu.exception.legacy=Legacy (new can return nullptr) -gen4iod.menu.exception.legacy.build.exception_flags=-fno-exceptions -gen4iod.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -gen4iod.menu.exception.disabled=Disabled (new can abort) -gen4iod.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +gen4iod.menu.exception.disabled=Disabled (new aborts on oom) +gen4iod.menu.exception.disabled.build.exception_flags=-fno-exceptions gen4iod.menu.exception.disabled.build.stdcpp_lib=-lstdc++ gen4iod.menu.exception.enabled=Enabled gen4iod.menu.exception.enabled.build.exception_flags=-fexceptions @@ -5628,11 +5562,8 @@ oak.menu.vt.heap=Heap oak.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM oak.menu.vt.iram=IRAM oak.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -oak.menu.exception.legacy=Legacy (new can return nullptr) -oak.menu.exception.legacy.build.exception_flags=-fno-exceptions -oak.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -oak.menu.exception.disabled=Disabled (new can abort) -oak.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +oak.menu.exception.disabled=Disabled (new aborts on oom) +oak.menu.exception.disabled.build.exception_flags=-fno-exceptions oak.menu.exception.disabled.build.stdcpp_lib=-lstdc++ oak.menu.exception.enabled=Enabled oak.menu.exception.enabled.build.exception_flags=-fexceptions @@ -5818,11 +5749,8 @@ wifiduino.menu.vt.heap=Heap wifiduino.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM wifiduino.menu.vt.iram=IRAM wifiduino.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -wifiduino.menu.exception.legacy=Legacy (new can return nullptr) -wifiduino.menu.exception.legacy.build.exception_flags=-fno-exceptions -wifiduino.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -wifiduino.menu.exception.disabled=Disabled (new can abort) -wifiduino.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +wifiduino.menu.exception.disabled=Disabled (new aborts on oom) +wifiduino.menu.exception.disabled.build.exception_flags=-fno-exceptions wifiduino.menu.exception.disabled.build.stdcpp_lib=-lstdc++ wifiduino.menu.exception.enabled=Enabled wifiduino.menu.exception.enabled.build.exception_flags=-fexceptions @@ -6008,11 +5936,8 @@ wifi_slot.menu.vt.heap=Heap wifi_slot.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM wifi_slot.menu.vt.iram=IRAM wifi_slot.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -wifi_slot.menu.exception.legacy=Legacy (new can return nullptr) -wifi_slot.menu.exception.legacy.build.exception_flags=-fno-exceptions -wifi_slot.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -wifi_slot.menu.exception.disabled=Disabled (new can abort) -wifi_slot.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +wifi_slot.menu.exception.disabled=Disabled (new aborts on oom) +wifi_slot.menu.exception.disabled.build.exception_flags=-fno-exceptions wifi_slot.menu.exception.disabled.build.stdcpp_lib=-lstdc++ wifi_slot.menu.exception.enabled=Enabled wifi_slot.menu.exception.enabled.build.exception_flags=-fexceptions @@ -6312,11 +6237,8 @@ wiolink.menu.vt.heap=Heap wiolink.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM wiolink.menu.vt.iram=IRAM wiolink.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -wiolink.menu.exception.legacy=Legacy (new can return nullptr) -wiolink.menu.exception.legacy.build.exception_flags=-fno-exceptions -wiolink.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -wiolink.menu.exception.disabled=Disabled (new can abort) -wiolink.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +wiolink.menu.exception.disabled=Disabled (new aborts on oom) +wiolink.menu.exception.disabled.build.exception_flags=-fno-exceptions wiolink.menu.exception.disabled.build.stdcpp_lib=-lstdc++ wiolink.menu.exception.enabled=Enabled wiolink.menu.exception.enabled.build.exception_flags=-fexceptions @@ -6502,11 +6424,8 @@ espectro.menu.vt.heap=Heap espectro.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM espectro.menu.vt.iram=IRAM espectro.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -espectro.menu.exception.legacy=Legacy (new can return nullptr) -espectro.menu.exception.legacy.build.exception_flags=-fno-exceptions -espectro.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -espectro.menu.exception.disabled=Disabled (new can abort) -espectro.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +espectro.menu.exception.disabled=Disabled (new aborts on oom) +espectro.menu.exception.disabled.build.exception_flags=-fno-exceptions espectro.menu.exception.disabled.build.stdcpp_lib=-lstdc++ espectro.menu.exception.enabled=Enabled espectro.menu.exception.enabled.build.exception_flags=-fexceptions @@ -6692,11 +6611,8 @@ eduinowifi.menu.vt.heap=Heap eduinowifi.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM eduinowifi.menu.vt.iram=IRAM eduinowifi.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -eduinowifi.menu.exception.legacy=Legacy (new can return nullptr) -eduinowifi.menu.exception.legacy.build.exception_flags=-fno-exceptions -eduinowifi.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -eduinowifi.menu.exception.disabled=Disabled (new can abort) -eduinowifi.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +eduinowifi.menu.exception.disabled=Disabled (new aborts on oom) +eduinowifi.menu.exception.disabled.build.exception_flags=-fno-exceptions eduinowifi.menu.exception.disabled.build.stdcpp_lib=-lstdc++ eduinowifi.menu.exception.enabled=Enabled eduinowifi.menu.exception.enabled.build.exception_flags=-fexceptions @@ -6892,11 +6808,8 @@ sonoff.menu.vt.heap=Heap sonoff.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM sonoff.menu.vt.iram=IRAM sonoff.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -sonoff.menu.exception.legacy=Legacy (new can return nullptr) -sonoff.menu.exception.legacy.build.exception_flags=-fno-exceptions -sonoff.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -sonoff.menu.exception.disabled=Disabled (new can abort) -sonoff.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +sonoff.menu.exception.disabled=Disabled (new aborts on oom) +sonoff.menu.exception.disabled.build.exception_flags=-fno-exceptions sonoff.menu.exception.disabled.build.stdcpp_lib=-lstdc++ sonoff.menu.exception.enabled=Enabled sonoff.menu.exception.enabled.build.exception_flags=-fexceptions @@ -7123,11 +7036,8 @@ espmxdevkit.menu.vt.heap=Heap espmxdevkit.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM espmxdevkit.menu.vt.iram=IRAM espmxdevkit.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM -espmxdevkit.menu.exception.legacy=Legacy (new can return nullptr) -espmxdevkit.menu.exception.legacy.build.exception_flags=-fno-exceptions -espmxdevkit.menu.exception.legacy.build.stdcpp_lib=-lstdc++ -espmxdevkit.menu.exception.disabled=Disabled (new can abort) -espmxdevkit.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +espmxdevkit.menu.exception.disabled=Disabled (new aborts on oom) +espmxdevkit.menu.exception.disabled.build.exception_flags=-fno-exceptions espmxdevkit.menu.exception.disabled.build.stdcpp_lib=-lstdc++ espmxdevkit.menu.exception.enabled=Enabled espmxdevkit.menu.exception.enabled.build.exception_flags=-fexceptions diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp index 80d969e40..e3dae810a 100644 --- a/cores/esp8266/Esp.cpp +++ b/cores/esp8266/Esp.cpp @@ -264,13 +264,6 @@ uint8_t EspClass::getBootMode(void) return system_get_boot_mode(); } -#ifndef F_CPU -uint8_t EspClass::getCpuFreqMHz(void) -{ - return system_get_cpu_freq(); -} -#endif - uint32_t EspClass::getFlashChipId(void) { static uint32_t flash_chip_id = 0; @@ -740,17 +733,17 @@ String EspClass::getSketchMD5() } uint32_t lengthLeft = getSketchSize(); const size_t bufSize = 512; - std::unique_ptr buf(new uint8_t[bufSize]); + std::unique_ptr buf(new (std::nothrow) uint8_t[bufSize]); uint32_t offset = 0; if(!buf.get()) { - return String(); + return emptyString; } MD5Builder md5; md5.begin(); while( lengthLeft > 0) { size_t readBytes = (lengthLeft < bufSize) ? lengthLeft : bufSize; if (!flashRead(offset, reinterpret_cast(buf.get()), (readBytes + 3) & ~3)) { - return String(); + return emptyString; } md5.add(buf.get(), readBytes); lengthLeft -= readBytes; diff --git a/cores/esp8266/Esp.h b/cores/esp8266/Esp.h index b3e187fc5..c321db382 100644 --- a/cores/esp8266/Esp.h +++ b/cores/esp8266/Esp.h @@ -122,16 +122,12 @@ class EspClass { uint8_t getBootMode(); #if defined(F_CPU) || defined(CORE_MOCK) - constexpr uint8_t getCpuFreqMHz() const - { - return esp_get_cpu_freq_mhz(); - } -#else - uint8_t getCpuFreqMHz() const - { - return esp_get_cpu_freq_mhz(); - } + constexpr #endif + inline uint8_t getCpuFreqMHz() const __attribute__((always_inline)) + { + return esp_get_cpu_freq_mhz(); + } uint32_t getFlashChipId(); uint8_t getFlashChipVendorId(); @@ -170,21 +166,15 @@ class EspClass { uint8_t *random(uint8_t *resultArray, const size_t outputSizeBytes) const; uint32_t random() const; -#ifndef CORE_MOCK - inline uint32_t getCycleCount() __attribute__((always_inline)); +#if !defined(CORE_MOCK) + inline uint32_t getCycleCount() __attribute__((always_inline)) + { + return esp_get_cycle_count(); + } #else uint32_t getCycleCount(); -#endif -}; - -#ifndef CORE_MOCK - -uint32_t EspClass::getCycleCount() -{ - return esp_get_cycle_count(); -} - #endif // !defined(CORE_MOCK) +}; extern EspClass ESP; diff --git a/cores/esp8266/Print.cpp b/cores/esp8266/Print.cpp index d93293ee8..b0e2e31a1 100644 --- a/cores/esp8266/Print.cpp +++ b/cores/esp8266/Print.cpp @@ -63,7 +63,7 @@ size_t Print::printf(const char *format, ...) { size_t len = vsnprintf(temp, sizeof(temp), format, arg); va_end(arg); if (len > sizeof(temp) - 1) { - buffer = new char[len + 1]; + buffer = new (std::nothrow) char[len + 1]; if (!buffer) { return 0; } @@ -86,7 +86,7 @@ size_t Print::printf_P(PGM_P format, ...) { size_t len = vsnprintf_P(temp, sizeof(temp), format, arg); va_end(arg); if (len > sizeof(temp) - 1) { - buffer = new char[len + 1]; + buffer = new (std::nothrow) char[len + 1]; if (!buffer) { return 0; } diff --git a/cores/esp8266/Stream.cpp b/cores/esp8266/Stream.cpp index 3d7f5bc23..c4d5fc87d 100644 --- a/cores/esp8266/Stream.cpp +++ b/cores/esp8266/Stream.cpp @@ -173,7 +173,7 @@ float Stream::parseFloat(char skipChar) { boolean isFraction = false; long value = 0; int c; - float fraction = 1.0; + float fraction = 1.0f; c = peekNextDigit(); // ignore non numeric leading characters @@ -190,7 +190,7 @@ float Stream::parseFloat(char skipChar) { else if(c >= '0' && c <= '9') { // is c a digit? value = value * 10 + c - '0'; if(isFraction) - fraction *= 0.1; + fraction *= 0.1f; } read(); // consume the character we got with peek c = timedPeek(); diff --git a/cores/esp8266/WString.cpp b/cores/esp8266/WString.cpp index 7b9d9db93..5498f8a23 100644 --- a/cores/esp8266/WString.cpp +++ b/cores/esp8266/WString.cpp @@ -124,9 +124,9 @@ String::~String() { invalidate(); } -// /*********************************************/ -// /* Memory Management */ -// /*********************************************/ +/*********************************************/ +/* Memory Management */ +/*********************************************/ inline void String::init(void) { setSSO(true); @@ -199,9 +199,9 @@ unsigned char String::changeBuffer(unsigned int maxStrLen) { return 0; } -// /*********************************************/ -// /* Copy and Move */ -// /*********************************************/ +/*********************************************/ +/* Copy and Move */ +/*********************************************/ String & String::copy(const char *cstr, unsigned int length) { if (!reserve(length)) { @@ -297,9 +297,9 @@ String & String::operator = (const __FlashStringHelper *pstr) return *this; } -// /*********************************************/ -// /* concat */ -// /*********************************************/ +/*********************************************/ +/* concat */ +/*********************************************/ unsigned char String::concat(const String &s) { // Special case if we're concatting ourself (s += s;) since we may end up @@ -483,9 +483,9 @@ StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHel return a; } -// /*********************************************/ -// /* Comparison */ -// /*********************************************/ +/*********************************************/ +/* Comparison */ +/*********************************************/ int String::compareTo(const String &s) const { if(!buffer() || !s.buffer()) { @@ -587,9 +587,9 @@ unsigned char String::endsWith(const String &s2) const { return strcmp(&buffer()[len() - s2.len()], s2.buffer()) == 0; } -// /*********************************************/ -// /* Character Access */ -// /*********************************************/ +/*********************************************/ +/* Character Access */ +/*********************************************/ char String::charAt(unsigned int loc) const { return operator[](loc); @@ -629,9 +629,9 @@ void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int ind buf[n] = 0; } -// /*********************************************/ -// /* Search */ -// /*********************************************/ +/*********************************************/ +/* Search */ +/*********************************************/ int String::indexOf(char c) const { return indexOf(c, 0); @@ -713,9 +713,9 @@ String String::substring(unsigned int left, unsigned int right) const { return out; } -// /*********************************************/ -// /* Modification */ -// /*********************************************/ +/*********************************************/ +/* Modification */ +/*********************************************/ void String::replace(char find, char replace) { if (!buffer()) @@ -828,9 +828,9 @@ void String::trim(void) { wbuffer()[newlen] = 0; } -// /*********************************************/ -// /* Parsing / Conversion */ -// /*********************************************/ +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ long String::toInt(void) const { if (buffer()) diff --git a/cores/esp8266/abi.cpp b/cores/esp8266/abi.cpp index fe6335410..aa031e640 100644 --- a/cores/esp8266/abi.cpp +++ b/cores/esp8266/abi.cpp @@ -32,18 +32,33 @@ extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); -#if !defined(__cpp_exceptions) && !defined(NEW_OOM_ABORT) -void *operator new(size_t size) +#if !defined(__cpp_exceptions) + +// overwrite weak operators new/new[] definitions + +void* operator new(size_t size) { void *ret = malloc(size); if (0 != size && 0 == ret) { umm_last_fail_alloc_addr = __builtin_return_address(0); umm_last_fail_alloc_size = size; + __unhandled_exception(PSTR("OOM")); } - return ret; + return ret; } -void *operator new[](size_t size) +void* operator new[](size_t size) +{ + void *ret = malloc(size); + if (0 != size && 0 == ret) { + umm_last_fail_alloc_addr = __builtin_return_address(0); + umm_last_fail_alloc_size = size; + __unhandled_exception(PSTR("OOM")); + } + return ret; +} + +void* operator new (size_t size, const std::nothrow_t&) { void *ret = malloc(size); if (0 != size && 0 == ret) { @@ -52,7 +67,18 @@ void *operator new[](size_t size) } return ret; } -#endif // arduino's std::new legacy + +void* operator new[] (size_t size, const std::nothrow_t&) +{ + void *ret = malloc(size); + if (0 != size && 0 == ret) { + umm_last_fail_alloc_addr = __builtin_return_address(0); + umm_last_fail_alloc_size = size; + } + return ret; +} + +#endif // !defined(__cpp_exceptions) void __cxa_pure_virtual(void) { diff --git a/cores/esp8266/cbuf.cpp b/cores/esp8266/cbuf.cpp index e655ca6fc..b9a2880e3 100644 --- a/cores/esp8266/cbuf.cpp +++ b/cores/esp8266/cbuf.cpp @@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include // std::nothrow #include "cbuf.h" #include "c_types.h" @@ -43,7 +44,7 @@ size_t cbuf::resize(size_t newSize) { return _size; } - char *newbuf = new char[newSize]; + char *newbuf = new (std::nothrow) char[newSize]; char *oldbuf = _buf; if(!newbuf) { diff --git a/cores/esp8266/core_esp8266_features.h b/cores/esp8266/core_esp8266_features.h index 6d6edf030..cc4cd3977 100644 --- a/cores/esp8266/core_esp8266_features.h +++ b/cores/esp8266/core_esp8266_features.h @@ -36,35 +36,6 @@ #include // size_t #include -#ifdef __cplusplus - -namespace arduino -{ - extern "C++" - template - T* new0 (size_t n, TConstructorArgs... TconstructorArgs) - { - // n==0: single allocation, otherwise it is an array - size_t offset = n? sizeof(size_t): 0; - size_t arraysize = n? n: 1; - T* ptr = (T*)malloc(offset + (arraysize * sizeof(T))); - if (ptr) - { - if (n) - *(size_t*)(ptr) = n; - for (size_t i = 0; i < arraysize; i++) - new (ptr + offset + i * sizeof(T)) T(TconstructorArgs...); - return ptr + offset; - } - return nullptr; - } -} - -#define arduino_new(Type, ...) arduino::new0(0, ##__VA_ARGS__) -#define arduino_newarray(Type, n, ...) arduino::new0(n, ##__VA_ARGS__) - -#endif // __cplusplus - #ifndef __STRINGIFY #define __STRINGIFY(a) #a #endif diff --git a/cores/esp8266/core_esp8266_postmortem.cpp b/cores/esp8266/core_esp8266_postmortem.cpp index f79ebace8..3e75342d0 100644 --- a/cores/esp8266/core_esp8266_postmortem.cpp +++ b/cores/esp8266/core_esp8266_postmortem.cpp @@ -220,6 +220,12 @@ void __wrap_system_restart_local() { cut_here(); + if (s_unhandled_exception && umm_last_fail_alloc_addr) { + // now outside from the "cut-here" zone, print correctly the `new` caller address, + // idf-monitor.py will be able to decode this one and show exact location in sources + ets_printf_P(PSTR("\nlast failed alloc caller: 0x%08x\n"), (uint32_t)umm_last_fail_alloc_addr); + } + custom_crash_callback( &rst_info, sp_dump + offset, stack_end ); ets_delay_us(10000); diff --git a/cores/esp8266/debug.h b/cores/esp8266/debug.h index fab128253..c48b79a14 100644 --- a/cores/esp8266/debug.h +++ b/cores/esp8266/debug.h @@ -22,6 +22,7 @@ void hexdump(const void *mem, uint32_t len, uint8_t cols); extern "C" { #endif +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/doc/reference.rst b/doc/reference.rst index 9551d9d03..2ae8ca5cd 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -323,36 +323,3 @@ C++ This assures correct behavior, including handling of all subobjects, which guarantees stability. History: `#6269 `__ `#6309 `__ `#6312 `__ - -- New optional allocator ``arduino_new`` - - A new optional global allocator is introduced with a different semantic: - - - never throws exceptions on oom - - - never calls constructors on oom - - - returns nullptr on oom - - It is similar to arduino ``new`` semantic without side effects - (except when parent constructors, or member constructors use ``new``). - - Syntax is slightly different, the following shows the different usages: - - .. code:: cpp - - // with new: - - SomeClass* sc = new SomeClass(arg1, arg2, ...); - delete sc; - - SomeClass* scs = new SomeClass[42]; - delete [] scs; - - // with arduino_new: - - SomeClass* sc = arduino_new(SomeClass, arg1, arg2, ...); - delete sc; - - SomeClass* scs = arduino_newarray(SomeClass, 42); - delete [] scs; diff --git a/libraries/ArduinoOTA/ArduinoOTA.cpp b/libraries/ArduinoOTA/ArduinoOTA.cpp index 64e8397a2..83cc5c790 100644 --- a/libraries/ArduinoOTA/ArduinoOTA.cpp +++ b/libraries/ArduinoOTA/ArduinoOTA.cpp @@ -31,19 +31,6 @@ extern "C" { #endif ArduinoOTAClass::ArduinoOTAClass() -: _port(0) -, _udp_ota(0) -, _initialized(false) -, _rebootOnSuccess(true) -, _useMDNS(true) -, _state(OTA_IDLE) -, _size(0) -, _cmd(0) -, _ota_port(0) -, _start_callback(NULL) -, _end_callback(NULL) -, _error_callback(NULL) -, _progress_callback(NULL) { } diff --git a/libraries/ArduinoOTA/ArduinoOTA.h b/libraries/ArduinoOTA/ArduinoOTA.h index 1dfcaeed3..323c8b73d 100644 --- a/libraries/ArduinoOTA/ArduinoOTA.h +++ b/libraries/ArduinoOTA/ArduinoOTA.h @@ -69,31 +69,31 @@ class ArduinoOTAClass int getCommand(); private: - int _port; - String _password; - String _hostname; - String _nonce; - UdpContext *_udp_ota; - bool _initialized; - bool _rebootOnSuccess; - bool _useMDNS; - ota_state_t _state; - int _size; - int _cmd; - uint16_t _ota_port; - uint16_t _ota_udp_port; - IPAddress _ota_ip; - String _md5; - - THandlerFunction _start_callback; - THandlerFunction _end_callback; - THandlerFunction_Error _error_callback; - THandlerFunction_Progress _progress_callback; - void _runUpdate(void); void _onRx(void); int parseInt(void); String readStringUntil(char end); + + int _port = 0; + String _password; + String _hostname; + String _nonce; + UdpContext *_udp_ota = nullptr; + bool _initialized = false; + bool _rebootOnSuccess = true; + bool _useMDNS = true; + ota_state_t _state = OTA_IDLE; + int _size = 0; + int _cmd = 0; + uint16_t _ota_port = 0; + uint16_t _ota_udp_port = 0; + IPAddress _ota_ip; + String _md5; + + THandlerFunction _start_callback = nullptr; + THandlerFunction _end_callback = nullptr; + THandlerFunction_Error _error_callback = nullptr; + THandlerFunction_Progress _progress_callback = nullptr; }; #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ARDUINOOTA) diff --git a/libraries/DNSServer/src/DNSServer.cpp b/libraries/DNSServer/src/DNSServer.cpp index 2113ae0f5..8d7b3dfb0 100644 --- a/libraries/DNSServer/src/DNSServer.cpp +++ b/libraries/DNSServer/src/DNSServer.cpp @@ -178,8 +178,7 @@ void DNSServer::processNextRequest() return; std::unique_ptr buffer(new (std::nothrow) uint8_t[currentPacketSize]); - - if (buffer == NULL) + if (buffer == nullptr) return; _udp.read(buffer.get(), currentPacketSize); diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index 74bc3be17..580964da1 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -182,7 +182,7 @@ bool HTTPClient::begin(String url, const uint8_t httpsFingerprint[20]) if (!beginInternal(url, "https")) { return false; } - _transportTraits = TransportTraitsPtr(new BearSSLTraits(httpsFingerprint)); + _transportTraits = TransportTraitsPtr(new (std::nothrow) BearSSLTraits(httpsFingerprint)); if(!_transportTraits) { DEBUG_HTTPCLIENT("[HTTP-Client][begin] could not create transport traits\n"); return false; diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index 218fd168a..a686c4346 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -126,12 +126,12 @@ bool ESP8266WebServerTemplate::authenticate(const char * username, c authReq = authReq.substring(6); authReq.trim(); char toencodeLen = strlen(username)+strlen(password)+1; - char *toencode = new char[toencodeLen + 1]; + char *toencode = new (std::nothrow) char[toencodeLen + 1]; if(toencode == NULL){ authReq = ""; return false; } - char *encoded = new char[base64_encode_expected_len(toencodeLen)+1]; + char *encoded = new (std::nothrow) char[base64_encode_expected_len(toencodeLen)+1]; if(encoded == NULL){ authReq = ""; delete[] toencode; diff --git a/libraries/ESP8266WiFi/src/CertStoreBearSSL.cpp b/libraries/ESP8266WiFi/src/CertStoreBearSSL.cpp index 905efde2b..9f3e0ac80 100644 --- a/libraries/ESP8266WiFi/src/CertStoreBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/CertStoreBearSSL.cpp @@ -50,9 +50,13 @@ CertStore::CertInfo CertStore::_preprocessCert(uint32_t length, uint32_t offset, memset(&ci, 0, sizeof(ci)); // Process it using SHA256, same as the hashed_dn - br_x509_decoder_context *ctx = new br_x509_decoder_context; - br_sha256_context *sha256 = new br_sha256_context; + br_x509_decoder_context *ctx = new (std::nothrow) br_x509_decoder_context; + br_sha256_context *sha256 = new (std::nothrow) br_sha256_context; if (!ctx || !sha256) { + if (ctx) + delete ctx; + if (sha256) + delete sha256; DEBUG_BSSL("CertStore::_preprocessCert: OOM\n"); return ci; } @@ -202,7 +206,7 @@ const br_x509_trust_anchor *CertStore::findHashedTA(void *ctx, void *hashed_dn, return nullptr; } data.close(); - cs->_x509 = new X509List(der, ci.length); + cs->_x509 = new (std::nothrow) X509List(der, ci.length); free(der); if (!cs->_x509) { DEBUG_BSSL("CertStore::findHashedTA: OOM\n"); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index abad142ed..304883506 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -369,17 +369,18 @@ WiFiPhyMode_t ESP8266WiFiGenericClass::getPhyMode() { */ void ESP8266WiFiGenericClass::setOutputPower(float dBm) { - if(dBm > 20.5) { - dBm = 20.5; - } else if(dBm < 0) { - dBm = 0; + int i_dBm = int(dBm * 4.0f); + + // i_dBm 82 == 20.5 dBm + if(i_dBm > 82) { + i_dBm = 82; + } else if(i_dBm < 0) { + i_dBm = 0; } - uint8_t val = (dBm*4.0f); - system_phy_set_max_tpw(val); + system_phy_set_max_tpw((uint8_t) i_dBm); } - /** * store WiFi config in SDK flash area * @param persistent diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index c94ac79e0..2aa177b64 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -977,7 +977,7 @@ extern "C" { // Set custom list of ciphers bool WiFiClientSecure::setCiphers(const uint16_t *cipherAry, int cipherCount) { _cipher_list = nullptr; - _cipher_list = std::shared_ptr(new uint16_t[cipherCount], std::default_delete()); + _cipher_list = std::shared_ptr(new (std::nothrow) uint16_t[cipherCount], std::default_delete()); if (!_cipher_list.get()) { DEBUG_BSSL("setCiphers: list empty\n"); return false; @@ -1067,8 +1067,8 @@ bool WiFiClientSecure::_connectSSL(const char* hostName) { _sc = std::make_shared(); _eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr - _iobuf_in = std::shared_ptr(new unsigned char[_iobuf_in_size], std::default_delete()); - _iobuf_out = std::shared_ptr(new unsigned char[_iobuf_out_size], std::default_delete()); + _iobuf_in = std::shared_ptr(new (std::nothrow) unsigned char[_iobuf_in_size], std::default_delete()); + _iobuf_out = std::shared_ptr(new (std::nothrow) unsigned char[_iobuf_out_size], std::default_delete()); if (!_sc || !_iobuf_in || !_iobuf_out) { _freeSSL(); // Frees _sc, _iobuf* @@ -1183,8 +1183,8 @@ bool WiFiClientSecure::_connectSSLServerRSA(const X509List *chain, _oom_err = false; _sc_svr = std::make_shared(); _eng = &_sc_svr->eng; // Allocation/deallocation taken care of by the _sc shared_ptr - _iobuf_in = std::shared_ptr(new unsigned char[_iobuf_in_size], std::default_delete()); - _iobuf_out = std::shared_ptr(new unsigned char[_iobuf_out_size], std::default_delete()); + _iobuf_in = std::shared_ptr(new (std::nothrow) unsigned char[_iobuf_in_size], std::default_delete()); + _iobuf_out = std::shared_ptr(new (std::nothrow) unsigned char[_iobuf_out_size], std::default_delete()); if (!_sc_svr || !_iobuf_in || !_iobuf_out) { _freeSSL(); @@ -1220,8 +1220,8 @@ bool WiFiClientSecure::_connectSSLServerEC(const X509List *chain, _oom_err = false; _sc_svr = std::make_shared(); _eng = &_sc_svr->eng; // Allocation/deallocation taken care of by the _sc shared_ptr - _iobuf_in = std::shared_ptr(new unsigned char[_iobuf_in_size], std::default_delete()); - _iobuf_out = std::shared_ptr(new unsigned char[_iobuf_out_size], std::default_delete()); + _iobuf_in = std::shared_ptr(new (std::nothrow) unsigned char[_iobuf_in_size], std::default_delete()); + _iobuf_out = std::shared_ptr(new (std::nothrow) unsigned char[_iobuf_out_size], std::default_delete()); if (!_sc_svr || !_iobuf_in || !_iobuf_out) { _freeSSL(); @@ -1421,7 +1421,7 @@ bool WiFiClientSecure::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint1 default: return false; // Invalid size } int ttlLen = sizeof(clientHelloHead_P) + (2 + sizeof(suites_P)) + (sizeof(clientHelloTail_P) + 1); - uint8_t *clientHello = new uint8_t[ttlLen]; + uint8_t *clientHello = new (std::nothrow) uint8_t[ttlLen]; if (!clientHello) { DEBUG_BSSL("probeMaxFragmentLength: OOM\n"); return false; diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp index 618f5eaa3..03345054b 100755 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp @@ -30,12 +30,12 @@ extern "C" uint32_t _FS_start; extern "C" uint32_t _FS_end; ESP8266HTTPUpdate::ESP8266HTTPUpdate(void) - : _httpClientTimeout(8000), _followRedirects(HTTPC_DISABLE_FOLLOW_REDIRECTS), _ledPin(-1) + : _httpClientTimeout(8000) { } ESP8266HTTPUpdate::ESP8266HTTPUpdate(int httpClientTimeout) - : _httpClientTimeout(httpClientTimeout), _followRedirects(HTTPC_DISABLE_FOLLOW_REDIRECTS), _ledPin(-1) + : _httpClientTimeout(httpClientTimeout) { } diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h index e8e722152..88216070d 100755 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h @@ -184,7 +184,7 @@ protected: private: int _httpClientTimeout; - followRedirects_t _followRedirects; + followRedirects_t _followRedirects = HTTPC_DISABLE_FOLLOW_REDIRECTS; // Callbacks HTTPUpdateStartCB _cbStart; @@ -192,7 +192,7 @@ private: HTTPUpdateErrorCB _cbError; HTTPUpdateProgressCB _cbProgress; - int _ledPin; + int _ledPin = -1; uint8_t _ledOn; }; diff --git a/libraries/Netdump/README.md b/libraries/Netdump/README.md new file mode 100644 index 000000000..7db9c725a --- /dev/null +++ b/libraries/Netdump/README.md @@ -0,0 +1,52 @@ + +esp8266/Arduino goodies +----------------------- + +* NetDump (lwip2) + Packet sniffer library to help study network issues, check example-sketches + Log examples on serial console: +``` +14:07:01.854 -> in 0 ARP who has 10.43.1.117 tell 10.43.1.254 +14:07:01.854 -> out 0 ARP 10.43.1.117 is at 5c:cf:7f:c3:ad:51 + +[...] hello-world, dumped in packets: +14:07:46.227 -> in 0 IPv4 10.43.1.254>10.43.1.117 TCP 54546>2[P.] seq:1945448681..1945448699 ack:6618 win:29200 len=18 +14:07:46.260 -> 5c cf 7f c3 ad 51 74 da 38 3a 1f 61 08 00 45 10 \..Qt.8:.a..E. +14:07:46.260 -> 00 3a b2 bc 40 00 40 06 70 29 0a 2b 01 fe 0a 2b .:..@.@.p).+...+ +14:07:46.260 -> 01 75 d5 12 00 02 73 f5 30 e9 00 00 19 da 50 18 .u....s.0.....P. +14:07:46.260 -> 72 10 f8 da 00 00 70 6c 20 68 65 6c 6c 6f 2d 77 r.....pl hello-w +14:07:46.260 -> 6f 72 6c 64 20 31 0d 0a orld 1.. +14:07:46.294 -> out 0 IPv4 10.43.1.117>10.43.1.254 TCP 2>54546[P.] seq:6618..6619 ack:1945448699 win:2126 len=1 +14:07:46.326 -> 00 20 00 00 00 00 aa aa 03 00 00 00 08 00 45 00 . ............E. +14:07:46.326 -> 00 29 00 0d 00 00 ff 06 a3 f9 0a 2b 01 75 0a 2b .).........+.u.+ +14:07:46.327 -> 01 fe 00 02 d5 12 00 00 19 da 73 f5 30 fb 50 18 ..........s.0.P. +14:07:46.327 -> 08 4e 93 d5 00 00 68 .N....h +14:07:46.327 -> in 0 IPv4 10.43.1.254>10.43.1.117 TCP 54546>2[.] seq:1945448699 ack:6619 win:29200 +14:07:46.327 -> 5c cf 7f c3 ad 51 74 da 38 3a 1f 61 08 00 45 10 \..Qt.8:.a..E. +14:07:46.360 -> 00 28 b2 bd 40 00 40 06 70 3a 0a 2b 01 fe 0a 2b .(..@.@.p:.+...+ +14:07:46.360 -> 01 75 d5 12 00 02 73 f5 30 fb 00 00 19 db 50 10 .u....s.0.....P. +14:07:46.360 -> 72 10 92 1b 00 00 r..... +14:07:46.360 -> out 0 IPv4 10.43.1.117>10.43.1.254 TCP 2>54546[P.] seq:6619..6630 ack:1945448699 win:2126 len=11 +14:07:46.360 -> 00 20 00 00 00 00 aa aa 03 00 00 00 08 00 45 00 . ............E. +14:07:46.360 -> 00 33 00 0e 00 00 ff 06 a3 ee 0a 2b 01 75 0a 2b .3.........+.u.+ +14:07:46.393 -> 01 fe 00 02 d5 12 00 00 19 db 73 f5 30 fb 50 18 ..........s.0.P. +14:07:46.393 -> 08 4e 16 a1 00 00 65 6c 6c 6f 2d 77 6f 72 6c 64 .N....ello-world +14:07:46.393 -> 0a . + +[...] help protocol decoding from inside the esp +14:08:11.715 -> in 0 IPv4 10.43.1.254>239.255.255.250 UDP 50315>1900 len=172 +14:08:11.716 -> 01 00 5e 7f ff fa 74 da 38 3a 1f 61 08 00 45 00 ....t.8:.a..E. +14:08:11.716 -> 00 c8 9b 40 40 00 01 11 e1 c1 0a 2b 01 fe ef ff ...@@......+.... +14:08:11.749 -> ff fa c4 8b 07 6c 00 b4 9c 28 4d 2d 53 45 41 52 .....l...(M-SEAR +14:08:11.749 -> 43 48 20 2a 20 48 54 54 50 2f 31 2e 31 0d 0a 48 CH * HTTP/1.1..H +14:08:11.749 -> 4f 53 54 3a 20 32 33 39 2e 32 35 35 2e 32 35 35 OST: 239.255.255 +14:08:11.749 -> 2e 32 35 30 3a 31 39 30 30 0d 0a 4d 41 4e 3a 20 .250:1900..MAN: +14:08:11.749 -> 22 73 73 64 70 3a 64 69 73 63 6f 76 65 72 22 0d "ssdp:discover". +14:08:11.749 -> 0a 4d 58 3a 20 31 0d 0a 53 54 3a 20 75 72 6e 3a .MX: 1..ST: urn: +14:08:11.782 -> 64 69 61 6c 2d 6d 75 6c 74 69 73 63 72 65 65 6e dial-multiscreen +14:08:11.782 -> 2d 6f 72 67 3a 73 65 72 76 69 63 65 3a 64 69 61 -org:service:dia +14:08:11.782 -> 6c 3a 31 0d 0a 55 53 45 52 2d 41 47 45 4e 54 3a l:1..USER-AGENT: +14:08:11.782 -> 20 47 6f 6f 67 6c 65 20 43 68 72 6f 6d 65 2f 36 Google Chrome/6 +14:08:11.782 -> 36 2e 30 2e 33 33 35 39 2e 31 31 37 20 4c 69 6e 6.0.3359.117 Lin +14:08:11.782 -> 75 78 0d 0a 0d 0a ux.... + diff --git a/libraries/Netdump/examples/Netdump/Netdump.ino b/libraries/Netdump/examples/Netdump/Netdump.ino new file mode 100644 index 000000000..dbba63869 --- /dev/null +++ b/libraries/Netdump/examples/Netdump/Netdump.ino @@ -0,0 +1,156 @@ +#include "Arduino.h" + +#include "Netdump.h" +#include +#include +#include +//#include +#include +#include + +using namespace NetCapture; + +#ifndef STASSID +#define STASSID "your-ssid" +#define STAPSK "your-password" +#endif + +const char* ssid = STASSID; +const char* password = STAPSK; + +Netdump nd; + +//FS* filesystem = &SPIFFS; +FS* filesystem = &LittleFS; + +ESP8266WebServer webServer(80); // Used for sending commands +WiFiServer tcpServer(8000); // Used to show netcat option. +File tracefile; + +std::map packetCount; + +enum class SerialOption : uint8_t { + AllFull, + LocalNone, + HTTPChar +}; + +void startSerial(SerialOption option) { + switch (option) { + case SerialOption::AllFull : //All Packets, show packet summary. + nd.printDump(Serial, Packet::PacketDetail::FULL); + break; + + case SerialOption::LocalNone : // Only local IP traffic, full details + nd.printDump(Serial, Packet::PacketDetail::NONE, + [](Packet n) { + return (n.hasIP(WiFi.localIP())); + } + ); + break; + case SerialOption::HTTPChar : // Only HTTP traffic, show packet content as chars + nd.printDump(Serial, Packet::PacketDetail::CHAR, + [](Packet n) { + return (n.isHTTP()); + } + ); + break; + default : + Serial.printf("No valid SerialOption provided\r\n"); + }; +} + +void startTracefile() { + // To file all traffic, format pcap file + tracefile = filesystem->open("/tr.pcap", "w"); + nd.fileDump(tracefile); +} + +void startTcpDump() { + // To tcpserver, all traffic. + tcpServer.begin(); + nd.tcpDump(tcpServer); +} + +void setup(void) { + Serial.begin(115200); + + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.println("WiFi Failed, stopping sketch"); + while (1) { + delay(1000); + } + } + + if (!MDNS.begin("netdumphost")) { + Serial.println("Error setting up MDNS responder!"); + } + + filesystem->begin(); + + webServer.on("/list", + []() { + Dir dir = filesystem->openDir("/"); + String d = "

File list

"; + while (dir.next()) { + d.concat("
  • " + dir.fileName() + "
  • "); + } + webServer.send(200, "text.html", d); + } + ); + + webServer.on("/req", + []() { + static int rq = 0; + String a = "

    You are connected, Number of requests = " + String(rq++) + "

    "; + webServer.send(200, "text/html", a); + } + ); + + webServer.on("/reset", + []() { + nd.reset(); + tracefile.close(); + tcpServer.close(); + webServer.send(200, "text.html", "

    Netdump session reset

    "); + } + ); + + webServer.serveStatic("/", *filesystem, "/"); + webServer.begin(); + + startSerial(SerialOption::AllFull); // Serial output examples, use enum SerialOption for selection + + // startTcpDump(); // tcpdump option + // startTracefile(); // output to SPIFFS or LittleFS + + // use a self provide callback, this count network packets + /* + nd.setCallback( + [](Packet p) + { + Serial.printf("PKT : %s : ",p.sourceIP().toString().c_str()); + for ( auto pp : p.allPacketTypes()) + { + Serial.printf("%s ",pp.toString().c_str()); + packetCount[pp]++; + } + Serial.printf("\r\n CNT "); + for (auto pc : packetCount) + { + Serial.printf("%s %d ", pc.first.toString().c_str(),pc.second); + } + Serial.printf("\r\n"); + } + ); + */ +} + +void loop(void) { + webServer.handleClient(); + MDNS.update(); +} + diff --git a/libraries/Netdump/keywords.txt b/libraries/Netdump/keywords.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/libraries/Netdump/keywords.txt @@ -0,0 +1 @@ + diff --git a/libraries/Netdump/library.properties b/libraries/Netdump/library.properties new file mode 100644 index 000000000..2f6ad5e22 --- /dev/null +++ b/libraries/Netdump/library.properties @@ -0,0 +1,9 @@ +name=NetDump +version=2 +author=Herman Reintke +maintainer=Herman Reintke +sentence=tcpdump-like logger for esp8266/Arduino +paragraph=Dumps input / output packets on "Print"able type, or provide a TCP server for the real tcpdump. Check examples. Some other unrelated and independant tools are included. +category=Communication +url=https:// +architectures=esp8266 lwip diff --git a/libraries/Netdump/src/Netdump.cpp b/libraries/Netdump/src/Netdump.cpp new file mode 100644 index 000000000..a608a1c3b --- /dev/null +++ b/libraries/Netdump/src/Netdump.cpp @@ -0,0 +1,220 @@ +/* + NetDump library - tcpdump-like packet logger facility + + Copyright (c) 2019 Herman Reintke. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Netdump.h" +#include +#include "Schedule.h" + + +namespace NetCapture +{ + +CallBackList Netdump::lwipCallback; + +Netdump::Netdump() +{ + using namespace std::placeholders; + phy_capture = capture; + lwipHandler = lwipCallback.add(std::bind(&Netdump::netdumpCapture, this, _1, _2, _3, _4, _5)); +}; + +Netdump::~Netdump() +{ + reset(); + if (packetBuffer) + { + delete[] packetBuffer; + } +}; + +void Netdump::setCallback(const Callback nc) +{ + netDumpCallback = nc; +} + +void Netdump::setCallback(const Callback nc, const Filter nf) +{ + netDumpFilter = nf; + netDumpCallback = nc; +} + +void Netdump::setFilter(const Filter nf) +{ + netDumpFilter = nf; +} + +void Netdump::reset() +{ + setCallback(nullptr, nullptr); +} + +void Netdump::printDump(Print& out, Packet::PacketDetail ndd, const Filter nf) +{ + out.printf("netDump starting\r\n"); + setCallback([&out, ndd, this](const Packet & ndp) + { + printDumpProcess(out, ndd, ndp); + }, nf); +} + +void Netdump::fileDump(File& outfile, const Filter nf) +{ + + writePcapHeader(outfile); + setCallback([&outfile, this](const Packet & ndp) + { + fileDumpProcess(outfile, ndp); + }, nf); +} +void Netdump::tcpDump(WiFiServer &tcpDumpServer, const Filter nf) +{ + + if (!packetBuffer) + { + packetBuffer = new (std::nothrow) char[tcpBufferSize]; + } + bufferIndex = 0; + + schedule_function([&tcpDumpServer, this, nf]() + { + tcpDumpLoop(tcpDumpServer, nf); + }); +} + +void Netdump::capture(int netif_idx, const char* data, size_t len, int out, int success) +{ + if (lwipCallback.execute(netif_idx, data, len, out, success) == 0) + { + phy_capture = nullptr; // No active callback/netdump instances, will be set again by new object. + } +} + +void Netdump::netdumpCapture(int netif_idx, const char* data, size_t len, int out, int success) +{ + if (netDumpCallback) + { + Packet np(millis(), netif_idx, data, len, out, success); + if (netDumpFilter && !netDumpFilter(np)) + { + return; + } + netDumpCallback(np); + } +} + +void Netdump::writePcapHeader(Stream& s) const +{ + uint32_t pcapHeader[6]; + pcapHeader[0] = 0xa1b2c3d4; // pcap magic number + pcapHeader[1] = 0x00040002; // pcap major/minor version + pcapHeader[2] = 0; // pcap UTC correction in seconds + pcapHeader[3] = 0; // pcap time stamp accuracy + pcapHeader[4] = maxPcapLength; // pcap max packet length per record + pcapHeader[5] = 1; // pacp data linkt type = ethernet + s.write(reinterpret_cast(pcapHeader), 24); +} + +void Netdump::printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) const +{ + out.printf_P(PSTR("%8d %s"), np.getTime(), np.toString(ndd).c_str()); +} + +void Netdump::fileDumpProcess(File& outfile, const Packet& np) const +{ + size_t incl_len = np.getPacketSize() > maxPcapLength ? maxPcapLength : np.getPacketSize(); + uint32_t pcapHeader[4]; + + struct timeval tv; + gettimeofday(&tv, nullptr); + pcapHeader[0] = tv.tv_sec; + pcapHeader[1] = tv.tv_usec; + pcapHeader[2] = incl_len; + pcapHeader[3] = np.getPacketSize(); + outfile.write(reinterpret_cast(pcapHeader), 16); // pcap record header + + outfile.write(np.rawData(), incl_len); +} + +void Netdump::tcpDumpProcess(const Packet& np) +{ + if (np.isTCP() && np.hasPort(tcpDumpClient.localPort())) + { + // skip myself + return; + } + size_t incl_len = np.getPacketSize() > maxPcapLength ? maxPcapLength : np.getPacketSize(); + + if (bufferIndex + 16 + incl_len < tcpBufferSize) // only add if enough space available + { + struct timeval tv; + gettimeofday(&tv, nullptr); + uint32_t* pcapHeader = reinterpret_cast(&packetBuffer[bufferIndex]); + pcapHeader[0] = tv.tv_sec; // add pcap record header + pcapHeader[1] = tv.tv_usec; + pcapHeader[2] = incl_len; + pcapHeader[3] = np.getPacketSize(); + bufferIndex += 16; // pcap header size + memcpy(&packetBuffer[bufferIndex], np.rawData(), incl_len); + bufferIndex += incl_len; + } + + if (bufferIndex && tcpDumpClient && tcpDumpClient.availableForWrite() >= bufferIndex) + { + tcpDumpClient.write(packetBuffer, bufferIndex); + bufferIndex = 0; + } +} + +void Netdump::tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf) +{ + if (tcpDumpServer.hasClient()) + { + tcpDumpClient = tcpDumpServer.available(); + tcpDumpClient.setNoDelay(true); + + bufferIndex = 0; + writePcapHeader(tcpDumpClient); + + setCallback([this](const Packet & ndp) + { + tcpDumpProcess(ndp); + }, nf); + } + if (!tcpDumpClient || !tcpDumpClient.connected()) + { + setCallback(nullptr); + } + if (bufferIndex && tcpDumpClient && tcpDumpClient.availableForWrite() >= bufferIndex) + { + tcpDumpClient.write(packetBuffer, bufferIndex); + bufferIndex = 0; + } + + if (tcpDumpServer.status() != CLOSED) + { + schedule_function([&tcpDumpServer, this, nf]() + { + tcpDumpLoop(tcpDumpServer, nf); + }); + } +} + +} // namespace NetCapture diff --git a/libraries/Netdump/src/Netdump.h b/libraries/Netdump/src/Netdump.h new file mode 100644 index 000000000..1011a8e95 --- /dev/null +++ b/libraries/Netdump/src/Netdump.h @@ -0,0 +1,87 @@ +/* + NetDump library - tcpdump-like packet logger facility + + Copyright (c) 2019 Herman Reintke. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __NETDUMP_H +#define __NETDUMP_H + +#include +#include +#include +#include +#include "NetdumpPacket.h" +#include +#include "CallBackList.h" + +namespace NetCapture +{ + +using namespace experimental::CBListImplentation; + +class Netdump +{ +public: + + using Filter = std::function; + using Callback = std::function; + using LwipCallback = std::function; + + Netdump(); + ~Netdump(); + + void setCallback(const Callback nc); + void setCallback(const Callback nc, const Filter nf); + void setFilter(const Filter nf); + void reset(); + + void printDump(Print& out, Packet::PacketDetail ndd, const Filter nf = nullptr); + void fileDump(File& outfile, const Filter nf = nullptr); + void tcpDump(WiFiServer &tcpDumpServer, const Filter nf = nullptr); + + +private: + Callback netDumpCallback = nullptr; + Filter netDumpFilter = nullptr; + + static void capture(int netif_idx, const char* data, size_t len, int out, int success); + static CallBackList lwipCallback; + CallBackList::CallBackHandler lwipHandler; + + void netdumpCapture(int netif_idx, const char* data, size_t len, int out, int success); + + void printDumpProcess(Print& out, Packet::PacketDetail ndd, const Packet& np) const; + void fileDumpProcess(File& outfile, const Packet& np) const; + void tcpDumpProcess(const Packet& np); + void tcpDumpLoop(WiFiServer &tcpDumpServer, const Filter nf); + + void writePcapHeader(Stream& s) const; + + WiFiClient tcpDumpClient; + char* packetBuffer = nullptr; + size_t bufferIndex = 0; + + static constexpr int tcpBufferSize = 2048; + static constexpr int maxPcapLength = 1024; + static constexpr uint32_t pcapMagic = 0xa1b2c3d4; +}; + +} // namespace NetCapture + +#endif /* __NETDUMP_H */ diff --git a/libraries/Netdump/src/NetdumpIP.cpp b/libraries/Netdump/src/NetdumpIP.cpp new file mode 100644 index 000000000..d66459d80 --- /dev/null +++ b/libraries/Netdump/src/NetdumpIP.cpp @@ -0,0 +1,375 @@ +/* + NetDump library - tcpdump-like packet logger facility + + Copyright (c) 2019 Herman Reintke. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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 + +*/ +#include +#include + +namespace NetCapture +{ + +NetdumpIP::NetdumpIP() +{ +} + +NetdumpIP::NetdumpIP(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) +{ + setV4(); + (*this)[0] = first_octet; + (*this)[1] = second_octet; + (*this)[2] = third_octet; + (*this)[3] = fourth_octet; +} + +NetdumpIP::NetdumpIP(const uint8_t *address, bool v4) +{ + uint8_t cnt; + if (v4) + { + cnt = 4; + setV4(); + } + else + { + cnt = 16; + setV6(); + } + for (int i = 0; i < cnt; i++) + { + (*this)[i] = address[i]; + } +} + +NetdumpIP::NetdumpIP(const IPAddress& ip) +{ + if (!ip.isSet()) + { + setUnset(); + } + else if (ip.isV4()) + { + setV4(); + for (int i = 0; i < 4; i++) + { + rawip[i] = ip[i]; + } + } + else + { + setV6(); + for (int i = 0; i < 16; i++) + { + rawip[i] = ip[i]; + } + } +} + +NetdumpIP::NetdumpIP(const String& ip) +{ + if (!fromString(ip.c_str())) + { + setUnset(); + } +} + +bool NetdumpIP::fromString(const char *address) +{ + if (!fromString4(address)) + { + return fromString6(address); + } + return true; +} + +bool NetdumpIP::fromString4(const char *address) +{ + // TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats + + uint16_t acc = 0; // Accumulator + uint8_t dots = 0; + + while (*address) + { + char c = *address++; + if (c >= '0' && c <= '9') + { + acc = acc * 10 + (c - '0'); + if (acc > 255) + { + // Value out of [0..255] range + return false; + } + } + else if (c == '.') + { + if (dots == 3) + { + // Too much dots (there must be 3 dots) + return false; + } + (*this)[dots++] = acc; + acc = 0; + } + else + { + // Invalid char + return false; + } + } + + if (dots != 3) + { + // Too few dots (there must be 3 dots) + return false; + } + (*this)[3] = acc; + + setV4(); + return true; +} + +bool NetdumpIP::fromString6(const char *address) +{ + // TODO: test test test + + uint32_t acc = 0; // Accumulator + int dots = 0, doubledots = -1; + + while (*address) + { + char c = tolower(*address++); + if (isalnum(c)) + { + if (c >= 'a') + { + c -= 'a' - '0' - 10; + } + acc = acc * 16 + (c - '0'); + if (acc > 0xffff) + // Value out of range + { + return false; + } + } + else if (c == ':') + { + if (*address == ':') + { + if (doubledots >= 0) + // :: allowed once + { + return false; + } + // remember location + doubledots = dots + !!acc; + address++; + } + if (dots == 7) + // too many separators + { + return false; + } + reinterpret_cast(rawip)[dots++] = PP_HTONS(acc); + acc = 0; + } + else + // Invalid char + { + return false; + } + } + + if (doubledots == -1 && dots != 7) + // Too few separators + { + return false; + } + reinterpret_cast(rawip)[dots++] = PP_HTONS(acc); + + if (doubledots != -1) + { + for (int i = dots - doubledots - 1; i >= 0; i--) + { + reinterpret_cast(rawip)[8 - dots + doubledots + i] = reinterpret_cast(rawip)[doubledots + i]; + } + for (int i = doubledots; i < 8 - dots + doubledots; i++) + { + reinterpret_cast(rawip)[i] = 0; + } + } + + setV6(); + return true; +} + +String NetdumpIP::toString() +{ + StreamString sstr; + if (isV6()) + { + sstr.reserve(40); // 8 shorts x 4 chars each + 7 colons + nullterm + + } + else + { + sstr.reserve(16); // 4 bytes with 3 chars max + 3 dots + nullterm, or '(IP unset)' + } + printTo(sstr); + return sstr; +} + +size_t NetdumpIP::printTo(Print& p) +{ + size_t n = 0; + + if (!isSet()) + { + return p.print(F("(IP unset)")); + } + + if (isV6()) + { + int count0 = 0; + for (int i = 0; i < 8; i++) + { + uint16_t bit = PP_NTOHS(reinterpret_cast(rawip)[i]); + if (bit || count0 < 0) + { + n += p.printf("%x", bit); + if (count0 > 0) + // no more hiding 0 + { + count0 = -8; + } + } + else + { + count0++; + } + if ((i != 7 && count0 < 2) || count0 == 7) + { + n += p.print(':'); + } + } + return n; + } + for (int i = 0; i < 4; i++) + { + n += p.print((*this)[i], DEC); + if (i != 3) + { + n += p.print('.'); + } + } + return n; +} + +bool NetdumpIP::compareRaw(IPversion v, const uint8_t* a, const uint8_t* b) const +{ + for (int i = 0; i < (v == IPversion::IPV4 ? 4 : 16); i++) + { + if (a[i] != b[i]) + { + return false; + } + } + return true; +} + +bool NetdumpIP::compareIP(const IPAddress& ip) const +{ + switch (ipv) + { + case IPversion::UNSET : + if (ip.isSet()) + { + return false; + } + else + { + return true; + } + break; + case IPversion::IPV4 : + if (ip.isV6() || !ip.isSet()) + { + return false; + } + else + { + return compareRaw(IPversion::IPV4, rawip, reinterpret_cast(&ip.v4())); + } + break; + case IPversion::IPV6 : + if (ip.isV4() || !ip.isSet()) + { + return false; + } + else + { + return compareRaw(IPversion::IPV6, rawip, reinterpret_cast(ip.raw6())); + } + break; + default : + return false; + break; + } +} + +bool NetdumpIP::compareIP(const NetdumpIP& nip) const +{ + switch (ipv) + { + case IPversion::UNSET : + if (nip.isSet()) + { + return false; + } + else + { + return true; + } + break; + case IPversion::IPV4 : + if (nip.isV6() || !nip.isSet()) + { + return false; + } + else + { + return compareRaw(IPversion::IPV4, rawip, nip.rawip); + } + break; + case IPversion::IPV6 : + if (nip.isV4() || !nip.isSet()) + { + return false; + } + else + { + return compareRaw(IPversion::IPV6, rawip, nip.rawip); + } + break; + default : + return false; + break; + } +} + +} // namespace NetCapture diff --git a/libraries/Netdump/src/NetdumpIP.h b/libraries/Netdump/src/NetdumpIP.h new file mode 100644 index 000000000..8a450c374 --- /dev/null +++ b/libraries/Netdump/src/NetdumpIP.h @@ -0,0 +1,103 @@ +/* + NetdumpIP.h + + Created on: 18 mei 2019 + Author: Herman +*/ + +#ifndef LIBRARIES_ESPGOODIES_HR_SRC_NETDUMP_NETDUMPIP_H_ +#define LIBRARIES_ESPGOODIES_HR_SRC_NETDUMP_NETDUMPIP_H_ + +#include +#include +#include +#include + +namespace NetCapture +{ + +class NetdumpIP +{ +public: + NetdumpIP(); + + NetdumpIP(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); + NetdumpIP(const uint8_t *address, bool V4 = true); + NetdumpIP(const IPAddress& ip); + NetdumpIP(const String& ip); + + uint8_t& operator[](int index) + { + return rawip[index]; + } + + bool fromString(const char *address); + + String toString(); + +private: + enum class IPversion {UNSET, IPV4, IPV6}; + IPversion ipv = IPversion::UNSET; + + uint8_t rawip[16] = {0}; + + void setV4() + { + ipv = IPversion::IPV4; + }; + void setV6() + { + ipv = IPversion::IPV6; + }; + void setUnset() + { + ipv = IPversion::UNSET; + }; + bool isV4() const + { + return (ipv == IPversion::IPV4); + }; + bool isV6() const + { + return (ipv == IPversion::IPV6); + }; + bool isUnset() const + { + return (ipv == IPversion::UNSET); + }; + bool isSet() const + { + return (ipv != IPversion::UNSET); + }; + + bool compareRaw(IPversion v, const uint8_t* a, const uint8_t* b) const; + bool compareIP(const IPAddress& ip) const; + bool compareIP(const NetdumpIP& nip) const; + + bool fromString4(const char *address); + bool fromString6(const char *address); + + size_t printTo(Print& p); +public: + bool operator==(const IPAddress& addr) const + { + return compareIP(addr); + }; + bool operator!=(const IPAddress& addr) + { + return compareIP(addr); + }; + bool operator==(const NetdumpIP& addr) + { + return compareIP(addr); + }; + bool operator!=(const NetdumpIP& addr) + { + return !compareIP(addr); + }; + +}; + +} // namespace NetCapture + +#endif /* LIBRARIES_ESPGOODIES_HR_SRC_NETDUMP_NETDUMPIP_H_ */ diff --git a/libraries/Netdump/src/NetdumpPacket.cpp b/libraries/Netdump/src/NetdumpPacket.cpp new file mode 100644 index 000000000..4e2fcbaf6 --- /dev/null +++ b/libraries/Netdump/src/NetdumpPacket.cpp @@ -0,0 +1,381 @@ +/* + NetDump library - tcpdump-like packet logger facility + + Copyright (c) 2018 David Gauchard. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Netdump.h" +#include + +namespace NetCapture +{ + +void Packet::printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const +{ + if (pd == PacketDetail::NONE) + { + return; + } + + uint16_t charCount = (pd == PacketDetail::CHAR) ? 80 : 24; + + size_t start = 0; + while (start < size) + { + size_t end = start + charCount; + if (end > size) + { + end = size; + } + out.printf("%s", indent.c_str()); + if (pd != PacketDetail::CHAR) + { + for (size_t i = start; i < end; i++) + { + out.printf("%02x ", (unsigned char)data[i]); + } + for (size_t i = end; i < start + charCount; i++) + { + out.print(" "); + } + } + for (size_t i = start; i < end; i++) + { + out.printf("%c", data[i] >= 32 && data[i] < 128 ? data[i] : '.'); + } + out.println(); + + start += charCount; + } +} + +void Packet::setPacketType(PacketType pt) +{ + thisPacketType = pt; + thisAllPacketTypes.emplace_back(pt); +} + +void Packet::setPacketTypes() +{ + if (isARP()) + { + setPacketType(PacketType::ARP); + } + else if (isIP()) + { + setPacketType(PacketType::IP); + setPacketType(isIPv4() ? PacketType::IPv4 : PacketType::IPv6); + if (isUDP()) + { + setPacketType(PacketType::UDP); + if (isMDNS()) + { + setPacketType(PacketType::MDNS); + } + if (isDNS()) + { + setPacketType(PacketType::DNS); + } + if (isSSDP()) + { + setPacketType(PacketType::SSDP); + } + if (isDHCP()) + { + setPacketType(PacketType::DHCP); + } + if (isWSDD()) + { + setPacketType(PacketType::WSDD); + } + if (isNETBIOS()) + { + setPacketType(PacketType::NETBIOS); + } + if (isSMB()) + { + setPacketType(PacketType::SMB); + } + if (isOTA()) + { + setPacketType(PacketType::OTA); + } + } + if (isTCP()) + { + setPacketType(PacketType::TCP); + if (isHTTP()) + { + setPacketType(PacketType::HTTP); + } + } + if (isICMP()) + { + setPacketType(PacketType::ICMP); + } + if (isIGMP()) + { + setPacketType(PacketType::IGMP); + } + } + else + { + setPacketType(PacketType::UKNW); + } +} + +const PacketType Packet::packetType() const +{ + return thisPacketType; +} + +const std::vector& Packet::allPacketTypes() const +{ + return thisAllPacketTypes; +} + +void Packet::MACtoString(int dataIdx, StreamString& sstr) const +{ + for (int i = 0; i < 6; i++) + { + sstr.printf_P(PSTR("%02x"), (unsigned char)data[dataIdx + i]); + if (i < 5) + { + sstr.print(':'); + } + } + +} + +void Packet::ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + switch (getARPType()) + { + case 1 : sstr.printf_P(PSTR("who has %s tell %s"), getIP(ETH_HDR_LEN + 24).toString().c_str(), getIP(ETH_HDR_LEN + 14).toString().c_str()); + break; + case 2 : sstr.printf_P(PSTR("%s is at "), getIP(ETH_HDR_LEN + 14).toString().c_str()); + MACtoString(ETH_HDR_LEN + 8, sstr); + break; + } + sstr.printf("\r\n"); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN], packetLength - ETH_HDR_LEN, netdumpDetail); +} + +void Packet::DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("ID=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8)); + sstr.printf_P(PSTR("F=0x%04x "), ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 2)); + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 4)) + { + sstr.printf_P(PSTR("Q=%d "), t); + } + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 6)) + { + sstr.printf_P(PSTR("R=%d "), t); + } + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 8)) + { + sstr.printf_P(PSTR("TR=%d "), t); + } + if (uint16_t t = ntoh16(ETH_HDR_LEN + getIpHdrLen() + 8 + 10)) + { + sstr.printf_P(PSTR("DR=%d "), t); + } + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); +} + +void Packet::UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("%d:%d"), getSrcPort(), getDstPort()); + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getUdpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getUdpHdrLen()], getUdpLen(), netdumpDetail); +} + +void Packet::TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("%d:%d "), getSrcPort(), getDstPort()); + uint16_t flags = getTcpFlags(); + sstr.print('['); + const char chars [] = "FSRPAUECN"; + for (uint8_t i = 0; i < sizeof chars; i++) + if (flags & (1 << i)) + { + sstr.print(chars[i]); + } + sstr.print(']'); + sstr.printf_P(PSTR(" len: %u seq: %u, ack: %u, wnd: %u "), getTcpLen(), getTcpSeq(), getTcpAck(), getTcpWindow()); + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN + getIpHdrLen()], getTcpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen() + getTcpHdrLen()], getTcpLen(), netdumpDetail); +} + +void Packet::ICMPtoString(PacketDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + if (isIPv4()) + { + switch (getIcmpType()) + { + case 0 : sstr.printf_P(PSTR("ping reply")); break; + case 8 : sstr.printf_P(PSTR("ping request")); break; + default: sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType()); break; + } + } + if (isIPv6()) + { + switch (getIcmpType()) + { + case 129 : sstr.printf_P(PSTR("ping reply")); break; + case 128 : sstr.printf_P(PSTR("ping request")); break; + case 135 : sstr.printf_P(PSTR("Neighbour solicitation")); break; + case 136 : sstr.printf_P(PSTR("Neighbour advertisement")); break; + default: sstr.printf_P(PSTR("type(0x%02x)"), getIcmpType()); break; + } + } + sstr.printf("\r\n"); +} + +void Packet::IGMPtoString(PacketDetail, StreamString& sstr) const +{ + switch (getIgmpType()) + { + case 1 : sstr.printf_P(PSTR("Create Group Request")); break; + case 2 : sstr.printf_P(PSTR("Create Group Reply")); break; + case 3 : sstr.printf_P(PSTR("Join Group Request")); break; + case 4 : sstr.printf_P(PSTR("Join Group Reply")); break; + case 5 : sstr.printf_P(PSTR("Leave Group Request")); break; + case 6 : sstr.printf_P(PSTR("Leave Group Reply")); break; + case 7 : sstr.printf_P(PSTR("Confirm Group Request")); break; + case 8 : sstr.printf_P(PSTR("Confirm Group Reply")); break; + case 0x11 : sstr.printf_P(PSTR("Group Membership Query")); break; + case 0x12 : sstr.printf_P(PSTR("IGMPv1 Membership Report")); break; + case 0x22 : sstr.printf_P(PSTR("IGMPv3 Membership Report")); break; + default: sstr.printf_P(PSTR("type(0x%02x)"), getIgmpType()); break; + } + sstr.printf_P(PSTR("\r\n")); +} + +void Packet::IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("%s>%s "), sourceIP().toString().c_str(), destIP().toString().c_str()); + sstr.printf_P(PSTR("Unknown IP type : %d\r\n"), ipType()); + printDetail(sstr, PSTR(" H "), &data[ETH_HDR_LEN], getIpHdrLen(), netdumpDetail); + printDetail(sstr, PSTR(" D "), &data[ETH_HDR_LEN + getIpHdrLen()], getIpTotalLen() - getIpHdrLen(), netdumpDetail); +} + +void Packet::UKNWtoString(PacketDetail, StreamString& sstr) const +{ + sstr.printf_P(PSTR("Unknown EtherType 0x%04x Src : "), ethType()); + MACtoString(0, sstr); + sstr.printf_P(PSTR(" Dst : ")); + MACtoString(6, sstr); + sstr.printf_P(PSTR("\r\n")); +} + +const String Packet::toString() const +{ + return toString(PacketDetail::NONE); +} + + +const String Packet::toString(PacketDetail netdumpDetail) const +{ + StreamString sstr; + sstr.reserve(128); + + sstr.printf_P(PSTR("%d %3s %-4s "), netif_idx, out ? "out" : "in ", packetType().toString().c_str()); + + if (netdumpDetail == PacketDetail::RAW) + { + sstr.printf_P(PSTR(" : ")); + for (auto at : thisAllPacketTypes) + { + sstr.printf_P(PSTR("%s "), at.toString().c_str()); + } + sstr.printf_P(PSTR("\r\n")); + printDetail(sstr, PSTR(" D "), data, packetLength, netdumpDetail); + return sstr; + } + + switch (thisPacketType) + { + case PacketType::ARP : + { + ARPtoString(netdumpDetail, sstr); + break; + } + case PacketType::MDNS : + case PacketType::DNS : + { + DNStoString(netdumpDetail, sstr); + break; + } + case PacketType::SSDP : + case PacketType::DHCP : + case PacketType::WSDD : + case PacketType::NETBIOS : + case PacketType::SMB : + case PacketType::OTA : + case PacketType::UDP : + { + UDPtoString(netdumpDetail, sstr); + break; + } + case PacketType::TCP : + case PacketType::HTTP : + { + TCPtoString(netdumpDetail, sstr); + break; + } + case PacketType::ICMP : + { + ICMPtoString(netdumpDetail, sstr); + break; + } + case PacketType::IGMP : + { + IGMPtoString(netdumpDetail, sstr); + break; + } + case PacketType::IPv4 : + case PacketType::IPv6 : + { + IPtoString(netdumpDetail, sstr); + break; + } + case PacketType::UKNW : + { + UKNWtoString(netdumpDetail, sstr); + break; + } + default : + { + sstr.printf_P(PSTR("Non identified packet\r\n")); + break; + } + } + return sstr; +} + +} // namespace NetCapture diff --git a/libraries/Netdump/src/NetdumpPacket.h b/libraries/Netdump/src/NetdumpPacket.h new file mode 100644 index 000000000..a898ef230 --- /dev/null +++ b/libraries/Netdump/src/NetdumpPacket.h @@ -0,0 +1,314 @@ +/* + NetDump library - tcpdump-like packet logger facility + + Copyright (c) 2019 Herman Reintke. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __NETDUMP_PACKET_H +#define __NETDUMP_PACKET_H + +#include +#include +#include +#include "NetdumpIP.h" +#include "PacketType.h" +#include + +namespace NetCapture +{ + +int constexpr ETH_HDR_LEN = 14; + +class Packet +{ +public: + Packet(unsigned long msec, int n, const char* d, size_t l, int o, int s) + : packetTime(msec), netif_idx(n), data(d), packetLength(l), out(o), success(s) + { + setPacketTypes(); + }; + + enum class PacketDetail + { + NONE, + FULL, + CHAR, + RAW + }; + + const char* rawData() const + { + return data; + } + int getInOut() const + { + return out; + } + time_t getTime() const + { + return packetTime; + } + uint32_t getPacketSize() const + { + return packetLength; + } + uint16_t ntoh16(uint16_t idx) const + { + return data[idx + 1] | (((uint16_t)data[idx]) << 8); + }; + uint32_t ntoh32(uint16_t idx) const + { + return ntoh16(idx + 2) | (((uint32_t)ntoh16(idx)) << 16); + }; + uint8_t byteData(uint16_t idx) const + { + return data[idx]; + } + const char* byteIdx(uint16_t idx) const + { + return &data[idx]; + }; + uint16_t ethType() const + { + return ntoh16(12); + }; + uint8_t ipType() const + { + return isIP() ? isIPv4() ? data[ETH_HDR_LEN + 9] : data[ETH_HDR_LEN + 6] : 0; + }; + uint16_t getIpHdrLen() const + { + return isIPv4() ? (((unsigned char)data[ETH_HDR_LEN]) & 0x0f) << 2 : 40 ; // IPv6 is fixed length + } + uint16_t getIpTotalLen() const + { + return isIP() ? isIPv4() ? ntoh16(ETH_HDR_LEN + 2) : (packetLength - ETH_HDR_LEN) : 0; + } + uint32_t getTcpSeq() const + { + return isTCP() ? ntoh32(ETH_HDR_LEN + getIpHdrLen() + 4) : 0; + } + uint32_t getTcpAck() const + { + return isTCP() ? ntoh32(ETH_HDR_LEN + getIpHdrLen() + 8) : 0; + } + uint16_t getTcpFlags() const + { + return isTCP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 12) : 0; + } + uint16_t getTcpWindow() const + { + return isTCP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 14) : 0; + } + uint8_t getTcpHdrLen() const + { + return isTCP() ? (data[ETH_HDR_LEN + getIpHdrLen() + 12] >> 4) * 4 : 0; + };//Header len is in multiple of 4 bytes + uint16_t getTcpLen() const + { + return isTCP() ? getIpTotalLen() - getIpHdrLen() - getTcpHdrLen() : 0 ; + }; + + uint8_t getIcmpType() const + { + return isICMP() ? data[ETH_HDR_LEN + getIpHdrLen() + 0] : 0; + } + uint8_t getIgmpType() const + { + return isIGMP() ? data[ETH_HDR_LEN + getIpHdrLen() + 0] : 0; + } + uint8_t getARPType() const + { + return isARP() ? data[ETH_HDR_LEN + 7] : 0; + } + bool is_ARP_who() const + { + return (getARPType() == 1); + } + bool is_ARP_is() const + { + return (getARPType() == 2); + } + + uint8_t getUdpHdrLen() const + { + return isUDP() ? 8 : 0; + }; + uint16_t getUdpLen() const + { + return isUDP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 4) : 0; + }; + bool isARP() const + { + return (ethType() == 0x0806); + }; + bool isIPv4() const + { + return (ethType() == 0x0800); + }; + bool isIPv6() const + { + return (ethType() == 0x86dd); + }; + bool isIP() const + { + return (isIPv4() || isIPv6()); + }; + bool isICMP() const + { + return (isIP() && ((ipType() == 1) || (ipType() == 58))); + }; + bool isIGMP() const + { + return (isIP() && (ipType() == 2)); + }; + bool isTCP() const + { + return (isIP() && (ipType() == 6)); + }; + bool isUDP() const + { + return (isIP() && ipType() == 17); + }; + bool isMDNS() const + { + return (isUDP() && hasPort(5353)); + }; + bool isDNS() const + { + return (isUDP() && hasPort(53)); + }; + bool isSSDP() const + { + return (isUDP() && hasPort(1900)); + }; + bool isDHCP() const + { + return (isUDP() && ((hasPort(546) || hasPort(547) || hasPort(67) || hasPort(68)))); + }; + bool isWSDD() const + { + return (isUDP() && hasPort(3702)); + }; + bool isHTTP() const + { + return (isTCP() && hasPort(80)); + }; + bool isOTA() const + { + return (isUDP() && hasPort(8266)); + } + bool isNETBIOS() const + { + return (isUDP() && (hasPort(137) || hasPort(138) || hasPort(139))); + } + bool isSMB() const + { + return (isUDP() && hasPort(445)); + } + NetdumpIP getIP(uint16_t idx) const + { + return NetdumpIP(data[idx], data[idx + 1], data[idx + 2], data[idx + 3]); + }; + + NetdumpIP getIP6(uint16_t idx) const + { + return NetdumpIP((const uint8_t*)&data[idx], false); + }; + NetdumpIP sourceIP() const + { + NetdumpIP ip; + if (isIPv4()) + { + ip = getIP(ETH_HDR_LEN + 12); + } + else if (isIPv6()) + { + ip = getIP6(ETH_HDR_LEN + 8); + } + return ip; + }; + + bool hasIP(NetdumpIP ip) const + { + return (isIP() && ((ip == sourceIP()) || (ip == destIP()))); + } + + NetdumpIP destIP() const + { + NetdumpIP ip; + if (isIPv4()) + { + ip = getIP(ETH_HDR_LEN + 16); + } + else if (isIPv6()) + { + ip = getIP6(ETH_HDR_LEN + 24); + } + return ip; + }; + uint16_t getSrcPort() const + { + return isIP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 0) : 0; + } + uint16_t getDstPort() const + { + return isIP() ? ntoh16(ETH_HDR_LEN + getIpHdrLen() + 2) : 0; + } + bool hasPort(uint16_t p) const + { + return (isIP() && ((getSrcPort() == p) || (getDstPort() == p))); + } + + const String toString() const; + const String toString(PacketDetail netdumpDetail) const; + void printDetail(Print& out, const String& indent, const char* data, size_t size, PacketDetail pd) const; + + const PacketType packetType() const; + const std::vector& allPacketTypes() const; + + +private: + + void setPacketType(PacketType); + void setPacketTypes(); + + void MACtoString(int dataIdx, StreamString& sstr) const; + void ARPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void DNStoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void UDPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void TCPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void ICMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void IGMPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void IPtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + void UKNWtoString(PacketDetail netdumpDetail, StreamString& sstr) const; + + + time_t packetTime; + int netif_idx; + const char* data; + size_t packetLength; + int out; + int success; + PacketType thisPacketType; + std::vector thisAllPacketTypes; +}; + +} // namespace NetCapture + +#endif /* __NETDUMP_PACKET_H */ diff --git a/libraries/Netdump/src/PacketType.cpp b/libraries/Netdump/src/PacketType.cpp new file mode 100644 index 000000000..565aa55f0 --- /dev/null +++ b/libraries/Netdump/src/PacketType.cpp @@ -0,0 +1,43 @@ +/* + PacketType.cpp + + Created on: 19 nov. 2019 + Author: Herman +*/ + +#include + +namespace NetCapture +{ + +PacketType::PacketType() +{ +} + +String PacketType::toString() const +{ + switch (ptype) + { + case PType::ARP : return PSTR("ARP"); + case PType::IP : return PSTR("IP"); + case PType::UDP : return PSTR("UDP"); + case PType::MDNS : return PSTR("MDNS"); + case PType::DNS : return PSTR("DNS"); + case PType::SSDP : return PSTR("SSDP"); + case PType::DHCP : return PSTR("DHCP"); + case PType::WSDD : return PSTR("WSDD"); + case PType::NETBIOS: return PSTR("NBIO"); + case PType::SMB : return PSTR("SMB"); + case PType::OTA : return PSTR("OTA"); + case PType::TCP : return PSTR("TCP"); + case PType::HTTP : return PSTR("HTTP"); + case PType::ICMP : return PSTR("ICMP"); + case PType::IGMP : return PSTR("IGMP"); + case PType::IPv4: return PSTR("IPv4"); + case PType::IPv6: return PSTR("IPv6"); + case PType::UKNW : return PSTR("UKNW"); + default : return PSTR("ERR"); + }; +} + +} /* namespace NetCapture */ diff --git a/libraries/Netdump/src/PacketType.h b/libraries/Netdump/src/PacketType.h new file mode 100644 index 000000000..8f4aa5ce7 --- /dev/null +++ b/libraries/Netdump/src/PacketType.h @@ -0,0 +1,61 @@ +/* + PacketType.h + + Created on: 19 nov. 2019 + Author: Herman +*/ + +#ifndef LIBRARIES_NETDUMP_SRC_PACKETTYPE_H_ +#define LIBRARIES_NETDUMP_SRC_PACKETTYPE_H_ +#include "Arduino.h" + +namespace NetCapture +{ + +class PacketType +{ +public: + + enum PType : int + { + ARP, + IP, + UDP, + MDNS, + DNS, + SSDP, + DHCP, + WSDD, + NETBIOS, + SMB, + OTA, + TCP, + HTTP, + ICMP, + IGMP, + IPv4, + IPv6, + UKNW, + }; + + PacketType(); + PacketType(PType pt) : ptype(pt) {}; + + operator PType() const + { + return ptype; + }; + bool operator==(const PacketType& p) + { + return ptype == p.ptype; + }; + + String toString() const; + +private: + PType ptype; +}; + +} /* namespace NetCapture */ + +#endif /* LIBRARIES_NETDUMP_SRC_PACKETTYPE_H_ */ diff --git a/libraries/esp8266/examples/arduino_new/arduino_new.ino b/libraries/esp8266/examples/arduino_new/arduino_new.ino deleted file mode 100644 index e31c56378..000000000 --- a/libraries/esp8266/examples/arduino_new/arduino_new.ino +++ /dev/null @@ -1,159 +0,0 @@ - -// show arduino_new benefits -// released to public domain -// result is below - -class SomeClass { - public: - SomeClass(const String& s1 = emptyString, const String& s2 = emptyString) { - Serial.printf("SomeClass@%p(%s)(%s)\n", this, s1.c_str(), s2.c_str()); - } - - ~SomeClass() { - Serial.printf("~ SomeClass @%p\n", this); - } -}; - -class oom { - private: - char large [65000]; - public: - oom() { - Serial.printf("this constructor should not be called\n"); - } -}; - -void setup() { - - Serial.begin(115200); - Serial.printf("\n\narduino_new benefits\n\n"); - delay(5000); // avoid too frequent bootloop - - // arduino_new / arduino_newarray api - - Serial.printf("\n----- arduino_new:\n"); - auto an = arduino_new(SomeClass); - delete an; - - Serial.printf("\n----- arduino_new with oom:\n"); - auto anoom = arduino_new(oom); - Serial.printf("nullptr: %p\n", anoom); - delete anoom; - - Serial.printf("\n----- arduino_new with constructor parameters:\n"); - auto ancp = arduino_new(SomeClass, "param1", "param2"); - delete ancp; - - Serial.printf("\n----- arduino_newarray[2]\n"); - auto ana2 = arduino_newarray(SomeClass, 2); - Serial.printf("@:%p s=%zd s(2)=%zd\n", ana2, sizeof(SomeClass), sizeof(SomeClass[2])); - Serial.printf("0: %p\n", &ana2[0]); - Serial.printf("1: %p\n", &ana2[1]); - delete [] ana2; - - Serial.printf("\n----- arduino_newarray[2] (with constructor parameters)\n"); - auto ana2cp = arduino_newarray(SomeClass, 2, "param1"); - Serial.printf("@:%p s=%zd s(2)=%zd\n", ana2cp, sizeof(SomeClass), sizeof(SomeClass[2])); - Serial.printf("0: %p\n", &ana2cp[0]); - Serial.printf("1: %p\n", &ana2cp[1]); - delete [] ana2cp; - - Serial.printf("\n----- arduino_newarray[100000]\n"); - auto anaX = arduino_newarray(SomeClass, 100000); - Serial.printf("@:%p\n", anaX); - - // standard c++ api for new and new[] - - Serial.printf("\n----- new\n"); - auto sn = new SomeClass; - delete sn; - - Serial.printf("\n----- new with oom: (abort() with option 'Exceptions: Disabled (new can abort)'\n"); - auto snoom = new oom; - Serial.printf("nullptr: %p\n", snoom); - delete snoom; - - Serial.printf("\n----- new[2]\n"); - auto sna2 = new SomeClass[2]; - Serial.printf("@:%p s=%zd s(2)=%zd\n", sna2, sizeof(SomeClass), sizeof(SomeClass[2])); - Serial.printf("0: %p\n", &sna2[0]); - Serial.printf("1: %p\n", &sna2[1]); - delete [] sna2; - - Serial.printf("\n----- new[10000] (badly fails with 'Exceptions: Legacy' or '...Disabled'\n"); - auto snaX = new SomeClass[100000]; - Serial.printf("@:%p\n", snaX); -} - -void loop() { -} - -////////////////////////////// -/* - - Result with: - Exceptions: Legacy(new can return nullptr) - - ////////////////////////////// - - arduino_new benefits - - ----- arduino_new: - SomeClass@0x3fff1864()() - ~ SomeClass @0x3fff1864 - - ----- arduino_new with oom: - nullptr: 0 - - ----- arduino_new with constructor parameters: - SomeClass@0x3fff1864(param1)(param2) - ~ SomeClass @0x3fff1864 - - ----- arduino_newarray[2] - SomeClass@0x3fff1868()() - SomeClass@0x3fff1869()() - @: 0x3fff1868 s = 1 s(2) = 2 - 0: 0x3fff1868 - 1: 0x3fff1869 - ~ SomeClass @0x3fff1869 - ~ SomeClass @0x3fff1868 - - ----- arduino_newarray[2](with constructor parameters) - SomeClass@0x3fff1868(param1)() - SomeClass@0x3fff1869(param1)() - @: 0x3fff1868 s = 1 s(2) = 2 - 0: 0x3fff1868 - 1: 0x3fff1869 - ~ SomeClass @0x3fff1869 - ~ SomeClass @0x3fff1868 - - ----- arduino_newarray[100000] - @: 0 - - ----- new - SomeClass@0x3fff1864()() - ~ SomeClass @0x3fff1864 - - ----- new with oom: (abort() with option 'Exceptions: Disabled (new can abort)' - this constructor should not be called - nullptr: 0 - - ----- new[2] - SomeClass@0x3fff1868()() - SomeClass@0x3fff1869()() - @:0x3fff1868 s = 1 s(2) = 2 - 0: 0x3fff1868 - 1: 0x3fff1869 - ~ SomeClass @0x3fff1869 - ~ SomeClass @0x3fff1868 - - ----- new[10000](badly fails with 'Exceptions: Legacy' or '...Disabled' - - Exception(29): - epc1 = 0x402013de epc2 = 0x00000000 epc3 = 0x00000000 excvaddr = 0x00000000 depc = 0x00000000 - - >>> stack >>> - ... - -*/ -///////////////////////////// diff --git a/tests/README.md b/tests/README.md index 7b49bc236..ffd5a4368 100644 --- a/tests/README.md +++ b/tests/README.md @@ -124,7 +124,7 @@ Makefile in tests/device/ directory handles compiling, uploading, and executing Here are some of the supported targets: -- `virtualenv`: prepares Python virtual environment inside tests/device/libaries/BSTest/virtualenv/. This has to be run once on each computer where tests are to be run. This target will use `pip` to install several Python libraries required by the test runner (see tests/device/libaries/BSTest/requirements.txt). +- `virtualenv`: prepares Python virtual environment inside tests/device/libraries/BSTest/virtualenv/. This has to be run once on each computer where tests are to be run. This target will use `pip` to install several Python libraries required by the test runner (see tests/device/libraries/BSTest/requirements.txt). - `test_xxx/test_xxx.ino`: compiles, uploads, and runs the tests defined in `test_xxx/test_xxx.ino` sketch. Some extra options are available, these can be passed as additional arguments to `make`: - `NO_BUILD=1`: don't compile the test. diff --git a/tests/ci/eboot_test.sh b/tests/ci/eboot_test.sh new file mode 100644 index 000000000..0450b0335 --- /dev/null +++ b/tests/ci/eboot_test.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +READELF="$TRAVIS_BUILD_DIR/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-readelf" + +set -ev + +cd $TRAVIS_BUILD_DIR/tools +python3 get.py -q + +cd $TRAVIS_BUILD_DIR/bootloaders/eboot + +"$READELF" -x .data -x .text eboot.elf > git.txt +make clean +make +"$READELF" -x .data -x .text eboot.elf > build.txt +diff git.txt build.txt +if [ $? -ne 0 ]; then + echo ERROR: eboot.elf in repo does not match output from compile. + echo ERROR: Need to rebuild and check in updated eboot. + exit 1 +fi diff --git a/tests/host/Makefile b/tests/host/Makefile index f4513eb22..591a56b1b 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -6,10 +6,26 @@ LIBRARIES_PATH := ../../libraries FORCE32 ?= 1 OPTZ ?= -Os V ?= 0 +R ?= noexec DEFSYM_FS ?= -Wl,--defsym,_FS_start=0x40300000 -Wl,--defsym,_FS_end=0x411FA000 -Wl,--defsym,_FS_page=0x100 -Wl,--defsym,_FS_block=0x2000 -Wl,--defsym,_EEPROM_start=0x411fb000 MAKEFILE = $(word 1, $(MAKEFILE_LIST)) +CXX = $(shell for i in g++-10 g++-9 g++-8 g++; do which $$i > /dev/null && { echo $$i; break; } done) +CC = $(shell for i in gcc-10 gcc-9 gcc-8 gcc; do which $$i > /dev/null && { echo $$i; break; } done) +GCOV = $(shell for i in gcov-10 gcov-9 gcov-8 gcov; do which $$i > /dev/null && { echo $$i; break; } done) +$(warning using $(CXX)) +ifeq ($(CXX),g++) +CXXFLAGS += -std=gnu++11 +else +CXXFLAGS += -std=gnu++17 +endif +ifeq ($(CC),gcc) +CFLAGS += -std=gnu11 +else +CFLAGS += -std=gnu17 +endif + # I wasn't able to build with clang when -coverage flag is enabled, forcing GCC on OS X ifeq ($(shell uname -s),Darwin) CC ?= gcc @@ -23,7 +39,7 @@ GENHTML ?= genhtml 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) -$(warning Cannot compile in 32 bit mode, switching to native mode) +$(warning Cannot compile in 32 bit mode (g++-multilib is missing?), switching to native mode) else N32 = 32 M32 = -m32 @@ -160,9 +176,11 @@ FLAGS += -DHOST_MOCK=1 FLAGS += -DNONOSDK221=1 FLAGS += $(MKFLAGS) FLAGS += -Wimplicit-fallthrough=2 # allow "// fall through" comments to stop spurious warnings -CXXFLAGS += -std=c++11 -fno-rtti $(FLAGS) -funsigned-char -CFLAGS += -std=c99 $(FLAGS) -funsigned-char +FLAGS += $(USERCFLAGS) +CXXFLAGS += -fno-rtti $(FLAGS) -funsigned-char +CFLAGS += $(FLAGS) -funsigned-char LDFLAGS += -coverage $(OPTZ) -g $(M32) +LDFLAGS += $(USERLDFLAGS) VALGRINDFLAGS += --leak-check=full --track-origins=yes --error-limit=no --show-leak-kinds=all --error-exitcode=999 CXXFLAGS += -Wno-error=format-security # cores/esp8266/Print.cpp:42:24: error: format not a string literal and no format arguments [-Werror=format-security] -- (os_printf_plus(not_the_best_way)) #CXXFLAGS += -Wno-format-security # cores/esp8266/Print.cpp:42:40: warning: format not a string literal and no format arguments [-Wformat-security] -- (os_printf_plus(not_the_best_way)) @@ -219,13 +237,14 @@ build-info: # show toolchain version $(CC) -v @echo "CXX: " $(CXX) $(CXX) -v - @echo "GCOV: " $(GCOV) - $(GCOV) -v + @echo "CFLAGS: " $(CFLAGS) + @echo "CXXFLAGS: " $(CXXFLAGS) @echo "----------------------------------" -include $(BINDIR)/.*.d .SUFFIXES: +.PRECIOUS: %.c$(E32).o %.c$(E32).o: %.c $(VERBC) $(CC) $(PREINCLUDES) $(CFLAGS) $(INC_PATHS) -MD -MF $(BINDIR)/.$(notdir $<).d -c -o $@ $< @@ -235,7 +254,7 @@ build-info: # show toolchain version $(BINDIR)/core.a: $(C_OBJECTS) $(CPP_OBJECTS_CORE) ar -rcu $@ $^ - ranlib -c $@ + ranlib $@ $(OUTPUT_BINARY): $(CPP_OBJECTS_TESTS) $(BINDIR)/core.a $(VERBLD) $(CXX) $(DEFSYM_FS) $(LDFLAGS) $^ -o $@ @@ -313,18 +332,19 @@ ssl: # download source and build BearSSL cd ../../tools/sdk/ssl && make native$(N32) ULIBPATHS = $(shell echo $(ULIBDIRS) | sed 's,:, ,g') -USERLIBDIRS = $(shell test -z "$(ULIBPATHS)" || for d in $(ULIBPATHS); do for dd in $$d $$d/src; do test -d $$dd && { echo -I$$dd; echo "userlib: using directory '$$dd'" 1>&2; } done; done) -USERLIBSRCS = $(shell test -z "$(ULIBPATHS)" || for d in $(ULIBPATHS); do for ss in $$d/*.cpp $$d/src/*.cpp; do test -r $$ss && echo $$ss; done; done) +USERLIBDIRS = $(shell test -z "$(ULIBPATHS)" || for d in $(ULIBPATHS); do for dd in $$d $$d/src $$d/src/libmad; do test -d $$dd && { echo -I$$dd; echo "userlib: using directory '$$dd'" 1>&2; } done; done) +USERLIBSRCS = $(shell test -z "$(ULIBPATHS)" || for d in $(ULIBPATHS); do for ss in $$d/*.cpp $$d/src/*.cpp $$d/src/libmad/*.c; do test -r $$ss && echo $$ss; done; done) INC_PATHS += $(USERLIBDIRS) INC_PATHS += -I$(INODIR)/.. -CPP_OBJECTS_CORE_EMU = $(CPP_SOURCES_CORE_EMU:.cpp=.cpp$(E32).o) $(USERLIBSRCS:.cpp=.cpp$(E32).o) +CPP_OBJECTS_CORE_EMU = $(CPP_SOURCES_CORE_EMU:.cpp=.cpp$(E32).o) $(USERLIBSRCS:.cpp=.cpp$(E32).o) $(USERCXXSOURCES:.cpp=.cpp$(E32).o) +C_OBJECTS_CORE_EMU = $(USERCSOURCES:.c=.c$(E32).o) -bin/fullcore.a: $(C_OBJECTS) $(CPP_OBJECTS_CORE_EMU) +bin/fullcore$(E32).a: $(C_OBJECTS) $(CPP_OBJECTS_CORE_EMU) $(C_OBJECTS_CORE_EMU) $(VERBAR) ar -rcu $@ $^ - $(VERBAR) ranlib -c $@ + $(VERBAR) ranlib $@ -%: %.ino.cpp$(E32).o bin/fullcore.a - $(VERBLD) $(CXX) $(LDFLAGS) $< bin/fullcore.a $(LIBSSL) -o $@ +%: %.ino.cpp$(E32).o bin/fullcore$(E32).a + $(VERBLD) $(CXX) $(LDFLAGS) $< bin/fullcore$(E32).a $(LIBSSL) -o $@ @echo "----> $@ <----" ################################################# @@ -333,7 +353,12 @@ ifeq ($(INO),) %: %.ino @# recursive 'make' with paths - $(MAKE) -f $(MAKEFILE) MKFLAGS=-Wextra INODIR=$(dir $@) INO=$(notdir $@) $(BINDIR)/$(notdir $@)/$(notdir $@) + $(MAKE) -f $(MAKEFILE) MKFLAGS=-Wextra INODIR=$(dir $@) INO=$(notdir $@) $(BINDIR)/$(notdir $@)/$(notdir $@) \ + USERCFLAGS="$(USERCFLAGS)" \ + USERCSOURCES="$(USERCSOURCES)" \ + USERCXXSOURCES="$(USERCXXSOURCES)" \ + USERLDFLAGS="$(USERLDFLAGS)" + test "$(R)" = noexec || $(BINDIR)/$(notdir $@)/$(notdir $@) $(R) @# see below the new build rule with fixed output path outside from core location ##################### diff --git a/tests/host/README.txt b/tests/host/README.txt index 4e947a954..abcbb511a 100644 --- a/tests/host/README.txt +++ b/tests/host/README.txt @@ -11,7 +11,7 @@ Sketch emulation on host This environment let compile esp8266/Arduino sketches into native environment. Network (tcp, udp, including ssl and multicast) is linked to -local host interfaces. WiFi is trivialy emulated and reported as "just" +local host interfaces. WiFi is trivially emulated and reported as "just" already connected and usable. Currently network emulation is a complete rewrite of @@ -24,7 +24,7 @@ stdin is connected to UART0(RX) and stdout is connected to UART0(TX). UART1(TX) writes to stderr. Reading from stdin happens in non-blocking raw mode, that means each character is directly injected into the UART FIFO without any buffering in the console. The command line switch -c -can be used to stop the emulation from intersepting CTRL-C (SIGINT). +can be used to stop the emulation from intercepting CTRL-C (SIGINT). How to compile and run a sketch ------------------------------- @@ -45,7 +45,7 @@ Optional 'V=1' enables makefile verbosity Optional 'D=1' enables core debug (same as IDE's tools menu) Optional 'OPTZ=-O2' will update gcc -O option (default is -Os, D=1 implies -O0) Optional 'FORCE32=0' will use native/default gcc (default is FORCE32=1 unless gcc-multilib is not detected) - +Optional 'R=""' (ex: R="-b -v") runs the executable with given options after build Non exhaustive list of working examples: make D=1 ../../libraries/ESP8266WiFi/examples/udp/udp @@ -64,7 +64,7 @@ Compile other sketches: or: ULIBDIRS=/path/to/your/arduino/libraries/lib1:/path/to/another/place/lib2 make D=1 /path/to/your/sketchdir/sketch/sketch - or (preferred): + or: export ULIBDIRS=/path/to/your/arduino/libraries/lib1:/path/to/another/place/lib2 export D=1 export OPTZ=-O2 @@ -72,6 +72,12 @@ Compile other sketches: make /path/to/your/sketchdir/sketch/sketch ./bin/sketch/sketch +Additional flags: + make USERCFLAGS="-I some/where -I some/where/else" \ + USERCSOURCES="some/where/file1.c some/where/file2.c ..." \ + USERCXXSOURCES="some/where/file3.cpp some/where/file4.cpp ..." \ + USERLDFLAGS="-L some/where/around" \ + ... Executable location is always in bin/. Once a sketch is compiled, just run it: bin/sketch/sketch @@ -96,7 +102,7 @@ Make fun, propose PRs. - SDCARD on Host filesystem ? or in an image ? - nice curses interface to display/change gpios ? - display device emulation (like ssd1306) -- optionaly use arduino-builder ? +- optionally use arduino-builder ? - store sketch objects and binaries outside from the source directories (done for sketches) - compile and use lwIP on host - easily debug HTTP classes diff --git a/tests/platformio.sh b/tests/platformio.sh index 2aa81a656..d85f18dc8 100755 --- a/tests/platformio.sh +++ b/tests/platformio.sh @@ -14,7 +14,7 @@ function install_platformio() rm -rf ~/.platformio/packages/toolchain-xtensa mv $TRAVIS_BUILD_DIR/tools/xtensa-lx106-elf ~/.platformio/packages/toolchain-xtensa mv .save ~/.platformio/packages/toolchain-xtensa/package.json - python -c "import json; import os; fp=open(os.path.expanduser('~/.platformio/platforms/espressif8266/platform.json'), 'r+'); data=json.load(fp); data['packages']['framework-arduinoespressif8266']['version'] = '*'; fp.seek(0); fp.truncate(); json.dump(data, fp); fp.close()" + python -c "import json; import os; fp=open(os.path.expanduser('~/.platformio/platforms/espressif8266/platform.json'), 'r+'); data=json.load(fp); data['packages']['framework-arduinoespressif8266']['version'] = '*'; del data['packages']['framework-arduinoespressif8266']['owner'];fp.seek(0); fp.truncate(); json.dump(data, fp); fp.close()" ln -sf $TRAVIS_BUILD_DIR ~/.platformio/packages/framework-arduinoespressif8266 # Install dependencies: # - esp8266/examples/ConfigFile @@ -39,7 +39,7 @@ function build_sketches_with_platformio() local sketchdirname=$(basename $sketchdir) local sketchname=$(basename $sketch) if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then - echo "Skipping $sketch, beacause it is not the main sketch file"; + echo "Skipping $sketch, because it is not the main sketch file"; continue fi; if [[ -f "$sketchdir/.test.skip" ]]; then diff --git a/tests/restyle.sh b/tests/restyle.sh index 86c1f337d..c50c5f641 100755 --- a/tests/restyle.sh +++ b/tests/restyle.sh @@ -14,6 +14,7 @@ all=" libraries/ESP8266mDNS libraries/Wire cores/esp8266/core_esp8266_si2c.cpp +libraries/Netdump " # core diff --git a/tools/boards.txt.py b/tools/boards.txt.py index 7be8f695d..f2b99fdc1 100755 --- a/tools/boards.txt.py +++ b/tools/boards.txt.py @@ -288,6 +288,7 @@ boards = collections.OrderedDict([ 'flashfreq_40', '1M', '2M', 'led', + 'sdk', ], 'desc': [ 'ESP8285 (`datasheet `__) is a multi-chip package which contains ESP8266 and 1MB flash. All points related to bootstrapping resistors and recommended circuits listed above apply to ESP8285 as well.', '', @@ -994,11 +995,8 @@ macros = { ]), 'exception_menu': collections.OrderedDict([ - ( '.menu.exception.legacy', 'Legacy (new can return nullptr)' ), - ( '.menu.exception.legacy.build.exception_flags', '-fno-exceptions' ), - ( '.menu.exception.legacy.build.stdcpp_lib', '-lstdc++' ), - ( '.menu.exception.disabled', 'Disabled (new can abort)' ), - ( '.menu.exception.disabled.build.exception_flags', '-fno-exceptions -DNEW_OOM_ABORT' ), + ( '.menu.exception.disabled', 'Disabled (new aborts on oom)' ), + ( '.menu.exception.disabled.build.exception_flags', '-fno-exceptions' ), ( '.menu.exception.disabled.build.stdcpp_lib', '-lstdc++' ), ( '.menu.exception.enabled', 'Enabled' ), ( '.menu.exception.enabled.build.exception_flags', '-fexceptions' ),