# micrOBU ESP32-C5 A standalone ITS-G5 (802.11p) VRU (Vulnerable Road User) ITS-S station on the ESP32-C5: firmware, the embedded [Vanetza](https://github.com/riebl/vanetza) C-ITS protocol stack (`external/vanetza-idf/`, see [PROVENANCE.md](external/vanetza-idf/PROVENANCE.md)), a phone-emulator example for the station-internal link, a localhost PKI reference chain, a Wireshark VAM dissector and the [V2X2MAP](https://github.com/711it/v2x2map) receiver bridge. A fresh clone can send a real, signed VAM (VRU Awareness Message) over the air in a handful of commands — see [Send a signed VAM](#4-send-a-signed-vam-in-a-few-commands) below. `station-link/python/demo-chain.vcr` is a disposable, **non-EU-registered** test credential chain generated specifically for this purpose (see [Security note on credentials](#security-note-on-credentials)); it carries no real-world trust and is safe to ship. ## Quickstart ### 1. Build & flash the ESP32-C5 firmware Requires [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c5/get-started/) 6.0.2 with the `esp32c5` target. ```powershell cd firmware idf.py set-target esp32c5 idf.py build idf.py -p COM flash monitor ``` ### 2. Install the Wireshark VAM dissector Wireshark decodes IEEE 1609.2 / ETSI TS 103 097 secured packets only down to `unsecuredData` unless the PSID is registered in its dissector table. **PSID 638** (VRU Awareness Service, ETSI TS 102 965) is not registered by default in Wireshark 4.x, so signed VAM traffic stops decoding at the security envelope without this plugin. ```powershell # Windows Copy-Item tools\wireshark\psid-vru.lua "$env:APPDATA\Wireshark\plugins\" ``` ```bash # Linux mkdir -p ~/.local/lib/wireshark/plugins && cp tools/wireshark/psid-vru.lua ~/.local/lib/wireshark/plugins/ # macOS mkdir -p ~/.config/wireshark/plugins && cp tools/wireshark/psid-vru.lua ~/.config/wireshark/plugins/ ``` Verify under **Help → About Wireshark → Plugins**, or use it directly with `tshark`: ```bash tshark -X lua_script:tools/wireshark/psid-vru.lua -r capture.pcap ``` See [tools/wireshark/README.md](tools/wireshark/README.md) for details. ### 3. Install Python dependencies ```bash pip install -r station-link/python/requirements.txt pip install -r tools/v2x2map-0.3.0/bridge/requirements.txt ``` ### 4. Send a signed VAM in a few commands With the firmware flashed (step 1) and the ESP32-C5 connected over USB Serial/JTAG, the phone emulator provisions the disposable demo credential chain and starts a small VRU basic service that assembles and transmits VAMs: ```bash python station-link/python/phone_emulator.py \ --port COM --bundle station-link/python/demo-chain.vcr \ --radio txrx --duration 30 ``` That's it — the micrOBU signs every VAM with the demo AT ticket (VRU ITS-AID 638, `psid 638 ssp 01`) and transmits it over ITS-G5. Capture it with a second ITS-G5-capable radio (or the [V2X2MAP bridge](#5-run-the-v2x2map-receiver-bridge-optional) below) and decode it with the [Wireshark dissector](#2-install-the-wireshark-vam-dissector) from step 2. To provision over BLE instead of USB, or to mirror packets to a `.pcap` without radiating, see the header of [`phone_emulator.py`](station-link/python/phone_emulator.py) for the `--ble`, `--radio off --divert --pcap` and full `--pki-*` (real online TS 102 941 enrolment/authorization) variants, and [station-link/README.md](station-link/README.md) for the link protocol itself. ### 5. Run the V2X2MAP receiver bridge (optional) A second ESP32-C5 flashed with the receiver firmware in [`tools/v2x2map-0.3.0/bridge/firmware/`](tools/v2x2map-0.3.0/bridge/firmware/) can feed a live web dashboard: ```bash python tools/v2x2map-0.3.0/bridge/its_g5_bridge.py --port COM --dashboard-port 8080 --open-browser ``` Open `http://localhost:8080` if it doesn't open automatically. This tool decodes VAMs for display but does **not** verify signatures (see [tools/v2x2map-0.3.0/README.md](tools/v2x2map-0.3.0/README.md)). ## Repository layout | Path | Contents | |---|---| | `firmware/` | ESP-IDF firmware project for the ESP32-C5 VRU ITS-S | | `external/vanetza-idf/` | Vanetza C-ITS stack + ESP-IDF port (upstream provenance in [PROVENANCE.md](external/vanetza-idf/PROVENANCE.md)) | | `station-link/` | Station-internal link protocol, Python client library, phone emulator | | `pki/` | Localhost PKI reference chain (root/AA/AT tooling); see [security note](#security-note-on-credentials) | | `tools/wireshark/` | PSID 638 (VRU) Wireshark Lua dissector | | `tools/v2x2map-0.3.0/` | Vendored [V2X2MAP](https://github.com/711it/v2x2map) receiver bridge and live dashboard | ## Security note on credentials `pki/uml-l0-rca/` documents the tooling for a **real, EU CCMS L0 ECTL-registered** root CA used elsewhere in the wider micrOBU project. Its private key material is intentionally **not** in this repository — `.gitignore` also backstops this (`*.vkey`, `*.ekey`, `private/`). `station-link/python/demo-chain.vcr` is unrelated: a separate, throwaway, **non-registered** root/AA/AT chain generated specifically for this repo's quickstart with `pki/uml-l0-rca/bin/windows/vidf_issue.exe`. Its `HashedId8` values do not match the registered root, it grants no real-world trust, and regenerating it is safe: ```powershell $pool = "" $exe = "pki\uml-l0-rca\bin\windows\vidf_issue.exe" openssl ecparam -name prime256v1 -genkey -noout -out "$pool\demo_root_key.pem" & $exe root --key "$pool\demo_root_key.pem" --name "Demo Root (NOT REGISTERED)" --id DEMO_RCA --out $pool --years 10 & $exe authority --issuer "$pool\DEMO_RCA.oer" --issuer-key "$pool\demo_root_key.pem" --name "Demo AA" --id DEMO_AA --out $pool --years 5 & $exe ticket --issuer "$pool\DEMO_AA.oer" --issuer-key "$pool\DEMO_AA.vkey" --id DEMO_AT --out $pool --hours 8760 --root "$pool\DEMO_RCA.oer" python external\vanetza-idf\ports\esp_idf\tools\credential_bundle.py build ` --pool $pool --root DEMO_RCA --aa DEMO_AA --at DEMO_AT --out station-link\python\demo-chain.vcr ``` `pki/uml-l0-rca/reference-generator/` cross-validates certificate generation against an independent Rust implementation ([`TheEnbyperor/c-its`](https://github.com/TheEnbyperor/c-its), pinned commit in [`reference-generator/README.md`](pki/uml-l0-rca/reference-generator/README.md)). Its vendored crates (`vendor/`) are excluded from this repository by `.gitignore` for size; regenerate with `cargo vendor` from that directory's `Cargo.lock`, or use `vidf_issue` directly as shown above — the vendor tree is only needed for that independent cross-check, not for ordinary use. ## License / provenance - Vanetza and its ESP-IDF port: BSD-3-Clause, see [external/vanetza-idf/LICENSE.md](external/vanetza-idf/LICENSE.md) and [external/vanetza-idf/PROVENANCE.md](external/vanetza-idf/PROVENANCE.md). - V2X2MAP bridge: MIT, see [tools/v2x2map-0.3.0/LICENSE](tools/v2x2map-0.3.0/LICENSE).