From 9814d2bc622803681ae1b06134397a130c4e8c3b Mon Sep 17 00:00:00 2001 From: rUv Date: Mon, 30 Mar 2026 11:54:03 -0400 Subject: [PATCH] fix(server): correct RSSI byte offset in frame parser (#332) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The server parsed rssi from buf[14] and noise_floor from buf[15], but the firmware (csi_collector.c) packs them at buf[16] and buf[17]: Firmware: n_subcarriers=u16(6-7) freq=u32(8-11) seq=u32(12-15) rssi=i8(16) Server: n_subcarriers=u8(6) freq=u16(8-9) seq=u32(10-13) rssi=i8(14) ← WRONG This caused RSSI to read the high byte of the sequence counter instead of the actual signed RSSI value, producing positive values (e.g., +9) instead of the correct negative values (e.g., -46 dBm). Added inline documentation of the frame layout matching csi_collector.c. Closes #332 --- .../wifi-densepose-sensing-server/src/main.rs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/rust-port/wifi-densepose-rs/crates/wifi-densepose-sensing-server/src/main.rs b/rust-port/wifi-densepose-rs/crates/wifi-densepose-sensing-server/src/main.rs index b0c16803..e5f921ce 100644 --- a/rust-port/wifi-densepose-rs/crates/wifi-densepose-sensing-server/src/main.rs +++ b/rust-port/wifi-densepose-rs/crates/wifi-densepose-sensing-server/src/main.rs @@ -565,13 +565,25 @@ fn parse_esp32_frame(buf: &[u8]) -> Option { return None; } + // Frame layout (must match firmware csi_collector.c): + // [0..3] magic (u32 LE) + // [4] node_id (u8) + // [5] n_antennas (u8) + // [6..7] n_subcarriers (u16 LE) + // [8..11] freq_mhz (u32 LE) + // [12..15] sequence (u32 LE) + // [16] rssi (i8) + // [17] noise_floor (i8) + // [18..19] reserved + // [20..] I/Q data let node_id = buf[4]; let n_antennas = buf[5]; - let n_subcarriers = buf[6]; - let freq_mhz = u16::from_le_bytes([buf[8], buf[9]]); - let sequence = u32::from_le_bytes([buf[10], buf[11], buf[12], buf[13]]); - let rssi = buf[14] as i8; - let noise_floor = buf[15] as i8; + let n_subcarriers_u16 = u16::from_le_bytes([buf[6], buf[7]]); + let n_subcarriers = n_subcarriers_u16 as u8; // truncate to u8 for Esp32Frame compat + let freq_mhz = u16::from_le_bytes([buf[8], buf[9]]); // low 16 bits of u32 + let sequence = u32::from_le_bytes([buf[12], buf[13], buf[14], buf[15]]); + let rssi = buf[16] as i8; // #332: was buf[14], 2 bytes off + let noise_floor = buf[17] as i8; // #332: was buf[15], 2 bytes off let iq_start = 20; let n_pairs = n_antennas as usize * n_subcarriers as usize;