#![allow(clippy::unwrap_used, clippy::panic)]
use donglora_protocol::framing::{CobsDecoder, MAX_FRAME, cobs_encode_response};
use donglora_protocol::{Bandwidth, Command, RADIO_CONFIG_SIZE, RadioConfig, Response};
use heapless::Vec as HVec;
fn base_config() -> RadioConfig {
RadioConfig {
freq_hz: 915_000_000,
bw: Bandwidth::Khz125,
sf: 7,
cr: 5,
sync_word: 0x1234,
tx_power_dbm: 22,
preamble_len: 16,
cad: 1,
}
}
#[test]
fn cad_enabled_is_true_for_non_zero() {
for cad in [1u8, 2, 127, 255] {
let cfg = RadioConfig {
cad,
..base_config()
};
assert!(cfg.cad_enabled(), "cad={cad} must report enabled");
}
}
#[test]
fn cad_enabled_is_false_for_zero() {
let cfg = RadioConfig {
cad: 0,
..base_config()
};
assert!(!cfg.cad_enabled());
}
#[test]
fn transmit_with_config_requires_more_than_radio_config_size() {
let mut just_config = [0u8; 2 + RADIO_CONFIG_SIZE];
just_config[0] = 5; just_config[1] = 1; base_config().write_to(&mut just_config[2..]);
assert!(
Command::from_bytes(&just_config).is_none(),
"has_config=1 with no len bytes must reject",
);
let mut bad_flag = [0u8; 32];
bad_flag[0] = 5;
bad_flag[1] = 2;
assert!(
Command::from_bytes(&bad_flag).is_none(),
"has_config must be strictly 0 or 1",
);
}
#[test]
fn cobs_decoder_reset_discards_partial_frame() {
let mut decoder = CobsDecoder::new();
decoder.feed(&[0x02, 0x99], |_| panic!("no command yet"));
decoder.reset();
let mut raw = [0u8; 1];
raw[0] = 0;
let mut framed = [0u8; 8];
let n = ucobs::encode(&raw[..1], &mut framed).unwrap();
framed[n] = 0x00;
let mut got = None;
decoder.feed(&framed[..n + 1], |c| got = Some(c));
assert_eq!(got, Some(Command::Ping));
}
#[test]
fn cobs_decoder_treats_back_to_back_zeros_as_empty_frames() {
let mut decoder = CobsDecoder::new();
let mut yielded = 0;
decoder.feed(&[0, 0, 0, 0, 0], |_| yielded += 1);
assert_eq!(yielded, 0);
}
#[test]
fn cobs_encode_response_rejects_overflow() {
let mut payload: HVec<u8, 256> = HVec::new();
for i in 0..256u16 {
payload.push((i & 0xFF) as u8).unwrap();
}
let mut write = [0u8; MAX_FRAME];
let mut encode = [0u8; MAX_FRAME];
let framed = cobs_encode_response(
Response::RxPacket {
rssi: -1,
snr: -2,
payload,
},
&mut write,
&mut encode,
)
.unwrap();
assert_eq!(*framed.last().unwrap(), 0x00);
assert!(framed.len() <= MAX_FRAME);
}