Skip to main content

ieee80211/common/
mod.rs

1use core::{mem::discriminant, time::Duration};
2
3use bitfield_struct::bitfield;
4use macro_bits::bit;
5use scroll::{
6    ctx::{MeasureWith, TryFromCtx, TryIntoCtx},
7    Endian, Pread, Pwrite,
8};
9
10mod subtypes;
11pub use subtypes::*;
12mod read_iterator;
13pub use read_iterator::*;
14mod capabilities;
15pub use capabilities::*;
16mod reason;
17pub use reason::*;
18mod status_code;
19pub use status_code::*;
20mod type_state;
21pub use type_state::*;
22mod auth_algo_num;
23pub use auth_algo_num::*;
24mod aid;
25pub use aid::*;
26mod sig;
27pub use sig::*;
28
29/// This is one **T**ime **U**nit, which equalls 1024µs.
30pub const TU: Duration = Duration::from_micros(1024);
31
32pub const IEEE_OUI: [u8; 3] = [0x00, 0x0f, 0xac];
33pub const WIFI_ALLIANCE_OUI: [u8; 3] = [0x50, 0x6f, 0x9a];
34
35#[cfg_attr(feature = "defmt", derive(defmt::Format))]
36#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
37/// The frame type of an IEEE 802.11 frame.
38pub enum FrameType {
39    Management(ManagementFrameSubtype),
40    Control(ControlFrameSubtype),
41    Data(DataFrameSubtype),
42    Unknown(u8),
43}
44impl FrameType {
45    /// Constructs the frame type from it's representation.
46    pub const fn from_bits(value: u8) -> Self {
47        let frame_type = value & bit!(0, 1);
48        let frame_subtype = (value & bit!(2, 3, 4, 5)) >> 2;
49        match frame_type {
50            0b00 => Self::Management(ManagementFrameSubtype::from_bits(frame_subtype)),
51            0b01 => Self::Control(ControlFrameSubtype::from_bits(frame_subtype)),
52            0b10 => Self::Data(DataFrameSubtype::from_bits(frame_subtype)),
53            _ => Self::Unknown(frame_subtype),
54        }
55    }
56    /// Turns the frame type into it's representation.
57    pub const fn into_bits(self) -> u8 {
58        match self {
59            FrameType::Management(subtype) => subtype.into_bits() << 2,
60            FrameType::Control(subtype) => 0b01 | (subtype.into_bits() << 2),
61            FrameType::Data(subtype) => 0b10 | (subtype.into_bits() << 2),
62            FrameType::Unknown(subtype) => 0b11 | (subtype << 2),
63        }
64    }
65    /// Check if just the frame type matches.
66    pub fn type_matches(&self, other: Self) -> bool {
67        discriminant(self) == discriminant(&other)
68    }
69    /// Checks if the frame type has a sequence control field.
70    pub const fn has_sequence_control(&self) -> bool {
71        matches!(self, FrameType::Data(_) | FrameType::Management(_))
72    }
73    /// Checks if the frame type has a second address.
74    pub const fn has_address_2(&self) -> bool {
75        match self {
76            Self::Data(_) | Self::Management(_) => true,
77            Self::Control(subtype) => subtype.has_address_2(),
78            _ => false,
79        }
80    }
81    /// Checks if the frame type has a third address.
82    pub const fn has_address_3(&self) -> bool {
83        matches!(self, Self::Data(_) | Self::Management(_))
84    }
85}
86impl From<u16> for FrameType {
87    fn from(value: u16) -> Self {
88        Self::from_bits(value as u8)
89    }
90}
91impl From<FrameType> for u16 {
92    fn from(value: FrameType) -> Self {
93        value.into_bits() as u16
94    }
95}
96
97/// These are the flags included in the frame control field.
98#[bitfield(u8, defmt = cfg(feature = "defmt"))]
99#[derive(PartialEq, Eq, Hash)]
100pub struct FCFFlags {
101    /// This frame is going to the distribution system.
102    pub to_ds: bool,
103    /// This frame is coming from the distribution system.
104    pub from_ds: bool,
105    /// This frame was fragmented and more are following.
106    pub more_fragments: bool,
107    /// This frame is a retransmission.
108    pub retry: bool,
109    // TODO: Docs
110    pub pwr_mgmt: bool,
111    // TODO: Docs
112    pub more_data: bool,
113    /// This frames contents are encrypted.
114    pub protected: bool,
115    // TODO: Docs
116    pub order: bool,
117}
118#[bitfield(u16, defmt = cfg(feature = "defmt"))]
119#[derive(PartialEq, Eq, Hash)]
120/// This is the frame control field, which is at the beginning of every frame.
121pub struct FrameControlField {
122    #[bits(2)]
123    pub version: u8,
124    #[bits(6)]
125    pub frame_type: FrameType,
126    #[bits(8)]
127    pub flags: FCFFlags,
128}
129#[bitfield(u16, defmt = cfg(feature = "defmt"))]
130#[derive(PartialEq, Eq, Hash)]
131/// This is information about the sequence number and the potential fragment number.
132pub struct SequenceControl {
133    #[bits(4)]
134    pub fragment_number: u8,
135    #[bits(12)]
136    pub sequence_number: u16,
137}
138
139#[cfg_attr(feature = "defmt", derive(defmt::Format))]
140#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, Hash)]
141/// An empty type, used for filling empty generics.
142pub struct Empty;
143impl<'a> TryFromCtx<'a> for Empty {
144    type Error = scroll::Error;
145    fn try_from_ctx(_: &'a [u8], _: ()) -> Result<(Self, usize), Self::Error> {
146        Ok((Self, 0))
147    }
148}
149impl MeasureWith<()> for Empty {
150    fn measure_with(&self, _: &()) -> usize {
151        0
152    }
153}
154impl TryIntoCtx for Empty {
155    type Error = scroll::Error;
156    fn try_into_ctx(self, _: &mut [u8], _: ()) -> Result<usize, Self::Error> {
157        Ok(0)
158    }
159}
160
161pub(crate) fn strip_and_validate_fcs(bytes: &[u8]) -> Result<&[u8], scroll::Error> {
162    let (slice_without_fcs, fcs) = bytes.split_at(bytes.len() - 4);
163    if fcs.pread_with::<u32>(0, Endian::Little)? == crc32fast::hash(slice_without_fcs) {
164        Ok(slice_without_fcs)
165    } else {
166        Err(scroll::Error::BadInput {
167            size: 0,
168            msg: "FCS check failed.",
169        })
170    }
171}
172
173pub(crate) fn attach_fcs(buf: &mut [u8], offset: &mut usize) -> Result<usize, scroll::Error> {
174    let fcs = crc32fast::hash(&buf[..*offset]);
175    buf.gwrite_with(fcs, offset, Endian::Little)
176}