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