156 lines
6.8 KiB
Markdown
156 lines
6.8 KiB
Markdown
# 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<PORT> 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<PORT> --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<PORT> --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 = "<some scratch directory>"
|
||
|
|
$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).
|