use crate::mac::{
Aid, FrameControl, HtControl, MacAddr, OptionalField, Presence, ReasonCode, SequenceControl,
StatusCode,
};
use crate::TimeUnit;
use wlan_bitfield::bitfield;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
#[bitfield(
0 ess,
1 ibss,
2 cf_pollable,
3 cf_poll_req,
4 privacy,
5 short_preamble,
6..=7 _, 8 spectrum_mgmt,
9 qos,
10 short_slot_time,
11 apsd,
12 radio_measurement,
13 _, 14 delayed_block_ack,
15 immediate_block_ack,
)]
#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Clone, Copy, Hash)]
#[repr(C)]
pub struct CapabilityInfo(pub u16);
#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, Clone, Copy, Debug, PartialEq, Eq)]
#[repr(C)]
pub struct ActionCategory(u8);
impl ActionCategory {
pub const SPECTRUM_MGMT: Self = Self(0);
pub const QOS: Self = Self(1);
pub const DLS: Self = Self(2);
pub const BLOCK_ACK: Self = Self(3);
pub const PUBLIC: Self = Self(4);
pub const RADIO_MEASURE: Self = Self(5);
pub const FT: Self = Self(6);
pub const HT: Self = Self(7);
pub const SA_QUERY: Self = Self(8);
pub const PROTECTED_DUAL: Self = Self(9);
pub const WNM: Self = Self(10);
pub const UNPROTECTED_WNM: Self = Self(11);
pub const TDLS: Self = Self(12);
pub const MESH: Self = Self(13);
pub const MULTIHOP: Self = Self(14);
pub const SELF_PROTECTED: Self = Self(15);
pub const DMG: Self = Self(16);
pub const FST: Self = Self(18);
pub const ROBUST_AV_STREAM: Self = Self(19);
pub const UNPROTECTED_DMG: Self = Self(20);
pub const VHT: Self = Self(21);
pub const VENDOR_PROTECTED: Self = Self(126);
pub const VENDOR: Self = Self(127);
}
#[derive(
KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, PartialEq, Eq, Clone, Copy, Debug,
)]
#[repr(C, packed)]
pub struct MgmtHdr {
pub frame_ctrl: FrameControl,
pub duration: u16,
pub addr1: MacAddr,
pub addr2: MacAddr,
pub addr3: MacAddr,
pub seq_ctrl: SequenceControl,
}
impl MgmtHdr {
pub fn len(has_ht_ctrl: Presence<HtControl>) -> usize {
let mut bytes = std::mem::size_of::<MgmtHdr>();
bytes += match has_ht_ctrl {
HtControl::PRESENT => std::mem::size_of::<HtControl>(),
HtControl::ABSENT => 0,
};
bytes
}
}
#[repr(C)]
#[derive(
IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Copy, Clone, Debug, Default,
)]
pub struct AuthAlgorithmNumber(pub u16);
impl AuthAlgorithmNumber {
pub const OPEN: Self = Self(0);
pub const SHARED_KEY: Self = Self(1);
pub const FAST_BSS_TRANSITION: Self = Self(2);
pub const SAE: Self = Self(3);
pub const VENDOR_SPECIFIC: Self = Self(65535);
}
#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct BeaconHdr {
timestamp: u64, pub beacon_interval: TimeUnit,
pub capabilities: CapabilityInfo,
}
impl BeaconHdr {
pub fn new(beacon_interval: TimeUnit, capabilities: CapabilityInfo) -> Self {
Self {
timestamp: 0, beacon_interval,
capabilities,
}
}
}
#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct AuthHdr {
pub auth_alg_num: AuthAlgorithmNumber,
pub auth_txn_seq_num: u16,
pub status_code: StatusCode,
}
#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct DeauthHdr {
pub reason_code: ReasonCode,
}
#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct AssocReqHdr {
pub capabilities: CapabilityInfo,
pub listen_interval: u16,
}
#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct AssocRespHdr {
pub capabilities: CapabilityInfo,
pub status_code: StatusCode,
pub aid: Aid,
}
#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct DisassocHdr {
pub reason_code: ReasonCode,
}
#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct ProbeRespHdr {
timestamp: u64, pub beacon_interval: TimeUnit,
pub capabilities: CapabilityInfo,
}
impl ProbeRespHdr {
pub fn new(beacon_interval: TimeUnit, capabilities: CapabilityInfo) -> Self {
Self {
timestamp: 0, beacon_interval,
capabilities,
}
}
}
#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct ActionHdr {
pub action: ActionCategory,
}
#[repr(C)]
#[derive(
IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Copy, Clone, Debug, Default,
)]
pub struct BlockAckAction(pub u8);
impl BlockAckAction {
pub const ADDBA_REQUEST: Self = Self(0);
pub const ADDBA_RESPONSE: Self = Self(1);
pub const DELBA: Self = Self(2);
}
#[repr(C)]
#[derive(
IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Copy, Clone, Debug, Default,
)]
pub struct BlockAckPolicy(pub u8);
impl BlockAckPolicy {
pub const DELAYED: Self = Self(0);
pub const IMMEDIATE: Self = Self(1);
}
#[bitfield(
0 amsdu,
1..=1 policy as BlockAckPolicy(u8),
2..=5 tid,
6..=15 buffer_size,
)]
#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Clone, Copy, Default)]
#[repr(C)]
pub struct BlockAckParameters(pub u16);
#[bitfield(
0..=10 reserved,
11 initiator,
12..=15 tid,
)]
#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Clone, Copy, Default)]
#[repr(C)]
pub struct DelbaParameters(pub u16);
#[bitfield(
0..=3 fragment_number, 4..=15 starting_sequence_number,
)]
#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Clone, Copy, Default)]
#[repr(C)]
pub struct BlockAckStartingSequenceControl(pub u16);
#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct AddbaReqHdr {
pub action: BlockAckAction,
pub dialog_token: u8,
pub parameters: BlockAckParameters,
pub timeout: u16,
pub starting_sequence_control: BlockAckStartingSequenceControl,
}
#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct AddbaRespHdr {
pub action: BlockAckAction,
pub dialog_token: u8,
pub status: StatusCode,
pub parameters: BlockAckParameters,
pub timeout: u16,
}
#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct DelbaHdr {
pub action: BlockAckAction,
pub parameters: DelbaParameters,
pub reason_code: ReasonCode,
}
#[repr(C)]
#[derive(
IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Copy, Clone, Debug, Default,
)]
pub struct SpectrumMgmtAction(pub u8);
impl SpectrumMgmtAction {
pub const MEASUREMENT_REQUEST: Self = Self(0);
pub const MEASUREMENT_REPORT: Self = Self(1);
pub const TPC_REQUEST: Self = Self(2);
pub const TPC_REPORT: Self = Self(3);
pub const CHANNEL_SWITCH_ANNOUNCEMENT: Self = Self(4);
}