use serde::{Deserialize, Serialize};
pub(crate) static INITIATOR_MAGIC_NUMBER: u32 = 0xA8912BF0;
pub(crate) static RESPONDER_MAGIC_NUMBER: u32 = !INITIATOR_MAGIC_NUMBER;
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct ControlPacket {
pub initiator_reports: bool,
pub sequence_number: u32,
}
impl ControlPacket {
pub fn new(initiator_reports: bool, sequence_number: u32) -> Self {
Self {
initiator_reports,
sequence_number,
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct ResponderPacket;
impl ResponderPacket {
pub fn new() -> Self {
Self
}
}
impl Default for ResponderPacket {
fn default() -> Self {
Self::new()
}
}
pub(crate) const RESPONDER_BEACON_SENTINEL: u8 = 0;
pub(crate) fn serialize_with_magic<'a, T: Serialize>(
packet: &T,
magic: u32,
send_magic: bool,
buf: &'a mut [u8],
) -> Result<&'a [u8], postcard::Error> {
if send_magic {
buf[0..4].copy_from_slice(&magic.to_le_bytes());
let body = postcard::to_slice(packet, &mut buf[4..])?;
let len = 4 + body.len();
Ok(&buf[..len])
} else {
let body = postcard::to_slice(packet, buf)?;
let len = body.len();
Ok(&buf[..len])
}
}
pub(crate) fn control_sequence_in(payload: &[u8]) -> Option<u32> {
let magic = INITIATOR_MAGIC_NUMBER.to_le_bytes();
let at = payload.windows(4).position(|w| w == magic)?;
postcard::take_from_bytes::<ControlPacket>(&payload[at + 4..])
.ok()
.map(|(p, _)| p.sequence_number)
}
pub(crate) fn parse_with_magic<T: for<'de> Deserialize<'de>>(
data: &[u8],
magic: u32,
expect_magic: bool,
) -> Option<T> {
let body = if expect_magic {
if data.len() < 4 || u32::from_le_bytes(data[0..4].try_into().ok()?) != magic {
return None;
}
&data[4..]
} else {
data
};
postcard::take_from_bytes::<T>(body)
.ok()
.map(|(v, _rest)| v)
}