dot15d4_frame/repr/ie/
payloads.rs1use super::super::super::{Error, Result};
2use super::super::super::{NestedInformationElement, PayloadGroupId, PayloadInformationElement};
3
4use super::NestedInformationElementRepr;
5
6use heapless::Vec;
7
8#[derive(Debug)]
10#[allow(clippy::large_enum_variant)]
11pub enum PayloadInformationElementRepr {
12 Mlme(Vec<NestedInformationElementRepr, 16>),
14 PayloadTermination,
16}
17
18#[cfg(feature = "fuzz")]
19impl arbitrary::Arbitrary<'_> for PayloadInformationElementRepr {
20 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
21 match u.int_in_range(0..=1)? {
22 0 => Ok(Self::PayloadTermination),
23 _ => {
24 let mut nested_information_elements = Vec::new();
25
26 for _ in 0..u.int_in_range(0..=15)? {
27 nested_information_elements
28 .push(NestedInformationElementRepr::arbitrary(u)?)
29 .map_err(|_err| arbitrary::Error::IncorrectFormat)?;
30 }
31
32 Ok(Self::Mlme(nested_information_elements))
33 }
34 }
35 }
36}
37
38impl PayloadInformationElementRepr {
39 pub fn parse(ie: &PayloadInformationElement<&[u8]>) -> Result<Self> {
41 match ie.group_id() {
42 PayloadGroupId::Mlme => {
43 let mut nested_information_elements = Vec::new();
44
45 for nested_ie in ie.nested_information_elements() {
46 if nested_information_elements
47 .push(NestedInformationElementRepr::parse(&nested_ie)?)
48 .is_err()
49 {
50 break;
51 }
52 }
53
54 Ok(Self::Mlme(nested_information_elements))
55 }
56 _ => Err(Error),
57 }
58 }
59
60 pub fn buffer_len(&self) -> usize {
62 2 + self.inner_len()
63 }
64
65 fn inner_len(&self) -> usize {
68 match self {
69 Self::Mlme(nested_ies) => {
70 let mut len = 0;
71
72 for ie in nested_ies.iter() {
73 len += ie.buffer_len();
74 }
75
76 len
77 }
78 Self::PayloadTermination => 0,
79 }
80 }
81
82 pub fn emit(&self, w: &mut PayloadInformationElement<&mut [u8]>) {
84 w.clear();
85 w.set_length(self.inner_len() as u16);
86 w.set_group_id(self.into());
87
88 let buffer = w.content_mut();
89 match self {
90 Self::Mlme(nested_ies) => {
91 let mut offset = 0;
92 for ie in nested_ies.iter() {
93 ie.emit(&mut NestedInformationElement::new_unchecked(
94 &mut buffer[offset..],
95 ));
96 offset += ie.buffer_len();
97 }
98 }
99 Self::PayloadTermination => todo!(),
100 }
101 }
102}
103
104impl From<&PayloadInformationElementRepr> for PayloadGroupId {
105 fn from(val: &PayloadInformationElementRepr) -> Self {
106 use PayloadInformationElementRepr::*;
107 match val {
108 Mlme(_) => PayloadGroupId::Mlme,
109 PayloadTermination => PayloadGroupId::PayloadTermination,
110 }
111 }
112}