Sign ITS messages on the ESP32-C5 with vanetza-idf, over USB or BLE

obu-firmware is now a port of the colleague's standalone VRU station
(microbu-esp32c5/firmware, kept beside this repository and gitignored): the
vanetza-idf C-ITS stack with the TS 103 097 security entity, credentials in
NVS, the station-link v1 protocol over the native USB port (frame type 0x10
in the existing 0xAA55 framing) and over a BLE GATT peripheral, and its
ITS-G5 radio adapter. The phone still builds CAM and VAM; the board adds
GeoNetworking/BTP and signs with the provisioned authorization ticket. The
private key never leaves the board. Builds with ESP-IDF 6.0.2 only, which
vanetza-idf pins for the radio's private driver ABI. The previous C firmware
stays on disk unbuilt; a full-flash backup of the bench board is kept in
firmware-backups/ (gitignored).

Changed against the colleague's firmware, marked MicrOBU: in the sources:
- Reception unchanged for the app. vanetza-idf drops what it cannot verify
  (unsigned traffic, every RSU), so each captured frame also goes through the
  previous gn_unwrap.c and reaches the phone as link opcode V2X_RX (0x85),
  whose body is the old SERIAL_MSG_V2X_RX payload.
- Unsigned transmission still possible, with the previous geonet.c header;
  the phone chooses per message.
- Console on UART0 (CH343 port); the native USB port carries only link frames.
- BLE advertising pauses while the USB link is in use: BLE and ITS-G5 share
  one RF front end.
- NVS 80 KB (app at 0x20000). At 24 KB, with Wi-Fi settings the previous
  firmware left behind, the BLE bond could not be stored and the phone had to
  pair on every connection.
- Bench fixes: the radio queue is drained before the first PoTi (no RX and
  ~177 queue drops before); the station loop waited pdMS_TO_TICKS(5) = 0
  ticks at 100 Hz and starved the idle task; the 2.4 KB RX capture buffer is
  off the Wi-Fi task stack; BLE notifications longer than the MTU are dropped
  instead of cut short, MTU 517; serial writes are skipped with no USB host.
- Manual country policy and TX-power read-back from the previous radio setup;
  logs for BLE encryption changes and the number of stored bonds.

Verified on the bench board (COM3) with the phone over USB and BLE: CAM and
VAM, signed and unsigned, go out; reception of the sim car and the RSU's
CAM/SPATEM/MAPEM continues; the board survives app restarts and reconnects.
See docs/06-signed-its-vam-ble.md.
This commit is contained in:
Ashin Walpola
2026-09-23 17:27:54 +02:00
parent 7285fa19b7
commit d2fd222a62
31 changed files with 4837 additions and 1022 deletions
+37 -11
View File
@@ -2,24 +2,38 @@
## Two toolchains - use a dedicated terminal for each
This project builds against the receiver-firmware's pinned ESP-IDF **6.1**.
The separate `obu-cam-transmistter` project builds against the global ESP-IDF
**5.5.4**. Exporting both in one PowerShell window fails: the second export
Since 2026-09-23 this project builds against ESP-IDF **6.0.2** exactly
(`C:\Espressif\frameworks\esp-idf-v6.0.2`): it is the vanetza-idf port (see
NOTES.md), and vanetza-idf's `radio_c5.cmake` refuses any other version because
the raw TX path pokes private Wi-Fi driver structures only validated there. The
previous C firmware used the receiver firmware's IDF **6.1**; the separate
`obu-cam-transmistter` project builds against the global ESP-IDF **5.5.4**.
Exporting two of them in one PowerShell window fails: the second export
inherits the first's `IDF_PYTHON_ENV_PATH` and reports every Python dependency
as unmet. Don't run `install.bat` to "fix" that - open a fresh terminal, or
clear the state with `$env:IDF_PYTHON_ENV_PATH = $null; $env:IDF_PATH = $null`.
## Every new PowerShell session
The build also needs the colleague's `microbu-esp32c5` checkout beside this
repository (gitignored here): vanetza-idf is taken from its
`external/vanetza-idf`. Pass `-DVANETZA_IDF_DIR=<path>` to `idf.py` if it lives
elsewhere. The first build downloads `espressif/esp-boost` into
`managed_components/`.
Activate the toolchain (obu-firmware has no esp-idf of its own — reuse the
receiver firmware's already-installed checkout):
## Every new PowerShell session
```powershell
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
C:\Users\Ashin\Documents\micrOBU_workspace\its-g5-receiver-firmware\esp-idf\export.ps1
idf.py --version
$env:IDF_TOOLS_PATH = "C:\Espressif"
C:\Espressif\frameworks\esp-idf-v6.0.2\export.ps1
idf.py --version # v6.0.2
```
## Going back to the previous firmware
`firmware-backups/` in the repository root (gitignored) holds a full-flash image
of the COM3 board as it was before the port, with the esptool command to write
it back in its README.txt.
## Build & flash
```powershell
@@ -97,10 +111,22 @@ Work down this list — each step isolates the layer below it.
CAMs reach the ESP32 but `esp_wifi_80211_tx` rejects them — a radio problem,
not a link problem.
## Connecting over Bluetooth instead
Settings > Connection > ESP32-C5 > link: Bluetooth, then Connect. The board
advertises as `micrOBU-XXXX` (last two bytes of its BT MAC; `micrOBU-4AFA` on
COM3), but only while nothing uses its native USB port. Android asks to pair
the first time: passkey **123456** (fixed in `simple_ble.cpp`). The bond is kept
on both sides; the board keeps one bond, so pairing a second phone or a PC
replaces the first. Log lines on the console start with `cits_ble:`.
## Notes
- No `git submodule update` needed here — obu-firmware has no pinned
submodule of its own, unlike its-g5-receiver-firmware.
- Don't use the global "ESP-IDF 5.5 PowerShell" shortcut — always export from
the receiver-firmware's pinned checkout, since this firmware's undocumented
PHY/driver internals were verified against that specific build.
- Don't use the global "ESP-IDF 5.5 PowerShell" shortcut or the receiver
firmware's 6.1 checkout — export from `esp-idf-v6.0.2`, the version the
vanetza-idf radio's undocumented driver internals were verified against.
- The console (ESP_LOG, boot messages, panics) stays on the UART-bridge port.
Opening it resets the board; do that only while nothing else depends on the
session.