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
+21 -17
View File
@@ -1,18 +1,22 @@
# wifi_patches.c is intentionally NOT in this list anymore - superseded by
# tx_custom.c (see that file for why). Left on disk, unused, for history.
# C++ station (from microbu-esp32c5/firmware/main) plus the C files of the previous firmware that
# still do a job here:
# gn_unwrap.c - raw receive path: 802.11/LLC-SNAP/GeoNetworking/BTP-B down to the ITS payload,
# for every frame on air, signed or not (station.cpp, forward_raw).
# geonet.c - unsigned transmit path: GN SHB + BTP-B exactly as the previous firmware built it
# (station.cpp, unsecured_request).
#
# cam.c is ALSO intentionally not in this list anymore (Phase 03): CAM is now built on the
# phone and sent down over serial_link, so this firmware never encodes CAM itself. cam.c/.h are
# left on disk as the byte-exact reference the Kotlin encoder was ported from - do not delete.
#
# serial_link.c/.h - binary phone<->ESP32 framing over the native USB Serial/JTAG port
# (Phase 03; changed from a GPIO UART1 wire to native USB because neither
# USB-C port on the ESP32-C5-WIFI6-KIT was actually routed to that UART).
# gn_unwrap.c/.h - strips 802.11/LLC-SNAP/GeoNetworking/BTP-B off received frames down to CAM
# UPER bytes, for forwarding to the phone over serial_link.
idf_component_register(
SRCS "main.c" "denm.c" "geonet.c" "dot11p.c" "tx_custom.c" "serial_link.c" "gn_unwrap.c"
INCLUDE_DIRS "."
REQUIRES esp_event esp_netif nvs_flash driver esp_phy esp_driver_gpio esp_driver_usb_serial_jtag
PRIV_REQUIRES esp_wifi
)
# Left on disk and NOT built, like cam.c before them:
# main.c, serial_link.c/.h - the previous firmware's entry point and phone link (frame types
# 0x01-0x05). Superseded by app_main.cpp and the station-link protocol.
# dot11p.c/.h - previous 802.11 framing; c5_radio.cpp frames through vanetza-idf now.
# Still compiled by the host tests in test/host.
# tx_custom.c/.h - previous copy of the OpenTrafficMap raw TX; otm_tx_custom.c replaces it.
# denm.c/.h, cam.c/.h, wifi_patches.c - reference only, as before.
idf_component_register(SRCS "app_main.cpp" "board_controls.cpp" "simple_ble.cpp" "c5_radio.cpp" "otm_tx_custom.c"
"link_protocol.cpp" "serial_link.cpp" "station.cpp" "station_test.cpp"
"link_service.cpp" "test_channel.cpp"
"gn_unwrap.c" "geonet.c"
INCLUDE_DIRS "."
LDFRAGMENTS "linker.lf"
REQUIRES vanetza-idf esp_wifi esp_phy esp_event bt esp_driver_gpio esp_driver_usb_serial_jtag nvs_flash esp_timer)
target_compile_features(${COMPONENT_LIB} PRIVATE cxx_std_17)