mac-os support stopped #56
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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
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
File: rust-port/wifi-densepose-rs/crates/wifi-densepose-wifiscan/src/adapter/macos_sc
anner.rs
Implements the WlanScanPort trait:
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.
File: rust-port/wifi-densepose-rs/crates/wifi-densepose-sensing-server/src/main.rs
Changes:
it outputs valid JSON
helper instead of netsh. Feeds results into the same BssidRegistry +
WindowsWifiPipeline (rename internally to RssiPipeline is optional but these work
as-is)
simulation fallback
windows_wifi_task() on Windows
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
crates/wifi-densepose-wifiscan/src/domain/bssid.rs
crates/wifi-densepose-sensing-server/src/main.rs:486-663
crates/wifi-densepose-wifiscan/src/domain/bssid.rs:191-217
Verification
source: "wifi:" with real RSSI values, not simulated
physical movement near the Mac
from real RSSI variance
Great write-up — the approach is solid and aligns well with the existing adapter architecture.
Confirming the current state:
wifi-densepose-wifiscancrate has a clean adapter pattern insrc/adapter/— currentlyNetshBssidScanner(Tier 1,netshsubprocess) andWlanApiScanner(Tier 2, async wrapper). AMacosCoreWlanScannerfollowing the sameCommand::new()+ parse JSON pattern is the right fit.tools/directory doesn't exist yet, so the Swift helper creates a new convention for platform-specific helper binaries.Notes on the proposed approach:
Swift helper as subprocess — correct call. CoreWLAN is ObjC/Swift-only, and FFI bridging is not worth the complexity. A Swift CLI outputting JSON to stdout, called via
Command::new(), matches thenetshpattern exactly.SSID:channel as synthetic BSSID — good workaround for Apple's BSSID redaction. Worth noting in the adapter docs that this means two APs on the same channel with the same SSID will collapse to one observation. Rare in practice but should be documented.
--probeflag on the Swift helper — clean way to handle auto-detection without a full scan. The probe can check CoreWLAN availability and return a minimal JSON response.Pipeline reuse — the existing
WindowsWifiPipeline/BssidRegistry/ 8-stage pipeline works as-is since it operates onBssidObservationstructs regardless of source. No changes needed there.One addition to consider:
#[cfg(target_os = "macos")]gate on themacos_scannermodule and themacos_wifi_task()inmain.rsso the macOS code doesn't compile on Windows/Linux (mirroring hownetsh_scanneris Windows-specific).Build integration:
The Swift binary build (
swiftc -framework CoreWLAN ...) should probably be abuild.shas proposed, documented in the crate README, and noted as a prerequisite for--source wifion macOS. Acargo buildalone won't produce the Swift binary — that's fine as long as the server gives a clear error message when the helper isn't found in$PATHor alongside the binary.This is a welcome addition. Tagged for implementation.
ADR-025 published:
docs/adr/ADR-025-macos-corewlan-wifi-sensing.mdCodename ORCA (OS-native Radio Channel Acquisition). Key decisions:
tools/macos-wifi-scan/main.swift) shells out to CoreWLAN, outputs JSON — same subprocess pattern asNetshBssidScanneron Windowssha256(ssid:channel)[:12]as synthetic BSSID when Apple redacts MAC addresses (no Location Services needed for basic sensing)BssidObservationidentical to Windows path, all downstream signal intelligence runs as-is#[cfg(target_os = "macos")]gating — zero impact on Windows/Linux buildsKnown limitation: CoreWLAN scan rate (~0.3 Hz) is slower than
netsh(~2 Hz), so breathing extraction will be marginal. Presence and motion detection work fine.Build/test target: Mac Mini (M2 Pro, macOS 26.3).