Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca57e5702b | ||
|
|
0e9525162d |
@@ -54,12 +54,3 @@ sdkconfig.old
|
||||
# ESP-IDF component manager downloads (espressif/esp-boost for obu-firmware's vanetza-idf), ~125 MB.
|
||||
# dependencies.lock beside the project pins them and is committed; this is its cache.
|
||||
managed_components/
|
||||
|
||||
# The colleague's standalone ESP32-C5 VRU station (its own repository, HAW GitLab
|
||||
# urban-mobility-lab/microbu/microbu-esp32c5). Kept beside the project on the lab laptop, for
|
||||
# reference and because the V2X2MAP bridge runs from its tools/, but not part of this repository:
|
||||
# obu-firmware only needs its vanetza-idf, which is copied to obu-firmware/external/vanetza-idf.
|
||||
/microbu-esp32c5/
|
||||
|
||||
# draw.io keeps a backup beside an open diagram.
|
||||
*.drawio.bkp
|
||||
|
||||
@@ -75,7 +75,7 @@ resets the board, the phone is on the other port.
|
||||
Signed CAMs from the pinger already show "signature verified" live. Switch to VAM with signing
|
||||
on: the VAM must be decoded (cyclist, position) and show "signature verified" too.
|
||||
Confirmed by the user 2026-09-23: signed VAMs decode and verify.
|
||||
- [x] **VAM.** Transmit VAM: BTP port 2018, psid 638; with `tools/wireshark/psid-vru.lua` from the colleague's microbu-esp32c5 repository
|
||||
- [x] **VAM.** Transmit VAM: BTP port 2018, psid 638; with `microbu-esp32c5/tools/wireshark/psid-vru.lua`
|
||||
Wireshark decodes the VAM (stationType cyclist, bicyclist profile in every ~2 s VAM). Rate:
|
||||
≥1 per 5 s standing still, about one per GNSS fix while riding.
|
||||
Covered by the V2X2MAP check above (decoded VAM, psid 638); Wireshark not needed.
|
||||
|
||||
@@ -35,10 +35,10 @@ fit together, how it was verified, and what is still open. Hardware checks still
|
||||
|
||||
## Firmware (obu-firmware)
|
||||
|
||||
obu-firmware is now a port of `microbu-esp32c5/firmware`, from the colleague's own repository
|
||||
(not part of this one; nothing is pushed there). The C-ITS library it needs is copied into this
|
||||
repository as `obu-firmware/external/vanetza-idf` (their commit cf4b99f, unchanged), so
|
||||
obu-firmware builds from a plain clone. It builds
|
||||
obu-firmware is now a port of `microbu-esp32c5/firmware`: the colleague's repository, of which
|
||||
this repository keeps a copy in `microbu-esp32c5/` (their commit cf4b99f plus our V2X2MAP signature
|
||||
verification; nothing is pushed to their repository). vanetza-idf is taken from
|
||||
`microbu-esp32c5/external/vanetza-idf`. It builds
|
||||
with **ESP-IDF 6.0.2 only**: the raw-TX path uses private Wi-Fi driver structures that vanetza-idf
|
||||
pins to that version. The previous C firmware (IDF 6.1) is backed up as a full flash image in
|
||||
`firmware-backups/` (gitignored, restore command in its README.txt); its sources stay on disk,
|
||||
@@ -64,7 +64,7 @@ Main changes against the colleague's firmware:
|
||||
|
||||
## Link protocol
|
||||
|
||||
Station-link v1 (colleague's repository, `station-link/README.md`): `[opcode][flags][sequence LE][body]`,
|
||||
Station-link v1 (`microbu-esp32c5/station-link/README.md`): `[opcode][flags][sequence LE][body]`,
|
||||
little-endian, at most 512 octets. Over USB each message is one `0xAA55` frame of type `0x10`
|
||||
(the old framing and CRC). Over BLE each message is one GATT value on service
|
||||
`0000C175-BA5E-4C17-8000-00805F9B34FB` (the README describes a different, Nordic-UART layout; the
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 660 KiB |
@@ -0,0 +1,43 @@
|
||||
# --- ESP-IDF build output ---
|
||||
firmware/build/
|
||||
firmware/build-*/
|
||||
firmware/managed_components/
|
||||
firmware/.cache/
|
||||
firmware/.vscode/
|
||||
firmware/sdkconfig
|
||||
firmware/sdkconfig.old
|
||||
firmware/*.log
|
||||
firmware/rf_characterization_output/
|
||||
|
||||
# --- Secrets: never commit real private key material ---
|
||||
# (this repo only ever ships the disposable, non-registered demo chain)
|
||||
*.vkey
|
||||
*.ekey
|
||||
private/
|
||||
*_private_encrypted.pem
|
||||
*_RCA_NEW_*/
|
||||
|
||||
# --- PKI reference-generator: regenerate locally, do not commit ---
|
||||
# (vendored Rust crates for the offline/deterministic c-its build path; see
|
||||
# pki/uml-l0-rca/reference-generator/README.md to rebuild with `cargo vendor`)
|
||||
pki/uml-l0-rca/reference-generator/vendor/
|
||||
pki/uml-l0-rca/reference-generator/_build_cits/
|
||||
pki/uml-l0-rca/reference-generator/_cargo_vendor/
|
||||
|
||||
# --- Python ---
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.egg-info/
|
||||
.venv/
|
||||
venv/
|
||||
|
||||
# --- v2x2map bridge local artifacts ---
|
||||
tools/v2x2map-0.3.0/bridge/recordings/
|
||||
tools/v2x2map-0.3.0/bridge/dist/
|
||||
tools/v2x2map-0.3.0/bridge/build/
|
||||
*.pcap
|
||||
|
||||
# --- OS / editor ---
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
*.swp
|
||||
@@ -0,0 +1,155 @@
|
||||
# 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).
|
||||
Vendored
Vendored
Vendored
Vendored
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user