-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
The wifi-densepose sensing server's --source wifi path only works on Windows (uses
netsh commands). On macOS, --source auto silently falls back to simulation. The user
wants real WiFi RSSI sensing on their M2 Pro MacBook — no simulated data.
macOS 26.3 has removed the legacy airport CLI. CoreWLAN (via Swift) is the working
API and provides real RSSI, channel, SSID, and noise data for all visible networks.
BSSIDs are redacted by macOS privacy policy, but SSID+channel uniquely identifies
each AP for the pipeline.
Goal: Add a macOS CoreWLAN adapter so --source wifi works on macOS with real RSSI
data flowing through the 8-stage sensing pipeline (motion detection, breathing
extraction, presence).
Approach
- Create Swift helper binary: macos-wifi-scan
A small Swift CLI that calls CoreWLAN and outputs JSON to stdout. The Rust adapter
calls this via Command::new() — same pattern as netsh on Windows.
File: rust-port/wifi-densepose-rs/tools/macos-wifi-scan/main.swift
// Calls CWWiFiClient.shared().interface().scanForNetworks()
// Outputs JSON array: [{ssid, rssi, noise, channel, band, phy_mode}, ...]
// Also includes connected network info
Build with: swiftc -framework CoreWLAN -framework Foundation -o macos-wifi-scan
main.swift
- Create Rust macOS adapter: MacosCoreWlanScanner
File: rust-port/wifi-densepose-rs/crates/wifi-densepose-wifiscan/src/adapter/macos_sc
anner.rs
Implements the WlanScanPort trait:
- scan() — calls the Swift helper, parses JSON output, returns Vec
- connected() — returns the connected network's observation
- Uses SSID:channel as a synthetic BSSID (since macOS redacts real BSSIDs)
- Converts RSSI dBm to amplitude via existing rssi_to_amplitude()
- Maps channel to BandType via existing BandType::from_channel()
- Maps PHY mode string to RadioType
- Register adapter in module
File: rust-port/wifi-densepose-rs/crates/wifi-densepose-wifiscan/src/adapter/mod.rs
Add pub mod macos_scanner; and re-export MacosCoreWlanScanner.
File: rust-port/wifi-densepose-rs/crates/wifi-densepose-wifiscan/src/lib.rs
Add re-export at crate root.
- Add macOS WiFi probe + task to sensing server
File: rust-port/wifi-densepose-rs/crates/wifi-densepose-sensing-server/src/main.rs
Changes:
- Add probe_macos_wifi() — runs the Swift helper with --probe flag, returns true if
it outputs valid JSON - Add macos_wifi_task() — same structure as windows_wifi_task() but calls the Swift
helper instead of netsh. Feeds results into the same BssidRegistry +
WindowsWifiPipeline (rename internally to RssiPipeline is optional but these work
as-is) - Update auto-detection (line ~1697): add probe_macos_wifi() check between ESP32 and
simulation fallback - Update --source wifi match (line ~1806): dispatch to macos_wifi_task() on macOS,
windows_wifi_task() on Windows
- Build integration
File: rust-port/wifi-densepose-rs/crates/wifi-densepose-sensing-server/Cargo.toml
No new Rust dependencies needed — std::process::Command + serde_json (already
available) handle the Swift subprocess.
The Swift binary is built separately and expected at a known path relative to the
server binary or in $PATH.
Files to Create
File: rust-port/wifi-densepose-rs/tools/macos-wifi-scan/main.swift
Purpose: Swift CoreWLAN helper binary
────────────────────────────────────────
File: rust-port/wifi-densepose-rs/tools/macos-wifi-scan/build.sh
Purpose: Build script for the Swift binary
────────────────────────────────────────
File: rust-port/wifi-densepose-rs/crates/wifi-densepose-wifiscan/src/adapter/macos_sc
anner.rs
Purpose: Rust macOS adapter
Files to Modify
File: crates/wifi-densepose-wifiscan/src/adapter/mod.rs
Change: Add macos_scanner module + exports
────────────────────────────────────────
File: crates/wifi-densepose-wifiscan/src/lib.rs
Change: Add MacosCoreWlanScanner re-export
────────────────────────────────────────
File: crates/wifi-densepose-sensing-server/src/main.rs
Change: Add probe_macos_wifi(), macos_wifi_task(), update auto-detect + source
dispatch
Existing Code to Reuse
- WlanScanPort trait — crates/wifi-densepose-wifiscan/src/port/scan_port.rs
- BssidObservation, BssidId, BandType, RadioType —
crates/wifi-densepose-wifiscan/src/domain/bssid.rs - BssidRegistry — crates/wifi-densepose-wifiscan/src/domain/registry.rs
- WindowsWifiPipeline — crates/wifi-densepose-wifiscan/src/pipeline/orchestrator.rs
- MultiApFrame — crates/wifi-densepose-wifiscan/src/domain/frame.rs
- WifiScanError — crates/wifi-densepose-wifiscan/src/error.rs
- windows_wifi_task() as template —
crates/wifi-densepose-sensing-server/src/main.rs:486-663 - rssi_to_amplitude(), pseudo_phase() —
crates/wifi-densepose-wifiscan/src/domain/bssid.rs:191-217
Verification
- Build the Swift helper: cd tools/macos-wifi-scan && ./build.sh
- Test it standalone: ./macos-wifi-scan — should print JSON with real RSSI values
- Build the Rust workspace: cargo build --release
- Run tests: cargo test --workspace
- Start server: ./target/release/sensing-server --source wifi --ui-path ../../ui
- Verify real data: curl http://localhost:8080/api/v1/sensing/latest — should show
source: "wifi:" with real RSSI values, not simulated - Open UI: http://localhost:8080/ui/index.html — signal field should respond to
physical movement near the Mac - Verify vitals: curl http://localhost:8080/api/v1/vital-signs — breathing/motion
from real RSSI variance