1pub mod ap;
6pub mod client;
7
8use crate::{MlmeEventStream, MlmeStream, Station};
9use anyhow::format_err;
10use fidl::endpoints::ServerEnd;
11use fidl_fuchsia_wlan_common as fidl_common;
12use fidl_fuchsia_wlan_mlme as fidl_mlme;
13use fidl_fuchsia_wlan_sme as fidl_sme;
14use fuchsia_sync::Mutex;
15use futures::channel::mpsc;
16use futures::future::FutureObj;
17use futures::prelude::*;
18use futures::select;
19use futures::stream::FuturesUnordered;
20use log::{error, info, warn};
21use std::convert::Infallible;
22use std::pin::Pin;
23use std::sync::Arc;
24use wlan_common::timer::{self, ScheduledEvent};
25
26pub type ClientSmeServer = mpsc::UnboundedSender<client::Endpoint>;
27pub type ApSmeServer = mpsc::UnboundedSender<ap::Endpoint>;
28
29#[derive(Clone)]
30pub enum SmeServer {
31 Client(ClientSmeServer),
32 Ap(ApSmeServer),
33}
34
35async fn serve_generic_sme(
36 mut generic_sme_request_stream: <fidl_sme::GenericSmeMarker as fidl::endpoints::ProtocolMarker>::RequestStream,
37 mlme_sink: crate::MlmeSink,
38 mut sme_server_sender: SmeServer,
39 mut telemetry_server_sender: Option<
40 mpsc::UnboundedSender<fidl::endpoints::ServerEnd<fidl_sme::TelemetryMarker>>,
41 >,
42) -> Result<(), anyhow::Error> {
43 loop {
44 match generic_sme_request_stream.next().await {
45 Some(Ok(req)) => {
46 let result = match req {
47 fidl_sme::GenericSmeRequest::Query { responder } => {
48 let (info_responder, info_receiver) = crate::responder::Responder::new();
49 mlme_sink.send(crate::MlmeRequest::QueryDeviceInfo(info_responder));
50 match info_receiver.await {
51 Ok(info) => responder.send(&fidl_sme::GenericSmeQuery {
52 role: info.role,
53 sta_addr: info.sta_addr,
54 factory_addr: info.factory_addr,
55 }),
56 Err(e) => {
57 error!("Failed to query device info: {}", e);
58 Ok(())
59 }
60 }
61 }
62 fidl_sme::GenericSmeRequest::QueryIfaceCapabilities { responder } => {
63 let (apf_responder, apf_receiver) = crate::responder::Responder::new();
64 mlme_sink
65 .send(crate::MlmeRequest::QueryApfPacketFilterSupport(apf_responder));
66 let (rssi_responder, rssi_receiver) = crate::responder::Responder::new();
67 mlme_sink.send(crate::MlmeRequest::QueryRssiMonitorSupport(rssi_responder));
68
69 let apf_support = apf_receiver.await.map(|res| match res {
70 Ok(apf) => Ok(apf),
71 Err(zx::sys::ZX_ERR_NOT_SUPPORTED) => {
72 Ok(fidl_common::ApfPacketFilterSupport {
73 supported: Some(false),
74 ..Default::default()
75 })
76 }
77 Err(e) => Err(e),
78 });
79 let rssi_support = rssi_receiver.await.map(|res| match res {
80 Ok(rssi) => Ok(rssi),
81 Err(zx::sys::ZX_ERR_NOT_SUPPORTED) => {
82 Ok(fidl_common::RssiMonitorSupport {
83 supported: Some(false),
84 ..Default::default()
85 })
86 }
87 Err(e) => Err(e),
88 });
89
90 match (apf_support, rssi_support) {
91 (Ok(Ok(apf)), Ok(Ok(rssi))) => {
92 let resp = fidl_sme::GenericSmeQueryIfaceCapabilitiesResponse {
93 apf_support: Some(apf),
94 rssi_monitor_support: Some(rssi),
95 ..Default::default()
96 };
97 responder.send(Ok(&resp))
98 }
99 (Ok(Err(e)), _) | (_, Ok(Err(e))) => responder.send(Err(e)),
100 (Err(e), _) | (_, Err(e)) => {
101 error!("Failed to query device capabilities: {}", e);
102 responder.send(Err(zx::Status::INTERNAL.into_raw()))
103 }
104 }
105 }
106 fidl_sme::GenericSmeRequest::GetClientSme { sme_server, responder } => {
107 let response =
108 if let SmeServer::Client(server_sender) = &mut sme_server_sender {
109 server_sender
110 .send(sme_server)
111 .await
112 .map_err(|_| zx::Status::PEER_CLOSED.into_raw())
113 } else {
114 Err(zx::Status::NOT_SUPPORTED.into_raw())
115 };
116 responder.send(response)
117 }
118 fidl_sme::GenericSmeRequest::GetApSme { sme_server, responder } => {
119 let response = if let SmeServer::Ap(server_sender) = &mut sme_server_sender
120 {
121 server_sender
122 .send(sme_server)
123 .await
124 .map_err(|_| zx::Status::PEER_CLOSED.into_raw())
125 } else {
126 Err(zx::Status::NOT_SUPPORTED.into_raw())
127 };
128 responder.send(response)
129 }
130 fidl_sme::GenericSmeRequest::GetSmeTelemetry {
131 telemetry_server,
132 responder,
133 } => {
134 let response = if let Some(server) = telemetry_server_sender.as_mut() {
135 server
136 .send(telemetry_server)
137 .await
138 .map_err(|_| zx::Status::PEER_CLOSED.into_raw())
139 } else {
140 warn!("Requested unsupported SME telemetry API");
141 Err(zx::Status::NOT_SUPPORTED.into_raw())
142 };
143 responder.send(response)
144 }
145 };
146 if let Err(e) = result {
147 error!("Failed to respond to SME handle request: {}", e);
148 }
149 }
150 Some(Err(e)) => {
151 return Err(format_err!("Generic SME request stream failed: {}", e));
152 }
153 None => {
154 info!("Generic SME request stream terminated. Shutting down.");
155 return Ok(());
156 }
157 }
158 }
159}
160
161#[allow(
162 clippy::too_many_arguments,
163 clippy::type_complexity,
164 reason = "mass allow for https://fxbug.dev/381896734"
165)]
166pub fn create_sme(
167 cfg: crate::Config,
168 mlme_event_stream: MlmeEventStream,
169 device_info: &fidl_mlme::DeviceInfo,
170 security_support: fidl_common::SecuritySupport,
171 spectrum_management_support: fidl_common::SpectrumManagementSupport,
172 inspector: fuchsia_inspect::Inspector,
173 generic_sme_request_stream: <fidl_sme::GenericSmeMarker as fidl::endpoints::ProtocolMarker>::RequestStream,
174 power_manager: Arc<dyn wlan_power_manager::SyncPowerManager>,
175) -> Result<
176 (MlmeStream, Pin<Box<impl Future<Output = Result<(), anyhow::Error>> + use<>>>),
177 anyhow::Error,
178> {
179 let device_info = device_info.clone();
180 let inspect_node = inspector.root().create_child("usme");
181 let (server, mlme_req_sink, mlme_req_stream, telemetry_sender, sme_fut) = match device_info.role
182 {
183 fidl_common::WlanMacRole::Client => {
184 let (telemetry_endpoint_sender, telemetry_endpoint_receiver) = mpsc::unbounded();
185 let (sender, receiver) = mpsc::unbounded();
186 let (mlme_req_sink, mlme_req_stream, fut) = client::serve(
187 cfg,
188 device_info,
189 security_support,
190 spectrum_management_support,
191 mlme_event_stream,
192 receiver,
193 telemetry_endpoint_receiver,
194 inspector,
195 inspect_node,
196 power_manager,
197 );
198 (
199 SmeServer::Client(sender),
200 mlme_req_sink,
201 mlme_req_stream,
202 Some(telemetry_endpoint_sender),
203 FutureObj::new(Box::new(fut)),
204 )
205 }
206 fidl_common::WlanMacRole::Ap => {
207 let (sender, receiver) = mpsc::unbounded();
208 let (mlme_req_sink, mlme_req_stream, fut) =
209 ap::serve(device_info, spectrum_management_support, mlme_event_stream, receiver);
210 (
211 SmeServer::Ap(sender),
212 mlme_req_sink,
213 mlme_req_stream,
214 None,
215 FutureObj::new(Box::new(fut)),
216 )
217 }
218 fidl_common::WlanMacRole::Mesh => {
219 return Err(format_err!("Mesh mode is unsupported"));
220 }
221 fidl_common::WlanMacRoleUnknown!() => {
222 return Err(format_err!("Unknown WlanMacRole type: {:?}", device_info.role));
223 }
224 };
225 let generic_sme_fut =
226 serve_generic_sme(generic_sme_request_stream, mlme_req_sink, server, telemetry_sender);
227 let unified_fut = async move {
228 select! {
229 sme_fut = sme_fut.fuse() => sme_fut,
230 generic_sme_fut = generic_sme_fut.fuse() => generic_sme_fut,
231 }
232 };
233 Ok((mlme_req_stream, Box::pin(unified_fut)))
234}
235
236async fn serve_mlme_sme<STA, TS>(
238 mut event_stream: MlmeEventStream,
239 station: Arc<Mutex<STA>>,
240 time_stream: TS,
241) -> Result<(), anyhow::Error>
242where
243 STA: Station,
244 TS: Stream<Item = ScheduledEvent<<STA as crate::Station>::Event>> + Unpin,
245{
246 let mut timeout_stream = timer::make_async_timed_event_stream(time_stream).fuse();
247
248 loop {
249 select! {
250 mlme_event = event_stream.next() => match mlme_event {
254 Some(mlme_event) => station.lock().on_mlme_event(mlme_event),
255 None => return Ok(()),
256 },
257 timeout = timeout_stream.next() => match timeout {
258 Some(timed_event) => station.lock().on_timeout(timed_event),
259 None => return Err(format_err!("SME timer stream has ended unexpectedly")),
260 },
261 }
262 }
263}
264
265#[allow(clippy::extra_unused_lifetimes, reason = "mass allow for https://fxbug.dev/381896734")]
266async fn serve_fidl<
267 'a,
268 C: Clone,
269 T: fidl::endpoints::ProtocolMarker,
270 Fut: futures::Future<Output = Result<(), fidl::Error>>,
271>(
272 context: C,
273 new_fidl_clients: mpsc::UnboundedReceiver<ServerEnd<T>>,
274 event_handler: impl Fn(C, fidl::endpoints::Request<T>) -> Fut + Copy,
275) -> Result<Infallible, anyhow::Error> {
276 let mut new_fidl_clients = new_fidl_clients.fuse();
277 let mut fidl_clients = FuturesUnordered::new();
278 loop {
279 select! {
280 new_fidl_client = new_fidl_clients.next() => match new_fidl_client {
281 Some(end) => fidl_clients.push(serve_fidl_endpoint(context.clone(), end, event_handler)),
282 None => return Err(format_err!("New FIDL client stream unexpectedly ended")),
283 },
284 () = fidl_clients.select_next_some() => {},
285 }
286 }
287}
288
289#[allow(
290 clippy::extra_unused_lifetimes,
291 clippy::needless_return,
292 reason = "mass allow for https://fxbug.dev/381896734"
293)]
294async fn serve_fidl_endpoint<
295 'a,
296 C: Clone,
297 T: fidl::endpoints::ProtocolMarker,
298 Fut: futures::Future<Output = Result<(), fidl::Error>>,
299>(
300 context: C,
301 endpoint: ServerEnd<T>,
302 event_handler: impl Fn(C, fidl::endpoints::Request<T>) -> Fut + Copy,
303) {
304 let stream = endpoint.into_stream();
305 const MAX_CONCURRENT_REQUESTS: usize = 1000;
306 let handler = &event_handler;
307 let r = stream
308 .try_for_each_concurrent(MAX_CONCURRENT_REQUESTS, move |request| {
309 (*handler)(context.clone(), request)
310 })
311 .await;
312 if let Err(e) = r {
313 error!("Error serving FIDL: {}", e);
314 return;
315 }
316}
317
318#[cfg(test)]
319mod tests {
320 use super::*;
321 use crate::test_utils;
322 use assert_matches::assert_matches;
323 use fidl::endpoints::{create_proxy, create_proxy_and_stream};
324 use fuchsia_async as fasync;
325 use fuchsia_inspect::Inspector;
326 use futures::task::Poll;
327 use std::pin::pin;
328 use test_case::test_case;
329 use wlan_common::test_utils::fake_features::{
330 fake_security_support, fake_spectrum_management_support_empty,
331 };
332
333 #[test]
334 fn create_sme_fails_startup_role_unknown() {
335 let mut _exec = fasync::TestExecutor::new();
336 let inspector = Inspector::default();
337 let (_mlme_event_sender, mlme_event_stream) = mpsc::unbounded();
338 let (_generic_sme_proxy, generic_sme_stream) =
339 create_proxy_and_stream::<fidl_sme::GenericSmeMarker>();
340 let device_info = fidl_mlme::DeviceInfo {
341 role: fidl_common::WlanMacRole::unknown(),
342 ..test_utils::fake_device_info([0; 6].into())
343 };
344 let result = create_sme(
345 crate::Config::default(),
346 mlme_event_stream,
347 &device_info,
348 fake_security_support(),
349 fake_spectrum_management_support_empty(),
350 inspector,
351 generic_sme_stream,
352 Arc::new(()),
353 );
354
355 assert!(result.is_err());
356 }
357
358 #[test]
359 fn sme_shutdown_on_generic_sme_closed() {
360 let mut exec = fasync::TestExecutor::new();
361 let (_mlme_event_sender, mlme_event_stream) = mpsc::unbounded();
362 let inspector = Inspector::default();
363 let (generic_sme_proxy, generic_sme_stream) =
364 create_proxy_and_stream::<fidl_sme::GenericSmeMarker>();
365 let (_mlme_req_stream, serve_fut) = create_sme(
366 crate::Config::default(),
367 mlme_event_stream,
368 &test_utils::fake_device_info([0; 6].into()),
369 fake_security_support(),
370 fake_spectrum_management_support_empty(),
371 inspector,
372 generic_sme_stream,
373 Arc::new(()),
374 )
375 .unwrap();
376 let mut serve_fut = pin!(serve_fut);
377 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
378
379 drop(generic_sme_proxy);
381
382 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Ready(Ok(())));
384 }
385
386 struct GenericSmeTestHelper {
387 proxy: fidl_sme::GenericSmeProxy,
388 mlme_req_stream: MlmeStream,
389
390 _inspector: Inspector,
393 _mlme_event_sender: mpsc::UnboundedSender<crate::MlmeEvent>,
394 exec: fasync::TestExecutor,
396 }
397
398 #[allow(clippy::type_complexity, reason = "mass allow for https://fxbug.dev/381896734")]
399 fn start_generic_sme_test(
400 role: fidl_common::WlanMacRole,
401 ) -> Result<
402 (GenericSmeTestHelper, Pin<Box<impl Future<Output = Result<(), anyhow::Error>>>>),
403 anyhow::Error,
404 > {
405 let mut exec = fasync::TestExecutor::new();
406 let inspector = Inspector::default();
407 let (mlme_event_sender, mlme_event_stream) = mpsc::unbounded();
408 let (generic_sme_proxy, generic_sme_stream) =
409 create_proxy_and_stream::<fidl_sme::GenericSmeMarker>();
410 let device_info =
411 fidl_mlme::DeviceInfo { role, ..test_utils::fake_device_info([0; 6].into()) };
412 let (mlme_req_stream, serve_fut) = create_sme(
413 crate::Config::default(),
414 mlme_event_stream,
415 &device_info,
416 fake_security_support(),
417 fake_spectrum_management_support_empty(),
418 inspector.clone(),
419 generic_sme_stream,
420 Arc::new(()),
421 )?;
422 let mut serve_fut = Box::pin(serve_fut);
423 assert_matches!(exec.run_until_stalled(&mut serve_fut), Poll::Pending);
424
425 Ok((
426 GenericSmeTestHelper {
427 proxy: generic_sme_proxy,
428 mlme_req_stream,
429 _inspector: inspector,
430 _mlme_event_sender: mlme_event_sender,
431 exec,
432 },
433 serve_fut,
434 ))
435 }
436
437 #[test]
438 fn generic_sme_get_client() {
439 let (mut helper, mut serve_fut) =
440 start_generic_sme_test(fidl_common::WlanMacRole::Client).unwrap();
441
442 let (client_proxy, client_server) = create_proxy();
443 let mut client_sme_fut = helper.proxy.get_client_sme(client_server);
444 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
445 assert_matches!(
446 helper.exec.run_until_stalled(&mut client_sme_fut),
447 Poll::Ready(Ok(Ok(())))
448 );
449
450 let mut status_fut = client_proxy.status();
451 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
452 assert_matches!(
453 helper.exec.run_until_stalled(&mut status_fut),
454 Poll::Ready(Ok(fidl_sme::ClientStatusResponse::Idle(_)))
455 );
456 }
457
458 #[test]
459 fn generic_sme_get_ap_from_client_fails() {
460 let (mut helper, mut serve_fut) =
461 start_generic_sme_test(fidl_common::WlanMacRole::Client).unwrap();
462
463 let (_ap_proxy, ap_server) = create_proxy();
464 let mut client_sme_fut = helper.proxy.get_ap_sme(ap_server);
465 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
466 assert_matches!(
467 helper.exec.run_until_stalled(&mut client_sme_fut),
468 Poll::Ready(Ok(Err(_)))
469 );
470 }
471
472 #[test]
473 fn generic_sme_get_ap() {
474 let (mut helper, mut serve_fut) =
475 start_generic_sme_test(fidl_common::WlanMacRole::Ap).unwrap();
476
477 let (ap_proxy, ap_server) = create_proxy();
478 let mut ap_sme_fut = helper.proxy.get_ap_sme(ap_server);
479 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
480 assert_matches!(helper.exec.run_until_stalled(&mut ap_sme_fut), Poll::Ready(Ok(Ok(()))));
481
482 let mut status_fut = ap_proxy.status();
483 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
484 assert_matches!(
485 helper.exec.run_until_stalled(&mut status_fut),
486 Poll::Ready(Ok(fidl_sme::ApStatusResponse { .. }))
487 );
488 }
489
490 #[test]
491 fn generic_sme_get_client_from_ap_fails() {
492 let (mut helper, mut serve_fut) =
493 start_generic_sme_test(fidl_common::WlanMacRole::Ap).unwrap();
494
495 let (_client_proxy, client_server) = create_proxy();
496 let mut client_sme_fut = helper.proxy.get_client_sme(client_server);
497 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
498 assert_matches!(
499 helper.exec.run_until_stalled(&mut client_sme_fut),
500 Poll::Ready(Ok(Err(_)))
501 );
502 }
503
504 fn get_telemetry_proxy(
505 helper: &mut GenericSmeTestHelper,
506 serve_fut: &mut Pin<Box<impl Future<Output = Result<(), anyhow::Error>>>>,
507 ) -> fidl_sme::TelemetryProxy {
508 let (proxy, server) = create_proxy();
509 let mut telemetry_fut = helper.proxy.get_sme_telemetry(server);
510 assert_matches!(helper.exec.run_until_stalled(serve_fut), Poll::Pending);
511 assert_matches!(helper.exec.run_until_stalled(&mut telemetry_fut), Poll::Ready(Ok(Ok(()))));
512 proxy
513 }
514
515 #[test]
516 fn generic_sme_query_telemetry_support_for_client() {
517 let (mut helper, mut serve_fut) =
518 start_generic_sme_test(fidl_common::WlanMacRole::Client).unwrap();
519 let telemetry_proxy = get_telemetry_proxy(&mut helper, &mut serve_fut);
520
521 let mut support_fut = telemetry_proxy.query_telemetry_support();
523 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
524
525 let support_req = assert_matches!(helper.exec.run_until_stalled(&mut helper.mlme_req_stream.next()), Poll::Ready(Some(req)) => req);
527 let support_responder = assert_matches!(support_req, crate::MlmeRequest::QueryTelemetrySupport(responder) => responder);
528 support_responder.respond(Err(1337));
529
530 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
532 let support_result = assert_matches!(helper.exec.run_until_stalled(&mut support_fut), Poll::Ready(Ok(support_result)) => support_result);
533 assert_eq!(support_result, Err(1337));
534 }
535
536 #[test]
537 fn generic_sme_get_histogram_stats_for_client() {
538 let (mut helper, mut serve_fut) =
539 start_generic_sme_test(fidl_common::WlanMacRole::Client).unwrap();
540 let telemetry_proxy = get_telemetry_proxy(&mut helper, &mut serve_fut);
541
542 let mut histogram_fut = telemetry_proxy.get_histogram_stats();
544 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
545
546 let histogram_req = assert_matches!(helper.exec.run_until_stalled(&mut helper.mlme_req_stream.next()), Poll::Ready(Some(req)) => req);
548 let histogram_responder = assert_matches!(histogram_req, crate::MlmeRequest::GetIfaceHistogramStats(responder) => responder);
549 histogram_responder.respond(fidl_mlme::GetIfaceHistogramStatsResponse::ErrorStatus(1337));
550
551 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
553 let histogram_result = assert_matches!(helper.exec.run_until_stalled(&mut histogram_fut), Poll::Ready(Ok(histogram_result)) => histogram_result);
554 assert_eq!(histogram_result, Err(1337));
555 }
556
557 #[test]
558 fn generic_sme_get_iface_stats_for_client() {
559 let (mut helper, mut serve_fut) =
560 start_generic_sme_test(fidl_common::WlanMacRole::Client).unwrap();
561 let telemetry_proxy = get_telemetry_proxy(&mut helper, &mut serve_fut);
562
563 let mut counter_fut = telemetry_proxy.get_iface_stats();
565 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
566
567 let counter_req = assert_matches!(helper.exec.run_until_stalled(&mut helper.mlme_req_stream.next()), Poll::Ready(Some(req)) => req);
569 let counter_responder =
570 assert_matches!(counter_req, crate::MlmeRequest::GetIfaceStats(responder) => responder);
571 counter_responder.respond(fidl_mlme::GetIfaceStatsResponse::ErrorStatus(1337));
572
573 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
575 let counter_result = assert_matches!(helper.exec.run_until_stalled(&mut counter_fut), Poll::Ready(Ok(counter_result)) => counter_result);
576 assert_eq!(counter_result, Err(1337));
577 }
578
579 #[test]
580 fn generic_sme_get_signal_report_for_client() {
581 let (mut helper, mut serve_fut) =
582 start_generic_sme_test(fidl_common::WlanMacRole::Client).unwrap();
583 let telemetry_proxy = get_telemetry_proxy(&mut helper, &mut serve_fut);
584
585 let mut report_fut = telemetry_proxy.get_signal_report();
587 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
588
589 let report_req = assert_matches!(helper.exec.run_until_stalled(&mut helper.mlme_req_stream.next()), Poll::Ready(Some(req)) => req);
591 let report_responder = assert_matches!(report_req, crate::MlmeRequest::GetSignalReport(responder) => responder);
592 report_responder.respond(Err(1337));
593
594 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
596 let report_result = assert_matches!(helper.exec.run_until_stalled(&mut report_fut), Poll::Ready(Ok(report_result)) => report_result);
597 assert_eq!(report_result, Err(1337));
598 }
599
600 #[test]
601 fn generic_sme_get_telemetry_for_ap_fails() {
602 let (mut helper, mut serve_fut) =
603 start_generic_sme_test(fidl_common::WlanMacRole::Ap).unwrap();
604
605 let (_telemetry_proxy, telemetry_server) = create_proxy();
606 let mut telemetry_fut = helper.proxy.get_sme_telemetry(telemetry_server);
607 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
608 assert_matches!(helper.exec.run_until_stalled(&mut telemetry_fut), Poll::Ready(Ok(Err(_))));
609 }
610
611 #[test_case(fidl_common::WlanMacRole::Client)]
612 #[test_case(fidl_common::WlanMacRole::Ap)]
613 fn generic_sme_query(mac_role: fidl_common::WlanMacRole) {
614 let (mut helper, mut serve_fut) = start_generic_sme_test(mac_role).unwrap();
615
616 let mut query_fut = helper.proxy.query();
617 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
618
619 let query_req = assert_matches!(helper.exec.run_until_stalled(&mut helper.mlme_req_stream.next()), Poll::Ready(Some(req)) => req);
620 let query_responder =
621 assert_matches!(query_req, crate::MlmeRequest::QueryDeviceInfo(responder) => responder);
622 query_responder.respond(fidl_mlme::DeviceInfo {
623 role: mac_role,
624 sta_addr: [2; 6],
625 factory_addr: [2; 6],
626 bands: vec![],
627 softmac_hardware_capability: 0,
628 qos_capable: false,
629 });
630
631 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
632 let query_result = assert_matches!(helper.exec.run_until_stalled(&mut query_fut), Poll::Ready(Ok(result)) => result);
633 assert_eq!(query_result.role, mac_role);
634 assert_eq!(query_result.sta_addr, [2; 6]);
635 }
636
637 #[test]
638 fn generic_sme_query_iface_capabilities() {
639 let (mut helper, mut serve_fut) =
640 start_generic_sme_test(fidl_common::WlanMacRole::Client).unwrap();
641
642 let mut query_fut = helper.proxy.query_iface_capabilities();
643 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
644
645 let apf_req = assert_matches!(helper.exec.run_until_stalled(&mut helper.mlme_req_stream.next()), Poll::Ready(Some(req)) => req);
646 let apf_responder = assert_matches!(apf_req, crate::MlmeRequest::QueryApfPacketFilterSupport(responder) => responder);
647 let apf_support = fidl_common::ApfPacketFilterSupport {
648 supported: Some(true),
649 version: Some(1),
650 max_filter_length: Some(1024),
651 ..Default::default()
652 };
653 apf_responder.respond(Ok(apf_support.clone()));
654 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
655
656 let rssi_req = assert_matches!(helper.exec.run_until_stalled(&mut helper.mlme_req_stream.next()), Poll::Ready(Some(req)) => req);
657 let rssi_responder = assert_matches!(rssi_req, crate::MlmeRequest::QueryRssiMonitorSupport(responder) => responder);
658 let rssi_support =
659 fidl_common::RssiMonitorSupport { supported: Some(true), ..Default::default() };
660 rssi_responder.respond(Ok(rssi_support.clone()));
661
662 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
663 let query_result = assert_matches!(helper.exec.run_until_stalled(&mut query_fut), Poll::Ready(Ok(result)) => result);
664 assert_eq!(
665 query_result,
666 Ok(fidl_sme::GenericSmeQueryIfaceCapabilitiesResponse {
667 apf_support: Some(apf_support),
668 rssi_monitor_support: Some(rssi_support),
669 ..Default::default()
670 })
671 );
672 }
673
674 #[test]
675 fn generic_sme_query_iface_capabilities_not_supported_maps_to_false() {
676 let (mut helper, mut serve_fut) =
677 start_generic_sme_test(fidl_common::WlanMacRole::Client).unwrap();
678
679 let mut query_fut = helper.proxy.query_iface_capabilities();
680 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
681
682 let apf_req = assert_matches!(helper.exec.run_until_stalled(&mut helper.mlme_req_stream.next()), Poll::Ready(Some(req)) => req);
683 let apf_responder = assert_matches!(apf_req, crate::MlmeRequest::QueryApfPacketFilterSupport(responder) => responder);
684 let apf_support = fidl_common::ApfPacketFilterSupport {
685 supported: Some(true),
686 version: Some(1),
687 max_filter_length: Some(1024),
688 ..Default::default()
689 };
690 apf_responder.respond(Ok(apf_support.clone()));
691 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
692
693 let rssi_req = assert_matches!(helper.exec.run_until_stalled(&mut helper.mlme_req_stream.next()), Poll::Ready(Some(req)) => req);
694 let rssi_responder = assert_matches!(rssi_req, crate::MlmeRequest::QueryRssiMonitorSupport(responder) => responder);
695 rssi_responder.respond(Err(zx::sys::ZX_ERR_NOT_SUPPORTED));
696
697 assert_matches!(helper.exec.run_until_stalled(&mut serve_fut), Poll::Pending);
698 let query_result = assert_matches!(helper.exec.run_until_stalled(&mut query_fut), Poll::Ready(Ok(result)) => result);
699 assert_eq!(
700 query_result,
701 Ok(fidl_sme::GenericSmeQueryIfaceCapabilitiesResponse {
702 apf_support: Some(apf_support),
703 rssi_monitor_support: Some(fidl_common::RssiMonitorSupport {
704 supported: Some(false),
705 ..Default::default()
706 }),
707 ..Default::default()
708 })
709 );
710 }
711}