118 lines
6.7 KiB
Markdown
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.
|