Files
DD3-LoRa-Bridge-MultiSender/docs/engineering/current-state.md
T
acidburns 99c07ecda6
CI / Non-hardware verification (push) Has been cancelled
Add firmware verification harness
2026-07-13 11:10:19 +02:00

6.7 KiB

Current State

Assessment date: 2026-07-13 Branch assessed: lora-refactor Commit assessed: def0916 refactor lora payload timing

Architecture Verification

Assumption Status Evidence
src/main.cpp is the thin top-level coordinator. Verified Initializes shared services, creates role configs, delegates loop() to role objects.
Sender runtime is owned by SenderStateMachine. Verified src/sender_state_machine.h/.cpp own sender state, queueing, sync, ACK, retry, and sleep loop.
Receiver runtime is owned by ReceiverPipeline. Verified src/receiver_pipeline.h/.cpp own receive, reassembly, ACK, duplicate, MQTT, SD, and web update flow.
One firmware image supports both roles. Verified detect_role() selects role at boot; loop() dispatches sender or receiver in one image.
PlatformIO is the canonical build system. Verified platformio.ini defines all firmware environments.
Arduino remains the framework. Verified [env] framework = arduino.
pioarduino Espressif platform remains pinned. Verified Platform URL is https://github.com/pioarduino/platform-espressif32/releases/download/51.03.07/platform-espressif32.zip.
Existing environments include production, debug, and test. Verified platformio.ini has exactly those project environments.
Payload schema v4 is current. Verified lib/dd3_legacy_core/src/payload_codec.cpp uses kSchema = 4; payload tests use schema v4 vectors.
Existing golden vectors remain relevant. Verified by inspection test/test_payload_codec contains schema v4 golden vectors.
Power behavior was changed by this task. Not changed This harness task did not edit firmware source.

Current Build Configuration

  • PlatformIO Core observed locally: 6.1.18.
  • Expected PlatformIO Core for CI and reproducible verification: 6.1.18.
  • PlatformIO emits a local warning that multiple/obsolete cores may be installed: Obsolete PIO Core v6.1.18 is used (previous was 6.1.19).
  • Board: ttgo-lora32-v1.
  • Framework: Arduino.
  • Environments:
    • production: serial debug off, light sleep on.
    • debug: serial diagnostics on, real meter and real LoRa.
  • test: ENABLE_TEST_MODE and PAYLOAD_CODEC_TEST.

Verification Snapshot

  • pio run -e production: passed; RAM 95588 bytes, flash 1182653 bytes.
  • pio run -e debug: passed; RAM 95628 bytes, flash 1189501 bytes.
  • pio run -e test: passed; RAM 95060 bytes, flash 1182177 bytes.
  • pio test -e test --without-uploading --without-testing: passed compile-only for all seven embedded Unity suites.
  • python tools/check_size.py: passed with current artifact baselines in docs/engineering/size-baseline.json.
  • python tools/verify.py: failed only at static analysis; pio check -e production --fail-on-defect=high exits 1 because cppcheck fails on the Xtensa C++ toolchain package header.
  • pio check -e production --fail-on-defect=high --skip-packages: also failed because cppcheck reports high defects in third-party ArduinoJson headers under .pio/libdeps.
  • The strict static-analysis failure is intentionally preserved until analyzer scope and third-party dependency policy are reviewed.

Resolved Dependency Baseline

Observed with pio pkg list after forcing UTF-8 console output:

Dependency Configured requirement Resolved version
pioarduino platform-espressif32 release URL 51.03.07 51.3.6
Arduino ESP32 framework platform-provided 3.0.7
ESP32 Arduino libs platform-provided 5.1.0+sha.632e0c2a9f
sandeepmistry/LoRa ^0.8.0 0.8.0
bblanchon/ArduinoJson ^6.21.5 6.21.6
adafruit/Adafruit SSD1306 ^2.5.9 2.5.17
adafruit/Adafruit GFX Library ^1.11.9 1.12.6
Adafruit BusIO transitive 1.17.4
knolleary/PubSubClient ^2.8 2.8.0
throwtheswitch/Unity ^2.6.1 2.6.1

Proposed exact direct pins for a separate dependency-only commit:

sandeepmistry/LoRa@0.8.0
bblanchon/ArduinoJson@6.21.6
adafruit/Adafruit SSD1306@2.5.17
adafruit/Adafruit GFX Library@1.12.6
knolleary/PubSubClient@2.8.0
throwtheswitch/Unity@2.6.1

Hardware and Persistence Contracts

  • Role pin: GPIO14; HIGH is sender, LOW is receiver.
  • OLED control pin: GPIO13.
  • LoRa defaults in include/config.h: 868 MHz, SF12, BW 125 kHz, coding rate 4/5, sync word 0x34.
  • Configured sender short ID: 0x6540; configured receiver short ID: 0x7EB4.
  • Preferences namespace: dd3cfg.
  • Preferences keys: ssid, pass, mqhost, mqport, mquser, mqpass, ntp1, ntp2, webuser, webpass, valid.
  • CSV current header: ts_utc,ts_hms_local,p_w,p1_w,p2_w,p3_w,e_kwh,bat_v,bat_pct,rssi,snr,err_m,err_d,err_tx,err_last.

Protocol Contracts

  • LoRa frame: [msg_kind:1][device_short_id_be:2][payload...][crc16_ccitt_be:2].
  • LoraMsgKind: BatchUp=0, AckDown=1.
  • BatchUp chunk header: [batch_id_le:2][chunk_index:1][chunk_count:1][total_len_le:2][chunk_payload...].
  • Payload codec: schema v4, magic 0xDDB3, 30-bit present_mask, n == 0 sync-request support.
  • AckDown payload length: 7 bytes, [flags:1][batch_id_be:2][epoch_utc_be:4].
  • ACK time is accepted only when flags bit0 is set and epoch is at least MIN_ACCEPTED_EPOCH_UTC.
  • MQTT state topic: smartmeter/<device_id>/state.
  • MQTT fault topic: smartmeter/<device_id>/faults.
  • Test MQTT topic: smartmeter/<device_id>/test.
  • Home Assistant discovery topic: homeassistant/sensor/<device_id>/<key>/config.

Repository Shape

  • lib/dd3_legacy_core: shared legacy logic for data model, HTML utilities, JSON codec, and payload codec.
  • lib/dd3_transport_logic: pure-ish transport helpers for LoRa frame, HA discovery JSON, and batch reassembly.
  • test/: seven embedded Unity suites, compile-only runnable without a board.
  • .vscode/: generated PlatformIO files plus extension recommendations. .vscode/extensions.json had pre-existing local modifications before this task.
  • Existing Gitea configuration: none found before this task.

Security Assessment

Confirmed current behavior:

  • AP password default is changeme123.
  • Web UI defaults are admin/admin.
  • WEB_AUTH_REQUIRE_AP and WEB_AUTH_REQUIRE_STA are both true.
  • Wi-Fi, MQTT, NTP, and web-auth credentials are stored through ESP32 Preferences in namespace dd3cfg.
  • The source does not implement LoRa cryptographic authentication; it uses CRC, configured sender/receiver IDs, batch IDs, and ACK rate limiting.
  • The source contains no OTA implementation or firmware signing path.
  • No project configuration for secure boot or flash encryption was found.

Recommendations are in docs/engineering/risk-register.md; authentication, encryption, secure boot, flash encryption, OTA signing, and eFuse changes need a separate approved task.