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 });
248 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
249
250 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
252 }
253
254 #[fuchsia::test]
255 fn test_add_legacy_unknown_iface() {
256 let mut exec = fasync::TestExecutor::new();
257 let mut test_values = test_setup(false, false);
258
259 let listener = Listener::new(
260 test_values.monitor_proxy,
261 IfaceRef::new(),
262 test_values.phy_manager.clone(),
263 test_values.iface_manager.clone(),
264 );
265
266 let fut = on_iface_added_legacy(&listener, 0);
267 let mut fut = pin!(fut);
268
269 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
271
272 let iface_response = Some(fidl_service::QueryIfaceResponse {
274 role: fidl_common::WlanMacRole::unknown(),
275 id: 0,
276 phy_id: 0,
277 phy_assigned_id: 0,
278 sta_addr: [0, 1, 2, 3, 4, 5],
279 });
280 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
281
282 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
285 }
286
287 #[fuchsia::test]
288 fn test_add_legacy_mesh_iface() {
289 let mut exec = fasync::TestExecutor::new();
290 let mut test_values = test_setup(false, false);
291
292 let listener = Listener::new(
293 test_values.monitor_proxy,
294 IfaceRef::new(),
295 test_values.phy_manager.clone(),
296 test_values.iface_manager.clone(),
297 );
298
299 let fut = on_iface_added_legacy(&listener, 0);
300 let mut fut = pin!(fut);
301
302 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
304
305 let iface_response = Some(fidl_service::QueryIfaceResponse {
307 role: fidl_common::WlanMacRole::Mesh,
308 id: 0,
309 phy_id: 0,
310 phy_assigned_id: 0,
311 sta_addr: [0, 1, 2, 3, 4, 5],
312 });
313 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
314
315 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
317 }
318
319 #[fuchsia::test]
320 fn test_add_legacy_client_iface_succeeds() {
321 let mut exec = fasync::TestExecutor::new();
322 let mut test_values = test_setup(false, false);
323
324 let listener = Listener::new(
325 test_values.monitor_proxy,
326 IfaceRef::new(),
327 test_values.phy_manager.clone(),
328 test_values.iface_manager.clone(),
329 );
330
331 let fut = on_iface_added_legacy(&listener, 0);
332 let mut fut = pin!(fut);
333
334 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
336
337 let iface_response = Some(fidl_service::QueryIfaceResponse {
339 role: fidl_common::WlanMacRole::Client,
340 id: 0,
341 phy_id: 0,
342 phy_assigned_id: 0,
343 sta_addr: [0, 1, 2, 3, 4, 5],
344 });
345 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
346
347 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
349 assert_matches!(
350 exec.run_until_stalled(&mut test_values.monitor_stream.next()),
351 Poll::Ready(Some(Ok(fidl_service::DeviceMonitorRequest::GetClientSme {
352 iface_id: 0, sme_server: _, responder
353 }))) => {
354 assert!(responder.send(Ok(())).is_ok())
355 }
356 );
357
358 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Ok(())));
360
361 assert!(listener.legacy_shim.get().is_ok());
363 }
364
365 #[fuchsia::test]
366 fn test_add_legacy_client_iface_fails() {
367 let mut exec = fasync::TestExecutor::new();
368 let mut test_values = test_setup(false, false);
369
370 let listener = Listener::new(
371 test_values.monitor_proxy,
372 IfaceRef::new(),
373 test_values.phy_manager.clone(),
374 test_values.iface_manager.clone(),
375 );
376
377 let fut = on_iface_added_legacy(&listener, 0);
378 let mut fut = pin!(fut);
379
380 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
382
383 let iface_response = Some(fidl_service::QueryIfaceResponse {
385 role: fidl_common::WlanMacRole::Client,
386 id: 0,
387 phy_id: 0,
388 phy_assigned_id: 0,
389 sta_addr: [0, 1, 2, 3, 4, 5],
390 });
391 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
392
393 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
395 assert_matches!(
396 exec.run_until_stalled(&mut test_values.monitor_stream.next()),
397 Poll::Ready(Some(Ok(fidl_service::DeviceMonitorRequest::GetClientSme {
398 iface_id: 0, sme_server: _, responder
399 }))) => {
400 assert!(responder.send(Err(zx::sys::ZX_ERR_NOT_FOUND)).is_ok())
401 }
402 );
403
404 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
406
407 assert!(listener.legacy_shim.get().is_err());
409 }
410
411 #[fuchsia::test]
412 fn test_add_legacy_client_iface_query_fails() {
413 let mut exec = fasync::TestExecutor::new();
414 let test_values = test_setup(false, false);
415
416 let listener = Listener::new(
417 test_values.monitor_proxy,
418 IfaceRef::new(),
419 test_values.phy_manager.clone(),
420 test_values.iface_manager.clone(),
421 );
422
423 drop(test_values.monitor_stream);
425
426 let fut = on_iface_added_legacy(&listener, 0);
427 let mut fut = pin!(fut);
428
429 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(Err(_)));
431
432 assert!(listener.legacy_shim.get().is_err());
434 }
435
436 #[fuchsia::test]
437 fn test_handle_add_phy_event() {
438 let mut exec = fasync::TestExecutor::new();
439 let test_values = test_setup(true, false);
440
441 let listener = Listener::new(
442 test_values.monitor_proxy,
443 IfaceRef::new(),
444 test_values.phy_manager.clone(),
445 test_values.iface_manager.clone(),
446 );
447
448 let fut = handle_event(&listener, DeviceWatcherEvent::OnPhyAdded { phy_id: 0 });
450 let mut fut = pin!(fut);
451 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
452
453 let list_phys_fut = async move {
455 let phy_manager = test_values.phy_manager.lock().await;
456 phy_manager.phys.clone()
457 };
458 let mut list_phys_fut = pin!(list_phys_fut);
459 let phys =
460 assert_matches!(exec.run_until_stalled(&mut list_phys_fut), Poll::Ready(phys) => phys);
461
462 assert_eq!(phys, vec![0]);
463 }
464
465 #[fuchsia::test]
466 fn test_handle_remove_phy_event() {
467 let mut exec = fasync::TestExecutor::new();
468 let test_values = test_setup(false, false);
469
470 {
472 let phy_manager = test_values.phy_manager.clone();
473 let add_phy_fut = async move {
474 let mut phy_manager = phy_manager.lock().await;
475 phy_manager.phys.push(0);
476 };
477 let mut add_phy_fut = pin!(add_phy_fut);
478 assert_matches!(exec.run_until_stalled(&mut add_phy_fut), Poll::Ready(()));
479 }
480
481 let listener = Listener::new(
482 test_values.monitor_proxy,
483 IfaceRef::new(),
484 test_values.phy_manager.clone(),
485 test_values.iface_manager.clone(),
486 );
487
488 let fut = handle_event(&listener, DeviceWatcherEvent::OnPhyRemoved { phy_id: 0 });
490 let mut fut = pin!(fut);
491 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
492
493 let list_phys_fut = async move {
495 let phy_manager = test_values.phy_manager.lock().await;
496 phy_manager.phys.clone()
497 };
498 let mut list_phys_fut = pin!(list_phys_fut);
499 let phys =
500 assert_matches!(exec.run_until_stalled(&mut list_phys_fut), Poll::Ready(phys) => phys);
501
502 assert!(phys.is_empty());
503 }
504
505 #[fuchsia::test]
506 fn test_handle_remove_nonexistent_iface_event() {
507 let mut exec = fasync::TestExecutor::new();
508 let test_values = test_setup(false, false);
509
510 {
512 let iface_manager = test_values.iface_manager.clone();
513 let add_iface_fut = async move {
514 let mut iface_manager = iface_manager.lock().await;
515 iface_manager.ifaces.push(0);
516 };
517 let mut add_iface_fut = pin!(add_iface_fut);
518 assert_matches!(exec.run_until_stalled(&mut add_iface_fut), Poll::Ready(()));
519 }
520
521 let (sme, _) = create_proxy::<fidl_sme::ClientSmeMarker>();
523 let iface_ref = IfaceRef::new();
524 iface_ref.set_if_empty(Iface { sme, iface_id: 0 });
525
526 let listener = Listener::new(
527 test_values.monitor_proxy,
528 iface_ref,
529 test_values.phy_manager.clone(),
530 test_values.iface_manager.clone(),
531 );
532
533 let fut = handle_event(&listener, DeviceWatcherEvent::OnIfaceRemoved { iface_id: 123 });
535 let mut fut = pin!(fut);
536 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
537
538 assert!(listener.legacy_shim.get().is_ok());
540 }
541
542 #[fuchsia::test]
543 fn test_handle_remove_iface_event() {
544 let mut exec = fasync::TestExecutor::new();
545 let test_values = test_setup(false, false);
546
547 {
549 let iface_manager = test_values.iface_manager.clone();
550 let add_iface_fut = async move {
551 let mut iface_manager = iface_manager.lock().await;
552 iface_manager.ifaces.push(0);
553 };
554 let mut add_iface_fut = pin!(add_iface_fut);
555 assert_matches!(exec.run_until_stalled(&mut add_iface_fut), Poll::Ready(()));
556 }
557
558 let (sme, _) = create_proxy::<fidl_sme::ClientSmeMarker>();
560 let iface_ref = IfaceRef::new();
561 iface_ref.set_if_empty(Iface { sme, iface_id: 0 });
562
563 let listener = Listener::new(
564 test_values.monitor_proxy,
565 iface_ref,
566 test_values.phy_manager.clone(),
567 test_values.iface_manager.clone(),
568 );
569
570 let fut = handle_event(&listener, DeviceWatcherEvent::OnIfaceRemoved { iface_id: 0 });
572 let mut fut = pin!(fut);
573 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
574
575 {
577 let phy_manager = test_values.phy_manager.clone();
578 let iface_manager = test_values.iface_manager.clone();
579 let verify_fut = async move {
580 let phy_manager = phy_manager.lock().await;
581 let iface_manager = iface_manager.lock().await;
582 assert!(phy_manager.ifaces.is_empty());
583 assert!(iface_manager.ifaces.is_empty());
584 };
585 let mut verify_fut = pin!(verify_fut);
586 assert_matches!(exec.run_until_stalled(&mut verify_fut), Poll::Ready(()));
587 }
588
589 assert!(listener.legacy_shim.get().is_err());
591 }
592
593 #[fuchsia::test]
594 fn test_handle_iface_added_succeeds() {
595 let mut exec = fasync::TestExecutor::new();
596 let mut test_values = test_setup(false, true);
597
598 let listener = Listener::new(
599 test_values.monitor_proxy,
600 IfaceRef::new(),
601 test_values.phy_manager.clone(),
602 test_values.iface_manager.clone(),
603 );
604
605 let fut = handle_event(&listener, DeviceWatcherEvent::OnIfaceAdded { iface_id: 0 });
606 let mut fut = pin!(fut);
607
608 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
610
611 let iface_response = Some(fidl_service::QueryIfaceResponse {
613 role: fidl_common::WlanMacRole::Client,
614 id: 0,
615 phy_id: 0,
616 phy_assigned_id: 0,
617 sta_addr: [0, 1, 2, 3, 4, 5],
618 });
619 send_query_iface_response(&mut exec, &mut test_values.monitor_stream, iface_response);
620
621 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Pending);
623 assert_matches!(
624 exec.run_until_stalled(&mut test_values.monitor_stream.next()),
625 Poll::Ready(Some(Ok(fidl_service::DeviceMonitorRequest::GetClientSme {
626 iface_id: 0, sme_server: _, responder
627 }))) => {
628 assert!(responder.send(Ok(())).is_ok())
629 }
630 );
631
632 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
634
635 {
637 let iface_manager = test_values.iface_manager.clone();
638 let verify_fut = async move {
639 let iface_manager = iface_manager.lock().await;
640 assert_eq!(iface_manager.ifaces, vec![0]);
641 };
642 let mut verify_fut = pin!(verify_fut);
643 assert_matches!(exec.run_until_stalled(&mut verify_fut), Poll::Ready(()));
644 }
645
646 assert!(listener.legacy_shim.get().is_ok());
648 }
649
650 #[fuchsia::test]
651 fn test_handle_iface_added_fails_due_to_monitor_service() {
652 let mut exec = fasync::TestExecutor::new();
653 let test_values = test_setup(false, true);
654
655 let listener = Listener::new(
656 test_values.monitor_proxy,
657 IfaceRef::new(),
658 test_values.phy_manager.clone(),
659 test_values.iface_manager.clone(),
660 );
661
662 drop(test_values.monitor_stream);
665
666 let fut = handle_event(&listener, DeviceWatcherEvent::OnIfaceAdded { iface_id: 0 });
668 let mut fut = pin!(fut);
669 assert_matches!(exec.run_until_stalled(&mut fut), Poll::Ready(()));
670
671 {
673 let iface_manager = test_values.iface_manager.clone();
674 let verify_fut = async move {
675 let iface_manager = iface_manager.lock().await;
676 assert_eq!(iface_manager.ifaces, vec![0]);
677 };
678 let mut verify_fut = pin!(verify_fut);
679 assert_matches!(exec.run_until_stalled(&mut verify_fut), Poll::Ready(()));
680 }
681
682 assert!(listener.legacy_shim.get().is_err());
684 }
685
686 #[derive(Debug)]
687 struct FakePhyManager {
688 phys: Vec<u16>,
689 ifaces: Vec<u16>,
690 failed_phys: u32,
691 add_phy_succeeds: bool,
692 add_iface_succeeds: bool,
693 }
694
695 impl FakePhyManager {
696 fn new(add_phy_succeeds: bool, add_iface_succeeds: bool) -> Self {
697 FakePhyManager {
698 phys: Vec::new(),
699 ifaces: Vec::new(),
700 failed_phys: 0,
701 add_phy_succeeds,
702 add_iface_succeeds,
703 }
704 }
705 }
706
707 #[async_trait(?Send)]
708 impl PhyManagerApi for FakePhyManager {
709 async fn add_phy(&mut self, phy_id: u16) -> Result<(), PhyManagerError> {
710 if self.add_phy_succeeds {
711 self.phys.push(phy_id);
712 Ok(())
713 } else {
714 Err(PhyManagerError::PhyQueryFailure)
715 }
716 }
717
718 fn remove_phy(&mut self, phy_id: u16) {
719 self.phys.retain(|phy| *phy != phy_id)
720 }
721
722 async fn on_iface_added(&mut self, iface_id: u16) -> Result<(), PhyManagerError> {
723 if self.add_iface_succeeds {
724 self.ifaces.push(iface_id);
725 Ok(())
726 } else {
727 Err(PhyManagerError::IfaceQueryFailure)
728 }
729 }
730
731 fn on_iface_removed(&mut self, iface_id: u16) {
732 self.ifaces.retain(|iface| *iface != iface_id)
733 }
734
735 async fn create_all_client_ifaces(
736 &mut self,
737 _reason: CreateClientIfacesReason,
738 ) -> HashMap<u16, Result<Vec<u16>, PhyManagerError>> {
739 unimplemented!()
740 }
741
742 fn client_connections_enabled(&self) -> bool {
743 unimplemented!()
744 }
745
746 async fn destroy_all_client_ifaces(&mut self) -> Result<(), PhyManagerError> {
747 unimplemented!()
748 }
749
750 fn get_client(&mut self) -> Option<u16> {
751 unimplemented!();
752 }
753
754 async fn create_or_get_ap_iface(&mut self) -> Result<Option<u16>, PhyManagerError> {
755 unimplemented!();
756 }
757
758 async fn destroy_ap_iface(&mut self, _iface_id: u16) -> Result<(), PhyManagerError> {
759 unimplemented!();
760 }
761
762 async fn destroy_all_ap_ifaces(&mut self) -> Result<(), PhyManagerError> {
763 unimplemented!();
764 }
765
766 fn suggest_ap_mac(&mut self, _mac: MacAddr) {
767 unimplemented!()
768 }
769
770 fn get_phy_ids(&self) -> Vec<u16> {
771 unimplemented!()
772 }
773
774 fn log_phy_add_failure(&mut self) {
775 self.failed_phys += 1;
776 }
777
778 async fn set_country_code(
779 &mut self,
780 _country_code: Option<client_types::CountryCode>,
781 ) -> Result<(), PhyManagerError> {
782 unimplemented!();
783 }
784
785 fn record_defect(&mut self, _defect: Defect) {
786 unimplemented!();
787 }
788
789 async fn perform_recovery(&mut self, _summary: RecoverySummary) {
790 unimplemented!();
791 }
792 }
793
794 #[derive(Debug)]
795 struct FakeIfaceManager {
796 ifaces: Vec<u16>,
797 }
798
799 impl FakeIfaceManager {
800 fn new() -> Self {
801 FakeIfaceManager { ifaces: Vec::new() }
802 }
803 }
804
805 #[async_trait(?Send)]
806 impl IfaceManagerApi for FakeIfaceManager {
807 async fn disconnect(
808 &mut self,
809 _network_id: client_types::NetworkIdentifier,
810 _reason: client_types::DisconnectReason,
811 ) -> Result<(), Error> {
812 unimplemented!();
813 }
814
815 async fn connect(&mut self, _connect_req: ConnectAttemptRequest) -> Result<(), Error> {
816 unimplemented!();
817 }
818
819 async fn record_idle_client(&mut self, _iface_id: u16) -> Result<(), Error> {
820 unimplemented!();
821 }
822
823 async fn has_idle_client(&mut self) -> Result<bool, Error> {
824 unimplemented!();
825 }
826
827 async fn handle_added_iface(&mut self, iface_id: u16) -> Result<(), Error> {
828 self.ifaces.push(iface_id);
829 Ok(())
830 }
831
832 async fn handle_removed_iface(&mut self, iface_id: u16) -> Result<(), Error> {
833 self.ifaces.retain(|iface| *iface != iface_id);
834 Ok(())
835 }
836
837 async fn get_sme_proxy_for_scan(&mut self) -> Result<SmeForScan, Error> {
838 unimplemented!()
839 }
840
841 async fn stop_client_connections(
842 &mut self,
843 _reason: client_types::DisconnectReason,
844 ) -> Result<(), Error> {
845 unimplemented!()
846 }
847
848 async fn start_client_connections(&mut self) -> Result<(), Error> {
849 unimplemented!()
850 }
851
852 async fn start_ap(
853 &mut self,
854 _config: ap_fsm::ApConfig,
855 ) -> Result<oneshot::Receiver<()>, Error> {
856 unimplemented!();
857 }
858
859 async fn stop_ap(
860 &mut self,
861 _ssid: ap_types::Ssid,
862 _password: Vec<u8>,
863 ) -> Result<(), Error> {
864 unimplemented!();
865 }
866
867 async fn stop_all_aps(&mut self) -> Result<(), Error> {
868 unimplemented!()
869 }
870
871 async fn set_country(
872 &mut self,
873 _country_code: Option<client_types::CountryCode>,
874 ) -> Result<(), Error> {
875 unimplemented!();
876 }
877 }
878
879 #[track_caller]
880 fn send_query_iface_response(
881 exec: &mut fasync::TestExecutor,
882 server: &mut fidl_service::DeviceMonitorRequestStream,
883 iface_info: Option<fidl_service::QueryIfaceResponse>,
884 ) {
885 let response = iface_info.as_ref().ok_or(zx::sys::ZX_ERR_NOT_FOUND);
886 assert_matches!(
887 exec.run_until_stalled(&mut server.next()),
888 Poll::Ready(Some(Ok(
889 fidl_service::DeviceMonitorRequest::QueryIface {
890 iface_id: _,
891 responder,
892 }
893 ))) => {
894 responder.send(response).expect("sending fake iface info");
895 }
896 );
897 }
898}