Skip to content

feat(server): parse CSI wire v2 and v3 headers - #1806

Open
clonea1 wants to merge 2 commits into
ruvnet:mainfrom
clonea1:contrib/server-wire-v3
Open

clonea1 wants to merge 2 commits into
ruvnet:mainfrom
clonea1:contrib/server-wire-v3

Conversation

@clonea1

@clonea1 clonea1 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

The frame parser accepts one magic (0xC5110001) and a fixed 20-byte header, so
a frame carrying transmitter or transmission identity is rejected outright.
That makes it impossible for a node to tell the server anything about WHICH
link a measurement belongs to, or WHICH transmission produced it.

Adds named constants for the three wire versions and dispatches on the magic:

v1  0xC5110001  20-byte header, unchanged
v2  0xC5110008  + transmitter MAC (addr2) at bytes 20..25
v3  0xC511000A  + 802.11 rx_seq (u16 LE) at bytes 26..27

Esp32Frame gains source_mac and rx_seq, both Option, both None for a v1 frame.
A mixed fleet therefore keeps working: older firmware parses exactly as before
and newer firmware simply carries more.

This is the receiver half of the wire change and should land BEFORE any
firmware starts emitting v2/v3, so there is never a moment where a node sends
something the server rejects.

It is also a prerequisite for two follow-on changes that cannot work without
per-frame identity: per-link CSI state keyed on (receiver, transmitter), and
cross-node pairing keyed on (transmitter, rx_seq).


Rebased onto current main before opening: staged before today's seven merges, so it needed replaying to avoid reading as a revert of them. Clean rebase, no files deleted.

The frame parser accepts one magic (0xC5110001) and a fixed 20-byte header, so
a frame carrying transmitter or transmission identity is rejected outright.
That makes it impossible for a node to tell the server anything about WHICH
link a measurement belongs to, or WHICH transmission produced it.

Adds named constants for the three wire versions and dispatches on the magic:

    v1  0xC5110001  20-byte header, unchanged
    v2  0xC5110008  + transmitter MAC (addr2) at bytes 20..25
    v3  0xC511000A  + 802.11 rx_seq (u16 LE) at bytes 26..27

Esp32Frame gains source_mac and rx_seq, both Option, both None for a v1 frame.
A mixed fleet therefore keeps working: older firmware parses exactly as before
and newer firmware simply carries more.

This is the receiver half of the wire change and should land BEFORE any
firmware starts emitting v2/v3, so there is never a moment where a node sends
something the server rejects.

It is also a prerequisite for two follow-on changes that cannot work without
per-frame identity: per-link CSI state keyed on (receiver, transmitter), and
cross-node pairing keyed on (transmitter, rx_seq).

Co-Authored-By: claude-flow <ruv@ruv.net>
@clonea1

clonea1 commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

Mapped this cohort against ADR-345 in #1956. This PR is the root of it —
it is the wire change that lets a measurement say which link it belongs to,
which is ADR-345's whole premise, and ADR-345 measured that on node 2 the AP
was only 34% of frames while the other 66% were peer frames the sink could
not attribute.

One commit, server-side only, no dependencies. Its parser commit is carried
by #1828, #1833 and #1834 because a fork PR cannot be based on another fork
branch; merging this one unblocks all three, and each then drops the
duplicate by patch-id on rebase with nothing to resolve.


Generated by Claude Code

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants