wifi-densepose/v2/crates/wifi-densepose-hardware
ruv df95360e52 feat(adr-110 P10): apply_to_local + NodeState::mesh_aligned_us + full ADR rewrite
Iter 16 closes the math loop and updates ADR-110 to reflect the full
P1-P10 sprint outcome (per user request).

Code (the math layer that converts the iter 15 stored sync into a
per-frame mesh-aligned timestamp):

  wifi-densepose-hardware:
    SyncPacket::apply_to_local(local_at_frame_us: u64) -> u64
      Pure integer math: offset = epoch - local; mesh = local_at_frame + offset.
      3 new unit tests (10 total, all green):
      - apply_to_local_recovers_packet_epoch (identity at the packet's local_us)
      - apply_to_local_preserves_inter_frame_delta (Δlocal == Δmesh)
      - apply_to_local_on_leader_is_near_identity (leader offset ≈ 0)

  wifi-densepose-sensing-server:
    NodeState::mesh_aligned_us(local_at_frame_us: u64) -> Option<u64>
      Returns the recovered mesh timestamp using the most-recent sync
      packet, or None if no sync seen or last one older than 9 s
      (3× firmware VALID_WINDOW_MS = 9 s staleness gate).
      cargo check -p wifi-densepose-sensing-server --no-default-features
        → green

ADR-110 substantial rewrite (per user "update adr 110 with details"):

  - Status line: P1-P10 complete, firmware-side substrate closed at v0.7.0.
  - Front matter now lists all 4 firmware releases + witness link.
  - Phase table grows a P10 row capturing the v0.6.8 / v0.6.9 / v0.7.0
    arc (EMA smoother + sync packet + bit-4 wire-fix + host crates).
  - New §4.1 — /loop 5m SOTA sprint summary table (iters 1-16, 4 releases,
    17 commits, 13 unit tests, what shipped each iter).
  - New §4.2 — measured numbers table with 99.56% RX, 104.1 µs smoothed
    stdev, 3.95x suppression, 1.4 ppm crystal skew, etc — every cell
    backed by a witness §A0.x entry and a preserved bench log.
  - New §4.3 — host-side production surface listing (sync_packet.rs +
    sensing-server NodeState + Python parser, with file paths).
  - §5 open question on 802.15.4 channel resolved (Kconfig, default ch26
    not ch15, with the witness §D1 rationale).
  - New §6 — explicit scope of what's outside this ADR (multistatic fusion
    math in ADR-029/030, hardware-gated measurements needing INA / 11ax AP,
    IDF upstream fixes pending).

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-23 13:16:11 -04:00
..
benches chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
src feat(adr-110 P10): apply_to_local + NodeState::mesh_aligned_us + full ADR rewrite 2026-05-23 13:16:11 -04:00
Cargo.toml chore(deps): bump thiserror from 1.0.69 to 2.0.18 in /v2 (#469) 2026-05-17 18:09:54 -04:00
README.md chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00

README.md

wifi-densepose-hardware

Crates.io Documentation License

Hardware interface abstractions for WiFi CSI sensors (ESP32, Intel 5300, Atheros).

Overview

wifi-densepose-hardware provides platform-agnostic parsers for WiFi CSI data from multiple hardware sources. All parsing operates on byte buffers with no C FFI or hardware dependencies at compile time, making the crate fully portable and deterministic -- the same bytes in always produce the same parsed output.

Features

  • ESP32 binary parser -- Parses ADR-018 binary CSI frames streamed over UDP from ESP32 and ESP32-S3 devices.
  • UDP aggregator -- Receives and aggregates CSI frames from multiple ESP32 nodes (ADR-018 Layer 2). Provided as a standalone binary.
  • Bridge -- Converts hardware CsiFrame into the CsiData format expected by the detection pipeline (ADR-018 Layer 3).
  • No mock data -- Parsers either parse real bytes or return explicit ParseError values. There are no synthetic fallbacks.
  • Pure byte-buffer parsing -- No FFI to ESP-IDF or kernel modules. Safe to compile and test on any platform.

Feature flags

Flag Default Description
std yes Standard library support
esp32 no ESP32 serial CSI frame parsing
intel5300 no Intel 5300 CSI Tool log parsing
linux-wifi no Linux WiFi interface for commodity sensing

Quick Start

use wifi_densepose_hardware::{CsiFrame, Esp32CsiParser, ParseError};

// Parse ESP32 CSI data from raw UDP bytes
let raw_bytes: &[u8] = &[/* ADR-018 binary frame */];
match Esp32CsiParser::parse_frame(raw_bytes) {
    Ok((frame, consumed)) => {
        println!("Parsed {} subcarriers ({} bytes)",
                 frame.subcarrier_count(), consumed);
        let (amplitudes, phases) = frame.to_amplitude_phase();
        // Feed into detection pipeline...
    }
    Err(ParseError::InsufficientData { needed, got }) => {
        eprintln!("Need {} bytes, got {}", needed, got);
    }
    Err(e) => eprintln!("Parse error: {}", e),
}

Architecture

wifi-densepose-hardware/src/
  lib.rs            -- Re-exports: CsiFrame, Esp32CsiParser, ParseError, CsiData
  csi_frame.rs      -- CsiFrame, CsiMetadata, SubcarrierData, Bandwidth, AntennaConfig
  esp32_parser.rs   -- Esp32CsiParser (ADR-018 binary protocol)
  error.rs          -- ParseError
  bridge.rs         -- CsiData bridge to detection pipeline
  aggregator/       -- UDP multi-node frame aggregator (binary)
Crate Role
wifi-densepose-core Foundation types (CsiFrame definitions)
wifi-densepose-signal Consumes parsed CSI data for processing
wifi-densepose-mat Uses hardware adapters for disaster detection
wifi-densepose-vitals Vital sign extraction from parsed frames

License

MIT OR Apache-2.0