esp32-csi-node: mDNS discovery for seed_url + provisioning UX fixes
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 94.4k
- Forks
- 12.5k
- Avg merge
- 21h 27m
- Merged PRs (30d)
- 43
Description
Summary
esp32-csi-node's swarm_bridge feature requires hand-set seed_url and seed_token via provision.py writes to the csi_cfg NVS namespace. Customers must know their Cognitum Seed's IP, run a Python tool, navigate provision.py's full-replace footgun (issue #391), and re-provision when the seed's DHCP lease changes. mDNS discovery would eliminate the manual step entirely for the common "ESP32 + Cognitum Seed on the same WiFi" case.
Why now
Customer onboarding friction. A real customer spent 4+ hours on what should have been a "flash and go" ESP32 ↔ Seed integration. The provision.py footgun and hand-set seed_url were two of the larger time sinks. mDNS + a USB-CDC pairing handshake should reduce this to under five minutes per node.
A separate seed-side issue exists for the cog fan-out gap that made the data invisible even after Brian got it flowing — cognitum-one/seed#166 (proposal pending @ruvnet review). This RuView-side discovery work is independent of that seed-side architectural decision and can ship on its own.
Done looks like
- ESP32 with empty
seed_urlperiodically queries_cognitum-seed._tcp.local(or similar) via mDNS while on WiFi - On match, optionally fetches
seed_tokenfrom the seed's pairing endpoint over USB-CDC if the seed is plugged in via USB at first-boot, falls back to operator-paste-from-CLI otherwise - Empty-by-default semantics preserved — explicit
seed_urlfromprovision.pystill wins - DHCP lease changes don't break the link (re-discovery on POST failure)
provision.pyno longer wipes thecsi_cfgnamespace on partial reconfigure (#391)
Work items
- mDNS query in new
seed_discovery.c(or extendnvs_config.c) whenseed_urlis empty at boot - Re-discovery loop on
swarm_bridgePOST failure (handle DHCP lease churn) - Optional: USB-CDC pairing flow that fetches
seed_tokenwithoutprovision.py -
provision.pyadditive-by-default mode (fix #391 footgun) so partial reconfigures don't wipe other NVS keys - Update
firmware/esp32-csi-node/README.mdquick-start with the discovery path
Status
Net-new feature work, no breaking changes proposed. Empty-default behaviour preserved so existing deployments are unaffected.
Technical detail
Current state
firmware/esp32-csi-node/main/nvs_config.c:308:
if (nvs_get_str(handle, \"seed_url\", cfg->seed_url, &len) != ESP_OK) {
cfg->seed_url[0] = '\\0'; /* Disabled by default */
}
swarm_bridge.c will silently log \"seed_url is empty — swarm bridge disabled\" and never attempt to reach a seed unless provision.py was run with --seed-url. Customers without that prior knowledge see no integration with their Cognitum Seed even when both devices are on the same network.
provision.py header warning (kept verbatim from script):
WARNING -- FULL-REPLACE SEMANTICS (issue #391):
Every invocation REPLACES the entire `csi_cfg` NVS namespace on the device.
Any key you don't pass on the CLI is erased.
This means a customer who provisions WiFi credentials, then later wants to add --seed-url, must re-pass every other flag (SSID, password, target-ip, node-id, zone) or lose that state. Easy to miss, painful to debug.
Proposed mDNS service record (seed side, for coordination)
Cognitum Seed would advertise:
_cognitum-seed._tcp.local port=8080
TXT: device_id=<uuid>, version=<seed-firmware-version>, paired=<bool>
ESP32 would query, prefer paired+matching version, fall back to first-found.
Pairing handshake (optional, USB-CDC only)
If ESP32 is plugged into the seed via USB at first boot:
- ESP32 enumerates as USB-CDC device
- Seed detects new CDC device, polls a small pairing endpoint on the ESP32
- Seed mints a
seed_token, writes it into ESP32 NVS via the pairing channel - ESP32 reboots, comes up with
seed_tokenset, joins WiFi, finds seed via mDNS, starts streaming
Customer experience reduces to: "plug ESP32 into seed USB, wait 30 s, unplug, mount somewhere on WiFi."
File pointers
firmware/esp32-csi-node/main/swarm_bridge.c— current HTTP POST loopfirmware/esp32-csi-node/main/nvs_config.c:306-322— current seed_url / seed_token / swarm_ingest_sec defaultsfirmware/esp32-csi-node/provision.py— full-replace semantics, footgun warning at lines 15-19- ADR-066 (this repo,
docs/adr/ADR-066-esp32-swarm-seed-coordinator.md) — swarm bridge architectural context - ADR-060 (provisioning) — referenced as related context
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with firmware/esp32-csi-node/main/swarm_bridge.c and nvs_config.c:306-322 to trace the current POST loop and empty seed_url behavior. Then inspect firmware/esp32-csi-node/provision.py, ADR-066, and ADR-060; done means discovery, lease-change recovery, additive provisioning, and the README quick-start work without breaking explicit seed_url configuration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, python
- Domain
- documentation, embedded-iot, networking
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100