1use crate::legacy::{Iface, IfaceRef};
6use crate::mode_management::iface_manager_api::IfaceManagerApi;
7use crate::mode_management::phy_manager::PhyManagerApi;
8use anyhow::format_err;
9use fidl::endpoints::create_proxy;
10use fidl_fuchsia_wlan_common as fidl_common;
11use fidl_fuchsia_wlan_device_service::{DeviceMonitorProxy, DeviceWatcherEvent};
12use futures::lock::Mutex;
13use log::{error, info};
14use std::sync::Arc;
15
16pub struct Listener {
17 proxy: DeviceMonitorProxy,
18 legacy_shim: IfaceRef,
19 phy_manager: Arc<Mutex<dyn PhyManagerApi>>,
20 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
21}
22
23pub async fn handle_event(listener: &Listener, evt: DeviceWatcherEvent) {
24 info!("got event: {:?}", evt);
25 match evt {
26 DeviceWatcherEvent::OnPhyAdded { phy_id } => {
27 on_phy_added(listener, phy_id).await;
28 }
29 DeviceWatcherEvent::OnPhyRemoved { phy_id } => {
30 info!("phy removed: {}", phy_id);
31 let mut phy_manager = listener.phy_manager.lock().await;
32 phy_manager.remove_phy(phy_id);
33 }
34 DeviceWatcherEvent::OnIfaceAdded { iface_id } => {
35 let mut iface_manager = listener.iface_manager.lock().await;
38 if let Err(e) = iface_manager.handle_added_iface(iface_id).await {
39 error!("Failed to add interface {} to IfaceManager: {}", iface_id, e);
40 return;
41 }
42
43 if let Err(e) = on_iface_added_legacy(listener, iface_id).await {
44 error!("error adding new iface {}: {}", iface_id, e)
45 }
46 }
47 DeviceWatcherEvent::OnIfaceRemoved { iface_id } => {
48 let mut iface_manager = listener.iface_manager.lock().await;
49 match iface_manager.handle_removed_iface(iface_id).await {
50 Ok(()) => {}
51 Err(e) => info!("Unable to record idle interface {}: {:?}", iface_id, e),
52 }
53
54 listener.legacy_shim.remove_if_matching(iface_id);
55 info!("iface removed: {}", iface_id);
56 }
57 }
58}
59
60async fn on_phy_added(listener: &Listener, phy_id: u16) {
61 info!("phy {} added", phy_id);
62 let mut phy_manager = listener.phy_manager.lock().await;
63 if let Err(e) = phy_manager.add_phy(phy_id).await {
64 info!("error adding new phy {}: {}", phy_id, e);
65 phy_manager.log_phy_add_failure();
66 }
67}
68
69async fn on_iface_added_legacy(listener: &Listener, iface_id: u16) -> Result<(), anyhow::Error> {
71 let response = match listener.proxy.query_iface(iface_id).await? {
72 Ok(response) => response,
73 Err(zx::sys::ZX_ERR_NOT_FOUND) => {
74 return Err(format_err!("Could not find iface: {}", iface_id));
75 }
76 Err(status) => return Err(format_err!("Could not query iface information: {}", status)),
77 };
78
79 let service = listener.proxy.clone();
80
81 match response.role {
82 fidl_common::WlanMacRole::Client => {
83 let legacy_shim = listener.legacy_shim.clone();
84 let (sme, remote) = create_proxy();
85
86 let result = service
87 .get_client_sme(iface_id, remote)
88 .await
89 .map_err(|e| format_err!("Failed to get client SME: {}", e))?;
90 result.map_err(|e| {
91 format_err!("GetClientSme returned an error: {}", zx::Status::from_raw(e))
92 })?;
93
94 let lc = Iface { sme: sme.clone(), iface_id };
95 legacy_shim.set_if_empty(lc);
96 }
97 fidl_common::WlanMacRole::Ap => {}
99 fidl_common::WlanMacRole::Mesh => {
100 return Err(format_err!("Unexpectedly observed a mesh iface: {}", iface_id));
101 }
102 fidl_common::WlanMacRoleUnknown!() => {
103 return Err(format_err!(
104 "Unknown WlanMacRole type {:?} on iface {}",
105 response.role,
106 iface_id
107 ));
108 }
109 }
110
111 info!("new iface {} added successfully", iface_id);
112 Ok(())
113}
114
115impl Listener {
116 pub fn new(
117 proxy: DeviceMonitorProxy,
118 legacy_shim: IfaceRef,
119 phy_manager: Arc<Mutex<dyn PhyManagerApi>>,
120 iface_manager: Arc<Mutex<dyn IfaceManagerApi>>,
121 ) -> Self {
122 Listener { proxy, legacy_shim, phy_manager, iface_manager }
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129 use crate::access_point::{state_machine as ap_fsm, types as ap_types};
130 use crate::client::types as client_types;
131 use crate::mode_management::Defect;
132 use crate::mode_management::iface_manager_api::{ConnectAttemptRequest, SmeForScan};
133 use crate::mode_management::phy_manager::{CreateClientIfacesReason, PhyManagerError};
134 use crate::mode_management::recovery::RecoverySummary;
135 use anyhow::Error;
136 use assert_matches::assert_matches;
137 use async_trait::async_trait;
138 use futures::StreamExt;
139 use futures::channel::oneshot;
140 use futures::task::Poll;
141 use ieee80211::MacAddr;
142 use std::collections::HashMap;
143 use std::pin::pin;
144 use {
145 fidl_fuchsia_wlan_device_service as fidl_service, fidl_fuchsia_wlan_sme as fidl_sme,
146 fuchsia_async as fasync,
147 };
148
149 struct TestValues {
150 phy_manager: Arc<Mutex<FakePhyManager>>,
151 iface_manager: Arc<Mutex<FakeIfaceManager>>,
152 monitor_proxy: fidl_service::DeviceMonitorProxy,
153 monitor_stream: fidl_service::DeviceMonitorRequestStream,
154 }
155
156 fn test_setup(add_phy_succeeds: bool, add_iface_succeeds: bool) -> TestValues {
157 let phy_manager =
158 Arc::new(Mutex::new(FakePhyManager::new(add_phy_succeeds, add_iface_succeeds)));
159 let iface_manager = Arc::new(Mutex::new(FakeIfaceManager::new()));
160 let (monitor_proxy, monitor_requests) = create_proxy::<fidl_service::DeviceMonitorMarker>();
161 let monitor_stream = monitor_requests.into_stream();
162
163 TestValues { phy_manager, iface_manager, monitor_proxy, monitor_stream }
164 }
165
166 #[fuchsia::test]
167 fn test_phy_add_succeeds() {
168 let mut exec = fasync::TestExecutor::new();
169 let test_values = test_setup(true, false);
170
171 let listener = Listener::new(
172 test_values.monitor_proxy,
173 IfaceRef::new(),
174 test_values.phy_manager.clone(),
175 test_values.iface_manager.clone(),
176 );
177
178 let fut = on_phy_added(&listener, 0);
180 let mut fut = pin!(fut);
181 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
182
183 let list_phys_fut = async move {
185 let phy_manager = test_values.phy_manager.lock().await;
186 phy_manager.phys.clone()
187 };
188 let mut list_phys_fut = pin!(list_phys_fut);
189 let phys =
190 assert_matches!(exec.run_until_stalled(&mut list_phys_fut), Poll::Ready(phys) => phys);
191
192 assert_eq!(phys, vec![0]);
193 }
194
195 #[fuchsia::test]
196 fn test_phy_add_fails() {
197 let mut exec = fasync::TestExecutor::new();
198 let test_values = test_setup(false, false);
199
200 let listener = Listener::new(
201 test_values.monitor_proxy,
202 IfaceRef::new(),
203 test_values.phy_manager.clone(),
204 test_values.iface_manager.clone(),
205 );
206
207 let fut = on_phy_added(&listener, 0);
209 let mut fut = pin!(fut);
210 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
211
212 let phy_manager_fut = async move {
214 let phy_manager = test_values.phy_manager.lock().await;
215 assert!(phy_manager.phys.is_empty());
216 assert_eq!(phy_manager.failed_phys, 1);
217 };
218 let mut phy_manager_fut = pin!(phy_manager_fut);
219 assert_matches!(exec.run_until_stalled(&mut phy_manager_fut), Poll::Ready(()));
220 }
221
222 #[fuchsia::test]
223 fn test_add_legacy_ap_iface() {
224 let mut exec = fasync::TestExecutor::new();
225 let mut test_values = test_setup(false, false);
226
227 let listener = Listener::new(
228 test_values.monitor_proxy,
229 IfaceRef::new(),
230 test_values.phy_manager.clone(),
231 test_values.iface_manager.clone(),
232 );
233
234 let fut = on_iface_added_legacy(&listener, 0);
235 let mut fut = pin!(fut);
236
237 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
239
240 let iface_response = Some(fidl_service::QueryIfaceResponse {
242 role: fidl_common::WlanMacRole::Ap,
243 id: 0,
244 phy_id: 0,
245 phy_assigned_id: 0,
246 sta_addr: [0, 1, 2, 3, 4, 5],
247 factory_addr: [0, 1, 2, 3, 4, 5],
248 });
249 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
250
251 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
253 }
254
255 #[fuchsia::test]
256 fn test_add_legacy_unknown_iface() {
257 let mut exec = fasync::TestExecutor::new();
258 let mut test_values = test_setup(false, false);
259
260 let listener = Listener::new(
261 test_values.monitor_proxy,
262 IfaceRef::new(),
263 test_values.phy_manager.clone(),
264 test_values.iface_manager.clone(),
265 );
266
267 let fut = on_iface_added_legacy(&listener, 0);
268 let mut fut = pin!(fut);
269
270 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
272
273 let iface_response = Some(fidl_service::QueryIfaceResponse {
275 role: fidl_common::WlanMacRole::unknown(),
276 id: 0,
277 phy_id: 0,
278 phy_assigned_id: 0,
279 sta_addr: [0, 1, 2, 3, 4, 5],
280 factory_addr: [0, 1, 2, 3, 4, 5],
281 });
282 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
283
284 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
287 }
288
289 #[fuchsia::test]
290 fn test_add_legacy_mesh_iface() {
291 let mut exec = fasync::TestExecutor::new();
292 let mut test_values = test_setup(false, false);
293
294 let listener = Listener::new(
295 test_values.monitor_proxy,
296 IfaceRef::new(),
297 test_values.phy_manager.clone(),
298 test_values.iface_manager.clone(),
299 );
300
301 let fut = on_iface_added_legacy(&listener, 0);
302 let mut fut = pin!(fut);
303
304 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
306
307 let iface_response = Some(fidl_service::QueryIfaceResponse {
309 role: fidl_common::WlanMacRole::Mesh,
310 id: 0,
311 phy_id: 0,
312 phy_assigned_id: 0,
313 sta_addr: [0, 1, 2, 3, 4, 5],
314 factory_addr: [0, 1, 2, 3, 4, 5],
315 });
316 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
317
318 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
320 }
321
322 #[fuchsia::test]
323 fn test_add_legacy_client_iface_succeeds() {
324 let mut exec = fasync::TestExecutor::new();
325 let mut test_values = test_setup(false, false);
326
327 let listener = Listener::new(
328 test_values.monitor_proxy,
329 IfaceRef::new(),
330 test_values.phy_manager.clone(),
331 test_values.iface_manager.clone(),
332 );
333
334 let fut = on_iface_added_legacy(&listener, 0);
335 let mut fut = pin!(fut);
336
337 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
339
340 let iface_response = Some(fidl_service::QueryIfaceResponse {
342 role: fidl_common::WlanMacRole::Client,
343 id: 0,
344 phy_id: 0,
345 phy_assigned_id: 0,
346 sta_addr: [0, 1, 2, 3, 4, 5],
347 factory_addr: [0, 1, 2, 3, 4, 5],
348 });
349 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
350
351 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
353 assert_matches!(
354 exec.run_until_stalled(&mut test_values.monitor_stream.next()),
355 Poll::Ready(Some(Ok(fidl_service::DeviceMonitorRequest::GetClientSme {
356 iface_id: 0, sme_server: _, responder
357 }))) => {
358 assert!(responder.send(Ok(())).is_ok())
359 }
360 );
361
362 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
364
365 assert!(listener.legacy_shim.get().is_ok());
367 }
368
369 #[fuchsia::test]
370 fn test_add_legacy_client_iface_fails() {
371 let mut exec = fasync::TestExecutor::new();
372 let mut test_values = test_setup(false, false);
373
374 let listener = Listener::new(
375 test_values.monitor_proxy,
376 IfaceRef::new(),
377 test_values.phy_manager.clone(),
378 test_values.iface_manager.clone(),
379 );
380
381 let fut = on_iface_added_legacy(&listener, 0);
382 let mut fut = pin!(fut);
383
384 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
386
387 let iface_response = Some(fidl_service::QueryIfaceResponse {
389 role: fidl_common::WlanMacRole::Client,
390 id: 0,
391 phy_id: 0,
392 phy_assigned_id: 0,
393 sta_addr: [0, 1, 2, 3, 4, 5],
394 factory_addr: [0, 1, 2, 3, 4, 5],
395 });
396 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
397
398 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
400 assert_matches!(
401 exec.run_until_stalled(&mut test_values.monitor_stream.next()),
402 Poll::Ready(Some(Ok(fidl_service::DeviceMonitorRequest::GetClientSme {
403 iface_id: 0, sme_server: _, responder
404 }))) => {
405 assert!(responder.send(Err(zx::sys::ZX_ERR_NOT_FOUND)).is_ok())
406 }
407 );
408
409 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
411
412 assert!(listener.legacy_shim.get().is_err());
414 }
415
416 #[fuchsia::test]
417 fn test_add_legacy_client_iface_query_fails() {
418 let mut exec = fasync::TestExecutor::new();
419 let test_values = test_setup(false, false);
420
421 let listener = Listener::new(
422 test_values.monitor_proxy,
423 IfaceRef::new(),
424 test_values.phy_manager.clone(),
425 test_values.iface_manager.clone(),
426 );
427
428 drop(test_values.monitor_stream);
430
431 let fut = on_iface_added_legacy(&listener, 0);
432 let mut fut = pin!(fut);
433
434 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
436
437 assert!(listener.legacy_shim.get().is_err());
439 }
440
441 #[fuchsia::test]
442 fn test_handle_add_phy_event() {
443 let mut exec = fasync::TestExecutor::new();
444 let test_values = test_setup(true, false);
445
446 let listener = Listener::new(
447 test_values.monitor_proxy,
448 IfaceRef::new(),
449 test_values.phy_manager.clone(),
450 test_values.iface_manager.clone(),
451 );
452
453 let fut = handle_event(&listener, DeviceWatcherEvent::OnPhyAdded { phy_id: 0 });
455 let mut fut = pin!(fut);
456 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
457
458 let list_phys_fut = async move {
460 let phy_manager = test_values.phy_manager.lock().await;
461 phy_manager.phys.clone()
462 };
463 let mut list_phys_fut = pin!(list_phys_fut);
464 let phys =
465 assert_matches!(exec.run_until_stalled(&mut list_phys_fut), Poll::Ready(phys) => phys);
466
467 assert_eq!(phys, vec![0]);
468 }
469
470 #[fuchsia::test]
471 fn test_handle_remove_phy_event() {
472 let mut exec = fasync::TestExecutor::new();
473 let test_values = test_setup(false, false);
474
475 {
477 let phy_manager = test_values.phy_manager.clone();
478 let add_phy_fut = async move {
479 let mut phy_manager = phy_manager.lock().await;
480 phy_manager.phys.push(0);
481 };
482 let mut add_phy_fut = pin!(add_phy_fut);
483 assert_matches!(exec.run_until_stalled(&mut add_phy_fut), Poll::Ready(()));
484 }
485
486 let listener = Listener::new(
487 test_values.monitor_proxy,
488 IfaceRef::new(),
489 test_values.phy_manager.clone(),
490 test_values.iface_manager.clone(),
491 );
492
493 let fut = handle_event(&listener, DeviceWatcherEvent::OnPhyRemoved { phy_id: 0 });
495 let mut fut = pin!(fut);
496 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
497
498 let list_phys_fut = async move {
500 let phy_manager = test_values.phy_manager.lock().await;
501 phy_manager.phys.clone()
502 };
503 let mut list_phys_fut = pin!(list_phys_fut);
504 let phys =
505 assert_matches!(exec.run_until_stalled(&mut list_phys_fut), Poll::Ready(phys) => phys);
506
507 assert!(phys.is_empty());
508 }
509
510 #[fuchsia::test]
511 fn test_handle_remove_nonexistent_iface_event() {
512 let mut exec = fasync::TestExecutor::new();
513 let test_values = test_setup(false, false);
514
515 {
517 let iface_manager = test_values.iface_manager.clone();
518 let add_iface_fut = async move {
519 let mut iface_manager = iface_manager.lock().await;
520 iface_manager.ifaces.push(0);
521 };
522 let mut add_iface_fut = pin!(add_iface_fut);
523 assert_matches!(exec.run_until_stalled(&mut add_iface_fut), Poll::Ready(()));
524 }
525
526 let (sme, _) = create_proxy::<fidl_sme::ClientSmeMarker>();
528 let iface_ref = IfaceRef::new();
529 iface_ref.set_if_empty(Iface { sme, iface_id: 0 });
530
531 let listener = Listener::new(
532 test_values.monitor_proxy,
533 iface_ref,
534 test_values.phy_manager.clone(),
535 test_values.iface_manager.clone(),
536 );
537
538 let fut = handle_event(&listener, DeviceWatcherEvent::OnIfaceRemoved { iface_id: 123 });
540 let mut fut = pin!(fut);
541 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
542
543 assert!(listener.legacy_shim.get().is_ok());
545 }
546
547 #[fuchsia::test]
548 fn test_handle_remove_iface_event() {
549 let mut exec = fasync::TestExecutor::new();
550 let test_values = test_setup(false, false);
551
552 {
554 let iface_manager = test_values.iface_manager.clone();
555 let add_iface_fut = async move {
556 let mut iface_manager = iface_manager.lock().await;
557 iface_manager.ifaces.push(0);
558 };
559 let mut add_iface_fut = pin!(add_iface_fut);
560 assert_matches!(exec.run_until_stalled(&mut add_iface_fut), Poll::Ready(()));
561 }
562
563 let (sme, _) = create_proxy::<fidl_sme::ClientSmeMarker>();
565 let iface_ref = IfaceRef::new();
566 iface_ref.set_if_empty(Iface { sme, iface_id: 0 });
567
568 let listener = Listener::new(
569 test_values.monitor_proxy,
570 iface_ref,
571 test_values.phy_manager.clone(),
572 test_values.iface_manager.clone(),
573 );
574
575 let fut = handle_event(&listener, DeviceWatcherEvent::OnIfaceRemoved { iface_id: 0 });
577 let mut fut = pin!(fut);
578 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
579
580 {
582 let phy_manager = test_values.phy_manager.clone();
583 let iface_manager = test_values.iface_manager.clone();
584 let verify_fut = async move {
585 let phy_manager = phy_manager.lock().await;
586 let iface_manager = iface_manager.lock().await;
587 assert!(phy_manager.ifaces.is_empty());
588 assert!(iface_manager.ifaces.is_empty());
589 };
590 let mut verify_fut = pin!(verify_fut);
591 assert_matches!(exec.run_until_stalled(&mut verify_fut), Poll::Ready(()));
592 }
593
594 assert!(listener.legacy_shim.get().is_err());
596 }
597
598 #[fuchsia::test]
599 fn test_handle_iface_added_succeeds() {
600 let mut exec = fasync::TestExecutor::new();
601 let mut test_values = test_setup(false, true);
602
603 let listener = Listener::new(
604 test_values.monitor_proxy,
605 IfaceRef::new(),
606 test_values.phy_manager.clone(),
607 test_values.iface_manager.clone(),
608 );
609
610 let fut = handle_event(&listener, DeviceWatcherEvent::OnIfaceAdded { iface_id: 0 });
611 let mut fut = pin!(fut);
612
613 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
615
616 let iface_response = Some(fidl_service::QueryIfaceResponse {
618 role: fidl_common::WlanMacRole::Client,
619 id: 0,
620 phy_id: 0,
621 phy_assigned_id: 0,
622 sta_addr: [0, 1, 2, 3, 4, 5],
623 factory_addr: [0, 1, 2, 3, 4, 5],
624 });
625 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
626
627 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
629 assert_matches!(
630 exec.run_until_stalled(&mut test_values.monitor_stream.next()),
631 Poll::Ready(Some(Ok(fidl_service::DeviceMonitorRequest::GetClientSme {
632 iface_id: 0, sme_server: _, responder
633 }))) => {
634 assert!(responder.send(Ok(())).is_ok())
635 }
636 );
637
638 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
640
641 {
643 let iface_manager = test_values.iface_manager.clone();
644 let verify_fut = async move {
645 let iface_manager = iface_manager.lock().await;
646 assert_eq!(iface_manager.ifaces, vec![0]);
647 };
648 let mut verify_fut = pin!(verify_fut);
649 assert_matches!(exec.run_until_stalled(&mut verify_fut), Poll::Ready(()));
650 }
651
652 assert!(listener.legacy_shim.get().is_ok());
654 }
655
656 #[fuchsia::test]
657 fn test_handle_iface_added_fails_due_to_monitor_service() {
658 let mut exec = fasync::TestExecutor::new();
659 let test_values = test_setup(false, true);
660
661 let listener = Listener::new(
662 test_values.monitor_proxy,
663 IfaceRef::new(),
664 test_values.phy_manager.clone(),
665 test_values.iface_manager.clone(),
666 );
667
668 drop(test_values.monitor_stream);
671
672 let fut = handle_event(&listener, DeviceWatcherEvent::OnIfaceAdded { iface_id: 0 });
674 let mut fut = pin!(fut);
675 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
676
677 {
679 let iface_manager = test_values.iface_manager.clone();
680 let verify_fut = async move {
681 let iface_manager = iface_manager.lock().await;
682 assert_eq!(iface_manager.ifaces, vec![0]);
683 };
684 let mut verify_fut = pin!(verify_fut);
685 assert_matches!(exec.run_until_stalled(&mut verify_fut), Poll::Ready(()));
686 }
687
688 assert!(listener.legacy_shim.get().is_err());
690 }
691
692 #[derive(Debug)]
693 struct FakePhyManager {
694 phys: Vec<u16>,
695 ifaces: Vec<u16>,
696 failed_phys: u32,
697 add_phy_succeeds: bool,
698 add_iface_succeeds: bool,
699 }
700
701 impl FakePhyManager {
702 fn new(add_phy_succeeds: bool, add_iface_succeeds: bool) -> Self {
703 FakePhyManager {
704 phys: Vec::new(),
705 ifaces: Vec::new(),
706 failed_phys: 0,
707 add_phy_succeeds,
708 add_iface_succeeds,
709 }
710 }
711 }
712
713 #[async_trait(?Send)]
714 impl PhyManagerApi for FakePhyManager {
715 async fn add_phy(&mut self, phy_id: u16) -> Result<(), PhyManagerError> {
716 if self.add_phy_succeeds {
717 self.phys.push(phy_id);
718 Ok(())
719 } else {
720 Err(PhyManagerError::PhyQueryFailure)
721 }
722 }
723
724 fn remove_phy(&mut self, phy_id: u16) {
725 self.phys.retain(|phy| *phy != phy_id)
726 }
727
728 async fn on_iface_added(&mut self, iface_id: u16) -> Result<(), PhyManagerError> {
729 if self.add_iface_succeeds {
730 self.ifaces.push(iface_id);
731 Ok(())
732 } else {
733 Err(PhyManagerError::IfaceQueryFailure)
734 }
735 }
736
737 fn on_iface_removed(&mut self, iface_id: u16) {
738 self.ifaces.retain(|iface| *iface != iface_id)
739 }
740
741 async fn create_all_client_ifaces(
742 &mut self,
743 _reason: CreateClientIfacesReason,
744 ) -> HashMap<u16, Result<Vec<u16>, PhyManagerError>> {
745 unimplemented!()
746 }
747
748 fn client_connections_enabled(&self) -> bool {
749 unimplemented!()
750 }
751
752 async fn destroy_all_client_ifaces(&mut self) -> Result<(), PhyManagerError> {
753 unimplemented!()
754 }
755
756 fn get_client(&mut self) -> Option<u16> {
757 unimplemented!();
758 }
759
760 async fn create_or_get_ap_iface(&mut self) -> Result<Option<u16>, PhyManagerError> {
761 unimplemented!();
762 }
763
764 async fn destroy_ap_iface(&mut self, _iface_id: u16) -> Result<(), PhyManagerError> {
765 unimplemented!();
766 }
767
768 async fn destroy_all_ap_ifaces(&mut self) -> Result<(), PhyManagerError> {
769 unimplemented!();
770 }
771
772 fn suggest_ap_mac(&mut self, _mac: MacAddr) {
773 unimplemented!()
774 }
775
776 fn get_phy_ids(&self) -> Vec<u16> {
777 unimplemented!()
778 }
779
780 fn log_phy_add_failure(&mut self) {
781 self.failed_phys += 1;
782 }
783
784 async fn set_country_code(
785 &mut self,
786 _country_code: Option<client_types::CountryCode>,
787 ) -> Result<(), PhyManagerError> {
788 unimplemented!();
789 }
790
791 fn record_defect(&mut self, _defect: Defect) {
792 unimplemented!();
793 }
794
795 async fn perform_recovery(&mut self, _summary: RecoverySummary) {
796 unimplemented!();
797 }
798 }
799
800 #[derive(Debug)]
801 struct FakeIfaceManager {
802 ifaces: Vec<u16>,
803 }
804
805 impl FakeIfaceManager {
806 fn new() -> Self {
807 FakeIfaceManager { ifaces: Vec::new() }
808 }
809 }
810
811 #[async_trait(?Send)]
812 impl IfaceManagerApi for FakeIfaceManager {
813 async fn disconnect(
814 &mut self,
815 _network_id: client_types::NetworkIdentifier,
816 _reason: client_types::DisconnectReason,
817 ) -> Result<(), Error> {
818 unimplemented!();
819 }
820
821 async fn connect(&mut self, _connect_req: ConnectAttemptRequest) -> Result<(), Error> {
822 unimplemented!();
823 }
824
825 async fn record_idle_client(&mut self, _iface_id: u16) -> Result<(), Error> {
826 unimplemented!();
827 }
828
829 async fn has_idle_client(&mut self) -> Result<bool, Error> {
830 unimplemented!();
831 }
832
833 async fn handle_added_iface(&mut self, iface_id: u16) -> Result<(), Error> {
834 self.ifaces.push(iface_id);
835 Ok(())
836 }
837
838 async fn handle_removed_iface(&mut self, iface_id: u16) -> Result<(), Error> {
839 self.ifaces.retain(|iface| *iface != iface_id);
840 Ok(())
841 }
842
843 async fn get_sme_proxy_for_scan(&mut self) -> Result<SmeForScan, Error> {
844 unimplemented!()
845 }
846
847 async fn stop_client_connections(
848 &mut self,
849 _reason: client_types::DisconnectReason,
850 ) -> Result<(), Error> {
851 unimplemented!()
852 }
853
854 async fn start_client_connections(&mut self) -> Result<(), Error> {
855 unimplemented!()
856 }
857
858 async fn start_ap(
859 &mut self,
860 _config: ap_fsm::ApConfig,
861 ) -> Result<oneshot::Receiver<()>, Error> {
862 unimplemented!();
863 }
864
865 async fn stop_ap(
866 &mut self,
867 _ssid: ap_types::Ssid,
868 _password: Vec<u8>,
869 ) -> Result<(), Error> {
870 unimplemented!();
871 }
872
873 async fn stop_all_aps(&mut self) -> Result<(), Error> {
874 unimplemented!()
875 }
876
877 async fn set_country(
878 &mut self,
879 _country_code: Option<client_types::CountryCode>,
880 ) -> Result<(), Error> {
881 unimplemented!();
882 }
883 }
884
885 #[track_caller]
886 fn send_query_iface_response(
887 exec: &mut fasync::TestExecutor,
888 server: &mut fidl_service::DeviceMonitorRequestStream,
889 iface_info: Option<fidl_service::QueryIfaceResponse>,
890 ) {
891 let response = iface_info.as_ref().ok_or(zx::sys::ZX_ERR_NOT_FOUND);
892 assert_matches!(
893 exec.run_until_stalled(&mut server.next()),
894 Poll::Ready(Some(Ok(
895 fidl_service::DeviceMonitorRequest::QueryIface {
896 iface_id: _,
897 responder,
898 }
899 ))) => {
900 responder.send(response).expect("sending fake iface info");
901 }
902 );
903 }
904}