use nom::{
number::streaming::{be_u16, be_u8},
Err, IResult, Needed,
};
use crate::Error;
use super::*;
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct Header {
pub packet_type: PktType,
pub c: bool,
pub t: bool,
pub tsi: Tsi,
pub tsf: Tsf,
pub packet_count: u8,
pub packet_size: u16,
}
impl Header {
pub fn parse(i: &[u8]) -> IResult<&[u8], Header> {
if i.len() < 4 {
return Err(Err::Incomplete(Needed::new(4)));
}
let (i, first_byte) = be_u8(i)?;
let packet_type = PktType::try_from((first_byte >> 4) & 0b1111)
.map_err(|_| Err::Error(nom::error::Error::new(i, nom::error::ErrorKind::Verify)))?;
let c = ((first_byte >> 3) & 0x01) != 0;
let t = ((first_byte >> 2) & 0x01) != 0;
let (i, second_byte) = be_u8(i)?;
let tsi = Tsi::try_from((second_byte >> 6) & 0b11)
.map_err(|_| Err::Error(nom::error::Error::new(i, nom::error::ErrorKind::Verify)))?;
let tsf = Tsf::try_from((second_byte >> 4) & 0b11)
.map_err(|_| Err::Error(nom::error::Error::new(i, nom::error::ErrorKind::Verify)))?;
let packet_count: u8 = (second_byte) & 0xf;
let (i, packet_size) = be_u16(i)?;
let hdr = Header {
packet_type,
c,
t,
tsi,
tsf,
packet_count,
packet_size,
};
Ok((i, hdr))
}
pub fn serialize(&self, buffer: &mut [u8]) -> Result<usize, Error> {
if buffer.len() < size_of::<u32>() {
return Err(Error::BufferFull);
}
let mut word = 0;
word |= u32::from(u8::from(self.packet_type)) << 28;
word |= u32::from(self.c) << 27;
word |= u32::from(self.t) << 26;
word |= u32::from(u8::from(self.tsi)) << 22;
word |= u32::from(u8::from(self.tsf)) << 20;
word |= (u32::from(self.packet_count) & 0xf) << 16;
word |= u32::from(self.packet_size);
buffer[..4].copy_from_slice(&word.to_be_bytes());
Ok(size_of::<u32>())
}
}