1use ::fidl as _;
6use anyhow::{Error, format_err};
7use eui48::MacAddress;
8use flex_client::ProxyHasDomain;
9use flex_fuchsia_net as net;
10use flex_fuchsia_wlan_policy as wlan_policy;
11use flex_fuchsia_wlan_product_deprecatedconfiguration as wlan_deprecated;
12use futures::TryStreamExt;
13use futures::future::LocalBoxFuture;
14
15pub mod opts;
16pub mod serialize;
17
18fn extract_network_id(
22 network_id: Option<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 wlan_policy::SecurityType::None => "",
29 wlan_policy::SecurityType::Wep => "wep",
30 wlan_policy::SecurityType::Wpa => "wpa",
31 wlan_policy::SecurityType::Wpa2 => "wpa2",
32 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!(
199 "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."
200 ));
201 } else {
204 return Err(format_err!(
205 "Multiple saved networks were found matching the provided name, please specify the security type of the network to connect to."
206 ));
207 }
208 };
209
210 let result = run_proxy_command(Box::pin(client_controller.connect(&network_id))).await?;
211 handle_request_status(result)?;
212
213 while let Some(update_request) = server_stream.try_next().await? {
214 let update = update_request.into_on_client_state_update();
215 let (update, responder) = match update {
216 Some((update, responder)) => (update, responder),
217 None => return Err(format_err!("Client provider produced invalid update.")),
218 };
219 let _ = responder.send();
220
221 match update.state {
222 Some(state) => {
223 if state == wlan_policy::WlanClientState::ConnectionsDisabled {
224 return Err(format_err!("Connections disabled while trying to conncet."));
225 }
226 }
227 None => continue,
228 }
229
230 let networks = match update.networks {
231 Some(networks) => networks,
232 None => continue,
233 };
234
235 for net_state in networks {
236 if net_state.id.is_none() || net_state.state.is_none() {
237 continue;
238 }
239 if net_state.id.unwrap().ssid == network_id.ssid {
240 match net_state.state.unwrap() {
241 wlan_policy::ConnectionState::Failed => {
242 return Err(format_err!(
243 "Failed to connect with reason {:?}",
244 net_state.status
245 ));
246 }
247 wlan_policy::ConnectionState::Disconnected => {
248 return Err(format_err!("Disconnect with reason {:?}", net_state.status));
249 }
250 wlan_policy::ConnectionState::Connecting => continue,
251 wlan_policy::ConnectionState::Connected => {
252 println!("Successfully connected");
253 return Ok(());
254 }
255 }
256 }
257 }
258 }
259 Err(format_err!("Status stream terminated before connection could be verified."))
260}
261
262pub async fn handle_get_saved_networks(
265 client_controller: &wlan_policy::ClientControllerProxy,
266) -> Result<Vec<wlan_policy::NetworkConfig>, Error> {
267 let (client_proxy, server_end) =
268 client_controller.domain().create_proxy::<wlan_policy::NetworkConfigIteratorMarker>();
269 let fut = async { client_controller.get_saved_networks(server_end) };
270 run_proxy_command(Box::pin(fut)).await?;
271
272 let mut saved_networks = Vec::new();
273 loop {
274 let mut new_configs = run_proxy_command(Box::pin(client_proxy.get_next())).await?;
275 if new_configs.is_empty() {
276 break;
277 }
278 saved_networks.append(&mut new_configs);
279 }
280 Ok(saved_networks)
281}
282
283pub async fn handle_listen(
290 mut server_stream: wlan_policy::ClientStateUpdatesRequestStream,
291 single_sample: bool,
292) -> Result<(), Error> {
293 let mut last_known_connection_state = None;
294 while let Some(update_request) = server_stream.try_next().await? {
295 let update = update_request.into_on_client_state_update();
296 let (update, responder) = match update {
297 Some((update, responder)) => (update, responder),
298 None => return Err(format_err!("Client provider produced invalid update.")),
299 };
300 let _ = responder.send();
301
302 match update.state {
303 Some(state) => {
304 if last_known_connection_state != Some(state) {
305 last_known_connection_state = Some(state);
306 match state {
307 wlan_policy::WlanClientState::ConnectionsEnabled => {
308 println!("Client connections are enabled");
309 }
310 wlan_policy::WlanClientState::ConnectionsDisabled => {
311 println!("Client connections are disabled");
312 }
313 }
314 };
315 }
316 None => {
317 println!("Unexpected client connection state 'None'");
318 }
319 }
320
321 let networks = match update.networks {
322 Some(networks) => networks,
323 None => continue,
324 };
325
326 let mut updates = vec![];
327 for net_state in networks {
329 if net_state.id.is_none() || net_state.state.is_none() {
330 continue;
331 }
332 let id = net_state.id.unwrap();
333 let ssid = std::str::from_utf8(&id.ssid).unwrap();
334 match net_state.state.unwrap() {
335 wlan_policy::ConnectionState::Failed => {
336 updates.push(format!(
337 "\t{:32} connection failed - {:?}",
338 format!("{}:", ssid),
339 net_state.status
340 ));
341 }
342 wlan_policy::ConnectionState::Disconnected => {
343 updates.push(format!(
344 "\t{:32} connection disconnected - {:?}",
345 format!("{}:", ssid),
346 net_state.status
347 ));
348 }
349 wlan_policy::ConnectionState::Connecting => {
350 updates.push(format!("\t{:32} connecting", format!("{}:", ssid)));
351 }
352 wlan_policy::ConnectionState::Connected => {
353 updates.push(format!("\t{:32} connected", format!("{}:", ssid)))
354 }
355 }
356 }
357
358 updates.sort_by_key(|s| s.to_lowercase());
360 println!("Update:");
361 for update in updates {
362 println!("{}", update);
363 }
364
365 if single_sample {
367 break;
368 }
369 }
370 Ok(())
371}
372
373pub async fn handle_forget_network(
377 client_controller: wlan_policy::ClientControllerProxy,
378 ssid: Vec<u8>,
379 security_type: Option<wlan_policy::SecurityType>,
380) -> Result<(), Error> {
381 let networks_before = handle_get_saved_networks(&client_controller).await.map_err(|e| {
382 format_err!(
383 "The network was not removed because an error occurred getting the list of networks \
384 before removing the requested network: {}",
385 e,
386 )
387 })?;
388
389 let network_id = if security_type.is_some() {
392 wlan_policy::NetworkIdentifier { ssid: ssid.clone(), type_: security_type.unwrap() }
393 } else {
394 let mut matching_networks = networks_before
398 .iter()
399 .filter(|c| config_matches(c, &ssid, &security_type))
400 .cloned()
401 .collect::<Vec<_>>();
402
403 if matching_networks.len() == 1 {
405 let config = matching_networks.pop().unwrap();
406 config.id.ok_or_else(|| format_err!("missing network ID in config"))?
407 } else if matching_networks.is_empty() {
408 return Err(format_err!(
409 "Failed to find a saved network with the provided arguments. Please check that the arguments are correct if there should be one saved."
410 ));
411 } else {
414 return Err(format_err!(
415 "Multiple saved networks were found matching the provided \
416 arguments, please specify SSID and security that matches only one \
417 saved network."
418 ));
419 }
420 };
421
422 run_proxy_command(Box::pin(client_controller.forget_network(&network_id)))
423 .await?
424 .map_err(|e| format_err!("failed to forget 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)) {
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(
462 config: &wlan_policy::NetworkConfig,
463 ssid: &Vec<u8>,
464 security_type: &Option<wlan_policy::SecurityType>,
465) -> bool {
466 let config_id = match &config.id {
467 Some(id) => id,
468 None => {
469 return false;
470 }
471 };
472
473 if config_id.ssid != *ssid {
474 return false;
475 }
476
477 if let Some(security) = *security_type {
479 if config_id.type_ != security {
480 return false;
481 }
482 }
483
484 return true;
485}
486
487pub async fn handle_save_network(
489 client_controller: wlan_policy::ClientControllerProxy,
490 config: wlan_policy::NetworkConfig,
491) -> Result<(), Error> {
492 save_network(client_controller, config).await
493}
494
495async fn save_network(
496 client_controller: wlan_policy::ClientControllerProxy,
497 network_config: wlan_policy::NetworkConfig,
498) -> Result<(), Error> {
499 run_proxy_command(Box::pin(client_controller.save_network(&network_config)))
500 .await?
501 .map_err(|e| format_err!("failed to save network with {:?}", e))?;
502 println!(
503 "Successfully saved network '{}'",
504 std::str::from_utf8(&network_config.id.unwrap().ssid).unwrap()
505 );
506 Ok(())
507}
508
509pub async fn handle_scan(
511 client_controller: wlan_policy::ClientControllerProxy,
512) -> Result<Vec<wlan_policy::ScanResult>, Error> {
513 let (client_proxy, server_end) =
514 client_controller.domain().create_proxy::<wlan_policy::ScanResultIteratorMarker>();
515 let fut = async { client_controller.scan_for_networks(server_end) };
516 run_proxy_command(Box::pin(fut)).await?;
517
518 let mut scanned_networks = Vec::<wlan_policy::ScanResult>::new();
519 loop {
520 match run_proxy_command(Box::pin(client_proxy.get_next())).await? {
521 Ok(mut new_networks) => {
522 if new_networks.is_empty() {
523 break;
524 }
525 scanned_networks.append(&mut new_networks);
526 }
527 Err(e) => return Err(format_err!("Scan failure error: {:?}", e)),
528 }
529 }
530
531 Ok(scanned_networks)
532}
533
534pub async fn handle_start_client_connections(
536 client_controller: wlan_policy::ClientControllerProxy,
537) -> Result<(), Error> {
538 let status = run_proxy_command(Box::pin(client_controller.start_client_connections())).await?;
539 return handle_request_status(status);
540}
541
542pub async fn handle_stop_client_connections(
544 client_controller: wlan_policy::ClientControllerProxy,
545) -> Result<(), Error> {
546 let status = run_proxy_command(Box::pin(client_controller.stop_client_connections())).await?;
547 return handle_request_status(status);
548}
549
550pub async fn handle_start_ap(
552 ap_controller: wlan_policy::AccessPointControllerProxy,
553 mut server_stream: wlan_policy::AccessPointStateUpdatesRequestStream,
554 config: wlan_policy::NetworkConfig,
555) -> Result<(), Error> {
556 let connectivity_mode = wlan_policy::ConnectivityMode::Unrestricted;
557 let operating_band = wlan_policy::OperatingBand::Any;
558 let result = run_proxy_command(Box::pin(ap_controller.start_access_point(
559 &config,
560 connectivity_mode,
561 operating_band,
562 )))
563 .await?;
564 handle_request_status(result)?;
565
566 while let Some(update_request) = server_stream.try_next().await? {
568 let update = update_request.into_on_access_point_state_update();
569 let (updates, responder) = match update {
570 Some((update, responder)) => (update, responder),
571 None => return Err(format_err!("AP provider produced invalid update.")),
572 };
573 let _ = responder.send();
574
575 for update in updates {
576 match update.state {
577 Some(state) => match state {
578 wlan_policy::OperatingState::Failed => {
579 return Err(format_err!("Failed to start AP."));
580 }
581 wlan_policy::OperatingState::Starting => {
582 println!("AP is starting.");
583 continue;
584 }
585 wlan_policy::OperatingState::Active => return Ok(()),
586 },
587 None => continue,
588 }
589 }
590 }
591 Err(format_err!("Status stream terminated before AP start could be verified."))
592}
593
594pub async fn handle_stop_ap(
596 ap_controller: wlan_policy::AccessPointControllerProxy,
597 config: wlan_policy::NetworkConfig,
598) -> Result<(), Error> {
599 let result = run_proxy_command(Box::pin(ap_controller.stop_access_point(&config))).await?;
600 handle_request_status(result)
601}
602
603pub async fn handle_stop_all_aps(
605 ap_controller: wlan_policy::AccessPointControllerProxy,
606) -> Result<(), Error> {
607 let fut = async { ap_controller.stop_all_access_points() };
608 run_proxy_command(Box::pin(fut)).await?;
609 Ok(())
610}
611
612pub async fn handle_ap_listen(
614 mut server_stream: wlan_policy::AccessPointStateUpdatesRequestStream,
615 single_sample: bool,
616) -> Result<(), Error> {
617 println!(
618 "{:32} | {:4} | {:8} | {:12} | {:6} | {:4} | {:7}",
619 "SSID", "Type", "State", "Mode", "Band", "Freq", "#Clients"
620 );
621
622 while let Some(update_request) = server_stream.try_next().await? {
623 let updates = update_request.into_on_access_point_state_update();
624 let (updates, responder) = match updates {
625 Some((update, responder)) => (update, responder),
626 None => return Err(format_err!("AP provider produced invalid update.")),
627 };
628 let _ = responder.send();
629
630 for update in updates {
631 let (ssid, security_type) = match update.id {
632 Some(network_id) => {
633 let ssid = network_id.ssid.clone();
634 let ssid = String::from_utf8(ssid)?;
635 let security_type = match network_id.type_ {
636 wlan_policy::SecurityType::None => "none",
637 wlan_policy::SecurityType::Wep => "wep",
638 wlan_policy::SecurityType::Wpa => "wpa",
639 wlan_policy::SecurityType::Wpa2 => "wpa2",
640 wlan_policy::SecurityType::Wpa3 => "wpa3",
641 };
642 (ssid, security_type.to_string())
643 }
644 None => ("".to_string(), "".to_string()),
645 };
646 let state = match update.state {
647 Some(state) => match state {
648 wlan_policy::OperatingState::Failed => "failed",
649 wlan_policy::OperatingState::Starting => "starting",
650 wlan_policy::OperatingState::Active => "active",
651 },
652 None => "",
653 };
654 let mode = match update.mode {
655 Some(mode) => match mode {
656 wlan_policy::ConnectivityMode::LocalOnly => "local only",
657 wlan_policy::ConnectivityMode::Unrestricted => "unrestricted",
658 },
659 None => "",
660 };
661 let band = match update.band {
662 Some(band) => match band {
663 wlan_policy::OperatingBand::Any => "any",
664 wlan_policy::OperatingBand::Only24Ghz => "2.4Ghz",
665 wlan_policy::OperatingBand::Only5Ghz => "5Ghz",
666 },
667 None => "",
668 };
669 let frequency = match update.frequency {
670 Some(frequency) => frequency.to_string(),
671 None => "".to_string(),
672 };
673 let client_count = match update.clients {
674 Some(connected_clients) => match connected_clients.count {
675 Some(count) => count.to_string(),
676 None => "".to_string(),
677 },
678 None => "".to_string(),
679 };
680
681 println!(
682 "{:32} | {:4} | {:8} | {:12} | {:6} | {:4} | {:7}",
683 ssid, security_type, state, mode, band, frequency, client_count
684 );
685 }
686
687 if single_sample {
689 break;
690 }
691 }
692 Ok(())
693}
694
695pub async fn handle_suggest_ap_mac(
696 configurator: wlan_deprecated::DeprecatedConfiguratorProxy,
697 mac: MacAddress,
698) -> Result<(), Error> {
699 let mac = net::MacAddress { octets: mac.to_array() };
700 let result = configurator.suggest_access_point_mac_address(&mac).await?;
701 result.map_err(|e| format_err!("suggesting MAC failed: {:?}", e))
702}
703
704#[cfg(test)]
705mod tests {
706 use super::*;
707 use assert_matches::assert_matches;
708 use fidl::endpoints;
709 use fuchsia_async::TestExecutor;
710 use futures::stream::StreamExt;
711 use futures::task::Poll;
712 use std::pin::pin;
713 use test_case::test_case;
714 use zx_status;
715
716 static TEST_SSID: &str = "test_ssid";
717 static TEST_PASSWORD: &str = "test_password";
718
719 struct ClientTestValues {
720 client_proxy: wlan_policy::ClientControllerProxy,
721 client_stream: wlan_policy::ClientControllerRequestStream,
722 update_proxy: wlan_policy::ClientStateUpdatesProxy,
723 update_stream: wlan_policy::ClientStateUpdatesRequestStream,
724 }
725
726 fn client_test_setup() -> ClientTestValues {
727 let (client_proxy, client_stream) =
728 endpoints::create_proxy_and_stream::<wlan_policy::ClientControllerMarker>();
729
730 let (listener_proxy, listener_stream) =
731 endpoints::create_proxy_and_stream::<wlan_policy::ClientStateUpdatesMarker>();
732
733 ClientTestValues {
734 client_proxy: client_proxy,
735 client_stream: client_stream,
736 update_proxy: listener_proxy,
737 update_stream: listener_stream,
738 }
739 }
740
741 fn send_client_request_status(
744 exec: &mut TestExecutor,
745 server: &mut wlan_policy::ClientControllerRequestStream,
746 response: wlan_policy::RequestStatus,
747 ) {
748 let poll = exec.run_until_stalled(&mut server.next());
749 let request = match poll {
750 Poll::Ready(poll_ready) => poll_ready
751 .expect("poll ready result is None")
752 .expect("poll ready result is an Error"),
753 Poll::Pending => panic!("no ClientController request available"),
754 };
755
756 let result = match request {
757 wlan_policy::ClientControllerRequest::StartClientConnections { responder } => {
758 responder.send(response)
759 }
760 wlan_policy::ClientControllerRequest::StopClientConnections { responder } => {
761 responder.send(response)
762 }
763 wlan_policy::ClientControllerRequest::Connect { responder, .. } => {
764 responder.send(response)
765 }
766 _ => panic!("expecting a request that expects a RequestStatus"),
767 };
768
769 if result.is_err() {
770 panic!("could not send request status");
771 }
772 }
773
774 fn create_client_state_summary(
776 ssid: &str,
777 state: wlan_policy::ConnectionState,
778 ) -> wlan_policy::ClientStateSummary {
779 let network_state = wlan_policy::NetworkState {
780 id: Some(create_network_id(ssid)),
781 state: Some(state),
782 status: None,
783 ..Default::default()
784 };
785 wlan_policy::ClientStateSummary {
786 state: Some(wlan_policy::WlanClientState::ConnectionsEnabled),
787 networks: Some(vec![network_state]),
788 ..Default::default()
789 }
790 }
791
792 fn create_ap_state_summary(
794 state: wlan_policy::OperatingState,
795 ) -> wlan_policy::AccessPointState {
796 wlan_policy::AccessPointState {
797 id: None,
798 state: Some(state),
799 mode: None,
800 band: None,
801 frequency: None,
802 clients: None,
803 ..Default::default()
804 }
805 }
806
807 #[track_caller]
809 fn send_network_config_response(
810 exec: &mut TestExecutor,
811 server: &mut wlan_policy::ClientControllerRequestStream,
812 success: bool,
813 ) {
814 let poll = exec.run_until_stalled(&mut server.next());
815 let request = match poll {
816 Poll::Ready(poll_ready) => poll_ready
817 .expect("poll ready result is None")
818 .expect("poll ready result is an Error"),
819 Poll::Pending => panic!("no ClientController request available"),
820 };
821
822 let result = match request {
823 wlan_policy::ClientControllerRequest::SaveNetwork { config: _, responder } => {
824 if success {
825 responder.send(Ok(()))
826 } else {
827 responder.send(Err(wlan_policy::NetworkConfigChangeError::GeneralError))
828 }
829 }
830 wlan_policy::ClientControllerRequest::ForgetNetwork { id: _, responder } => {
831 if success {
832 responder.send(Ok(()))
833 } else {
834 responder.send(Err(wlan_policy::NetworkConfigChangeError::GeneralError))
835 }
836 }
837 _ => panic!("expecting a request that optionally receives a NetworkConfigChangeError"),
838 };
839
840 if result.is_err() {
841 panic!("could not send network config response");
842 }
843 }
844
845 struct ApTestValues {
846 ap_proxy: wlan_policy::AccessPointControllerProxy,
847 ap_stream: wlan_policy::AccessPointControllerRequestStream,
848 update_proxy: wlan_policy::AccessPointStateUpdatesProxy,
849 update_stream: wlan_policy::AccessPointStateUpdatesRequestStream,
850 }
851
852 fn ap_test_setup() -> ApTestValues {
853 let (ap_proxy, ap_stream) =
854 endpoints::create_proxy_and_stream::<wlan_policy::AccessPointControllerMarker>();
855
856 let (listener_proxy, listener_stream) =
857 endpoints::create_proxy_and_stream::<wlan_policy::AccessPointStateUpdatesMarker>();
858
859 ApTestValues {
860 ap_proxy,
861 ap_stream,
862 update_proxy: listener_proxy,
863 update_stream: listener_stream,
864 }
865 }
866
867 fn send_ap_request_status(
870 exec: &mut TestExecutor,
871 server: &mut wlan_policy::AccessPointControllerRequestStream,
872 response: wlan_policy::RequestStatus,
873 ) {
874 let poll = exec.run_until_stalled(&mut server.next());
875 let request = match poll {
876 Poll::Ready(poll_ready) => poll_ready
877 .expect("poll ready result is None")
878 .expect("poll ready result is an Error"),
879 Poll::Pending => panic!("no AccessPointController request available"),
880 };
881
882 let result = match request {
883 wlan_policy::AccessPointControllerRequest::StartAccessPoint { responder, .. } => {
884 responder.send(response)
885 }
886 wlan_policy::AccessPointControllerRequest::StopAccessPoint { config: _, responder } => {
887 responder.send(response)
888 }
889 _ => panic!("expecting a request that expects a RequestStatus"),
890 };
891
892 if result.is_err() {
893 panic!("could not send request status");
894 }
895 }
896
897 fn create_network_id(ssid: &str) -> wlan_policy::NetworkIdentifier {
899 wlan_policy::NetworkIdentifier {
900 ssid: ssid.as_bytes().to_vec(),
901 type_: wlan_policy::SecurityType::Wpa2,
902 }
903 }
904
905 fn create_network_config(ssid: &str) -> wlan_policy::NetworkConfig {
907 wlan_policy::NetworkConfig {
908 id: Some(create_network_id(ssid)),
909 credential: Some(create_password(TEST_PASSWORD)),
910 ..Default::default()
911 }
912 }
913
914 fn create_password(val: &str) -> wlan_policy::Credential {
915 wlan_policy::Credential::Password(val.as_bytes().to_vec())
916 }
917
918 fn create_network_config_with_security(
920 ssid: &str,
921 security: wlan_policy::SecurityType,
922 ) -> wlan_policy::NetworkConfig {
923 let id = wlan_policy::NetworkIdentifier { ssid: ssid.as_bytes().to_vec(), type_: security };
924 wlan_policy::NetworkConfig { id: Some(id), credential: None, ..Default::default() }
925 }
926
927 fn create_scan_result(ssid: &str) -> wlan_policy::ScanResult {
929 wlan_policy::ScanResult {
930 id: Some(create_network_id(ssid)),
931 entries: None,
932 compatibility: None,
933 ..Default::default()
934 }
935 }
936
937 fn get_scan_result_iterator(
940 exec: &mut TestExecutor,
941 mut server: wlan_policy::ClientControllerRequestStream,
942 ) -> wlan_policy::ScanResultIteratorRequestStream {
943 let poll = exec.run_until_stalled(&mut server.next());
944 let request = match poll {
945 Poll::Ready(poll_ready) => poll_ready
946 .expect("poll ready result is None")
947 .expect("poll ready result is an Error"),
948 Poll::Pending => panic!("no ClientController request available"),
949 };
950
951 match request {
952 wlan_policy::ClientControllerRequest::ScanForNetworks {
953 iterator,
954 control_handle: _,
955 } => iterator.into_stream(),
956 _ => panic!("expecting a ScanForNetworks"),
957 }
958 }
959
960 fn send_scan_result(
962 exec: &mut TestExecutor,
963 server: &mut wlan_policy::ScanResultIteratorRequestStream,
964 scan_result: Result<&[wlan_policy::ScanResult], wlan_policy::ScanErrorCode>,
965 ) {
966 assert_matches!(
967 exec.run_until_stalled(&mut server.next()),
968 Poll::Ready(Some(Ok(wlan_policy::ScanResultIteratorRequest::GetNext {
969 responder
970 }))) => {
971 match responder.send(scan_result) {
972 Ok(()) => {}
973 Err(e) => panic!("failed to send scan result: {}", e),
974 }
975 }
976 );
977 }
978
979 #[track_caller]
982 fn get_saved_networks_iterator(
983 exec: &mut TestExecutor,
984 server: &mut wlan_policy::ClientControllerRequestStream,
985 ) -> wlan_policy::NetworkConfigIteratorRequestStream {
986 let poll = exec.run_until_stalled(&mut server.next());
987 let request = match poll {
988 Poll::Ready(poll_ready) => poll_ready
989 .expect("poll ready result is None")
990 .expect("poll ready result is an Error"),
991 Poll::Pending => panic!("no ClientController request available"),
992 };
993
994 match request {
995 wlan_policy::ClientControllerRequest::GetSavedNetworks {
996 iterator,
997 control_handle: _,
998 } => iterator.into_stream(),
999 _ => panic!("expecting a ScanForNetworks"),
1000 }
1001 }
1002
1003 fn send_saved_networks(
1005 exec: &mut TestExecutor,
1006 server: &mut wlan_policy::NetworkConfigIteratorRequestStream,
1007 saved_networks_response: Vec<wlan_policy::NetworkConfig>,
1008 ) {
1009 assert_matches!(
1010 exec.run_until_stalled(&mut server.next()),
1011 Poll::Ready(Some(Ok(wlan_policy::NetworkConfigIteratorRequest::GetNext {
1012 responder
1013 }))) => {
1014 match responder.send(&saved_networks_response) {
1015 Ok(()) => {}
1016 Err(e) => panic!("failed to send saved networks: {}", e),
1017 }
1018 }
1019 );
1020 }
1021
1022 #[fuchsia::test]
1024 fn test_start_client_connections_success() {
1025 let mut exec = TestExecutor::new();
1026 let mut test_values = client_test_setup();
1027 let fut = handle_start_client_connections(test_values.client_proxy);
1028 let mut fut = pin!(fut);
1029
1030 assert!(exec.run_until_stalled(&mut fut).is_pending());
1032
1033 send_client_request_status(
1035 &mut exec,
1036 &mut test_values.client_stream,
1037 wlan_policy::RequestStatus::Acknowledged,
1038 );
1039
1040 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1041 }
1042
1043 #[fuchsia::test]
1045 fn test_start_client_connections_fail() {
1046 let mut exec = TestExecutor::new();
1047 let mut test_values = client_test_setup();
1048 let fut = handle_start_client_connections(test_values.client_proxy);
1049 let mut fut = pin!(fut);
1050
1051 assert!(exec.run_until_stalled(&mut fut).is_pending());
1053
1054 send_client_request_status(
1056 &mut exec,
1057 &mut test_values.client_stream,
1058 wlan_policy::RequestStatus::RejectedNotSupported,
1059 );
1060
1061 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1062 }
1063
1064 #[fuchsia::test]
1066 fn test_stop_client_connections_success() {
1067 let mut exec = TestExecutor::new();
1068 let mut test_values = client_test_setup();
1069 let fut = handle_stop_client_connections(test_values.client_proxy);
1070 let mut fut = pin!(fut);
1071
1072 assert!(exec.run_until_stalled(&mut fut).is_pending());
1074
1075 send_client_request_status(
1077 &mut exec,
1078 &mut test_values.client_stream,
1079 wlan_policy::RequestStatus::Acknowledged,
1080 );
1081
1082 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1083 }
1084
1085 #[fuchsia::test]
1087 fn test_stop_client_connections_fail() {
1088 let mut exec = TestExecutor::new();
1089 let mut test_values = client_test_setup();
1090 let fut = handle_stop_client_connections(test_values.client_proxy);
1091 let mut fut = pin!(fut);
1092
1093 assert!(exec.run_until_stalled(&mut fut).is_pending());
1095
1096 send_client_request_status(
1098 &mut exec,
1099 &mut test_values.client_stream,
1100 wlan_policy::RequestStatus::RejectedNotSupported,
1101 );
1102
1103 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1104 }
1105
1106 #[fuchsia::test]
1108 fn test_save_network_pass() {
1109 let mut exec = TestExecutor::new();
1110 let mut test_values = client_test_setup();
1111 let config = create_network_config(TEST_SSID);
1112 let fut = handle_save_network(test_values.client_proxy, config);
1113 let mut fut = pin!(fut);
1114
1115 assert!(exec.run_until_stalled(&mut fut).is_pending());
1117
1118 send_network_config_response(&mut exec, &mut test_values.client_stream, true);
1120
1121 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1122 }
1123
1124 #[fuchsia::test]
1126 fn test_save_network_fail() {
1127 let mut exec = TestExecutor::new();
1128 let mut test_values = client_test_setup();
1129 let config = create_network_config(TEST_SSID);
1130 let fut = handle_save_network(test_values.client_proxy, config);
1131 let mut fut = pin!(fut);
1132
1133 assert!(exec.run_until_stalled(&mut fut).is_pending());
1135
1136 send_network_config_response(&mut exec, &mut test_values.client_stream, false);
1138
1139 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1140 }
1141
1142 #[fuchsia::test]
1144 fn test_forget_network_pass() {
1145 let mut exec = TestExecutor::new();
1146 let mut test_values = client_test_setup();
1147 let security = Some(wlan_policy::SecurityType::Wpa2);
1148 let fut = handle_forget_network(test_values.client_proxy, TEST_SSID.into(), security);
1149 let mut fut = pin!(fut);
1150 assert!(exec.run_until_stalled(&mut fut).is_pending());
1151
1152 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1154 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1155 assert!(exec.run_until_stalled(&mut fut).is_pending());
1156 send_saved_networks(&mut exec, &mut iterator, vec![]);
1157
1158 assert!(exec.run_until_stalled(&mut fut).is_pending());
1160
1161 send_network_config_response(&mut exec, &mut test_values.client_stream, true);
1163 assert!(exec.run_until_stalled(&mut fut).is_pending());
1164
1165 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1167 send_saved_networks(&mut exec, &mut iterator, vec![]);
1168
1169 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1170 }
1171
1172 #[fuchsia::test]
1176 fn test_forget_network_ssid_only_pass() {
1177 let mut exec = TestExecutor::new();
1178 let mut test_values = client_test_setup();
1179
1180 let security = None;
1182 let fut = handle_forget_network(test_values.client_proxy, TEST_SSID.into(), security);
1183 let mut fut = pin!(fut);
1184
1185 assert!(exec.run_until_stalled(&mut fut).is_pending());
1187
1188 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1190 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1191 assert!(exec.run_until_stalled(&mut fut).is_pending());
1192 send_saved_networks(&mut exec, &mut iterator, vec![]);
1193
1194 assert!(exec.run_until_stalled(&mut fut).is_pending());
1196
1197 send_network_config_response(&mut exec, &mut test_values.client_stream, true);
1199 assert!(exec.run_until_stalled(&mut fut).is_pending());
1200
1201 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1203 send_saved_networks(&mut exec, &mut iterator, vec![]);
1204
1205 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1206 }
1207
1208 #[fuchsia::test]
1210 fn test_forget_network_fail() {
1211 let mut exec = TestExecutor::new();
1212 let mut test_values = client_test_setup();
1213 let security = Some(wlan_policy::SecurityType::Wpa2);
1214 let fut = handle_forget_network(test_values.client_proxy, TEST_SSID.into(), security);
1215 let mut fut = pin!(fut);
1216 assert!(exec.run_until_stalled(&mut fut).is_pending());
1217
1218 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1220 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1221 assert!(exec.run_until_stalled(&mut fut).is_pending());
1222 send_saved_networks(&mut exec, &mut iterator, vec![]);
1223
1224 assert!(exec.run_until_stalled(&mut fut).is_pending());
1226
1227 send_network_config_response(&mut exec, &mut test_values.client_stream, false);
1229
1230 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1231 }
1232
1233 #[fuchsia::test]
1235 fn test_forget_network_not_removed_fails() {
1236 let mut exec = TestExecutor::new();
1237 let mut test_values = client_test_setup();
1238 let security = Some(wlan_policy::SecurityType::Wpa2);
1239 let fut = handle_forget_network(test_values.client_proxy, TEST_SSID.into(), security);
1240 let mut fut = pin!(fut);
1241 assert!(exec.run_until_stalled(&mut fut).is_pending());
1242
1243 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1245 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1246 assert!(exec.run_until_stalled(&mut fut).is_pending());
1247 send_saved_networks(&mut exec, &mut iterator, vec![]);
1248
1249 assert!(exec.run_until_stalled(&mut fut).is_pending());
1251
1252 send_network_config_response(&mut exec, &mut test_values.client_stream, true);
1254 assert!(exec.run_until_stalled(&mut fut).is_pending());
1255
1256 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1259 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1260 assert!(exec.run_until_stalled(&mut fut).is_pending());
1261 send_saved_networks(&mut exec, &mut iterator, vec![]);
1262
1263 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1264 }
1265
1266 #[test_case(TEST_SSID, Some(wlan_policy::SecurityType::Wpa2), true)]
1270 #[test_case(TEST_SSID, None, true)]
1271 #[test_case(TEST_SSID, Some(wlan_policy::SecurityType::Wpa3), false)]
1272 #[test_case("otherssid", Some(wlan_policy::SecurityType::Wpa2), false)]
1273 #[fuchsia::test(add_test_attr = false)]
1274 fn test_config_matches_config(
1275 ssid: &str,
1276 security: Option<wlan_policy::SecurityType>,
1277 expected_result: bool,
1278 ) {
1279 let ssid = ssid.as_bytes().to_vec();
1280 let config = create_network_config(TEST_SSID);
1281 let result = config_matches(&config, &ssid, &security);
1282 assert_eq!(result, expected_result);
1283 }
1284
1285 #[fuchsia::test]
1287 fn test_connect_pass() {
1288 let mut exec = TestExecutor::new();
1289 let mut test_values = client_test_setup();
1290
1291 let ssid = TEST_SSID.to_string();
1293 let security = Some(wlan_policy::SecurityType::Wpa2);
1294 let fut =
1295 handle_connect(test_values.client_proxy, test_values.update_stream, ssid, security);
1296 let mut fut = pin!(fut);
1297
1298 assert!(exec.run_until_stalled(&mut fut).is_pending());
1300
1301 send_client_request_status(
1303 &mut exec,
1304 &mut test_values.client_stream,
1305 wlan_policy::RequestStatus::Acknowledged,
1306 );
1307
1308 assert!(exec.run_until_stalled(&mut fut).is_pending());
1310 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1311 TEST_SSID,
1312 wlan_policy::ConnectionState::Connecting,
1313 ));
1314
1315 assert!(exec.run_until_stalled(&mut fut).is_pending());
1317 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1318 TEST_SSID,
1319 wlan_policy::ConnectionState::Connected,
1320 ));
1321
1322 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1324 }
1325
1326 #[fuchsia::test]
1329 fn test_connect_unspecified_security_pass() {
1330 let mut exec = TestExecutor::new();
1331 let mut test_values = client_test_setup();
1332
1333 let ssid = TEST_SSID.to_string();
1335 let fut = handle_connect(test_values.client_proxy, test_values.update_stream, ssid, None);
1336 let mut fut = pin!(fut);
1337
1338 assert!(exec.run_until_stalled(&mut fut).is_pending());
1340
1341 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1343 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1344 assert!(exec.run_until_stalled(&mut fut).is_pending());
1345
1346 send_saved_networks(&mut exec, &mut iterator, vec![]);
1348
1349 assert!(exec.run_until_stalled(&mut fut).is_pending());
1351
1352 send_client_request_status(
1354 &mut exec,
1355 &mut test_values.client_stream,
1356 wlan_policy::RequestStatus::Acknowledged,
1357 );
1358
1359 assert!(exec.run_until_stalled(&mut fut).is_pending());
1361 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1362 TEST_SSID,
1363 wlan_policy::ConnectionState::Connecting,
1364 ));
1365
1366 assert!(exec.run_until_stalled(&mut fut).is_pending());
1368 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1369 TEST_SSID,
1370 wlan_policy::ConnectionState::Connected,
1371 ));
1372
1373 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1375 }
1376
1377 #[fuchsia::test]
1380 fn test_connect_no_security_given_nothing_saved_fails() {
1381 let mut exec = TestExecutor::new();
1382 let mut test_values = client_test_setup();
1383
1384 let ssid = TEST_SSID.to_string();
1386 let fut = handle_connect(test_values.client_proxy, test_values.update_stream, ssid, None);
1387 let mut fut = pin!(fut);
1388
1389 assert!(exec.run_until_stalled(&mut fut).is_pending());
1391
1392 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1394 send_saved_networks(&mut exec, &mut iterator, vec![]);
1395
1396 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1398
1399 assert_matches!(
1401 exec.run_until_stalled(&mut test_values.client_stream.next()),
1402 Poll::Ready(None)
1403 );
1404 }
1405
1406 #[fuchsia::test]
1409 fn test_connect_no_security_given_multiple_saved_fails() {
1410 let mut exec = TestExecutor::new();
1411 let mut test_values = client_test_setup();
1412
1413 let ssid = TEST_SSID.to_string();
1415 let fut = handle_connect(test_values.client_proxy, test_values.update_stream, ssid, None);
1416 let mut fut = pin!(fut);
1417
1418 assert!(exec.run_until_stalled(&mut fut).is_pending());
1420
1421 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1423 let wpa_config =
1424 create_network_config_with_security(TEST_SSID, wlan_policy::SecurityType::Wpa);
1425 let networks = vec![create_network_config(TEST_SSID), wpa_config];
1426
1427 send_saved_networks(&mut exec, &mut iterator, networks);
1428 assert!(exec.run_until_stalled(&mut fut).is_pending());
1429
1430 send_saved_networks(&mut exec, &mut iterator, vec![]);
1432
1433 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1435
1436 assert_matches!(
1438 exec.run_until_stalled(&mut test_values.client_stream.next()),
1439 Poll::Ready(None)
1440 );
1441 }
1442
1443 #[fuchsia::test]
1445 fn test_connect_fail() {
1446 let mut exec = TestExecutor::new();
1447 let mut test_values = client_test_setup();
1448
1449 let ssid = TEST_SSID.to_string();
1451 let security = Some(wlan_policy::SecurityType::Wpa2);
1452 let fut =
1453 handle_connect(test_values.client_proxy, test_values.update_stream, ssid, security);
1454 let mut fut = pin!(fut);
1455
1456 assert!(exec.run_until_stalled(&mut fut).is_pending());
1458
1459 send_client_request_status(
1461 &mut exec,
1462 &mut test_values.client_stream,
1463 wlan_policy::RequestStatus::Acknowledged,
1464 );
1465
1466 assert!(exec.run_until_stalled(&mut fut).is_pending());
1468 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1469 TEST_SSID,
1470 wlan_policy::ConnectionState::Failed,
1471 ));
1472
1473 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1475 }
1476
1477 #[fuchsia::test]
1479 fn test_scan_pass() {
1480 let mut exec = TestExecutor::new();
1481 let test_values = client_test_setup();
1482
1483 let fut = handle_scan(test_values.client_proxy);
1484 let mut fut = pin!(fut);
1485
1486 assert!(exec.run_until_stalled(&mut fut).is_pending());
1488
1489 let mut iterator = get_scan_result_iterator(&mut exec, test_values.client_stream);
1491 send_scan_result(&mut exec, &mut iterator, Ok(&[create_scan_result(TEST_SSID)]));
1492
1493 assert!(exec.run_until_stalled(&mut fut).is_pending());
1495
1496 send_scan_result(&mut exec, &mut iterator, Ok(&[]));
1498
1499 assert_matches!(
1501 exec.run_until_stalled(&mut fut),
1502 Poll::Ready(Ok(result)) => {
1503 assert_eq!(result.len(), 1);
1504 assert_eq!(result[0].id.as_ref().unwrap().ssid, TEST_SSID.as_bytes().to_vec());
1505 }
1506 );
1507 }
1508
1509 #[fuchsia::test]
1511 fn test_scan_fail() {
1512 let mut exec = TestExecutor::new();
1513 let test_values = client_test_setup();
1514
1515 let fut = handle_scan(test_values.client_proxy);
1516 let mut fut = pin!(fut);
1517
1518 assert!(exec.run_until_stalled(&mut fut).is_pending());
1520
1521 let mut iterator = get_scan_result_iterator(&mut exec, test_values.client_stream);
1523 send_scan_result(&mut exec, &mut iterator, Err(wlan_policy::ScanErrorCode::GeneralError));
1524
1525 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1527 }
1528
1529 #[fuchsia::test]
1531 fn test_get_saved_networks() {
1532 let mut exec = TestExecutor::new();
1533 let mut test_values = client_test_setup();
1534
1535 let fut = handle_get_saved_networks(&test_values.client_proxy);
1536 let mut fut = pin!(fut);
1537
1538 assert!(exec.run_until_stalled(&mut fut).is_pending());
1540
1541 let mut iterator = get_saved_networks_iterator(&mut exec, &mut test_values.client_stream);
1543 send_saved_networks(&mut exec, &mut iterator, vec![create_network_config(TEST_SSID)]);
1544 assert!(exec.run_until_stalled(&mut fut).is_pending());
1545
1546 send_saved_networks(&mut exec, &mut iterator, vec![]);
1548
1549 assert_matches!(
1551 exec.run_until_stalled(&mut fut),
1552 Poll::Ready(Ok(result)) => {
1553 assert_eq!(result.len(), 1);
1554 assert_eq!(result[0].id.as_ref().unwrap().ssid, TEST_SSID.as_bytes().to_vec());
1555 }
1556 );
1557 }
1558
1559 #[fuchsia::test]
1561 fn test_client_listen() {
1562 let mut exec = TestExecutor::new();
1563 let test_values = client_test_setup();
1564
1565 let fut = handle_listen(test_values.update_stream, false);
1566 let mut fut = pin!(fut);
1567
1568 assert!(exec.run_until_stalled(&mut fut).is_pending());
1570 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1571 TEST_SSID,
1572 wlan_policy::ConnectionState::Connecting,
1573 ));
1574
1575 assert!(exec.run_until_stalled(&mut fut).is_pending());
1577 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1578 TEST_SSID,
1579 wlan_policy::ConnectionState::Connected,
1580 ));
1581
1582 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
1584 }
1585
1586 #[fuchsia::test]
1588 fn test_client_status() {
1589 let mut exec = TestExecutor::new();
1590 let test_values = client_test_setup();
1591
1592 let fut = handle_listen(test_values.update_stream, true);
1593 let mut fut = pin!(fut);
1594
1595 assert!(exec.run_until_stalled(&mut fut).is_pending());
1597 let _ = test_values.update_proxy.on_client_state_update(&create_client_state_summary(
1598 TEST_SSID,
1599 wlan_policy::ConnectionState::Connecting,
1600 ));
1601
1602 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1604 }
1605
1606 #[fuchsia::test]
1609 fn test_stop_ap_fail() {
1610 let mut exec = TestExecutor::new();
1611 let mut test_values = ap_test_setup();
1612
1613 let network_config = create_network_config(&TEST_SSID);
1614 let fut = handle_stop_ap(test_values.ap_proxy, network_config);
1615 let mut fut = pin!(fut);
1616
1617 assert!(exec.run_until_stalled(&mut fut).is_pending());
1619
1620 send_ap_request_status(
1622 &mut exec,
1623 &mut test_values.ap_stream,
1624 wlan_policy::RequestStatus::RejectedNotSupported,
1625 );
1626
1627 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1629 }
1630
1631 #[fuchsia::test]
1633 fn test_stop_ap_pass() {
1634 let mut exec = TestExecutor::new();
1635 let mut test_values = ap_test_setup();
1636
1637 let network_config = create_network_config(&TEST_SSID);
1638 let fut = handle_stop_ap(test_values.ap_proxy, network_config);
1639 let mut fut = pin!(fut);
1640
1641 assert!(exec.run_until_stalled(&mut fut).is_pending());
1643
1644 send_ap_request_status(
1646 &mut exec,
1647 &mut test_values.ap_stream,
1648 wlan_policy::RequestStatus::Acknowledged,
1649 );
1650
1651 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1653 }
1654
1655 #[fuchsia::test]
1657 fn test_start_ap_request_fail() {
1658 let mut exec = TestExecutor::new();
1659 let mut test_values = ap_test_setup();
1660
1661 let network_config = create_network_config(&TEST_SSID);
1662 let fut = handle_start_ap(test_values.ap_proxy, test_values.update_stream, network_config);
1663 let mut fut = pin!(fut);
1664
1665 assert!(exec.run_until_stalled(&mut fut).is_pending());
1667
1668 send_ap_request_status(
1670 &mut exec,
1671 &mut test_values.ap_stream,
1672 wlan_policy::RequestStatus::RejectedNotSupported,
1673 );
1674
1675 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1677 }
1678
1679 #[fuchsia::test]
1682 fn test_start_ap_pass() {
1683 let mut exec = TestExecutor::new();
1684 let mut test_values = ap_test_setup();
1685
1686 let network_config = create_network_config(&TEST_SSID);
1687 let fut = handle_start_ap(test_values.ap_proxy, test_values.update_stream, network_config);
1688 let mut fut = pin!(fut);
1689
1690 assert!(exec.run_until_stalled(&mut fut).is_pending());
1692
1693 send_ap_request_status(
1695 &mut exec,
1696 &mut test_values.ap_stream,
1697 wlan_policy::RequestStatus::Acknowledged,
1698 );
1699
1700 assert!(exec.run_until_stalled(&mut fut).is_pending());
1702
1703 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1705 wlan_policy::OperatingState::Starting,
1706 )]);
1707
1708 assert!(exec.run_until_stalled(&mut fut).is_pending());
1710
1711 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1713 wlan_policy::OperatingState::Active,
1714 )]);
1715
1716 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1718 }
1719
1720 #[fuchsia::test]
1723 fn test_ap_failed_to_start() {
1724 let mut exec = TestExecutor::new();
1725 let mut test_values = ap_test_setup();
1726
1727 let network_config = create_network_config(&TEST_SSID);
1728 let fut = handle_start_ap(test_values.ap_proxy, test_values.update_stream, network_config);
1729 let mut fut = pin!(fut);
1730
1731 assert!(exec.run_until_stalled(&mut fut).is_pending());
1733
1734 send_ap_request_status(
1736 &mut exec,
1737 &mut test_values.ap_stream,
1738 wlan_policy::RequestStatus::Acknowledged,
1739 );
1740
1741 assert!(exec.run_until_stalled(&mut fut).is_pending());
1743
1744 let state_updates = &[create_ap_state_summary(wlan_policy::OperatingState::Failed)];
1746 let _ = test_values.update_proxy.on_access_point_state_update(state_updates);
1747
1748 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
1750 }
1751
1752 #[fuchsia::test]
1754 fn test_stop_all_aps() {
1755 let mut exec = TestExecutor::new();
1756 let mut test_values = ap_test_setup();
1757
1758 let fut = handle_stop_all_aps(test_values.ap_proxy);
1759 let mut fut = pin!(fut);
1760
1761 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1763
1764 assert_matches!(
1766 exec.run_until_stalled(&mut test_values.ap_stream.next()),
1767 Poll::Ready(Some(Ok(
1768 wlan_policy::AccessPointControllerRequest::StopAllAccessPoints { .. }
1769 )))
1770 );
1771 }
1772
1773 #[fuchsia::test]
1775 fn test_ap_listen() {
1776 let mut exec = TestExecutor::new();
1777 let test_values = ap_test_setup();
1778
1779 let fut = handle_ap_listen(test_values.update_stream, false);
1780 let mut fut = pin!(fut);
1781
1782 assert!(exec.run_until_stalled(&mut fut).is_pending());
1784 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1785 wlan_policy::OperatingState::Starting,
1786 )]);
1787
1788 assert!(exec.run_until_stalled(&mut fut).is_pending());
1790 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1791 wlan_policy::OperatingState::Active,
1792 )]);
1793
1794 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
1796 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1797 wlan_policy::OperatingState::Failed,
1798 )]);
1799
1800 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
1801 }
1802
1803 #[fuchsia::test]
1805 fn test_ap_status() {
1806 let mut exec = TestExecutor::new();
1807 let test_values = ap_test_setup();
1808
1809 let fut = handle_ap_listen(test_values.update_stream, true);
1810 let mut fut = pin!(fut);
1811
1812 assert!(exec.run_until_stalled(&mut fut).is_pending());
1814 let _ = test_values.update_proxy.on_access_point_state_update(&[create_ap_state_summary(
1815 wlan_policy::OperatingState::Starting,
1816 )]);
1817
1818 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
1820 }
1821
1822 #[fuchsia::test]
1823 fn test_suggest_ap_mac_succeeds() {
1824 let mut exec = TestExecutor::new();
1825
1826 let (configurator_proxy, mut configurator_stream) =
1827 endpoints::create_proxy_and_stream::<wlan_deprecated::DeprecatedConfiguratorMarker>();
1828 let mac = MacAddress::from_bytes(&[0, 1, 2, 3, 4, 5]).unwrap();
1829 let suggest_fut = handle_suggest_ap_mac(configurator_proxy, mac);
1830 let mut suggest_fut = pin!(suggest_fut);
1831
1832 assert_matches!(exec.run_until_stalled(&mut suggest_fut), Poll::Pending);
1833
1834 assert_matches!(
1835 exec.run_until_stalled(&mut configurator_stream.next()),
1836 Poll::Ready(Some(Ok(wlan_deprecated::DeprecatedConfiguratorRequest::SuggestAccessPointMacAddress {
1837 mac: net::MacAddress { octets: [0, 1, 2, 3, 4, 5] }, responder
1838 }))) => {
1839 assert!(responder.send(Ok(())).is_ok());
1840 }
1841 );
1842
1843 assert_matches!(exec.run_until_stalled(&mut suggest_fut), Poll::Ready(Ok(())));
1844 }
1845
1846 #[fuchsia::test]
1847 fn test_suggest_ap_mac_fails() {
1848 let mut exec = TestExecutor::new();
1849
1850 let (configurator_proxy, mut configurator_stream) =
1851 endpoints::create_proxy_and_stream::<wlan_deprecated::DeprecatedConfiguratorMarker>();
1852 let mac = MacAddress::from_bytes(&[0, 1, 2, 3, 4, 5]).unwrap();
1853 let suggest_fut = handle_suggest_ap_mac(configurator_proxy, mac);
1854 let mut suggest_fut = pin!(suggest_fut);
1855
1856 assert_matches!(exec.run_until_stalled(&mut suggest_fut), Poll::Pending);
1857
1858 assert_matches!(
1859 exec.run_until_stalled(&mut configurator_stream.next()),
1860 Poll::Ready(Some(Ok(wlan_deprecated::DeprecatedConfiguratorRequest::SuggestAccessPointMacAddress {
1861 mac: net::MacAddress { octets: [0, 1, 2, 3, 4, 5] }, responder
1862 }))) => {
1863 assert!(responder.send(Err(wlan_deprecated::SuggestMacAddressError::InvalidArguments)).is_ok());
1864 }
1865 );
1866
1867 assert_matches!(exec.run_until_stalled(&mut suggest_fut), Poll::Ready(Err(_)));
1868 }
1869
1870 #[fuchsia::test]
1871 async fn test_proxy_command_succeeds() {
1872 match run_proxy_command(Box::pin(async { Ok(zx_status::Status::OK) })).await {
1873 Ok(status) => {
1874 assert_eq!(status, zx_status::Status::OK)
1875 }
1876 Err(e) => panic!("Test unexpectedly failed with {}", e),
1877 }
1878 }
1879
1880 #[fuchsia::test]
1881 async fn test_proxy_command_already_bound() {
1882 let result: Result<(), Error> = run_proxy_command(Box::pin(async {
1883 Err(fidl::Error::ClientChannelClosed {
1884 epitaph: fidl::Epitaph::Explicit(Err(zx_status::Status::ALREADY_BOUND)),
1885 protocol_name: "test",
1886 })
1887 }))
1888 .await;
1889 match result {
1890 Ok(status) => panic!("Test unexpectedly succeeded with {:?}", status),
1891 Err(e) => {
1892 assert!(e.to_string().contains("Failed to obtain a WLAN policy controller"));
1893 }
1894 }
1895 }
1896
1897 #[fuchsia::test]
1898 async fn test_proxy_command_generic_failure() {
1899 let result: Result<(), Error> =
1900 run_proxy_command(Box::pin(async { Err(fidl::Error::Invalid) })).await;
1901 match result {
1902 Ok(status) => panic!("Test unexpectedly succeeded with {:?}", status),
1903 Err(e) => {
1904 assert!(!e.to_string().contains("Failed to obtain a WLAN policy controller"));
1905 }
1906 }
1907 }
1908}