wlan_common/mac/mgmt/
fields.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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// IEEE Std 802.11-2016, 9.4.1.4
14#[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   _,  // reserved
22    8       spectrum_mgmt,
23    9       qos,
24    10      short_slot_time,
25    11      apsd,
26    12      radio_measurement,
27    13      _,  // reserved
28    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// IEEE Std 802.11-2016, 9.4.1.11, Table Table 9-47
36#[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    // 17 reserved
59    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    // 22 - 125 reserved
64    pub const VENDOR_PROTECTED: Self = Self(126);
65    pub const VENDOR: Self = Self(127);
66    // 128 - 255: Error
67}
68
69// IEEE Std 802.11-2016, 9.3.3.2
70#[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    /// Returns the length in bytes of a mgmt header including all its fixed and optional
85    /// fields (if they are present).
86    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// IEEE Std 802.11-2016, 9.4.1.1
97#[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    // 4-65534 Reserved
109    pub const VENDOR_SPECIFIC: Self = Self(65535);
110}
111
112// IEEE Std 802.11-2016, 9.3.3.3
113#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
114#[repr(C, packed)]
115pub struct BeaconHdr {
116    // IEEE Std 802.11-2016, 9.4.1.10, 11.1.3.1, and 11.22
117    // Intentionally private until TSF timer functionality implemented.
118    timestamp: u64, // TSF timer value in increments of microseconds
119    pub beacon_interval: TimeUnit,
120    // IEEE Std 802.11-2016, 9.4.1.4
121    pub capabilities: CapabilityInfo,
122}
123
124impl BeaconHdr {
125    pub fn new(beacon_interval: TimeUnit, capabilities: CapabilityInfo) -> Self {
126        Self {
127            timestamp: 0, // always 0 since TSF Timer not implemented
128            beacon_interval,
129            capabilities,
130        }
131    }
132}
133
134// IEEE Std 802.11-2016, 9.3.3.12
135#[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// IEEE Std 802.11-2016, 9.3.3.13
144#[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// IEEE Std 802.11-2016, 9.3.3.6
151#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
152#[repr(C, packed)]
153pub struct AssocReqHdr {
154    // IEEE Std 802.11-2016, 9.4.1.4
155    pub capabilities: CapabilityInfo,
156    pub listen_interval: u16,
157}
158
159// IEEE Std 802.11-2016, 9.3.3.7
160#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
161#[repr(C, packed)]
162pub struct AssocRespHdr {
163    // IEEE Std 802.11-2016, 9.4.1.4
164    pub capabilities: CapabilityInfo,
165    pub status_code: StatusCode,
166    pub aid: Aid,
167}
168
169// IEEE Std 802.11-2016, 9.3.3.5
170#[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// IEEE Std 802.11-2016, 9.3.3.11
177#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
178#[repr(C, packed)]
179pub struct ProbeRespHdr {
180    // IEEE Std 802.11-2016, 9.4.1.10, 11.1.3.1, and 11.22
181    // Intentionally private until TSF timer functionality implemented.
182    timestamp: u64, // TSF timer value in increments of microseconds
183    pub beacon_interval: TimeUnit,
184    // IEEE Std 802.11-2016, 9.4.1.4
185    pub capabilities: CapabilityInfo,
186}
187
188impl ProbeRespHdr {
189    pub fn new(beacon_interval: TimeUnit, capabilities: CapabilityInfo) -> Self {
190        Self {
191            timestamp: 0, // always 0 since TSF Timer not implemented
192            beacon_interval,
193            capabilities,
194        }
195    }
196}
197
198// IEEE Std 802.11-2016, 9.3.3.14
199#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
200#[repr(C, packed)]
201pub struct ActionHdr {
202    pub action: ActionCategory,
203}
204
205// IEEE Std 802.11-2016, 9.6.5.1
206#[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// IEEE Std 802.11-2016, 9.4.1.14
219#[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// IEEE Std 802.11-2016, 9.4.1.14
231#[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// IEEE Std 802.11-2016, 9.4.1.16
242#[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// IEEE Std 802.11-2016, 9.6.5.2 & Figure 9-28
252#[bitfield(
253    0..=3  fragment_number, // Always set to 0 (IEEE Std 802.11-2016, 9.6.5.2)
254    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// IEEE Std 802.11-2016, 9.6.5.2 - ADDBA stands for Add BlockAck.
261#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
262#[repr(C, packed)]
263pub struct AddbaReqHdr {
264    pub action: BlockAckAction,
265    // IEEE Std 802.11-2016, 9.4.1.12 - This is a numeric value.
266    pub dialog_token: u8,
267    pub parameters: BlockAckParameters,
268    // IEEE Std 802.11-2016, 9.4.1.15 - unit is TU, 0 disables the timeout.
269    pub timeout: u16,
270    pub starting_sequence_control: BlockAckStartingSequenceControl,
271    // TODO(https://fxbug.dev/42104687): Evaluate the use cases and support optional fields.
272    // GCR Group Address element
273    // Multi-band
274    // TCLAS
275    // ADDBA Extension
276}
277
278// IEEE Std 802.11-2016, 9.6.5.3 - ADDBA stands for Add BlockAck.
279#[derive(Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, Clone, Copy, Debug)]
280#[repr(C, packed)]
281pub struct AddbaRespHdr {
282    pub action: BlockAckAction,
283    // IEEE Std 802.11-2016, 9.4.1.12 - This is a numeric value.
284    pub dialog_token: u8,
285    pub status: StatusCode,
286    pub parameters: BlockAckParameters,
287    // IEEE Std 802.11-2016, 9.4.1.15 - unit is TU, 0 disables the timeout.
288    pub timeout: u16,
289    // TODO(https://fxbug.dev/42104687): Evaluate the use cases and support optional fields.
290    // GCR Group Address element
291    // Multi-band
292    // TCLAS
293    // ADDBA Extension
294}
295
296// IEEE Std 802.11-2016, 9.6.5.4 - DELBA stands for Delete BlockAck.
297#[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    // TODO(https://fxbug.dev/42104687): Evaluate the use cases and support optional fields.
304    // GCR Group Address element
305    // Multi-band
306    // TCLAS
307}
308
309// IEEE Std 802.11-2016, 9.6.2.1
310#[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}