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);
304 if let Err(e) = scan::send_scan_results_over_fidl(output_iterator, &fidl_results).await
305 {
306 warn!("Failed to send scan results to requester: {:?}", e);
307 }
308 }
309 Err(e) => {
310 if let Err(e) = scan::send_scan_error_over_fidl(output_iterator, e).await {
311 warn!("Failed to send scan error to requester: {:?}", e);
312 }
313 }
314 }
315}
316
317async fn handle_client_request_save_network(
321 saved_networks: SavedNetworksPtr,
322 network_config: fidl_policy::NetworkConfig,
323 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
324) -> Result<(), NetworkConfigError> {
325 let net_id: client_types::NetworkIdentifier =
328 network_config.id.ok_or(NetworkConfigError::ConfigMissingId)?.into();
329 let credential = Credential::try_from(
330 network_config.credential.ok_or(NetworkConfigError::ConfigMissingCredential)?,
331 )?;
332 let evicted_config = saved_networks.store(net_id.clone(), credential.clone()).await?;
333
334 let mut iface_manager = iface_manager.lock().await;
336 if let Some(config) = evicted_config {
337 let net_id = client_types::NetworkIdentifier {
338 ssid: config.ssid,
339 security_type: config.security_type,
340 };
341 match iface_manager
342 .disconnect(net_id, client_types::DisconnectReason::NetworkConfigUpdated)
343 .await
344 {
345 Ok(()) => {}
346 Err(e) => error!("failed to disconnect from network: {}", e),
347 }
348 }
349
350 let connect_req = ConnectAttemptRequest::new(
352 net_id,
353 credential,
354 client_types::ConnectReason::NewSavedNetworkAutoconnect,
355 );
356 match iface_manager.has_idle_client().await {
357 Ok(true) => {
358 info!("Idle interface available, will attempt connection to new saved network");
359 let _ = iface_manager.connect(connect_req).await;
360 }
361 Ok(false) => {}
362 Err(e) => {
363 error!("Unable to query idle client state while saving network: {:?}", e);
364 }
365 }
366
367 Ok(())
368}
369
370async fn handle_client_request_remove_network(
373 saved_networks: SavedNetworksPtr,
374 network_config: fidl_policy::NetworkConfig,
375 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
376) -> Result<(), NetworkConfigError> {
377 let net_id =
380 NetworkIdentifier::from(network_config.id.ok_or(NetworkConfigError::ConfigMissingId)?);
381 let credential = Credential::try_from(
382 network_config.credential.ok_or(NetworkConfigError::ConfigMissingCredential)?,
383 )?;
384 if saved_networks.remove(net_id.clone(), credential.clone()).await? {
385 match iface_manager
386 .lock()
387 .await
388 .disconnect(net_id, client_types::DisconnectReason::NetworkUnsaved)
389 .await
390 {
391 Ok(()) => {}
392 Err(e) => error!("failed to disconnect from network: {}", e),
393 }
394 }
395 Ok(())
396}
397
398async fn handle_client_request_get_networks(
399 saved_networks: SavedNetworksPtr,
400 iterator: fidl::endpoints::ServerEnd<fidl_policy::NetworkConfigIteratorMarker>,
401) -> Result<(), fidl::Error> {
402 let network_configs = saved_networks.get_networks().await;
404 let chunks = network_configs.chunks(MAX_CONFIGS_PER_RESPONSE);
405 let fidl_chunks = chunks.into_iter().map(|chunk| {
406 chunk
407 .iter()
408 .map(fidl_policy::NetworkConfig::from)
409 .collect::<Vec<fidl_policy::NetworkConfig>>()
410 });
411 let mut stream = iterator.into_stream();
412 for chunk in fidl_chunks {
413 send_next_chunk(&mut stream, chunk).await?;
414 }
415 send_next_chunk(&mut stream, vec![]).await
416}
417
418async fn send_next_chunk(
420 stream: &mut fidl_policy::NetworkConfigIteratorRequestStream,
421 chunk: Vec<fidl_policy::NetworkConfig>,
422) -> Result<(), fidl::Error> {
423 if let Some(req) = stream.try_next().await? {
424 let fidl_policy::NetworkConfigIteratorRequest::GetNext { responder } = req;
425 responder.send(&chunk)
426 } else {
427 info!("Info: peer closed channel for network config results unexpectedly");
431 Ok(())
432 }
433}
434
435async fn handle_listener_request(
437 update_sender: listener::ClientListenerMessageSender,
438 req: fidl_policy::ClientListenerRequest,
439) -> Result<(), fidl::Error> {
440 match req {
441 fidl_policy::ClientListenerRequest::GetListener { updates, .. } => {
442 register_listener(update_sender, updates.into_proxy());
443 Ok(())
444 }
445 }
446}
447
448fn register_listener(
451 update_sender: listener::ClientListenerMessageSender,
452 listener: fidl_policy::ClientStateUpdatesProxy,
453) {
454 let _ignored = update_sender.unbounded_send(listener::Message::NewListener(listener));
455}
456
457fn reject_provider_request(req: fidl_policy::ClientProviderRequest) -> Result<(), fidl::Error> {
460 match req {
461 fidl_policy::ClientProviderRequest::GetController { requests, updates, .. } => {
462 info!("Rejecting new client controller request because a controller is in use");
463 requests.into_channel().close_with_epitaph(zx::Status::ALREADY_BOUND)?;
464 updates.into_channel().close_with_epitaph(zx::Status::ALREADY_BOUND)?;
465 Ok(())
466 }
467 }
468}
469
470async fn handle_client_request_start_client_connections(
472 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
473) -> fidl_policy::RequestStatus {
474 let mut iface_manager = iface_manager.lock().await;
475 if let Err(e) = iface_manager.start_client_connections().await {
476 warn!("encountered an error while starting client connections: {:?}", e);
477 }
478 fidl_policy::RequestStatus::Acknowledged
479}
480
481async fn handle_client_request_stop_client_connections(
483 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
484) -> fidl_policy::RequestStatus {
485 let mut iface_manager = iface_manager.lock().await;
486 if let Err(e) = iface_manager
487 .stop_client_connections(client_types::DisconnectReason::FidlStopClientConnectionsRequest)
488 .await
489 {
490 warn!("encountered an error while stopping client connections: {:?}", e);
491 }
492 fidl_policy::RequestStatus::Acknowledged
493}
494
495#[cfg(test)]
496mod tests {
497 use super::*;
498 use crate::access_point::state_machine as ap_fsm;
499 use crate::config_management::{NetworkConfig, SecurityType, WPA_PSK_BYTE_LEN};
500 use crate::mode_management::iface_manager_api::SmeForScan;
501 use crate::util::testing::fakes::{FakeSavedNetworksManager, FakeScanRequester};
502 use crate::util::testing::{
503 generate_random_fidl_network_config, generate_random_fidl_network_config_with_ssid,
504 };
505 use anyhow::{Error, format_err};
506 use assert_matches::assert_matches;
507 use async_trait::async_trait;
508 use fidl::endpoints::{Proxy, create_proxy, create_request_stream};
509 use fuchsia_async as fasync;
510 use futures::channel::{mpsc, oneshot};
511 use futures::task::Poll;
512 use std::pin::pin;
513 use test_case::test_case;
514
515 #[derive(Debug)]
518 enum IfaceManagerRequest {
519 Disconnect(client_types::NetworkIdentifier, client_types::DisconnectReason),
520 }
521
522 struct FakeIfaceManager {
523 pub sme_proxy: fidl_fuchsia_wlan_sme::ClientSmeProxy,
524 pub disconnected_ifaces: Vec<u16>,
525 command_sender: mpsc::Sender<IfaceManagerRequest>,
526 start_client_connections_succeeds: bool,
527 stop_client_connections_succeeds: bool,
528 }
529
530 impl FakeIfaceManager {
531 pub fn new(
532 proxy: fidl_fuchsia_wlan_sme::ClientSmeProxy,
533 command_sender: mpsc::Sender<IfaceManagerRequest>,
534 ) -> Self {
535 FakeIfaceManager {
536 sme_proxy: proxy,
537 disconnected_ifaces: Vec::new(),
538 command_sender,
539 start_client_connections_succeeds: true,
540 stop_client_connections_succeeds: true,
541 }
542 }
543 }
544
545 #[async_trait(?Send)]
546 impl IfaceManagerApi for FakeIfaceManager {
547 async fn disconnect(
548 &mut self,
549 network_id: client_types::NetworkIdentifier,
550 reason: client_types::DisconnectReason,
551 ) -> Result<(), Error> {
552 self.command_sender
553 .try_send(IfaceManagerRequest::Disconnect(network_id, reason))
554 .map_err(|e| {
555 error!(
556 "Failed to send disconnect: commands_sender's receiver may have
557 been dropped. FakeIfaceManager should be created manually with a sender
558 assigned: {:?}",
559 e
560 );
561 format_err!("failed to send disconnect: {:?}", e)
562 })
563 }
564
565 async fn connect(&mut self, _connect_req: ConnectAttemptRequest) -> Result<(), Error> {
566 let _ = self.disconnected_ifaces.pop();
567 Ok(())
568 }
569
570 async fn record_idle_client(&mut self, iface_id: u16) -> Result<(), Error> {
571 self.disconnected_ifaces.push(iface_id);
572 Ok(())
573 }
574
575 async fn has_idle_client(&mut self) -> Result<bool, Error> {
576 Ok(!self.disconnected_ifaces.is_empty())
577 }
578
579 async fn handle_added_iface(&mut self, _iface_id: u16) -> Result<(), Error> {
580 unimplemented!()
581 }
582
583 async fn handle_removed_iface(&mut self, _iface_id: u16) -> Result<(), Error> {
584 unimplemented!()
585 }
586
587 async fn get_sme_proxy_for_scan(&mut self) -> Result<SmeForScan, Error> {
588 let (defect_sender, _) = mpsc::channel(100);
589 Ok(SmeForScan::new(self.sme_proxy.clone(), 0, defect_sender))
590 }
591
592 async fn stop_client_connections(
593 &mut self,
594 _reason: client_types::DisconnectReason,
595 ) -> Result<(), Error> {
596 if self.stop_client_connections_succeeds {
597 Ok(())
598 } else {
599 Err(format_err!("stop client connections failed"))
600 }
601 }
602
603 async fn start_client_connections(&mut self) -> Result<(), Error> {
604 if self.start_client_connections_succeeds {
605 Ok(())
606 } else {
607 Err(format_err!("start client connections failed"))
608 }
609 }
610
611 async fn start_ap(
612 &mut self,
613 _config: ap_fsm::ApConfig,
614 ) -> Result<oneshot::Receiver<()>, Error> {
615 unimplemented!()
616 }
617
618 async fn stop_ap(&mut self, _ssid: types::Ssid, _password: Vec<u8>) -> Result<(), Error> {
619 unimplemented!()
620 }
621
622 async fn stop_all_aps(&mut self) -> Result<(), Error> {
623 unimplemented!()
624 }
625
626 async fn set_country(
627 &mut self,
628 _country_code: Option<types::CountryCode>,
629 ) -> Result<(), Error> {
630 unimplemented!()
631 }
632 }
633
634 fn request_controller(
636 provider: &fidl_policy::ClientProviderProxy,
637 ) -> (fidl_policy::ClientControllerProxy, fidl_policy::ClientStateUpdatesRequestStream) {
638 let (controller, requests) = create_proxy::<fidl_policy::ClientControllerMarker>();
639 let (update_sink, update_stream) =
640 create_request_stream::<fidl_policy::ClientStateUpdatesMarker>();
641 provider.get_controller(requests, update_sink).expect("error getting controller");
642 (controller, update_stream)
643 }
644
645 struct TestValues {
646 saved_networks: SavedNetworksPtr,
647 net_id_open: fidl_policy::NetworkIdentifier,
648 net_id_wpa2_w_password: fidl_policy::NetworkIdentifier,
649 net_id_wpa2_w_psk: fidl_policy::NetworkIdentifier,
650 provider: fidl_policy::ClientProviderProxy,
651 requests: fidl_policy::ClientProviderRequestStream,
652 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
653 iface_mgr_req_recvr: mpsc::Receiver<IfaceManagerRequest>,
654 scan_requester: Arc<FakeScanRequester>,
655 update_sender: mpsc::UnboundedSender<listener::ClientListenerMessage>,
656 listener_updates: mpsc::UnboundedReceiver<listener::ClientListenerMessage>,
657 client_provider_lock: Arc<Mutex<()>>,
658 telemetry_sender: TelemetrySender,
659 telemetry_receiver: mpsc::Receiver<TelemetryEvent>,
660 }
661
662 fn test_setup() -> TestValues {
666 let net_id_open = fidl_policy::NetworkIdentifier {
667 ssid: "foobar".to_string().into_bytes(),
668 type_: fidl_policy::SecurityType::None,
669 };
670 let net_id_wpa2_w_password = fidl_policy::NetworkIdentifier {
671 ssid: b"foobar-wpa2".to_vec(),
672 type_: fidl_policy::SecurityType::Wpa2,
673 };
674 let net_id_wpa2_w_psk = fidl_policy::NetworkIdentifier {
675 ssid: b"foobar-psk".to_vec(),
676 type_: fidl_policy::SecurityType::Wpa2,
677 };
678
679 let presaved_default_configs = vec![
680 fidl_policy::NetworkConfig {
681 id: Some(net_id_open.clone()),
682 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
683 ..Default::default()
684 },
685 fidl_policy::NetworkConfig {
686 id: Some(net_id_wpa2_w_password.clone()),
687 credential: Some(fidl_policy::Credential::Password(b"foobar-password".to_vec())),
688 ..Default::default()
689 },
690 fidl_policy::NetworkConfig {
691 id: Some(net_id_wpa2_w_psk.clone()),
692 credential: Some(fidl_policy::Credential::Psk([64; WPA_PSK_BYTE_LEN].to_vec())),
693 ..Default::default()
694 },
695 ];
696 let saved_networks =
697 Arc::new(FakeSavedNetworksManager::new_with_saved_networks(presaved_default_configs));
698 let (telemetry_sender, telemetry_receiver) = mpsc::channel::<TelemetryEvent>(100);
699 let (provider, requests) = create_proxy::<fidl_policy::ClientProviderMarker>();
700 let requests = requests.into_stream();
701
702 let (proxy, _server) = create_proxy::<fidl_fuchsia_wlan_sme::ClientSmeMarker>();
703 let (req_sender, iface_mgr_req_recvr) = mpsc::channel(1);
704 let iface_manager = FakeIfaceManager::new(proxy.clone(), req_sender);
705 let iface_manager = Arc::new(Mutex::new(iface_manager));
706 let scan_requester = Arc::new(FakeScanRequester::new());
707
708 let (update_sender, listener_updates) = mpsc::unbounded();
709
710 TestValues {
711 saved_networks,
712 net_id_open,
713 net_id_wpa2_w_password,
714 net_id_wpa2_w_psk,
715 provider,
716 requests,
717 iface_manager,
718 iface_mgr_req_recvr,
719 scan_requester,
720 update_sender,
721 listener_updates,
722 client_provider_lock: Arc::new(Mutex::new(())),
723 telemetry_sender: TelemetrySender::new(telemetry_sender),
724 telemetry_receiver,
725 }
726 }
727
728 #[fuchsia::test]
729 fn connect_request_unknown_network() {
730 let ssid = client_types::Ssid::try_from("foobar-unknown").unwrap();
731 let mut exec = fasync::TestExecutor::new();
732 let test_values = test_setup();
733 let serve_fut = serve_provider_requests(
734 test_values.iface_manager,
735 test_values.update_sender,
736 Arc::clone(&test_values.saved_networks),
737 test_values.scan_requester,
738 test_values.client_provider_lock,
739 test_values.requests,
740 test_values.telemetry_sender,
741 );
742 let mut serve_fut = pin!(serve_fut);
743
744 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
746
747 let (controller, _) = request_controller(&test_values.provider);
749 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
750
751 let connect_fut = controller.connect(&fidl_policy::NetworkIdentifier {
753 ssid: ssid.to_vec(),
754 type_: fidl_policy::SecurityType::None,
755 });
756 let mut connect_fut = pin!(connect_fut);
757
758 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
760
761 assert_matches!(
762 exec.run_until_stalled(&mut connect_fut),
763 Poll::Ready(Ok(fidl_policy::RequestStatus::RejectedNotSupported))
764 );
765
766 let id = NetworkIdentifier::new(ssid, SecurityType::None);
769 let lookup_fut = test_values.saved_networks.lookup(&id);
770 assert!(exec.run_singlethreaded(lookup_fut).is_empty());
771 }
772
773 #[fuchsia::test]
774 fn connect_request_open_network() {
775 let mut exec = fasync::TestExecutor::new();
776
777 let test_values = test_setup();
778 let serve_fut = serve_provider_requests(
779 test_values.iface_manager,
780 test_values.update_sender,
781 Arc::clone(&test_values.saved_networks),
782 test_values.scan_requester,
783 test_values.client_provider_lock,
784 test_values.requests,
785 test_values.telemetry_sender,
786 );
787 let mut serve_fut = pin!(serve_fut);
788
789 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
791
792 let (controller, _update_stream) = request_controller(&test_values.provider);
794 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
795
796 let connect_fut = controller.connect(&test_values.net_id_open);
798 let mut connect_fut = pin!(connect_fut);
799
800 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
802
803 assert_matches!(
805 exec.run_until_stalled(&mut connect_fut),
806 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
807 );
808 }
809
810 #[fuchsia::test]
811 fn connect_request_protected_network() {
812 let mut exec = fasync::TestExecutor::new();
813
814 let test_values = test_setup();
815 let serve_fut = serve_provider_requests(
816 test_values.iface_manager,
817 test_values.update_sender,
818 Arc::clone(&test_values.saved_networks),
819 test_values.scan_requester,
820 test_values.client_provider_lock,
821 test_values.requests,
822 test_values.telemetry_sender,
823 );
824 let mut serve_fut = pin!(serve_fut);
825
826 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
828
829 let (controller, _update_stream) = request_controller(&test_values.provider);
831 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
832
833 let connect_fut = controller.connect(&test_values.net_id_wpa2_w_password);
835 let mut connect_fut = pin!(connect_fut);
836
837 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
839
840 assert_matches!(
842 exec.run_until_stalled(&mut connect_fut),
843 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
844 );
845 }
846
847 #[fuchsia::test]
848 fn connect_request_protected_psk_network() {
849 let mut exec = fasync::TestExecutor::new();
850
851 let test_values = test_setup();
852 let serve_fut = serve_provider_requests(
853 test_values.iface_manager,
854 test_values.update_sender,
855 Arc::clone(&test_values.saved_networks),
856 test_values.scan_requester,
857 test_values.client_provider_lock,
858 test_values.requests,
859 test_values.telemetry_sender,
860 );
861 let mut serve_fut = pin!(serve_fut);
862
863 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
865
866 let (controller, _update_stream) = request_controller(&test_values.provider);
868 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
869
870 let connect_fut = controller.connect(&test_values.net_id_wpa2_w_psk);
872 let mut connect_fut = pin!(connect_fut);
873
874 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
876
877 assert_matches!(
879 exec.run_until_stalled(&mut connect_fut),
880 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
881 );
882 }
883
884 #[fuchsia::test]
885 fn start_and_stop_client_connections() {
886 let mut exec = fasync::TestExecutor::new();
887 let mut test_values = test_setup();
888 let serve_fut = serve_provider_requests(
889 test_values.iface_manager,
890 test_values.update_sender,
891 test_values.saved_networks,
892 test_values.scan_requester,
893 test_values.client_provider_lock,
894 test_values.requests,
895 test_values.telemetry_sender,
896 );
897 let mut serve_fut = pin!(serve_fut);
898
899 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
901
902 let (controller, _update_stream) = request_controller(&test_values.provider);
904 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
905
906 let start_fut = controller.start_client_connections();
908 let mut start_fut = pin!(start_fut);
909
910 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
912 assert_matches!(
913 exec.run_until_stalled(&mut start_fut),
914 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
915 );
916
917 assert_matches!(test_values.telemetry_receiver.try_next(), Ok(Some(event)) => {
919 assert_matches!(event, TelemetryEvent::StartClientConnectionsRequest);
920 });
921
922 let connect_fut = controller.connect(&test_values.net_id_wpa2_w_password);
924 let mut connect_fut = pin!(connect_fut);
925
926 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
928
929 assert_matches!(
931 exec.run_until_stalled(&mut connect_fut),
932 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
933 );
934
935 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
937
938 let stop_fut = controller.stop_client_connections();
940 let mut stop_fut = pin!(stop_fut);
941
942 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
944
945 assert_matches!(test_values.telemetry_receiver.try_next(), Ok(Some(event)) => {
947 assert_matches!(event, TelemetryEvent::StopClientConnectionsRequest);
948 });
949
950 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
952 assert_matches!(
953 exec.run_until_stalled(&mut stop_fut),
954 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
955 );
956 }
957
958 #[fuchsia::test]
962 fn scan_end_to_end() {
963 let mut exec = fasync::TestExecutor::new();
964 let test_values = test_setup();
965 let serve_fut = serve_provider_requests(
966 test_values.iface_manager,
967 test_values.update_sender,
968 test_values.saved_networks,
969 test_values.scan_requester.clone(),
970 test_values.client_provider_lock,
971 test_values.requests,
972 test_values.telemetry_sender,
973 );
974 let mut serve_fut = pin!(serve_fut);
975
976 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
978
979 let (controller, _update_stream) = request_controller(&test_values.provider);
981 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
982
983 let (_iter, server) = fidl::endpoints::create_proxy();
985 controller.scan_for_networks(server).expect("Failed to call scan for networks");
986
987 exec.run_singlethreaded(test_values.scan_requester.add_scan_result(Ok(vec![])));
990 exec.run_singlethreaded(test_values.scan_requester.add_scan_result(Ok(vec![])));
992
993 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
995
996 let expected_active_ssids = [
999 test_values.net_id_wpa2_w_password,
1000 test_values.net_id_wpa2_w_psk,
1001 test_values.net_id_open,
1002 ]
1003 .iter()
1004 .map(|id| types::Ssid::from_bytes_unchecked(id.ssid.clone()))
1005 .collect();
1006 exec.run_singlethreaded(test_values.scan_requester.verify_scan_request((
1007 scan::ScanReason::ClientRequest,
1008 vec![],
1009 vec![],
1010 )));
1011 exec.run_singlethreaded(test_values.scan_requester.verify_scan_request((
1012 scan::ScanReason::ClientRequest,
1013 expected_active_ssids,
1014 vec![],
1015 )));
1016 }
1017
1018 #[fuchsia::test]
1019 fn save_network() {
1020 let mut exec = fasync::TestExecutor::new();
1021 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1022
1023 let mut test_values = test_setup();
1024 let serve_fut = serve_provider_requests(
1025 test_values.iface_manager,
1026 test_values.update_sender,
1027 saved_networks.clone(),
1028 test_values.scan_requester,
1029 test_values.client_provider_lock,
1030 test_values.requests,
1031 test_values.telemetry_sender,
1032 );
1033 let mut serve_fut = pin!(serve_fut);
1034
1035 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1037
1038 let (controller, _update_stream) = request_controller(&test_values.provider);
1040 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1041 assert_matches!(
1042 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1043 Poll::Ready(_)
1044 );
1045
1046 let network_id = fidl_policy::NetworkIdentifier {
1048 ssid: b"foo".to_vec(),
1049 type_: fidl_policy::SecurityType::None,
1050 };
1051 let network_config = fidl_policy::NetworkConfig {
1052 id: Some(network_id.clone()),
1053 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
1054 ..Default::default()
1055 };
1056 let mut save_fut = controller.save_network(&network_config);
1057
1058 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Pending);
1060 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1061
1062 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(Ok(Ok(()))));
1064
1065 let target_id = NetworkIdentifier::from(network_id);
1067 let target_config = NetworkConfig::new(target_id.clone(), Credential::None, false, None)
1068 .expect("Failed to create network config");
1069 assert_eq!(exec.run_singlethreaded(saved_networks.lookup(&target_id)), vec![target_config]);
1070 }
1071
1072 #[fuchsia::test]
1073 fn save_network_with_disconnected_iface() {
1074 let mut exec = fasync::TestExecutor::new();
1075 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1076
1077 let mut test_values = test_setup();
1078 let serve_fut = serve_provider_requests(
1079 test_values.iface_manager.clone(),
1080 test_values.update_sender,
1081 saved_networks.clone(),
1082 test_values.scan_requester,
1083 test_values.client_provider_lock,
1084 test_values.requests,
1085 test_values.telemetry_sender,
1086 );
1087 let mut serve_fut = pin!(serve_fut);
1088
1089 {
1091 let iface_manager = test_values.iface_manager.clone();
1092 let iface_manager_fut = iface_manager.lock();
1093 let mut iface_manager_fut = pin!(iface_manager_fut);
1094 let mut iface_manager = match exec.run_until_stalled(&mut iface_manager_fut) {
1095 Poll::Ready(iface_manager) => iface_manager,
1096 Poll::Pending => panic!("expected to acquire iface_manager lock"),
1097 };
1098 let record_idle_fut = iface_manager.record_idle_client(0);
1099 let mut record_idle_fut = pin!(record_idle_fut);
1100 assert_matches!(exec.run_until_stalled(&mut record_idle_fut), Poll::Ready(Ok(())));
1101 }
1102
1103 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1105
1106 let (controller, _update_stream) = request_controller(&test_values.provider);
1108 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1109 assert_matches!(
1110 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1111 Poll::Ready(_)
1112 );
1113
1114 let network_id = fidl_policy::NetworkIdentifier {
1116 ssid: b"foo".to_vec(),
1117 type_: fidl_policy::SecurityType::None,
1118 };
1119 let network_config = fidl_policy::NetworkConfig {
1120 id: Some(network_id.clone()),
1121 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
1122 ..Default::default()
1123 };
1124 let mut save_fut = controller.save_network(&network_config);
1125
1126 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Pending);
1127 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1128
1129 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(result) => {
1131 let save_result = result.expect("Failed to get save network response");
1132 assert_eq!(save_result, Ok(()));
1133 });
1134
1135 let target_id = NetworkIdentifier::from(network_id);
1137 let target_config = NetworkConfig::new(target_id.clone(), Credential::None, false, None)
1138 .expect("Failed to create network config");
1139 assert_eq!(exec.run_singlethreaded(saved_networks.lookup(&target_id)), vec![target_config]);
1140 }
1141
1142 #[fuchsia::test]
1143 fn save_network_overwrite_disconnects() {
1144 let mut exec = fasync::TestExecutor::new();
1145 let mut test_values = test_setup();
1146 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1147
1148 let serve_fut = serve_provider_requests(
1149 test_values.iface_manager,
1150 test_values.update_sender,
1151 saved_networks.clone(),
1152 test_values.scan_requester,
1153 test_values.client_provider_lock,
1154 test_values.requests,
1155 test_values.telemetry_sender,
1156 );
1157 let mut serve_fut = pin!(serve_fut);
1158
1159 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1161
1162 let (controller, _update_stream) = request_controller(&test_values.provider);
1164 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1165 assert_matches!(
1166 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1167 Poll::Ready(_)
1168 );
1169
1170 let network_id = NetworkIdentifier::try_from("foo", SecurityType::Wpa2).unwrap();
1172 let credential = Credential::Password(b"password".to_vec());
1173 let save_fut = saved_networks.store(network_id.clone(), credential.clone());
1174 let mut save_fut = pin!(save_fut);
1175 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(Ok(None)));
1176
1177 let network_config = fidl_policy::NetworkConfig {
1179 id: Some(fidl_policy::NetworkIdentifier::from(network_id.clone())),
1180 credential: Some(fidl_policy::Credential::Password(b"other-password".to_vec())),
1181 ..Default::default()
1182 };
1183 let mut save_fut = controller.save_network(&network_config);
1184
1185 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1187 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1188
1189 assert_matches!(exec.run_until_stalled(&mut test_values.iface_mgr_req_recvr.next()), Poll::Ready(Some(IfaceManagerRequest::Disconnect(net_id, reason))) => {
1191 assert_eq!(net_id, network_id.clone());
1192 assert_eq!(reason, client_types::DisconnectReason::NetworkConfigUpdated);
1193 });
1194 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1195 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(Ok(Ok(()))));
1196 }
1197
1198 #[fuchsia::test]
1199 fn save_bad_network_should_fail() {
1200 let mut exec = fasync::TestExecutor::new();
1201 let mut saved_networks = FakeSavedNetworksManager::new();
1202 saved_networks.fail_all_stores = true;
1203 let saved_networks = Arc::new(saved_networks);
1204
1205 let mut test_values = test_setup();
1206 let serve_fut = serve_provider_requests(
1207 test_values.iface_manager,
1208 test_values.update_sender,
1209 saved_networks.clone(),
1210 test_values.scan_requester,
1211 test_values.client_provider_lock,
1212 test_values.requests,
1213 test_values.telemetry_sender,
1214 );
1215 let mut serve_fut = pin!(serve_fut);
1216
1217 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1219
1220 let (controller, _update_stream) = request_controller(&test_values.provider);
1222 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1223 assert_matches!(
1224 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1225 Poll::Ready(_)
1226 );
1227
1228 let bad_network_id = fidl_policy::NetworkIdentifier {
1232 ssid: b"foo".to_vec(),
1233 type_: fidl_policy::SecurityType::Wpa2,
1234 };
1235 let network_config = fidl_policy::NetworkConfig {
1236 id: Some(bad_network_id.clone()),
1237 credential: Some(fidl_policy::Credential::Password(b"bar".to_vec())),
1238 ..Default::default()
1239 };
1240 let mut save_fut = controller.save_network(&network_config);
1242
1243 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1245
1246 assert_matches!(exec.run_until_stalled(&mut save_fut), Poll::Ready(result) => {
1248 let error = result.expect("Failed to get save network response");
1249 assert_eq!(error, Err(fidl_policy::NetworkConfigChangeError::NetworkConfigWriteError));
1250 });
1251
1252 let target_id = NetworkIdentifier::from(bad_network_id);
1254 assert_eq!(exec.run_singlethreaded(saved_networks.lookup(&target_id)), vec![]);
1255 }
1256
1257 #[fuchsia::test]
1258 fn test_remove_a_network() {
1259 let mut exec = fasync::TestExecutor::new();
1260 let mut test_values = test_setup();
1261
1262 let serve_fut = serve_provider_requests(
1263 test_values.iface_manager,
1264 test_values.update_sender,
1265 test_values.saved_networks.clone(),
1266 test_values.scan_requester,
1267 test_values.client_provider_lock,
1268 test_values.requests,
1269 test_values.telemetry_sender,
1270 );
1271 let mut serve_fut = pin!(serve_fut);
1272
1273 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1275
1276 let (controller, _update_stream) = request_controller(&test_values.provider);
1278 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1279 assert_matches!(
1280 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1281 Poll::Ready(_)
1282 );
1283
1284 let network_config = fidl_policy::NetworkConfig {
1286 id: Some(test_values.net_id_open.clone()),
1287 credential: Some(fidl_policy::Credential::None(fidl_policy::Empty)),
1288 ..Default::default()
1289 };
1290 let mut remove_fut = controller.remove_network(&network_config);
1291
1292 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1294 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1295
1296 assert_matches!(exec.run_until_stalled(&mut test_values.iface_mgr_req_recvr.next()), Poll::Ready(Some(IfaceManagerRequest::Disconnect(net_id, reason))) => {
1300 assert_eq!(net_id, test_values.net_id_open.clone().into());
1301 assert_eq!(reason, client_types::DisconnectReason::NetworkUnsaved);
1302 });
1303 assert_matches!(exec.run_until_stalled(&mut remove_fut), Poll::Ready(Ok(Ok(()))));
1304 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1305 assert!(
1306 exec.run_singlethreaded(
1307 test_values.saved_networks.lookup(&test_values.net_id_open.clone().into())
1308 )
1309 .is_empty()
1310 );
1311
1312 let mut remove_fut = controller.remove_network(&network_config);
1314 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1316 assert_matches!(
1317 exec.run_until_stalled(&mut test_values.iface_mgr_req_recvr.next()),
1318 Poll::Pending
1319 );
1320 assert_matches!(exec.run_until_stalled(&mut remove_fut), Poll::Ready(Ok(Ok(()))));
1321 }
1322
1323 #[fuchsia::test]
1324 fn test_get_saved_network() {
1325 let expected_configs = vec![generate_random_fidl_network_config()];
1326 let expected_num_sends = 1;
1327 run_get_saved_networks_test(expected_configs, expected_num_sends);
1328 }
1329
1330 #[fuchsia::test]
1331 fn test_get_saved_networks_multiple_chunks() {
1332 let mut configs = vec![];
1335 for index in 0..MAX_CONFIGS_PER_RESPONSE + 1 {
1336 let ssid = format!("some_config{index}");
1338 let network_config = generate_random_fidl_network_config_with_ssid(&ssid);
1339 configs.push(network_config);
1340 }
1341
1342 let expected_num_sends = 2;
1343 run_get_saved_networks_test(configs, expected_num_sends);
1344 }
1345
1346 fn run_get_saved_networks_test(
1353 configs: Vec<fidl_policy::NetworkConfig>,
1354 expected_num_sends: usize,
1355 ) {
1356 let mut exec = fasync::TestExecutor::new();
1357 let saved_networks =
1358 Arc::new(FakeSavedNetworksManager::new_with_saved_networks(configs.clone()));
1359
1360 let test_values = test_setup();
1361 let serve_fut = serve_provider_requests(
1362 test_values.iface_manager,
1363 test_values.update_sender,
1364 saved_networks.clone(),
1365 test_values.scan_requester,
1366 test_values.client_provider_lock,
1367 test_values.requests,
1368 test_values.telemetry_sender,
1369 );
1370 let mut serve_fut = pin!(serve_fut);
1371
1372 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1374
1375 let (controller, _update_stream) = request_controller(&test_values.provider);
1377 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1378
1379 let (iter, server) =
1381 fidl::endpoints::create_proxy::<fidl_policy::NetworkConfigIteratorMarker>();
1382 controller.get_saved_networks(server).expect("Failed to call get saved networks");
1383
1384 let mut saved_networks_results = vec![];
1387 for i in 0..expected_num_sends {
1388 let get_saved_fut = iter.get_next();
1389 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1390 let results = exec
1391 .run_singlethreaded(get_saved_fut)
1392 .expect("Failed to get next chunk of saved networks results");
1393 if i < expected_num_sends - 1 {
1396 assert_eq!(results.len(), MAX_CONFIGS_PER_RESPONSE);
1397 } else {
1398 assert_eq!(results.len(), configs.len() % MAX_CONFIGS_PER_RESPONSE);
1399 }
1400 saved_networks_results.extend(results);
1401 }
1402 let get_saved_end_fut = iter.get_next();
1403 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1404 let results = exec
1405 .run_singlethreaded(get_saved_end_fut)
1406 .expect("Failed to get next chunk of saved networks results");
1407 assert!(results.is_empty());
1408
1409 for network_config in &configs {
1411 assert!(saved_networks_results.contains(network_config));
1412 }
1413 assert_eq!(configs.len(), saved_networks_results.len());
1414 }
1415
1416 #[fuchsia::test]
1417 fn register_update_listener() {
1418 let mut exec = fasync::TestExecutor::new();
1419 let mut test_values = test_setup();
1420 let serve_fut = serve_provider_requests(
1421 test_values.iface_manager,
1422 test_values.update_sender,
1423 test_values.saved_networks,
1424 test_values.scan_requester,
1425 test_values.client_provider_lock,
1426 test_values.requests,
1427 test_values.telemetry_sender,
1428 );
1429 let mut serve_fut = pin!(serve_fut);
1430
1431 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1433
1434 let (_controller, _update_stream) = request_controller(&test_values.provider);
1436 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1437 assert_matches!(
1438 exec.run_until_stalled(&mut test_values.listener_updates.next()),
1439 Poll::Ready(Some(listener::Message::NewListener(_)))
1440 );
1441 }
1442
1443 #[fuchsia::test]
1444 fn get_listener() {
1445 let mut exec = fasync::TestExecutor::new();
1446 let (listener, requests) = create_proxy::<fidl_policy::ClientListenerMarker>();
1447 let requests = requests.into_stream();
1448
1449 let (update_sender, mut listener_updates) = mpsc::unbounded();
1450 let serve_fut = serve_listener_requests(update_sender, requests);
1451 let mut serve_fut = pin!(serve_fut);
1452
1453 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1455
1456 let (update_sink, _update_stream) =
1458 create_request_stream::<fidl_policy::ClientStateUpdatesMarker>();
1459 listener.get_listener(update_sink).expect("error getting listener");
1460
1461 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1462 assert_matches!(
1463 exec.run_until_stalled(&mut listener_updates.next()),
1464 Poll::Ready(Some(listener::Message::NewListener(_)))
1465 );
1466 }
1467
1468 #[fuchsia::test]
1469 fn multiple_controllers_write_attempt() {
1470 let mut exec = fasync::TestExecutor::new();
1471 let test_values = test_setup();
1472 let serve_fut = serve_provider_requests(
1473 test_values.iface_manager,
1474 test_values.update_sender,
1475 test_values.saved_networks,
1476 test_values.scan_requester,
1477 test_values.client_provider_lock,
1478 test_values.requests,
1479 test_values.telemetry_sender,
1480 );
1481 let mut serve_fut = pin!(serve_fut);
1482
1483 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1485
1486 let (controller1, _) = request_controller(&test_values.provider);
1488 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1489
1490 let (controller2, _) = request_controller(&test_values.provider);
1492 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1493
1494 let connect_fut = controller1.connect(&test_values.net_id_open);
1496 let mut connect_fut = pin!(connect_fut);
1497
1498 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1500
1501 assert_matches!(
1502 exec.run_until_stalled(&mut connect_fut),
1503 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
1504 );
1505
1506 let connect_fut = controller2.connect(&test_values.net_id_open);
1508 let mut connect_fut = pin!(connect_fut);
1509
1510 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1512 assert_matches!(
1513 exec.run_until_stalled(&mut connect_fut),
1514 Poll::Ready(Err(fidl::Error::ClientChannelClosed {
1515 status: zx::Status::ALREADY_BOUND,
1516 ..
1517 }))
1518 );
1519
1520 drop(controller1);
1522 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1523
1524 let (controller3, _) = request_controller(&test_values.provider);
1526 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1527
1528 let connect_fut = controller3.connect(&test_values.net_id_open);
1530 let mut connect_fut = pin!(connect_fut);
1531
1532 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1534
1535 assert_matches!(
1536 exec.run_until_stalled(&mut connect_fut),
1537 Poll::Ready(Ok(fidl_policy::RequestStatus::Acknowledged))
1538 );
1539 }
1540
1541 #[fuchsia::test]
1542 fn multiple_controllers_epitaph() {
1543 let mut exec = fasync::TestExecutor::new();
1544 let test_values = test_setup();
1545 let serve_fut = serve_provider_requests(
1546 test_values.iface_manager,
1547 test_values.update_sender,
1548 test_values.saved_networks.clone(),
1549 test_values.scan_requester,
1550 test_values.client_provider_lock,
1551 test_values.requests,
1552 test_values.telemetry_sender,
1553 );
1554 let mut serve_fut = pin!(serve_fut);
1555
1556 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1558
1559 let (_controller1, _) = request_controller(&test_values.provider);
1561 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1562
1563 let (controller2, _) = request_controller(&test_values.provider);
1565 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1566
1567 let mut controller2_event_stream = controller2.take_event_stream();
1569 let controller2_event_fut = controller2_event_stream.next();
1570 let mut controller2_event_fut = pin!(controller2_event_fut);
1571 assert_matches!(
1572 exec.run_until_stalled(&mut controller2_event_fut),
1573 Poll::Ready(Some(Err(fidl::Error::ClientChannelClosed {
1574 status: zx::Status::ALREADY_BOUND,
1575 ..
1576 })))
1577 );
1578 assert!(controller2.is_closed());
1579 }
1580
1581 struct FakeIfaceManagerNoIfaces {}
1582
1583 #[async_trait(?Send)]
1584 impl IfaceManagerApi for FakeIfaceManagerNoIfaces {
1585 async fn disconnect(
1586 &mut self,
1587 _network_id: client_types::NetworkIdentifier,
1588 _reason: client_types::DisconnectReason,
1589 ) -> Result<(), Error> {
1590 Err(format_err!("No ifaces"))
1591 }
1592
1593 async fn connect(&mut self, _connect_req: ConnectAttemptRequest) -> Result<(), Error> {
1594 Err(format_err!("No ifaces"))
1595 }
1596
1597 async fn record_idle_client(&mut self, _iface_id: u16) -> Result<(), Error> {
1598 unimplemented!()
1599 }
1600
1601 async fn has_idle_client(&mut self) -> Result<bool, Error> {
1602 unimplemented!()
1603 }
1604
1605 async fn handle_added_iface(&mut self, _iface_id: u16) -> Result<(), Error> {
1606 unimplemented!()
1607 }
1608
1609 async fn handle_removed_iface(&mut self, _iface_id: u16) -> Result<(), Error> {
1610 unimplemented!()
1611 }
1612
1613 async fn get_sme_proxy_for_scan(&mut self) -> Result<SmeForScan, Error> {
1614 Err(format_err!("No ifaces"))
1615 }
1616
1617 async fn stop_client_connections(
1618 &mut self,
1619 _reason: client_types::DisconnectReason,
1620 ) -> Result<(), Error> {
1621 unimplemented!()
1622 }
1623
1624 async fn start_client_connections(&mut self) -> Result<(), Error> {
1625 unimplemented!()
1626 }
1627
1628 async fn start_ap(
1629 &mut self,
1630 _config: ap_fsm::ApConfig,
1631 ) -> Result<oneshot::Receiver<()>, Error> {
1632 unimplemented!()
1633 }
1634
1635 async fn stop_ap(&mut self, _ssid: types::Ssid, _password: Vec<u8>) -> Result<(), Error> {
1636 unimplemented!()
1637 }
1638
1639 async fn stop_all_aps(&mut self) -> Result<(), Error> {
1640 unimplemented!()
1641 }
1642
1643 async fn set_country(
1644 &mut self,
1645 _country_code: Option<types::CountryCode>,
1646 ) -> Result<(), Error> {
1647 unimplemented!()
1648 }
1649 }
1650
1651 #[fuchsia::test]
1652 fn no_client_interface() {
1653 let mut exec = fasync::TestExecutor::new();
1654 let test_values = test_setup();
1655
1656 let iface_manager = Arc::new(Mutex::new(FakeIfaceManagerNoIfaces {}));
1657
1658 let serve_fut = serve_provider_requests(
1659 iface_manager,
1660 test_values.update_sender,
1661 test_values.saved_networks,
1662 test_values.scan_requester,
1663 test_values.client_provider_lock,
1664 test_values.requests,
1665 test_values.telemetry_sender,
1666 );
1667 let mut serve_fut = pin!(serve_fut);
1668
1669 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1671
1672 let (controller, _) = request_controller(&test_values.provider);
1674 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1675
1676 let connect_fut = controller.connect(&test_values.net_id_open);
1678 let mut connect_fut = pin!(connect_fut);
1679
1680 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
1682 assert_matches!(
1683 exec.run_until_stalled(&mut connect_fut),
1684 Poll::Ready(Ok(fidl_policy::RequestStatus::RejectedIncompatibleMode))
1685 );
1686 }
1687
1688 async fn get_config(
1692 saved_networks: Arc<dyn SavedNetworksManagerApi>,
1693 id: NetworkIdentifier,
1694 cred: Credential,
1695 ) -> Option<NetworkConfig> {
1696 let mut cfgs = saved_networks
1697 .lookup(&id)
1698 .await
1699 .into_iter()
1700 .filter(|cfg| cfg.credential == cred)
1701 .collect::<Vec<_>>();
1702 assert!(cfgs.len() <= 1);
1704 cfgs.pop()
1705 }
1706
1707 #[fuchsia::test]
1708 async fn get_correct_config() {
1709 let saved_networks = Arc::new(FakeSavedNetworksManager::new());
1710 let network_id = NetworkIdentifier::try_from("foo", SecurityType::Wpa2).unwrap();
1711 let cfg = NetworkConfig::new(
1712 network_id.clone(),
1713 Credential::Password(b"password".to_vec()),
1714 false,
1715 None,
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}