dot15d4_frame/repr/ie/
headers.rs

1use super::super::super::{Error, Result};
2use super::super::super::{HeaderElementId, HeaderInformationElement, TimeCorrection};
3
4use crate::time::Duration;
5
6/// A high-level representation of a Header Information Element.
7#[derive(Debug)]
8#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
9pub enum HeaderInformationElementRepr {
10    /// Time Correction Header Information Element.
11    TimeCorrection(TimeCorrectionRepr),
12    /// Header Termination 1.
13    HeaderTermination1,
14    /// Header Termination 2.
15    HeaderTermination2,
16}
17
18impl HeaderInformationElementRepr {
19    /// Parse a Header Information Element.
20    pub fn parse(ie: &HeaderInformationElement<&[u8]>) -> Result<Self> {
21        Ok(match ie.element_id() {
22            HeaderElementId::TimeCorrection => Self::TimeCorrection(TimeCorrectionRepr::parse(
23                &TimeCorrection::new(ie.content())?,
24            )),
25            HeaderElementId::HeaderTermination1 => Self::HeaderTermination1,
26            HeaderElementId::HeaderTermination2 => Self::HeaderTermination2,
27            _ => return Err(Error),
28        })
29    }
30
31    /// The buffer length required to emit the Header Information Element.
32    pub fn buffer_len(&self) -> usize {
33        2 + self.inner_len()
34    }
35
36    /// The buffer length required to emit the inner part of the Header
37    /// Information Element.
38    fn inner_len(&self) -> usize {
39        match self {
40            Self::TimeCorrection(tc) => tc.buffer_len(),
41            Self::HeaderTermination1 => 0,
42            Self::HeaderTermination2 => 0,
43        }
44    }
45
46    /// Emit the Header Information Element into a buffer.
47    pub fn emit(&self, buffer: &mut [u8]) {
48        let mut w = HeaderInformationElement::new_unchecked(&mut buffer[..]);
49        w.clear();
50        w.set_length(self.inner_len() as u16);
51        w.set_element_id(self.into());
52
53        match self {
54            Self::TimeCorrection(repr) => {
55                repr.emit(&mut TimeCorrection::new_unchecked(w.content_mut()));
56            }
57            Self::HeaderTermination1 => {}
58            Self::HeaderTermination2 => {}
59        }
60    }
61}
62
63impl From<&HeaderInformationElementRepr> for HeaderElementId {
64    fn from(val: &HeaderInformationElementRepr) -> Self {
65        use HeaderInformationElementRepr::*;
66        match val {
67            TimeCorrection(_) => HeaderElementId::TimeCorrection,
68            HeaderTermination1 => HeaderElementId::HeaderTermination1,
69            HeaderTermination2 => HeaderElementId::HeaderTermination2,
70        }
71    }
72}
73
74/// A high-level representation of a Time Correction Header Information Element.
75#[derive(Debug)]
76#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
77pub struct TimeCorrectionRepr {
78    /// The time correction value in microseconds.
79    pub time_correction: Duration,
80    /// The negative acknowledgment flag.
81    pub nack: bool,
82}
83
84impl TimeCorrectionRepr {
85    /// Parse a Time Correction Header Information Element.
86    pub fn parse(tc: &TimeCorrection<&'_ [u8]>) -> Self {
87        Self {
88            time_correction: tc.time_correction(),
89            nack: tc.nack(),
90        }
91    }
92
93    /// The buffer length required to emit the Time Correction Header
94    /// Information Element.
95    pub const fn buffer_len(&self) -> usize {
96        2
97    }
98
99    /// Emit the Time Correction Header Information Element into a buffer.
100    pub fn emit(&self, buffer: &mut TimeCorrection<&mut [u8]>) {
101        buffer.set_time_correction(self.time_correction);
102        buffer.set_nack(self.nack);
103    }
104}