Files
MeshCore/platformio.ini
T
mikecarper b699e552ec Add secure host CLI bridge and harden OTA workflows
Expose the Full Companion terminal over TCP and add an authenticated, replay-resistant host command service with documented CPU temperature, reboot, and allowlisted program examples.\n\nImprove LoRa OTA diagnostics and persistent CLI handling, reduce clock correction drift to ten minutes, and make mOTA stream flush behavior an explicit transport policy with regression coverage.
2026-08-23 15:29:30 -07:00

331 lines
12 KiB
INI

; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
extra_configs =
variants/*/platformio.ini
platformio.local.ini
[arduino_base]
framework = arduino
monitor_speed = 115200
lib_deps =
SPI
Wire
;jgromes/RadioLib @ ^7.7.1
https://github.com/jgromes/RadioLib.git#6d8934836678d8894e3d556550475b37dce3e2b6
rweather/Crypto @ ^0.4.0
adafruit/RTClib @ ^2.1.3
melopero/Melopero RV3028 @ ^1.1.0
electroniccats/CayenneLPP @ 1.6.1
build_flags = -w -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1
-D LORA_FREQ=869.618
-D LORA_BW=62.5
-D LORA_SF=8
-D ENABLE_ADVERT_ON_BOOT=1
-D ENABLE_PRIVATE_KEY_IMPORT=1 ; NOTE: comment these out for more secure firmware
-D ENABLE_PRIVATE_KEY_EXPORT=1
-D RADIOLIB_EXCLUDE_CC1101=1
-D RADIOLIB_EXCLUDE_RF69=1
-D RADIOLIB_EXCLUDE_SX1231=1
-D RADIOLIB_EXCLUDE_SI443X=1
-D RADIOLIB_EXCLUDE_RFM2X=1
-D RADIOLIB_EXCLUDE_SX128X=1
-D RADIOLIB_EXCLUDE_AFSK=1
-D RADIOLIB_EXCLUDE_AX25=1
-D RADIOLIB_EXCLUDE_HELLSCHREIBER=1
-D RADIOLIB_EXCLUDE_MORSE=1
-D RADIOLIB_EXCLUDE_APRS=1
-D RADIOLIB_EXCLUDE_BELL=1
-D RADIOLIB_EXCLUDE_RTTY=1
-D RADIOLIB_EXCLUDE_SSTV=1
build_src_filter =
+<*.cpp>
+<helpers/*.cpp>
; MQTT-only sources (need Timezone/NTPClient); observer envs add them back.
-<helpers/MQTTMessageBuilder.cpp>
-<helpers/JWTHelper.cpp>
+<helpers/radiolib/*.cpp>
+<helpers/bridges/BridgeBase.cpp>
+<helpers/ui/MomentaryButton.cpp>
; ----------------- ESP32 ---------------------
[esp32_base]
extends = arduino_base
platform = platformio/espressif32@6.11.0
monitor_filters = esp32_exception_decoder
; OTA is available on every ESP32 variant (A/B via esp_ota; the detools-sequential apply decodes into the
; inactive slot). The received .mota is staged in the INACTIVE OTA slot (OtaStoreFlashEsp32), not RAM, so
; deltas/full images of any size fetch over the air (RX-safe, sector-coalesced). The build always includes
; it; for `applydelta` to actually run, the board must use a dual-app/OTA partition table
; (board_build.partitions) with two app slots + otadata (boards without one fetch-refuse cleanly).
; pio_endf appends the EndF self-identity trailer. (nRF52 single-slot OTA is enabled per-board, not here -
; it needs a custom bootloader; RP2040/STM32 have no A/B path yet.)
extra_scripts =
pre:scripts/generate_webconfig_html.py
pre:scripts/portable_esp32_link.py
merge-bin.py
post:tools/mota/pio_endf.py
build_flags = ${arduino_base.build_flags}
-D ESP32_PLATFORM
-D ENABLE_OTA=1
-D OTA_FLASH_STORE=1
-D OTA_FOLDER_SERIAL ; `ota folder on` relays a host folder of .mota over the USB console (no extra HW)
; Route esp_transport_ws_init through src/helpers/ESP32WsTransportFix.cpp to
; fix a heap-overflow in the precompiled IDF 4.4 WS transport (see that file).
-Wl,--wrap=esp_transport_ws_init
; -D ESP32_CPU_FREQ=80 ; change it to your need
lib_deps = ${arduino_base.lib_deps}
ESP32Async/ESPAsyncWebServer @ 3.10.3
bblanchon/ArduinoJson @ 7.4.3
build_src_filter = ${arduino_base.build_src_filter}
+<helpers/esp32/WebConfigServer.cpp>
+<helpers/esp32/PortableErrorStrings.cpp>
+<helpers/esp32/WiFiOtaSeeder.cpp>
+<helpers/ota/*.cpp>
+<helpers/ota/detools/detools.c>
[esp32_ota]
lib_deps =
ESP32Async/ESPAsyncWebServer @ 3.10.3
file://arch/esp32/AsyncElegantOTA
; esp32c6 uses arduino framework 3.x
; WARNING: experimental. May not work as stable as other platforms.
[esp32c6_base]
extends = esp32_base
platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.13-1/platform-espressif32.zip
; ----------------- NRF52 ---------------------
[nrf52_base]
extends = arduino_base
platform = nordicnrf52
platform_packages =
; use internal fork that includes patch to ble stack to prevent firmware lockup during rapid connect/disconnect
; https://github.com/meshcore-dev/MeshCore/pull/1177
; https://github.com/meshcore-dev/MeshCore/pull/1295
framework-arduinoadafruitnrf52 @ https://github.com/meshcore-dev/Adafruit_nRF52_Arduino#d541301
platformio/toolchain-gccarmnoneeabi@^1.140201.0
extra_scripts = create-uf2.py
pre:scripts/nrf52_internal_bootloader_link.py
build_flags = ${arduino_base.build_flags}
-D NRF52_PLATFORM
-D LFS_NO_ASSERT=1
-D EXTRAFS=1
-D MESH_NRF52_LOOP_STACK_WORDS=2048
-Wl,--wrap=xTaskCreate
-D USE_CC310_HW_CRYPTO=1
lib_deps =
${arduino_base.lib_deps}
https://github.com/oltaco/CustomLFS#0.2.3
; Vendored ESP-IDF MQTT client; the LDF otherwise pulls it into non-ESP builds.
lib_ignore = PsychicMqttClient
; Shared LoRa OTA recipe for nRF52840 variants. nRF52840 has no A/B slot, so the update is
; applied in place by the custom OTAFIX bootloader (in-place detools); the app only stages + verifies +
; approves it. OtaFlashLayout_nrf52.h derives the safe ceiling from the linked app region and secondary
; storage: internal ExtraFS stays protected at 0xD4000; QSPI/no-ExtraFS roles can stage through 0xED000.
; The EndF hook records that resolved geometry so motatool can size each in-place patch without target-name
; heuristics. An older bootloader makes the app stage below 0xD4000; packages sized for the expanded window
; require the updated OTAFIX bootloader (or a legacy motatool override). The device must run the matching
; OTAFIX bootloader for `applydelta` to actually apply. (detools.c is intentionally NOT built into the app -
; only the bootloader decodes.) The [rak4631] base defines this same recipe inline because it carries
; board-specific extras (fix_bsec_lib.py, BSEC lib) and a fixed post-script order.
[nrf52_lora_ota]
extends = nrf52_base
extra_scripts = ${nrf52_base.extra_scripts}
post:tools/mota/pio_endf.py
build_flags = ${nrf52_base.build_flags}
-D ENABLE_OTA=1
-D OTA_FLASH_STORE=1
-D OTA_FOLDER_SERIAL ; `ota folder on` relays a host folder of .mota over the USB console (no extra HW)
build_src_filter = ${nrf52_base.build_src_filter}
+<helpers/ota/*.cpp>
lib_deps = ${nrf52_base.lib_deps}
; Opt-in for repeater environments whose exact board has dedicated QSPI flash
; and a matching QSPI-capable OTAFIX bootloader. The raw OTA store owns that
; chip, so companion builds that mount QSPI as LittleFS must not use this flag.
[nrf52_qspi_ota]
build_flags =
-D OTA_QSPI_STORE=1
; RAK15001 is a single-data-line GD25Q16C connected to the WisBlock sensor
; SPI bus. The nRF QSPI peripheral can issue its FAST_READ and page-program
; commands in single-line mode, but the module's 15 MHz limit requires an
; 8 MHz clock. Exact JEDEC matching makes a missing or different shared-bus
; device fail closed instead of being mistaken for an OTA store.
[nrf52_rak15001_ota]
build_flags =
${nrf52_qspi_ota.build_flags}
-D OTA_QSPI_SHARED_WISBLOCK_SPI=1
-D OTA_QSPI_SCK_ARDUINO_PIN=3
-D OTA_QSPI_CS_ARDUINO_PIN=26
-D OTA_QSPI_IO0_ARDUINO_PIN=30
-D OTA_QSPI_IO1_ARDUINO_PIN=29
-D OTA_QSPI_IO2_NOT_CONNECTED=1
-D OTA_QSPI_IO3_NOT_CONNECTED=1
-D OTA_QSPI_SCK_FREQUENCY=NRF_QSPI_FREQ_32MDIV4
-D OTA_QSPI_EXPECTED_JEDEC_ID=0xC84015UL
-D OTA_QSPI_EXPECTED_SIZE=2097152UL
; Compatibility alias retained for existing nRF52840 board definitions.
[rak4631_hw]
extends = nrf52_lora_ota
extra_scripts = ${nrf52_lora_ota.extra_scripts}
build_flags = ${nrf52_lora_ota.build_flags}
build_src_filter = ${nrf52_lora_ota.build_src_filter}
lib_deps = ${nrf52_lora_ota.lib_deps}
; ----------------- RP2040 ---------------------
[rp2040_base]
extends = arduino_base
upload_protocol = picotool
board_build.core = earlephilhower
platform = https://github.com/maxgerhardt/platform-raspberrypi.git ; framework-arduinopico @ 1.50600.0+sha.6a1d13e9
build_flags = ${arduino_base.build_flags}
-D RP2040_PLATFORM
; ----------------- STM32 ----------------------
[stm32_base]
extends = arduino_base
platform = ststm32
extra_scripts = post:arch/stm32/build_hex.py
build_flags = ${arduino_base.build_flags}
-D STM32_PLATFORM
-I src/helpers/stm32
-I $PROJECT_PACKAGES_DIR/framework-arduinoststm32/libraries/SubGhz/src
build_src_filter = ${arduino_base.build_src_filter}
+<helpers/stm32>
lib_deps = ${arduino_base.lib_deps}
file://arch/stm32/Adafruit_LittleFS_stm32
SubGhz
[sensor_base]
build_flags =
-D ENV_INCLUDE_GPS=1
-D ENV_INCLUDE_AHTX0=1
-D ENV_INCLUDE_BME280=1
-D ENV_INCLUDE_BMP280=1
-D ENV_INCLUDE_SHTC3=1
-D ENV_INCLUDE_SHT4X=1
-D ENV_INCLUDE_LPS22HB=1
-D ENV_INCLUDE_INA3221=1
-D ENV_INCLUDE_INA219=1
-D ENV_INCLUDE_INA226=1
-D ENV_INCLUDE_INA260=1
-D ENV_INCLUDE_MLX90614=1
-D ENV_INCLUDE_VL53L0X=1
-D ENV_INCLUDE_BME680=1
-D ENV_INCLUDE_BMP085=1
lib_deps =
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
robtillaart/INA226 @ ^0.6.4
adafruit/Adafruit INA260 Library @ ^1.5.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
adafruit/Adafruit BMP280 Library @ ^2.6.8
adafruit/Adafruit SHTC3 Library @ ^1.0.1
sensirion/Sensirion I2C SHT4x @ ^1.1.2
arduino-libraries/Arduino_LPS22HB @ ^1.0.2
adafruit/Adafruit MLX90614 Library @ ^2.1.5
adafruit/Adafruit_VL53L0X @ ^1.2.4
stevemarple/MicroNMEA @ ^2.0.6
adafruit/Adafruit BME680 Library @ ^2.0.4
adafruit/Adafruit BMP085 Library @ ^1.2.4
; Lean nRF52 LoRa OTA roles with onboard GPS use this external-sensor trim.
; Board-native GPS, radio, display, buttons, battery monitoring, and other board
; telemetry remain.
[nrf52_no_external_sensors_keep_gps]
build_flags =
-UENV_INCLUDE_AHTX0
-UENV_INCLUDE_BME280
-UENV_INCLUDE_BMP280
-UENV_INCLUDE_SHTC3
-UENV_INCLUDE_SHT4X
-UENV_INCLUDE_LPS22HB
-UENV_INCLUDE_INA3221
-UENV_INCLUDE_INA219
-UENV_INCLUDE_INA226
-UENV_INCLUDE_INA260
-UENV_INCLUDE_MLX90614
-UENV_INCLUDE_VL53L0X
-UENV_INCLUDE_BME680
-UENV_INCLUDE_BMP085
-UENV_INCLUDE_RAK12035
-UENV_INCLUDE_BME680_BSEC
lib_deps =
stevemarple/MicroNMEA @ ^2.0.6
; Lean nRF52 LoRa OTA roles without onboard GPS also remove the GPS provider.
[nrf52_no_external_sensors]
build_flags =
${nrf52_no_external_sensors_keep_gps.build_flags}
-UENV_INCLUDE_GPS
; ----------------- TESTING ---------------------
; Host GoogleTest suites for the fork's pure logic. See test/README.md.
; Run: `pio test -e native` (all) or `pio test -e native -f <suite>` (one).
[env:native]
platform = native
test_framework = googletest
build_flags = -std=c++17
-I src
-I test/mocks
-D OTA_FETCH_PIPELINE=4
test_build_src = yes
test_ignore = test_kiss_modem
build_src_filter =
-<*>
+<../src/Utils.cpp>
+<../src/helpers/MQTTPayloadBuilder.cpp>
+<../src/Packet.cpp>
+<../src/Dispatcher.cpp>
+<../src/Identity.cpp>
+<../src/Mesh.cpp>
+<../src/helpers/TxtDataHelpers.cpp>
+<../src/helpers/StaticPoolPacketManager.cpp>
+<../src/helpers/ota/MerkleTree.cpp>
+<../src/helpers/ota/MotaContainer.cpp>
+<../src/helpers/ota/FirmwareInfo.cpp>
+<../src/helpers/ota/MotaSourceSerial.cpp>
+<../src/helpers/ota/FolderMotaStore.cpp>
+<../src/helpers/ota/OtaProtocol.cpp>
+<../src/helpers/ota/OtaManager.cpp>
+<../src/helpers/ota/detools/detools.c>
+<../src/helpers/UserGpio.cpp>
+<../src/helpers/ConfigSerializer.cpp>
+<../src/helpers/ArduinoSerialInterface.cpp>
lib_deps =
google/googletest @ 1.17.0
bblanchon/ArduinoJson @ 7.4.3
[env:native_kiss_modem]
platform = native
test_framework = googletest
build_flags = -std=c++17
-I test/mocks
-I src
-I examples/kiss_modem
test_build_src = yes
test_filter = test_kiss_modem
build_src_filter =
-<*>
+<../examples/kiss_modem/KissModem.cpp>
lib_deps =
google/googletest @ 1.17.0