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

118 lines
6.7 KiB
Markdown

# 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:
```ini
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.