1use super::*;
2use crate::{Address, AddressingMode, FrameType, FrameVersion};
3use crate::{Error, Result};
4
5pub struct Beacon;
6pub struct EnhancedBeacon;
7pub struct Ack;
8pub struct Data;
9
10pub struct FrameBuilder<'p, T> {
12 frame: FrameRepr<'p>,
13 r#type: core::marker::PhantomData<T>,
14}
15
16impl<'p> FrameBuilder<'p, Ack> {
17 pub fn new_imm_ack(sequence_number: u8) -> Self {
19 Self {
20 frame: FrameRepr {
21 frame_control: FrameControlRepr {
22 frame_type: FrameType::Ack,
23 security_enabled: false,
24 frame_pending: false,
25 ack_request: false,
26 pan_id_compression: false,
27 sequence_number_suppression: false,
28 information_elements_present: false,
29 dst_addressing_mode: AddressingMode::Absent,
30 src_addressing_mode: AddressingMode::Absent,
31 frame_version: FrameVersion::Ieee802154_2006,
32 },
33 sequence_number: Some(sequence_number),
34 addressing_fields: None,
35 information_elements: None,
36 payload: None,
37 },
38 r#type: Default::default(),
39 }
40 }
41
42 pub fn new_ack() -> Self {
44 Self {
45 frame: FrameRepr {
46 frame_control: FrameControlRepr {
47 frame_type: FrameType::Ack,
48 security_enabled: false,
49 frame_pending: false,
50 ack_request: false,
51 pan_id_compression: false,
52 sequence_number_suppression: true,
53 information_elements_present: false,
54 dst_addressing_mode: AddressingMode::Absent,
55 src_addressing_mode: AddressingMode::Absent,
56 frame_version: FrameVersion::Ieee802154_2020,
57 },
58 sequence_number: None,
59 addressing_fields: None,
60 information_elements: None,
61 payload: None,
62 },
63 r#type: Default::default(),
64 }
65 }
66}
67
68impl<'p> FrameBuilder<'p, Beacon> {
69 pub fn new_beacon() -> Self {
71 Self {
72 frame: FrameRepr {
73 frame_control: FrameControlRepr {
74 frame_type: FrameType::Beacon,
75 security_enabled: false,
76 frame_pending: false,
77 ack_request: false,
78 pan_id_compression: false,
79 sequence_number_suppression: true,
80 information_elements_present: false,
81 dst_addressing_mode: AddressingMode::Absent,
82 src_addressing_mode: AddressingMode::Absent,
83 frame_version: FrameVersion::Ieee802154_2006,
84 },
85 sequence_number: None,
86 addressing_fields: None,
87 information_elements: None,
88 payload: None,
89 },
90 r#type: core::marker::PhantomData,
91 }
92 }
93}
94
95impl<'p> FrameBuilder<'p, EnhancedBeacon> {
96 pub fn new_enhanced_beacon() -> Self {
98 Self {
99 frame: FrameRepr {
100 frame_control: FrameControlRepr {
101 frame_type: FrameType::Beacon,
102 security_enabled: false,
103 frame_pending: false,
104 ack_request: false,
105 pan_id_compression: false,
106 sequence_number_suppression: true,
107 information_elements_present: false,
108 dst_addressing_mode: AddressingMode::Absent,
109 src_addressing_mode: AddressingMode::Absent,
110 frame_version: FrameVersion::Ieee802154_2020,
111 },
112 sequence_number: None,
113 addressing_fields: None,
114 information_elements: None,
115 payload: None,
116 },
117 r#type: core::marker::PhantomData,
118 }
119 }
120}
121
122impl<'p> FrameBuilder<'p, Data> {
123 pub fn new_data(payload: &'p [u8]) -> Self {
125 Self {
126 frame: FrameRepr {
127 frame_control: FrameControlRepr {
128 frame_type: FrameType::Data,
129 security_enabled: false,
130 frame_pending: false,
131 ack_request: false,
132 pan_id_compression: false,
133 sequence_number_suppression: true,
134 information_elements_present: false,
135 dst_addressing_mode: AddressingMode::Absent,
136 src_addressing_mode: AddressingMode::Absent,
137 frame_version: FrameVersion::Ieee802154_2006,
138 },
139 sequence_number: None,
140 addressing_fields: None,
141 information_elements: None,
142 payload: Some(payload),
143 },
144 r#type: core::marker::PhantomData,
145 }
146 }
147}
148
149impl<'p, T> FrameBuilder<'p, T> {
150 pub fn set_sequence_number(mut self, sequence_number: u8) -> Self {
155 self.frame.sequence_number = Some(sequence_number);
156 self.frame.frame_control.sequence_number_suppression = false;
157 self
158 }
159
160 pub fn set_dst_pan_id(mut self, pan_id: u16) -> Self {
162 self.frame
163 .addressing_fields
164 .get_or_insert_with(AddressingFieldsRepr::default)
165 .dst_pan_id = Some(pan_id);
166
167 self
168 }
169
170 pub fn set_src_pan_id(mut self, pan_id: u16) -> Self {
172 self.frame
173 .addressing_fields
174 .get_or_insert_with(AddressingFieldsRepr::default)
175 .src_pan_id = Some(pan_id);
176 self
177 }
178
179 pub fn set_dst_address(mut self, address: Address) -> Self {
184 self.frame.frame_control.dst_addressing_mode = address.into();
185 self.frame
186 .addressing_fields
187 .get_or_insert_with(AddressingFieldsRepr::default)
188 .dst_address = Some(address);
189 self
190 }
191
192 pub fn set_src_address(mut self, address: Address) -> Self {
197 self.frame.frame_control.src_addressing_mode = address.into();
198 self.frame
199 .addressing_fields
200 .get_or_insert_with(AddressingFieldsRepr::default)
201 .src_address = Some(address);
202 self
203 }
204
205 pub fn add_header_information_element(mut self, ie: HeaderInformationElementRepr) -> Self {
211 self.frame.frame_control.information_elements_present = true;
212 self.frame
213 .information_elements
214 .get_or_insert_with(InformationElementsRepr::default)
215 .header_information_elements
216 .push(ie)
217 .unwrap();
218
219 self.frame.frame_control.frame_version = FrameVersion::Ieee802154_2020;
220
221 self
222 }
223
224 pub fn add_payload_information_element(mut self, ie: PayloadInformationElementRepr) -> Self {
230 self.frame.frame_control.information_elements_present = true;
231 self.frame
232 .information_elements
233 .get_or_insert_with(InformationElementsRepr::default)
234 .payload_information_elements
235 .push(ie)
236 .unwrap();
237
238 self.frame.frame_control.frame_version = FrameVersion::Ieee802154_2020;
239
240 self
241 }
242
243 pub fn set_payload(mut self, payload: &'p [u8]) -> Self {
245 self.frame.payload = Some(payload);
246 self
247 }
248
249 pub fn finalize(mut self) -> Result<FrameRepr<'p>> {
255 if self.frame.frame_control.frame_version == FrameVersion::Ieee802154_2020 {
257 let Some(addr) = self.frame.addressing_fields.as_mut() else {
258 return Err(Error);
259 };
260
261 self.frame.frame_control.pan_id_compression = match (
262 addr.dst_address,
263 addr.src_address,
264 addr.dst_pan_id,
265 addr.src_pan_id,
266 ) {
267 (None, None, None, None) => false,
268 (None, None, Some(_), None) => true,
269 (Some(_), None, Some(_), None) => false,
270 (None, Some(_), None, Some(_)) => false,
271 (None, Some(_), None, None) => true,
272 (Some(Address::Extended(_)), Some(Address::Extended(_)), Some(_), None) => false,
273 (Some(Address::Extended(_)), Some(Address::Extended(_)), None, None) => true,
274 (Some(Address::Short(_)), Some(Address::Short(_)), Some(dst), Some(src)) => {
275 if dst == src {
276 addr.src_pan_id = None;
277 }
278
279 dst == src
280 }
281 (Some(Address::Short(_)), Some(Address::Extended(_)), Some(dst), Some(src)) => {
282 if dst == src {
283 addr.src_pan_id = None;
284 }
285
286 dst == src
287 }
288 (Some(Address::Extended(_)), Some(Address::Short(_)), Some(dst), Some(src)) => {
289 if dst == src {
290 addr.src_pan_id = None;
291 }
292
293 dst == src
294 }
295 (Some(Address::Short(_)), Some(Address::Extended(_)), Some(_), None) => true,
296 (Some(Address::Extended(_)), Some(Address::Short(_)), Some(_), None) => true,
297 (Some(Address::Short(_)), Some(Address::Short(_)), Some(_), None) => true,
298 _ => return Err(Error),
299 };
300 } else {
301 if matches!(self.frame.frame_control.frame_type, FrameType::Ack) {
302 if self.frame.sequence_number.is_none() {
304 return Err(Error);
305 }
306
307 self.frame.addressing_fields = None;
309
310 return Ok(self.frame);
311 }
312
313 let Some(addr) = self.frame.addressing_fields.as_mut() else {
321 return Err(Error);
322 };
323
324 match (
325 addr.dst_address,
326 addr.src_address,
327 addr.dst_pan_id,
328 addr.src_pan_id,
329 ) {
330 (Some(_), Some(_), Some(dst_pan_id), Some(src_pan_id)) => {
331 if dst_pan_id == src_pan_id {
332 self.frame.frame_control.pan_id_compression = true;
333 addr.src_pan_id = None;
334 }
335 }
336 (Some(_), None, Some(_), _) => {
337 self.frame.frame_control.pan_id_compression = false;
338 addr.src_pan_id = None;
339 }
340 (None, Some(_), _, Some(_)) => {
341 self.frame.frame_control.pan_id_compression = false;
342 addr.dst_pan_id = None;
343 }
344 _ => return Err(Error),
345 }
346 }
347
348 Ok(self.frame)
349 }
350}