dot15d4_frame/repr/ie/
mod.rs1mod headers;
2pub use headers::*;
3
4mod nested;
5pub use nested::*;
6
7mod payloads;
8pub use payloads::*;
9
10use super::super::{InformationElements, PayloadInformationElement};
11use super::Result;
12
13use heapless::Vec;
14
15#[derive(Debug, Default)]
17pub struct InformationElementsRepr {
18 pub header_information_elements: Vec<HeaderInformationElementRepr, 16>,
20 pub payload_information_elements: Vec<PayloadInformationElementRepr, 16>,
22}
23
24#[cfg(feature = "fuzz")]
25impl arbitrary::Arbitrary<'_> for InformationElementsRepr {
26 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
27 let mut header_information_elements = Vec::new();
28 let mut payload_information_elements = Vec::new();
29
30 for _ in 0..u.int_in_range(0..=15)? {
31 header_information_elements
32 .push(HeaderInformationElementRepr::arbitrary(u)?)
33 .map_err(|_| arbitrary::Error::IncorrectFormat)?;
34 }
35
36 for _ in 0..u.int_in_range(0..=15)? {
37 payload_information_elements
38 .push(PayloadInformationElementRepr::arbitrary(u)?)
39 .map_err(|_| arbitrary::Error::IncorrectFormat)?;
40 }
41
42 Ok(Self {
43 header_information_elements,
44 payload_information_elements,
45 })
46 }
47}
48
49impl InformationElementsRepr {
50 pub fn parse(ie: InformationElements<&[u8]>) -> Result<Self> {
52 let mut header_information_elements = Vec::new();
53 let mut payload_information_elements = Vec::new();
54
55 for header_ie in ie.header_information_elements() {
56 if header_information_elements
57 .push(HeaderInformationElementRepr::parse(&header_ie)?)
58 .is_err()
59 {
60 break;
61 }
62 }
63
64 for payload_ie in ie.payload_information_elements() {
65 if payload_information_elements
66 .push(PayloadInformationElementRepr::parse(&payload_ie)?)
67 .is_err()
68 {
69 break;
70 };
71 }
72
73 Ok(Self {
74 header_information_elements,
75 payload_information_elements,
76 })
77 }
78
79 fn header_terminations(&self, contains_payload: bool) -> (bool, bool, bool) {
83 match (
84 !self.header_information_elements.is_empty(),
85 !self.payload_information_elements.is_empty(),
86 contains_payload,
87 ) {
88 (false, false, false) => (false, false, false),
90 (true, false, false) => (false, false, false),
93 (false, true, false) => (true, false, false),
95 (true, true, false) => (true, false, false),
98 (false, false, true) => (false, false, false),
100 (true, false, true) => (false, true, false),
102 (false, true, true) => (true, false, true),
105 (true, true, true) => (true, false, true),
108 }
109 }
110
111 pub fn buffer_len(&self, contains_payload: bool) -> usize {
113 let mut len = 0;
114
115 let (ht1, ht2, pt) = self.header_terminations(contains_payload);
116
117 for ie in self.header_information_elements.iter() {
118 len += ie.buffer_len();
119 }
120
121 if ht1 {
122 len += HeaderInformationElementRepr::HeaderTermination1.buffer_len();
123 }
124
125 if ht2 {
126 len += HeaderInformationElementRepr::HeaderTermination1.buffer_len();
127 }
128
129 for ie in self.payload_information_elements.iter() {
130 len += ie.buffer_len();
131 }
132
133 if pt {
134 len += PayloadInformationElementRepr::PayloadTermination.buffer_len();
135 }
136
137 len
138 }
139
140 pub fn emit(&self, buffer: &mut [u8], contains_payload: bool) {
142 let mut offset = 0;
143
144 let (ht1, ht2, pt) = self.header_terminations(contains_payload);
145
146 for ie in self.header_information_elements.iter() {
147 ie.emit(&mut buffer[offset..][..ie.buffer_len()]);
148 offset += ie.buffer_len();
149 }
150
151 if ht1 {
152 HeaderInformationElementRepr::HeaderTermination1.emit(&mut buffer[offset..][..2]);
153 offset += 2;
154 }
155
156 if ht2 {
157 HeaderInformationElementRepr::HeaderTermination2.emit(&mut buffer[offset..][..2]);
158 offset += 2;
159 }
160
161 for ie in self.payload_information_elements.iter() {
162 ie.emit(&mut PayloadInformationElement::new_unchecked(
163 &mut buffer[offset..][..ie.buffer_len()],
164 ));
165 offset += ie.buffer_len();
166 }
167
168 if pt {
169 PayloadInformationElementRepr::PayloadTermination.emit(
170 &mut PayloadInformationElement::new_unchecked(&mut buffer[offset..][..2]),
171 );
172 }
173 }
174}