wlan_common/ie/
fake_ies.rs

1// Copyright 2021 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::append::BufferTooSmall;
6use crate::ie::rsn::rsne::Rsne;
7use crate::ie::rsn::{akm, cipher};
8use crate::ie::wpa::WpaIe;
9use crate::ie::wsc::{ProbeRespWsc, WpsState};
10use crate::ie::*;
11use crate::organization::Oui;
12
13pub fn fake_ht_cap_chanwidth(chanwidth: ChanWidthSet) -> HtCapabilities {
14    let mut ht_cap = fake_ht_capabilities();
15    ht_cap.ht_cap_info = ht_cap.ht_cap_info.with_chan_width_set(chanwidth);
16    ht_cap
17}
18
19pub fn fake_ht_op_sec_offset(secondary_offset: SecChanOffset) -> HtOperation {
20    let mut ht_op = fake_ht_operation();
21    ht_op.ht_op_info.set_secondary_chan_offset(secondary_offset);
22    ht_op
23}
24
25fn fake_supported_mcs_set() -> SupportedMcsSet {
26    SupportedMcsSet(0)
27        .with_rx_mcs(RxMcsBitmask(0x01000000ff))
28        .with_rx_highest_rate(0)
29        .with_tx_set_defined(true)
30        .with_tx_rx_diff(false)
31        .with_tx_max_ss(NumSpatialStreams::from_human(1).unwrap())
32        .with_tx_ueqm(false)
33}
34
35pub fn fake_ht_capabilities() -> HtCapabilities {
36    HtCapabilities {
37        ht_cap_info: HtCapabilityInfo(0)
38            .with_chan_width_set(ChanWidthSet::TWENTY_FORTY)
39            .with_sm_power_save(SmPowerSave::DISABLED)
40            .with_greenfield(true)
41            .with_short_gi_20(true)
42            .with_short_gi_40(true)
43            .with_tx_stbc(true)
44            .with_rx_stbc(1),
45        ampdu_params: AmpduParams(0),
46        mcs_set: fake_supported_mcs_set(),
47        ht_ext_cap: HtExtCapabilities(0),
48        txbf_cap: TxBfCapability(0)
49            .with_csi_antennas(NumAntennas::from_human(1).unwrap())
50            .with_noncomp_steering_ants(NumAntennas::from_human(1).unwrap())
51            .with_comp_steering_ants(NumAntennas::from_human(1).unwrap())
52            .with_csi_rows(NumCsiRows::from_human(1).unwrap())
53            .with_chan_estimation(NumSpaceTimeStreams::from_human(1).unwrap()),
54        asel_cap: AselCapability(0),
55    }
56}
57
58pub fn fake_ht_operation() -> HtOperation {
59    HtOperation {
60        primary_channel: 36,
61        ht_op_info: HtOpInfo::new()
62            .with_secondary_chan_offset(SecChanOffset::SECONDARY_ABOVE)
63            .with_sta_chan_width(StaChanWidth::ANY)
64            .with_rifs_mode_permitted(false)
65            .with_ht_protection(HtProtection::NONE)
66            .with_nongreenfield_present(true)
67            .with_obss_non_ht_stas_present(true)
68            .with_center_freq_seg2(0)
69            .with_dual_beacon(false)
70            .with_dual_cts_protection(false)
71            .with_stbc_beacon(false)
72            .with_lsig_txop_protection(false)
73            .with_pco_active(false)
74            .with_pco_phase(PcoPhase::TWENTY_MHZ),
75        basic_ht_mcs_set: fake_supported_mcs_set(),
76    }
77}
78
79pub fn fake_vht_capabilities() -> VhtCapabilities {
80    VhtCapabilities {
81        vht_cap_info: VhtCapabilitiesInfo(0)
82            .with_max_mpdu_len(MaxMpduLen::OCTECTS_7991)
83            .with_supported_cbw_set(0)
84            .with_rx_ldpc(true)
85            .with_sgi_cbw80(true)
86            .with_sgi_cbw160(false)
87            .with_tx_stbc(true)
88            .with_rx_stbc(2)
89            .with_su_bfer(false)
90            .with_su_bfee(false)
91            .with_bfee_sts(0)
92            .with_num_sounding(0)
93            .with_mu_bfer(false)
94            .with_mu_bfee(false)
95            .with_txop_ps(false)
96            .with_htc_vht(false)
97            .with_max_ampdu_exponent(MaxAmpduExponent(2))
98            .with_link_adapt(VhtLinkAdaptation::NO_FEEDBACK)
99            .with_rx_ant_pattern(true)
100            .with_tx_ant_pattern(true)
101            .with_ext_nss_bw(2),
102        vht_mcs_nss: VhtMcsNssSet(0)
103            .with_rx_max_mcs_raw(0x0001020300010203)
104            .with_rx_max_data_rate(867)
105            .with_max_nsts(2)
106            .with_tx_max_mcs_raw(0x0001020300010203)
107            .with_tx_max_data_rate(867)
108            .with_ext_nss_bw(false),
109    }
110}
111
112pub fn fake_vht_operation() -> VhtOperation {
113    VhtOperation {
114        vht_cbw: VhtChannelBandwidth::CBW_80_160_80P80,
115        center_freq_seg0: 42,
116        center_freq_seg1: 0,
117        basic_mcs_nss: VhtMcsNssMap(0x1b1b),
118    }
119}
120
121pub fn fake_ht_cap_bytes() -> [u8; std::mem::size_of::<HtCapabilities>()] {
122    // Safe to unwrap because the size matches the IE.
123    fake_ht_capabilities().as_bytes().try_into().unwrap()
124}
125
126pub fn fake_ht_op_bytes() -> [u8; std::mem::size_of::<HtOperation>()] {
127    // Safe to unwrap because the size matches the IE.
128    fake_ht_operation().as_bytes().try_into().unwrap()
129}
130
131pub fn fake_vht_cap_bytes() -> [u8; std::mem::size_of::<VhtCapabilities>()] {
132    // Safe to unwrap because the size matches the IE.
133    fake_vht_capabilities().as_bytes().try_into().unwrap()
134}
135
136pub fn fake_vht_op_bytes() -> [u8; std::mem::size_of::<VhtOperation>()] {
137    // Safe to unwrap because the size matches the IE.
138    fake_vht_operation().as_bytes().try_into().unwrap()
139}
140
141pub fn fake_wpa_ie() -> WpaIe {
142    WpaIe {
143        unicast_cipher_list: vec![cipher::Cipher { oui: Oui::MSFT, suite_type: cipher::TKIP }],
144        akm_list: vec![akm::Akm { oui: Oui::MSFT, suite_type: akm::PSK }],
145        multicast_cipher: cipher::Cipher { oui: Oui::MSFT, suite_type: cipher::TKIP },
146    }
147}
148
149pub fn get_vendor_ie_bytes_for_wpa_ie(wpa_ie: &WpaIe) -> Result<Vec<u8>, BufferTooSmall> {
150    let mut buf = vec![];
151    write_wpa1_ie(&mut buf, &wpa_ie).map(|_| buf)
152}
153
154pub fn get_rsn_ie_bytes(rsne: &Rsne) -> Vec<u8> {
155    let mut buf = Vec::with_capacity(rsne.len());
156    rsne.write_into(&mut buf).expect("error writing RSNE into buffer");
157    buf
158}
159
160// The returned ProbeRespWsc corresponds to the bytes returned by
161// fake_probe_resp_wsc_ie_bytes().
162pub fn fake_probe_resp_wsc_ie() -> ProbeRespWsc {
163    ProbeRespWsc {
164        version: 0x10,
165        wps_state: WpsState::CONFIGURED,
166        ap_setup_locked: true,
167        selected_reg: false,
168        selected_reg_config_methods: None,
169        response_type: 0x03,
170        uuid_e: [
171            0x3b, 0x3b, 0xe3, 0x66, 0x80, 0x84, 0x4b, 0x03, 0xbb, 0x66, 0x45, 0x2a, 0xf3, 0x00,
172            0x59, 0x22,
173        ],
174        manufacturer: b"ASUSTek Computer Inc.".to_vec(),
175        model_name: b"RT-AC58U".to_vec(),
176        model_number: b"123".to_vec(),
177        serial_number: b"12345".to_vec(),
178        primary_device_type: [0x00, 0x06, 0x00, 0x50, 0xf2, 0x04, 0x00, 0x01],
179        device_name: b"ASUS Router".to_vec(),
180        config_methods: [0x20, 0x0c],
181        rf_bands: None,
182        vendor_ext: vec![0x00, 0x37, 0x2a, 0x00, 0x01, 0x20],
183    }
184}
185
186// The bytes returned correspond to the ProbeRespWsc returned by
187// fake_probe_resp_wsc_ie().
188pub fn fake_probe_resp_wsc_ie_bytes() -> Vec<u8> {
189    #[rustfmt::skip]
190    let bytes = vec![
191        0x10, 0x4a, 0x00, 0x01, 0x10, // Version
192        0x10, 0x44, 0x00, 0x01, 0x02, // WiFi Protected Setup State
193        0x10, 0x57, 0x00, 0x01, 0x01, // AP Setup Locked
194        0x10, 0x3b, 0x00, 0x01, 0x03, // Response Type
195        // UUID-E
196        0x10, 0x47, 0x00, 0x10,
197        0x3b, 0x3b, 0xe3, 0x66, 0x80, 0x84, 0x4b, 0x03,
198        0xbb, 0x66, 0x45, 0x2a, 0xf3, 0x00, 0x59, 0x22,
199        // Manufacturer
200        0x10, 0x21, 0x00, 0x15,
201        0x41, 0x53, 0x55, 0x53, 0x54, 0x65, 0x6b, 0x20, 0x43, 0x6f, 0x6d, 0x70,
202        0x75, 0x74, 0x65, 0x72, 0x20, 0x49, 0x6e, 0x63, 0x2e,
203        // Model name
204        0x10, 0x23, 0x00, 0x08, 0x52, 0x54, 0x2d, 0x41, 0x43, 0x35, 0x38, 0x55,
205        // Model number
206        0x10, 0x24, 0x00, 0x03, 0x31, 0x32, 0x33,
207        // Serial number
208        0x10, 0x42, 0x00, 0x05, 0x31, 0x32, 0x33, 0x34, 0x35,
209        // Primary device type
210        0x10, 0x54, 0x00, 0x08, 0x00, 0x06, 0x00, 0x50, 0xf2, 0x04, 0x00, 0x01,
211        // Device name
212        0x10, 0x11, 0x00, 0x0b,
213        0x41, 0x53, 0x55, 0x53, 0x20, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72,
214        // Config methods
215        0x10, 0x08, 0x00, 0x02, 0x20, 0x0c,
216        // Vendor extension
217        0x10, 0x49, 0x00, 0x06, 0x00, 0x37, 0x2a, 0x00, 0x01, 0x20,
218    ];
219    bytes
220}
221
222pub fn get_vendor_ie_bytes_for_wsc_ie(wsc_ie_bytes: &[u8]) -> Result<Vec<u8>, BufferTooSmall> {
223    let mut buf = vec![];
224    write_wsc_ie(&mut buf, &wsc_ie_bytes).map(|_| buf)
225}
226
227pub fn fake_wmm_param() -> WmmParam {
228    WmmParam {
229        wmm_info: WmmInfo(0).with_ap_wmm_info(ApWmmInfo(0).with_uapsd(true)),
230        _reserved: 0,
231        ac_be_params: WmmAcParams {
232            aci_aifsn: WmmAciAifsn(0).with_aifsn(3).with_aci(0),
233            ecw_min_max: EcwMinMax(0).with_ecw_min(4).with_ecw_max(10),
234            txop_limit: 0,
235        },
236        ac_bk_params: WmmAcParams {
237            aci_aifsn: WmmAciAifsn(0).with_aifsn(7).with_aci(1),
238            ecw_min_max: EcwMinMax(0).with_ecw_min(4).with_ecw_max(10),
239            txop_limit: 0,
240        },
241        ac_vi_params: WmmAcParams {
242            aci_aifsn: WmmAciAifsn(0).with_aifsn(2).with_aci(2),
243            ecw_min_max: EcwMinMax(0).with_ecw_min(3).with_ecw_max(4),
244            txop_limit: 94,
245        },
246        ac_vo_params: WmmAcParams {
247            aci_aifsn: WmmAciAifsn(0).with_aifsn(2).with_aci(3),
248            ecw_min_max: EcwMinMax(0).with_ecw_min(2).with_ecw_max(3),
249            txop_limit: 47,
250        },
251    }
252}