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