diff --git a/TODO.md b/TODO.md index 566940a..a2c01c4 100644 --- a/TODO.md +++ b/TODO.md @@ -9,20 +9,24 @@ Engineering to-do list. The reviewer-facing open items live in `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 +compiled `geonet_wrap_shb` stores the new byte. Confirmed on air 2026-09-14. 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/.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). +- [x] Flash `obu-firmware` (done 2026-09-14 on COM3; flash backed up first to + `Documents/micrOBU_workspace/firmware-backups/COM3-2026-09-14-before-secured-rx.bin`). +- [x] Capture with the receiver (COM8) into `its-g5-receiver-firmware/recordings/`. +- [x] `pcap_gn_tally.py` on capture_20260914_132126.pcap: our station sends SHB, port 2001, + lifetime `0x05`, same as both bench stations. It was `0x83` in the August captures. +- [x] Real-station CAMs/DENMs/SPATEM still reach the app (logcat: `handleCamUper`, + `handleDenmUper`, `handleSpatUper` all decoding, 2026-09-14). +- [x] Our own CAMs decode on air: 397 frames from station 999999 decode with asn1tools and + re-encode byte-identically. +- [ ] Confirm the CAM Pinger card's `tx fail` / oversize / CRC counters are 0 (needs a look at the + phone; not readable from the PC). 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 @@ -33,11 +37,12 @@ that it transmits correctly. 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: +IDF 5.5.4. Since 2026-09-14 the spare board on COM10 runs it as a bench beacon: -- [ ] After flashing it: capture, run `pcap_gn_tally.py`, and decode the CAM payload with - asn1tools (`py -3.11`, modules in `asn1/`). +- [x] Done 2026-09-14: flashed on COM10 and captured on COM8. All 72 CAMs from station + 195936478 (0x0BADC0DE) decode with asn1tools and re-encode byte-identically, so the + 4-bit yawRateConfidence is right on air. COM10 now runs this beacon rather than + obu-firmware - reflash it if the spare is needed as an OBU again. ### Signed-message reception and exact payloads (added 2026-09-11) @@ -45,17 +50,21 @@ obu-firmware's `gn_unwrap.c` now unwraps TS 103 097 signed packets (signature no 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 +50M-iteration fuzz) and flashed to the production OBU on 2026-09-14. The remaining gap is signed +traffic to receive: 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). +- [x] Flash obu-firmware (done 2026-09-14, COM3). +- [x] Unsigned bench traffic still decodes in the app, with messages now cut to their declared + length (CAM, DENM and SPATEM all decoding in logcat after the flash). - [ ] 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). + them on air (`pcap_gn_tally.py` lists them as `secured`). NOT possible at this bench: the + CiT One transmits unsigned (`ItsGnSecurity = 0`) and nothing else here signs. Needs a drive + past real RSUs, the CiT One switched to signed mode if its API allows, or a replay firmware + on a spare board that re-transmits the recorded signed frames. +- [ ] The heartbeat's oversize counter still counts over-long messages. Not exercised at the + bench: the SPATEMs here are ~340 bytes on air, far below the cap. ## Set up host testing @@ -92,6 +101,19 @@ Suggested order after the host tests exist: 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-14 + +- [ ] **Commit the `live_capture.py` fix in the receiver repo.** Its console inserts a CR before + every LF, which also hits every 0x0a byte of the binary pcap stream, shifting pcap record + headers and frames. A 787 KB capture parsed cleanly for only 82 of ~2000 records, and DENMs + showed up on nonsense BTP ports. `undo_crlf()` now reverses it on the raw stream before + framing; afterwards a capture parsed to EOF and DENMs read as port 2002. This is the + "occasional byte inserted mid-frame" in the older recordings, so **every capture taken before + 2026-09-14 is truncated at its first corrupted record** - re-measure anything derived from + them. The change is in the `its-g5-receiver-firmware` repo, uncommitted. +- [ ] **Do not open COM3's console while the phone is attached.** Opening it toggles DTR/RTS on the + CH343 and resets the OBU, which drops the phone's USB link and needs a manual Connect. + ## Follow-ups found 2026-09-11 - [ ] **App: show the signed flag.** `V2xRxFrame.parse` in `SerialFrame.kt` only reads bit0 of diff --git a/obu-cam-transmistter/NOTES.md b/obu-cam-transmistter/NOTES.md index c672494..8ed701b 100644 --- a/obu-cam-transmistter/NOTES.md +++ b/obu-cam-transmistter/NOTES.md @@ -51,3 +51,49 @@ Known gaps, tracked as TODOs in the source: no real GNSS (lat/long hardcoded 0), no real time source (detectionTime/referenceTime hardcoded 0, decodes as 2004-01-01), fixed (non-rotating) pseudonym MAC, SHB instead of GeoBroadcast (no multi-hop forwarding), unsecured (no IEEE 1609.2 signing). + +## Running it as a bench beacon + +This firmware needs no phone: it beacons a CAM every second by itself +(`TX_INTERVAL_MS`) from station `0x0BADC0DE` (195936478), stationType 5 +(passengerCar), at the hardcoded bench position, under the fixed MAC +`02:00:00:00:00:01`, on 5900 MHz. That makes it the quickest way to put known, +repeatable traffic on air, and it is how the 4-bit `yawRateConfidence` encoding +was confirmed over the air on 2026-09-14. + +A board with only one USB-C port is fine. This firmware's console is on UART0, +so such a board shows no log output, but nothing here needs the console. + +Flash it from the toolchain terminal (ESP-IDF 5.5.4, see the table above): + +```powershell +cd C:\Users\Ashin\AndroidStudioProjects\MicrOBU\obu-cam-transmistter +idf.py -p COM10 -b 921600 flash +``` + +Or flash the existing build without any toolchain terminal: + +```powershell +cd obu-cam-transmistter\build +C:\Espressif\python_env\idf5.5_py3.11_env\Scripts\python.exe -m esptool --chip esp32c5 -p COM10 -b 921600 write_flash --flash_mode dio --flash_freq 80m --flash_size 2MB 0x2000 bootloader/bootloader.bin 0x8000 partition_table/partition-table.bin 0x10000 obu_firmware.bin +``` + +It starts beaconing as soon as it boots, so there is nothing to start by hand, +and unplugging it is how you stop it. + +**It transmits under the same MAC as the phone's CAM pinger**, so on air the two +are told apart by station ID (195936478 here, 999999 for the pinger), never by +source address. + +To see what it is sending, capture on the sniffer board and decode: + +```powershell +cd its-g5-receiver-firmware +py -3.11 live_capture.py COM8 +py -3.11 ..\obu-firmware\test\pcap_gn_tally.py recordings\capture_.pcap +``` + +The tally lists it as SHB / port 2001 / lifetime `0x05`. For the message itself, +decode the payload with `asn1tools` against `asn1/cam_1_4_1.asn` + +`asn1/cdd_1_3_1_1.asn`; re-encoding must return the identical bytes. On +2026-09-14, 72 of 72 frames did.