1use anyhow::{bail, Result};
6use fidl_fuchsia_wlan_ieee80211::MAX_SSID_BYTE_LEN;
7use {
8 fidl_fuchsia_wlan_common as fidl_common, fidl_fuchsia_wlan_fullmac as fidl_fullmac,
9 fidl_fuchsia_wlan_ieee80211 as fidl_ieee80211, fidl_fuchsia_wlan_mlme as fidl_mlme,
10};
11
12pub fn convert_scan_request(
13 req: fidl_mlme::ScanRequest,
14) -> Result<fidl_fullmac::WlanFullmacImplStartScanRequest> {
15 for ssid in &req.ssid_list {
16 if ssid.len() > MAX_SSID_BYTE_LEN.into() {
17 bail!(
18 "ScanRequest ssid len {} exceeds allowed meximum {}",
19 ssid.len(),
20 MAX_SSID_BYTE_LEN
21 );
22 }
23 }
24 Ok(fidl_fullmac::WlanFullmacImplStartScanRequest {
25 txn_id: Some(req.txn_id),
26 scan_type: Some(match req.scan_type {
27 fidl_mlme::ScanTypes::Active => fidl_fullmac::WlanScanType::Active,
28 fidl_mlme::ScanTypes::Passive => fidl_fullmac::WlanScanType::Passive,
29 }),
30
31 channels: Some(req.channel_list),
34 ssids: Some(req.ssid_list),
35 min_channel_time: Some(req.min_channel_time),
36 max_channel_time: Some(req.max_channel_time),
37 ..Default::default()
38 })
39}
40
41pub fn convert_connect_request(
42 req: fidl_mlme::ConnectRequest,
43) -> fidl_fullmac::WlanFullmacImplConnectRequest {
44 fidl_fullmac::WlanFullmacImplConnectRequest {
45 selected_bss: Some(req.selected_bss),
46 connect_failure_timeout: Some(req.connect_failure_timeout),
47 auth_type: Some(convert_auth_type(req.auth_type)),
48 sae_password: Some(req.sae_password),
49
50 wep_key: req.wep_key.clone().map(|key| convert_set_key_descriptor_legacy(&key)),
52 security_ie: Some(req.security_ie),
53 wep_key_desc: req.wep_key.map(|key| convert_set_key_descriptor(&key)),
54 ..Default::default()
55 }
56}
57
58pub fn convert_reconnect_request(
59 req: fidl_mlme::ReconnectRequest,
60) -> fidl_fullmac::WlanFullmacImplReconnectRequest {
61 fidl_fullmac::WlanFullmacImplReconnectRequest {
62 peer_sta_address: Some(req.peer_sta_address),
63 ..Default::default()
64 }
65}
66
67pub fn convert_roam_request(
68 req: fidl_mlme::RoamRequest,
69) -> fidl_fullmac::WlanFullmacImplRoamRequest {
70 fidl_fullmac::WlanFullmacImplRoamRequest {
71 selected_bss: Some(req.selected_bss),
72 ..Default::default()
73 }
74}
75pub fn convert_authenticate_response(
76 resp: fidl_mlme::AuthenticateResponse,
77) -> fidl_fullmac::WlanFullmacImplAuthRespRequest {
78 fidl_fullmac::WlanFullmacImplAuthRespRequest {
79 peer_sta_address: Some(resp.peer_sta_address),
80 result_code: Some(match resp.result_code {
81 fidl_mlme::AuthenticateResultCode::Success => fidl_fullmac::WlanAuthResult::Success,
82 fidl_mlme::AuthenticateResultCode::Refused => fidl_fullmac::WlanAuthResult::Refused,
83 fidl_mlme::AuthenticateResultCode::AntiCloggingTokenRequired => {
84 fidl_fullmac::WlanAuthResult::AntiCloggingTokenRequired
85 }
86 fidl_mlme::AuthenticateResultCode::FiniteCyclicGroupNotSupported => {
87 fidl_fullmac::WlanAuthResult::FiniteCyclicGroupNotSupported
88 }
89 fidl_mlme::AuthenticateResultCode::AuthenticationRejected => {
90 fidl_fullmac::WlanAuthResult::Rejected
91 }
92 fidl_mlme::AuthenticateResultCode::AuthFailureTimeout => {
93 fidl_fullmac::WlanAuthResult::FailureTimeout
94 }
95 }),
96 ..Default::default()
97 }
98}
99
100pub fn convert_deauthenticate_request(
101 req: fidl_mlme::DeauthenticateRequest,
102) -> fidl_fullmac::WlanFullmacImplDeauthRequest {
103 fidl_fullmac::WlanFullmacImplDeauthRequest {
104 peer_sta_address: Some(req.peer_sta_address),
105 reason_code: Some(req.reason_code),
106 ..Default::default()
107 }
108}
109
110pub fn convert_associate_response(
111 resp: fidl_mlme::AssociateResponse,
112) -> fidl_fullmac::WlanFullmacImplAssocRespRequest {
113 use fidl_fullmac::WlanAssocResult;
114 fidl_fullmac::WlanFullmacImplAssocRespRequest {
115 peer_sta_address: Some(resp.peer_sta_address),
116 result_code: Some(match resp.result_code {
117 fidl_mlme::AssociateResultCode::Success => WlanAssocResult::Success,
118 fidl_mlme::AssociateResultCode::RefusedReasonUnspecified => {
119 WlanAssocResult::RefusedReasonUnspecified
120 }
121 fidl_mlme::AssociateResultCode::RefusedNotAuthenticated => {
122 WlanAssocResult::RefusedNotAuthenticated
123 }
124 fidl_mlme::AssociateResultCode::RefusedCapabilitiesMismatch => {
125 WlanAssocResult::RefusedCapabilitiesMismatch
126 }
127 fidl_mlme::AssociateResultCode::RefusedExternalReason => {
128 WlanAssocResult::RefusedExternalReason
129 }
130 fidl_mlme::AssociateResultCode::RefusedApOutOfMemory => {
131 WlanAssocResult::RefusedApOutOfMemory
132 }
133 fidl_mlme::AssociateResultCode::RefusedBasicRatesMismatch => {
134 WlanAssocResult::RefusedBasicRatesMismatch
135 }
136 fidl_mlme::AssociateResultCode::RejectedEmergencyServicesNotSupported => {
137 WlanAssocResult::RejectedEmergencyServicesNotSupported
138 }
139 fidl_mlme::AssociateResultCode::RefusedTemporarily => {
140 WlanAssocResult::RefusedTemporarily
141 }
142 }),
143 association_id: Some(resp.association_id),
144 ..Default::default()
145 }
146}
147pub fn convert_disassociate_request(
148 req: fidl_mlme::DisassociateRequest,
149) -> fidl_fullmac::WlanFullmacImplDisassocRequest {
150 fidl_fullmac::WlanFullmacImplDisassocRequest {
151 peer_sta_address: Some(req.peer_sta_address),
152 reason_code: Some(req.reason_code),
153 ..Default::default()
154 }
155}
156
157pub fn convert_start_bss_request(
158 req: fidl_mlme::StartRequest,
159) -> Result<fidl_fullmac::WlanFullmacImplStartBssRequest> {
160 if let Some(rsne) = &req.rsne {
161 if rsne.len() > fidl_ieee80211::WLAN_IE_MAX_LEN as usize {
162 bail!(
163 "MLME RSNE length ({}) exceeds allowed maximum ({})",
164 rsne.len(),
165 fidl_ieee80211::WLAN_IE_BODY_MAX_LEN
166 );
167 }
168 }
169 Ok(fidl_fullmac::WlanFullmacImplStartBssRequest {
170 ssid: Some(req.ssid),
171 bss_type: Some(req.bss_type),
172 beacon_period: Some(req.beacon_period as u32),
173 dtim_period: Some(req.dtim_period as u32),
174 channel: Some(req.channel),
175 rsne: req.rsne,
176
177 vendor_ie: Some(vec![]),
179 ..Default::default()
180 })
181}
182
183pub fn convert_stop_bss_request(
184 req: fidl_mlme::StopRequest,
185) -> Result<fidl_fullmac::WlanFullmacImplStopBssRequest> {
186 if req.ssid.len() > MAX_SSID_BYTE_LEN.into() {
187 bail!(
188 "StopBssRequest ssid len {} exceeds allowed meximum {}",
189 req.ssid.len(),
190 MAX_SSID_BYTE_LEN
191 );
192 }
193 Ok(fidl_fullmac::WlanFullmacImplStopBssRequest { ssid: Some(req.ssid), ..Default::default() })
194}
195
196pub fn convert_set_keys_request(
198 req: &fidl_mlme::SetKeysRequest,
199) -> Result<fidl_fullmac::WlanFullmacImplSetKeysRequest> {
200 const MAX_NUM_KEYS: usize = fidl_fullmac::WLAN_MAX_KEYLIST_SIZE as usize;
201 if req.keylist.len() > MAX_NUM_KEYS {
202 bail!(
203 "SetKeysRequest keylist len {} exceeds allowed maximum {}",
204 req.keylist.len(),
205 MAX_NUM_KEYS
206 );
207 }
208 let keylist: Vec<_> = req.keylist.iter().map(convert_set_key_descriptor_legacy).collect();
209 let key_descriptors: Vec<_> = req.keylist.iter().map(convert_set_key_descriptor).collect();
210
211 Ok(fidl_fullmac::WlanFullmacImplSetKeysRequest {
212 keylist: Some(keylist),
213 key_descriptors: Some(key_descriptors),
214 ..Default::default()
215 })
216}
217
218pub fn convert_eapol_request(
219 req: fidl_mlme::EapolRequest,
220) -> fidl_fullmac::WlanFullmacImplEapolTxRequest {
221 fidl_fullmac::WlanFullmacImplEapolTxRequest {
222 src_addr: Some(req.src_addr),
223 dst_addr: Some(req.dst_addr),
224 data: Some(req.data),
225 ..Default::default()
226 }
227}
228
229pub fn convert_sae_handshake_response(
230 resp: fidl_mlme::SaeHandshakeResponse,
231) -> fidl_fullmac::WlanFullmacImplSaeHandshakeRespRequest {
232 fidl_fullmac::WlanFullmacImplSaeHandshakeRespRequest {
233 peer_sta_address: Some(resp.peer_sta_address),
234 status_code: Some(resp.status_code),
235 ..Default::default()
236 }
237}
238
239pub fn convert_sae_frame(frame: fidl_mlme::SaeFrame) -> fidl_fullmac::SaeFrame {
240 fidl_fullmac::SaeFrame {
241 peer_sta_address: Some(frame.peer_sta_address),
242 status_code: Some(frame.status_code),
243 seq_num: Some(frame.seq_num),
244 sae_fields: Some(frame.sae_fields),
245 ..Default::default()
246 }
247}
248
249fn convert_auth_type(mlme_auth: fidl_mlme::AuthenticationTypes) -> fidl_fullmac::WlanAuthType {
254 match mlme_auth {
255 fidl_mlme::AuthenticationTypes::OpenSystem => fidl_fullmac::WlanAuthType::OpenSystem,
256 fidl_mlme::AuthenticationTypes::SharedKey => fidl_fullmac::WlanAuthType::SharedKey,
257 fidl_mlme::AuthenticationTypes::FastBssTransition => {
258 fidl_fullmac::WlanAuthType::FastBssTransition
259 }
260 fidl_mlme::AuthenticationTypes::Sae => fidl_fullmac::WlanAuthType::Sae,
261 }
262}
263fn convert_set_key_descriptor(
264 mlme_key: &fidl_mlme::SetKeyDescriptor,
265) -> fidl_ieee80211::SetKeyDescriptor {
266 fidl_ieee80211::SetKeyDescriptor {
267 cipher_oui: Some(mlme_key.cipher_suite_oui.clone()),
268 cipher_type: Some(mlme_key.cipher_suite_type),
269 key_type: Some(convert_key_type(mlme_key.key_type)),
270 peer_addr: Some(mlme_key.address.clone()),
271 key_id: Some(mlme_key.key_id),
272 key: Some(mlme_key.key.clone()),
273 rsc: Some(mlme_key.rsc),
274 ..Default::default()
275 }
276}
277fn convert_set_key_descriptor_legacy(
278 mlme_key: &fidl_mlme::SetKeyDescriptor,
279) -> fidl_common::WlanKeyConfig {
280 fidl_common::WlanKeyConfig {
281 protection: Some(fidl_common::WlanProtection::RxTx),
284 cipher_oui: Some(mlme_key.cipher_suite_oui.clone()),
285 cipher_type: Some(mlme_key.cipher_suite_type),
286 key_type: Some(convert_key_type_legacy(mlme_key.key_type)),
287 peer_addr: Some(mlme_key.address.clone()),
288 key_idx: Some(mlme_key.key_id as u8),
289 key: Some(mlme_key.key.clone()),
290 rsc: Some(mlme_key.rsc),
291 ..Default::default()
292 }
293}
294
295fn convert_key_type(mlme_key_type: fidl_mlme::KeyType) -> fidl_ieee80211::KeyType {
296 match mlme_key_type {
297 fidl_mlme::KeyType::Group => fidl_ieee80211::KeyType::Group,
298 fidl_mlme::KeyType::Pairwise => fidl_ieee80211::KeyType::Pairwise,
299 fidl_mlme::KeyType::PeerKey => fidl_ieee80211::KeyType::Peer,
300 fidl_mlme::KeyType::Igtk => fidl_ieee80211::KeyType::Igtk,
301 }
302}
303
304fn convert_key_type_legacy(mlme_key_type: fidl_mlme::KeyType) -> fidl_common::WlanKeyType {
305 match mlme_key_type {
306 fidl_mlme::KeyType::Group => fidl_common::WlanKeyType::Group,
307 fidl_mlme::KeyType::Pairwise => fidl_common::WlanKeyType::Pairwise,
308 fidl_mlme::KeyType::PeerKey => fidl_common::WlanKeyType::Peer,
309 fidl_mlme::KeyType::Igtk => fidl_common::WlanKeyType::Igtk,
310 }
311}
312
313#[cfg(test)]
314mod tests {
315 use super::*;
316 use fidl_fuchsia_wlan_common as fidl_common;
317
318 fn fake_bss_description() -> fidl_common::BssDescription {
319 fidl_common::BssDescription {
320 bssid: [6, 5, 4, 3, 2, 1],
321 bss_type: fidl_common::BssType::Infrastructure,
322 beacon_period: 123u16,
323 capability_info: 456u16,
324 ies: vec![1, 2, 3, 4],
325 channel: fidl_common::WlanChannel {
326 primary: 112,
327 cbw: fidl_common::ChannelBandwidth::Cbw20,
328 secondary80: 45,
329 },
330 rssi_dbm: -41i8,
331 snr_db: -90i8,
332 }
333 }
334
335 fn fake_set_key_descriptor() -> fidl_mlme::SetKeyDescriptor {
336 fidl_mlme::SetKeyDescriptor {
337 key: vec![99, 100, 101, 102, 103, 14],
338 key_id: 23,
339 key_type: fidl_mlme::KeyType::Group,
340 address: [4u8; 6],
341 rsc: 123456,
342 cipher_suite_oui: [77, 88, 99],
343 cipher_suite_type: fidl_ieee80211::CipherSuiteType::Ccmp128,
344 }
345 }
346
347 #[test]
348 fn test_convert_scan_request_empty_vectors() {
349 let mlme = fidl_mlme::ScanRequest {
350 txn_id: 123,
351 scan_type: fidl_mlme::ScanTypes::Passive,
352 channel_list: vec![],
353 ssid_list: vec![],
354 probe_delay: 42,
355 min_channel_time: 10,
356 max_channel_time: 100,
357 };
358
359 assert_eq!(
360 convert_scan_request(mlme.clone()).unwrap(),
361 fidl_fullmac::WlanFullmacImplStartScanRequest {
362 txn_id: Some(123),
363 scan_type: Some(fidl_fullmac::WlanScanType::Passive),
364 channels: Some(vec![]),
365 ssids: Some(vec![]),
366 min_channel_time: Some(10),
367 max_channel_time: Some(100),
368 ..Default::default()
369 }
370 );
371 }
372
373 #[test]
374 fn test_convert_scan_request_ssid_too_long() {
375 let mlme = fidl_mlme::ScanRequest {
376 txn_id: 123,
377 scan_type: fidl_mlme::ScanTypes::Passive,
378 channel_list: vec![],
379 ssid_list: vec![vec![123; 4], vec![42; fidl_ieee80211::MAX_SSID_BYTE_LEN as usize + 1]],
380 probe_delay: 42,
381 min_channel_time: 10,
382 max_channel_time: 100,
383 };
384
385 assert!(convert_scan_request(mlme).is_err());
386 }
387
388 #[test]
389 fn test_convert_connect_request_no_wep_key() {
390 let mlme = fidl_mlme::ConnectRequest {
391 selected_bss: fake_bss_description(),
392 connect_failure_timeout: 60,
393 auth_type: fidl_mlme::AuthenticationTypes::OpenSystem,
394 sae_password: vec![10, 11, 12, 13, 14],
395 wep_key: None,
396 security_ie: vec![44, 55, 66],
397 };
398
399 assert_eq!(
400 convert_connect_request(mlme.clone()),
401 fidl_fullmac::WlanFullmacImplConnectRequest {
402 selected_bss: Some(mlme.selected_bss.clone()),
403 connect_failure_timeout: Some(60),
404 auth_type: Some(fidl_fullmac::WlanAuthType::OpenSystem),
405 sae_password: Some(vec![10, 11, 12, 13, 14]),
406 security_ie: Some(vec![44, 55, 66]),
407 ..Default::default()
408 }
409 );
410 }
411
412 #[test]
413 fn test_convert_connect_request_empty_vectors() {
414 let mlme = fidl_mlme::ConnectRequest {
415 selected_bss: fake_bss_description(),
416 connect_failure_timeout: 60,
417 auth_type: fidl_mlme::AuthenticationTypes::OpenSystem,
418 sae_password: vec![],
419 wep_key: None,
420 security_ie: vec![],
421 };
422
423 assert_eq!(
424 convert_connect_request(mlme.clone()),
425 fidl_fullmac::WlanFullmacImplConnectRequest {
426 selected_bss: Some(mlme.selected_bss.clone()),
427 connect_failure_timeout: Some(60),
428 auth_type: Some(fidl_fullmac::WlanAuthType::OpenSystem),
429 sae_password: Some(vec![]),
430 security_ie: Some(vec![]),
431 ..Default::default()
432 }
433 );
434 }
435
436 #[test]
437 fn test_convert_start_bss_request_rsne_too_long() {
438 let mlme = fidl_mlme::StartRequest {
439 ssid: vec![1, 2, 3, 4],
440 bss_type: fidl_common::BssType::Independent,
441 beacon_period: 10000,
442 dtim_period: 123,
443 channel: 12,
444 capability_info: 4321,
445 rates: vec![10, 20, 30, 40],
446 country: fidl_mlme::Country { alpha2: [1, 2], suffix: 45 },
447 mesh_id: vec![6, 5, 6, 5],
448 rsne: Some(vec![123; fidl_ieee80211::WLAN_IE_MAX_LEN as usize + 1]),
449 phy: fidl_common::WlanPhyType::Ofdm,
450 channel_bandwidth: fidl_common::ChannelBandwidth::Cbw20,
451 };
452
453 assert!(convert_start_bss_request(mlme).is_err());
454 }
455
456 #[test]
457 fn test_convert_stop_bss_request_ssid_too_long() {
458 let mlme = fidl_mlme::StopRequest {
459 ssid: vec![42; fidl_ieee80211::MAX_SSID_BYTE_LEN as usize + 1],
460 };
461 assert!(convert_stop_bss_request(mlme).is_err());
462 }
463
464 #[test]
465 fn test_convert_set_keys_request() {
466 let mlme = fidl_mlme::SetKeysRequest { keylist: vec![fake_set_key_descriptor(); 2] };
467
468 let fullmac = convert_set_keys_request(&mlme).unwrap();
469
470 assert_eq!(fullmac.keylist.as_ref().unwrap().len(), 2);
471 let keylist = fullmac.keylist.unwrap();
472 for key in &keylist[0..2] {
473 assert_eq!(key, &convert_set_key_descriptor_legacy(&fake_set_key_descriptor()));
474 }
475
476 let key_descriptors = fullmac.key_descriptors.unwrap();
477 for key in &key_descriptors[0..2] {
478 assert_eq!(key, &convert_set_key_descriptor(&fake_set_key_descriptor()));
479 }
480 }
481
482 #[test]
483 fn test_convert_set_keys_request_keylist_too_long() {
484 let mlme = fidl_mlme::SetKeysRequest {
485 keylist: vec![
486 fake_set_key_descriptor();
487 fidl_fullmac::WLAN_MAX_KEYLIST_SIZE as usize + 1
488 ],
489 };
490 assert!(convert_set_keys_request(&mlme).is_err());
491 }
492
493 #[test]
497 fn test_convert_set_key_descriptor() {
498 let mlme = fidl_mlme::SetKeyDescriptor {
499 key: vec![1, 2, 3],
500 key_id: 123,
501 key_type: fidl_mlme::KeyType::Group,
502 address: [3; 6],
503 rsc: 1234567,
504 cipher_suite_oui: [4, 3, 2],
505 cipher_suite_type: fidl_ieee80211::CipherSuiteType::Ccmp128,
506 };
507
508 assert_eq!(
509 convert_set_key_descriptor(&mlme),
510 fidl_ieee80211::SetKeyDescriptor {
511 cipher_oui: Some([4, 3, 2]),
512 cipher_type: Some(fidl_ieee80211::CipherSuiteType::Ccmp128),
513 key_type: Some(fidl_ieee80211::KeyType::Group),
514 peer_addr: Some([3; 6]),
515 key_id: Some(123),
516 key: Some(vec![1, 2, 3]),
517 rsc: Some(1234567),
518 ..Default::default()
519 }
520 );
521 }
522}