mirror of
https://github.com/ruvnet/RuView
synced 2026-08-11 20:41:44 +00:00
feat(rvcsi): Raspberry Pi 5 (BCM43455c0) + Nexmon chip registry
Adds first-class support for the Raspberry Pi 5's WiFi chip (CYW43455 /
BCM43455c0 — the same 802.11ac wireless as the Pi 4 / Pi 3B+ / Pi 400, and the
chip with the most mature nexmon_csi support), plus a registry of the other
Nexmon-supported Broadcom/Cypress chips.
rvcsi-adapter-nexmon — new `chips.rs`:
- `NexmonChip` (Bcm43455c0, Bcm43436b0, Bcm4366c0, Bcm4375b1, Bcm4358, Bcm4339,
Unknown{chip_ver}) + `RaspberryPiModel` (Pi5/Pi4/Pi400/Pi3BPlus/PiZero2W/
PiZeroW) — Pi5/Pi4/Pi400/Pi3B+ → Bcm43455c0; PiZero2W → Bcm43436b0.
- `nexmon_adapter_profile(chip)` / `raspberry_pi_profile(model)` build the
per-device `AdapterProfile` (channels: 2.4 GHz 1-13 + 5 GHz UNII for dual-band;
bandwidths 20/40/80[/160]; expected subcarrier counts 64/128/256[/512]) that
`validate_frame` bounds CSI frames against.
- `NexmonChip::from_chip_ver` (0x4345 → Bcm43455c0, 0x4339, 0x4358, 0x4366,
0x4375 — best-effort; the raw `chip_ver` is always preserved) and `from_slug`
/ `RaspberryPiModel::from_slug` ("pi5", "raspberry pi 4", "bcm43455c0", ...).
- `NexmonCsiHeader::chip()`; `NexmonPcapAdapter` auto-detects the chip from the
packets' `chip_ver` and uses the matching profile, overridable via
`.with_chip(NexmonChip)` / `.with_pi_model(RaspberryPiModel)`; `.detected_chip()`.
rvcsi-runtime: `decode_nexmon_pcap_for(.., chip_spec)` (validate against a chip /
Pi model, drop non-conforming) + `nexmon_profile_for(spec)`; `NexmonPcapSummary`
gains `chip_names` + `detected_chip`; `CaptureSummary` gains `chip`.
rvcsi-cli: `record --source nexmon-pcap --chip pi5`; new `nexmon-chips`
subcommand (lists chips + Pi models, human or `--json`); `inspect-nexmon` and
`inspect` now print the resolved chip.
rvcsi-node (napi-rs): `nexmonDecodePcap` gains an optional `chip` arg;
`nexmonChipName(chipVer)`, `nexmonProfile(spec)`, `nexmonChips()`. @ruv/rvcsi
SDK + `.d.ts` updated (AdapterProfile / NexmonChipsListing interfaces, the new
fns, `chip` on CaptureSummary, `chip_names`/`detected_chip` on NexmonPcapSummary).
168 rvcsi tests pass (adapter-nexmon 22→28, cli 9→10), 0 failures, clippy-clean.
The synthetic test captures now stamp chip_ver = 0x4345 (the BCM4345 family chip
ID), so the chip-detection happy path is exercised end to end.
ADR-096, CHANGELOG, README, CLAUDE.md updated.
https://claude.ai/code/session_01CdYAPvRTjcch6YrYf42n1z
This commit is contained in:
@@ -98,17 +98,25 @@ function exportCaptureToRfMemory(capturePath, outJsonlPath) {
|
||||
* @param {string} sourceId
|
||||
* @param {number} sessionId
|
||||
* @param {number} [port] CSI UDP port (default 5500)
|
||||
* @param {string} [chip] chip / Raspberry-Pi-model spec to validate against
|
||||
* (e.g. `'pi5'`, `'bcm43455c0'`); non-conforming frames are dropped
|
||||
* @returns {import('./index').CsiFrame[]}
|
||||
*/
|
||||
function nexmonDecodePcap(pcap, sourceId, sessionId, port) {
|
||||
function nexmonDecodePcap(pcap, sourceId, sessionId, port, chip) {
|
||||
return JSON.parse(
|
||||
binding().nexmonDecodePcap(pcap, String(sourceId), u32(sessionId), port == null ? undefined : Number(port)),
|
||||
binding().nexmonDecodePcap(
|
||||
pcap,
|
||||
String(sourceId),
|
||||
u32(sessionId),
|
||||
port == null ? undefined : Number(port),
|
||||
chip == null ? undefined : String(chip),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Summarize a nexmon_csi `.pcap` file (link type, CSI frame count, channels,
|
||||
* bandwidths, chip versions, RSSI range, time span).
|
||||
* bandwidths, chip versions + resolved chip names, RSSI range, time span).
|
||||
* @param {string} path
|
||||
* @param {number} [port] CSI UDP port (default 5500)
|
||||
* @returns {import('./index').NexmonPcapSummary}
|
||||
@@ -126,6 +134,36 @@ function decodeChanspec(chanspec) {
|
||||
return JSON.parse(binding().decodeChanspec(u32(chanspec)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a `chip_ver` word from a nexmon_csi packet to a chip slug
|
||||
* (`'bcm43455c0'` for a Raspberry Pi 3B+/4/400/5; `'unknown:0xNNNN'` otherwise).
|
||||
* @param {number} chipVer
|
||||
* @returns {string}
|
||||
*/
|
||||
function nexmonChipName(chipVer) {
|
||||
return binding().nexmonChipName(u32(chipVer));
|
||||
}
|
||||
|
||||
/**
|
||||
* The AdapterProfile (channels / bandwidths / expected subcarrier counts /
|
||||
* capability flags) for a chip / Raspberry-Pi-model spec (`'pi5'`,
|
||||
* `'bcm43455c0'`, ...). Throws on an unknown spec.
|
||||
* @param {string} spec
|
||||
* @returns {import('./index').AdapterProfile}
|
||||
*/
|
||||
function nexmonProfile(spec) {
|
||||
return JSON.parse(binding().nexmonProfile(String(spec)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Listing of the Nexmon-supported chips + the Raspberry Pi models that carry
|
||||
* them (incl. the Pi 5 → BCM43455c0).
|
||||
* @returns {import('./index').NexmonChipsListing}
|
||||
*/
|
||||
function nexmonChips() {
|
||||
return JSON.parse(binding().nexmonChips());
|
||||
}
|
||||
|
||||
/** Streaming capture runtime: a source + the DSP stage + the event pipeline. */
|
||||
class RvCsi {
|
||||
/** @param {*} rt the underlying napi RvcsiRuntime handle */
|
||||
@@ -203,6 +241,9 @@ module.exports = {
|
||||
nexmonDecodePcap,
|
||||
inspectNexmonPcap,
|
||||
decodeChanspec,
|
||||
nexmonChipName,
|
||||
nexmonProfile,
|
||||
nexmonChips,
|
||||
inspectCaptureFile,
|
||||
eventsFromCaptureFile,
|
||||
exportCaptureToRfMemory,
|
||||
|
||||
Reference in New Issue
Block a user