ieee80211/frames/mgmt_frame/
header.rs1use mac_parser::MACAddress;
2use scroll::{
3 ctx::{TryFromCtx, TryIntoCtx},
4 Endian, Pread, Pwrite,
5};
6
7use crate::common::{FCFFlags, SequenceControl};
8
9#[cfg_attr(feature = "defmt", derive(defmt::Format))]
10#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
11pub struct ManagementFrameHeader {
13 pub fcf_flags: FCFFlags,
15 pub duration: u16,
16 pub receiver_address: MACAddress,
18 pub transmitter_address: MACAddress,
20 pub bssid: MACAddress,
23 pub sequence_control: SequenceControl,
24 pub ht_control: Option<[u8; 4]>,
25}
26impl ManagementFrameHeader {
27 pub const fn length_in_bytes(&self) -> usize {
28 let mut size = 2 + 2 + 6 + 6 + 6 + 2;
29 if self.ht_control.is_some() {
30 size += 4;
31 }
32 size
33 }
34}
35impl TryFromCtx<'_, FCFFlags> for ManagementFrameHeader {
36 type Error = scroll::Error;
37 fn try_from_ctx(from: &'_ [u8], fcf_flags: FCFFlags) -> Result<(Self, usize), Self::Error> {
38 let mut offset = 0;
39
40 let duration = from.gread_with(&mut offset, Endian::Little)?;
41 let receiver_address = from.gread(&mut offset)?;
42 let transmitter_address = from.gread(&mut offset)?;
43 let bssid = from.gread(&mut offset)?;
44 let frag_seq_info =
45 SequenceControl::from_bits(from.gread_with(&mut offset, Endian::Little)?);
46 let ht_control = if fcf_flags.order() {
47 Some(from.gread(&mut offset)?)
48 } else {
49 None
50 };
51 Ok((
52 Self {
53 fcf_flags,
54 duration,
55 receiver_address,
56 transmitter_address,
57 bssid,
58 sequence_control: frag_seq_info,
59 ht_control,
60 },
61 offset,
62 ))
63 }
64}
65impl TryIntoCtx for ManagementFrameHeader {
66 type Error = scroll::Error;
67 fn try_into_ctx(self, buf: &mut [u8], _ctx: ()) -> Result<usize, Self::Error> {
68 let mut offset = 0;
69
70 buf.gwrite_with(self.duration, &mut offset, Endian::Little)?;
71 buf.gwrite(self.receiver_address, &mut offset)?;
72 buf.gwrite(self.transmitter_address, &mut offset)?;
73 buf.gwrite(self.bssid, &mut offset)?;
74 buf.gwrite_with(
75 self.sequence_control.into_bits(),
76 &mut offset,
77 Endian::Little,
78 )?;
79 if let Some(ht_control) = self.ht_control {
80 buf.gwrite(ht_control, &mut offset)?;
81 }
82
83 Ok(offset)
84 }
85}