1use crate::net::stream::SResult;
10use crate::net::stream::{decode_bytes_be, decode_u16, decode_u32, decode_u8};
11use crate::net::stream::{encode_bytes, encode_bytes_be, encode_u16, encode_u32, encode_u8};
12
13#[derive(Copy, Clone, Eq, PartialEq, Debug)]
14pub enum MacAddress {
15 Short(u16),
16 Long([u8; 8]),
17}
18
19impl MacAddress {
20 pub fn encode(&self, buf: &mut [u8]) -> SResult {
21 match *self {
22 MacAddress::Short(ref short_addr) => encode_u16(buf, short_addr.to_be()),
23 MacAddress::Long(ref long_addr) => encode_bytes_be(buf, long_addr),
24 }
25 }
26
27 pub fn decode(buf: &[u8], mode: AddressMode) -> SResult<Option<MacAddress>> {
28 match mode {
29 AddressMode::NotPresent => stream_done!(0, None),
30 AddressMode::Short => {
31 let (off, short_addr_be) = dec_try!(buf; decode_u16);
32 let short_addr = u16::from_be(short_addr_be);
33 stream_done!(off, Some(MacAddress::Short(short_addr)));
34 }
35 AddressMode::Long => {
36 let mut long_addr = [0u8; 8];
37 let off = dec_consume!(buf; decode_bytes_be, &mut long_addr);
38 stream_done!(off, Some(MacAddress::Long(long_addr)));
39 }
40 }
41 }
42}
43
44pub type PanID = u16;
45
46mod frame_control {
47 pub const FRAME_TYPE_MASK: u16 = 0b111;
48 pub const SECURITY_ENABLED: u16 = 1 << 3;
49 pub const FRAME_PENDING: u16 = 1 << 4;
50 pub const ACK_REQUESTED: u16 = 1 << 5;
51 pub const PAN_ID_COMPRESSION: u16 = 1 << 6;
52 pub const SEQ_SUPPRESSED: u16 = 1 << 8;
53 pub const IE_PRESENT: u16 = 1 << 9;
54 pub const DST_MODE_POS: usize = 10;
55 pub const FRAME_VERSION_MASK: u16 = 0b11 << 12;
56 pub const SRC_MODE_POS: usize = 14;
57 pub const MODE_MASK: u16 = 0b11;
58}
59
60#[repr(u16)]
61#[derive(Copy, Clone, Eq, PartialEq, Debug)]
62pub enum FrameType {
63 Beacon = 0b000,
65 Data = 0b001,
66 Acknowledgement = 0b010,
67 MACCommand = 0b011,
68 Multipurpose = 0b101,
69 Fragment = 0b110,
70 Extended = 0b111,
71}
72
73impl FrameType {
74 pub fn from_fcf(fcf: u16) -> Option<FrameType> {
75 match fcf & frame_control::FRAME_TYPE_MASK {
76 0b000 => Some(FrameType::Beacon),
77 0b001 => Some(FrameType::Data),
78 0b010 => Some(FrameType::Acknowledgement),
79 0b011 => Some(FrameType::MACCommand),
80 0b101 => Some(FrameType::Multipurpose),
81 0b110 => Some(FrameType::Fragment),
82 0b111 => Some(FrameType::Extended),
83 _ => None,
84 }
85 }
86}
87
88#[repr(u16)]
89#[derive(Copy, Clone, Eq, PartialEq, Debug)]
90pub enum FrameVersion {
91 V2003 = 0x0000,
93 V2006 = 0x1000,
94 V2015 = 0x2000,
95}
96
97impl FrameVersion {
98 pub fn from_fcf(fcf: u16) -> Option<FrameVersion> {
99 match fcf & frame_control::FRAME_VERSION_MASK {
100 0x0000 => Some(FrameVersion::V2003),
101 0x1000 => Some(FrameVersion::V2006),
102 0x2000 => Some(FrameVersion::V2015),
103 _ => None,
104 }
105 }
106}
107
108#[repr(u8)]
109#[derive(Copy, Clone, Eq, PartialEq, Debug)]
110pub enum AddressMode {
111 NotPresent = 0b00,
112 Short = 0b10,
113 Long = 0b11,
114}
115
116impl<'a> From<&'a Option<MacAddress>> for AddressMode {
117 fn from(opt_addr: &'a Option<MacAddress>) -> Self {
118 match *opt_addr {
119 None => AddressMode::NotPresent,
120 Some(addr) => match addr {
121 MacAddress::Short(_) => AddressMode::Short,
122 MacAddress::Long(_) => AddressMode::Long,
123 },
124 }
125 }
126}
127
128impl AddressMode {
129 pub fn from_mode(mode: u16) -> Option<AddressMode> {
130 match mode {
131 0b00 => Some(AddressMode::NotPresent),
132 0b10 => Some(AddressMode::Short),
133 0b11 => Some(AddressMode::Long),
134 _ => None,
135 }
136 }
137}
138
139mod security_control {
140 pub const SECURITY_LEVEL_MASK: u8 = 0b111;
141 pub const KEY_ID_MODE_MASK: u8 = 0b11 << 3;
142 pub const FRAME_COUNTER_SUPPRESSION: u8 = 1 << 5;
143 pub const ASN_IN_NONCE: u8 = 1 << 6;
144}
145
146#[repr(u8)]
147#[derive(Copy, Clone, Eq, PartialEq, Debug)]
148pub enum SecurityLevel {
149 None = 0b000,
151 Mic32 = 0b001,
152 Mic64 = 0b010,
153 Mic128 = 0b011,
154 EncMic32 = 0b101,
155 EncMic64 = 0b110,
156 EncMic128 = 0b111,
157}
158
159impl SecurityLevel {
160 pub fn from_scf(scf: u8) -> Option<SecurityLevel> {
161 match scf & security_control::SECURITY_LEVEL_MASK {
162 0b000 => Some(SecurityLevel::None),
163 0b001 => Some(SecurityLevel::Mic32),
164 0b010 => Some(SecurityLevel::Mic64),
165 0b011 => Some(SecurityLevel::Mic128),
166 0b101 => Some(SecurityLevel::EncMic32),
167 0b110 => Some(SecurityLevel::EncMic64),
168 0b111 => Some(SecurityLevel::EncMic128),
169 _ => None,
170 }
171 }
172
173 pub fn encryption_needed(&self) -> bool {
174 match *self {
175 SecurityLevel::EncMic32 | SecurityLevel::EncMic64 | SecurityLevel::EncMic128 => true,
176 _ => false,
177 }
178 }
179
180 pub fn mic_len(&self) -> usize {
181 match *self {
182 SecurityLevel::Mic32 | SecurityLevel::EncMic32 => 4,
183 SecurityLevel::Mic64 | SecurityLevel::EncMic64 => 8,
184 SecurityLevel::Mic128 | SecurityLevel::EncMic128 => 16,
185 _ => 0,
186 }
187 }
188}
189
190#[repr(u8)]
191#[derive(Copy, Clone, Eq, PartialEq, Debug)]
192pub enum KeyIdMode {
193 Implicit = 0x00,
194 Index = 0x08,
195 Source4Index = 0x10,
196 Source8Index = 0x18,
197}
198
199impl KeyIdMode {
200 pub fn from_scf(scf: u8) -> Option<KeyIdMode> {
201 match scf & security_control::KEY_ID_MODE_MASK {
202 0x00 => Some(KeyIdMode::Implicit),
203 0x08 => Some(KeyIdMode::Index),
204 0x10 => Some(KeyIdMode::Source4Index),
205 0x18 => Some(KeyIdMode::Source8Index),
206 _ => panic!("Unreachable case because of mask"),
207 }
208 }
209}
210
211#[derive(Copy, Clone, Eq, PartialEq, Debug)]
212pub enum KeyId {
213 Implicit,
214 Index(u8),
215 Source4Index([u8; 4], u8),
216 Source8Index([u8; 8], u8),
217}
218
219impl KeyId {
220 pub fn encode(&self, buf: &mut [u8]) -> SResult {
221 let off = match *self {
222 KeyId::Implicit => 0,
223 KeyId::Index(index) => enc_consume!(buf; encode_u8, index),
224 KeyId::Source4Index(ref src, index) => {
225 let off = enc_consume!(buf; encode_bytes_be, src);
226 enc_consume!(buf, off; encode_u8, index)
227 }
228 KeyId::Source8Index(ref src, index) => {
229 let off = enc_consume!(buf; encode_bytes_be, src);
230 enc_consume!(buf, off; encode_u8, index)
231 }
232 };
233 stream_done!(off);
234 }
235
236 pub fn decode(buf: &[u8], mode: KeyIdMode) -> SResult<KeyId> {
237 match mode {
238 KeyIdMode::Implicit => stream_done!(0, KeyId::Implicit),
239 KeyIdMode::Index => {
240 let (off, index) = dec_try!(buf; decode_u8);
241 stream_done!(off, KeyId::Index(index));
242 }
243 KeyIdMode::Source4Index => {
244 let mut src = [0u8; 4];
245 let off = dec_consume!(buf; decode_bytes_be, &mut src);
246 let (off, index) = dec_try!(buf, off; decode_u8);
247 stream_done!(off, KeyId::Source4Index(src, index));
248 }
249 KeyIdMode::Source8Index => {
250 let mut src = [0u8; 8];
251 let off = dec_consume!(buf; decode_bytes_be, &mut src);
252 let (off, index) = dec_try!(buf, off; decode_u8);
253 stream_done!(off, KeyId::Source8Index(src, index));
254 }
255 }
256 }
257}
258
259impl<'a> From<&'a KeyId> for KeyIdMode {
260 fn from(key_id: &'a KeyId) -> Self {
261 match *key_id {
262 KeyId::Implicit => KeyIdMode::Implicit,
263 KeyId::Index(_) => KeyIdMode::Index,
264 KeyId::Source4Index(_, _) => KeyIdMode::Source4Index,
265 KeyId::Source8Index(_, _) => KeyIdMode::Source8Index,
266 }
267 }
268}
269
270#[derive(Copy, Clone, Eq, PartialEq, Debug)]
271pub struct Security {
272 pub level: SecurityLevel,
273 pub asn_in_nonce: bool,
274 pub frame_counter: Option<u32>,
275 pub key_id: KeyId,
276}
277
278impl Security {
279 pub fn encode(&self, buf: &mut [u8]) -> SResult {
280 stream_len_cond!(buf, 1);
283 let mut off = 1;
284
285 let mut scf = self.level as u8;
287 if self.asn_in_nonce {
288 scf |= security_control::ASN_IN_NONCE;
289 }
290
291 if let Some(ref frame_counter) = self.frame_counter {
293 off = enc_consume!(buf, off; encode_u32, frame_counter.to_be());
294 } else {
295 scf |= security_control::FRAME_COUNTER_SUPPRESSION;
296 }
297
298 scf |= KeyIdMode::from(&self.key_id) as u8;
300 off = enc_consume!(buf, off; self.key_id; encode);
301
302 enc_try!(buf; encode_u8, scf);
304 stream_done!(off);
305 }
306
307 pub fn decode(buf: &[u8]) -> SResult<Security> {
308 let (off, scf) = dec_try!(buf; decode_u8);
310 let level = stream_from_option!(SecurityLevel::from_scf(scf));
311 let asn_in_nonce = (scf & security_control::ASN_IN_NONCE) != 0;
312
313 let frame_counter_present = (scf & security_control::FRAME_COUNTER_SUPPRESSION) == 0;
316 let (off, frame_counter) = if frame_counter_present {
317 let (off, frame_counter_be) = dec_try!(buf, off; decode_u32);
318 (off, Some(u32::from_be(frame_counter_be)))
319 } else {
320 (off, None)
321 };
322
323 let key_id_mode = stream_from_option!(KeyIdMode::from_scf(scf));
325 let (off, key_id) = dec_try!(buf, off; KeyId::decode, key_id_mode);
326
327 stream_done!(
328 off,
329 Security {
330 level,
331 asn_in_nonce,
332 frame_counter,
333 key_id,
334 }
335 );
336 }
337}
338
339mod ie_control {
340 pub const HEADER_LEN_MAX: usize = (1 << 7) - 1;
342 pub const HEADER_LEN_MASK: u16 = HEADER_LEN_MAX as u16;
343 pub const HEADER_ID_POS: usize = 7;
344
345 pub const PAYLOAD_LEN_MAX: usize = (1 << 11) - 1;
347 pub const PAYLOAD_LEN_MASK: u16 = PAYLOAD_LEN_MAX as u16;
348 pub const PAYLOAD_ID_MASK: u8 = 0xf; pub const PAYLOAD_ID_POS: usize = 11;
350
351 pub const TYPE: u16 = 0x8000;
352}
353
354#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
355pub enum HeaderIE<'a> {
356 Undissected {
357 element_id: u8,
358 content: &'a [u8],
359 },
360 #[default]
361 Termination1,
362 Termination2,
363}
364
365impl HeaderIE<'_> {
366 pub fn is_termination(&self) -> bool {
367 match *self {
368 HeaderIE::Termination1 | HeaderIE::Termination2 => true,
369 _ => false,
370 }
371 }
372
373 pub fn encode(&self, buf: &mut [u8]) -> SResult {
374 let mut off = 2;
376 let element_id: u8 = match *self {
377 HeaderIE::Undissected {
378 element_id,
379 content,
380 } => {
381 off = enc_consume!(buf, off; encode_bytes, content);
382 element_id
383 }
384 HeaderIE::Termination1 => 0x7e,
385 HeaderIE::Termination2 => 0x7f,
386 };
387
388 let content_len = off - 2;
390 stream_cond!(content_len <= ie_control::HEADER_LEN_MAX);
391 let ie_ctl = ((content_len as u16) & ie_control::HEADER_LEN_MASK)
392 | ((element_id as u16) << ie_control::HEADER_ID_POS);
393 enc_consume!(buf; encode_u16, ie_ctl.to_be());
394
395 stream_done!(off);
396 }
397
398 pub fn decode(buf: &[u8]) -> SResult<HeaderIE<'_>> {
399 let (off, ie_ctl_be) = dec_try!(buf; decode_u16);
400 let ie_ctl = u16::from_be(ie_ctl_be);
401
402 stream_cond!(ie_ctl & ie_control::TYPE == 0);
404 let content_len = (ie_ctl & ie_control::HEADER_LEN_MASK) as usize;
405 let element_id = (ie_ctl >> ie_control::HEADER_ID_POS) as u8;
406
407 stream_len_cond!(buf, off + content_len);
408 let content = &buf[off..off + content_len];
409
410 let ie = match element_id {
411 0x7e => HeaderIE::Termination1,
412 0x7f => HeaderIE::Termination2,
413 element_id => HeaderIE::Undissected {
414 element_id,
415 content,
416 },
417 };
418
419 stream_done!(off + content_len, ie);
420 }
421}
422
423#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
424pub enum PayloadIE<'a> {
425 Undissected {
426 group_id: u8,
427 content: &'a [u8],
428 },
429 #[default]
430 Termination,
431}
432
433impl PayloadIE<'_> {
434 pub fn is_termination(&self) -> bool {
435 match *self {
436 PayloadIE::Termination => true,
437 _ => false,
438 }
439 }
440
441 pub fn encode(&self, buf: &mut [u8]) -> SResult {
442 let mut off = 2;
444 let group_id: u8 = match *self {
445 PayloadIE::Undissected { group_id, content } => {
446 off = enc_consume!(buf, off; encode_bytes, content);
447 group_id
448 }
449 PayloadIE::Termination => 0xf,
450 };
451
452 let content_len = off - 2;
454 stream_cond!(content_len <= ie_control::PAYLOAD_LEN_MAX);
455 let ie_ctl = ((content_len as u16) & ie_control::PAYLOAD_LEN_MASK)
456 | ((group_id & ie_control::PAYLOAD_ID_MASK) as u16) << ie_control::PAYLOAD_ID_POS;
457 enc_consume!(buf; encode_u16, ie_ctl.to_be());
458
459 stream_done!(off);
460 }
461
462 pub fn decode(buf: &[u8]) -> SResult<PayloadIE<'_>> {
463 let (off, ie_ctl_be) = dec_try!(buf; decode_u16);
464 let ie_ctl = u16::from_be(ie_ctl_be);
465
466 stream_cond!(ie_ctl & ie_control::TYPE != 0);
468 let content_len = (ie_ctl & ie_control::PAYLOAD_LEN_MASK) as usize;
469 let element_id =
470 ((ie_ctl >> ie_control::PAYLOAD_ID_POS) as u8) & ie_control::PAYLOAD_ID_MASK;
471
472 stream_len_cond!(buf, off + content_len);
473 let content = &buf[off..off + content_len];
474
475 let ie = match element_id {
476 0xf => PayloadIE::Termination,
477 group_id => PayloadIE::Undissected { group_id, content },
478 };
479
480 stream_done!(off + content_len, ie);
481 }
482}
483
484pub const MAX_HEADER_IES: usize = 5;
485pub const MAX_PAYLOAD_IES: usize = 5;
486
487#[derive(Copy, Clone, Eq, PartialEq, Debug)]
488pub struct Header<'a> {
489 pub frame_type: FrameType,
490 pub frame_pending: bool,
491 pub ack_requested: bool,
492 pub version: FrameVersion,
493 pub seq: Option<u8>,
494 pub dst_pan: Option<PanID>,
495 pub dst_addr: Option<MacAddress>,
496 pub src_pan: Option<PanID>,
497 pub src_addr: Option<MacAddress>,
498 pub security: Option<Security>,
499 pub header_ies: [HeaderIE<'a>; MAX_HEADER_IES],
500 pub header_ies_len: usize,
501 pub payload_ies: [PayloadIE<'a>; MAX_PAYLOAD_IES],
502 pub payload_ies_len: usize,
503}
504
505impl Header<'_> {
506 pub fn encode(&self, buf: &mut [u8], has_payload: bool) -> SResult<usize> {
507 stream_len_cond!(buf, 2);
510 let mut off = 2;
511
512 if self.version != FrameVersion::V2015 {
514 stream_cond!(self.seq.is_some());
516 }
517 let seq_suppressed = if let Some(seq) = self.seq {
518 off = enc_consume!(buf, off; encode_u8, seq);
519 false
520 } else {
521 true
522 };
523
524 let (off, pan_id_compression) = enc_try!(buf, off; self; encode_addressing);
526 let dst_mode = AddressMode::from(&self.dst_addr);
527 let src_mode = AddressMode::from(&self.src_addr);
528
529 let (mut off, security_enabled) = match self.security {
532 None => (off, false),
533 Some(ref security) => (enc_consume!(buf, off; security; encode), true),
534 };
535
536 let has_header_ies = self.header_ies_len != 0;
541 let has_payload_ies = self.payload_ies_len != 0;
542 stream_cond!(self.header_ies_len <= MAX_HEADER_IES);
543 stream_cond!(self.payload_ies_len <= MAX_PAYLOAD_IES);
544 for ie in self.header_ies[..self.header_ies_len].iter() {
545 stream_cond!(!ie.is_termination());
546 off = enc_consume!(buf, off; ie; encode);
547 }
548 if has_payload_ies {
549 off = enc_consume!(buf, off; HeaderIE::Termination1; encode);
551 } else if has_header_ies && has_payload {
552 off = enc_consume!(buf, off; HeaderIE::Termination2; encode);
554 }
555 let mac_payload_off = off;
557 for ie in self.payload_ies[..self.payload_ies_len].iter() {
558 stream_cond!(!ie.is_termination());
559 off = enc_consume!(buf, off; ie; encode);
560 }
561 if has_payload_ies && has_payload {
562 off = enc_consume!(buf, off; PayloadIE::Termination; encode);
564 }
565 let ie_present = has_header_ies || has_payload_ies;
566
567 let mut fcf = self.frame_type as u16;
569 if security_enabled {
570 fcf |= frame_control::SECURITY_ENABLED;
571 }
572 if self.frame_pending {
573 fcf |= frame_control::FRAME_PENDING;
574 }
575 if self.ack_requested {
576 fcf |= frame_control::ACK_REQUESTED;
577 }
578 if pan_id_compression {
579 fcf |= frame_control::PAN_ID_COMPRESSION;
580 }
581 if seq_suppressed {
582 fcf |= frame_control::SEQ_SUPPRESSED;
583 }
584 if ie_present {
585 fcf |= frame_control::IE_PRESENT;
586 }
587 fcf |= (dst_mode as u16) << frame_control::DST_MODE_POS;
588 fcf |= self.version as u16;
589 fcf |= (src_mode as u16) << frame_control::SRC_MODE_POS;
590
591 enc_try!(buf; encode_u16, fcf.to_be());
593 stream_done!(off, mac_payload_off);
594 }
595
596 pub fn encode_addressing(&self, buf: &mut [u8]) -> SResult<bool> {
597 let mut drop_src_pan = false;
600 let pan_id_compression = match self.version {
601 FrameVersion::V2015 => {
602 match (self.dst_addr, self.src_addr) {
605 (None, None) => {
606 stream_cond!(self.src_pan.is_none());
607 self.dst_pan.is_some()
608 }
609 (Some(_), None) => {
610 stream_cond!(self.src_pan.is_none());
611 self.dst_pan.is_none()
612 }
613 (None, Some(_)) => {
614 stream_cond!(self.dst_pan.is_none());
615 self.src_pan.is_none()
616 }
617 (Some(_), Some(_)) => {
618 drop_src_pan = match (self.dst_pan, self.src_pan) {
622 (Some(dst_pan), Some(src_pan)) => dst_pan == src_pan,
623 _ => stream_err!(),
624 };
625 drop_src_pan
626 }
627 }
628 }
629 FrameVersion::V2003 | FrameVersion::V2006 => {
630 stream_cond!(self.dst_addr.is_some() == self.dst_pan.is_some());
634 stream_cond!(self.src_addr.is_some() == self.src_pan.is_some());
635
636 match (self.dst_pan, self.src_pan) {
637 (Some(dst_pan), Some(src_pan)) => {
638 drop_src_pan = dst_pan == src_pan;
639 }
640 _ => {}
641 }
642 drop_src_pan
643 }
644 };
645
646 let mut off = 0;
648 if let Some(pan) = self.dst_pan {
649 off = enc_consume!(buf, off; encode_u16, pan.to_be());
650 }
651 if let Some(addr) = self.dst_addr {
652 off = enc_consume!(buf, off; addr; encode);
653 }
654 if let Some(pan) = self.src_pan {
655 if !drop_src_pan {
656 off = enc_consume!(buf, off; encode_u16, pan.to_be());
657 }
658 }
659 if let Some(addr) = self.src_addr {
660 off = enc_consume!(buf, off; addr; encode);
661 }
662
663 stream_done!(off, pan_id_compression);
664 }
665
666 pub fn decode<'b>(buf: &'b [u8], unsecured: bool) -> SResult<(Header<'b>, usize)> {
672 let (off, fcf_be) = dec_try!(buf; decode_u16);
674 let fcf = u16::from_be(fcf_be);
675
676 let frame_type = stream_from_option!(FrameType::from_fcf(fcf));
678 let security_enabled = (fcf & frame_control::SECURITY_ENABLED) != 0;
679 let frame_pending = (fcf & frame_control::FRAME_PENDING) != 0;
680 let ack_requested = (fcf & frame_control::ACK_REQUESTED) != 0;
681 let pan_id_compression = (fcf & frame_control::PAN_ID_COMPRESSION) != 0;
682 let seq_suppressed = (fcf & frame_control::SEQ_SUPPRESSED) != 0;
683 let ie_present = (fcf & frame_control::IE_PRESENT) != 0;
684 let dst_mode = {
685 let mode = (fcf >> frame_control::DST_MODE_POS) & frame_control::MODE_MASK;
686 stream_from_option!(AddressMode::from_mode(mode))
687 };
688 let version = stream_from_option!(FrameVersion::from_fcf(fcf));
689 let src_mode = {
690 let mode = (fcf >> frame_control::SRC_MODE_POS) & frame_control::MODE_MASK;
691 stream_from_option!(AddressMode::from_mode(mode))
692 };
693
694 let (off, seq) = if !seq_suppressed {
696 let (off, seq) = dec_try!(buf, off; decode_u8);
697 (off, Some(seq))
698 } else {
699 (off, None)
700 };
701
702 let (off, (dst_pan, dst_addr, src_pan, src_addr)) = dec_try!(buf, off;
704 Self::decode_addressing,
705 version,
706 dst_mode,
707 src_mode,
708 pan_id_compression);
709
710 let (mut off, security) = if security_enabled {
712 let (off, security) = dec_try!(buf, off; Security::decode);
713 (off, Some(security))
714 } else {
715 (off, None)
716 };
717
718 let mut header_ies: [HeaderIE<'b>; MAX_HEADER_IES] = Default::default();
720 let mut header_ies_len = 0;
721 let mut payload_ies: [PayloadIE<'b>; MAX_PAYLOAD_IES] = Default::default();
722 let mut payload_ies_len = 0;
723
724 let mut has_payload_ies = false;
725 if ie_present {
726 loop {
727 let (next_off, ie) = dec_try!(buf, off; HeaderIE::decode);
728 off = next_off;
729 match ie {
730 HeaderIE::Termination1 => {
731 has_payload_ies = true;
732 break;
733 }
734 HeaderIE::Termination2 => {
735 break;
736 }
737 other_ie => {
738 stream_cond!(header_ies_len + 1 < MAX_HEADER_IES);
739 header_ies[header_ies_len] = other_ie;
740 header_ies_len += 1;
741 }
742 }
743 }
744 }
745 let mac_payload_off = off;
748 let unencrypted = unsecured || !security_enabled;
749 if has_payload_ies && unencrypted {
750 loop {
751 let (next_off, ie) = dec_try!(buf, off; PayloadIE::decode);
752 off = next_off;
753 match ie {
754 PayloadIE::Termination => {
755 break;
756 }
757 other_ie => {
758 stream_cond!(payload_ies_len + 1 < MAX_PAYLOAD_IES);
759 payload_ies[payload_ies_len] = other_ie;
760 payload_ies_len += 1;
761 }
762 }
763 }
764 }
765
766 stream_done!(
767 off,
768 (
769 Header {
770 frame_type,
771 frame_pending,
772 ack_requested,
773 version,
774 seq,
775 dst_pan,
776 dst_addr,
777 src_pan,
778 src_addr,
779 security,
780 header_ies,
781 header_ies_len,
782 payload_ies,
783 payload_ies_len,
784 },
785 mac_payload_off
786 )
787 );
788 }
789
790 pub fn decode_addressing(
791 buf: &[u8],
792 version: FrameVersion,
793 dst_mode: AddressMode,
794 src_mode: AddressMode,
795 pan_id_compression: bool,
796 ) -> SResult<(
797 Option<PanID>,
798 Option<MacAddress>,
799 Option<PanID>,
800 Option<MacAddress>,
801 )> {
802 let mut src_pan_dropped = false;
807 let dst_present = dst_mode != AddressMode::NotPresent;
808 let src_present = src_mode != AddressMode::NotPresent;
809 let (dst_pan_present, src_pan_present) = match version {
810 FrameVersion::V2015 => {
811 match (dst_present, src_present) {
813 (false, false) => (pan_id_compression, false),
814 (true, false) => (!pan_id_compression, false),
815 (false, true) => (false, !pan_id_compression),
816 (true, true) => {
817 src_pan_dropped = pan_id_compression;
818 (true, !pan_id_compression)
819 }
820 }
821 }
822 FrameVersion::V2003 | FrameVersion::V2006 => {
823 src_pan_dropped = pan_id_compression;
828 (dst_present, src_present && !src_pan_dropped)
829 }
830 };
831
832 let off = 0;
833 let (off, dst_pan) = if dst_pan_present {
834 let (off, pan_be) = dec_try!(buf, off; decode_u16);
835 (off, Some(u16::from_be(pan_be)))
836 } else {
837 (off, None)
838 };
839 let (off, dst_addr) = dec_try!(buf, off; MacAddress::decode, dst_mode);
840 let (off, src_pan) = if src_pan_present {
841 let (off, pan_be) = dec_try!(buf, off; decode_u16);
842 (off, Some(u16::from_be(pan_be)))
843 } else {
844 if src_pan_dropped {
845 (off, Some(stream_from_option!(dst_pan)))
849 } else {
850 (off, None)
851 }
852 };
853 let (off, src_addr) = dec_try!(buf, off; MacAddress::decode, src_mode);
854
855 stream_done!(off, (dst_pan, dst_addr, src_pan, src_addr));
856 }
857}