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