dot15d4_frame/repr/ie/
nested.rs1use super::super::super::{
2 ChannelHopping, NestedInformationElement, NestedSubId, NestedSubIdLong, NestedSubIdShort,
3 TschSlotframeAndLink, TschSynchronization, TschTimeslot,
4};
5use super::super::super::{Error, Result};
6
7#[derive(Debug)]
9#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
10pub enum NestedInformationElementRepr {
11 TschSynchronization(TschSynchronizationRepr),
13 TschTimeslot(TschTimeslotRepr),
15 TschSlotframeAndLink(TschSlotframeAndLinkRepr),
17 ChannelHopping(ChannelHoppingRepr),
19}
20
21impl NestedInformationElementRepr {
22 pub fn parse(ie: &NestedInformationElement<&[u8]>) -> Result<Self> {
24 Ok(match ie.sub_id() {
25 NestedSubId::Short(NestedSubIdShort::TschSynchronization) => Self::TschSynchronization(
26 TschSynchronizationRepr::parse(&TschSynchronization::new(ie.content())?),
27 ),
28 NestedSubId::Short(NestedSubIdShort::TschTimeslot) => {
29 Self::TschTimeslot(TschTimeslotRepr::parse(&TschTimeslot::new(ie.content())?))
30 }
31 NestedSubId::Short(NestedSubIdShort::TschSlotframeAndLink) => {
32 Self::TschSlotframeAndLink(TschSlotframeAndLinkRepr::parse(
33 &TschSlotframeAndLink::new(ie.content())?,
34 ))
35 }
36 NestedSubId::Long(NestedSubIdLong::ChannelHopping) => Self::ChannelHopping(
37 ChannelHoppingRepr::parse(&ChannelHopping::new(ie.content())?),
38 ),
39 _ => return Err(Error),
40 })
41 }
42
43 pub fn buffer_len(&self) -> usize {
45 2 + self.inner_len()
46 }
47
48 pub fn inner_len(&self) -> usize {
51 match self {
52 Self::TschSynchronization(repr) => repr.buffer_len(),
53 Self::TschTimeslot(repr) => repr.buffer_len(),
54 Self::TschSlotframeAndLink(repr) => repr.buffer_len(),
55 Self::ChannelHopping(repr) => repr.buffer_len(),
56 }
57 }
58
59 pub fn emit(&self, w: &mut NestedInformationElement<&mut [u8]>) {
61 let id = NestedSubId::from(self);
62
63 w.clear();
64 w.set_length(self.inner_len() as u16, id);
65 w.set_sub_id(id);
66
67 match self {
68 Self::TschSynchronization(repr) => {
69 repr.emit(&mut TschSynchronization::new_unchecked(w.content_mut()))
70 }
71 Self::TschTimeslot(repr) => {
72 repr.emit(&mut TschTimeslot::new_unchecked(w.content_mut()))
73 }
74 Self::TschSlotframeAndLink(repr) => {
75 repr.emit(&mut TschSlotframeAndLink::new_unchecked(w.content_mut()))
76 }
77 Self::ChannelHopping(repr) => {
78 repr.emit(&mut ChannelHopping::new_unchecked(w.content_mut()))
79 }
80 }
81 }
82}
83
84impl From<&NestedInformationElementRepr> for NestedSubId {
85 fn from(value: &NestedInformationElementRepr) -> Self {
86 match value {
87 NestedInformationElementRepr::TschSynchronization(_) => {
88 NestedSubId::Short(NestedSubIdShort::TschSynchronization)
89 }
90 NestedInformationElementRepr::TschTimeslot(_) => {
91 NestedSubId::Short(NestedSubIdShort::TschTimeslot)
92 }
93 NestedInformationElementRepr::TschSlotframeAndLink(_) => {
94 NestedSubId::Short(NestedSubIdShort::TschSlotframeAndLink)
95 }
96 NestedInformationElementRepr::ChannelHopping(_) => {
97 NestedSubId::Long(NestedSubIdLong::ChannelHopping)
98 }
99 }
100 }
101}
102
103#[derive(Debug)]
106#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
107pub struct TschSynchronizationRepr {
108 pub absolute_slot_number: u64,
110 pub join_metric: u8,
112}
113
114impl TschSynchronizationRepr {
115 pub fn parse(ie: &TschSynchronization<&[u8]>) -> Self {
117 Self {
118 absolute_slot_number: ie.absolute_slot_number(),
119 join_metric: ie.join_metric(),
120 }
121 }
122
123 pub const fn buffer_len(&self) -> usize {
126 6
127 }
128
129 pub fn emit(&self, ie: &mut TschSynchronization<&mut [u8]>) {
131 ie.set_absolute_slot_number(self.absolute_slot_number);
132 ie.set_join_metric(self.join_metric);
133 }
134}
135
136#[derive(Debug)]
139#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
140pub struct TschSlotframeAndLinkRepr {
141 pub number_of_slot_frames: u8,
143}
144
145impl TschSlotframeAndLinkRepr {
146 pub fn parse(ie: &TschSlotframeAndLink<&[u8]>) -> Self {
148 Self {
149 number_of_slot_frames: ie.number_of_slot_frames(),
150 }
151 }
152
153 pub fn buffer_len(&self) -> usize {
156 1
157 }
158
159 pub fn emit(&self, ie: &mut TschSlotframeAndLink<&mut [u8]>) {
161 ie.set_number_of_slot_frames(self.number_of_slot_frames);
162 }
163}
164
165#[derive(Debug)]
167#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
168pub struct TschTimeslotRepr {
169 pub id: u8,
171}
172
173impl TschTimeslotRepr {
174 pub fn parse(ie: &TschTimeslot<&[u8]>) -> Self {
176 Self { id: ie.id() }
177 }
178
179 pub fn buffer_len(&self) -> usize {
182 1
184 }
185
186 pub fn emit(&self, ie: &mut TschTimeslot<&mut [u8]>) {
188 ie.set_time_slot_id(self.id);
189 }
190}
191
192#[derive(Debug)]
194#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
195pub struct ChannelHoppingRepr {
196 pub hopping_sequence_id: u8,
198}
199
200impl ChannelHoppingRepr {
201 pub fn parse(ie: &ChannelHopping<&[u8]>) -> Self {
203 Self {
204 hopping_sequence_id: ie.hopping_sequence_id(),
205 }
206 }
207
208 pub fn buffer_len(&self) -> usize {
211 1
212 }
213
214 pub fn emit(&self, ie: &mut ChannelHopping<&mut [u8]>) {
216 ie.set_hopping_sequence_id(self.hopping_sequence_id);
217 }
218}