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::GetSavedNetworks { .. } => "GetSavedNetworks",
134 }
135 );
136}
137
138async fn handle_client_requests(
140 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
141 scan_requester: Arc<dyn scan::ScanRequestApi>,
142 saved_networks: SavedNetworksPtr,
143 client_provider_guard: MutexGuard<'_, ()>,
144 requests: ClientRequests,
145 telemetry_sender: TelemetrySender,
146) -> Result<(), fidl::Error> {
147 let mut request_stream = requests.into_stream();
148 while let Some(request) = request_stream.try_next().await? {
149 log_client_request(&request);
150 match request {
151 fidl_policy::ClientControllerRequest::Connect { id, responder, .. } => {
152 let response = handle_client_request_connect(
153 Arc::clone(&iface_manager),
154 saved_networks.clone(),
155 &id,
156 )
157 .await;
158 responder.send(response)?
159 }
160 fidl_policy::ClientControllerRequest::StartClientConnections { responder } => {
161 telemetry_sender.send(TelemetryEvent::StartClientConnectionsRequest);
162 let response =
163 handle_client_request_start_client_connections(iface_manager.clone()).await;
164 responder.send(response)?
165 }
166 fidl_policy::ClientControllerRequest::StopClientConnections { responder } => {
167 telemetry_sender.send(TelemetryEvent::StopClientConnectionsRequest);
168 let response =
169 handle_client_request_stop_client_connections(iface_manager.clone()).await;
170 responder.send(response)?
171 }
172 fidl_policy::ClientControllerRequest::ScanForNetworks { iterator, .. } => {
173 let fut = handle_client_request_scan(
174 scan_requester.clone(),
175 saved_networks.clone(),
176 telemetry_sender.clone(),
177 iterator,
178 );
179 fuchsia_async::Task::local(fut).detach();
182 }
183 fidl_policy::ClientControllerRequest::SaveNetwork { config, responder } => {
184 let response = handle_client_request_save_network(
186 saved_networks.clone(),
187 config,
188 Arc::clone(&iface_manager),
189 )
190 .await
191 .map_err(|e| {
192 error!("Failed to save network: {:?}", e);
193 fidl_policy::NetworkConfigChangeError::from(e)
194 });
195 responder.send(response)?;
196 }
197 fidl_policy::ClientControllerRequest::RemoveNetwork { config, responder } => {
198 let err = handle_client_request_remove_network(
199 saved_networks.clone(),
200 config,
201 iface_manager.clone(),
202 )
203 .map_err(|_| SaveError::GeneralError)
204 .await;
205
206 responder.send(err)?;
207 }
208 fidl_policy::ClientControllerRequest::GetSavedNetworks { iterator, .. } => {
209 handle_client_request_get_networks(saved_networks.clone(), iterator).await?;
210 }
211 }
212 }
213 drop(client_provider_guard);
214 Ok(())
215}
216
217async fn handle_client_request_connect(
220 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
221 saved_networks: SavedNetworksPtr,
222 network: &fidl_policy::NetworkIdentifier,
223) -> fidl_policy::RequestStatus {
224 let network_config = match saved_networks
225 .lookup(&NetworkIdentifier::new(
226 client_types::Ssid::from_bytes_unchecked(network.ssid.clone()),
227 network.type_.into(),
228 ))
229 .await
230 .pop()
231 {
232 Some(config) => config,
233 None => {
234 error!("Requested network not found in saved networks");
235 return fidl_policy::RequestStatus::RejectedNotSupported;
236 }
237 };
238
239 let network_id = fidl_policy::NetworkIdentifier {
240 ssid: network_config.ssid.into(),
241 type_: fidl_policy::SecurityType::from(network_config.security_type),
242 };
243 let connect_req = ConnectAttemptRequest::new(
244 network_id.into(),
245 network_config.credential,
246 client_types::ConnectReason::FidlConnectRequest,
247 );
248
249 let mut iface_manager = iface_manager.lock().await;
250 match iface_manager.connect(connect_req).await {
251 Ok(_) => fidl_policy::RequestStatus::Acknowledged,
252 Err(e) => {
253 error!("failed to connect: {:?}", e);
254 fidl_policy::RequestStatus::RejectedIncompatibleMode
255 }
256 }
257}
258
259async fn handle_client_request_scan(
260 scan_requester: Arc<dyn scan::ScanRequestApi>,
261 saved_networks: SavedNetworksPtr,
262 telemetry_sender: TelemetrySender,
263 output_iterator: fidl::endpoints::ServerEnd<fidl_fuchsia_wlan_policy::ScanResultIteratorMarker>,
264) {
265 let get_scan_results = async {
266 let passive_scan_results =
267 scan_requester.perform_scan(scan::ScanReason::ClientRequest, vec![], vec![]).await?;
268
269 let requested_active_scan_ssids: Vec<types::Ssid> =
270 config_management::select_high_probability_hidden_networks(
271 saved_networks.get_networks().await,
272 )
273 .drain(..)
274 .map(|id| id.ssid)
275 .collect();
276
277 info!(
278 "Completed passive scan for API request, {} likely-hidden networks to scan for.",
279 requested_active_scan_ssids.len()
280 );
281 telemetry_sender.send(TelemetryEvent::ActiveScanRequestedViaApi {
282 num_ssids_requested: requested_active_scan_ssids.len(),
283 });
284
285 if requested_active_scan_ssids.is_empty() {
286 Ok(passive_scan_results)
287 } else {
288 scan_requester
289 .perform_scan(scan::ScanReason::ClientRequest, requested_active_scan_ssids, vec![])
290 .await
291 .map(|mut scan_results| {
292 scan_results.extend(passive_scan_results);
293 scan_results
294 })
295 }
296 };
297
298 match get_scan_results.await {
299 Ok(results) => {
300 let fidl_results = scan::scan_result_to_policy_scan_result(&results, false);
305 if let Err(e) = scan::send_scan_results_over_fidl(output_iterator, &fidl_results).await
306 {
307 warn!("Failed to send scan results to requester: {:?}", e);
308 }
309 }
310 Err(e) => {
311 if let Err(e) = scan::send_scan_error_over_fidl(output_iterator, e).await {
312 warn!("Failed to send scan error to requester: {:?}", e);
313 }
314 }
315 }
316}
317
318async fn handle_client_request_save_network(
322 saved_networks: SavedNetworksPtr,
323 network_config: fidl_policy::NetworkConfig,
324 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
325) -> Result<(), NetworkConfigError> {
326 let net_id: client_types::NetworkIdentifier =
329 network_config.id.ok_or(NetworkConfigError::ConfigMissingId)?.into();
330 let credential = Credential::try_from(
331 network_config.credential.ok_or(NetworkConfigError::ConfigMissingCredential)?,
332 )?;
333 let evicted_config = saved_networks.store(net_id.clone(), credential.clone()).await?;
334
335 let mut iface_manager = iface_manager.lock().await;
337 if let Some(config) = evicted_config {
338 let net_id = client_types::NetworkIdentifier {
339 ssid: config.ssid,
340 security_type: config.security_type,
341 };
342 match iface_manager
343 .disconnect(net_id, client_types::DisconnectReason::NetworkConfigUpdated)
344 .await
345 {
346 Ok(()) => {}
347 Err(e) => error!("failed to disconnect from network: {}", e),
348 }
349 }
350
351 let connect_req = ConnectAttemptRequest::new(
353 net_id,
354 credential,
355 client_types::ConnectReason::NewSavedNetworkAutoconnect,
356 );
357 match iface_manager.has_idle_client().await {
358 Ok(true) => {
359 info!("Idle interface available, will attempt connection to new saved network");
360 let _ = iface_manager.connect(connect_req).await;
361 }
362 Ok(false) => {}
363 Err(e) => {
364 error!("Unable to query idle client state while saving network: {:?}", e);
365 }
366 }
367
368 Ok(())
369}
370
371async fn handle_client_request_remove_network(
374 saved_networks: SavedNetworksPtr,
375 network_config: fidl_policy::NetworkConfig,
376 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
377) -> Result<(), NetworkConfigError> {
378 let net_id =
381 NetworkIdentifier::from(network_config.id.ok_or(NetworkConfigError::ConfigMissingId)?);
382 let credential = Credential::try_from(
383 network_config.credential.ok_or(NetworkConfigError::ConfigMissingCredential)?,
384 )?;
385 if saved_networks.remove(net_id.clone(), credential.clone()).await? {
386 match iface_manager
387 .lock()
388 .await
389 .disconnect(net_id, client_types::DisconnectReason::NetworkUnsaved)
390 .await
391 {
392 Ok(()) => {}
393 Err(e) => error!("failed to disconnect from network: {}", e),
394 }
395 }
396 Ok(())
397}
398
399async fn handle_client_request_get_networks(
400 saved_networks: SavedNetworksPtr,
401 iterator: fidl::endpoints::ServerEnd<fidl_policy::NetworkConfigIteratorMarker>,
402) -> Result<(), fidl::Error> {
403 let network_configs = saved_networks.get_networks().await;
405 let chunks = network_configs.chunks(MAX_CONFIGS_PER_RESPONSE);
406 let fidl_chunks = chunks.into_iter().map(|chunk| {
407 chunk
408 .iter()
409 .map(fidl_policy::NetworkConfig::from)
410 .collect::<Vec<fidl_policy::NetworkConfig>>()
411 });
412 let mut stream = iterator.into_stream();
413 for chunk in fidl_chunks {
414 send_next_chunk(&mut stream, chunk).await?;
415 }
416 send_next_chunk(&mut stream, vec![]).await
417}
418
419async fn send_next_chunk(
421 stream: &mut fidl_policy::NetworkConfigIteratorRequestStream,
422 chunk: Vec<fidl_policy::NetworkConfig>,
423) -> Result<(), fidl::Error> {
424 if let Some(req) = stream.try_next().await? {
425 let fidl_policy::NetworkConfigIteratorRequest::GetNext { responder } = req;
426 responder.send(&chunk)
427 } else {
428 info!("Info: peer closed channel for network config results unexpectedly");
432 Ok(())
433 }
434}
435
436async fn handle_listener_request(
438 update_sender: listener::ClientListenerMessageSender,
439 req: fidl_policy::ClientListenerRequest,
440) -> Result<(), fidl::Error> {
441 match req {
442 fidl_policy::ClientListenerRequest::GetListener { updates, .. } => {
443 register_listener(update_sender, updates.into_proxy());
444 Ok(())
445 }
446 }
447}
448
449fn register_listener(
452 update_sender: listener::ClientListenerMessageSender,
453 listener: fidl_policy::ClientStateUpdatesProxy,
454) {
455 let _ignored = update_sender.unbounded_send(listener::Message::NewListener(listener));
456}
457
458fn reject_provider_request(req: fidl_policy::ClientProviderRequest) -> Result<(), fidl::Error> {
461 match req {
462 fidl_policy::ClientProviderRequest::GetController { requests, updates, .. } => {
463 info!("Rejecting new client controller request because a controller is in use");
464 requests.into_channel().close_with_epitaph(zx::Status::ALREADY_BOUND)?;
465 updates.into_channel().close_with_epitaph(zx::Status::ALREADY_BOUND)?;
466 Ok(())
467 }
468 }
469}
470
471async fn handle_client_request_start_client_connections(
473 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
474) -> fidl_policy::RequestStatus {
475 let mut iface_manager = iface_manager.lock().await;
476 if let Err(e) = iface_manager.start_client_connections().await {
477 warn!("encountered an error while starting client connections: {:?}", e);
478 }
479 fidl_policy::RequestStatus::Acknowledged
480}
481
482async fn handle_client_request_stop_client_connections(
484 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
485) -> fidl_policy::RequestStatus {
486 let mut iface_manager = iface_manager.lock().await;
487 if let Err(e) = iface_manager
488 .stop_client_connections(client_types::DisconnectReason::FidlStopClientConnectionsRequest)
489 .await
490 {
491 warn!("encountered an error while stopping client connections: {:?}", e);
492 }
493 fidl_policy::RequestStatus::Acknowledged
494}
495
496#[cfg(test)]
497mod tests {
498 use super::*;
499 use crate::access_point::state_machine as ap_fsm;
500 use crate::config_management::{NetworkConfig, SecurityType, WPA_PSK_BYTE_LEN};
501 use crate::mode_management::iface_manager_api::SmeForScan;
502 use crate::util::testing::fakes::{FakeSavedNetworksManager, FakeScanRequester};
503 use crate::util::testing::{
504 generate_random_fidl_network_config, generate_random_fidl_network_config_with_ssid,
505 };
506 use anyhow::{Error, format_err};
507 use assert_matches::assert_matches;
508 use async_trait::async_trait;
509 use fidl::endpoints::{Proxy, create_proxy, create_request_stream};
510 use fuchsia_async as fasync;
511 use futures::channel::{mpsc, oneshot};
512 use futures::task::Poll;
513 use std::pin::pin;
514 use test_case::test_case;
515
516 #[derive(Debug)]
519 enum IfaceManagerRequest {
520 Disconnect(client_types::NetworkIdentifier, client_types::DisconnectReason),
521 }
522
523 struct FakeIfaceManager {
524 pub sme_proxy: fidl_fuchsia_wlan_sme::ClientSmeProxy,
525 pub disconnected_ifaces: Vec<u16>,
526 command_sender: mpsc::Sender<IfaceManagerRequest>,
527 start_client_connections_succeeds: bool,
528 stop_client_connections_succeeds: bool,
529 }
530
531 impl FakeIfaceManager {
532 pub fn new(
533 proxy: fidl_fuchsia_wlan_sme::ClientSmeProxy,
534 command_sender: mpsc::Sender<IfaceManagerRequest>,
535 ) -> Self {
536 FakeIfaceManager {
537 sme_proxy: proxy,
538 disconnected_ifaces: Vec::new(),
539 command_sender,
540 start_client_connections_succeeds: true,
541 stop_client_connections_succeeds: true,
542 }
543 }
544 }
545
546 #[async_trait(?Send)]
547 impl IfaceManagerApi for FakeIfaceManager {
548 async fn disconnect(
549 &mut self,
550 network_id: client_types::NetworkIdentifier,
551 reason: client_types::DisconnectReason,
552 ) -> Result<(), Error> {
553 self.command_sender
554 .try_send(IfaceManagerRequest::Disconnect(network_id, reason))
555 .map_err(|e| {
556 error!(
557 "Failed to send disconnect: commands_sender's receiver may have
558 been dropped. FakeIfaceManager should be created manually with a sender
559 assigned: {:?}",
560 e
561 );
562 format_err!("failed to send disconnect: {:?}", e)
563 })
564 }
565
566 async fn connect(&mut self, _connect_req: ConnectAttemptRequest) -> Result<(), Error> {
567 let _ = self.disconnected_ifaces.pop();
568 Ok(())
569 }
570
571 async fn record_idle_client(&mut self, iface_id: u16) -> Result<(), Error> {
572 self.disconnected_ifaces.push(iface_id);
573 Ok(())
574 }
575
576 async fn has_idle_client(&mut self) -> Result<bool, Error> {
577 Ok(!self.disconnected_ifaces.is_empty())
578 }
579
580 async fn handle_added_iface(&mut self, _iface_id: u16) -> Result<(), Error> {
581 unimplemented!()
582 }
583
584 async fn handle_removed_iface(&mut self, _iface_id: u16) -> Result<(), Error> {
585 unimplemented!()
586 }
587
588 async fn get_sme_proxy_for_scan(&mut self) -> Result<SmeForScan, Error> {
589 let (defect_sender, _) = mpsc::channel(100);
590 Ok(SmeForScan::new(self.sme_proxy.clone(), 0, defect_sender))
591 }
592
593 async fn stop_client_connections(
594 &mut self,
595 _reason: client_types::DisconnectReason,
596 ) -> Result<(), Error> {
597 if self.stop_client_connections_succeeds {
598 Ok(())
599 } else {
600 Err(format_err!("stop client connections failed"))
601 }
602 }
603
604 async fn start_client_connections(&mut self) -> Result<(), Error> {
605 if self.start_client_connections_succeeds {
606 Ok(())
607 } else {
608 Err(format_err!("start client connections failed"))
609 }
610 }
611
612 async fn start_ap(
613 &mut self,
614 _config: ap_fsm::ApConfig,
615 ) -> Result<oneshot::Receiver<()>, Error> {
616 unimplemented!()
617 }
618
619 async fn stop_ap(&mut self, _ssid: types::Ssid, _password: Vec<u8>) -> Result<(), Error> {
620 unimplemented!()
621 }
622
623 async fn stop_all_aps(&mut self) -> Result<(), Error> {
624 unimplemented!()
625 }
626
627 async fn set_country(
628 &mut self,
629 _country_code: Option<types::CountryCode>,
630 ) -> Result<(), Error> {
631 unimplemented!()
632 }
633 }
634
635 fn request_controller(
637 provider: &fidl_policy::ClientProviderProxy,
638 ) -> (fidl_policy::ClientControllerProxy, fidl_policy::ClientStateUpdatesRequestStream) {
639 let (controller, requests) = create_proxy::<fidl_policy::ClientControllerMarker>();
640 let (update_sink, update_stream) =
641 create_request_stream::<fidl_policy::ClientStateUpdatesMarker>();
642 provider.get_controller(requests, update_sink).expect("error getting controller");
643 (controller, update_stream)
644 }
645
646 struct TestValues {
647 saved_networks: SavedNetworksPtr,
648 net_id_open: fidl_policy::NetworkIdentifier,
649 net_id_wpa2_w_password: fidl_policy::NetworkIdentifier,
650 net_id_wpa2_w_psk: fidl_policy::NetworkIdentifier,
651 provider: fidl_policy::ClientProviderProxy,
652 requests: fidl_policy::ClientProviderRequestStream,
653 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
654 iface_mgr_req_recvr: mpsc::Receiver<IfaceManagerRequest>,
655 scan_requester: Arc<FakeScanRequester>,
656 update_sender: mpsc::UnboundedSender<listener::ClientListenerMessage>,
657 listener_updates: mpsc::UnboundedReceiver<listener::ClientListenerMessage>,
658 client_provider_lock: Arc<Mutex<()>>,
659 telemetry_sender: TelemetrySender,
660 telemetry_receiver: mpsc::Receiver<TelemetryEvent>,
661 }
662
663 fn test_setup() -> TestValues {
667 let net_id_open = fidl_policy::NetworkIdentifier {
668 ssid: "foobar".to_string().into_bytes(),
669 type_: fidl_policy::SecurityType::None,
670 };
671 let net_id_wpa2_w_password = fidl_policy::NetworkIdentifier {
672 ssid: b"foobar-wpa2".to_vec(),
673 type_: fidl_policy::SecurityType::Wpa2,
674 };
675 let net_id_wpa2_w_psk = fidl_policy::NetworkIdentifier {
676 ssid: b"foobar-psk".to_vec(),
677 type_: fidl_policy::SecurityType::Wpa2,
678 };
679
680 let presaved_default_configs = vec![
681 fidl_policy::NetworkConfig {
682 id: Some(net_id_open.clone()),
683 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
684 ..Default::default()
685 },
686 fidl_policy::NetworkConfig {
687 id: Some(net_id_wpa2_w_password.clone()),
688 credential: Some(fidl_policy::Credential::Password(b"foobar-password".to_vec())),
689 ..Default::default()
690 },
691 fidl_policy::NetworkConfig {
692 id: Some(net_id_wpa2_w_psk.clone()),
693 credential: Some(fidl_policy::Credential::Psk([64; WPA_PSK_BYTE_LEN].to_vec())),
694 ..Default::default()
695 },
696 ];
697 let saved_networks =
698 Arc::new(FakeSavedNetworksManager::new_with_saved_networks(presaved_default_configs));
699 let (telemetry_sender, telemetry_receiver) = mpsc::channel::<TelemetryEvent>(100);
700 let (provider, requests) = create_proxy::<fidl_policy::ClientProviderMarker>();
701 let requests = requests.into_stream();
702
703 let (proxy, _server) = create_proxy::<fidl_fuchsia_wlan_sme::ClientSmeMarker>();
704 let (req_sender, iface_mgr_req_recvr) = mpsc::channel(1);
705 let iface_manager = FakeIfaceManager::new(proxy.clone(), req_sender);
706 let iface_manager = Arc::new(Mutex::new(iface_manager));
707 let scan_requester = Arc::new(FakeScanRequester::new());
708
709 let (update_sender, listener_updates) = mpsc::unbounded();
710
711 TestValues {
712 saved_networks,
713 net_id_open,
714 net_id_wpa2_w_password,
715 net_id_wpa2_w_psk,
716 provider,
717 requests,
718 iface_manager,
719 iface_mgr_req_recvr,
720 scan_requester,
721 update_sender,
722 listener_updates,
723 client_provider_lock: Arc::new(Mutex::new(())),
724 telemetry_sender: TelemetrySender::new(telemetry_sender),
725 telemetry_receiver,
726 }
727 }
728
729 #[fuchsia::test]
730 fn connect_request_unknown_network() {
731 let ssid = client_types::Ssid::try_from("foobar-unknown").unwrap();
732 let mut exec = fasync::TestExecutor::new();
733 let test_values = test_setup();
734 let serve_fut = serve_provider_requests(
735 test_values.iface_manager,
736 test_values.update_sender,
737 Arc::clone(&test_values.saved_networks),
738 test_values.scan_requester,
739 test_values.client_provider_lock,
740 test_values.requests,
741 test_values.telemetry_sender,
742 );
743 let mut serve_fut = pin!(serve_fut);
744
745 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
747
748 let (controller, _) = request_controller(&test_values.provider);
750 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
751
752 let connect_fut = controller.connect(&fidl_policy::NetworkIdentifier {
754 ssid: ssid.to_vec(),
755 type_: fidl_policy::SecurityType::None,
756 });
757 let mut connect_fut = pin!(connect_fut);
758
759 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
761
762 assert_matches!(
763 exec.run_until_stalled(&mut connect_fut),
764 Poll::Ready(Ok(fidl_policy::RequestStatus::RejectedNotSupported))
765 );
766
767 let id = NetworkIdentifier::new(ssid, SecurityType::None);
770 let lookup_fut = test_values.saved_networks.lookup(&id);
771 assert!(exec.run_singlethreaded(lookup_fut).is_empty());
772 }
773
774 #[fuchsia::test]
775 fn connect_request_open_network() {
776 let mut exec = fasync::TestExecutor::new();
777
778 let test_values = test_setup();
779 let serve_fut = serve_provider_requests(
780 test_values.iface_manager,
781 test_values.update_sender,
782 Arc::clone(&test_values.saved_networks),
783 test_values.scan_requester,
784 test_values.client_provider_lock,
785 test_values.requests,
786 test_values.telemetry_sender,
787 );
788 let mut serve_fut = pin!(serve_fut);
789
790 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
792
793 let (controller, _update_stream) = request_controller(&test_values.provider);
795 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
796
797 let connect_fut = controller.connect(&test_values.net_id_open);
799 let mut connect_fut = pin!(connect_fut);
800
801 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
803
804 assert_matches!(
806 exec.run_until_stalled(&mut connect_fut),
807 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
808 );
809 }
810
811 #[fuchsia::test]
812 fn connect_request_protected_network() {
813 let mut exec = fasync::TestExecutor::new();
814
815 let test_values = test_setup();
816 let serve_fut = serve_provider_requests(
817 test_values.iface_manager,
818 test_values.update_sender,
819 Arc::clone(&test_values.saved_networks),
820 test_values.scan_requester,
821 test_values.client_provider_lock,
822 test_values.requests,
823 test_values.telemetry_sender,
824 );
825 let mut serve_fut = pin!(serve_fut);
826
827 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
829
830 let (controller, _update_stream) = request_controller(&test_values.provider);
832 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
833
834 let connect_fut = controller.connect(&test_values.net_id_wpa2_w_password);
836 let mut connect_fut = pin!(connect_fut);
837
838 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
840
841 assert_matches!(
843 exec.run_until_stalled(&mut connect_fut),
844 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
845 );
846 }
847
848 #[fuchsia::test]
849 fn connect_request_protected_psk_network() {
850 let mut exec = fasync::TestExecutor::new();
851
852 let test_values = test_setup();
853 let serve_fut = serve_provider_requests(
854 test_values.iface_manager,
855 test_values.update_sender,
856 Arc::clone(&test_values.saved_networks),
857 test_values.scan_requester,
858 test_values.client_provider_lock,
859 test_values.requests,
860 test_values.telemetry_sender,
861 );
862 let mut serve_fut = pin!(serve_fut);
863
864 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
866
867 let (controller, _update_stream) = request_controller(&test_values.provider);
869 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
870
871 let connect_fut = controller.connect(&test_values.net_id_wpa2_w_psk);
873 let mut connect_fut = pin!(connect_fut);
874
875 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
877
878 assert_matches!(
880 exec.run_until_stalled(&mut connect_fut),
881 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
882 );
883 }
884
885 #[fuchsia::test]
886 fn start_and_stop_client_connections() {
887 let mut exec = fasync::TestExecutor::new();
888 let mut test_values = test_setup();
889 let serve_fut = serve_provider_requests(
890 test_values.iface_manager,
891 test_values.update_sender,
892 test_values.saved_networks,
893 test_values.scan_requester,
894 test_values.client_provider_lock,
895 test_values.requests,
896 test_values.telemetry_sender,
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 start_fut = controller.start_client_connections();
909 let mut start_fut = pin!(start_fut);
910
911 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
913 assert_matches!(
914 exec.run_until_stalled(&mut start_fut),
915 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
916 );
917
918 assert_matches!(test_values.telemetry_receiver.try_next(), Ok(Some(event)) => {
920 assert_matches!(event, TelemetryEvent::StartClientConnectionsRequest);
921 });
922
923 let connect_fut = controller.connect(&test_values.net_id_wpa2_w_password);
925 let mut connect_fut = pin!(connect_fut);
926
927 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
929
930 assert_matches!(
932 exec.run_until_stalled(&mut connect_fut),
933 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
934 );
935
936 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
938
939 let stop_fut = controller.stop_client_connections();
941 let mut stop_fut = pin!(stop_fut);
942
943 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
945
946 assert_matches!(test_values.telemetry_receiver.try_next(), Ok(Some(event)) => {
948 assert_matches!(event, TelemetryEvent::StopClientConnectionsRequest);
949 });
950
951 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
953 assert_matches!(
954 exec.run_until_stalled(&mut stop_fut),
955 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
956 );
957 }
958
959 #[fuchsia::test]
963 fn scan_end_to_end() {
964 let mut exec = fasync::TestExecutor::new();
965 let test_values = test_setup();
966 let serve_fut = serve_provider_requests(
967 test_values.iface_manager,
968 test_values.update_sender,
969 test_values.saved_networks,
970 test_values.scan_requester.clone(),
971 test_values.client_provider_lock,
972 test_values.requests,
973 test_values.telemetry_sender,
974 );
975 let mut serve_fut = pin!(serve_fut);
976
977 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
979
980 let (controller, _update_stream) = request_controller(&test_values.provider);
982 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
983
984 let (_iter, server) = fidl::endpoints::create_proxy();
986 controller.scan_for_networks(server).expect("Failed to call scan for networks");
987
988 exec.run_singlethreaded(test_values.scan_requester.add_scan_result(Ok(vec![])));
991 exec.run_singlethreaded(test_values.scan_requester.add_scan_result(Ok(vec![])));
993
994 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
996
997 let expected_active_ssids = [
1000 test_values.net_id_wpa2_w_password,
1001 test_values.net_id_wpa2_w_psk,
1002 test_values.net_id_open,
1003 ]
1004 .iter()
1005 .map(|id| types::Ssid::from_bytes_unchecked(id.ssid.clone()))
1006 .collect();
1007 exec.run_singlethreaded(test_values.scan_requester.verify_scan_request((
1008 scan::ScanReason::ClientRequest,
1009 vec![],
1010 vec![],
1011 )));
1012 exec.run_singlethreaded(test_values.scan_requester.verify_scan_request((
1013 scan::ScanReason::ClientRequest,
1014 expected_active_ssids,
1015 vec![],
1016 )));
1017 }
1018
1019 #[fuchsia::test]
1020 fn save_network() {
1021 let mut exec = fasync::TestExecutor::new();
1022 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1023
1024 let mut test_values = test_setup();
1025 let serve_fut = serve_provider_requests(
1026 test_values.iface_manager,
1027 test_values.update_sender,
1028 saved_networks.clone(),
1029 test_values.scan_requester,
1030 test_values.client_provider_lock,
1031 test_values.requests,
1032 test_values.telemetry_sender,
1033 );
1034 let mut serve_fut = pin!(serve_fut);
1035
1036 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1038
1039 let (controller, _update_stream) = request_controller(&test_values.provider);
1041 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1042 assert_matches!(
1043 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1044 Poll::Ready(_)
1045 );
1046
1047 let network_id = fidl_policy::NetworkIdentifier {
1049 ssid: b"foo".to_vec(),
1050 type_: fidl_policy::SecurityType::None,
1051 };
1052 let network_config = fidl_policy::NetworkConfig {
1053 id: Some(network_id.clone()),
1054 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
1055 ..Default::default()
1056 };
1057 let mut save_fut = controller.save_network(&network_config);
1058
1059 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Pending);
1061 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1062
1063 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(Ok(Ok(()))));
1065
1066 let target_id = NetworkIdentifier::from(network_id);
1068 let target_config = NetworkConfig::new(target_id.clone(), Credential::None, false)
1069 .expect("Failed to create network config");
1070 assert_eq!(exec.run_singlethreaded(saved_networks.lookup(&target_id)), vec![target_config]);
1071 }
1072
1073 #[fuchsia::test]
1074 fn save_network_with_disconnected_iface() {
1075 let mut exec = fasync::TestExecutor::new();
1076 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1077
1078 let mut test_values = test_setup();
1079 let serve_fut = serve_provider_requests(
1080 test_values.iface_manager.clone(),
1081 test_values.update_sender,
1082 saved_networks.clone(),
1083 test_values.scan_requester,
1084 test_values.client_provider_lock,
1085 test_values.requests,
1086 test_values.telemetry_sender,
1087 );
1088 let mut serve_fut = pin!(serve_fut);
1089
1090 {
1092 let iface_manager = test_values.iface_manager.clone();
1093 let iface_manager_fut = iface_manager.lock();
1094 let mut iface_manager_fut = pin!(iface_manager_fut);
1095 let mut iface_manager = match exec.run_until_stalled(&mut iface_manager_fut) {
1096 Poll::Ready(iface_manager) => iface_manager,
1097 Poll::Pending => panic!("expected to acquire iface_manager lock"),
1098 };
1099 let record_idle_fut = iface_manager.record_idle_client(0);
1100 let mut record_idle_fut = pin!(record_idle_fut);
1101 assert_matches!(exec.run_until_stalled(&mut record_idle_fut), Poll::Ready(Ok(())));
1102 }
1103
1104 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1106
1107 let (controller, _update_stream) = request_controller(&test_values.provider);
1109 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1110 assert_matches!(
1111 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1112 Poll::Ready(_)
1113 );
1114
1115 let network_id = fidl_policy::NetworkIdentifier {
1117 ssid: b"foo".to_vec(),
1118 type_: fidl_policy::SecurityType::None,
1119 };
1120 let network_config = fidl_policy::NetworkConfig {
1121 id: Some(network_id.clone()),
1122 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
1123 ..Default::default()
1124 };
1125 let mut save_fut = controller.save_network(&network_config);
1126
1127 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Pending);
1128 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1129
1130 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(result) => {
1132 let save_result = result.expect("Failed to get save network response");
1133 assert_eq!(save_result, Ok(()));
1134 });
1135
1136 let target_id = NetworkIdentifier::from(network_id);
1138 let target_config = NetworkConfig::new(target_id.clone(), Credential::None, false)
1139 .expect("Failed to create network config");
1140 assert_eq!(exec.run_singlethreaded(saved_networks.lookup(&target_id)), vec![target_config]);
1141 }
1142
1143 #[fuchsia::test]
1144 fn save_network_overwrite_disconnects() {
1145 let mut exec = fasync::TestExecutor::new();
1146 let mut test_values = test_setup();
1147 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1148
1149 let serve_fut = serve_provider_requests(
1150 test_values.iface_manager,
1151 test_values.update_sender,
1152 saved_networks.clone(),
1153 test_values.scan_requester,
1154 test_values.client_provider_lock,
1155 test_values.requests,
1156 test_values.telemetry_sender,
1157 );
1158 let mut serve_fut = pin!(serve_fut);
1159
1160 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1162
1163 let (controller, _update_stream) = request_controller(&test_values.provider);
1165 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1166 assert_matches!(
1167 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1168 Poll::Ready(_)
1169 );
1170
1171 let network_id = NetworkIdentifier::try_from("foo", SecurityType::Wpa2).unwrap();
1173 let credential = Credential::Password(b"password".to_vec());
1174 let save_fut = saved_networks.store(network_id.clone(), credential.clone());
1175 let mut save_fut = pin!(save_fut);
1176 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(Ok(None)));
1177
1178 let network_config = fidl_policy::NetworkConfig {
1180 id: Some(fidl_policy::NetworkIdentifier::from(network_id.clone())),
1181 credential: Some(fidl_policy::Credential::Password(b"other-password".to_vec())),
1182 ..Default::default()
1183 };
1184 let mut save_fut = controller.save_network(&network_config);
1185
1186 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1188 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1189
1190 assert_matches!(exec.run_until_stalled(&mut test_values.iface_mgr_req_recvr.next()), Poll::Ready(Some(IfaceManagerRequest::Disconnect(net_id, reason))) => {
1192 assert_eq!(net_id, network_id.clone());
1193 assert_eq!(reason, client_types::DisconnectReason::NetworkConfigUpdated);
1194 });
1195 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1196 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(Ok(Ok(()))));
1197 }
1198
1199 #[fuchsia::test]
1200 fn save_bad_network_should_fail() {
1201 let mut exec = fasync::TestExecutor::new();
1202 let mut saved_networks = FakeSavedNetworksManager::new();
1203 saved_networks.fail_all_stores = true;
1204 let saved_networks = Arc::new(saved_networks);
1205
1206 let mut test_values = test_setup();
1207 let serve_fut = serve_provider_requests(
1208 test_values.iface_manager,
1209 test_values.update_sender,
1210 saved_networks.clone(),
1211 test_values.scan_requester,
1212 test_values.client_provider_lock,
1213 test_values.requests,
1214 test_values.telemetry_sender,
1215 );
1216 let mut serve_fut = pin!(serve_fut);
1217
1218 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1220
1221 let (controller, _update_stream) = request_controller(&test_values.provider);
1223 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1224 assert_matches!(
1225 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1226 Poll::Ready(_)
1227 );
1228
1229 let bad_network_id = fidl_policy::NetworkIdentifier {
1233 ssid: b"foo".to_vec(),
1234 type_: fidl_policy::SecurityType::Wpa2,
1235 };
1236 let network_config = fidl_policy::NetworkConfig {
1237 id: Some(bad_network_id.clone()),
1238 credential: Some(fidl_policy::Credential::Password(b"bar".to_vec())),
1239 ..Default::default()
1240 };
1241 let mut save_fut = controller.save_network(&network_config);
1243
1244 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1246
1247 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(result) => {
1249 let error = result.expect("Failed to get save network response");
1250 assert_eq!(error, Err(fidl_policy::NetworkConfigChangeError::NetworkConfigWriteError));
1251 });
1252
1253 let target_id = NetworkIdentifier::from(bad_network_id);
1255 assert_eq!(exec.run_singlethreaded(saved_networks.lookup(&target_id)), vec![]);
1256 }
1257
1258 #[fuchsia::test]
1259 fn test_remove_a_network() {
1260 let mut exec = fasync::TestExecutor::new();
1261 let mut test_values = test_setup();
1262
1263 let serve_fut = serve_provider_requests(
1264 test_values.iface_manager,
1265 test_values.update_sender,
1266 test_values.saved_networks.clone(),
1267 test_values.scan_requester,
1268 test_values.client_provider_lock,
1269 test_values.requests,
1270 test_values.telemetry_sender,
1271 );
1272 let mut serve_fut = pin!(serve_fut);
1273
1274 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1276
1277 let (controller, _update_stream) = request_controller(&test_values.provider);
1279 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1280 assert_matches!(
1281 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1282 Poll::Ready(_)
1283 );
1284
1285 let network_config = fidl_policy::NetworkConfig {
1287 id: Some(test_values.net_id_open.clone()),
1288 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
1289 ..Default::default()
1290 };
1291 let mut remove_fut = controller.remove_network(&network_config);
1292
1293 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1295 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1296
1297 assert_matches!(exec.run_until_stalled(&mut test_values.iface_mgr_req_recvr.next()), Poll::Ready(Some(IfaceManagerRequest::Disconnect(net_id, reason))) => {
1301 assert_eq!(net_id, test_values.net_id_open.clone().into());
1302 assert_eq!(reason, client_types::DisconnectReason::NetworkUnsaved);
1303 });
1304 assert_matches!(exec.run_until_stalled(&mut remove_fut), Poll::Ready(Ok(Ok(()))));
1305 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1306 assert!(
1307 exec.run_singlethreaded(
1308 test_values.saved_networks.lookup(&test_values.net_id_open.clone().into())
1309 )
1310 .is_empty()
1311 );
1312
1313 let mut remove_fut = controller.remove_network(&network_config);
1315 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1317 assert_matches!(
1318 exec.run_until_stalled(&mut test_values.iface_mgr_req_recvr.next()),
1319 Poll::Pending
1320 );
1321 assert_matches!(exec.run_until_stalled(&mut remove_fut), Poll::Ready(Ok(Ok(()))));
1322 }
1323
1324 #[fuchsia::test]
1325 fn test_get_saved_network() {
1326 let expected_configs = vec![generate_random_fidl_network_config()];
1327 let expected_num_sends = 1;
1328 run_get_saved_networks_test(expected_configs, expected_num_sends);
1329 }
1330
1331 #[fuchsia::test]
1332 fn test_get_saved_networks_multiple_chunks() {
1333 let mut configs = vec![];
1336 for index in 0..MAX_CONFIGS_PER_RESPONSE + 1 {
1337 let ssid = format!("some_config{index}");
1339 let network_config = generate_random_fidl_network_config_with_ssid(&ssid);
1340 configs.push(network_config);
1341 }
1342
1343 let expected_num_sends = 2;
1344 run_get_saved_networks_test(configs, expected_num_sends);
1345 }
1346
1347 fn run_get_saved_networks_test(
1354 configs: Vec<fidl_policy::NetworkConfig>,
1355 expected_num_sends: usize,
1356 ) {
1357 let mut exec = fasync::TestExecutor::new();
1358 let saved_networks =
1359 Arc::new(FakeSavedNetworksManager::new_with_saved_networks(configs.clone()));
1360
1361 let test_values = test_setup();
1362 let serve_fut = serve_provider_requests(
1363 test_values.iface_manager,
1364 test_values.update_sender,
1365 saved_networks.clone(),
1366 test_values.scan_requester,
1367 test_values.client_provider_lock,
1368 test_values.requests,
1369 test_values.telemetry_sender,
1370 );
1371 let mut serve_fut = pin!(serve_fut);
1372
1373 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1375
1376 let (controller, _update_stream) = request_controller(&test_values.provider);
1378 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1379
1380 let (iter, server) =
1382 fidl::endpoints::create_proxy::<fidl_policy::NetworkConfigIteratorMarker>();
1383 controller.get_saved_networks(server).expect("Failed to call get saved networks");
1384
1385 let mut saved_networks_results = vec![];
1388 for i in 0..expected_num_sends {
1389 let get_saved_fut = iter.get_next();
1390 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1391 let results = exec
1392 .run_singlethreaded(get_saved_fut)
1393 .expect("Failed to get next chunk of saved networks results");
1394 if i < expected_num_sends - 1 {
1397 assert_eq!(results.len(), MAX_CONFIGS_PER_RESPONSE);
1398 } else {
1399 assert_eq!(results.len(), configs.len() % MAX_CONFIGS_PER_RESPONSE);
1400 }
1401 saved_networks_results.extend(results);
1402 }
1403 let get_saved_end_fut = iter.get_next();
1404 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1405 let results = exec
1406 .run_singlethreaded(get_saved_end_fut)
1407 .expect("Failed to get next chunk of saved networks results");
1408 assert!(results.is_empty());
1409
1410 for network_config in &configs {
1412 assert!(saved_networks_results.contains(network_config));
1413 }
1414 assert_eq!(configs.len(), saved_networks_results.len());
1415 }
1416
1417 #[fuchsia::test]
1418 fn register_update_listener() {
1419 let mut exec = fasync::TestExecutor::new();
1420 let mut test_values = test_setup();
1421 let serve_fut = serve_provider_requests(
1422 test_values.iface_manager,
1423 test_values.update_sender,
1424 test_values.saved_networks,
1425 test_values.scan_requester,
1426 test_values.client_provider_lock,
1427 test_values.requests,
1428 test_values.telemetry_sender,
1429 );
1430 let mut serve_fut = pin!(serve_fut);
1431
1432 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1434
1435 let (_controller, _update_stream) = request_controller(&test_values.provider);
1437 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1438 assert_matches!(
1439 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1440 Poll::Ready(Some(listener::Message::NewListener(_)))
1441 );
1442 }
1443
1444 #[fuchsia::test]
1445 fn get_listener() {
1446 let mut exec = fasync::TestExecutor::new();
1447 let (listener, requests) = create_proxy::<fidl_policy::ClientListenerMarker>();
1448 let requests = requests.into_stream();
1449
1450 let (update_sender, mut listener_updates) = mpsc::unbounded();
1451 let serve_fut = serve_listener_requests(update_sender, requests);
1452 let mut serve_fut = pin!(serve_fut);
1453
1454 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1456
1457 let (update_sink, _update_stream) =
1459 create_request_stream::<fidl_policy::ClientStateUpdatesMarker>();
1460 listener.get_listener(update_sink).expect("error getting listener");
1461
1462 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1463 assert_matches!(
1464 exec.run_until_stalled(&mut listener_updates.next()),
1465 Poll::Ready(Some(listener::Message::NewListener(_)))
1466 );
1467 }
1468
1469 #[fuchsia::test]
1470 fn multiple_controllers_write_attempt() {
1471 let mut exec = fasync::TestExecutor::new();
1472 let test_values = test_setup();
1473 let serve_fut = serve_provider_requests(
1474 test_values.iface_manager,
1475 test_values.update_sender,
1476 test_values.saved_networks,
1477 test_values.scan_requester,
1478 test_values.client_provider_lock,
1479 test_values.requests,
1480 test_values.telemetry_sender,
1481 );
1482 let mut serve_fut = pin!(serve_fut);
1483
1484 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1486
1487 let (controller1, _) = request_controller(&test_values.provider);
1489 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1490
1491 let (controller2, _) = request_controller(&test_values.provider);
1493 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1494
1495 let connect_fut = controller1.connect(&test_values.net_id_open);
1497 let mut connect_fut = pin!(connect_fut);
1498
1499 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1501
1502 assert_matches!(
1503 exec.run_until_stalled(&mut connect_fut),
1504 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
1505 );
1506
1507 let connect_fut = controller2.connect(&test_values.net_id_open);
1509 let mut connect_fut = pin!(connect_fut);
1510
1511 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1513 assert_matches!(
1514 exec.run_until_stalled(&mut connect_fut),
1515 Poll::Ready(Err(fidl::Error::ClientChannelClosed {
1516 status: zx::Status::ALREADY_BOUND,
1517 ..
1518 }))
1519 );
1520
1521 drop(controller1);
1523 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1524
1525 let (controller3, _) = request_controller(&test_values.provider);
1527 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1528
1529 let connect_fut = controller3.connect(&test_values.net_id_open);
1531 let mut connect_fut = pin!(connect_fut);
1532
1533 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1535
1536 assert_matches!(
1537 exec.run_until_stalled(&mut connect_fut),
1538 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
1539 );
1540 }
1541
1542 #[fuchsia::test]
1543 fn multiple_controllers_epitaph() {
1544 let mut exec = fasync::TestExecutor::new();
1545 let test_values = test_setup();
1546 let serve_fut = serve_provider_requests(
1547 test_values.iface_manager,
1548 test_values.update_sender,
1549 test_values.saved_networks.clone(),
1550 test_values.scan_requester,
1551 test_values.client_provider_lock,
1552 test_values.requests,
1553 test_values.telemetry_sender,
1554 );
1555 let mut serve_fut = pin!(serve_fut);
1556
1557 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1559
1560 let (_controller1, _) = request_controller(&test_values.provider);
1562 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1563
1564 let (controller2, _) = request_controller(&test_values.provider);
1566 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1567
1568 let mut controller2_event_stream = controller2.take_event_stream();
1570 let controller2_event_fut = controller2_event_stream.next();
1571 let mut controller2_event_fut = pin!(controller2_event_fut);
1572 assert_matches!(
1573 exec.run_until_stalled(&mut controller2_event_fut),
1574 Poll::Ready(Some(Err(fidl::Error::ClientChannelClosed {
1575 status: zx::Status::ALREADY_BOUND,
1576 ..
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 let mut cfgs = saved_networks
1698 .lookup(&id)
1699 .await
1700 .into_iter()
1701 .filter(|cfg| cfg.credential == cred)
1702 .collect::<Vec<_>>();
1703 assert!(cfgs.len() <= 1);
1705 cfgs.pop()
1706 }
1707
1708 #[fuchsia::test]
1709 async fn get_correct_config() {
1710 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1711 let network_id = NetworkIdentifier::try_from("foo", SecurityType::Wpa2).unwrap();
1712 let cfg = NetworkConfig::new(
1713 network_id.clone(),
1714 Credential::Password(b"password".to_vec()),
1715 false,
1716 )
1717 .expect("Failed to create network config");
1718
1719 assert!(
1720 saved_networks
1721 .store(network_id.clone(), Credential::Password(b"password".to_vec()))
1722 .await
1723 .expect("Failed to store network config")
1724 .is_none()
1725 );
1726
1727 assert_eq!(
1728 Some(cfg),
1729 get_config(
1730 saved_networks.clone(),
1731 network_id,
1732 Credential::Password(b"password".to_vec())
1733 )
1734 .await
1735 );
1736 assert_eq!(
1737 None,
1738 get_config(
1739 saved_networks.clone(),
1740 NetworkIdentifier::try_from("foo", SecurityType::Wpa2).unwrap(),
1741 Credential::Password(b"not-saved".to_vec())
1742 )
1743 .await
1744 );
1745 }
1746
1747 #[fuchsia::test]
1748 fn multiple_api_clients() {
1749 let mut exec = fasync::TestExecutor::new();
1750 let test_values = test_setup();
1751 let serve_fut = serve_provider_requests(
1752 test_values.iface_manager.clone(),
1753 test_values.update_sender.clone(),
1754 test_values.saved_networks.clone(),
1755 test_values.scan_requester.clone(),
1756 test_values.client_provider_lock.clone(),
1757 test_values.requests,
1758 test_values.telemetry_sender.clone(),
1759 );
1760 let mut serve_fut = pin!(serve_fut);
1761
1762 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1764
1765 let (controller1, _) = request_controller(&test_values.provider);
1767 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1768
1769 let (provider, requests) = create_proxy::<fidl_policy::ClientProviderMarker>();
1772 let requests = requests.into_stream();
1773
1774 let second_serve_fut = serve_provider_requests(
1775 test_values.iface_manager.clone(),
1776 test_values.update_sender.clone(),
1777 test_values.saved_networks.clone(),
1778 test_values.scan_requester,
1779 test_values.client_provider_lock.clone(),
1780 requests,
1781 test_values.telemetry_sender,
1782 );
1783 let mut second_serve_fut = pin!(second_serve_fut);
1784
1785 let (controller2, _) = request_controller(&provider);
1787 assert_matches!(exec.run_until_stalled(&mut second_serve_fut), Poll::Pending);
1788
1789 let mut controller2_event_stream = controller2.take_event_stream();
1791 let controller2_event_fut = controller2_event_stream.next();
1792 let mut controller2_event_fut = pin!(controller2_event_fut);
1793 assert_matches!(
1794 exec.run_until_stalled(&mut controller2_event_fut),
1795 Poll::Ready(Some(Err(fidl::Error::ClientChannelClosed {
1796 status: zx::Status::ALREADY_BOUND,
1797 ..
1798 })))
1799 );
1800 assert!(controller2.is_closed());
1801
1802 drop(controller1);
1805 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1806
1807 let (controller2, _) = request_controller(&provider);
1808 assert_matches!(exec.run_until_stalled(&mut second_serve_fut), Poll::Pending);
1809
1810 let connect_fut = controller2.connect(&test_values.net_id_open);
1812 let mut connect_fut = pin!(connect_fut);
1813
1814 assert_matches!(exec.run_until_stalled(&mut second_serve_fut), Poll::Pending);
1816
1817 assert_matches!(
1818 exec.run_until_stalled(&mut connect_fut),
1819 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
1820 );
1821 }
1822
1823 #[test_case(true)]
1824 #[test_case(false)]
1825 #[fuchsia::test(add_test_attr = false)]
1826 fn test_start_client_connections(start_client_connections_succeeds: bool) {
1827 let mut exec = fasync::TestExecutor::new();
1828 let (proxy, _server) = create_proxy::<fidl_fuchsia_wlan_sme::ClientSmeMarker>();
1829 let (req_sender, _req_recvr) = mpsc::channel(1);
1830 let mut iface_manager = FakeIfaceManager::new(proxy.clone(), req_sender);
1831
1832 iface_manager.start_client_connections_succeeds = start_client_connections_succeeds;
1834
1835 let iface_manager: Arc<Mutex<dyn IfaceManagerApi>> = Arc::new(Mutex::new(iface_manager));
1836
1837 let fut = handle_client_request_start_client_connections(iface_manager);
1840 let mut fut = pin!(fut);
1841 assert_matches!(
1842 exec.run_until_stalled(&mut fut),
1843 Poll::Ready(fidl_policy::RequestStatus::Acknowledged)
1844 );
1845 }
1846
1847 #[test_case(true)]
1848 #[test_case(false)]
1849 #[fuchsia::test(add_test_attr = false)]
1850 fn test_stop_client_connections(stop_client_connections_succeeds: bool) {
1851 let mut exec = fasync::TestExecutor::new();
1852 let (proxy, _server) = create_proxy::<fidl_fuchsia_wlan_sme::ClientSmeMarker>();
1853 let (req_sender, _req_recvr) = mpsc::channel(1);
1854 let mut iface_manager = FakeIfaceManager::new(proxy.clone(), req_sender);
1855
1856 iface_manager.stop_client_connections_succeeds = stop_client_connections_succeeds;
1858
1859 let iface_manager: Arc<Mutex<dyn IfaceManagerApi>> = Arc::new(Mutex::new(iface_manager));
1860
1861 let fut = handle_client_request_stop_client_connections(iface_manager);
1864 let mut fut = pin!(fut);
1865 assert_matches!(
1866 exec.run_until_stalled(&mut fut),
1867 Poll::Ready(fidl_policy::RequestStatus::Acknowledged)
1868 );
1869 }
1870}