1use super::crc;
7use super::types;
8use super::{FCS_LEN, build_fcf, compute_header_len};
9
10#[derive(Debug, Clone)]
12pub enum Dot15d4Addr {
13 None,
15 Short(u16),
17 Long(u64),
19}
20
21impl Dot15d4Addr {
22 fn mode(&self) -> u8 {
24 match self {
25 Self::None => types::addr_mode::NONE,
26 Self::Short(_) => types::addr_mode::SHORT,
27 Self::Long(_) => types::addr_mode::LONG,
28 }
29 }
30}
31
32#[derive(Debug, Clone)]
34pub struct Dot15d4Builder {
35 pub frame_type: u8,
37 pub security: bool,
39 pub pending: bool,
41 pub ackreq: bool,
43 pub panid_compress: bool,
45 pub frame_ver: u8,
47 pub seqnum: u8,
49 pub dest_panid: Option<u16>,
51 pub dest_addr: Dot15d4Addr,
53 pub src_panid: Option<u16>,
55 pub src_addr: Dot15d4Addr,
57}
58
59impl Dot15d4Builder {
60 #[must_use]
62 pub fn new() -> Self {
63 Self {
64 frame_type: types::frame_type::DATA,
65 security: false,
66 pending: false,
67 ackreq: false,
68 panid_compress: false,
69 frame_ver: 0,
70 seqnum: 1,
71 dest_panid: Some(0xFFFF),
72 dest_addr: Dot15d4Addr::Short(0xFFFF),
73 src_panid: None,
74 src_addr: Dot15d4Addr::None,
75 }
76 }
77
78 #[must_use]
80 pub fn beacon() -> Self {
81 Self {
82 frame_type: types::frame_type::BEACON,
83 security: false,
84 pending: false,
85 ackreq: false,
86 panid_compress: false,
87 frame_ver: 0,
88 seqnum: 0,
89 dest_panid: None,
90 dest_addr: Dot15d4Addr::None,
91 src_panid: None,
92 src_addr: Dot15d4Addr::None,
93 }
94 }
95
96 #[must_use]
98 pub fn data() -> Self {
99 Self::new()
100 }
101
102 #[must_use]
104 pub fn ack() -> Self {
105 Self {
106 frame_type: types::frame_type::ACK,
107 security: false,
108 pending: false,
109 ackreq: false,
110 panid_compress: false,
111 frame_ver: 0,
112 seqnum: 0,
113 dest_panid: None,
114 dest_addr: Dot15d4Addr::None,
115 src_panid: None,
116 src_addr: Dot15d4Addr::None,
117 }
118 }
119
120 #[must_use]
122 pub fn command() -> Self {
123 Self {
124 frame_type: types::frame_type::MAC_CMD,
125 security: false,
126 pending: false,
127 ackreq: false,
128 panid_compress: false,
129 frame_ver: 0,
130 seqnum: 0,
131 dest_panid: Some(0xFFFF),
132 dest_addr: Dot15d4Addr::Short(0x0000),
133 src_panid: None,
134 src_addr: Dot15d4Addr::None,
135 }
136 }
137
138 #[must_use]
142 pub fn frame_type(mut self, ft: u8) -> Self {
143 self.frame_type = ft;
144 self
145 }
146
147 #[must_use]
149 pub fn security(mut self, val: bool) -> Self {
150 self.security = val;
151 self
152 }
153
154 #[must_use]
156 pub fn pending(mut self, val: bool) -> Self {
157 self.pending = val;
158 self
159 }
160
161 #[must_use]
163 pub fn ackreq(mut self, val: bool) -> Self {
164 self.ackreq = val;
165 self
166 }
167
168 #[must_use]
170 pub fn panid_compress(mut self, val: bool) -> Self {
171 self.panid_compress = val;
172 self
173 }
174
175 #[must_use]
177 pub fn frame_ver(mut self, ver: u8) -> Self {
178 self.frame_ver = ver;
179 self
180 }
181
182 #[must_use]
184 pub fn seqnum(mut self, seq: u8) -> Self {
185 self.seqnum = seq;
186 self
187 }
188
189 #[must_use]
191 pub fn dest_panid(mut self, panid: u16) -> Self {
192 self.dest_panid = Some(panid);
193 self
194 }
195
196 #[must_use]
198 pub fn dest_addr_short(mut self, addr: u16) -> Self {
199 self.dest_addr = Dot15d4Addr::Short(addr);
200 if self.dest_panid.is_none() {
201 self.dest_panid = Some(0xFFFF);
202 }
203 self
204 }
205
206 #[must_use]
208 pub fn dest_addr_long(mut self, addr: u64) -> Self {
209 self.dest_addr = Dot15d4Addr::Long(addr);
210 if self.dest_panid.is_none() {
211 self.dest_panid = Some(0xFFFF);
212 }
213 self
214 }
215
216 #[must_use]
218 pub fn no_dest_addr(mut self) -> Self {
219 self.dest_addr = Dot15d4Addr::None;
220 self.dest_panid = None;
221 self
222 }
223
224 #[must_use]
226 pub fn src_panid(mut self, panid: u16) -> Self {
227 self.src_panid = Some(panid);
228 self
229 }
230
231 #[must_use]
233 pub fn src_addr_short(mut self, addr: u16) -> Self {
234 self.src_addr = Dot15d4Addr::Short(addr);
235 self
236 }
237
238 #[must_use]
240 pub fn src_addr_long(mut self, addr: u64) -> Self {
241 self.src_addr = Dot15d4Addr::Long(addr);
242 self
243 }
244
245 #[must_use]
247 pub fn no_src_addr(mut self) -> Self {
248 self.src_addr = Dot15d4Addr::None;
249 self.src_panid = None;
250 self
251 }
252
253 fn dest_addr_mode(&self) -> u8 {
255 self.dest_addr.mode()
256 }
257
258 fn src_addr_mode(&self) -> u8 {
260 self.src_addr.mode()
261 }
262
263 #[must_use]
265 pub fn build(&self) -> Vec<u8> {
266 let dest_mode = self.dest_addr_mode();
267 let src_mode = self.src_addr_mode();
268
269 let fcf = build_fcf(
270 self.frame_type,
271 self.security,
272 self.pending,
273 self.ackreq,
274 self.panid_compress,
275 dest_mode,
276 self.frame_ver,
277 src_mode,
278 );
279
280 let header_len = compute_header_len(fcf);
281 let mut out = Vec::with_capacity(header_len);
282
283 out.extend_from_slice(&fcf.to_le_bytes());
285
286 out.push(self.seqnum);
288
289 if dest_mode != types::addr_mode::NONE {
291 let panid = self.dest_panid.unwrap_or(0xFFFF);
292 out.extend_from_slice(&panid.to_le_bytes());
293
294 match &self.dest_addr {
295 Dot15d4Addr::Short(addr) => {
296 out.extend_from_slice(&addr.to_le_bytes());
297 },
298 Dot15d4Addr::Long(addr) => {
299 out.extend_from_slice(&addr.to_le_bytes());
300 },
301 Dot15d4Addr::None => {}, }
303 }
304
305 if src_mode != types::addr_mode::NONE {
307 if !self.panid_compress {
308 let panid = self.src_panid.unwrap_or(0x0000);
309 out.extend_from_slice(&panid.to_le_bytes());
310 }
311
312 match &self.src_addr {
313 Dot15d4Addr::Short(addr) => {
314 out.extend_from_slice(&addr.to_le_bytes());
315 },
316 Dot15d4Addr::Long(addr) => {
317 out.extend_from_slice(&addr.to_le_bytes());
318 },
319 Dot15d4Addr::None => {}, }
321 }
322
323 out
324 }
325
326 #[must_use]
328 pub fn header_size(&self) -> usize {
329 let fcf = build_fcf(
330 self.frame_type,
331 self.security,
332 self.pending,
333 self.ackreq,
334 self.panid_compress,
335 self.dest_addr_mode(),
336 self.frame_ver,
337 self.src_addr_mode(),
338 );
339 compute_header_len(fcf)
340 }
341}
342
343impl Default for Dot15d4Builder {
344 fn default() -> Self {
345 Self::new()
346 }
347}
348
349#[derive(Debug, Clone)]
353pub struct Dot15d4FcsBuilder {
354 pub inner: Dot15d4Builder,
356}
357
358impl Dot15d4FcsBuilder {
359 #[must_use]
361 pub fn new() -> Self {
362 Self {
363 inner: Dot15d4Builder::new(),
364 }
365 }
366
367 #[must_use]
369 pub fn from_builder(builder: Dot15d4Builder) -> Self {
370 Self { inner: builder }
371 }
372
373 #[must_use]
375 pub fn beacon() -> Self {
376 Self {
377 inner: Dot15d4Builder::beacon(),
378 }
379 }
380
381 #[must_use]
383 pub fn data() -> Self {
384 Self {
385 inner: Dot15d4Builder::data(),
386 }
387 }
388
389 #[must_use]
391 pub fn ack() -> Self {
392 Self {
393 inner: Dot15d4Builder::ack(),
394 }
395 }
396
397 #[must_use]
399 pub fn command() -> Self {
400 Self {
401 inner: Dot15d4Builder::command(),
402 }
403 }
404
405 #[must_use]
408 pub fn frame_type(mut self, ft: u8) -> Self {
409 self.inner = self.inner.frame_type(ft);
410 self
411 }
412
413 #[must_use]
414 pub fn security(mut self, val: bool) -> Self {
415 self.inner = self.inner.security(val);
416 self
417 }
418
419 #[must_use]
420 pub fn pending(mut self, val: bool) -> Self {
421 self.inner = self.inner.pending(val);
422 self
423 }
424
425 #[must_use]
426 pub fn ackreq(mut self, val: bool) -> Self {
427 self.inner = self.inner.ackreq(val);
428 self
429 }
430
431 #[must_use]
432 pub fn panid_compress(mut self, val: bool) -> Self {
433 self.inner = self.inner.panid_compress(val);
434 self
435 }
436
437 #[must_use]
438 pub fn frame_ver(mut self, ver: u8) -> Self {
439 self.inner = self.inner.frame_ver(ver);
440 self
441 }
442
443 #[must_use]
444 pub fn seqnum(mut self, seq: u8) -> Self {
445 self.inner = self.inner.seqnum(seq);
446 self
447 }
448
449 #[must_use]
450 pub fn dest_panid(mut self, panid: u16) -> Self {
451 self.inner = self.inner.dest_panid(panid);
452 self
453 }
454
455 #[must_use]
456 pub fn dest_addr_short(mut self, addr: u16) -> Self {
457 self.inner = self.inner.dest_addr_short(addr);
458 self
459 }
460
461 #[must_use]
462 pub fn dest_addr_long(mut self, addr: u64) -> Self {
463 self.inner = self.inner.dest_addr_long(addr);
464 self
465 }
466
467 #[must_use]
468 pub fn no_dest_addr(mut self) -> Self {
469 self.inner = self.inner.no_dest_addr();
470 self
471 }
472
473 #[must_use]
474 pub fn src_panid(mut self, panid: u16) -> Self {
475 self.inner = self.inner.src_panid(panid);
476 self
477 }
478
479 #[must_use]
480 pub fn src_addr_short(mut self, addr: u16) -> Self {
481 self.inner = self.inner.src_addr_short(addr);
482 self
483 }
484
485 #[must_use]
486 pub fn src_addr_long(mut self, addr: u64) -> Self {
487 self.inner = self.inner.src_addr_long(addr);
488 self
489 }
490
491 #[must_use]
492 pub fn no_src_addr(mut self) -> Self {
493 self.inner = self.inner.no_src_addr();
494 self
495 }
496
497 #[must_use]
499 pub fn build(&self) -> Vec<u8> {
500 let mut frame = self.inner.build();
501 let fcs = crc::compute_fcs(&frame);
502 frame.extend_from_slice(&fcs);
503 frame
504 }
505
506 #[must_use]
508 pub fn total_size(&self) -> usize {
509 self.inner.header_size() + FCS_LEN
510 }
511}
512
513impl Default for Dot15d4FcsBuilder {
514 fn default() -> Self {
515 Self::new()
516 }
517}
518
519#[cfg(test)]
520mod tests {
521 use super::*;
522 use crate::layer::dot15d4::{Dot15d4FcsLayer, Dot15d4Layer};
523
524 #[test]
525 fn test_builder_default() {
526 let b = Dot15d4Builder::new();
527 assert_eq!(b.frame_type, types::frame_type::DATA);
528 assert!(!b.security);
529 assert!(!b.ackreq);
530 assert_eq!(b.seqnum, 1);
531 }
532
533 #[test]
534 fn test_builder_beacon() {
535 let b = Dot15d4Builder::beacon();
536 assert_eq!(b.frame_type, types::frame_type::BEACON);
537 }
538
539 #[test]
540 fn test_builder_ack() {
541 let b = Dot15d4Builder::ack();
542 assert_eq!(b.frame_type, types::frame_type::ACK);
543 let frame = b.build();
544 assert_eq!(frame.len(), 3); }
546
547 #[test]
548 fn test_builder_fluent_api() {
549 let b = Dot15d4Builder::new()
550 .frame_type(types::frame_type::DATA)
551 .ackreq(true)
552 .panid_compress(true)
553 .seqnum(42)
554 .dest_panid(0x1234)
555 .dest_addr_short(0xFFFF)
556 .src_addr_short(0x0001);
557
558 assert_eq!(b.frame_type, types::frame_type::DATA);
559 assert!(b.ackreq);
560 assert!(b.panid_compress);
561 assert_eq!(b.seqnum, 42);
562 }
563
564 #[test]
565 fn test_build_data_frame_short() {
566 let frame = Dot15d4Builder::new()
567 .frame_type(types::frame_type::DATA)
568 .ackreq(true)
569 .panid_compress(true)
570 .seqnum(5)
571 .dest_panid(0x1234)
572 .dest_addr_short(0xFFFF)
573 .src_addr_short(0x0001)
574 .build();
575
576 let layer = Dot15d4Layer::new(0, frame.len());
578 assert_eq!(layer.fcf_frametype(&frame).unwrap(), 1);
579 assert!(layer.fcf_ackreq(&frame).unwrap());
580 assert!(layer.fcf_panidcompress(&frame).unwrap());
581 assert_eq!(layer.fcf_destaddrmode(&frame).unwrap(), 2);
582 assert_eq!(layer.fcf_srcaddrmode(&frame).unwrap(), 2);
583 assert_eq!(layer.seqnum(&frame).unwrap(), 5);
584 assert_eq!(layer.dest_panid(&frame).unwrap(), Some(0x1234));
585 assert_eq!(layer.dest_addr_short(&frame).unwrap(), Some(0xFFFF));
586 assert_eq!(layer.src_panid(&frame).unwrap(), None); assert_eq!(layer.src_addr_short(&frame).unwrap(), Some(0x0001));
588
589 assert_eq!(frame.len(), 9);
591 }
592
593 #[test]
594 fn test_build_data_frame_long() {
595 let frame = Dot15d4Builder::new()
596 .frame_type(types::frame_type::DATA)
597 .seqnum(10)
598 .dest_panid(0x1234)
599 .dest_addr_long(0x0102030405060708)
600 .src_panid(0xABCD)
601 .src_addr_long(0x1112131415161718)
602 .build();
603
604 let layer = Dot15d4Layer::new(0, frame.len());
605 assert_eq!(layer.fcf_destaddrmode(&frame).unwrap(), 3);
606 assert_eq!(layer.fcf_srcaddrmode(&frame).unwrap(), 3);
607 assert_eq!(layer.dest_panid(&frame).unwrap(), Some(0x1234));
608 assert_eq!(
609 layer.dest_addr_long(&frame).unwrap(),
610 Some(0x0102030405060708)
611 );
612 assert_eq!(layer.src_panid(&frame).unwrap(), Some(0xABCD));
613 assert_eq!(
614 layer.src_addr_long(&frame).unwrap(),
615 Some(0x1112131415161718)
616 );
617
618 assert_eq!(frame.len(), 23);
620 }
621
622 #[test]
623 fn test_build_ack_frame() {
624 let frame = Dot15d4Builder::ack().seqnum(42).build();
625
626 let layer = Dot15d4Layer::new(0, frame.len());
627 assert_eq!(layer.fcf_frametype(&frame).unwrap(), 2);
628 assert_eq!(layer.fcf_destaddrmode(&frame).unwrap(), 0);
629 assert_eq!(layer.fcf_srcaddrmode(&frame).unwrap(), 0);
630 assert_eq!(layer.seqnum(&frame).unwrap(), 42);
631 assert_eq!(frame.len(), 3);
632 }
633
634 #[test]
635 fn test_fcs_builder() {
636 let frame = Dot15d4FcsBuilder::new()
637 .frame_type(types::frame_type::DATA)
638 .ackreq(true)
639 .panid_compress(true)
640 .seqnum(5)
641 .dest_panid(0x1234)
642 .dest_addr_short(0xFFFF)
643 .src_addr_short(0x0001)
644 .build();
645
646 assert_eq!(frame.len(), 11); let layer = Dot15d4FcsLayer::new(0, frame.len());
651 assert!(layer.verify_fcs(&frame).unwrap());
652
653 assert_eq!(layer.fcf_frametype(&frame).unwrap(), 1);
655 assert_eq!(layer.seqnum(&frame).unwrap(), 5);
656 }
657
658 #[test]
659 fn test_fcs_builder_from_inner() {
660 let inner = Dot15d4Builder::ack().seqnum(99);
661 let fcs_builder = Dot15d4FcsBuilder::from_builder(inner);
662 let frame = fcs_builder.build();
663
664 assert_eq!(frame.len(), 5); let layer = Dot15d4FcsLayer::new(0, frame.len());
667 assert!(layer.verify_fcs(&frame).unwrap());
668 assert_eq!(layer.seqnum(&frame).unwrap(), 99);
669 }
670
671 #[test]
672 fn test_header_size() {
673 let b = Dot15d4Builder::ack();
674 assert_eq!(b.header_size(), 3);
675
676 let b = Dot15d4Builder::new()
677 .dest_addr_short(0xFFFF)
678 .panid_compress(true)
679 .src_addr_short(0x0001);
680 assert_eq!(b.header_size(), 9);
681
682 let b = Dot15d4Builder::new()
683 .dest_addr_long(0x0102030405060708)
684 .src_addr_long(0x1112131415161718);
685 assert_eq!(b.header_size(), 23);
686 }
687
688 #[test]
689 fn test_fcs_total_size() {
690 let b = Dot15d4FcsBuilder::ack();
691 assert_eq!(b.total_size(), 5);
692 }
693
694 #[test]
695 fn test_builder_no_dest_addr() {
696 let b = Dot15d4Builder::new().no_dest_addr().no_src_addr();
697 let frame = b.build();
698 assert_eq!(frame.len(), 3);
699 }
700
701 #[test]
702 fn test_build_parse_roundtrip_short() {
703 let original = Dot15d4Builder::new()
704 .frame_type(types::frame_type::DATA)
705 .ackreq(true)
706 .panid_compress(true)
707 .seqnum(77)
708 .dest_panid(0xBEEF)
709 .dest_addr_short(0x1234)
710 .src_addr_short(0x5678);
711
712 let frame = original.build();
713 let layer = Dot15d4Layer::new(0, frame.len());
714
715 assert_eq!(
716 layer.fcf_frametype(&frame).unwrap(),
717 types::frame_type::DATA
718 );
719 assert!(layer.fcf_ackreq(&frame).unwrap());
720 assert!(layer.fcf_panidcompress(&frame).unwrap());
721 assert_eq!(layer.seqnum(&frame).unwrap(), 77);
722 assert_eq!(layer.dest_panid(&frame).unwrap(), Some(0xBEEF));
723 assert_eq!(layer.dest_addr_short(&frame).unwrap(), Some(0x1234));
724 assert_eq!(layer.src_addr_short(&frame).unwrap(), Some(0x5678));
725 }
726
727 #[test]
728 fn test_fcs_builder_beacon() {
729 let frame = Dot15d4FcsBuilder::beacon().seqnum(0).build();
730 let layer = Dot15d4FcsLayer::new(0, frame.len());
731 assert_eq!(
732 layer.fcf_frametype(&frame).unwrap(),
733 types::frame_type::BEACON
734 );
735 assert!(layer.verify_fcs(&frame).unwrap());
736 }
737
738 #[test]
739 fn test_fcs_builder_command() {
740 let frame = Dot15d4FcsBuilder::command()
741 .seqnum(10)
742 .dest_panid(0x1234)
743 .dest_addr_short(0x0001)
744 .build();
745 let layer = Dot15d4FcsLayer::new(0, frame.len());
746 assert_eq!(
747 layer.fcf_frametype(&frame).unwrap(),
748 types::frame_type::MAC_CMD
749 );
750 assert!(layer.verify_fcs(&frame).unwrap());
751 }
752}