1use super::AddressingMode;
4use super::{Error, Result};
5
6#[derive(Debug, Eq, PartialEq, Clone, Copy)]
8#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
9pub enum FrameType {
10 Beacon = 0b000,
12 Data = 0b001,
14 Ack = 0b010,
16 MacCommand = 0b011,
18 Multipurpose = 0b101,
20 FragmentOrFrak = 0b110,
22 Extended = 0b111,
24 Unknown,
26}
27
28impl From<u8> for FrameType {
29 fn from(value: u8) -> Self {
30 match value {
31 0b000 => Self::Beacon,
32 0b001 => Self::Data,
33 0b010 => Self::Ack,
34 0b011 => Self::MacCommand,
35 0b101 => Self::Multipurpose,
36 0b110 => Self::FragmentOrFrak,
37 0b111 => Self::Extended,
38 _ => Self::Unknown,
39 }
40 }
41}
42
43#[derive(Debug, Eq, PartialEq, Clone, Copy)]
45#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
46pub enum FrameVersion {
47 Ieee802154_2003 = 0b00,
49 Ieee802154_2006 = 0b01,
51 Ieee802154_2020 = 0b10,
53 Unknown,
55}
56
57impl From<u8> for FrameVersion {
58 fn from(value: u8) -> Self {
59 match value {
60 0b00 => Self::Ieee802154_2003,
61 0b01 => Self::Ieee802154_2006,
62 0b10 => Self::Ieee802154_2020,
63 _ => Self::Unknown,
64 }
65 }
66}
67
68pub struct FrameControl<T: AsRef<[u8]>> {
70 buffer: T,
71}
72
73impl<T: AsRef<[u8]>> FrameControl<T> {
74 pub fn new(buffer: T) -> Result<Self> {
80 let fc = Self::new_unchecked(buffer);
81
82 if !fc.check_len() {
83 return Err(Error);
84 }
85
86 Ok(fc)
87 }
88
89 fn check_len(&self) -> bool {
92 self.buffer.as_ref().len() >= 2
93 }
94
95 pub fn new_unchecked(buffer: T) -> Self {
98 Self { buffer }
99 }
100
101 pub fn into_inner(self) -> T {
103 self.buffer
104 }
105
106 pub fn frame_type(&self) -> FrameType {
108 let b = &self.buffer.as_ref()[..2];
109 FrameType::from((u16::from_le_bytes([b[0], b[1]]) & 0b111) as u8)
110 }
111
112 pub fn security_enabled(&self) -> bool {
114 let b = &self.buffer.as_ref()[..2];
115 ((u16::from_le_bytes([b[0], b[1]]) >> 3) & 0b1) == 1
116 }
117
118 pub fn frame_pending(&self) -> bool {
120 let b = &self.buffer.as_ref()[..2];
121 ((u16::from_le_bytes([b[0], b[1]]) >> 4) & 0b1) == 1
122 }
123
124 pub fn ack_request(&self) -> bool {
126 let b = &self.buffer.as_ref()[..2];
127 ((u16::from_le_bytes([b[0], b[1]]) >> 5) & 0b1) == 1
128 }
129
130 pub fn pan_id_compression(&self) -> bool {
132 let b = &self.buffer.as_ref()[..2];
133 ((u16::from_le_bytes([b[0], b[1]]) >> 6) & 0b1) == 1
134 }
135
136 pub fn sequence_number_suppression(&self) -> bool {
138 let b = &self.buffer.as_ref()[..2];
139 ((u16::from_le_bytes([b[0], b[1]]) >> 8) & 0b1) == 1
140 }
141
142 pub fn information_elements_present(&self) -> bool {
144 let b = &self.buffer.as_ref()[..2];
145 ((u16::from_le_bytes([b[0], b[1]]) >> 9) & 0b1) == 1
146 }
147
148 pub fn dst_addressing_mode(&self) -> AddressingMode {
150 let b = &self.buffer.as_ref()[..2];
151 let raw = (u16::from_le_bytes([b[0], b[1]]) >> 10) & 0b11;
152 AddressingMode::from(raw as u8)
153 }
154
155 pub fn src_addressing_mode(&self) -> AddressingMode {
157 let b = &self.buffer.as_ref()[..2];
158 let raw = (u16::from_le_bytes([b[0], b[1]]) >> 14) & 0b11;
159 AddressingMode::from(raw as u8)
160 }
161
162 pub fn frame_version(&self) -> FrameVersion {
164 let b = &self.buffer.as_ref()[..2];
165 let raw = (u16::from_le_bytes([b[0], b[1]]) >> 12) & 0b11;
166 FrameVersion::from(raw as u8)
167 }
168}
169
170impl<T: AsRef<[u8]> + AsMut<[u8]>> FrameControl<T> {
171 pub fn set_frame_type(&mut self, frame_type: FrameType) {
173 let b = &mut self.buffer.as_mut()[..2];
174 let mut raw = u16::from_le_bytes([b[0], b[1]]);
175 raw = (raw & !0b111) | ((frame_type as u8) as u16 & 0b111);
176 b.copy_from_slice(&raw.to_le_bytes());
177 }
178
179 pub fn set_security_enabled(&mut self, security_enabled: bool) {
181 let b = &mut self.buffer.as_mut()[..2];
182 let mut raw = u16::from_le_bytes([b[0], b[1]]);
183 raw |= (security_enabled as u16) << 3;
184 b.copy_from_slice(&raw.to_le_bytes());
185 }
186
187 pub fn set_frame_pending(&mut self, frame_pending: bool) {
189 let b = &mut self.buffer.as_mut()[..2];
190 let mut raw = u16::from_le_bytes([b[0], b[1]]);
191 raw |= (frame_pending as u16) << 4;
192 b.copy_from_slice(&raw.to_le_bytes());
193 }
194
195 pub fn set_ack_request(&mut self, ack_request: bool) {
197 let b = &mut self.buffer.as_mut()[..2];
198 let mut raw = u16::from_le_bytes([b[0], b[1]]);
199 raw |= (ack_request as u16) << 5;
200 b.copy_from_slice(&raw.to_le_bytes());
201 }
202
203 pub fn set_pan_id_compression(&mut self, pan_id_compression: bool) {
205 let b = &mut self.buffer.as_mut()[..2];
206 let mut raw = u16::from_le_bytes([b[0], b[1]]);
207 raw |= (pan_id_compression as u16) << 6;
208 b.copy_from_slice(&raw.to_le_bytes());
209 }
210
211 pub fn set_sequence_number_suppression(&mut self, sequence_number_suppression: bool) {
213 let b = &mut self.buffer.as_mut()[..2];
214 let mut raw = u16::from_le_bytes([b[0], b[1]]);
215 raw |= (sequence_number_suppression as u16) << 8;
216 b.copy_from_slice(&raw.to_le_bytes());
217 }
218
219 pub fn set_information_elements_present(&mut self, information_elements_present: bool) {
221 let b = &mut self.buffer.as_mut()[..2];
222 let mut raw = u16::from_le_bytes([b[0], b[1]]);
223 raw |= (information_elements_present as u16) << 9;
224 b.copy_from_slice(&raw.to_le_bytes());
225 }
226
227 pub fn set_dst_addressing_mode(&mut self, addressing_mode: AddressingMode) {
229 let b = &mut self.buffer.as_mut()[..2];
230 let mut raw = u16::from_le_bytes([b[0], b[1]]);
231 raw = (raw & !(0b11 << 10)) | (((addressing_mode as u8) as u16 & 0b11) << 10);
232 b.copy_from_slice(&raw.to_le_bytes());
233 }
234
235 pub fn set_src_addressing_mode(&mut self, addressing_mode: AddressingMode) {
237 let b = &mut self.buffer.as_mut()[..2];
238 let mut raw = u16::from_le_bytes([b[0], b[1]]);
239 raw = (raw & !(0b11 << 14)) | (((addressing_mode as u8) as u16 & 0b11) << 14);
240 b.copy_from_slice(&raw.to_le_bytes());
241 }
242
243 pub fn set_frame_version(&mut self, frame_version: FrameVersion) {
245 let b = &mut self.buffer.as_mut()[..2];
246 let mut raw = u16::from_le_bytes([b[0], b[1]]);
247 raw = (raw & !(0b11 << 12)) | (((frame_version as u8) as u16 & 0b11) << 12);
248 b.copy_from_slice(&raw.to_le_bytes());
249 }
250}
251
252impl<T: AsRef<[u8]>> core::fmt::Display for FrameControl<T> {
253 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
254 writeln!(f, "Frame Control")?;
255 writeln!(f, " type: {:?}", self.frame_type())?;
256 writeln!(
257 f,
258 " security enabled: {}",
259 self.security_enabled() as usize
260 )?;
261 writeln!(f, " frame pending: {}", self.frame_pending() as usize)?;
262 writeln!(f, " ack request: {}", self.ack_request() as usize)?;
263 writeln!(
264 f,
265 " pan id compression: {}",
266 self.pan_id_compression() as usize
267 )?;
268 writeln!(
269 f,
270 " sequence number suppression: {}",
271 self.sequence_number_suppression() as usize
272 )?;
273 writeln!(
274 f,
275 " information elements present: {}",
276 self.information_elements_present() as usize
277 )?;
278 writeln!(f, " dst addressing mode: {:?}", self.dst_addressing_mode())?;
279 writeln!(f, " src addressing mode: {:?}", self.src_addressing_mode())?;
280 writeln!(f, " frame version: {:?}", self.frame_version())?;
281 Ok(())
282 }
283}
284
285#[cfg(test)]
286mod tests {
287 use super::*;
288
289 #[test]
290 fn bad_length() {
291 let fc = [0x0];
292 assert!(FrameControl::new(&fc).is_err());
293 }
294
295 #[test]
296 fn get_fields() {
297 let fc = [0x0, 0x0];
298 let fc = FrameControl::new(&fc).unwrap();
299 assert_eq!(fc.frame_type(), FrameType::Beacon);
300 assert!(!fc.security_enabled());
301 assert!(!fc.frame_pending());
302 assert!(!fc.ack_request());
303 assert!(!fc.pan_id_compression());
304 assert!(!fc.sequence_number_suppression());
305 assert!(!fc.information_elements_present());
306 assert_eq!(fc.dst_addressing_mode(), AddressingMode::Absent);
307 assert_eq!(fc.src_addressing_mode(), AddressingMode::Absent);
308 assert_eq!(fc.frame_version(), FrameVersion::Ieee802154_2003);
309
310 let fc = [0b0010_1001, 0b1010_1010];
311 let fc = FrameControl::new(&fc).unwrap();
312 assert_eq!(fc.frame_type(), FrameType::Data);
313 assert!(fc.security_enabled());
314 assert!(!fc.frame_pending());
315 assert!(fc.ack_request());
316 assert!(!fc.pan_id_compression());
317 assert!(!fc.sequence_number_suppression());
318 assert!(fc.information_elements_present());
319 assert_eq!(fc.dst_addressing_mode(), AddressingMode::Short);
320 assert_eq!(fc.src_addressing_mode(), AddressingMode::Short);
321 assert_eq!(fc.frame_version(), FrameVersion::Ieee802154_2020);
322 }
323
324 #[test]
325 fn set_fields() {
326 let mut fc = [0x0, 0x0];
327 let mut fc = FrameControl::new_unchecked(&mut fc);
328 fc.set_frame_type(FrameType::Beacon);
329 fc.set_security_enabled(false);
330 fc.set_frame_pending(false);
331 fc.set_ack_request(false);
332 fc.set_pan_id_compression(false);
333 fc.set_sequence_number_suppression(false);
334 fc.set_information_elements_present(false);
335 fc.set_dst_addressing_mode(AddressingMode::Absent);
336 fc.set_src_addressing_mode(AddressingMode::Absent);
337 fc.set_frame_version(FrameVersion::Ieee802154_2003);
338 assert_eq!(*fc.into_inner(), [0x0, 0x0]);
339
340 let mut fc = [0x0, 0x0];
341 let mut fc = FrameControl::new_unchecked(&mut fc);
342 fc.set_frame_type(FrameType::Data);
343 fc.set_security_enabled(true);
344 fc.set_frame_pending(false);
345 fc.set_ack_request(true);
346 fc.set_pan_id_compression(false);
347 fc.set_sequence_number_suppression(false);
348 fc.set_information_elements_present(true);
349 fc.set_dst_addressing_mode(AddressingMode::Short);
350 fc.set_src_addressing_mode(AddressingMode::Short);
351 fc.set_frame_version(FrameVersion::Ieee802154_2020);
352 assert_eq!(*fc.into_inner(), [0b0010_1001, 0b1010_1010]);
353 }
354
355 #[test]
356 fn frame_type() {
357 assert_eq!(FrameType::from(0b000), FrameType::Beacon);
358 assert_eq!(FrameType::from(0b001), FrameType::Data);
359 assert_eq!(FrameType::from(0b010), FrameType::Ack);
360 assert_eq!(FrameType::from(0b011), FrameType::MacCommand);
361 assert_eq!(FrameType::from(0b101), FrameType::Multipurpose);
362 assert_eq!(FrameType::from(0b110), FrameType::FragmentOrFrak);
363 assert_eq!(FrameType::from(0b111), FrameType::Extended);
364 assert_eq!(FrameType::from(0b100), FrameType::Unknown);
365 }
366
367 #[test]
368 fn frame_version() {
369 assert_eq!(FrameVersion::from(0b00), FrameVersion::Ieee802154_2003);
370 assert_eq!(FrameVersion::from(0b01), FrameVersion::Ieee802154_2006);
371 assert_eq!(FrameVersion::from(0b10), FrameVersion::Ieee802154_2020);
372 assert_eq!(FrameVersion::from(0b11), FrameVersion::Unknown);
373 }
374
375 #[test]
376 fn formatting() {
377 let fc = [0b0010_1001, 0b1010_1010];
378 let fc = FrameControl::new(&fc).unwrap();
379 assert_eq!(
380 format!("{}", fc),
381 r"Frame Control
382 type: Data
383 security enabled: 1
384 frame pending: 0
385 ack request: 1
386 pan id compression: 0
387 sequence number suppression: 0
388 information elements present: 1
389 dst addressing mode: Short
390 src addressing mode: Short
391 frame version: Ieee802154_2020
392"
393 );
394 }
395}