use super::frame_control::FrameControl;
use crate::internal::macros::impl_byte;
use crate::internal::types::IeeeAddress;
use crate::internal::types::ShortAddress;
impl_byte! {
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Header<'a> {
pub frame_control: FrameControl,
pub destination: ShortAddress,
pub source: ShortAddress,
pub radius: u8,
pub sequence_number: u8,
#[parse_if = frame_control.destination_ieee_flag()]
pub destination_ieee: Option<IeeeAddress>,
#[parse_if = frame_control.source_ieee_flag()]
pub source_ieee: Option<IeeeAddress>,
#[parse_if = frame_control.multicast_flag()]
pub multicast_control: Option<MulticastControl>,
#[parse_if = frame_control.source_flag()]
pub source_route_subframe: Option<SourceRouteSubframe<'a>>,
}
}
impl_byte! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct MulticastControl(u8);
}
impl_byte! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct SourceRouteSubframe<'a> {
pub relay_count: u8,
pub relay_index: u8,
#[ctx = byte::ctx::Bytes::Len(relay_count as usize)]
#[ctx_write = ()]
pub relay_list: &'a [u8],
}
}
#[cfg(test)]
mod tests {
use byte::TryRead;
use super::*;
#[test]
fn parse_nwk_header() {
let raw = [
0x09, 0x12, 0xfc, 0xff, 0x00, 0x00, 0x08, 0xbf, 0x66, 0x71, 0x9a, 0x2a, 0x00, 0x4b,
0x12, 0x00,
];
let (header, _) = Header::try_read(&raw, ()).unwrap();
assert!(header.frame_control.security_flag());
assert!(header.frame_control.source_ieee_flag());
assert_eq!(header.destination, ShortAddress(0xfffc));
assert_eq!(header.source_ieee, Some(IeeeAddress(0x0012_4b00_2a9a_7166)));
assert_eq!(header.radius, 8);
assert_eq!(header.sequence_number, 191);
}
}