dot15d4_frame/repr/
mod.rsuse crate::FrameType;
use super::{Error, Frame, Result};
mod addressing;
pub use addressing::AddressingFieldsRepr;
mod frame_control;
pub use frame_control::FrameControlRepr;
mod ie;
pub use ie::*;
mod builder;
pub use builder::FrameBuilder;
#[derive(Debug)]
#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
pub struct FrameRepr<'p> {
pub frame_control: FrameControlRepr,
pub sequence_number: Option<u8>,
pub addressing_fields: Option<AddressingFieldsRepr>,
pub information_elements: Option<InformationElementsRepr>,
pub payload: Option<&'p [u8]>,
}
impl<'f> FrameRepr<'f> {
pub fn parse(reader: &Frame<&'f [u8]>) -> Result<Self> {
let frame_control = FrameControlRepr::parse(reader.frame_control())?;
let addressing_fields = reader
.addressing()
.map(|af| AddressingFieldsRepr::parse(af));
let information_elements = reader
.information_elements()
.map(InformationElementsRepr::parse)
.transpose()?;
Ok(Self {
frame_control,
sequence_number: reader.sequence_number(),
addressing_fields,
information_elements,
payload: reader.payload(),
})
}
pub fn validate(&self) -> Result<()> {
if self.frame_control.frame_type == FrameType::Data {
if self.addressing_fields.is_none() {
return Err(Error);
}
if self.payload.is_none() {
return Err(Error);
}
}
if let Some(af) = &self.addressing_fields {
af.validate(&self.frame_control)?;
}
if let Some(payload) = self.payload {
if payload.is_empty() {
return Err(Error);
}
}
Ok(())
}
pub fn buffer_len(&self) -> usize {
let mut len = 2; if self.sequence_number.is_some() {
len += 1;
}
if let Some(af) = &self.addressing_fields {
len += af.buffer_len(&self.frame_control);
}
if let Some(ie) = &self.information_elements {
len += ie.buffer_len(self.payload.is_some());
}
if let Some(payload) = self.payload {
len += payload.len();
}
len
}
pub fn emit(&self, frame: &mut Frame<&'_ mut [u8]>) {
frame.set_frame_control(&self.frame_control);
if let Some(sequence_number) = self.sequence_number {
frame.set_sequence_number(sequence_number);
}
if let Some(af) = &self.addressing_fields {
frame.set_addressing_fields(af);
}
if let Some(ie) = &self.information_elements {
frame.set_information_elements(ie, self.payload.is_some());
}
if let Some(payload) = self.payload {
frame.set_payload(payload);
}
}
}