95 lines
3.0 KiB
Rust
95 lines
3.0 KiB
Rust
//! Acceptance tests for `BfldFrameHeader` serialization (ADR-119 AC5/AC6).
|
|
|
|
use wifi_densepose_bfld::frame::flags;
|
|
use wifi_densepose_bfld::{BfldError, BfldFrameHeader, BFLD_HEADER_SIZE, BFLD_MAGIC};
|
|
|
|
fn sample_header() -> BfldFrameHeader {
|
|
let mut h = BfldFrameHeader::empty();
|
|
h.flags = flags::HAS_CSI_DELTA | flags::PRIVACY_MODE;
|
|
h.timestamp_ns = 0x0123_4567_89AB_CDEF;
|
|
h.ap_hash = [0xAA; 16];
|
|
h.sta_hash = [0xBB; 16];
|
|
h.session_id = [0xCC; 16];
|
|
h.channel = 36;
|
|
h.bandwidth_mhz = 80;
|
|
h.rssi_dbm = -55;
|
|
h.noise_floor_dbm = -95;
|
|
h.n_subcarriers = 234;
|
|
h.n_tx = 3;
|
|
h.n_rx = 4;
|
|
h.quantization = 1;
|
|
h.privacy_class = 2;
|
|
h.payload_len = 12_345;
|
|
h.payload_crc32 = 0xDEAD_BEEF;
|
|
h
|
|
}
|
|
|
|
#[test]
|
|
fn header_roundtrip_preserves_all_fields() {
|
|
let original = sample_header();
|
|
let bytes = original.to_le_bytes();
|
|
let parsed = BfldFrameHeader::from_le_bytes(&bytes).expect("parse must succeed");
|
|
|
|
assert_eq!({ parsed.magic }, BFLD_MAGIC);
|
|
assert_eq!({ parsed.version }, 1);
|
|
assert_eq!({ parsed.flags }, flags::HAS_CSI_DELTA | flags::PRIVACY_MODE);
|
|
assert_eq!({ parsed.timestamp_ns }, 0x0123_4567_89AB_CDEF);
|
|
assert_eq!(parsed.ap_hash, [0xAA; 16]);
|
|
assert_eq!(parsed.sta_hash, [0xBB; 16]);
|
|
assert_eq!(parsed.session_id, [0xCC; 16]);
|
|
assert_eq!({ parsed.channel }, 36);
|
|
assert_eq!({ parsed.bandwidth_mhz }, 80);
|
|
assert_eq!({ parsed.rssi_dbm }, -55);
|
|
assert_eq!({ parsed.noise_floor_dbm }, -95);
|
|
assert_eq!({ parsed.n_subcarriers }, 234);
|
|
assert_eq!(parsed.n_tx, 3);
|
|
assert_eq!(parsed.n_rx, 4);
|
|
assert_eq!(parsed.quantization, 1);
|
|
assert_eq!(parsed.privacy_class, 2);
|
|
assert_eq!({ parsed.payload_len }, 12_345);
|
|
assert_eq!({ parsed.payload_crc32 }, 0xDEAD_BEEF);
|
|
}
|
|
|
|
#[test]
|
|
fn header_serialization_is_deterministic() {
|
|
let h = sample_header();
|
|
let a = h.to_le_bytes();
|
|
let b = h.to_le_bytes();
|
|
assert_eq!(a, b, "two serializations of the same header must be bit-identical");
|
|
}
|
|
|
|
#[test]
|
|
fn header_magic_is_at_offset_zero_little_endian() {
|
|
let bytes = sample_header().to_le_bytes();
|
|
// BFLD_MAGIC = 0xBF1D_0001 → little-endian: 01 00 1D BF
|
|
assert_eq!(&bytes[0..4], &[0x01, 0x00, 0x1D, 0xBF]);
|
|
}
|
|
|
|
#[test]
|
|
fn parsing_rejects_invalid_magic() {
|
|
let mut bytes = sample_header().to_le_bytes();
|
|
bytes[0] = 0xFF; // clobber magic
|
|
match BfldFrameHeader::from_le_bytes(&bytes) {
|
|
Err(BfldError::InvalidMagic(got)) => {
|
|
assert_ne!(got, BFLD_MAGIC);
|
|
}
|
|
other => panic!("expected InvalidMagic, got {other:?}"),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn parsing_rejects_unsupported_version() {
|
|
let mut bytes = sample_header().to_le_bytes();
|
|
bytes[4] = 99; // version field at offset 4 (LE u16)
|
|
bytes[5] = 0;
|
|
match BfldFrameHeader::from_le_bytes(&bytes) {
|
|
Err(BfldError::UnsupportedVersion(v)) => assert_eq!(v, 99),
|
|
other => panic!("expected UnsupportedVersion, got {other:?}"),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn wire_size_is_constant() {
|
|
assert_eq!(sample_header().to_le_bytes().len(), BFLD_HEADER_SIZE);
|
|
}
|