1use crate::client::types as client_types;
7use crate::config_management::{
8 self, Credential, NetworkConfigError, NetworkIdentifier, SaveError, SavedNetworksManagerApi,
9};
10use crate::mode_management::iface_manager_api::{ConnectAttemptRequest, IfaceManagerApi};
11use crate::telemetry::{TelemetryEvent, TelemetrySender};
12use crate::util::listener;
13use fidl::epitaph::ChannelEpitaphExt;
14use fidl_fuchsia_wlan_policy as fidl_policy;
15use futures::lock::{Mutex, MutexGuard};
16use futures::prelude::*;
17use futures::select;
18use futures::stream::FuturesUnordered;
19use log::{error, info, warn};
20use std::sync::Arc;
21
22pub mod connection_selection;
23pub mod roaming;
24pub mod scan;
25pub mod state_machine;
26pub mod types;
27
28const MAX_CONFIGS_PER_RESPONSE: usize = 100;
32
33const MAX_CONCURRENT_LISTENERS: usize = 1000;
35
36type ClientRequests = fidl::endpoints::ServerEnd<fidl_policy::ClientControllerMarker>;
37type SavedNetworksPtr = Arc<dyn SavedNetworksManagerApi>;
38
39pub async fn serve_provider_requests(
43 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
44 update_sender: listener::ClientListenerMessageSender,
45 saved_networks: SavedNetworksPtr,
46 scan_requester: Arc<dyn scan::ScanRequestApi>,
47 client_provider_lock: Arc<Mutex<()>>,
48 mut requests: fidl_policy::ClientProviderRequestStream,
49 telemetry_sender: TelemetrySender,
50 power_manager: Arc<dyn wlan_power_manager::PowerManager>,
51) {
52 let mut controller_reqs = FuturesUnordered::new();
53
54 loop {
55 select! {
56 _ = controller_reqs.select_next_some() => (),
58 req = requests.select_next_some() => if let Ok(req) = req {
60 if let Some(client_provider_guard) = client_provider_lock.try_lock() {
62 let fut = handle_provider_request(
63 Arc::clone(&iface_manager),
64 update_sender.clone(),
65 saved_networks.clone(),
66 scan_requester.clone(),
67 client_provider_guard,
68 req,
69 telemetry_sender.clone(),
70 power_manager.clone(),
71 );
72 controller_reqs.push(fut);
73 } else if let Err(e) = reject_provider_request(req) {
74 error!("error sending rejection epitaph: {:?}", e);
75 }
76 },
77 complete => break,
78 }
79 }
80}
81
82pub async fn serve_listener_requests(
84 update_sender: listener::ClientListenerMessageSender,
85 requests: fidl_policy::ClientListenerRequestStream,
86) {
87 let serve_fut = requests
88 .try_for_each_concurrent(MAX_CONCURRENT_LISTENERS, |req| {
89 handle_listener_request(update_sender.clone(), req)
90 })
91 .unwrap_or_else(|e| error!("error serving Client Listener API: {}", e));
92 serve_fut.await;
93}
94
95async fn handle_provider_request(
97 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
98 update_sender: listener::ClientListenerMessageSender,
99 saved_networks: SavedNetworksPtr,
100 scan_requester: Arc<dyn scan::ScanRequestApi>,
101 client_provider_guard: MutexGuard<'_, ()>,
102 req: fidl_policy::ClientProviderRequest,
103 telemetry_sender: TelemetrySender,
104 power_manager: Arc<dyn wlan_power_manager::PowerManager>,
105) -> Result<(), fidl::Error> {
106 match req {
107 fidl_policy::ClientProviderRequest::GetController { requests, updates, .. } => {
108 register_listener(update_sender, updates.into_proxy());
109 handle_client_requests(
110 iface_manager,
111 scan_requester,
112 saved_networks,
113 client_provider_guard,
114 requests,
115 telemetry_sender,
116 power_manager,
117 )
118 .await?;
119 Ok(())
120 }
121 }
122}
123
124fn log_client_request(request: &fidl_policy::ClientControllerRequest) {
126 info!(
127 "Received policy client request {}",
128 match request {
129 fidl_policy::ClientControllerRequest::Connect { .. } => "Connect",
130 fidl_policy::ClientControllerRequest::StartClientConnections { .. } =>
131 "StartClientConnections",
132 fidl_policy::ClientControllerRequest::StopClientConnections { .. } =>
133 "StopClientConnections",
134 fidl_policy::ClientControllerRequest::ScanForNetworks { .. } => "ScanForNetworks",
135 fidl_policy::ClientControllerRequest::SaveNetwork { .. } => "SaveNetwork",
136 fidl_policy::ClientControllerRequest::RemoveNetwork { .. } => "RemoveNetwork",
137 fidl_policy::ClientControllerRequest::ForgetNetwork { .. } => "ForgetNetwork",
138 fidl_policy::ClientControllerRequest::GetSavedNetworks { .. } => "GetSavedNetworks",
139 }
140 );
141}
142
143async fn handle_client_requests(
145 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
146 scan_requester: Arc<dyn scan::ScanRequestApi>,
147 saved_networks: SavedNetworksPtr,
148 client_provider_guard: MutexGuard<'_, ()>,
149 requests: ClientRequests,
150 telemetry_sender: TelemetrySender,
151 power_manager: Arc<dyn wlan_power_manager::PowerManager>,
152) -> Result<(), fidl::Error> {
153 let mut request_stream = requests.into_stream();
154 while let Some(request) = request_stream.try_next().await? {
155 log_client_request(&request);
156 match request {
157 fidl_policy::ClientControllerRequest::Connect { id, responder, .. } => {
158 let _wake_lease = power_manager.take_wake_lease("wlancfg-client-connect").await;
159 let response = handle_client_request_connect(
160 Arc::clone(&iface_manager),
161 saved_networks.clone(),
162 &id,
163 )
164 .await;
165 responder.send(response)?
166 }
167 fidl_policy::ClientControllerRequest::StartClientConnections { responder } => {
168 let _wake_lease =
169 power_manager.take_wake_lease("wlancfg-client-start-connections").await;
170 telemetry_sender.send(TelemetryEvent::StartClientConnectionsRequest);
171 let response =
172 handle_client_request_start_client_connections(iface_manager.clone()).await;
173 responder.send(response)?
174 }
175 fidl_policy::ClientControllerRequest::StopClientConnections { responder } => {
176 let _wake_lease =
177 power_manager.take_wake_lease("wlancfg-client-stop-connections").await;
178 telemetry_sender.send(TelemetryEvent::StopClientConnectionsRequest);
179 let response =
180 handle_client_request_stop_client_connections(iface_manager.clone()).await;
181 responder.send(response)?
182 }
183 fidl_policy::ClientControllerRequest::ScanForNetworks { iterator, .. } => {
184 let fut = handle_client_request_scan(
185 scan_requester.clone(),
186 saved_networks.clone(),
187 telemetry_sender.clone(),
188 power_manager.clone(),
189 iterator,
190 );
191 fuchsia_async::Task::local(fut).detach();
194 }
195 fidl_policy::ClientControllerRequest::SaveNetwork { config, responder } => {
196 let _wake_lease =
197 power_manager.take_wake_lease("wlancfg-client-save-network").await;
198 let response = handle_client_request_save_network(
200 saved_networks.clone(),
201 config,
202 Arc::clone(&iface_manager),
203 )
204 .await
205 .map_err(|e| {
206 error!("Failed to save network: {:?}", e);
207 fidl_policy::NetworkConfigChangeError::from(e)
208 });
209 responder.send(response)?;
210 }
211 fidl_policy::ClientControllerRequest::RemoveNetwork { config, responder } => {
212 let _wake_lease =
213 power_manager.take_wake_lease("wlancfg-client-remove-network").await;
214 let id_opt = config.id;
215 let err = async {
216 let id = id_opt.ok_or(NetworkConfigError::ConfigMissingId)?;
217 handle_client_request_remove_network(
218 saved_networks.clone(),
219 id,
220 iface_manager.clone(),
221 )
222 .await
223 }
224 .await
225 .map_err(|_| SaveError::GeneralError);
226
227 responder.send(err)?;
228 }
229 fidl_policy::ClientControllerRequest::ForgetNetwork { id, responder } => {
230 let _wake_lease =
231 power_manager.take_wake_lease("wlancfg-client-remove-network").await;
232 let err = handle_client_request_remove_network(
233 saved_networks.clone(),
234 id,
235 iface_manager.clone(),
236 )
237 .map_err(|_| SaveError::GeneralError)
238 .await;
239 responder.send(err)?;
240 }
241 fidl_policy::ClientControllerRequest::GetSavedNetworks { iterator, .. } => {
242 let _wake_lease =
243 power_manager.take_wake_lease("wlancfg-client-get-saved-networks").await;
244 handle_client_request_get_networks(saved_networks.clone(), iterator).await?;
245 }
246 }
247 }
248 drop(client_provider_guard);
249 Ok(())
250}
251
252async fn handle_client_request_connect(
255 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
256 saved_networks: SavedNetworksPtr,
257 network: &fidl_policy::NetworkIdentifier,
258) -> fidl_policy::RequestStatus {
259 let network_config = match saved_networks
260 .lookup(&NetworkIdentifier::new(
261 client_types::Ssid::from_bytes_unchecked(network.ssid.clone()),
262 network.type_.into(),
263 ))
264 .await
265 {
266 Some(config) => config,
267 None => {
268 error!("Requested network not found in saved networks");
269 return fidl_policy::RequestStatus::RejectedNotSupported;
270 }
271 };
272
273 let network_id = fidl_policy::NetworkIdentifier {
274 ssid: network_config.ssid.into(),
275 type_: fidl_policy::SecurityType::from(network_config.security_type),
276 };
277 let connect_req = ConnectAttemptRequest::new(
278 network_id.into(),
279 network_config.credential,
280 client_types::ConnectReason::FidlConnectRequest,
281 );
282
283 let mut iface_manager = iface_manager.lock().await;
284 match iface_manager.connect(connect_req).await {
285 Ok(_) => fidl_policy::RequestStatus::Acknowledged,
286 Err(e) => {
287 error!("failed to connect: {:?}", e);
288 fidl_policy::RequestStatus::RejectedIncompatibleMode
289 }
290 }
291}
292
293async fn handle_client_request_scan(
294 scan_requester: Arc<dyn scan::ScanRequestApi>,
295 saved_networks: SavedNetworksPtr,
296 telemetry_sender: TelemetrySender,
297 power_manager: Arc<dyn wlan_power_manager::PowerManager>,
298 output_iterator: fidl::endpoints::ServerEnd<fidl_fuchsia_wlan_policy::ScanResultIteratorMarker>,
299) {
300 let _wake_lease = power_manager.take_wake_lease("wlancfg-client-scan").await;
301 let get_scan_results = async {
302 let passive_scan_results =
303 scan_requester.perform_scan(scan::ScanReason::ClientRequest, vec![], vec![]).await?;
304
305 let requested_active_scan_ssids: Vec<types::Ssid> =
306 config_management::select_high_probability_hidden_networks(
307 saved_networks.get_networks().await,
308 )
309 .drain(..)
310 .map(|id| id.ssid)
311 .collect();
312
313 info!(
314 "Completed passive scan for API request, {} likely-hidden networks to scan for.",
315 requested_active_scan_ssids.len()
316 );
317 telemetry_sender.send(TelemetryEvent::ActiveScanRequestedViaApi {
318 num_ssids_requested: requested_active_scan_ssids.len(),
319 });
320
321 if requested_active_scan_ssids.is_empty() {
322 Ok(passive_scan_results)
323 } else {
324 scan_requester
325 .perform_scan(scan::ScanReason::ClientRequest, requested_active_scan_ssids, vec![])
326 .await
327 .map(|mut scan_results| {
328 scan_results.extend(passive_scan_results);
329 scan_results
330 })
331 }
332 };
333
334 match get_scan_results.await {
335 Ok(results) => {
336 let fidl_results = scan::scan_result_to_policy_scan_result(&results);
340 if let Err(e) = scan::send_scan_results_over_fidl(output_iterator, &fidl_results).await
341 {
342 warn!("Failed to send scan results to requester: {:?}", e);
343 }
344 }
345 Err(e) => {
346 if let Err(e) = scan::send_scan_error_over_fidl(output_iterator, e).await {
347 warn!("Failed to send scan error to requester: {:?}", e);
348 }
349 }
350 }
351}
352
353async fn handle_client_request_save_network(
357 saved_networks: SavedNetworksPtr,
358 network_config: fidl_policy::NetworkConfig,
359 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
360) -> Result<(), NetworkConfigError> {
361 let net_id: client_types::NetworkIdentifier =
364 network_config.id.ok_or(NetworkConfigError::ConfigMissingId)?.into();
365 let credential = Credential::try_from(
366 network_config.credential.ok_or(NetworkConfigError::ConfigMissingCredential)?,
367 )?;
368 let evicted_config = saved_networks.store(net_id.clone(), credential.clone()).await?;
369
370 let mut iface_manager = iface_manager.lock().await;
372 if let Some(config) = evicted_config {
373 let net_id = client_types::NetworkIdentifier {
374 ssid: config.ssid,
375 security_type: config.security_type,
376 };
377 match iface_manager
378 .disconnect(net_id, client_types::DisconnectReason::NetworkConfigUpdated)
379 .await
380 {
381 Ok(()) => {}
382 Err(e) => error!("failed to disconnect from network: {}", e),
383 }
384 }
385
386 let connect_req = ConnectAttemptRequest::new(
388 net_id,
389 credential,
390 client_types::ConnectReason::NewSavedNetworkAutoconnect,
391 );
392 match iface_manager.has_idle_client().await {
393 Ok(true) => {
394 info!("Idle interface available, will attempt connection to new saved network");
395 let _ = iface_manager.connect(connect_req).await;
396 }
397 Ok(false) => {}
398 Err(e) => {
399 error!("Unable to query idle client state while saving network: {:?}", e);
400 }
401 }
402
403 Ok(())
404}
405
406async fn handle_client_request_remove_network(
409 saved_networks: SavedNetworksPtr,
410 network_id: fidl_policy::NetworkIdentifier,
411 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
412) -> Result<(), NetworkConfigError> {
413 let net_id = NetworkIdentifier::from(network_id);
414 if saved_networks.remove(net_id.clone()).await? {
415 match iface_manager
416 .lock()
417 .await
418 .disconnect(net_id, client_types::DisconnectReason::NetworkUnsaved)
419 .await
420 {
421 Ok(()) => {}
422 Err(e) => error!("failed to disconnect from network: {}", e),
423 }
424 }
425 Ok(())
426}
427
428async fn handle_client_request_get_networks(
429 saved_networks: SavedNetworksPtr,
430 iterator: fidl::endpoints::ServerEnd<fidl_policy::NetworkConfigIteratorMarker>,
431) -> Result<(), fidl::Error> {
432 let network_configs = saved_networks.get_networks().await;
434 let chunks = network_configs.chunks(MAX_CONFIGS_PER_RESPONSE);
435 let fidl_chunks = chunks.into_iter().map(|chunk| {
436 chunk
437 .iter()
438 .map(fidl_policy::NetworkConfig::from)
439 .collect::<Vec<fidl_policy::NetworkConfig>>()
440 });
441 let mut stream = iterator.into_stream();
442 for chunk in fidl_chunks {
443 send_next_chunk(&mut stream, chunk).await?;
444 }
445 send_next_chunk(&mut stream, vec![]).await
446}
447
448async fn send_next_chunk(
450 stream: &mut fidl_policy::NetworkConfigIteratorRequestStream,
451 chunk: Vec<fidl_policy::NetworkConfig>,
452) -> Result<(), fidl::Error> {
453 if let Some(req) = stream.try_next().await? {
454 let fidl_policy::NetworkConfigIteratorRequest::GetNext { responder } = req;
455 responder.send(&chunk)
456 } else {
457 info!("Info: peer closed channel for network config results unexpectedly");
461 Ok(())
462 }
463}
464
465async fn handle_listener_request(
467 update_sender: listener::ClientListenerMessageSender,
468 req: fidl_policy::ClientListenerRequest,
469) -> Result<(), fidl::Error> {
470 match req {
471 fidl_policy::ClientListenerRequest::GetListener { updates, .. } => {
472 register_listener(update_sender, updates.into_proxy());
473 Ok(())
474 }
475 }
476}
477
478fn register_listener(
481 update_sender: listener::ClientListenerMessageSender,
482 listener: fidl_policy::ClientStateUpdatesProxy,
483) {
484 let _ignored = update_sender.unbounded_send(listener::Message::NewListener(listener));
485}
486
487fn reject_provider_request(req: fidl_policy::ClientProviderRequest) -> Result<(), fidl::Error> {
490 match req {
491 fidl_policy::ClientProviderRequest::GetController { requests, updates, .. } => {
492 info!("Rejecting new client controller request because a controller is in use");
493 requests.into_channel().close_with_epitaph(zx::Status::ALREADY_BOUND)?;
494 updates.into_channel().close_with_epitaph(zx::Status::ALREADY_BOUND)?;
495 Ok(())
496 }
497 }
498}
499
500async fn handle_client_request_start_client_connections(
502 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
503) -> fidl_policy::RequestStatus {
504 let mut iface_manager = iface_manager.lock().await;
505 if let Err(e) = iface_manager.start_client_connections().await {
506 warn!("encountered an error while starting client connections: {:?}", e);
507 }
508 fidl_policy::RequestStatus::Acknowledged
509}
510
511async fn handle_client_request_stop_client_connections(
513 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
514) -> fidl_policy::RequestStatus {
515 let mut iface_manager = iface_manager.lock().await;
516 if let Err(e) = iface_manager
517 .stop_client_connections(client_types::DisconnectReason::FidlStopClientConnectionsRequest)
518 .await
519 {
520 warn!("encountered an error while stopping client connections: {:?}", e);
521 }
522 fidl_policy::RequestStatus::Acknowledged
523}
524
525#[cfg(test)]
526mod tests {
527 use super::*;
528 use crate::access_point::state_machine as ap_fsm;
529 use crate::config_management::{NetworkConfig, SecurityType, WPA_PSK_BYTE_LEN};
530 use crate::mode_management::iface_manager_api::SmeForScan;
531 use crate::util::testing::fakes::{FakeSavedNetworksManager, FakeScanRequester};
532 use crate::util::testing::{
533 generate_random_fidl_network_config, generate_random_fidl_network_config_with_ssid,
534 };
535 use anyhow::{Error, format_err};
536 use assert_matches::assert_matches;
537 use async_trait::async_trait;
538 use fidl::endpoints::{Proxy, create_proxy, create_request_stream};
539 use fuchsia_async as fasync;
540 use futures::channel::{mpsc, oneshot};
541 use futures::task::Poll;
542 use std::pin::pin;
543 use test_case::test_case;
544
545 #[derive(Debug)]
548 enum IfaceManagerRequest {
549 Disconnect(client_types::NetworkIdentifier, client_types::DisconnectReason),
550 }
551
552 struct FakeIfaceManager {
553 pub sme_proxy: fidl_fuchsia_wlan_sme::ClientSmeProxy,
554 pub disconnected_ifaces: Vec<u16>,
555 command_sender: mpsc::Sender<IfaceManagerRequest>,
556 start_client_connections_succeeds: bool,
557 stop_client_connections_succeeds: bool,
558 }
559
560 impl FakeIfaceManager {
561 pub fn new(
562 proxy: fidl_fuchsia_wlan_sme::ClientSmeProxy,
563 command_sender: mpsc::Sender<IfaceManagerRequest>,
564 ) -> Self {
565 FakeIfaceManager {
566 sme_proxy: proxy,
567 disconnected_ifaces: Vec::new(),
568 command_sender,
569 start_client_connections_succeeds: true,
570 stop_client_connections_succeeds: true,
571 }
572 }
573 }
574
575 #[async_trait(?Send)]
576 impl IfaceManagerApi for FakeIfaceManager {
577 async fn disconnect(
578 &mut self,
579 network_id: client_types::NetworkIdentifier,
580 reason: client_types::DisconnectReason,
581 ) -> Result<(), Error> {
582 self.command_sender
583 .try_send(IfaceManagerRequest::Disconnect(network_id, reason))
584 .map_err(|e| {
585 error!(
586 "Failed to send disconnect: commands_sender's receiver may have
587 been dropped. FakeIfaceManager should be created manually with a sender
588 assigned: {:?}",
589 e
590 );
591 format_err!("failed to send disconnect: {:?}", e)
592 })
593 }
594
595 async fn connect(&mut self, _connect_req: ConnectAttemptRequest) -> Result<(), Error> {
596 let _ = self.disconnected_ifaces.pop();
597 Ok(())
598 }
599
600 async fn record_idle_client(&mut self, iface_id: u16) -> Result<(), Error> {
601 self.disconnected_ifaces.push(iface_id);
602 Ok(())
603 }
604
605 async fn has_idle_client(&mut self) -> Result<bool, Error> {
606 Ok(!self.disconnected_ifaces.is_empty())
607 }
608
609 async fn handle_added_iface(&mut self, _iface_id: u16) -> Result<(), Error> {
610 unimplemented!()
611 }
612
613 async fn handle_removed_iface(&mut self, _iface_id: u16) -> Result<(), Error> {
614 unimplemented!()
615 }
616
617 async fn get_sme_proxy_for_scan(&mut self) -> Result<SmeForScan, Error> {
618 let (defect_sender, _) = mpsc::channel(100);
619 Ok(SmeForScan::new(self.sme_proxy.clone(), 0, defect_sender))
620 }
621
622 async fn stop_client_connections(
623 &mut self,
624 _reason: client_types::DisconnectReason,
625 ) -> Result<(), Error> {
626 if self.stop_client_connections_succeeds {
627 Ok(())
628 } else {
629 Err(format_err!("stop client connections failed"))
630 }
631 }
632
633 async fn start_client_connections(&mut self) -> Result<(), Error> {
634 if self.start_client_connections_succeeds {
635 Ok(())
636 } else {
637 Err(format_err!("start client connections failed"))
638 }
639 }
640
641 async fn start_ap(
642 &mut self,
643 _config: ap_fsm::ApConfig,
644 ) -> Result<oneshot::Receiver<()>, Error> {
645 unimplemented!()
646 }
647
648 async fn stop_ap(&mut self, _ssid: types::Ssid, _password: Vec<u8>) -> Result<(), Error> {
649 unimplemented!()
650 }
651
652 async fn stop_all_aps(&mut self) -> Result<(), Error> {
653 unimplemented!()
654 }
655
656 async fn set_country(
657 &mut self,
658 _country_code: Option<types::CountryCode>,
659 ) -> Result<(), Error> {
660 unimplemented!()
661 }
662 }
663
664 fn request_controller(
666 provider: &fidl_policy::ClientProviderProxy,
667 ) -> (fidl_policy::ClientControllerProxy, fidl_policy::ClientStateUpdatesRequestStream) {
668 let (controller, requests) = create_proxy::<fidl_policy::ClientControllerMarker>();
669 let (update_sink, update_stream) =
670 create_request_stream::<fidl_policy::ClientStateUpdatesMarker>();
671 provider.get_controller(requests, update_sink).expect("error getting controller");
672 (controller, update_stream)
673 }
674
675 struct TestValues {
676 saved_networks: SavedNetworksPtr,
677 net_id_open: fidl_policy::NetworkIdentifier,
678 net_id_wpa2_w_password: fidl_policy::NetworkIdentifier,
679 net_id_wpa2_w_psk: fidl_policy::NetworkIdentifier,
680 provider: fidl_policy::ClientProviderProxy,
681 requests: fidl_policy::ClientProviderRequestStream,
682 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
683 iface_mgr_req_recvr: mpsc::Receiver<IfaceManagerRequest>,
684 scan_requester: Arc<FakeScanRequester>,
685 update_sender: mpsc::UnboundedSender<listener::ClientListenerMessage>,
686 listener_updates: mpsc::UnboundedReceiver<listener::ClientListenerMessage>,
687 client_provider_lock: Arc<Mutex<()>>,
688 telemetry_sender: TelemetrySender,
689 telemetry_receiver: mpsc::Receiver<TelemetryEvent>,
690 power_manager: Arc<wlan_power_manager_testing::TestPowerManager>,
691 }
692
693 fn test_setup() -> TestValues {
697 let net_id_open = fidl_policy::NetworkIdentifier {
698 ssid: "foobar".to_string().into_bytes(),
699 type_: fidl_policy::SecurityType::None,
700 };
701 let net_id_wpa2_w_password = fidl_policy::NetworkIdentifier {
702 ssid: b"foobar-wpa2".to_vec(),
703 type_: fidl_policy::SecurityType::Wpa2,
704 };
705 let net_id_wpa2_w_psk = fidl_policy::NetworkIdentifier {
706 ssid: b"foobar-psk".to_vec(),
707 type_: fidl_policy::SecurityType::Wpa2,
708 };
709
710 let presaved_default_configs = vec![
711 fidl_policy::NetworkConfig {
712 id: Some(net_id_open.clone()),
713 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
714 ..Default::default()
715 },
716 fidl_policy::NetworkConfig {
717 id: Some(net_id_wpa2_w_password.clone()),
718 credential: Some(fidl_policy::Credential::Password(b"foobar-password".to_vec())),
719 ..Default::default()
720 },
721 fidl_policy::NetworkConfig {
722 id: Some(net_id_wpa2_w_psk.clone()),
723 credential: Some(fidl_policy::Credential::Psk([64; WPA_PSK_BYTE_LEN].to_vec())),
724 ..Default::default()
725 },
726 ];
727 let saved_networks =
728 Arc::new(FakeSavedNetworksManager::new_with_saved_networks(presaved_default_configs));
729 let (telemetry_sender, telemetry_receiver) = mpsc::channel::<TelemetryEvent>(100);
730 let (provider, requests) = create_proxy::<fidl_policy::ClientProviderMarker>();
731 let requests = requests.into_stream();
732
733 let (proxy, _server) = create_proxy::<fidl_fuchsia_wlan_sme::ClientSmeMarker>();
734 let (req_sender, iface_mgr_req_recvr) = mpsc::channel(1);
735 let iface_manager = FakeIfaceManager::new(proxy.clone(), req_sender);
736 let iface_manager = Arc::new(Mutex::new(iface_manager));
737 let scan_requester = Arc::new(FakeScanRequester::new());
738
739 let (update_sender, listener_updates) = mpsc::unbounded();
740 let power_manager = Arc::new(wlan_power_manager_testing::TestPowerManager::new());
741
742 TestValues {
743 saved_networks,
744 net_id_open,
745 net_id_wpa2_w_password,
746 net_id_wpa2_w_psk,
747 provider,
748 requests,
749 iface_manager,
750 iface_mgr_req_recvr,
751 scan_requester,
752 update_sender,
753 listener_updates,
754 client_provider_lock: Arc::new(Mutex::new(())),
755 telemetry_sender: TelemetrySender::new(telemetry_sender),
756 telemetry_receiver,
757 power_manager,
758 }
759 }
760
761 #[fuchsia::test]
762 fn connect_request_unknown_network() {
763 let ssid = client_types::Ssid::try_from("foobar-unknown").unwrap();
764 let mut exec = fasync::TestExecutor::new();
765 let test_values = test_setup();
766 let serve_fut = serve_provider_requests(
767 test_values.iface_manager,
768 test_values.update_sender,
769 Arc::clone(&test_values.saved_networks),
770 test_values.scan_requester,
771 test_values.client_provider_lock,
772 test_values.requests,
773 test_values.telemetry_sender,
774 test_values.power_manager.clone(),
775 );
776 let mut serve_fut = pin!(serve_fut);
777
778 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
780
781 let (controller, _) = request_controller(&test_values.provider);
783 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
784
785 let connect_fut = controller.connect(&fidl_policy::NetworkIdentifier {
787 ssid: ssid.to_vec(),
788 type_: fidl_policy::SecurityType::None,
789 });
790 let mut connect_fut = pin!(connect_fut);
791
792 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
794
795 assert_matches!(
796 exec.run_until_stalled(&mut connect_fut),
797 Poll::Ready(Ok(fidl_policy::RequestStatus::RejectedNotSupported))
798 );
799
800 let id = NetworkIdentifier::new(ssid, SecurityType::None);
803 let lookup_fut = test_values.saved_networks.lookup(&id);
804 assert!(exec.run_singlethreaded(lookup_fut).is_none());
805 }
806
807 #[fuchsia::test]
808 fn connect_request_open_network() {
809 let mut exec = fasync::TestExecutor::new();
810
811 let test_values = test_setup();
812 let serve_fut = serve_provider_requests(
813 test_values.iface_manager,
814 test_values.update_sender,
815 Arc::clone(&test_values.saved_networks),
816 test_values.scan_requester,
817 test_values.client_provider_lock,
818 test_values.requests,
819 test_values.telemetry_sender,
820 test_values.power_manager.clone(),
821 );
822 let mut serve_fut = pin!(serve_fut);
823
824 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
826
827 let (controller, _update_stream) = request_controller(&test_values.provider);
829 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
830
831 let connect_fut = controller.connect(&test_values.net_id_open);
833 let mut connect_fut = pin!(connect_fut);
834
835 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
837
838 assert_matches!(
840 exec.run_until_stalled(&mut connect_fut),
841 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
842 );
843 }
844
845 #[fuchsia::test]
846 fn connect_request_protected_network() {
847 let mut exec = fasync::TestExecutor::new();
848
849 let test_values = test_setup();
850 let serve_fut = serve_provider_requests(
851 test_values.iface_manager,
852 test_values.update_sender,
853 Arc::clone(&test_values.saved_networks),
854 test_values.scan_requester,
855 test_values.client_provider_lock,
856 test_values.requests,
857 test_values.telemetry_sender,
858 test_values.power_manager.clone(),
859 );
860 let mut serve_fut = pin!(serve_fut);
861
862 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
864
865 let (controller, _update_stream) = request_controller(&test_values.provider);
867 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
868
869 let connect_fut = controller.connect(&test_values.net_id_wpa2_w_password);
871 let mut connect_fut = pin!(connect_fut);
872
873 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
875
876 assert_matches!(
878 exec.run_until_stalled(&mut connect_fut),
879 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
880 );
881 }
882
883 #[fuchsia::test]
884 fn connect_request_protected_psk_network() {
885 let mut exec = fasync::TestExecutor::new();
886
887 let test_values = test_setup();
888 let serve_fut = serve_provider_requests(
889 test_values.iface_manager,
890 test_values.update_sender,
891 Arc::clone(&test_values.saved_networks),
892 test_values.scan_requester,
893 test_values.client_provider_lock,
894 test_values.requests,
895 test_values.telemetry_sender,
896 test_values.power_manager.clone(),
897 );
898 let mut serve_fut = pin!(serve_fut);
899
900 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
902
903 let (controller, _update_stream) = request_controller(&test_values.provider);
905 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
906
907 let connect_fut = controller.connect(&test_values.net_id_wpa2_w_psk);
909 let mut connect_fut = pin!(connect_fut);
910
911 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
913
914 assert_matches!(
916 exec.run_until_stalled(&mut connect_fut),
917 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
918 );
919 }
920
921 #[fuchsia::test]
922 fn start_and_stop_client_connections() {
923 let mut exec = fasync::TestExecutor::new();
924 let mut test_values = test_setup();
925 let serve_fut = serve_provider_requests(
926 test_values.iface_manager,
927 test_values.update_sender,
928 test_values.saved_networks,
929 test_values.scan_requester,
930 test_values.client_provider_lock,
931 test_values.requests,
932 test_values.telemetry_sender,
933 test_values.power_manager.clone(),
934 );
935 let mut serve_fut = pin!(serve_fut);
936
937 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
939
940 let (controller, _update_stream) = request_controller(&test_values.provider);
942 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
943
944 let start_fut = controller.start_client_connections();
946 let mut start_fut = pin!(start_fut);
947
948 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
950 assert_matches!(
951 exec.run_until_stalled(&mut start_fut),
952 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
953 );
954
955 assert_matches!(test_values.telemetry_receiver.try_recv(), Ok(event) => {
957 assert_matches!(event, TelemetryEvent::StartClientConnectionsRequest);
958 });
959
960 let connect_fut = controller.connect(&test_values.net_id_wpa2_w_password);
962 let mut connect_fut = pin!(connect_fut);
963
964 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
966
967 assert_matches!(
969 exec.run_until_stalled(&mut connect_fut),
970 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
971 );
972
973 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
975
976 let stop_fut = controller.stop_client_connections();
978 let mut stop_fut = pin!(stop_fut);
979
980 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
982
983 assert_matches!(test_values.telemetry_receiver.try_recv(), Ok(event) => {
985 assert_matches!(event, TelemetryEvent::StopClientConnectionsRequest);
986 });
987
988 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
990 assert_matches!(
991 exec.run_until_stalled(&mut stop_fut),
992 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
993 );
994 }
995
996 #[fuchsia::test]
1000 fn scan_end_to_end() {
1001 let mut exec = fasync::TestExecutor::new();
1002 let test_values = test_setup();
1003 let serve_fut = serve_provider_requests(
1004 test_values.iface_manager,
1005 test_values.update_sender,
1006 test_values.saved_networks,
1007 test_values.scan_requester.clone(),
1008 test_values.client_provider_lock,
1009 test_values.requests,
1010 test_values.telemetry_sender,
1011 test_values.power_manager.clone(),
1012 );
1013 let mut serve_fut = pin!(serve_fut);
1014
1015 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1017
1018 let (controller, _update_stream) = request_controller(&test_values.provider);
1020 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1021
1022 let (_iter, server) = fidl::endpoints::create_proxy();
1024 controller.scan_for_networks(server).expect("Failed to call scan for networks");
1025
1026 exec.run_singlethreaded(test_values.scan_requester.add_scan_result(Ok(vec![])));
1029 exec.run_singlethreaded(test_values.scan_requester.add_scan_result(Ok(vec![])));
1031
1032 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1034
1035 let expected_active_ssids = [
1038 test_values.net_id_wpa2_w_password,
1039 test_values.net_id_wpa2_w_psk,
1040 test_values.net_id_open,
1041 ]
1042 .iter()
1043 .map(|id| types::Ssid::from_bytes_unchecked(id.ssid.clone()))
1044 .collect();
1045 exec.run_singlethreaded(test_values.scan_requester.verify_scan_request((
1046 scan::ScanReason::ClientRequest,
1047 vec![],
1048 vec![],
1049 )));
1050 exec.run_singlethreaded(test_values.scan_requester.verify_scan_request((
1051 scan::ScanReason::ClientRequest,
1052 expected_active_ssids,
1053 vec![],
1054 )));
1055 }
1056
1057 #[fuchsia::test]
1058 fn save_network() {
1059 let mut exec = fasync::TestExecutor::new();
1060 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1061
1062 let mut test_values = test_setup();
1063 let serve_fut = serve_provider_requests(
1064 test_values.iface_manager,
1065 test_values.update_sender,
1066 saved_networks.clone(),
1067 test_values.scan_requester,
1068 test_values.client_provider_lock,
1069 test_values.requests,
1070 test_values.telemetry_sender,
1071 test_values.power_manager.clone(),
1072 );
1073 let mut serve_fut = pin!(serve_fut);
1074
1075 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1077
1078 let (controller, _update_stream) = request_controller(&test_values.provider);
1080 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1081 assert_matches!(
1082 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1083 Poll::Ready(_)
1084 );
1085
1086 let network_id = fidl_policy::NetworkIdentifier {
1088 ssid: b"foo".to_vec(),
1089 type_: fidl_policy::SecurityType::None,
1090 };
1091 let network_config = fidl_policy::NetworkConfig {
1092 id: Some(network_id.clone()),
1093 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
1094 ..Default::default()
1095 };
1096 let mut save_fut = controller.save_network(&network_config);
1097
1098 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Pending);
1100 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1101
1102 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(Ok(Ok(()))));
1104
1105 let target_id = NetworkIdentifier::from(network_id);
1107 let target_config = NetworkConfig::new(target_id.clone(), Credential::None, false, None)
1108 .expect("Failed to create network config");
1109 assert_eq!(exec.run_singlethreaded(saved_networks.lookup(&target_id)), Some(target_config));
1110 }
1111
1112 #[fuchsia::test]
1113 fn save_network_with_disconnected_iface() {
1114 let mut exec = fasync::TestExecutor::new();
1115 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1116
1117 let mut test_values = test_setup();
1118 let serve_fut = serve_provider_requests(
1119 test_values.iface_manager.clone(),
1120 test_values.update_sender,
1121 saved_networks.clone(),
1122 test_values.scan_requester,
1123 test_values.client_provider_lock,
1124 test_values.requests,
1125 test_values.telemetry_sender,
1126 test_values.power_manager.clone(),
1127 );
1128 let mut serve_fut = pin!(serve_fut);
1129
1130 {
1132 let iface_manager = test_values.iface_manager.clone();
1133 let iface_manager_fut = iface_manager.lock();
1134 let mut iface_manager_fut = pin!(iface_manager_fut);
1135 let mut iface_manager = match exec.run_until_stalled(&mut iface_manager_fut) {
1136 Poll::Ready(iface_manager) => iface_manager,
1137 Poll::Pending => panic!("expected to acquire iface_manager lock"),
1138 };
1139 let record_idle_fut = iface_manager.record_idle_client(0);
1140 let mut record_idle_fut = pin!(record_idle_fut);
1141 assert_matches!(exec.run_until_stalled(&mut record_idle_fut), Poll::Ready(Ok(())));
1142 }
1143
1144 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1146
1147 let (controller, _update_stream) = request_controller(&test_values.provider);
1149 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1150 assert_matches!(
1151 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1152 Poll::Ready(_)
1153 );
1154
1155 let network_id = fidl_policy::NetworkIdentifier {
1157 ssid: b"foo".to_vec(),
1158 type_: fidl_policy::SecurityType::None,
1159 };
1160 let network_config = fidl_policy::NetworkConfig {
1161 id: Some(network_id.clone()),
1162 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
1163 ..Default::default()
1164 };
1165 let mut save_fut = controller.save_network(&network_config);
1166
1167 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Pending);
1168 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1169
1170 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(result) => {
1172 let save_result = result.expect("Failed to get save network response");
1173 assert_eq!(save_result, Ok(()));
1174 });
1175
1176 let target_id = NetworkIdentifier::from(network_id);
1178 let target_config = NetworkConfig::new(target_id.clone(), Credential::None, false, None)
1179 .expect("Failed to create network config");
1180 assert_eq!(exec.run_singlethreaded(saved_networks.lookup(&target_id)), Some(target_config));
1181 }
1182
1183 #[fuchsia::test]
1184 fn save_network_overwrite_disconnects() {
1185 let mut exec = fasync::TestExecutor::new();
1186 let mut test_values = test_setup();
1187 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1188
1189 let serve_fut = serve_provider_requests(
1190 test_values.iface_manager,
1191 test_values.update_sender,
1192 saved_networks.clone(),
1193 test_values.scan_requester,
1194 test_values.client_provider_lock,
1195 test_values.requests,
1196 test_values.telemetry_sender,
1197 test_values.power_manager.clone(),
1198 );
1199 let mut serve_fut = pin!(serve_fut);
1200
1201 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1203
1204 let (controller, _update_stream) = request_controller(&test_values.provider);
1206 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1207 assert_matches!(
1208 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1209 Poll::Ready(_)
1210 );
1211
1212 let network_id = NetworkIdentifier::try_from("foo", SecurityType::Wpa2).unwrap();
1214 let credential = Credential::Password(b"password".to_vec());
1215 let save_fut = saved_networks.store(network_id.clone(), credential.clone());
1216 let mut save_fut = pin!(save_fut);
1217 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(Ok(None)));
1218
1219 let network_config = fidl_policy::NetworkConfig {
1221 id: Some(fidl_policy::NetworkIdentifier::from(network_id.clone())),
1222 credential: Some(fidl_policy::Credential::Password(b"other-password".to_vec())),
1223 ..Default::default()
1224 };
1225 let mut save_fut = controller.save_network(&network_config);
1226
1227 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1229 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1230
1231 assert_matches!(exec.run_until_stalled(&mut test_values.iface_mgr_req_recvr.next()), Poll::Ready(Some(IfaceManagerRequest::Disconnect(net_id, reason))) => {
1233 assert_eq!(net_id, network_id.clone());
1234 assert_eq!(reason, client_types::DisconnectReason::NetworkConfigUpdated);
1235 });
1236 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1237 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(Ok(Ok(()))));
1238 }
1239
1240 #[fuchsia::test]
1241 fn save_bad_network_should_fail() {
1242 let mut exec = fasync::TestExecutor::new();
1243 let mut saved_networks = FakeSavedNetworksManager::new();
1244 saved_networks.fail_all_stores = true;
1245 let saved_networks = Arc::new(saved_networks);
1246
1247 let mut test_values = test_setup();
1248 let serve_fut = serve_provider_requests(
1249 test_values.iface_manager,
1250 test_values.update_sender,
1251 saved_networks.clone(),
1252 test_values.scan_requester,
1253 test_values.client_provider_lock,
1254 test_values.requests,
1255 test_values.telemetry_sender,
1256 test_values.power_manager.clone(),
1257 );
1258 let mut serve_fut = pin!(serve_fut);
1259
1260 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1262
1263 let (controller, _update_stream) = request_controller(&test_values.provider);
1265 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1266 assert_matches!(
1267 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1268 Poll::Ready(_)
1269 );
1270
1271 let bad_network_id = fidl_policy::NetworkIdentifier {
1275 ssid: b"foo".to_vec(),
1276 type_: fidl_policy::SecurityType::Wpa2,
1277 };
1278 let network_config = fidl_policy::NetworkConfig {
1279 id: Some(bad_network_id.clone()),
1280 credential: Some(fidl_policy::Credential::Password(b"bar".to_vec())),
1281 ..Default::default()
1282 };
1283 let mut save_fut = controller.save_network(&network_config);
1285
1286 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1288
1289 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(result) => {
1291 let error = result.expect("Failed to get save network response");
1292 assert_eq!(error, Err(fidl_policy::NetworkConfigChangeError::NetworkConfigWriteError));
1293 });
1294
1295 let target_id = NetworkIdentifier::from(bad_network_id);
1297 assert_eq!(exec.run_singlethreaded(saved_networks.lookup(&target_id)), None);
1298 }
1299
1300 #[fuchsia::test]
1301 fn test_remove_a_network() {
1302 let mut exec = fasync::TestExecutor::new();
1303 let mut test_values = test_setup();
1304
1305 let serve_fut = serve_provider_requests(
1306 test_values.iface_manager,
1307 test_values.update_sender,
1308 test_values.saved_networks.clone(),
1309 test_values.scan_requester,
1310 test_values.client_provider_lock,
1311 test_values.requests,
1312 test_values.telemetry_sender,
1313 test_values.power_manager.clone(),
1314 );
1315 let mut serve_fut = pin!(serve_fut);
1316
1317 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1319
1320 let (controller, _update_stream) = request_controller(&test_values.provider);
1322 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1323 assert_matches!(
1324 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1325 Poll::Ready(_)
1326 );
1327
1328 let mut remove_fut = controller.forget_network(&test_values.net_id_open);
1330
1331 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1333 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1334
1335 assert_matches!(exec.run_until_stalled(&mut test_values.iface_mgr_req_recvr.next()), Poll::Ready(Some(IfaceManagerRequest::Disconnect(net_id, reason))) => {
1339 assert_eq!(net_id, test_values.net_id_open.clone().into());
1340 assert_eq!(reason, client_types::DisconnectReason::NetworkUnsaved);
1341 });
1342 assert_matches!(exec.run_until_stalled(&mut remove_fut), Poll::Ready(Ok(Ok(()))));
1343 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1344 assert!(
1345 exec.run_singlethreaded(
1346 test_values.saved_networks.lookup(&test_values.net_id_open.clone().into())
1347 )
1348 .is_none()
1349 );
1350
1351 let mut remove_fut = controller.forget_network(&test_values.net_id_open);
1353 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1355 assert_matches!(
1356 exec.run_until_stalled(&mut test_values.iface_mgr_req_recvr.next()),
1357 Poll::Pending
1358 );
1359 assert_matches!(exec.run_until_stalled(&mut remove_fut), Poll::Ready(Ok(Ok(()))));
1360 }
1361
1362 #[fuchsia::test]
1363 fn test_get_saved_network() {
1364 let expected_configs = vec![generate_random_fidl_network_config()];
1365 let expected_num_sends = 1;
1366 run_get_saved_networks_test(expected_configs, expected_num_sends);
1367 }
1368
1369 #[fuchsia::test]
1370 fn test_get_saved_networks_multiple_chunks() {
1371 let mut configs = vec![];
1374 for index in 0..MAX_CONFIGS_PER_RESPONSE + 1 {
1375 let ssid = format!("some_config{index}");
1377 let network_config = generate_random_fidl_network_config_with_ssid(&ssid);
1378 configs.push(network_config);
1379 }
1380
1381 let expected_num_sends = 2;
1382 run_get_saved_networks_test(configs, expected_num_sends);
1383 }
1384
1385 fn run_get_saved_networks_test(
1392 configs: Vec<fidl_policy::NetworkConfig>,
1393 expected_num_sends: usize,
1394 ) {
1395 let mut exec = fasync::TestExecutor::new();
1396 let saved_networks =
1397 Arc::new(FakeSavedNetworksManager::new_with_saved_networks(configs.clone()));
1398
1399 let test_values = test_setup();
1400 let serve_fut = serve_provider_requests(
1401 test_values.iface_manager,
1402 test_values.update_sender,
1403 saved_networks.clone(),
1404 test_values.scan_requester,
1405 test_values.client_provider_lock,
1406 test_values.requests,
1407 test_values.telemetry_sender,
1408 test_values.power_manager.clone(),
1409 );
1410 let mut serve_fut = pin!(serve_fut);
1411
1412 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1414
1415 let (controller, _update_stream) = request_controller(&test_values.provider);
1417 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1418
1419 let (iter, server) =
1421 fidl::endpoints::create_proxy::<fidl_policy::NetworkConfigIteratorMarker>();
1422 controller.get_saved_networks(server).expect("Failed to call get saved networks");
1423
1424 let mut saved_networks_results = vec![];
1427 for i in 0..expected_num_sends {
1428 let get_saved_fut = iter.get_next();
1429 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1430 let results = exec
1431 .run_singlethreaded(get_saved_fut)
1432 .expect("Failed to get next chunk of saved networks results");
1433 if i < expected_num_sends - 1 {
1436 assert_eq!(results.len(), MAX_CONFIGS_PER_RESPONSE);
1437 } else {
1438 assert_eq!(results.len(), configs.len() % MAX_CONFIGS_PER_RESPONSE);
1439 }
1440 saved_networks_results.extend(results);
1441 }
1442 let get_saved_end_fut = iter.get_next();
1443 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1444 let results = exec
1445 .run_singlethreaded(get_saved_end_fut)
1446 .expect("Failed to get next chunk of saved networks results");
1447 assert!(results.is_empty());
1448
1449 for network_config in &configs {
1451 assert!(saved_networks_results.contains(network_config));
1452 }
1453 assert_eq!(configs.len(), saved_networks_results.len());
1454 }
1455
1456 #[fuchsia::test]
1457 fn register_update_listener() {
1458 let mut exec = fasync::TestExecutor::new();
1459 let mut test_values = test_setup();
1460 let serve_fut = serve_provider_requests(
1461 test_values.iface_manager,
1462 test_values.update_sender,
1463 test_values.saved_networks,
1464 test_values.scan_requester,
1465 test_values.client_provider_lock,
1466 test_values.requests,
1467 test_values.telemetry_sender,
1468 test_values.power_manager.clone(),
1469 );
1470 let mut serve_fut = pin!(serve_fut);
1471
1472 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1474
1475 let (_controller, _update_stream) = request_controller(&test_values.provider);
1477 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1478 assert_matches!(
1479 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1480 Poll::Ready(Some(listener::Message::NewListener(_)))
1481 );
1482 }
1483
1484 #[fuchsia::test]
1485 fn get_listener() {
1486 let mut exec = fasync::TestExecutor::new();
1487 let (listener, requests) = create_proxy::<fidl_policy::ClientListenerMarker>();
1488 let requests = requests.into_stream();
1489
1490 let (update_sender, mut listener_updates) = mpsc::unbounded();
1491 let serve_fut = serve_listener_requests(update_sender, requests);
1492 let mut serve_fut = pin!(serve_fut);
1493
1494 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1496
1497 let (update_sink, _update_stream) =
1499 create_request_stream::<fidl_policy::ClientStateUpdatesMarker>();
1500 listener.get_listener(update_sink).expect("error getting listener");
1501
1502 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1503 assert_matches!(
1504 exec.run_until_stalled(&mut listener_updates.next()),
1505 Poll::Ready(Some(listener::Message::NewListener(_)))
1506 );
1507 }
1508
1509 #[fuchsia::test]
1510 fn multiple_controllers_write_attempt() {
1511 let mut exec = fasync::TestExecutor::new();
1512 let test_values = test_setup();
1513 let serve_fut = serve_provider_requests(
1514 test_values.iface_manager,
1515 test_values.update_sender,
1516 test_values.saved_networks,
1517 test_values.scan_requester,
1518 test_values.client_provider_lock,
1519 test_values.requests,
1520 test_values.telemetry_sender,
1521 test_values.power_manager.clone(),
1522 );
1523 let mut serve_fut = pin!(serve_fut);
1524
1525 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1527
1528 let (controller1, _) = request_controller(&test_values.provider);
1530 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1531
1532 let (controller2, _) = request_controller(&test_values.provider);
1534 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1535
1536 let connect_fut = controller1.connect(&test_values.net_id_open);
1538 let mut connect_fut = pin!(connect_fut);
1539
1540 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1542
1543 assert_matches!(
1544 exec.run_until_stalled(&mut connect_fut),
1545 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
1546 );
1547
1548 let connect_fut = controller2.connect(&test_values.net_id_open);
1550 let mut connect_fut = pin!(connect_fut);
1551
1552 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1554 assert_matches!(
1555 exec.run_until_stalled(&mut connect_fut),
1556 Poll::Ready(Err(fidl::Error::ClientChannelClosed { epitaph, .. }))
1557 if epitaph == zx::Status::ALREADY_BOUND
1558 );
1559
1560 drop(controller1);
1562 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1563
1564 let (controller3, _) = request_controller(&test_values.provider);
1566 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1567
1568 let connect_fut = controller3.connect(&test_values.net_id_open);
1570 let mut connect_fut = pin!(connect_fut);
1571
1572 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1574
1575 assert_matches!(
1576 exec.run_until_stalled(&mut connect_fut),
1577 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
1578 );
1579 }
1580
1581 #[fuchsia::test]
1582 fn multiple_controllers_epitaph() {
1583 let mut exec = fasync::TestExecutor::new();
1584 let test_values = test_setup();
1585 let serve_fut = serve_provider_requests(
1586 test_values.iface_manager,
1587 test_values.update_sender,
1588 test_values.saved_networks.clone(),
1589 test_values.scan_requester,
1590 test_values.client_provider_lock,
1591 test_values.requests,
1592 test_values.telemetry_sender,
1593 test_values.power_manager.clone(),
1594 );
1595 let mut serve_fut = pin!(serve_fut);
1596
1597 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1599
1600 let (_controller1, _) = request_controller(&test_values.provider);
1602 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1603
1604 let (controller2, _) = request_controller(&test_values.provider);
1606 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1607
1608 let mut controller2_event_stream = controller2.take_event_stream();
1610 let controller2_event_fut = controller2_event_stream.next();
1611 let mut controller2_event_fut = pin!(controller2_event_fut);
1612 assert_matches!(
1613 exec.run_until_stalled(&mut controller2_event_fut),
1614 Poll::Ready(Some(Err(fidl::Error::ClientChannelClosed { epitaph, .. })))
1615 if epitaph == zx::Status::ALREADY_BOUND
1616 );
1617
1618 assert!(controller2.is_closed());
1619 }
1620
1621 struct FakeIfaceManagerNoIfaces {}
1622
1623 #[async_trait(?Send)]
1624 impl IfaceManagerApi for FakeIfaceManagerNoIfaces {
1625 async fn disconnect(
1626 &mut self,
1627 _network_id: client_types::NetworkIdentifier,
1628 _reason: client_types::DisconnectReason,
1629 ) -> Result<(), Error> {
1630 Err(format_err!("No ifaces"))
1631 }
1632
1633 async fn connect(&mut self, _connect_req: ConnectAttemptRequest) -> Result<(), Error> {
1634 Err(format_err!("No ifaces"))
1635 }
1636
1637 async fn record_idle_client(&mut self, _iface_id: u16) -> Result<(), Error> {
1638 unimplemented!()
1639 }
1640
1641 async fn has_idle_client(&mut self) -> Result<bool, Error> {
1642 unimplemented!()
1643 }
1644
1645 async fn handle_added_iface(&mut self, _iface_id: u16) -> Result<(), Error> {
1646 unimplemented!()
1647 }
1648
1649 async fn handle_removed_iface(&mut self, _iface_id: u16) -> Result<(), Error> {
1650 unimplemented!()
1651 }
1652
1653 async fn get_sme_proxy_for_scan(&mut self) -> Result<SmeForScan, Error> {
1654 Err(format_err!("No ifaces"))
1655 }
1656
1657 async fn stop_client_connections(
1658 &mut self,
1659 _reason: client_types::DisconnectReason,
1660 ) -> Result<(), Error> {
1661 unimplemented!()
1662 }
1663
1664 async fn start_client_connections(&mut self) -> Result<(), Error> {
1665 unimplemented!()
1666 }
1667
1668 async fn start_ap(
1669 &mut self,
1670 _config: ap_fsm::ApConfig,
1671 ) -> Result<oneshot::Receiver<()>, Error> {
1672 unimplemented!()
1673 }
1674
1675 async fn stop_ap(&mut self, _ssid: types::Ssid, _password: Vec<u8>) -> Result<(), Error> {
1676 unimplemented!()
1677 }
1678
1679 async fn stop_all_aps(&mut self) -> Result<(), Error> {
1680 unimplemented!()
1681 }
1682
1683 async fn set_country(
1684 &mut self,
1685 _country_code: Option<types::CountryCode>,
1686 ) -> Result<(), Error> {
1687 unimplemented!()
1688 }
1689 }
1690
1691 #[fuchsia::test]
1692 fn no_client_interface() {
1693 let mut exec = fasync::TestExecutor::new();
1694 let test_values = test_setup();
1695
1696 let iface_manager = Arc::new(Mutex::new(FakeIfaceManagerNoIfaces {}));
1697
1698 let serve_fut = serve_provider_requests(
1699 iface_manager,
1700 test_values.update_sender,
1701 test_values.saved_networks,
1702 test_values.scan_requester,
1703 test_values.client_provider_lock,
1704 test_values.requests,
1705 test_values.telemetry_sender,
1706 test_values.power_manager.clone(),
1707 );
1708 let mut serve_fut = pin!(serve_fut);
1709
1710 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1712
1713 let (controller, _) = request_controller(&test_values.provider);
1715 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1716
1717 let connect_fut = controller.connect(&test_values.net_id_open);
1719 let mut connect_fut = pin!(connect_fut);
1720
1721 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1723 assert_matches!(
1724 exec.run_until_stalled(&mut connect_fut),
1725 Poll::Ready(Ok(fidl_policy::RequestStatus::RejectedIncompatibleMode))
1726 );
1727 }
1728
1729 async fn get_config(
1733 saved_networks: Arc<dyn SavedNetworksManagerApi>,
1734 id: NetworkIdentifier,
1735 cred: Credential,
1736 ) -> Option<NetworkConfig> {
1737 saved_networks.lookup(&id).await.filter(|cfg| cfg.credential == cred)
1738 }
1739
1740 #[fuchsia::test]
1741 async fn get_correct_config() {
1742 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1743 let network_id = NetworkIdentifier::try_from("foo", SecurityType::Wpa2).unwrap();
1744 let cfg = NetworkConfig::new(
1745 network_id.clone(),
1746 Credential::Password(b"password".to_vec()),
1747 false,
1748 None,
1749 )
1750 .expect("Failed to create network config");
1751
1752 assert!(
1753 saved_networks
1754 .store(network_id.clone(), Credential::Password(b"password".to_vec()))
1755 .await
1756 .expect("Failed to store network config")
1757 .is_none()
1758 );
1759
1760 assert_eq!(
1761 Some(cfg),
1762 get_config(
1763 saved_networks.clone(),
1764 network_id,
1765 Credential::Password(b"password".to_vec())
1766 )
1767 .await
1768 );
1769 assert_eq!(
1770 None,
1771 get_config(
1772 saved_networks.clone(),
1773 NetworkIdentifier::try_from("foo", SecurityType::Wpa2).unwrap(),
1774 Credential::Password(b"not-saved".to_vec())
1775 )
1776 .await
1777 );
1778 }
1779
1780 #[fuchsia::test]
1781 fn multiple_api_clients() {
1782 let mut exec = fasync::TestExecutor::new();
1783 let test_values = test_setup();
1784 let serve_fut = serve_provider_requests(
1785 test_values.iface_manager.clone(),
1786 test_values.update_sender.clone(),
1787 test_values.saved_networks.clone(),
1788 test_values.scan_requester.clone(),
1789 test_values.client_provider_lock.clone(),
1790 test_values.requests,
1791 test_values.telemetry_sender.clone(),
1792 test_values.power_manager.clone(),
1793 );
1794 let mut serve_fut = pin!(serve_fut);
1795
1796 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1798
1799 let (controller1, _) = request_controller(&test_values.provider);
1801 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1802
1803 let (provider, requests) = create_proxy::<fidl_policy::ClientProviderMarker>();
1806 let requests = requests.into_stream();
1807
1808 let second_serve_fut = serve_provider_requests(
1809 test_values.iface_manager.clone(),
1810 test_values.update_sender.clone(),
1811 test_values.saved_networks.clone(),
1812 test_values.scan_requester,
1813 test_values.client_provider_lock.clone(),
1814 requests,
1815 test_values.telemetry_sender,
1816 test_values.power_manager.clone(),
1817 );
1818 let mut second_serve_fut = pin!(second_serve_fut);
1819
1820 let (controller2, _) = request_controller(&provider);
1822 assert_matches!(exec.run_until_stalled(&mut second_serve_fut), Poll::Pending);
1823
1824 let mut controller2_event_stream = controller2.take_event_stream();
1826 let controller2_event_fut = controller2_event_stream.next();
1827 let mut controller2_event_fut = pin!(controller2_event_fut);
1828 assert_matches!(
1829 exec.run_until_stalled(&mut controller2_event_fut),
1830 Poll::Ready(Some(Err(fidl::Error::ClientChannelClosed { epitaph, .. })))
1831 if epitaph == zx::Status::ALREADY_BOUND
1832 );
1833
1834 assert!(controller2.is_closed());
1835
1836 drop(controller1);
1839 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1840
1841 let (controller2, _) = request_controller(&provider);
1842 assert_matches!(exec.run_until_stalled(&mut second_serve_fut), Poll::Pending);
1843
1844 let connect_fut = controller2.connect(&test_values.net_id_open);
1846 let mut connect_fut = pin!(connect_fut);
1847
1848 assert_matches!(exec.run_until_stalled(&mut second_serve_fut), Poll::Pending);
1850
1851 assert_matches!(
1852 exec.run_until_stalled(&mut connect_fut),
1853 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
1854 );
1855 }
1856
1857 #[test_case(true)]
1858 #[test_case(false)]
1859 #[fuchsia::test(add_test_attr = false)]
1860 fn test_start_client_connections(start_client_connections_succeeds: bool) {
1861 let mut exec = fasync::TestExecutor::new();
1862 let (proxy, _server) = create_proxy::<fidl_fuchsia_wlan_sme::ClientSmeMarker>();
1863 let (req_sender, _req_recvr) = mpsc::channel(1);
1864 let mut iface_manager = FakeIfaceManager::new(proxy.clone(), req_sender);
1865
1866 iface_manager.start_client_connections_succeeds = start_client_connections_succeeds;
1868
1869 let iface_manager: Arc<Mutex<dyn IfaceManagerApi>> = Arc::new(Mutex::new(iface_manager));
1870
1871 let fut = handle_client_request_start_client_connections(iface_manager);
1874 let mut fut = pin!(fut);
1875 assert_matches!(
1876 exec.run_until_stalled(&mut fut),
1877 Poll::Ready(fidl_policy::RequestStatus::Acknowledged)
1878 );
1879 }
1880
1881 #[test_case(true)]
1882 #[test_case(false)]
1883 #[fuchsia::test(add_test_attr = false)]
1884 fn test_stop_client_connections(stop_client_connections_succeeds: bool) {
1885 let mut exec = fasync::TestExecutor::new();
1886 let (proxy, _server) = create_proxy::<fidl_fuchsia_wlan_sme::ClientSmeMarker>();
1887 let (req_sender, _req_recvr) = mpsc::channel(1);
1888 let mut iface_manager = FakeIfaceManager::new(proxy.clone(), req_sender);
1889
1890 iface_manager.stop_client_connections_succeeds = stop_client_connections_succeeds;
1892
1893 let iface_manager: Arc<Mutex<dyn IfaceManagerApi>> = Arc::new(Mutex::new(iface_manager));
1894
1895 let fut = handle_client_request_stop_client_connections(iface_manager);
1898 let mut fut = pin!(fut);
1899 assert_matches!(
1900 exec.run_until_stalled(&mut fut),
1901 Poll::Ready(fidl_policy::RequestStatus::Acknowledged)
1902 );
1903 }
1904
1905 #[fuchsia::test]
1906 fn test_client_wake_leases() {
1907 let mut exec = fasync::TestExecutor::new();
1908 let test_values = test_setup();
1909 let serve_fut = serve_provider_requests(
1910 test_values.iface_manager,
1911 test_values.update_sender,
1912 Arc::clone(&test_values.saved_networks),
1913 test_values.scan_requester,
1914 test_values.client_provider_lock,
1915 test_values.requests,
1916 test_values.telemetry_sender,
1917 test_values.power_manager.clone(),
1918 );
1919 let mut serve_fut = pin!(serve_fut);
1920 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1921
1922 let (controller, _) = request_controller(&test_values.provider);
1923 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1924
1925 let connect_fut = controller.connect(&test_values.net_id_open);
1927 let mut connect_fut = pin!(connect_fut);
1928 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1929 assert_matches!(exec.run_until_stalled(&mut connect_fut), Poll::Ready(Ok(_)));
1930
1931 let start_fut = controller.start_client_connections();
1933 let mut start_fut = pin!(start_fut);
1934 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1935 assert_matches!(exec.run_until_stalled(&mut start_fut), Poll::Ready(Ok(_)));
1936
1937 let stop_fut = controller.stop_client_connections();
1939 let mut stop_fut = pin!(stop_fut);
1940 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1941 assert_matches!(exec.run_until_stalled(&mut stop_fut), Poll::Ready(Ok(_)));
1942
1943 let save_fut = controller.save_network(&fidl_policy::NetworkConfig {
1945 id: Some(test_values.net_id_open.clone()),
1946 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
1947 ..Default::default()
1948 });
1949 let mut save_fut = pin!(save_fut);
1950 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1951 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(Ok(_)));
1952
1953 let remove_fut = controller.remove_network(&fidl_policy::NetworkConfig {
1955 id: Some(test_values.net_id_open.clone()),
1956 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
1957 ..Default::default()
1958 });
1959 let mut remove_fut = pin!(remove_fut);
1960 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1961 assert_matches!(exec.run_until_stalled(&mut remove_fut), Poll::Ready(Ok(_)));
1962
1963 let (_iterator, server_end) =
1965 fidl::endpoints::create_endpoints::<fidl_policy::NetworkConfigIteratorMarker>();
1966 let _ = controller.get_saved_networks(server_end);
1967 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1968
1969 let calls = test_values.power_manager.calls.lock();
1971 assert!(calls.contains(&"wlancfg-client-connect".to_string()));
1972 assert!(calls.contains(&"wlancfg-client-start-connections".to_string()));
1973 assert!(calls.contains(&"wlancfg-client-stop-connections".to_string()));
1974 assert!(calls.contains(&"wlancfg-client-save-network".to_string()));
1975 assert!(calls.contains(&"wlancfg-client-remove-network".to_string()));
1976 assert!(calls.contains(&"wlancfg-client-get-saved-networks".to_string()));
1977 }
1978}