104 lines
6.3 KiB
Markdown
104 lines
6.3 KiB
Markdown
# TODO
|
|||
|
|
|
||
|
|
Engineering to-do list. The reviewer-facing open items live in
|
||
|
|
`docs/01-requirements-traceability.md` ("Open items"); this file is the working list behind them.
|
||
|
|
|
||
|
|
## Waiting on hardware
|
||
|
|
|
||
|
|
### Over-the-air check of the GN lifetime fix (added 2026-09-11)
|
||
|
|
|
||
|
|
`geonet.c` now writes GN lifetime `0x05` (1 s) instead of `0x83`, which decoded to 3200 s. Changed
|
||
|
|
in both `obu-firmware` and `obu-cam-transmistter`. Both still build (IDF 6.1 / 5.5.4), and the
|
||
|
|
compiled `geonet_wrap_shb` stores the new byte, but it has not been seen on air yet. Nothing else
|
||
|
|
reads this byte (`gn_unwrap.c` ignores it, the app never sees GN headers), so the app does not
|
||
|
|
need updating alongside the firmware.
|
||
|
|
|
||
|
|
Needs: the phone with the app, the OBU ESP32-C5, and a **second** ESP32-C5 running
|
||
|
|
`its-g5-receiver-firmware` to capture with.
|
||
|
|
|
||
|
|
- [ ] Flash `obu-firmware` (see `obu-firmware/FLASHING.md`).
|
||
|
|
- [ ] Connect the phone, let it send CAMs, and confirm the CAM Pinger's `tx fail` counter stays 0.
|
||
|
|
- [ ] Capture with the receiver into `its-g5-receiver-firmware/recordings/`.
|
||
|
|
- [ ] Run `python obu-firmware/test/pcap_gn_tally.py its-g5-receiver-firmware/recordings/<capture>.pcap`.
|
||
|
|
The rows for the phone's pseudonym MACs must show SHB, port 2001, lifetime `0x05`, exactly
|
||
|
|
like every other station's CAMs.
|
||
|
|
- [ ] While the phone is connected: real-station CAMs/DENMs still reach the app (RX path unchanged).
|
||
|
|
|
||
|
|
Partial check possible with one board and no phone: flash it, `idf.py -p COMx monitor`, and look
|
||
|
|
for `OCB @ 5900 MHz - TX/RX armed`. That proves the new build boots and brings the radio up, not
|
||
|
|
that it transmits correctly.
|
||
|
|
|
||
|
|
### obu-cam-transmistter yawRateConfidence fix (added 2026-09-11)
|
||
|
|
|
||
|
|
Its `cam.c` (compiled into that firmware) wrote `yawRateConfidence` as 3 bits / 7 instead of
|
||
|
|
4 bits / unavailable(8), the bug the app fixed on 2026-08-20. Fixed in it and in obu-firmware's
|
||
|
|
reference copy; asn1tools now decodes the CAM and re-encodes it byte-identically, and it builds on
|
||
|
|
IDF 5.5.4. No board runs this firmware right now (the production OBU runs obu-firmware), so this
|
||
|
|
only matters if it is flashed again:
|
||
|
|
|
||
|
|
- [ ] After flashing it: capture, run `pcap_gn_tally.py`, and decode the CAM payload with
|
||
|
|
asn1tools (`py -3.11`, modules in `asn1/`).
|
||
|
|
|
||
|
|
### Signed-message reception and exact payloads (added 2026-09-11)
|
||
|
|
|
||
|
|
obu-firmware's `gn_unwrap.c` now unwraps TS 103 097 signed packets (signature not verified,
|
||
|
|
reported as V2X_RX flags bit1) and cuts every message to the length its header declares, dropping
|
||
|
|
the 8 bytes the chip's RX appends to each frame, which were forwarded to the phone until now.
|
||
|
|
Verified on the host (`obu-firmware/test/host`: chain, replay of all recordings against asn1tools,
|
||
|
|
50M-iteration fuzz) and built on IDF 6.1, but not flashed: the production OBU still runs the
|
||
|
|
2026-09-10 build. Needs the OBU with this build, the phone, and signed traffic - real vehicles or
|
||
|
|
RSUs, since the bench CiT One sends unsigned. A second ESP32 running the receiver firmware is
|
||
|
|
optional, but shows what was on air at the time.
|
||
|
|
|
||
|
|
- [ ] Flash obu-firmware (this also carries the GN lifetime fix above).
|
||
|
|
- [ ] Near signed traffic: signed CAMs/DENMs appear in the app, and a simultaneous capture shows
|
||
|
|
them on air (`pcap_gn_tally.py` lists them as `secured`).
|
||
|
|
- [ ] Unsigned bench traffic still decodes in the app as before (messages now arrive 8 bytes
|
||
|
|
shorter).
|
||
|
|
- [ ] The heartbeat's oversize counter still counts over-long messages (e.g. road SPATEMs).
|
||
|
|
|
||
|
|
## Set up host testing
|
||
|
|
|
||
|
|
- [x] Install MSYS2 UCRT64 gcc (done 2026-09-11: gcc 16.2.0, GNU Make 4.4.1; chosen over WSL,
|
||
|
|
vanetza is not going to be built). Setup and the PATH gotcha: `obu-firmware/test/host/README.md`.
|
||
|
|
- [x] Host round-trip test `obu-firmware/test/host/test_chain.c` (`geonet_wrap_shb` ->
|
||
|
|
`dot11p_build_frame` -> `gn_unwrap_its`, byte-checked against the standard). Done
|
||
|
|
2026-09-11: 491 checks, 0 failed. Run `make` in that folder before flashing any firmware fix.
|
||
|
|
- [x] Replay of the recorded captures (`test_replay.c` + `check_replay.py`, independent asn1tools
|
||
|
|
check). Done 2026-09-11: C and Python agree on all 15 145 records.
|
||
|
|
- [x] Mutation fuzzer `fuzz_gn_unwrap.c`, inputs against a no-access guard page. Done 2026-09-11:
|
||
|
|
50 000 000 iterations, no crash. `make` runs a 2 000 000-iteration pass every time.
|
||
|
|
|
||
|
|
## Firmware ideas from the vanetza review (2026-09-11, not started)
|
||
|
|
|
||
|
|
Suggested order after the host tests exist:
|
||
|
|
|
||
|
|
- [x] **Read secured packets (GN NextHeader=2) without verifying them.** Done 2026-09-11 in
|
||
|
|
`gn_unwrap.c`, host-verified; flagged to the phone as V2X_RX flags bit1. On-air check under
|
||
|
|
"Waiting on hardware".
|
||
|
|
- [ ] **Forward the full GeoBroadcast area**: shape (circle/rectangle/ellipse), DistanceB, angle,
|
||
|
|
appended to the V2X_RX prefix behind a capability bit. Port vanetza's `geonet/areas.cpp`
|
||
|
|
`inside_or_at_border` to the app, which currently treats every area as a circle.
|
||
|
|
- [ ] **RX filtering before the serial link**: duplicate detection for GBC (last 8 sequence numbers
|
||
|
|
per source, as vanetza does), drop our own frames, reject GN version != 1.
|
||
|
|
- [ ] **Read the DCC-MCO field** (the 4 "reserved" bytes of an SHB header): neighbours' channel
|
||
|
|
busy ratio for free.
|
||
|
|
- [ ] **Minimum TX gap in firmware** as a DCC safety net (vanetza reactive table: 60 ms relaxed ...
|
||
|
|
460 ms restrictive), with a CBR estimate in the heartbeat.
|
||
|
|
- [ ] **Generic V2X_TX message** (BTP port, SHB/GBC, traffic class, lifetime, area) so the phone can
|
||
|
|
send DENM and VAM without reflashing. Consider QoS Data frames: vanetza's Cohda receive path
|
||
|
|
drops non-QoS ones.
|
||
|
|
|
||
|
|
Dropped: building vanetza as a GN/BTP oracle. Real captures (`pcap_gn_tally.py`), the host
|
||
|
|
round-trip test and `asn1tools` for UPER cover what it would have checked.
|
||
|
|
|
||
|
|
## Follow-ups found 2026-09-11
|
||
|
|
|
||
|
|
- [ ] **App: show the signed flag.** `V2xRxFrame.parse` in `SerialFrame.kt` only reads bit0 of
|
||
|
|
the flags byte; read bit1 (signed, not verified) and show it where messages are listed.
|
||
|
|
- [ ] **Messages that do not decode with asn1tools.** In the recordings, 56 from the CiT One
|
||
|
|
(`aa:f8:76:7d:bd:ad`: 54 CAMs of 245 bytes, 2 DENMs of 402 bytes) and one 218-byte CAM from
|
||
|
|
`6e:94:03:1b:05:26` fail against `cam_1_4_1`/`denm_1_3_1` + `cdd_1_3_1_1`, with or without the
|
||
|
|
old trailing bytes. A newer module version on the sender, or a sender bug; check what the
|
||
|
|
app's decoders make of them (`check_replay.py` lists the records).
|