1use anyhow::{format_err, Error};
6use eui48::MacAddress;
7use fidl::endpoints::create_proxy;
8use futures::future::LocalBoxFuture;
9use futures::TryStreamExt;
10use {
11 fidl_fuchsia_wlan_policy as wlan_policy,
12 fidl_fuchsia_wlan_product_deprecatedconfiguration as wlan_deprecated,
13};
14
15pub mod opts;
16pub mod serialize;
17
18fn extract_network_id(
22 network_id: Option<fidl_fuchsia_wlan_policy::NetworkIdentifier>,
23) -> Result<(String, String), Error> {
24 match network_id {
25 Some(id) => {
26 let ssid = std::string::String::from_utf8(id.ssid).unwrap();
27 let security_type = match id.type_ {
28 fidl_fuchsia_wlan_policy::SecurityType::None => "",
29 fidl_fuchsia_wlan_policy::SecurityType::Wep => "wep",
30 fidl_fuchsia_wlan_policy::SecurityType::Wpa => "wpa",
31 fidl_fuchsia_wlan_policy::SecurityType::Wpa2 => "wpa2",
32 fidl_fuchsia_wlan_policy::SecurityType::Wpa3 => "wpa3",
33 };
34 return Ok((ssid, security_type.to_string()));
35 }
36 None => return Ok(("".to_string(), "".to_string())),
37 };
38}
39
40fn extract_bss_details(bss: wlan_policy::Bss) -> (String, i8, u32) {
42 let bssid = match bss.bssid {
43 Some(bssid) => hex::encode(bssid),
44 None => "".to_string(),
45 };
46 let rssi = match bss.rssi {
47 Some(rssi) => rssi,
48 None => 0,
49 };
50 let frequency = match bss.frequency {
51 Some(frequency) => frequency,
52 None => 0,
53 };
54
55 (bssid, rssi, frequency)
56}
57
58fn extract_compatibility(compatibility: Option<wlan_policy::Compatibility>) -> String {
60 if compatibility.is_some() {
61 match compatibility.unwrap() {
62 wlan_policy::Compatibility::Supported => return "supported".to_string(),
63 wlan_policy::Compatibility::DisallowedInsecure => {
64 return "disallowed, insecure".to_string();
65 }
66 wlan_policy::Compatibility::DisallowedNotSupported => {
67 return "disallowed, not supported".to_string();
68 }
69 }
70 }
71
72 return "compatilibity unknown".to_string();
73}
74
75pub fn print_saved_networks(saved_networks: Vec<wlan_policy::NetworkConfig>) -> Result<(), Error> {
77 for config in saved_networks {
78 let (ssid, security_type) = extract_network_id(config.id)?;
79 let password = match config.credential {
80 Some(credential) => match credential {
81 wlan_policy::Credential::None(wlan_policy::Empty) => String::from(""),
82 wlan_policy::Credential::Password(bytes) => {
83 let password = std::string::String::from_utf8(bytes);
84 password.unwrap()
85 }
86 wlan_policy::Credential::Psk(bytes) => {
87 hex::encode(bytes)
89 }
90 _ => return Err(format_err!("unknown credential variant detected")),
91 },
92 None => String::from(""),
93 };
94 println!("{:32} | {:4} | {}", ssid, security_type, password);
95 }
96 Ok(())
97}
98
99pub fn print_serialized_saved_networks(
101 saved_networks: Vec<wlan_policy::NetworkConfig>,
102) -> Result<(), Error> {
103 let serialized = serialize::serialize_saved_networks(saved_networks)?;
104 println!("{}", serialized);
105 Ok(())
106}
107
108pub async fn restore_serialized_config(
110 client_controller: wlan_policy::ClientControllerProxy,
111 serialized_config: String,
112) -> Result<(), Error> {
113 let network_configs = serialize::deserialize_saved_networks(serialized_config)?;
114 for network in network_configs {
115 save_network(client_controller.clone(), network).await?;
116 }
117 Ok(())
118}
119
120pub fn print_scan_results(scan_results: Vec<wlan_policy::ScanResult>) -> Result<(), Error> {
122 for network in scan_results {
123 let (ssid, security_type) = extract_network_id(network.id)?;
124 let compatibility = extract_compatibility(network.compatibility);
125 println!("{:32} | {:3} ({})", ssid, security_type, compatibility);
126
127 if network.entries.is_some() {
128 for entry in network.entries.unwrap() {
129 let (bssid, rssi, frequency) = extract_bss_details(entry);
130 println!("\t0x{:12} | {:3} | {:5}", bssid, rssi, frequency);
131 }
132 }
133 }
134 Ok(())
135}
136
137fn handle_request_status(status: wlan_policy::RequestStatus) -> Result<(), Error> {
140 match status {
141 wlan_policy::RequestStatus::Acknowledged => Ok(()),
142 wlan_policy::RequestStatus::RejectedNotSupported => {
143 Err(format_err!("request failed: not supported"))
144 }
145 wlan_policy::RequestStatus::RejectedIncompatibleMode => {
146 Err(format_err!("request failed: incompatible mode"))
147 }
148 wlan_policy::RequestStatus::RejectedAlreadyInUse => {
149 Err(format_err!("request failed: already in use"))
150 }
151 wlan_policy::RequestStatus::RejectedDuplicateRequest => {
152 Err(format_err!("request failed: duplicate request."))
153 }
154 }
155}
156
157async fn run_proxy_command<'a, T>(
161 fut: LocalBoxFuture<'a, Result<T, fidl::Error>>,
162) -> Result<T, Error> {
163 fut.await.map_err(|e| {
164 match e {
165 fidl::Error::ClientChannelClosed{ .. } => format_err!(
166 "Failed to obtain a WLAN policy controller. Your command was not executed.\n\n\
167 Help: Only one component may hold a policy controller at once. You can try killing\n\
168 other holders with:\n\
169 * ffx component destroy /core/session-manager/session:session\n"
170 ),
171 e => format_err!("{}", e)
172 }
173 })
174}
175
176pub async fn handle_connect(
181 client_controller: wlan_policy::ClientControllerProxy,
182 mut server_stream: wlan_policy::ClientStateUpdatesRequestStream,
183 ssid: String,
184 security_type: Option<wlan_policy::SecurityType>,
185) -> Result<(), Error> {
186 let network_id = if let Some(type_) = security_type {
188 wlan_policy::NetworkIdentifier { ssid: ssid.into_bytes(), type_ }
189 } else {
190 let mut saved_networks = handle_get_saved_networks(&client_controller)
191 .await
192 .map_err(|e| format_err!("failed to look up matching saved networks: {:?}", e))?;
193 saved_networks.retain(|config| config.id.as_ref().unwrap().ssid == ssid.as_bytes());
194 if saved_networks.len() == 1 {
196 saved_networks.pop().unwrap().id.unwrap()
197 } else if saved_networks.is_empty() {
198 return Err(format_err!("Failed to find a saved network with the provided name. Please check that the name is correct or make sure the network with the provided name is saved."));
199 } else {
202 return Err(format_err!("Multiple saved networks were found matching the provided name, please specify the security type of the network to connect to."));
203 }
204 };
205
206 let result = run_proxy_command(Box::pin(client_controller.connect(&network_id))).await?;
207 handle_request_status(result)?;
208
209 while let Some(update_request) = server_stream.try_next().await? {
210 let update = update_request.into_on_client_state_update();
211 let (update, responder) = match update {
212 Some((update, responder)) => (update, responder),
213 None => return Err(format_err!("Client provider produced invalid update.")),
214 };
215 let _ = responder.send();
216
217 match update.state {
218 Some(state) => {
219 if state == wlan_policy::WlanClientState::ConnectionsDisabled {
220 return Err(format_err!("Connections disabled while trying to conncet."));
221 }
222 }
223 None => continue,
224 }
225
226 let networks = match update.networks {
227 Some(networks) => networks,
228 None => continue,
229 };
230
231 for net_state in networks {
232 if net_state.id.is_none() || net_state.state.is_none() {
233 continue;
234 }
235 if net_state.id.unwrap().ssid == network_id.ssid {
236 match net_state.state.unwrap() {
237 wlan_policy::ConnectionState::Failed => {
238 return Err(format_err!(
239 "Failed to connect with reason {:?}",
240 net_state.status
241 ));
242 }
243 wlan_policy::ConnectionState::Disconnected => {
244 return Err(format_err!("Disconnect with reason {:?}", net_state.status));
245 }
246 wlan_policy::ConnectionState::Connecting => continue,
247 wlan_policy::ConnectionState::Connected => {
248 println!("Successfully connected");
249 return Ok(());
250 }
251 }
252 }
253 }
254 }
255 Err(format_err!("Status stream terminated before connection could be verified."))
256}
257
258pub async fn handle_get_saved_networks(
261 client_controller: &wlan_policy::ClientControllerProxy,
262) -> Result<Vec<wlan_policy::NetworkConfig>, Error> {
263 let (client_proxy, server_end) = create_proxy::<wlan_policy::NetworkConfigIteratorMarker>();
264 let fut = async { client_controller.get_saved_networks(server_end) };
265 run_proxy_command(Box::pin(fut)).await?;
266
267 let mut saved_networks = Vec::new();
268 loop {
269 let mut new_configs = run_proxy_command(Box::pin(client_proxy.get_next())).await?;
270 if new_configs.is_empty() {
271 break;
272 }
273 saved_networks.append(&mut new_configs);
274 }
275 Ok(saved_networks)
276}
277
278pub async fn handle_listen(
285 mut server_stream: wlan_policy::ClientStateUpdatesRequestStream,
286 single_sample: bool,
287) -> Result<(), Error> {
288 let mut last_known_connection_state = None;
289 while let Some(update_request) = server_stream.try_next().await? {
290 let update = update_request.into_on_client_state_update();
291 let (update, responder) = match update {
292 Some((update, responder)) => (update, responder),
293 None => return Err(format_err!("Client provider produced invalid update.")),
294 };
295 let _ = responder.send();
296
297 match update.state {
298 Some(state) => {
299 if last_known_connection_state != Some(state) {
300 last_known_connection_state = Some(state);
301 match state {
302 wlan_policy::WlanClientState::ConnectionsEnabled => {
303 println!("Client connections are enabled");
304 }
305 wlan_policy::WlanClientState::ConnectionsDisabled => {
306 println!("Client connections are disabled");
307 }
308 }
309 };
310 }
311 None => {
312 println!("Unexpected client connection state 'None'");
313 }
314 }
315
316 let networks = match update.networks {
317 Some(networks) => networks,
318 None => continue,
319 };
320
321 let mut updates = vec![];
322 for net_state in networks {
324 if net_state.id.is_none() || net_state.state.is_none() {
325 continue;
326 }
327 let id = net_state.id.unwrap();
328 let ssid = std::str::from_utf8(&id.ssid).unwrap();
329 match net_state.state.unwrap() {
330 wlan_policy::ConnectionState::Failed => {
331 updates.push(format!(
332 "\t{:32} connection failed - {:?}",
333 format!("{}:", ssid),
334 net_state.status
335 ));
336 }
337 wlan_policy::ConnectionState::Disconnected => {
338 updates.push(format!(
339 "\t{:32} connection disconnected - {:?}",
340 format!("{}:", ssid),
341 net_state.status
342 ));
343 }
344 wlan_policy::ConnectionState::Connecting => {
345 updates.push(format!("\t{:32} connecting", format!("{}:", ssid)));
346 }
347 wlan_policy::ConnectionState::Connected => {
348 updates.push(format!("\t{:32} connected", format!("{}:", ssid)))
349 }
350 }
351 }
352
353 updates.sort_by_key(|s| s.to_lowercase());
355 println!("Update:");
356 for update in updates {
357 println!("{}", update);
358 }
359
360 if single_sample {
362 break;
363 }
364 }
365 Ok(())
366}
367
368pub async fn handle_remove_network(
372 client_controller: wlan_policy::ClientControllerProxy,
373 ssid: Vec<u8>,
374 security_type: Option<wlan_policy::SecurityType>,
375 credential: Option<wlan_policy::Credential>,
376) -> Result<(), Error> {
377 let networks_before = handle_get_saved_networks(&client_controller).await.map_err(|e| {
378 format_err!(
379 "The network was not removed because an error occurred getting the list of networks \
380 before removing the requested network: {}",
381 e,
382 )
383 })?;
384
385 let config = if security_type.is_some() && credential.is_some() {
388 wlan_policy::NetworkConfig {
389 id: Some(wlan_policy::NetworkIdentifier {
390 ssid: ssid.clone(),
391 type_: security_type.unwrap(),
392 }),
393 credential: credential.clone(),
394 ..Default::default()
395 }
396 } else {
397 let mut matching_networks = networks_before
401 .iter()
402 .filter(|c| config_matches(c, &ssid, &security_type, &credential))
403 .cloned()
404 .collect::<Vec<_>>();
405
406 if matching_networks.len() == 1 {
408 matching_networks.pop().unwrap()
409 } else if matching_networks.is_empty() {
410 return Err(format_err!("Failed to find a saved network with the provided arguments. Please check that the arguments are correct if there should be one saved."));
411 } else {
414 return Err(format_err!(
415 "Multiple saved networks were found matching the provided \
416 arguments, please specify SSID, security, and credential that matches only one \
417 saved network."
418 ));
419 }
420 };
421
422 run_proxy_command(Box::pin(client_controller.remove_network(&config)))
423 .await?
424 .map_err(|e| format_err!("failed to remove network with {:?}", e))?;
425
426 let networks_after = match handle_get_saved_networks(&client_controller).await {
427 Ok(networks) => networks,
428 Err(e) => {
429 println!(
430 "The network provided may or may not have been removed. An error occurred \
431 getting the list of networks after removing: {}",
432 e
433 );
434 return Ok(());
435 }
436 };
437
438 if networks_after.iter().any(|c| config_matches(c, &ssid, &security_type, &credential)) {
441 return Err(format_err!(
442 "The network may not have been removed. A network matching the \
443 provided arguments was found after attempting to remove the network."
444 ));
445 }
446
447 if networks_before.len() == networks_after.len() {
449 println!(
450 "The number of saved networks is the same after removing the specified network. \
451 Please check that the arguments provided are correct and whether the intended \
452 network is saved."
453 );
454 } else {
455 println!("Successfully removed network '{}'", std::str::from_utf8(&ssid).unwrap());
456 }
457 Ok(())
458}
459
460fn config_matches(
463 config: &wlan_policy::NetworkConfig,
464 ssid: &Vec<u8>,
465 security_type: &Option<wlan_policy::SecurityType>,
466 credential: &Option<wlan_policy::Credential>,
467) -> bool {
468 let config_id = match &config.id {
469 Some(id) => id,
470 None => {
471 return false;
472 }
473 };
474
475 if config_id.ssid != *ssid {
476 return false;
477 }
478
479 if let Some(security) = *security_type {
481 if config_id.type_ != security {
482 return false;
483 }
484 }
485 if credential.is_some() {
486 if config.credential != *credential {
487 return false;
488 }
489 }
490
491 return true;
492}
493
494pub async fn handle_save_network(
496 client_controller: wlan_policy::ClientControllerProxy,
497 config: wlan_policy::NetworkConfig,
498) -> Result<(), Error> {
499 save_network(client_controller, config).await
500}
501
502async fn save_network(
503 client_controller: wlan_policy::ClientControllerProxy,
504 network_config: wlan_policy::NetworkConfig,
505) -> Result<(), Error> {
506 run_proxy_command(Box::pin(client_controller.save_network(&network_config)))
507 .await?
508 .map_err(|e| format_err!("failed to save network with {:?}", e))?;
509 println!(
510 "Successfully saved network '{}'",
511 std::str::from_utf8(&network_config.id.unwrap().ssid).unwrap()
512 );
513 Ok(())
514}
515
516pub async fn handle_scan(
518 client_controller: wlan_policy::ClientControllerProxy,
519) -> Result<Vec<wlan_policy::ScanResult>, Error> {
520 let (client_proxy, server_end) = create_proxy::<wlan_policy::ScanResultIteratorMarker>();
521 let fut = async { client_controller.scan_for_networks(server_end) };
522 run_proxy_command(Box::pin(fut)).await?;
523
524 let mut scanned_networks = Vec::<wlan_policy::ScanResult>::new();
525 loop {
526 match run_proxy_command(Box::pin(client_proxy.get_next())).await? {
527 Ok(mut new_networks) => {
528 if new_networks.is_empty() {
529 break;
530 }
531 scanned_networks.append(&mut new_networks);
532 }
533 Err(e) => return Err(format_err!("Scan failure error: {:?}", e)),
534 }
535 }
536
537 Ok(scanned_networks)
538}
539
540pub async fn handle_start_client_connections(
542 client_controller: wlan_policy::ClientControllerProxy,
543) -> Result<(), Error> {
544 let status = run_proxy_command(Box::pin(client_controller.start_client_connections())).await?;
545 return handle_request_status(status);
546}
547
548pub async fn handle_stop_client_connections(
550 client_controller: wlan_policy::ClientControllerProxy,
551) -> Result<(), Error> {
552 let status = run_proxy_command(Box::pin(client_controller.stop_client_connections())).await?;
553 return handle_request_status(status);
554}
555
556pub async fn handle_start_ap(
558 ap_controller: wlan_policy::AccessPointControllerProxy,
559 mut server_stream: wlan_policy::AccessPointStateUpdatesRequestStream,
560 config: wlan_policy::NetworkConfig,
561) -> Result<(), Error> {
562 let connectivity_mode = wlan_policy::ConnectivityMode::Unrestricted;
563 let operating_band = wlan_policy::OperatingBand::Any;
564 let result = run_proxy_command(Box::pin(ap_controller.start_access_point(
565 &config,
566 connectivity_mode,
567 operating_band,
568 )))
569 .await?;
570 handle_request_status(result)?;
571
572 while let Some(update_request) = server_stream.try_next().await? {
574 let update = update_request.into_on_access_point_state_update();
575 let (updates, responder) = match update {
576 Some((update, responder)) => (update, responder),
577 None => return Err(format_err!("AP provider produced invalid update.")),
578 };
579 let _ = responder.send();
580
581 for update in updates {
582 match update.state {
583 Some(state) => match state {
584 wlan_policy::OperatingState::Failed => {
585 return Err(format_err!("Failed to start AP."));
586 }
587 wlan_policy::OperatingState::Starting => {
588 println!("AP is starting.");
589 continue;
590 }
591 wlan_policy::OperatingState::Active => return Ok(()),
592 },
593 None => continue,
594 }
595 }
596 }
597 Err(format_err!("Status stream terminated before AP start could be verified."))
598}
599
600pub async fn handle_stop_ap(
602 ap_controller: wlan_policy::AccessPointControllerProxy,
603 config: wlan_policy::NetworkConfig,
604) -> Result<(), Error> {
605 let result = run_proxy_command(Box::pin(ap_controller.stop_access_point(&config))).await?;
606 handle_request_status(result)
607}
608
609pub async fn handle_stop_all_aps(
611 ap_controller: wlan_policy::AccessPointControllerProxy,
612) -> Result<(), Error> {
613 let fut = async { ap_controller.stop_all_access_points() };
614 run_proxy_command(Box::pin(fut)).await?;
615 Ok(())
616}
617
618pub async fn handle_ap_listen(
620 mut server_stream: wlan_policy::AccessPointStateUpdatesRequestStream,
621 single_sample: bool,
622) -> Result<(), Error> {
623 println!(
624 "{:32} | {:4} | {:8} | {:12} | {:6} | {:4} | {:7}",
625 "SSID", "Type", "State", "Mode", "Band", "Freq", "#Clients"
626 );
627
628 while let Some(update_request) = server_stream.try_next().await? {
629 let updates = update_request.into_on_access_point_state_update();
630 let (updates, responder) = match updates {
631 Some((update, responder)) => (update, responder),
632 None => return Err(format_err!("AP provider produced invalid update.")),
633 };
634 let _ = responder.send();
635
636 for update in updates {
637 let (ssid, security_type) = match update.id {
638 Some(network_id) => {
639 let ssid = network_id.ssid.clone();
640 let ssid = String::from_utf8(ssid)?;
641 let security_type = match network_id.type_ {
642 wlan_policy::SecurityType::None => "none",
643 wlan_policy::SecurityType::Wep => "wep",
644 wlan_policy::SecurityType::Wpa => "wpa",
645 wlan_policy::SecurityType::Wpa2 => "wpa2",
646 wlan_policy::SecurityType::Wpa3 => "wpa3",
647 };
648 (ssid, security_type.to_string())
649 }
650 None => ("".to_string(), "".to_string()),
651 };
652 let state = match update.state {
653 Some(state) => match state {
654 wlan_policy::OperatingState::Failed => "failed",
655 wlan_policy::OperatingState::Starting => "starting",
656 wlan_policy::OperatingState::Active => "active",
657 },
658 None => "",
659 };
660 let mode = match update.mode {
661 Some(mode) => match mode {
662 wlan_policy::ConnectivityMode::LocalOnly => "local only",
663 wlan_policy::ConnectivityMode::Unrestricted => "unrestricted",
664 },
665 None => "",
666 };
667 let band = match update.band {
668 Some(band) => match band {
669 wlan_policy::OperatingBand::Any => "any",
670 wlan_policy::OperatingBand::Only24Ghz => "2.4Ghz",
671 wlan_policy::OperatingBand::Only5Ghz => "5Ghz",
672 },
673 None => "",
674 };
675 let frequency = match update.frequency {
676 Some(frequency) => frequency.to_string(),
677 None => "".to_string(),
678 };
679 let client_count = match update.clients {
680 Some(connected_clients) => match connected_clients.count {
681 Some(count) => count.to_string(),
682 None => "".to_string(),
683 },
684 None => "".to_string(),
685 };
686
687 println!(
688 "{:32} | {:4} | {:8} | {:12} | {:6} | {:4} | {:7}",
689 ssid, security_type, state, mode, band, frequency, client_count
690 );
691 }
692
693 if single_sample {
695 break;
696 }
697 }
698 Ok(())
699}
700
701pub async fn handle_suggest_ap_mac(
702 configurator: wlan_deprecated::DeprecatedConfiguratorProxy,
703 mac: MacAddress,
704) -> Result<(), Error> {
705 let mac = fidl_fuchsia_net::MacAddress { octets: mac.to_array() };
706 let result = configurator.suggest_access_point_mac_address(&mac).await?;
707 result.map_err(|e| format_err!("suggesting MAC failed: {:?}", e))
708}
709
710#[cfg(test)]
711mod tests {
712 use super::*;
713 use fidl::endpoints;
714 use fuchsia_async::TestExecutor;
715 use futures::stream::StreamExt;
716 use futures::task::Poll;
717 use std::pin::pin;
718 use test_case::test_case;
719 use wlan_common::assert_variant;
720 use zx_status;
721
722 static TEST_SSID: &str = "test_ssid";
723 static TEST_PASSWORD: &str = "test_password";
724
725 struct ClientTestValues {
726 client_proxy: wlan_policy::ClientControllerProxy,
727 client_stream: wlan_policy::ClientControllerRequestStream,
728 update_proxy: wlan_policy::ClientStateUpdatesProxy,
729 update_stream: wlan_policy::ClientStateUpdatesRequestStream,
730 }
731
732 fn client_test_setup() -> ClientTestValues {
733 let (client_proxy, client_stream) =
734 endpoints::create_proxy_and_stream::<wlan_policy::ClientControllerMarker>();
735
736 let (listener_proxy, listener_stream) =
737 endpoints::create_proxy_and_stream::<wlan_policy::ClientStateUpdatesMarker>();
738
739 ClientTestValues {
740 client_proxy: client_proxy,
741 client_stream: client_stream,
742 update_proxy: listener_proxy,
743 update_stream: listener_stream,
744 }
745 }
746
747 fn send_client_request_status(
750 exec: &mut TestExecutor,
751 server: &mut wlan_policy::ClientControllerRequestStream,
752 response: wlan_policy::RequestStatus,
753 ) {
754 let poll = exec.run_until_stalled(&mut server.next());
755 let request = match poll {
756 Poll::Ready(poll_ready) => poll_ready
757 .expect("poll ready result is None")
758 .expect("poll ready result is an Error"),
759 Poll::Pending => panic!("no ClientController request available"),
760 };
761
762 let result = match request {
763 wlan_policy::ClientControllerRequest::StartClientConnections { responder } => {
764 responder.send(response)
765 }
766 wlan_policy::ClientControllerRequest::StopClientConnections { responder } => {
767 responder.send(response)
768 }
769 wlan_policy::ClientControllerRequest::Connect { responder, .. } => {
770 responder.send(response)
771 }
772 _ => panic!("expecting a request that expects a RequestStatus"),
773 };
774
775 if result.is_err() {
776 panic!("could not send request status");
777 }
778 }
779
780 fn create_client_state_summary(
782 ssid: &str,
783 state: wlan_policy::ConnectionState,
784 ) -> wlan_policy::ClientStateSummary {
785 let network_state = wlan_policy::NetworkState {
786 id: Some(create_network_id(ssid)),
787 state: Some(state),
788 status: None,
789 ..Default::default()
790 };
791 wlan_policy::ClientStateSummary {
792 state: Some(wlan_policy::WlanClientState::ConnectionsEnabled),
793 networks: Some(vec![network_state]),
794 ..Default::default()
795 }
796 }
797
798 fn create_ap_state_summary(
800 state: wlan_policy::OperatingState,
801 ) -> wlan_policy::AccessPointState {
802 wlan_policy::AccessPointState {
803 id: None,
804 state: Some(state),
805 mode: None,
806 band: None,
807 frequency: None,
808 clients: None,
809 ..Default::default()
810 }
811 }
812
813 #[track_caller]
815 fn send_network_config_response(
816 exec: &mut TestExecutor,
817 server: &mut wlan_policy::ClientControllerRequestStream,
818 success: bool,
819 ) {
820 let poll = exec.run_until_stalled(&mut server.next());
821 let request = match poll {
822 Poll::Ready(poll_ready) => poll_ready
823 .expect("poll ready result is None")
824 .expect("poll ready result is an Error"),
825 Poll::Pending => panic!("no ClientController request available"),
826 };
827
828 let result = match request {
829 wlan_policy::ClientControllerRequest::SaveNetwork { config: _, responder } => {
830 if success {
831 responder.send(Ok(()))
832 } else {
833 responder.send(Err(wlan_policy::NetworkConfigChangeError::GeneralError))
834 }
835 }
836 wlan_policy::ClientControllerRequest::RemoveNetwork { config: _, responder } => {
837 if success {
838 responder.send(Ok(()))
839 } else {
840 responder.send(Err(wlan_policy::NetworkConfigChangeError::GeneralError))
841 }
842 }
843 _ => panic!("expecting a request that optionally receives a NetworkConfigChangeError"),
844 };
845
846 if result.is_err() {
847 panic!("could not send network config response");
848 }
849 }
850
851 struct ApTestValues {
852 ap_proxy: wlan_policy::AccessPointControllerProxy,
853 ap_stream: wlan_policy::AccessPointControllerRequestStream,
854 update_proxy: wlan_policy::AccessPointStateUpdatesProxy,
855 update_stream: wlan_policy::AccessPointStateUpdatesRequestStream,
856 }
857
858 fn ap_test_setup() -> ApTestValues {
859 let (ap_proxy, ap_stream) =
860 endpoints::create_proxy_and_stream::<wlan_policy::AccessPointControllerMarker>();
861
862 let (listener_proxy, listener_stream) =
863 endpoints::create_proxy_and_stream::<wlan_policy::AccessPointStateUpdatesMarker>();
864
865 ApTestValues {
866 ap_proxy,
867 ap_stream,
868 update_proxy: listener_proxy,
869 update_stream: listener_stream,
870 }
871 }
872
873 fn send_ap_request_status(
876 exec: &mut TestExecutor,
877 server: &mut wlan_policy::AccessPointControllerRequestStream,
878 response: wlan_policy::RequestStatus,
879 ) {
880 let poll = exec.run_until_stalled(&mut server.next());
881 let request = match poll {
882 Poll::Ready(poll_ready) => poll_ready
883 .expect("poll ready result is None")
884 .expect("poll ready result is an Error"),
885 Poll::Pending => panic!("no AccessPointController request available"),
886 };
887
888 let result = match request {
889 wlan_policy::AccessPointControllerRequest::StartAccessPoint { responder, .. } => {
890 responder.send(response)
891 }
892 wlan_policy::AccessPointControllerRequest::StopAccessPoint { config: _, responder } => {
893 responder.send(response)
894 }
895 _ => panic!("expecting a request that expects a RequestStatus"),
896 };
897
898 if result.is_err() {
899 panic!("could not send request status");
900 }
901 }
902
903 fn create_network_id(ssid: &str) -> fidl_fuchsia_wlan_policy::NetworkIdentifier {
905 wlan_policy::NetworkIdentifier {
906 ssid: ssid.as_bytes().to_vec(),
907 type_: wlan_policy::SecurityType::Wpa2,
908 }
909 }
910
911 fn create_network_config(ssid: &str) -> fidl_fuchsia_wlan_policy::NetworkConfig {
913 wlan_policy::NetworkConfig {
914 id: Some(create_network_id(ssid)),
915 credential: Some(create_password(TEST_PASSWORD)),
916 ..Default::default()
917 }
918 }
919
920 fn create_password(val: &str) -> fidl_fuchsia_wlan_policy::Credential {
921 wlan_policy::Credential::Password(val.as_bytes().to_vec())
922 }
923
924 fn create_network_config_with_security(
926 ssid: &str,
927 security: wlan_policy::SecurityType,
928 ) -> fidl_fuchsia_wlan_policy::NetworkConfig {
929 let id = wlan_policy::NetworkIdentifier { ssid: ssid.as_bytes().to_vec(), type_: security };
930 wlan_policy::NetworkConfig { id: Some(id), credential: None, ..Default::default() }
931 }
932
933 fn create_scan_result(ssid: &str) -> wlan_policy::ScanResult {
935 wlan_policy::ScanResult {
936 id: Some(create_network_id(ssid)),
937 entries: None,
938 compatibility: None,
939 ..Default::default()
940 }
941 }
942
943 fn get_scan_result_iterator(
946 exec: &mut TestExecutor,
947 mut server: wlan_policy::ClientControllerRequestStream,
948 ) -> wlan_policy::ScanResultIteratorRequestStream {
949 let poll = exec.run_until_stalled(&mut server.next());
950 let request = match poll {
951 Poll::Ready(poll_ready) => poll_ready
952 .expect("poll ready result is None")
953 .expect("poll ready result is an Error"),
954 Poll::Pending => panic!("no ClientController request available"),
955 };
956
957 match request {
958 wlan_policy::ClientControllerRequest::ScanForNetworks {
959 iterator,
960 control_handle: _,
961 } => iterator.into_stream(),
962 _ => panic!("expecting a ScanForNetworks"),
963 }
964 }
965
966 fn send_scan_result(
968 exec: &mut TestExecutor,
969 server: &mut wlan_policy::ScanResultIteratorRequestStream,
970 scan_result: Result<&[wlan_policy::ScanResult], wlan_policy::ScanErrorCode>,
971 ) {
972 assert_variant!(
973 exec.run_until_stalled(&mut server.next()),
974 Poll::Ready(Some(Ok(wlan_policy::ScanResultIteratorRequest::GetNext {
975 responder
976 }))) => {
977 match responder.send(scan_result) {
978 Ok(()) => {}
979 Err(e) => panic!("failed to send scan result: {}", e),
980 }
981 }
982 );
983 }
984
985 #[track_caller]
988 fn get_saved_networks_iterator(
989 exec: &mut TestExecutor,
990 server: &mut wlan_policy::ClientControllerRequestStream,
991 ) -> wlan_policy::NetworkConfigIteratorRequestStream {
992 let poll = exec.run_until_stalled(&mut server.next());
993 let request = match poll {
994 Poll::Ready(poll_ready) => poll_ready
995 .expect("poll ready result is None")
996 .expect("poll ready result is an Error"),
997 Poll::Pending => panic!("no ClientController request available"),
998 };
999
1000 match request {
1001 wlan_policy::ClientControllerRequest::GetSavedNetworks {
1002 iterator,
1003 control_handle: _,
1004 } => iterator.into_stream(),
1005 _ => panic!("expecting a ScanForNetworks"),
1006 }
1007 }
1008
1009 fn send_saved_networks(
1011 exec: &mut TestExecutor,
1012 server: &mut wlan_policy::NetworkConfigIteratorRequestStream,
1013 saved_networks_response: Vec<wlan_policy::NetworkConfig>,
1014 ) {
1015 assert_variant!(
1016 exec.run_until_stalled(&mut server.next()),
1017 Poll::Ready(Some(Ok(wlan_policy::NetworkConfigIteratorRequest::GetNext {
1018 responder
1019 }))) => {
1020 match responder.send(&saved_networks_response) {
1021 Ok(()) => {}
1022 Err(e) => panic!("failed to send saved networks: {}", e),
1023 }
1024 }
1025 );
1026 }
1027
1028 #[fuchsia::test]
1030 fn test_start_client_connections_success() {
1031 let mut exec = TestExecutor::new();
1032 let mut test_values = client_test_setup();
1033 let fut = handle_start_client_connections(test_values.client_proxy);
1034 let mut fut = pin!(fut);
1035
1036 assert!(exec.run_until_stalled(&mut fut).is_pending());
1038
1039 send_client_request_status(
1041 &mut exec,
1042 &mut test_values.client_stream,
1043 wlan_policy::RequestStatus::Acknowledged,
1044 );
1045
1046 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1047 }
1048
1049 #[fuchsia::test]
1051 fn test_start_client_connections_fail() {
1052 let mut exec = TestExecutor::new();
1053 let mut test_values = client_test_setup();
1054 let fut = handle_start_client_connections(test_values.client_proxy);
1055 let mut fut = pin!(fut);
1056
1057 assert!(exec.run_until_stalled(&mut fut).is_pending());
1059
1060 send_client_request_status(
1062 &mut exec,
1063 &mut test_values.client_stream,
1064 wlan_policy::RequestStatus::RejectedNotSupported,
1065 );
1066
1067 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1068 }
1069
1070 #[fuchsia::test]
1072 fn test_stop_client_connections_success() {
1073 let mut exec = TestExecutor::new();
1074 let mut test_values = client_test_setup();
1075 let fut = handle_stop_client_connections(test_values.client_proxy);
1076 let mut fut = pin!(fut);
1077
1078 assert!(exec.run_until_stalled(&mut fut).is_pending());
1080
1081 send_client_request_status(
1083 &mut exec,
1084 &mut test_values.client_stream,
1085 wlan_policy::RequestStatus::Acknowledged,
1086 );
1087
1088 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1089 }
1090
1091 #[fuchsia::test]
1093 fn test_stop_client_connections_fail() {
1094 let mut exec = TestExecutor::new();
1095 let mut test_values = client_test_setup();
1096 let fut = handle_stop_client_connections(test_values.client_proxy);
1097 let mut fut = pin!(fut);
1098
1099 assert!(exec.run_until_stalled(&mut fut).is_pending());
1101
1102 send_client_request_status(
1104 &mut exec,
1105 &mut test_values.client_stream,
1106 wlan_policy::RequestStatus::RejectedNotSupported,
1107 );
1108
1109 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1110 }
1111
1112 #[fuchsia::test]
1114 fn test_save_network_pass() {
1115 let mut exec = TestExecutor::new();
1116 let mut test_values = client_test_setup();
1117 let config = create_network_config(TEST_SSID);
1118 let fut = handle_save_network(test_values.client_proxy, config);
1119 let mut fut = pin!(fut);
1120
1121 assert!(exec.run_until_stalled(&mut fut).is_pending());
1123
1124 send_network_config_response(&mut exec, &mut test_values.client_stream, true);
1126
1127 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1128 }
1129
1130 #[fuchsia::test]
1132 fn test_save_network_fail() {
1133 let mut exec = TestExecutor::new();
1134 let mut test_values = client_test_setup();
1135 let config = create_network_config(TEST_SSID);
1136 let fut = handle_save_network(test_values.client_proxy, config);
1137 let mut fut = pin!(fut);
1138
1139 assert!(exec.run_until_stalled(&mut fut).is_pending());
1141
1142 send_network_config_response(&mut exec, &mut test_values.client_stream, false);
1144
1145 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1146 }
1147
1148 #[fuchsia::test]
1150 fn test_remove_network_pass() {
1151 let mut exec = TestExecutor::new();
1152 let mut test_values = client_test_setup();
1153 let security = Some(wlan_policy::SecurityType::Wpa2);
1154 let credential = Some(create_password(TEST_PASSWORD));
1155 let fut =
1156 handle_remove_network(test_values.client_proxy, TEST_SSID.into(), security, credential);
1157 let mut fut = pin!(fut);
1158 assert!(exec.run_until_stalled(&mut fut).is_pending());
1159
1160 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1162 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1163 assert!(exec.run_until_stalled(&mut fut).is_pending());
1164 send_saved_networks(&mut exec, &mut iterator, vec![]);
1165
1166 assert!(exec.run_until_stalled(&mut fut).is_pending());
1168
1169 send_network_config_response(&mut exec, &mut test_values.client_stream, true);
1171 assert!(exec.run_until_stalled(&mut fut).is_pending());
1172
1173 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1175 send_saved_networks(&mut exec, &mut iterator, vec![]);
1176
1177 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1178 }
1179
1180 #[fuchsia::test]
1184 fn test_remove_network_ssid_only_pass() {
1185 let mut exec = TestExecutor::new();
1186 let mut test_values = client_test_setup();
1187
1188 let security = None;
1190 let credential = None;
1191 let fut =
1192 handle_remove_network(test_values.client_proxy, TEST_SSID.into(), security, credential);
1193 let mut fut = pin!(fut);
1194
1195 assert!(exec.run_until_stalled(&mut fut).is_pending());
1197
1198 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1200 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1201 assert!(exec.run_until_stalled(&mut fut).is_pending());
1202 send_saved_networks(&mut exec, &mut iterator, vec![]);
1203
1204 assert!(exec.run_until_stalled(&mut fut).is_pending());
1206
1207 send_network_config_response(&mut exec, &mut test_values.client_stream, true);
1209 assert!(exec.run_until_stalled(&mut fut).is_pending());
1210
1211 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1213 send_saved_networks(&mut exec, &mut iterator, vec![]);
1214
1215 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1216 }
1217
1218 #[fuchsia::test]
1222 fn test_remove_network_unspecified_security_pass() {
1223 let mut exec = TestExecutor::new();
1224 let mut test_values = client_test_setup();
1225
1226 let security = None;
1228 let credential = Some(create_password(TEST_PASSWORD));
1229 let fut =
1230 handle_remove_network(test_values.client_proxy, TEST_SSID.into(), security, credential);
1231 let mut fut = pin!(fut);
1232
1233 assert!(exec.run_until_stalled(&mut fut).is_pending());
1235
1236 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1238 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1239 assert!(exec.run_until_stalled(&mut fut).is_pending());
1240 send_saved_networks(&mut exec, &mut iterator, vec![]);
1241
1242 assert!(exec.run_until_stalled(&mut fut).is_pending());
1244
1245 send_network_config_response(&mut exec, &mut test_values.client_stream, true);
1247 assert!(exec.run_until_stalled(&mut fut).is_pending());
1248
1249 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1251 send_saved_networks(&mut exec, &mut iterator, vec![]);
1252
1253 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1254 }
1255
1256 #[fuchsia::test]
1260 fn test_remove_network_no_credential_pass() {
1261 let mut exec = TestExecutor::new();
1262 let mut test_values = client_test_setup();
1263
1264 let security = Some(wlan_policy::SecurityType::Wpa2);
1266 let credential = None;
1267 let fut =
1268 handle_remove_network(test_values.client_proxy, TEST_SSID.into(), security, credential);
1269 let mut fut = pin!(fut);
1270
1271 assert!(exec.run_until_stalled(&mut fut).is_pending());
1273
1274 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1276 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1277 assert!(exec.run_until_stalled(&mut fut).is_pending());
1278 send_saved_networks(&mut exec, &mut iterator, vec![]);
1279
1280 assert!(exec.run_until_stalled(&mut fut).is_pending());
1282
1283 send_network_config_response(&mut exec, &mut test_values.client_stream, true);
1285 assert!(exec.run_until_stalled(&mut fut).is_pending());
1286
1287 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1289 send_saved_networks(&mut exec, &mut iterator, vec![]);
1290
1291 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1292 }
1293
1294 #[fuchsia::test]
1297 fn test_remove_network_ssid_only_no_match_fails() {
1298 let mut exec = TestExecutor::new();
1299 let mut test_values = client_test_setup();
1300
1301 let security = None;
1303 let credential = None;
1304 let fut =
1305 handle_remove_network(test_values.client_proxy, TEST_SSID.into(), security, credential);
1306 let mut fut = pin!(fut);
1307
1308 assert!(exec.run_until_stalled(&mut fut).is_pending());
1310
1311 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1313 send_saved_networks(
1314 &mut exec,
1315 &mut iterator,
1316 vec![create_network_config("some-other-ssid")],
1317 );
1318 assert!(exec.run_until_stalled(&mut fut).is_pending());
1319 send_saved_networks(&mut exec, &mut iterator, vec![]);
1320
1321 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1323 }
1324
1325 #[fuchsia::test]
1327 fn test_remove_network_fail() {
1328 let mut exec = TestExecutor::new();
1329 let mut test_values = client_test_setup();
1330 let security = Some(wlan_policy::SecurityType::Wpa2);
1331 let credential = Some(create_password(TEST_PASSWORD));
1332 let fut =
1333 handle_remove_network(test_values.client_proxy, TEST_SSID.into(), security, credential);
1334 let mut fut = pin!(fut);
1335 assert!(exec.run_until_stalled(&mut fut).is_pending());
1336
1337 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1339 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1340 assert!(exec.run_until_stalled(&mut fut).is_pending());
1341 send_saved_networks(&mut exec, &mut iterator, vec![]);
1342
1343 assert!(exec.run_until_stalled(&mut fut).is_pending());
1345
1346 send_network_config_response(&mut exec, &mut test_values.client_stream, false);
1348
1349 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1350 }
1351
1352 #[fuchsia::test]
1354 fn test_remove_network_not_removed_fails() {
1355 let mut exec = TestExecutor::new();
1356 let mut test_values = client_test_setup();
1357 let security = Some(wlan_policy::SecurityType::Wpa2);
1358 let credential = Some(create_password(TEST_PASSWORD));
1359 let fut =
1360 handle_remove_network(test_values.client_proxy, TEST_SSID.into(), security, credential);
1361 let mut fut = pin!(fut);
1362 assert!(exec.run_until_stalled(&mut fut).is_pending());
1363
1364 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1366 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1367 assert!(exec.run_until_stalled(&mut fut).is_pending());
1368 send_saved_networks(&mut exec, &mut iterator, vec![]);
1369
1370 assert!(exec.run_until_stalled(&mut fut).is_pending());
1372
1373 send_network_config_response(&mut exec, &mut test_values.client_stream, true);
1375 assert!(exec.run_until_stalled(&mut fut).is_pending());
1376
1377 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1380 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1381 assert!(exec.run_until_stalled(&mut fut).is_pending());
1382 send_saved_networks(&mut exec, &mut iterator, vec![]);
1383
1384 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1385 }
1386
1387 #[test_case(
1391 TEST_SSID,
1392 Some(wlan_policy::SecurityType::Wpa2),
1393 Some(create_password(TEST_PASSWORD)),
1394 true
1395 )]
1396 #[test_case(TEST_SSID, Some(wlan_policy::SecurityType::Wpa2), None, true)]
1397 #[test_case(TEST_SSID, None, Some(create_password(TEST_PASSWORD)), true)]
1398 #[test_case(TEST_SSID, None, None, true)]
1399 #[test_case(
1400 TEST_SSID,
1401 Some(wlan_policy::SecurityType::Wpa2),
1402 Some(create_password("otherpassword")),
1403 false
1404 )]
1405 #[test_case(TEST_SSID, None, Some(create_password("otherpassword")), false)]
1406 #[test_case(
1407 TEST_SSID,
1408 Some(wlan_policy::SecurityType::Wpa3),
1409 Some(create_password(TEST_PASSWORD)),
1410 false
1411 )]
1412 #[test_case(TEST_SSID, Some(wlan_policy::SecurityType::Wpa3), None, false)]
1413 #[test_case(
1414 "otherssid",
1415 Some(wlan_policy::SecurityType::Wpa3),
1416 Some(create_password(TEST_PASSWORD)),
1417 false
1418 )]
1419 #[test_case("otherssid", None, None, false)]
1420 #[fuchsia::test]
1421 fn test_config_matches_config(
1422 ssid: &str,
1423 security: Option<wlan_policy::SecurityType>,
1424 credential: Option<wlan_policy::Credential>,
1425 expected_result: bool,
1426 ) {
1427 let ssid = ssid.as_bytes().to_vec();
1428 let config = create_network_config(TEST_SSID);
1429 let result = config_matches(&config, &ssid, &security, &credential);
1430 assert_eq!(result, expected_result);
1431 }
1432
1433 #[fuchsia::test]
1435 fn test_connect_pass() {
1436 let mut exec = TestExecutor::new();
1437 let mut test_values = client_test_setup();
1438
1439 let ssid = TEST_SSID.to_string();
1441 let security = Some(wlan_policy::SecurityType::Wpa2);
1442 let fut =
1443 handle_connect(test_values.client_proxy, test_values.update_stream, ssid, security);
1444 let mut fut = pin!(fut);
1445
1446 assert!(exec.run_until_stalled(&mut fut).is_pending());
1448
1449 send_client_request_status(
1451 &mut exec,
1452 &mut test_values.client_stream,
1453 wlan_policy::RequestStatus::Acknowledged,
1454 );
1455
1456 assert!(exec.run_until_stalled(&mut fut).is_pending());
1458 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1459 TEST_SSID,
1460 wlan_policy::ConnectionState::Connecting,
1461 ));
1462
1463 assert!(exec.run_until_stalled(&mut fut).is_pending());
1465 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1466 TEST_SSID,
1467 wlan_policy::ConnectionState::Connected,
1468 ));
1469
1470 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1472 }
1473
1474 #[fuchsia::test]
1477 fn test_connect_unspecified_security_pass() {
1478 let mut exec = TestExecutor::new();
1479 let mut test_values = client_test_setup();
1480
1481 let ssid = TEST_SSID.to_string();
1483 let fut = handle_connect(test_values.client_proxy, test_values.update_stream, ssid, None);
1484 let mut fut = pin!(fut);
1485
1486 assert!(exec.run_until_stalled(&mut fut).is_pending());
1488
1489 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1491 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1492 assert!(exec.run_until_stalled(&mut fut).is_pending());
1493
1494 send_saved_networks(&mut exec, &mut iterator, vec![]);
1496
1497 assert!(exec.run_until_stalled(&mut fut).is_pending());
1499
1500 send_client_request_status(
1502 &mut exec,
1503 &mut test_values.client_stream,
1504 wlan_policy::RequestStatus::Acknowledged,
1505 );
1506
1507 assert!(exec.run_until_stalled(&mut fut).is_pending());
1509 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1510 TEST_SSID,
1511 wlan_policy::ConnectionState::Connecting,
1512 ));
1513
1514 assert!(exec.run_until_stalled(&mut fut).is_pending());
1516 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1517 TEST_SSID,
1518 wlan_policy::ConnectionState::Connected,
1519 ));
1520
1521 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1523 }
1524
1525 #[fuchsia::test]
1528 fn test_connect_no_security_given_nothing_saved_fails() {
1529 let mut exec = TestExecutor::new();
1530 let mut test_values = client_test_setup();
1531
1532 let ssid = TEST_SSID.to_string();
1534 let fut = handle_connect(test_values.client_proxy, test_values.update_stream, ssid, None);
1535 let mut fut = pin!(fut);
1536
1537 assert!(exec.run_until_stalled(&mut fut).is_pending());
1539
1540 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1542 send_saved_networks(&mut exec, &mut iterator, vec![]);
1543
1544 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1546
1547 assert_variant!(
1549 exec.run_until_stalled(&mut test_values.client_stream.next()),
1550 Poll::Ready(None)
1551 );
1552 }
1553
1554 #[fuchsia::test]
1557 fn test_connect_no_security_given_multiple_saved_fails() {
1558 let mut exec = TestExecutor::new();
1559 let mut test_values = client_test_setup();
1560
1561 let ssid = TEST_SSID.to_string();
1563 let fut = handle_connect(test_values.client_proxy, test_values.update_stream, ssid, None);
1564 let mut fut = pin!(fut);
1565
1566 assert!(exec.run_until_stalled(&mut fut).is_pending());
1568
1569 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1571 let wpa_config =
1572 create_network_config_with_security(TEST_SSID, wlan_policy::SecurityType::Wpa);
1573 let networks = vec![create_network_config(TEST_SSID), wpa_config];
1574
1575 send_saved_networks(&mut exec, &mut iterator, networks);
1576 assert!(exec.run_until_stalled(&mut fut).is_pending());
1577
1578 send_saved_networks(&mut exec, &mut iterator, vec![]);
1580
1581 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1583
1584 assert_variant!(
1586 exec.run_until_stalled(&mut test_values.client_stream.next()),
1587 Poll::Ready(None)
1588 );
1589 }
1590
1591 #[fuchsia::test]
1593 fn test_connect_fail() {
1594 let mut exec = TestExecutor::new();
1595 let mut test_values = client_test_setup();
1596
1597 let ssid = TEST_SSID.to_string();
1599 let security = Some(wlan_policy::SecurityType::Wpa2);
1600 let fut =
1601 handle_connect(test_values.client_proxy, test_values.update_stream, ssid, security);
1602 let mut fut = pin!(fut);
1603
1604 assert!(exec.run_until_stalled(&mut fut).is_pending());
1606
1607 send_client_request_status(
1609 &mut exec,
1610 &mut test_values.client_stream,
1611 wlan_policy::RequestStatus::Acknowledged,
1612 );
1613
1614 assert!(exec.run_until_stalled(&mut fut).is_pending());
1616 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1617 TEST_SSID,
1618 wlan_policy::ConnectionState::Failed,
1619 ));
1620
1621 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1623 }
1624
1625 #[fuchsia::test]
1627 fn test_scan_pass() {
1628 let mut exec = TestExecutor::new();
1629 let test_values = client_test_setup();
1630
1631 let fut = handle_scan(test_values.client_proxy);
1632 let mut fut = pin!(fut);
1633
1634 assert!(exec.run_until_stalled(&mut fut).is_pending());
1636
1637 let mut iterator = get_scan_result_iterator(&mut exec, test_values.client_stream);
1639 send_scan_result(&mut exec, &mut iterator, Ok(&[create_scan_result(TEST_SSID)]));
1640
1641 assert!(exec.run_until_stalled(&mut fut).is_pending());
1643
1644 send_scan_result(&mut exec, &mut iterator, Ok(&[]));
1646
1647 assert_variant!(
1649 exec.run_until_stalled(&mut fut),
1650 Poll::Ready(Ok(result)) => {
1651 assert_eq!(result.len(), 1);
1652 assert_eq!(result[0].id.as_ref().unwrap().ssid, TEST_SSID.as_bytes().to_vec());
1653 }
1654 );
1655 }
1656
1657 #[fuchsia::test]
1659 fn test_scan_fail() {
1660 let mut exec = TestExecutor::new();
1661 let test_values = client_test_setup();
1662
1663 let fut = handle_scan(test_values.client_proxy);
1664 let mut fut = pin!(fut);
1665
1666 assert!(exec.run_until_stalled(&mut fut).is_pending());
1668
1669 let mut iterator = get_scan_result_iterator(&mut exec, test_values.client_stream);
1671 send_scan_result(&mut exec, &mut iterator, Err(wlan_policy::ScanErrorCode::GeneralError));
1672
1673 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1675 }
1676
1677 #[fuchsia::test]
1679 fn test_get_saved_networks() {
1680 let mut exec = TestExecutor::new();
1681 let mut test_values = client_test_setup();
1682
1683 let fut = handle_get_saved_networks(&test_values.client_proxy);
1684 let mut fut = pin!(fut);
1685
1686 assert!(exec.run_until_stalled(&mut fut).is_pending());
1688
1689 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1691 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1692 assert!(exec.run_until_stalled(&mut fut).is_pending());
1693
1694 send_saved_networks(&mut exec, &mut iterator, vec![]);
1696
1697 assert_variant!(
1699 exec.run_until_stalled(&mut fut),
1700 Poll::Ready(Ok(result)) => {
1701 assert_eq!(result.len(), 1);
1702 assert_eq!(result[0].id.as_ref().unwrap().ssid, TEST_SSID.as_bytes().to_vec());
1703 }
1704 );
1705 }
1706
1707 #[fuchsia::test]
1709 fn test_client_listen() {
1710 let mut exec = TestExecutor::new();
1711 let test_values = client_test_setup();
1712
1713 let fut = handle_listen(test_values.update_stream, false);
1714 let mut fut = pin!(fut);
1715
1716 assert!(exec.run_until_stalled(&mut fut).is_pending());
1718 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1719 TEST_SSID,
1720 wlan_policy::ConnectionState::Connecting,
1721 ));
1722
1723 assert!(exec.run_until_stalled(&mut fut).is_pending());
1725 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1726 TEST_SSID,
1727 wlan_policy::ConnectionState::Connected,
1728 ));
1729
1730 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Pending);
1732 }
1733
1734 #[fuchsia::test]
1736 fn test_client_status() {
1737 let mut exec = TestExecutor::new();
1738 let test_values = client_test_setup();
1739
1740 let fut = handle_listen(test_values.update_stream, true);
1741 let mut fut = pin!(fut);
1742
1743 assert!(exec.run_until_stalled(&mut fut).is_pending());
1745 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1746 TEST_SSID,
1747 wlan_policy::ConnectionState::Connecting,
1748 ));
1749
1750 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1752 }
1753
1754 #[fuchsia::test]
1757 fn test_stop_ap_fail() {
1758 let mut exec = TestExecutor::new();
1759 let mut test_values = ap_test_setup();
1760
1761 let network_config = create_network_config(&TEST_SSID);
1762 let fut = handle_stop_ap(test_values.ap_proxy, network_config);
1763 let mut fut = pin!(fut);
1764
1765 assert!(exec.run_until_stalled(&mut fut).is_pending());
1767
1768 send_ap_request_status(
1770 &mut exec,
1771 &mut test_values.ap_stream,
1772 wlan_policy::RequestStatus::RejectedNotSupported,
1773 );
1774
1775 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1777 }
1778
1779 #[fuchsia::test]
1781 fn test_stop_ap_pass() {
1782 let mut exec = TestExecutor::new();
1783 let mut test_values = ap_test_setup();
1784
1785 let network_config = create_network_config(&TEST_SSID);
1786 let fut = handle_stop_ap(test_values.ap_proxy, network_config);
1787 let mut fut = pin!(fut);
1788
1789 assert!(exec.run_until_stalled(&mut fut).is_pending());
1791
1792 send_ap_request_status(
1794 &mut exec,
1795 &mut test_values.ap_stream,
1796 wlan_policy::RequestStatus::Acknowledged,
1797 );
1798
1799 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1801 }
1802
1803 #[fuchsia::test]
1805 fn test_start_ap_request_fail() {
1806 let mut exec = TestExecutor::new();
1807 let mut test_values = ap_test_setup();
1808
1809 let network_config = create_network_config(&TEST_SSID);
1810 let fut = handle_start_ap(test_values.ap_proxy, test_values.update_stream, network_config);
1811 let mut fut = pin!(fut);
1812
1813 assert!(exec.run_until_stalled(&mut fut).is_pending());
1815
1816 send_ap_request_status(
1818 &mut exec,
1819 &mut test_values.ap_stream,
1820 wlan_policy::RequestStatus::RejectedNotSupported,
1821 );
1822
1823 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1825 }
1826
1827 #[fuchsia::test]
1830 fn test_start_ap_pass() {
1831 let mut exec = TestExecutor::new();
1832 let mut test_values = ap_test_setup();
1833
1834 let network_config = create_network_config(&TEST_SSID);
1835 let fut = handle_start_ap(test_values.ap_proxy, test_values.update_stream, network_config);
1836 let mut fut = pin!(fut);
1837
1838 assert!(exec.run_until_stalled(&mut fut).is_pending());
1840
1841 send_ap_request_status(
1843 &mut exec,
1844 &mut test_values.ap_stream,
1845 wlan_policy::RequestStatus::Acknowledged,
1846 );
1847
1848 assert!(exec.run_until_stalled(&mut fut).is_pending());
1850
1851 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1853 wlan_policy::OperatingState::Starting,
1854 )]);
1855
1856 assert!(exec.run_until_stalled(&mut fut).is_pending());
1858
1859 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1861 wlan_policy::OperatingState::Active,
1862 )]);
1863
1864 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1866 }
1867
1868 #[fuchsia::test]
1871 fn test_ap_failed_to_start() {
1872 let mut exec = TestExecutor::new();
1873 let mut test_values = ap_test_setup();
1874
1875 let network_config = create_network_config(&TEST_SSID);
1876 let fut = handle_start_ap(test_values.ap_proxy, test_values.update_stream, network_config);
1877 let mut fut = pin!(fut);
1878
1879 assert!(exec.run_until_stalled(&mut fut).is_pending());
1881
1882 send_ap_request_status(
1884 &mut exec,
1885 &mut test_values.ap_stream,
1886 wlan_policy::RequestStatus::Acknowledged,
1887 );
1888
1889 assert!(exec.run_until_stalled(&mut fut).is_pending());
1891
1892 let state_updates = &[create_ap_state_summary(wlan_policy::OperatingState::Failed)];
1894 let _ = test_values.update_proxy.on_access_point_state_update(state_updates);
1895
1896 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1898 }
1899
1900 #[fuchsia::test]
1902 fn test_stop_all_aps() {
1903 let mut exec = TestExecutor::new();
1904 let mut test_values = ap_test_setup();
1905
1906 let fut = handle_stop_all_aps(test_values.ap_proxy);
1907 let mut fut = pin!(fut);
1908
1909 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1911
1912 assert_variant!(
1914 exec.run_until_stalled(&mut test_values.ap_stream.next()),
1915 Poll::Ready(Some(Ok(
1916 wlan_policy::AccessPointControllerRequest::StopAllAccessPoints { .. }
1917 )))
1918 );
1919 }
1920
1921 #[fuchsia::test]
1923 fn test_ap_listen() {
1924 let mut exec = TestExecutor::new();
1925 let test_values = ap_test_setup();
1926
1927 let fut = handle_ap_listen(test_values.update_stream, false);
1928 let mut fut = pin!(fut);
1929
1930 assert!(exec.run_until_stalled(&mut fut).is_pending());
1932 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1933 wlan_policy::OperatingState::Starting,
1934 )]);
1935
1936 assert!(exec.run_until_stalled(&mut fut).is_pending());
1938 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1939 wlan_policy::OperatingState::Active,
1940 )]);
1941
1942 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Pending);
1944 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1945 wlan_policy::OperatingState::Failed,
1946 )]);
1947
1948 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Pending);
1949 }
1950
1951 #[fuchsia::test]
1953 fn test_ap_status() {
1954 let mut exec = TestExecutor::new();
1955 let test_values = ap_test_setup();
1956
1957 let fut = handle_ap_listen(test_values.update_stream, true);
1958 let mut fut = pin!(fut);
1959
1960 assert!(exec.run_until_stalled(&mut fut).is_pending());
1962 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1963 wlan_policy::OperatingState::Starting,
1964 )]);
1965
1966 assert_variant!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1968 }
1969
1970 #[fuchsia::test]
1971 fn test_suggest_ap_mac_succeeds() {
1972 let mut exec = TestExecutor::new();
1973
1974 let (configurator_proxy, mut configurator_stream) =
1975 endpoints::create_proxy_and_stream::<wlan_deprecated::DeprecatedConfiguratorMarker>();
1976 let mac = MacAddress::from_bytes(&[0, 1, 2, 3, 4, 5]).unwrap();
1977 let suggest_fut = handle_suggest_ap_mac(configurator_proxy, mac);
1978 let mut suggest_fut = pin!(suggest_fut);
1979
1980 assert_variant!(exec.run_until_stalled(&mut suggest_fut), Poll::Pending);
1981
1982 assert_variant!(
1983 exec.run_until_stalled(&mut configurator_stream.next()),
1984 Poll::Ready(Some(Ok(wlan_deprecated::DeprecatedConfiguratorRequest::SuggestAccessPointMacAddress {
1985 mac: fidl_fuchsia_net::MacAddress { octets: [0, 1, 2, 3, 4, 5] }, responder
1986 }))) => {
1987 assert!(responder.send(Ok(())).is_ok());
1988 }
1989 );
1990
1991 assert_variant!(exec.run_until_stalled(&mut suggest_fut), Poll::Ready(Ok(())));
1992 }
1993
1994 #[fuchsia::test]
1995 fn test_suggest_ap_mac_fails() {
1996 let mut exec = TestExecutor::new();
1997
1998 let (configurator_proxy, mut configurator_stream) =
1999 endpoints::create_proxy_and_stream::<wlan_deprecated::DeprecatedConfiguratorMarker>();
2000 let mac = MacAddress::from_bytes(&[0, 1, 2, 3, 4, 5]).unwrap();
2001 let suggest_fut = handle_suggest_ap_mac(configurator_proxy, mac);
2002 let mut suggest_fut = pin!(suggest_fut);
2003
2004 assert_variant!(exec.run_until_stalled(&mut suggest_fut), Poll::Pending);
2005
2006 assert_variant!(
2007 exec.run_until_stalled(&mut configurator_stream.next()),
2008 Poll::Ready(Some(Ok(wlan_deprecated::DeprecatedConfiguratorRequest::SuggestAccessPointMacAddress {
2009 mac: fidl_fuchsia_net::MacAddress { octets: [0, 1, 2, 3, 4, 5] }, responder
2010 }))) => {
2011 assert!(responder.send(Err(wlan_deprecated::SuggestMacAddressError::InvalidArguments)).is_ok());
2012 }
2013 );
2014
2015 assert_variant!(exec.run_until_stalled(&mut suggest_fut), Poll::Ready(Err(_)));
2016 }
2017
2018 #[fuchsia_async::run_singlethreaded(test)]
2019 async fn test_proxy_command_succeeds() {
2020 match run_proxy_command(Box::pin(async { Ok(zx_status::Status::OK) })).await {
2021 Ok(status) => {
2022 assert_eq!(status, zx_status::Status::OK)
2023 }
2024 Err(e) => panic!("Test unexpectedly failed with {}", e),
2025 }
2026 }
2027
2028 #[fuchsia_async::run_singlethreaded(test)]
2029 async fn test_proxy_command_already_bound() {
2030 let result: Result<(), Error> = run_proxy_command(Box::pin(async {
2031 Err(fidl::Error::ClientChannelClosed {
2032 status: zx_status::Status::ALREADY_BOUND,
2033 protocol_name: "test",
2034 epitaph: Some(zx_status::Status::ALREADY_BOUND.into_raw() as u32),
2035 })
2036 }))
2037 .await;
2038 match result {
2039 Ok(status) => panic!("Test unexpectedly succeeded with {:?}", status),
2040 Err(e) => {
2041 assert!(e.to_string().contains("Failed to obtain a WLAN policy controller"));
2042 }
2043 }
2044 }
2045
2046 #[fuchsia_async::run_singlethreaded(test)]
2047 async fn test_proxy_command_generic_failure() {
2048 let result: Result<(), Error> =
2049 run_proxy_command(Box::pin(async { Err(fidl::Error::Invalid) })).await;
2050 match result {
2051 Ok(status) => panic!("Test unexpectedly succeeded with {:?}", status),
2052 Err(e) => {
2053 assert!(!e.to_string().contains("Failed to obtain a WLAN policy controller"));
2054 }
2055 }
2056 }
2057}