6.7 KiB
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_MODEandPAYLOAD_CODEC_TEST.
Verification Snapshot
pio run -e production: passed; RAM95588bytes, flash1182653bytes.pio run -e debug: passed; RAM95628bytes, flash1189501bytes.pio run -e test: passed; RAM95060bytes, flash1182177bytes.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 indocs/engineering/size-baseline.json.python tools/verify.py: failed only at static analysis;pio check -e production --fail-on-defect=highexits 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 word0x34. - 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.BatchUpchunk header:[batch_id_le:2][chunk_index:1][chunk_count:1][total_len_le:2][chunk_payload...].- Payload codec: schema v4, magic
0xDDB3, 30-bitpresent_mask,n == 0sync-request support. AckDownpayload length: 7 bytes,[flags:1][batch_id_be:2][epoch_utc_be:4].- ACK time is accepted only when
flags bit0is set and epoch is at leastMIN_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.jsonhad 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_APandWEB_AUTH_REQUIRE_STAare bothtrue.- 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.