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