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