use crate::integrity::crc::Crc8;
use super::EnvelopeMagic;
pub const WIRE_MAGIC_LEN: usize = 1;
pub const WIRE_HEADER_LEN: usize = WIRE_MAGIC_LEN + core::mem::size_of::<u8>() + 1;
pub const WIRE_PACKET_LEN_OFFSET: usize = WIRE_MAGIC_LEN;
pub const WIRE_HEADER_CRC_OFFSET: usize = WIRE_PACKET_LEN_OFFSET + core::mem::size_of::<u8>();
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct EnvelopeHeader {
pub magic: EnvelopeMagic,
pub packet_len: u8,
pub header_crc: u8,
}
impl EnvelopeHeader {
#[must_use]
pub const fn new(packet_len: u8) -> Self {
Self {
magic: EnvelopeMagic::MSRT,
packet_len,
header_crc: header_crc(packet_len),
}
}
#[must_use]
pub const fn has_valid_header_crc(self) -> bool {
self.header_crc == header_crc(self.packet_len)
}
#[must_use]
pub const fn total_len(self, integrity_tag_len: usize) -> usize {
WIRE_HEADER_LEN + self.packet_len as usize + integrity_tag_len
}
}
#[must_use]
pub const fn header_crc(packet_len: u8) -> u8 {
Crc8.calculate(&[packet_len])
}
#[cfg(test)]
mod tests {
use super::{EnvelopeHeader, WIRE_HEADER_LEN, header_crc};
#[test]
fn header_total_len_includes_integrity_tag() {
let header = EnvelopeHeader::new(9);
let integrity_tag_len = 2;
assert!(header.has_valid_header_crc());
assert_eq!(
header.total_len(integrity_tag_len),
WIRE_HEADER_LEN + 9 + integrity_tag_len
);
}
#[test]
fn header_crc_changes_when_length_changes() {
assert_ne!(header_crc(9), header_crc(10));
}
}