1use crate::mac::{
6 Aid, FrameControl, HtControl, MacAddr, OptionalField, Presence, ReasonCode, SequenceControl,
7 StatusCode,
8};
9use crate::TimeUnit;
10use wlan_bitfield::bitfield;
11use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
12
13#[bitfield(
15 0 ess,
16 1 ibss,
17 2 cf_pollable,
18 3 cf_poll_req,
19 4 privacy,
20 5 short_preamble,
21 6..=7 _, 8 spectrum_mgmt,
23 9 qos,
24 10 short_slot_time,
25 11 apsd,
26 12 radio_measurement,
27 13 _, 14 delayed_block_ack,
29 15 immediate_block_ack,
30)]
31#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Clone, Copy, Hash)]
32#[repr(C)]
33pub struct CapabilityInfo(pub u16);
34
35#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, Clone, Copy, Debug, PartialEq, Eq)]
37#[repr(C)]
38pub struct ActionCategory(u8);
39
40impl ActionCategory {
41 pub const SPECTRUM_MGMT: Self = Self(0);
42 pub const QOS: Self = Self(1);
43 pub const DLS: Self = Self(2);
44 pub const BLOCK_ACK: Self = Self(3);
45 pub const PUBLIC: Self = Self(4);
46 pub const RADIO_MEASURE: Self = Self(5);
47 pub const FT: Self = Self(6);
48 pub const HT: Self = Self(7);
49 pub const SA_QUERY: Self = Self(8);
50 pub const PROTECTED_DUAL: Self = Self(9);
51 pub const WNM: Self = Self(10);
52 pub const UNPROTECTED_WNM: Self = Self(11);
53 pub const TDLS: Self = Self(12);
54 pub const MESH: Self = Self(13);
55 pub const MULTIHOP: Self = Self(14);
56 pub const SELF_PROTECTED: Self = Self(15);
57 pub const DMG: Self = Self(16);
58 pub const FST: Self = Self(18);
60 pub const ROBUST_AV_STREAM: Self = Self(19);
61 pub const UNPROTECTED_DMG: Self = Self(20);
62 pub const VHT: Self = Self(21);
63 pub const VENDOR_PROTECTED: Self = Self(126);
65 pub const VENDOR: Self = Self(127);
66 }
68
69#[derive(
71 KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, PartialEq, Eq, Clone, Copy, Debug,
72)]
73#[repr(C, packed)]
74pub struct MgmtHdr {
75 pub frame_ctrl: FrameControl,
76 pub duration: u16,
77 pub addr1: MacAddr,
78 pub addr2: MacAddr,
79 pub addr3: MacAddr,
80 pub seq_ctrl: SequenceControl,
81}
82
83impl MgmtHdr {
84 pub fn len(has_ht_ctrl: Presence<HtControl>) -> usize {
87 let mut bytes = std::mem::size_of::<MgmtHdr>();
88 bytes += match has_ht_ctrl {
89 HtControl::PRESENT => std::mem::size_of::<HtControl>(),
90 HtControl::ABSENT => 0,
91 };
92 bytes
93 }
94}
95
96#[repr(C)]
98#[derive(
99 IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Copy, Clone, Debug, Default,
100)]
101pub struct AuthAlgorithmNumber(pub u16);
102
103impl AuthAlgorithmNumber {
104 pub const OPEN: Self = Self(0);
105 pub const SHARED_KEY: Self = Self(1);
106 pub const FAST_BSS_TRANSITION: Self = Self(2);
107 pub const SAE: Self = Self(3);
108 pub const VENDOR_SPECIFIC: Self = Self(65535);
110}
111
112#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
114#[repr(C, packed)]
115pub struct BeaconHdr {
116 timestamp: u64, pub beacon_interval: TimeUnit,
120 pub capabilities: CapabilityInfo,
122}
123
124impl BeaconHdr {
125 pub fn new(beacon_interval: TimeUnit, capabilities: CapabilityInfo) -> Self {
126 Self {
127 timestamp: 0, beacon_interval,
129 capabilities,
130 }
131 }
132}
133
134#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
136#[repr(C, packed)]
137pub struct AuthHdr {
138 pub auth_alg_num: AuthAlgorithmNumber,
139 pub auth_txn_seq_num: u16,
140 pub status_code: StatusCode,
141}
142
143#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
145#[repr(C, packed)]
146pub struct DeauthHdr {
147 pub reason_code: ReasonCode,
148}
149
150#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
152#[repr(C, packed)]
153pub struct AssocReqHdr {
154 pub capabilities: CapabilityInfo,
156 pub listen_interval: u16,
157}
158
159#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
161#[repr(C, packed)]
162pub struct AssocRespHdr {
163 pub capabilities: CapabilityInfo,
165 pub status_code: StatusCode,
166 pub aid: Aid,
167}
168
169#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
171#[repr(C, packed)]
172pub struct DisassocHdr {
173 pub reason_code: ReasonCode,
174}
175
176#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
178#[repr(C, packed)]
179pub struct ProbeRespHdr {
180 timestamp: u64, pub beacon_interval: TimeUnit,
184 pub capabilities: CapabilityInfo,
186}
187
188impl ProbeRespHdr {
189 pub fn new(beacon_interval: TimeUnit, capabilities: CapabilityInfo) -> Self {
190 Self {
191 timestamp: 0, beacon_interval,
193 capabilities,
194 }
195 }
196}
197
198#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
200#[repr(C, packed)]
201pub struct ActionHdr {
202 pub action: ActionCategory,
203}
204
205#[repr(C)]
207#[derive(
208 IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Copy, Clone, Debug, Default,
209)]
210pub struct BlockAckAction(pub u8);
211
212impl BlockAckAction {
213 pub const ADDBA_REQUEST: Self = Self(0);
214 pub const ADDBA_RESPONSE: Self = Self(1);
215 pub const DELBA: Self = Self(2);
216}
217
218#[repr(C)]
220#[derive(
221 IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Copy, Clone, Debug, Default,
222)]
223pub struct BlockAckPolicy(pub u8);
224
225impl BlockAckPolicy {
226 pub const DELAYED: Self = Self(0);
227 pub const IMMEDIATE: Self = Self(1);
228}
229
230#[bitfield(
232 0 amsdu,
233 1..=1 policy as BlockAckPolicy(u8),
234 2..=5 tid,
235 6..=15 buffer_size,
236)]
237#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Clone, Copy, Default)]
238#[repr(C)]
239pub struct BlockAckParameters(pub u16);
240
241#[bitfield(
243 0..=10 reserved,
244 11 initiator,
245 12..=15 tid,
246)]
247#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Clone, Copy, Default)]
248#[repr(C)]
249pub struct DelbaParameters(pub u16);
250
251#[bitfield(
253 0..=3 fragment_number, 4..=15 starting_sequence_number,
255)]
256#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Clone, Copy, Default)]
257#[repr(C)]
258pub struct BlockAckStartingSequenceControl(pub u16);
259
260#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
262#[repr(C, packed)]
263pub struct AddbaReqHdr {
264 pub action: BlockAckAction,
265 pub dialog_token: u8,
267 pub parameters: BlockAckParameters,
268 pub timeout: u16,
270 pub starting_sequence_control: BlockAckStartingSequenceControl,
271 }
277
278#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
280#[repr(C, packed)]
281pub struct AddbaRespHdr {
282 pub action: BlockAckAction,
283 pub dialog_token: u8,
285 pub status: StatusCode,
286 pub parameters: BlockAckParameters,
287 pub timeout: u16,
289 }
295
296#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
298#[repr(C, packed)]
299pub struct DelbaHdr {
300 pub action: BlockAckAction,
301 pub parameters: DelbaParameters,
302 pub reason_code: ReasonCode,
303 }
308
309#[repr(C)]
311#[derive(
312 IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Eq, Copy, Clone, Debug, Default,
313)]
314pub struct SpectrumMgmtAction(pub u8);
315
316impl SpectrumMgmtAction {
317 pub const MEASUREMENT_REQUEST: Self = Self(0);
318 pub const MEASUREMENT_REPORT: Self = Self(1);
319 pub const TPC_REQUEST: Self = Self(2);
320 pub const TPC_REPORT: Self = Self(3);
321 pub const CHANNEL_SWITCH_ANNOUNCEMENT: Self = Self(4);
322}