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 pub fn new() -> Self {
62 Self {
63 frame_type: types::frame_type::DATA,
64 security: false,
65 pending: false,
66 ackreq: false,
67 panid_compress: false,
68 frame_ver: 0,
69 seqnum: 1,
70 dest_panid: Some(0xFFFF),
71 dest_addr: Dot15d4Addr::Short(0xFFFF),
72 src_panid: None,
73 src_addr: Dot15d4Addr::None,
74 }
75 }
76
77 pub fn beacon() -> Self {
79 Self {
80 frame_type: types::frame_type::BEACON,
81 security: false,
82 pending: false,
83 ackreq: false,
84 panid_compress: false,
85 frame_ver: 0,
86 seqnum: 0,
87 dest_panid: None,
88 dest_addr: Dot15d4Addr::None,
89 src_panid: None,
90 src_addr: Dot15d4Addr::None,
91 }
92 }
93
94 pub fn data() -> Self {
96 Self::new()
97 }
98
99 pub fn ack() -> Self {
101 Self {
102 frame_type: types::frame_type::ACK,
103 security: false,
104 pending: false,
105 ackreq: false,
106 panid_compress: false,
107 frame_ver: 0,
108 seqnum: 0,
109 dest_panid: None,
110 dest_addr: Dot15d4Addr::None,
111 src_panid: None,
112 src_addr: Dot15d4Addr::None,
113 }
114 }
115
116 pub fn command() -> Self {
118 Self {
119 frame_type: types::frame_type::MAC_CMD,
120 security: false,
121 pending: false,
122 ackreq: false,
123 panid_compress: false,
124 frame_ver: 0,
125 seqnum: 0,
126 dest_panid: Some(0xFFFF),
127 dest_addr: Dot15d4Addr::Short(0x0000),
128 src_panid: None,
129 src_addr: Dot15d4Addr::None,
130 }
131 }
132
133 pub fn frame_type(mut self, ft: u8) -> Self {
137 self.frame_type = ft;
138 self
139 }
140
141 pub fn security(mut self, val: bool) -> Self {
143 self.security = val;
144 self
145 }
146
147 pub fn pending(mut self, val: bool) -> Self {
149 self.pending = val;
150 self
151 }
152
153 pub fn ackreq(mut self, val: bool) -> Self {
155 self.ackreq = val;
156 self
157 }
158
159 pub fn panid_compress(mut self, val: bool) -> Self {
161 self.panid_compress = val;
162 self
163 }
164
165 pub fn frame_ver(mut self, ver: u8) -> Self {
167 self.frame_ver = ver;
168 self
169 }
170
171 pub fn seqnum(mut self, seq: u8) -> Self {
173 self.seqnum = seq;
174 self
175 }
176
177 pub fn dest_panid(mut self, panid: u16) -> Self {
179 self.dest_panid = Some(panid);
180 self
181 }
182
183 pub fn dest_addr_short(mut self, addr: u16) -> Self {
185 self.dest_addr = Dot15d4Addr::Short(addr);
186 if self.dest_panid.is_none() {
187 self.dest_panid = Some(0xFFFF);
188 }
189 self
190 }
191
192 pub fn dest_addr_long(mut self, addr: u64) -> Self {
194 self.dest_addr = Dot15d4Addr::Long(addr);
195 if self.dest_panid.is_none() {
196 self.dest_panid = Some(0xFFFF);
197 }
198 self
199 }
200
201 pub fn no_dest_addr(mut self) -> Self {
203 self.dest_addr = Dot15d4Addr::None;
204 self.dest_panid = None;
205 self
206 }
207
208 pub fn src_panid(mut self, panid: u16) -> Self {
210 self.src_panid = Some(panid);
211 self
212 }
213
214 pub fn src_addr_short(mut self, addr: u16) -> Self {
216 self.src_addr = Dot15d4Addr::Short(addr);
217 self
218 }
219
220 pub fn src_addr_long(mut self, addr: u64) -> Self {
222 self.src_addr = Dot15d4Addr::Long(addr);
223 self
224 }
225
226 pub fn no_src_addr(mut self) -> Self {
228 self.src_addr = Dot15d4Addr::None;
229 self.src_panid = None;
230 self
231 }
232
233 fn dest_addr_mode(&self) -> u8 {
235 self.dest_addr.mode()
236 }
237
238 fn src_addr_mode(&self) -> u8 {
240 self.src_addr.mode()
241 }
242
243 pub fn build(&self) -> Vec<u8> {
245 let dest_mode = self.dest_addr_mode();
246 let src_mode = self.src_addr_mode();
247
248 let fcf = build_fcf(
249 self.frame_type,
250 self.security,
251 self.pending,
252 self.ackreq,
253 self.panid_compress,
254 dest_mode,
255 self.frame_ver,
256 src_mode,
257 );
258
259 let header_len = compute_header_len(fcf);
260 let mut out = Vec::with_capacity(header_len);
261
262 out.extend_from_slice(&fcf.to_le_bytes());
264
265 out.push(self.seqnum);
267
268 if dest_mode != types::addr_mode::NONE {
270 let panid = self.dest_panid.unwrap_or(0xFFFF);
271 out.extend_from_slice(&panid.to_le_bytes());
272
273 match &self.dest_addr {
274 Dot15d4Addr::Short(addr) => {
275 out.extend_from_slice(&addr.to_le_bytes());
276 }
277 Dot15d4Addr::Long(addr) => {
278 out.extend_from_slice(&addr.to_le_bytes());
279 }
280 Dot15d4Addr::None => {} }
282 }
283
284 if src_mode != types::addr_mode::NONE {
286 if !self.panid_compress {
287 let panid = self.src_panid.unwrap_or(0x0000);
288 out.extend_from_slice(&panid.to_le_bytes());
289 }
290
291 match &self.src_addr {
292 Dot15d4Addr::Short(addr) => {
293 out.extend_from_slice(&addr.to_le_bytes());
294 }
295 Dot15d4Addr::Long(addr) => {
296 out.extend_from_slice(&addr.to_le_bytes());
297 }
298 Dot15d4Addr::None => {} }
300 }
301
302 out
303 }
304
305 pub fn header_size(&self) -> usize {
307 let fcf = build_fcf(
308 self.frame_type,
309 self.security,
310 self.pending,
311 self.ackreq,
312 self.panid_compress,
313 self.dest_addr_mode(),
314 self.frame_ver,
315 self.src_addr_mode(),
316 );
317 compute_header_len(fcf)
318 }
319}
320
321impl Default for Dot15d4Builder {
322 fn default() -> Self {
323 Self::new()
324 }
325}
326
327#[derive(Debug, Clone)]
331pub struct Dot15d4FcsBuilder {
332 pub inner: Dot15d4Builder,
334}
335
336impl Dot15d4FcsBuilder {
337 pub fn new() -> Self {
339 Self {
340 inner: Dot15d4Builder::new(),
341 }
342 }
343
344 pub fn from_builder(builder: Dot15d4Builder) -> Self {
346 Self { inner: builder }
347 }
348
349 pub fn beacon() -> Self {
351 Self {
352 inner: Dot15d4Builder::beacon(),
353 }
354 }
355
356 pub fn data() -> Self {
358 Self {
359 inner: Dot15d4Builder::data(),
360 }
361 }
362
363 pub fn ack() -> Self {
365 Self {
366 inner: Dot15d4Builder::ack(),
367 }
368 }
369
370 pub fn command() -> Self {
372 Self {
373 inner: Dot15d4Builder::command(),
374 }
375 }
376
377 pub fn frame_type(mut self, ft: u8) -> Self {
380 self.inner = self.inner.frame_type(ft);
381 self
382 }
383
384 pub fn security(mut self, val: bool) -> Self {
385 self.inner = self.inner.security(val);
386 self
387 }
388
389 pub fn pending(mut self, val: bool) -> Self {
390 self.inner = self.inner.pending(val);
391 self
392 }
393
394 pub fn ackreq(mut self, val: bool) -> Self {
395 self.inner = self.inner.ackreq(val);
396 self
397 }
398
399 pub fn panid_compress(mut self, val: bool) -> Self {
400 self.inner = self.inner.panid_compress(val);
401 self
402 }
403
404 pub fn frame_ver(mut self, ver: u8) -> Self {
405 self.inner = self.inner.frame_ver(ver);
406 self
407 }
408
409 pub fn seqnum(mut self, seq: u8) -> Self {
410 self.inner = self.inner.seqnum(seq);
411 self
412 }
413
414 pub fn dest_panid(mut self, panid: u16) -> Self {
415 self.inner = self.inner.dest_panid(panid);
416 self
417 }
418
419 pub fn dest_addr_short(mut self, addr: u16) -> Self {
420 self.inner = self.inner.dest_addr_short(addr);
421 self
422 }
423
424 pub fn dest_addr_long(mut self, addr: u64) -> Self {
425 self.inner = self.inner.dest_addr_long(addr);
426 self
427 }
428
429 pub fn no_dest_addr(mut self) -> Self {
430 self.inner = self.inner.no_dest_addr();
431 self
432 }
433
434 pub fn src_panid(mut self, panid: u16) -> Self {
435 self.inner = self.inner.src_panid(panid);
436 self
437 }
438
439 pub fn src_addr_short(mut self, addr: u16) -> Self {
440 self.inner = self.inner.src_addr_short(addr);
441 self
442 }
443
444 pub fn src_addr_long(mut self, addr: u64) -> Self {
445 self.inner = self.inner.src_addr_long(addr);
446 self
447 }
448
449 pub fn no_src_addr(mut self) -> Self {
450 self.inner = self.inner.no_src_addr();
451 self
452 }
453
454 pub fn build(&self) -> Vec<u8> {
456 let mut frame = self.inner.build();
457 let fcs = crc::compute_fcs(&frame);
458 frame.extend_from_slice(&fcs);
459 frame
460 }
461
462 pub fn total_size(&self) -> usize {
464 self.inner.header_size() + FCS_LEN
465 }
466}
467
468impl Default for Dot15d4FcsBuilder {
469 fn default() -> Self {
470 Self::new()
471 }
472}
473
474#[cfg(test)]
475mod tests {
476 use super::*;
477 use crate::layer::dot15d4::{Dot15d4FcsLayer, Dot15d4Layer};
478
479 #[test]
480 fn test_builder_default() {
481 let b = Dot15d4Builder::new();
482 assert_eq!(b.frame_type, types::frame_type::DATA);
483 assert!(!b.security);
484 assert!(!b.ackreq);
485 assert_eq!(b.seqnum, 1);
486 }
487
488 #[test]
489 fn test_builder_beacon() {
490 let b = Dot15d4Builder::beacon();
491 assert_eq!(b.frame_type, types::frame_type::BEACON);
492 }
493
494 #[test]
495 fn test_builder_ack() {
496 let b = Dot15d4Builder::ack();
497 assert_eq!(b.frame_type, types::frame_type::ACK);
498 let frame = b.build();
499 assert_eq!(frame.len(), 3); }
501
502 #[test]
503 fn test_builder_fluent_api() {
504 let b = Dot15d4Builder::new()
505 .frame_type(types::frame_type::DATA)
506 .ackreq(true)
507 .panid_compress(true)
508 .seqnum(42)
509 .dest_panid(0x1234)
510 .dest_addr_short(0xFFFF)
511 .src_addr_short(0x0001);
512
513 assert_eq!(b.frame_type, types::frame_type::DATA);
514 assert!(b.ackreq);
515 assert!(b.panid_compress);
516 assert_eq!(b.seqnum, 42);
517 }
518
519 #[test]
520 fn test_build_data_frame_short() {
521 let frame = Dot15d4Builder::new()
522 .frame_type(types::frame_type::DATA)
523 .ackreq(true)
524 .panid_compress(true)
525 .seqnum(5)
526 .dest_panid(0x1234)
527 .dest_addr_short(0xFFFF)
528 .src_addr_short(0x0001)
529 .build();
530
531 let layer = Dot15d4Layer::new(0, frame.len());
533 assert_eq!(layer.fcf_frametype(&frame).unwrap(), 1);
534 assert!(layer.fcf_ackreq(&frame).unwrap());
535 assert!(layer.fcf_panidcompress(&frame).unwrap());
536 assert_eq!(layer.fcf_destaddrmode(&frame).unwrap(), 2);
537 assert_eq!(layer.fcf_srcaddrmode(&frame).unwrap(), 2);
538 assert_eq!(layer.seqnum(&frame).unwrap(), 5);
539 assert_eq!(layer.dest_panid(&frame).unwrap(), Some(0x1234));
540 assert_eq!(layer.dest_addr_short(&frame).unwrap(), Some(0xFFFF));
541 assert_eq!(layer.src_panid(&frame).unwrap(), None); assert_eq!(layer.src_addr_short(&frame).unwrap(), Some(0x0001));
543
544 assert_eq!(frame.len(), 9);
546 }
547
548 #[test]
549 fn test_build_data_frame_long() {
550 let frame = Dot15d4Builder::new()
551 .frame_type(types::frame_type::DATA)
552 .seqnum(10)
553 .dest_panid(0x1234)
554 .dest_addr_long(0x0102030405060708)
555 .src_panid(0xABCD)
556 .src_addr_long(0x1112131415161718)
557 .build();
558
559 let layer = Dot15d4Layer::new(0, frame.len());
560 assert_eq!(layer.fcf_destaddrmode(&frame).unwrap(), 3);
561 assert_eq!(layer.fcf_srcaddrmode(&frame).unwrap(), 3);
562 assert_eq!(layer.dest_panid(&frame).unwrap(), Some(0x1234));
563 assert_eq!(
564 layer.dest_addr_long(&frame).unwrap(),
565 Some(0x0102030405060708)
566 );
567 assert_eq!(layer.src_panid(&frame).unwrap(), Some(0xABCD));
568 assert_eq!(
569 layer.src_addr_long(&frame).unwrap(),
570 Some(0x1112131415161718)
571 );
572
573 assert_eq!(frame.len(), 23);
575 }
576
577 #[test]
578 fn test_build_ack_frame() {
579 let frame = Dot15d4Builder::ack().seqnum(42).build();
580
581 let layer = Dot15d4Layer::new(0, frame.len());
582 assert_eq!(layer.fcf_frametype(&frame).unwrap(), 2);
583 assert_eq!(layer.fcf_destaddrmode(&frame).unwrap(), 0);
584 assert_eq!(layer.fcf_srcaddrmode(&frame).unwrap(), 0);
585 assert_eq!(layer.seqnum(&frame).unwrap(), 42);
586 assert_eq!(frame.len(), 3);
587 }
588
589 #[test]
590 fn test_fcs_builder() {
591 let frame = Dot15d4FcsBuilder::new()
592 .frame_type(types::frame_type::DATA)
593 .ackreq(true)
594 .panid_compress(true)
595 .seqnum(5)
596 .dest_panid(0x1234)
597 .dest_addr_short(0xFFFF)
598 .src_addr_short(0x0001)
599 .build();
600
601 assert_eq!(frame.len(), 11); let layer = Dot15d4FcsLayer::new(0, frame.len());
606 assert!(layer.verify_fcs(&frame).unwrap());
607
608 assert_eq!(layer.fcf_frametype(&frame).unwrap(), 1);
610 assert_eq!(layer.seqnum(&frame).unwrap(), 5);
611 }
612
613 #[test]
614 fn test_fcs_builder_from_inner() {
615 let inner = Dot15d4Builder::ack().seqnum(99);
616 let fcs_builder = Dot15d4FcsBuilder::from_builder(inner);
617 let frame = fcs_builder.build();
618
619 assert_eq!(frame.len(), 5); let layer = Dot15d4FcsLayer::new(0, frame.len());
622 assert!(layer.verify_fcs(&frame).unwrap());
623 assert_eq!(layer.seqnum(&frame).unwrap(), 99);
624 }
625
626 #[test]
627 fn test_header_size() {
628 let b = Dot15d4Builder::ack();
629 assert_eq!(b.header_size(), 3);
630
631 let b = Dot15d4Builder::new()
632 .dest_addr_short(0xFFFF)
633 .panid_compress(true)
634 .src_addr_short(0x0001);
635 assert_eq!(b.header_size(), 9);
636
637 let b = Dot15d4Builder::new()
638 .dest_addr_long(0x0102030405060708)
639 .src_addr_long(0x1112131415161718);
640 assert_eq!(b.header_size(), 23);
641 }
642
643 #[test]
644 fn test_fcs_total_size() {
645 let b = Dot15d4FcsBuilder::ack();
646 assert_eq!(b.total_size(), 5);
647 }
648
649 #[test]
650 fn test_builder_no_dest_addr() {
651 let b = Dot15d4Builder::new().no_dest_addr().no_src_addr();
652 let frame = b.build();
653 assert_eq!(frame.len(), 3);
654 }
655
656 #[test]
657 fn test_build_parse_roundtrip_short() {
658 let original = Dot15d4Builder::new()
659 .frame_type(types::frame_type::DATA)
660 .ackreq(true)
661 .panid_compress(true)
662 .seqnum(77)
663 .dest_panid(0xBEEF)
664 .dest_addr_short(0x1234)
665 .src_addr_short(0x5678);
666
667 let frame = original.build();
668 let layer = Dot15d4Layer::new(0, frame.len());
669
670 assert_eq!(
671 layer.fcf_frametype(&frame).unwrap(),
672 types::frame_type::DATA
673 );
674 assert!(layer.fcf_ackreq(&frame).unwrap());
675 assert!(layer.fcf_panidcompress(&frame).unwrap());
676 assert_eq!(layer.seqnum(&frame).unwrap(), 77);
677 assert_eq!(layer.dest_panid(&frame).unwrap(), Some(0xBEEF));
678 assert_eq!(layer.dest_addr_short(&frame).unwrap(), Some(0x1234));
679 assert_eq!(layer.src_addr_short(&frame).unwrap(), Some(0x5678));
680 }
681
682 #[test]
683 fn test_fcs_builder_beacon() {
684 let frame = Dot15d4FcsBuilder::beacon().seqnum(0).build();
685 let layer = Dot15d4FcsLayer::new(0, frame.len());
686 assert_eq!(
687 layer.fcf_frametype(&frame).unwrap(),
688 types::frame_type::BEACON
689 );
690 assert!(layer.verify_fcs(&frame).unwrap());
691 }
692
693 #[test]
694 fn test_fcs_builder_command() {
695 let frame = Dot15d4FcsBuilder::command()
696 .seqnum(10)
697 .dest_panid(0x1234)
698 .dest_addr_short(0x0001)
699 .build();
700 let layer = Dot15d4FcsLayer::new(0, frame.len());
701 assert_eq!(
702 layer.fcf_frametype(&frame).unwrap(),
703 types::frame_type::MAC_CMD
704 );
705 assert!(layer.verify_fcs(&frame).unwrap());
706 }
707}