1use anyhow::{Context, format_err};
6use fidl::endpoints::ClientEnd;
7use fidl_fuchsia_wlan_common as fidl_common;
8use fidl_fuchsia_wlan_fullmac as fidl_fullmac;
9use fidl_fuchsia_wlan_mlme as fidl_mlme;
10use fidl_fuchsia_wlan_stats as fidl_stats;
11
12pub trait DeviceOps {
16 fn init(
17 &mut self,
18 fullmac_ifc_client_end: ClientEnd<fidl_fullmac::WlanFullmacImplIfcMarker>,
19 ) -> Result<fidl::Channel, zx::Status>;
20 fn query_device_info(&self) -> anyhow::Result<fidl_fullmac::WlanFullmacImplQueryResponse>;
21 fn query_security_support(&self) -> anyhow::Result<fidl_common::SecuritySupport>;
22 fn query_spectrum_management_support(
23 &self,
24 ) -> anyhow::Result<fidl_common::SpectrumManagementSupport>;
25 fn query_telemetry_support(&self) -> anyhow::Result<Result<fidl_stats::TelemetrySupport, i32>>;
26 fn query_apf_packet_filter_support(
27 &self,
28 ) -> anyhow::Result<Result<fidl_common::ApfPacketFilterSupport, i32>>;
29 fn query_rssi_monitor_support(
30 &self,
31 ) -> anyhow::Result<Result<fidl_common::RssiMonitorSupport, i32>>;
32 fn start_scan(&self, req: fidl_fullmac::WlanFullmacImplStartScanRequest) -> anyhow::Result<()>;
33 fn connect(&self, req: fidl_fullmac::WlanFullmacImplConnectRequest) -> anyhow::Result<()>;
34 fn reconnect(&self, req: fidl_fullmac::WlanFullmacImplReconnectRequest) -> anyhow::Result<()>;
35 fn roam(&self, req: fidl_fullmac::WlanFullmacImplRoamRequest) -> anyhow::Result<()>;
36 fn auth_resp(&self, resp: fidl_fullmac::WlanFullmacImplAuthRespRequest) -> anyhow::Result<()>;
37 fn deauth(&self, req: fidl_fullmac::WlanFullmacImplDeauthRequest) -> anyhow::Result<()>;
38 fn assoc_resp(&self, resp: fidl_fullmac::WlanFullmacImplAssocRespRequest)
39 -> anyhow::Result<()>;
40 fn disassoc(&self, req: fidl_fullmac::WlanFullmacImplDisassocRequest) -> anyhow::Result<()>;
41 fn start_bss(&self, req: fidl_fullmac::WlanFullmacImplStartBssRequest) -> anyhow::Result<()>;
42 fn stop_bss(&self, req: fidl_fullmac::WlanFullmacImplStopBssRequest) -> anyhow::Result<()>;
43 fn set_keys(
44 &self,
45 req: fidl_fullmac::WlanFullmacImplSetKeysRequest,
46 ) -> anyhow::Result<fidl_fullmac::WlanFullmacSetKeysResp>;
47 fn eapol_tx(&self, req: fidl_fullmac::WlanFullmacImplEapolTxRequest) -> anyhow::Result<()>;
48 fn get_iface_stats(&self) -> anyhow::Result<fidl_mlme::GetIfaceStatsResponse>;
49 fn get_iface_histogram_stats(
50 &self,
51 ) -> anyhow::Result<fidl_mlme::GetIfaceHistogramStatsResponse>;
52 fn get_signal_report(&self) -> anyhow::Result<Result<fidl_stats::SignalReport, i32>>;
53 fn sae_handshake_resp(
54 &self,
55 resp: fidl_fullmac::WlanFullmacImplSaeHandshakeRespRequest,
56 ) -> anyhow::Result<()>;
57 fn sae_frame_tx(&self, frame: fidl_fullmac::SaeFrame) -> anyhow::Result<()>;
58 fn wmm_status_req(&self) -> anyhow::Result<()>;
59 fn on_link_state_changed(
60 &self,
61 req: fidl_fullmac::WlanFullmacImplOnLinkStateChangedRequest,
62 ) -> anyhow::Result<()>;
63 fn set_mac_address(
64 &self,
65 req: fidl_fullmac::WlanFullmacImplSetMacAddressRequest,
66 ) -> anyhow::Result<Result<(), i32>>;
67 fn install_apf_packet_filter(
68 &self,
69 req: fidl_fullmac::WlanFullmacImplInstallApfPacketFilterRequest,
70 ) -> anyhow::Result<Result<(), i32>>;
71 fn read_apf_packet_filter_data(
72 &self,
73 ) -> anyhow::Result<Result<fidl_fullmac::WlanFullmacImplReadApfPacketFilterDataResponse, i32>>;
74 fn set_apf_packet_filter_enabled(
75 &self,
76 req: fidl_fullmac::WlanFullmacImplSetApfPacketFilterEnabledRequest,
77 ) -> anyhow::Result<Result<(), i32>>;
78 fn get_apf_packet_filter_enabled(
79 &self,
80 ) -> anyhow::Result<Result<fidl_fullmac::WlanFullmacImplGetApfPacketFilterEnabledResponse, i32>>;
81 fn start_scheduled_scan(
82 &self,
83 req: fidl_fullmac::WlanFullmacImplStartScheduledScanRequest,
84 ) -> anyhow::Result<Result<(), i32>>;
85 fn stop_scheduled_scan(
86 &self,
87 req: fidl_fullmac::WlanFullmacImplStopScheduledScanRequest,
88 ) -> anyhow::Result<Result<(), i32>>;
89 fn get_scheduled_scan_enabled(
90 &self,
91 ) -> anyhow::Result<Result<fidl_fullmac::WlanFullmacImplGetScheduledScanEnabledResponse, i32>>;
92 fn start_rssi_monitor(
93 &self,
94 req: fidl_fullmac::WlanFullmacImplStartRssiMonitorRequest,
95 ) -> anyhow::Result<Result<(), i32>>;
96 fn stop_rssi_monitor(&self) -> anyhow::Result<Result<(), i32>>;
97}
98
99pub struct FullmacDevice {
100 fullmac_impl_sync_proxy: fidl_fullmac::WlanFullmacImpl_SynchronousProxy,
101}
102
103impl FullmacDevice {
106 pub fn new(
107 fullmac_impl_sync_proxy: fidl_fullmac::WlanFullmacImpl_SynchronousProxy,
108 ) -> FullmacDevice {
109 FullmacDevice { fullmac_impl_sync_proxy }
110 }
111}
112
113impl DeviceOps for FullmacDevice {
114 fn init(
115 &mut self,
116 fullmac_ifc_client_end: ClientEnd<fidl_fullmac::WlanFullmacImplIfcMarker>,
117 ) -> Result<fidl::Channel, zx::Status> {
118 let req = fidl_fullmac::WlanFullmacImplInitRequest {
119 ifc: Some(fullmac_ifc_client_end),
120 ..Default::default()
121 };
122 let resp = self
123 .fullmac_impl_sync_proxy
124 .init(req, zx::MonotonicInstant::INFINITE)
125 .map_err(|e| {
126 log::error!("FIDL error on Start: {}", e);
127 zx::Status::INTERNAL
128 })?
129 .map_err(zx::Status::err_from_raw)?;
130
131 resp.sme_channel.ok_or(zx::Status::INVALID_ARGS)
132 }
133
134 fn query_device_info(&self) -> anyhow::Result<fidl_fullmac::WlanFullmacImplQueryResponse> {
135 self.fullmac_impl_sync_proxy
136 .query(zx::MonotonicInstant::INFINITE)
137 .context("FIDL error on QueryDeviceInfo")?
138 .map_err(|e| format_err!("Driver returned error on QueryDeviceInfo: {}", e))
139 }
140
141 fn query_security_support(&self) -> anyhow::Result<fidl_common::SecuritySupport> {
142 self.fullmac_impl_sync_proxy
143 .query_security_support(zx::MonotonicInstant::INFINITE)
144 .context("FIDL error on QuerySecuritySupport")?
145 .map_err(|e| format_err!("Driver returned error on QuerySecuritySupport: {}", e))
146 .and_then(|support| {
147 support.resp.ok_or_else(|| {
148 format_err!("Driver returned empty QuerySecuritySupport response")
149 })
150 })
151 }
152
153 fn query_spectrum_management_support(
154 &self,
155 ) -> anyhow::Result<fidl_common::SpectrumManagementSupport> {
156 self.fullmac_impl_sync_proxy
157 .query_spectrum_management_support(zx::MonotonicInstant::INFINITE)
158 .context("FIDL error on QuerySpectrumManagementSupport")?
159 .map_err(|e| {
160 format_err!("Driver returned error on QuerySpectrumManagementSupport: {}", e)
161 })
162 .and_then(|support| {
163 support.resp.ok_or_else(|| {
164 format_err!("Driver returned empty QuerySpectrumManagementSupport response")
165 })
166 })
167 }
168
169 fn query_telemetry_support(&self) -> anyhow::Result<Result<fidl_stats::TelemetrySupport, i32>> {
170 self.fullmac_impl_sync_proxy
171 .query_telemetry_support(zx::MonotonicInstant::INFINITE)
172 .context("FIDL error on QueryTelemetrySupport")
173 .and_then(|support| match support {
174 Ok(response) => response
175 .resp
176 .ok_or_else(|| {
177 format_err!("Driver returned empty QueryTelemetrySupport response")
178 })
179 .map(Ok),
180 Err(e) => Ok(Err(e)),
181 })
182 }
183
184 fn query_apf_packet_filter_support(
185 &self,
186 ) -> anyhow::Result<Result<fidl_common::ApfPacketFilterSupport, i32>> {
187 self.fullmac_impl_sync_proxy
188 .query_apf_packet_filter_support(zx::MonotonicInstant::INFINITE)
189 .context("FIDL error on QueryApfPacketFilterSupport")
190 .and_then(|support| match support {
191 Ok(response) => response
192 .resp
193 .ok_or_else(|| {
194 format_err!("Driver returned empty QueryApfPacketFilterSupport response")
195 })
196 .map(Ok),
197 Err(e) => Ok(Err(e)),
198 })
199 }
200
201 fn query_rssi_monitor_support(
202 &self,
203 ) -> anyhow::Result<Result<fidl_common::RssiMonitorSupport, i32>> {
204 self.fullmac_impl_sync_proxy
205 .query_rssi_monitor_support(zx::MonotonicInstant::INFINITE)
206 .context("FIDL error on QueryRssiMonitorSupport")
207 .and_then(|support| match support {
208 Ok(response) => response
209 .resp
210 .ok_or_else(|| {
211 format_err!("Driver returned empty QueryRssiMonitorSupport response")
212 })
213 .map(Ok),
214 Err(e) => Ok(Err(e)),
215 })
216 }
217
218 fn start_scan(&self, req: fidl_fullmac::WlanFullmacImplStartScanRequest) -> anyhow::Result<()> {
219 self.fullmac_impl_sync_proxy
220 .start_scan(&req, zx::MonotonicInstant::INFINITE)
221 .context("FIDL error on StartScan")
222 }
223 fn connect(&self, req: fidl_fullmac::WlanFullmacImplConnectRequest) -> anyhow::Result<()> {
224 self.fullmac_impl_sync_proxy
225 .connect(&req, zx::MonotonicInstant::INFINITE)
226 .context("FIDL error on Connect")
227 }
228 fn reconnect(&self, req: fidl_fullmac::WlanFullmacImplReconnectRequest) -> anyhow::Result<()> {
229 self.fullmac_impl_sync_proxy
230 .reconnect(&req, zx::MonotonicInstant::INFINITE)
231 .context("FIDL error on Reconnect")
232 }
233 fn roam(&self, req: fidl_fullmac::WlanFullmacImplRoamRequest) -> anyhow::Result<()> {
234 self.fullmac_impl_sync_proxy
235 .roam(&req, zx::MonotonicInstant::INFINITE)
236 .context("FIDL error on Roam")
237 }
238 fn auth_resp(&self, resp: fidl_fullmac::WlanFullmacImplAuthRespRequest) -> anyhow::Result<()> {
239 self.fullmac_impl_sync_proxy
240 .auth_resp(&resp, zx::MonotonicInstant::INFINITE)
241 .context("FIDL error on AuthResp")
242 }
243 fn deauth(&self, req: fidl_fullmac::WlanFullmacImplDeauthRequest) -> anyhow::Result<()> {
244 self.fullmac_impl_sync_proxy
245 .deauth(&req, zx::MonotonicInstant::INFINITE)
246 .context("FIDL error on Deauth")
247 }
248 fn assoc_resp(
249 &self,
250 resp: fidl_fullmac::WlanFullmacImplAssocRespRequest,
251 ) -> anyhow::Result<()> {
252 self.fullmac_impl_sync_proxy
253 .assoc_resp(&resp, zx::MonotonicInstant::INFINITE)
254 .context("FIDL error on AssocResp")
255 }
256 fn disassoc(&self, req: fidl_fullmac::WlanFullmacImplDisassocRequest) -> anyhow::Result<()> {
257 self.fullmac_impl_sync_proxy
258 .disassoc(&req, zx::MonotonicInstant::INFINITE)
259 .context("FIDL error on Disassoc")
260 }
261 fn start_bss(&self, req: fidl_fullmac::WlanFullmacImplStartBssRequest) -> anyhow::Result<()> {
262 self.fullmac_impl_sync_proxy
263 .start_bss(&req, zx::MonotonicInstant::INFINITE)
264 .context("FIDL error on StartBss")
265 }
266 fn stop_bss(&self, req: fidl_fullmac::WlanFullmacImplStopBssRequest) -> anyhow::Result<()> {
267 self.fullmac_impl_sync_proxy
268 .stop_bss(&req, zx::MonotonicInstant::INFINITE)
269 .context("FIDL error on StopBss")
270 }
271 fn set_keys(
272 &self,
273 req: fidl_fullmac::WlanFullmacImplSetKeysRequest,
274 ) -> anyhow::Result<fidl_fullmac::WlanFullmacSetKeysResp> {
275 self.fullmac_impl_sync_proxy
276 .set_keys(&req, zx::MonotonicInstant::INFINITE)
277 .context("FIDL error on SetKeysReq")
278 }
279 fn eapol_tx(&self, req: fidl_fullmac::WlanFullmacImplEapolTxRequest) -> anyhow::Result<()> {
280 self.fullmac_impl_sync_proxy
281 .eapol_tx(&req, zx::MonotonicInstant::INFINITE)
282 .context("FIDL error on EapolTx")
283 }
284 fn get_iface_stats(&self) -> anyhow::Result<fidl_mlme::GetIfaceStatsResponse> {
285 match self
286 .fullmac_impl_sync_proxy
287 .get_iface_stats(zx::MonotonicInstant::INFINITE)
288 .context("FIDL error on GetIfaceStats")?
289 {
290 Ok(stats) => Ok(fidl_mlme::GetIfaceStatsResponse::Stats(stats)),
291 Err(e) => Ok(fidl_mlme::GetIfaceStatsResponse::ErrorStatus(e)),
292 }
293 }
294 fn get_iface_histogram_stats(
295 &self,
296 ) -> anyhow::Result<fidl_mlme::GetIfaceHistogramStatsResponse> {
297 match self
298 .fullmac_impl_sync_proxy
299 .get_iface_histogram_stats(zx::MonotonicInstant::INFINITE)
300 .context("FIDL error on GetIfaceHistogramStats")?
301 {
302 Ok(stats) => Ok(fidl_mlme::GetIfaceHistogramStatsResponse::Stats(stats)),
303 Err(e) => Ok(fidl_mlme::GetIfaceHistogramStatsResponse::ErrorStatus(e)),
304 }
305 }
306 fn get_signal_report(&self) -> anyhow::Result<Result<fidl_stats::SignalReport, i32>> {
307 self.fullmac_impl_sync_proxy
308 .get_signal_report(zx::MonotonicInstant::INFINITE)
309 .context("FIDL error on GetSignalReport")
310 }
311
312 fn sae_handshake_resp(
313 &self,
314 resp: fidl_fullmac::WlanFullmacImplSaeHandshakeRespRequest,
315 ) -> anyhow::Result<()> {
316 self.fullmac_impl_sync_proxy
317 .sae_handshake_resp(&resp, zx::MonotonicInstant::INFINITE)
318 .context("FIDL error on SaeHandshakeResp")
319 }
320 fn sae_frame_tx(&self, frame: fidl_fullmac::SaeFrame) -> anyhow::Result<()> {
321 self.fullmac_impl_sync_proxy
322 .sae_frame_tx(&frame, zx::MonotonicInstant::INFINITE)
323 .context("FIDL error on SaeFrameTx")
324 }
325 fn wmm_status_req(&self) -> anyhow::Result<()> {
326 self.fullmac_impl_sync_proxy
327 .wmm_status_req(zx::MonotonicInstant::INFINITE)
328 .context("FIDL error on WmmStatusReq")
329 }
330 fn on_link_state_changed(
331 &self,
332 req: fidl_fullmac::WlanFullmacImplOnLinkStateChangedRequest,
333 ) -> anyhow::Result<()> {
334 self.fullmac_impl_sync_proxy
335 .on_link_state_changed(&req, zx::MonotonicInstant::INFINITE)
336 .context("FIDL error on OnLinkStateChanged")
337 }
338 fn set_mac_address(
339 &self,
340 req: fidl_fuchsia_wlan_fullmac::WlanFullmacImplSetMacAddressRequest,
341 ) -> anyhow::Result<Result<(), i32>> {
342 self.fullmac_impl_sync_proxy
343 .set_mac_address(&req.mac_addr, zx::MonotonicInstant::INFINITE)
344 .context("FIDL error on SetMacAddress")
345 }
346
347 fn install_apf_packet_filter(
348 &self,
349 req: fidl_fullmac::WlanFullmacImplInstallApfPacketFilterRequest,
350 ) -> anyhow::Result<Result<(), i32>> {
351 self.fullmac_impl_sync_proxy
352 .install_apf_packet_filter(&req, zx::MonotonicInstant::INFINITE)
353 .context("FIDL error on InstallApfPacketFilter")
354 }
355
356 fn read_apf_packet_filter_data(
357 &self,
358 ) -> anyhow::Result<Result<fidl_fullmac::WlanFullmacImplReadApfPacketFilterDataResponse, i32>>
359 {
360 self.fullmac_impl_sync_proxy
361 .read_apf_packet_filter_data(zx::MonotonicInstant::INFINITE)
362 .context("FIDL error on ReadApfPacketFilterData")
363 }
364
365 fn set_apf_packet_filter_enabled(
366 &self,
367 req: fidl_fullmac::WlanFullmacImplSetApfPacketFilterEnabledRequest,
368 ) -> anyhow::Result<Result<(), i32>> {
369 self.fullmac_impl_sync_proxy
370 .set_apf_packet_filter_enabled(&req, zx::MonotonicInstant::INFINITE)
371 .context("FIDL error on SetApfPacketFilterEnabled")
372 }
373
374 fn get_apf_packet_filter_enabled(
375 &self,
376 ) -> anyhow::Result<Result<fidl_fullmac::WlanFullmacImplGetApfPacketFilterEnabledResponse, i32>>
377 {
378 self.fullmac_impl_sync_proxy
379 .get_apf_packet_filter_enabled(zx::MonotonicInstant::INFINITE)
380 .context("FIDL error on GetApfPacketFilterEnabled")
381 }
382
383 fn start_scheduled_scan(
384 &self,
385 req: fidl_fullmac::WlanFullmacImplStartScheduledScanRequest,
386 ) -> anyhow::Result<Result<(), i32>> {
387 self.fullmac_impl_sync_proxy
388 .start_scheduled_scan(&req, zx::MonotonicInstant::INFINITE)
389 .context("FIDL error on StartScheduledScan")
390 }
391
392 fn stop_scheduled_scan(
393 &self,
394 req: fidl_fullmac::WlanFullmacImplStopScheduledScanRequest,
395 ) -> anyhow::Result<Result<(), i32>> {
396 self.fullmac_impl_sync_proxy
397 .stop_scheduled_scan(&req, zx::MonotonicInstant::INFINITE)
398 .context("FIDL error on StopScheduledScan")
399 }
400
401 fn get_scheduled_scan_enabled(
402 &self,
403 ) -> anyhow::Result<Result<fidl_fullmac::WlanFullmacImplGetScheduledScanEnabledResponse, i32>>
404 {
405 self.fullmac_impl_sync_proxy
406 .get_scheduled_scan_enabled(zx::MonotonicInstant::INFINITE)
407 .context("FIDL error on GetScheduledScanEnabled")
408 }
409
410 fn start_rssi_monitor(
411 &self,
412 req: fidl_fullmac::WlanFullmacImplStartRssiMonitorRequest,
413 ) -> anyhow::Result<Result<(), i32>> {
414 self.fullmac_impl_sync_proxy
415 .start_rssi_monitor(&req, zx::MonotonicInstant::INFINITE)
416 .context("FIDL error on StartRssiMonitor")
417 }
418
419 fn stop_rssi_monitor(&self) -> anyhow::Result<Result<(), i32>> {
420 self.fullmac_impl_sync_proxy
421 .stop_rssi_monitor(zx::MonotonicInstant::INFINITE)
422 .context("FIDL error on StopRssiMonitor")
423 }
424}
425
426#[cfg(test)]
427pub mod test_utils {
428 use super::*;
429 use fidl_fuchsia_wlan_sme as fidl_sme;
430 use fuchsia_sync::Mutex;
431 use futures::channel::mpsc;
432 use std::sync::Arc;
433 use wlan_common::sink::UnboundedSink;
434
435 #[derive(Debug)]
436 pub enum DriverCall {
437 StartScan {
438 req: fidl_fullmac::WlanFullmacImplStartScanRequest,
439 },
440 StartScheduledScan {
441 req: fidl_fullmac::WlanFullmacImplStartScheduledScanRequest,
442 },
443 StopScheduledScan {
444 req: fidl_fullmac::WlanFullmacImplStopScheduledScanRequest,
445 },
446 GetScheduledScanEnabled,
447 ConnectReq {
448 req: fidl_fullmac::WlanFullmacImplConnectRequest,
449 },
450 ReconnectReq {
451 req: fidl_fullmac::WlanFullmacImplReconnectRequest,
452 },
453 RoamReq {
454 req: fidl_fullmac::WlanFullmacImplRoamRequest,
455 },
456 AuthResp {
457 resp: fidl_fullmac::WlanFullmacImplAuthRespRequest,
458 },
459 DeauthReq {
460 req: fidl_fullmac::WlanFullmacImplDeauthRequest,
461 },
462 AssocResp {
463 resp: fidl_fullmac::WlanFullmacImplAssocRespRequest,
464 },
465 Disassoc {
466 req: fidl_fullmac::WlanFullmacImplDisassocRequest,
467 },
468 StartBss {
469 req: fidl_fullmac::WlanFullmacImplStartBssRequest,
470 },
471 StopBss {
472 req: fidl_fullmac::WlanFullmacImplStopBssRequest,
473 },
474 SetKeys {
475 req: fidl_fullmac::WlanFullmacImplSetKeysRequest,
476 },
477 EapolTx {
478 req: fidl_fullmac::WlanFullmacImplEapolTxRequest,
479 },
480 QueryTelemetrySupport,
481 QueryApfPacketFilterSupport,
482 QueryRssiMonitorSupport,
483 GetIfaceStats,
484 GetIfaceHistogramStats,
485 GetSignalReport,
486 SaeHandshakeResp {
487 resp: fidl_fullmac::WlanFullmacImplSaeHandshakeRespRequest,
488 },
489 SaeFrameTx {
490 frame: fidl_fullmac::SaeFrame,
491 },
492 WmmStatusReq,
493 OnLinkStateChanged {
494 req: fidl_fullmac::WlanFullmacImplOnLinkStateChangedRequest,
495 },
496 SetMacAddress {
497 req: fidl_fullmac::WlanFullmacImplSetMacAddressRequest,
498 },
499 InstallApfPacketFilter {
500 req: fidl_fullmac::WlanFullmacImplInstallApfPacketFilterRequest,
501 },
502 ReadApfPacketFilterData,
503 SetApfPacketFilterEnabled {
504 req: fidl_fullmac::WlanFullmacImplSetApfPacketFilterEnabledRequest,
505 },
506 GetApfPacketFilterEnabled,
507 StartRssiMonitor {
508 req: fidl_fullmac::WlanFullmacImplStartRssiMonitorRequest,
509 },
510 StopRssiMonitor,
511 }
512
513 pub struct FakeFullmacDeviceMocks {
514 pub start_fn_status_mock: Option<zx::sys::zx_status_t>,
515
516 pub query_device_info_mock: Option<fidl_fullmac::WlanFullmacImplQueryResponse>,
522 pub query_security_support_mock: Option<fidl_common::SecuritySupport>,
523 pub query_spectrum_management_support_mock: Option<fidl_common::SpectrumManagementSupport>,
524 pub query_telemetry_support_mock: Option<Result<fidl_stats::TelemetrySupport, i32>>,
525 pub query_apf_packet_filter_support_mock:
526 Option<Result<fidl_common::ApfPacketFilterSupport, i32>>,
527 pub query_rssi_monitor_support_mock: Option<Result<fidl_common::RssiMonitorSupport, i32>>,
528
529 pub set_keys_resp_mock: Option<fidl_fullmac::WlanFullmacSetKeysResp>,
530 pub get_iface_stats_mock: Option<fidl_mlme::GetIfaceStatsResponse>,
531 pub get_iface_histogram_stats_mock: Option<fidl_mlme::GetIfaceHistogramStatsResponse>,
532 pub get_signal_report_mock: Option<Result<fidl_stats::SignalReport, i32>>,
533 pub install_apf_packet_filter_mock: Option<Result<(), i32>>,
534 pub read_apf_packet_filter_data_mock:
535 Option<Result<fidl_fullmac::WlanFullmacImplReadApfPacketFilterDataResponse, i32>>,
536 pub set_apf_packet_filter_enabled_mock: Option<Result<(), i32>>,
537 pub get_apf_packet_filter_enabled_mock:
538 Option<Result<fidl_fullmac::WlanFullmacImplGetApfPacketFilterEnabledResponse, i32>>,
539 pub get_scheduled_scan_enabled_mock:
540 Option<Result<fidl_fullmac::WlanFullmacImplGetScheduledScanEnabledResponse, i32>>,
541 pub start_rssi_monitor_mock: Option<Result<(), i32>>,
542 pub stop_rssi_monitor_mock: Option<Result<(), i32>>,
543 pub fullmac_ifc_client_end: Option<ClientEnd<fidl_fullmac::WlanFullmacImplIfcMarker>>,
544 }
545
546 unsafe impl Send for FakeFullmacDevice {}
547 pub struct FakeFullmacDevice {
548 pub usme_bootstrap_client_end:
549 Option<fidl::endpoints::ClientEnd<fidl_sme::UsmeBootstrapMarker>>,
550 pub usme_bootstrap_server_end:
551 Option<fidl::endpoints::ServerEnd<fidl_sme::UsmeBootstrapMarker>>,
552 driver_call_sender: UnboundedSink<DriverCall>,
553
554 pub mocks: Arc<Mutex<FakeFullmacDeviceMocks>>,
558 }
559
560 impl FakeFullmacDevice {
561 pub fn new() -> (Self, mpsc::UnboundedReceiver<DriverCall>) {
562 let (usme_bootstrap_client_end, usme_bootstrap_server_end) =
564 fidl::endpoints::create_endpoints::<fidl_sme::UsmeBootstrapMarker>();
565
566 let (driver_call_sender, driver_call_receiver) = mpsc::unbounded();
567
568 let device = Self {
569 usme_bootstrap_client_end: Some(usme_bootstrap_client_end),
570 usme_bootstrap_server_end: Some(usme_bootstrap_server_end),
571 driver_call_sender: UnboundedSink::new(driver_call_sender),
572 mocks: Arc::new(Mutex::new(FakeFullmacDeviceMocks {
573 fullmac_ifc_client_end: None,
574 start_fn_status_mock: None,
575 query_device_info_mock: Some(fidl_fullmac::WlanFullmacImplQueryResponse {
576 sta_addr: Some([0u8; 6]),
577 factory_addr: Some([0u8; 6]),
578 role: Some(fidl_common::WlanMacRole::Client),
579 band_caps: Some(vec![]),
580 ..Default::default()
581 }),
582 query_security_support_mock: Some(fidl_common::SecuritySupport {
583 sae: Some(fidl_common::SaeFeature {
584 driver_handler_supported: Some(false),
585 sme_handler_supported: Some(true),
586 hash_to_element_supported: Some(false),
587 ..Default::default()
588 }),
589 mfp: Some(fidl_common::MfpFeature {
590 supported: Some(false),
591 ..Default::default()
592 }),
593 owe: Some(fidl_common::OweFeature {
594 supported: Some(false),
595 ..Default::default()
596 }),
597 ..Default::default()
598 }),
599 query_spectrum_management_support_mock: Some(
600 fidl_common::SpectrumManagementSupport {
601 dfs: Some(fidl_common::DfsFeature {
602 supported: Some(false),
603 ..Default::default()
604 }),
605 ..Default::default()
606 },
607 ),
608 query_telemetry_support_mock: Some(Ok(fidl_stats::TelemetrySupport {
609 ..Default::default()
610 })),
611 query_apf_packet_filter_support_mock: Some(Ok(
612 fidl_common::ApfPacketFilterSupport {
613 supported: Some(false),
614 ..Default::default()
615 },
616 )),
617 query_rssi_monitor_support_mock: Some(Ok(fidl_common::RssiMonitorSupport {
618 supported: Some(false),
619 ..Default::default()
620 })),
621 get_signal_report_mock: Some(Ok(fidl_stats::SignalReport {
622 ..Default::default()
623 })),
624 set_keys_resp_mock: None,
625 get_iface_stats_mock: None,
626 get_iface_histogram_stats_mock: None,
627 install_apf_packet_filter_mock: Some(Ok(())),
628 read_apf_packet_filter_data_mock: Some(Ok(
629 fidl_fullmac::WlanFullmacImplReadApfPacketFilterDataResponse {
630 memory: Some(vec![]),
631 ..Default::default()
632 },
633 )),
634 set_apf_packet_filter_enabled_mock: Some(Ok(())),
635 get_apf_packet_filter_enabled_mock: Some(Ok(
636 fidl_fullmac::WlanFullmacImplGetApfPacketFilterEnabledResponse {
637 enabled: Some(false),
638 ..Default::default()
639 },
640 )),
641 get_scheduled_scan_enabled_mock: Some(Ok(
642 fidl_fullmac::WlanFullmacImplGetScheduledScanEnabledResponse {
643 active_txn_ids: Some(vec![]),
644 ..Default::default()
645 },
646 )),
647 start_rssi_monitor_mock: Some(Ok(())),
648 stop_rssi_monitor_mock: Some(Ok(())),
649 })),
650 };
651
652 (device, driver_call_receiver)
653 }
654 }
655
656 impl DeviceOps for FakeFullmacDevice {
657 fn init(
658 &mut self,
659 fullmac_ifc_client_end: ClientEnd<fidl_fullmac::WlanFullmacImplIfcMarker>,
660 ) -> Result<fidl::Channel, zx::Status> {
661 let mut mocks = self.mocks.lock();
662
663 mocks.fullmac_ifc_client_end = Some(fullmac_ifc_client_end);
664 match mocks.start_fn_status_mock {
665 Some(status) => Err(zx::Status::err_from_raw(status)),
666
667 None => Ok(self.usme_bootstrap_server_end.take().unwrap().into_channel()),
669 }
670 }
671
672 fn query_device_info(&self) -> anyhow::Result<fidl_fullmac::WlanFullmacImplQueryResponse> {
673 self.mocks.lock().query_device_info_mock.clone().ok_or_else(|| format_err!(""))
674 }
675
676 fn query_security_support(&self) -> anyhow::Result<fidl_common::SecuritySupport> {
677 self.mocks.lock().query_security_support_mock.clone().ok_or_else(|| format_err!(""))
678 }
679
680 fn query_spectrum_management_support(
681 &self,
682 ) -> anyhow::Result<fidl_common::SpectrumManagementSupport> {
683 self.mocks
684 .lock()
685 .query_spectrum_management_support_mock
686 .clone()
687 .ok_or_else(|| format_err!(""))
688 }
689
690 fn query_telemetry_support(
691 &self,
692 ) -> anyhow::Result<Result<fidl_stats::TelemetrySupport, i32>> {
693 self.driver_call_sender.send(DriverCall::QueryTelemetrySupport);
694 self.mocks.lock().query_telemetry_support_mock.clone().ok_or_else(|| format_err!(""))
695 }
696
697 fn query_apf_packet_filter_support(
698 &self,
699 ) -> anyhow::Result<Result<fidl_common::ApfPacketFilterSupport, i32>> {
700 self.driver_call_sender.send(DriverCall::QueryApfPacketFilterSupport);
701 self.mocks.lock().query_apf_packet_filter_support_mock.clone().ok_or_else(|| {
702 format_err!("query_apf_packet_filter_support_mock is None in FakeFullmacDevice")
703 })
704 }
705
706 fn query_rssi_monitor_support(
707 &self,
708 ) -> anyhow::Result<Result<fidl_common::RssiMonitorSupport, i32>> {
709 self.driver_call_sender.send(DriverCall::QueryRssiMonitorSupport);
710 self.mocks.lock().query_rssi_monitor_support_mock.clone().ok_or_else(|| {
711 format_err!("query_rssi_monitor_support_mock is None in FakeFullmacDevice")
712 })
713 }
714
715 fn start_scan(
717 &self,
718 req: fidl_fullmac::WlanFullmacImplStartScanRequest,
719 ) -> anyhow::Result<()> {
720 self.driver_call_sender.send(DriverCall::StartScan { req });
721 Ok(())
722 }
723
724 fn connect(&self, req: fidl_fullmac::WlanFullmacImplConnectRequest) -> anyhow::Result<()> {
725 self.driver_call_sender.send(DriverCall::ConnectReq { req });
726 Ok(())
727 }
728 fn reconnect(
729 &self,
730 req: fidl_fullmac::WlanFullmacImplReconnectRequest,
731 ) -> anyhow::Result<()> {
732 self.driver_call_sender.send(DriverCall::ReconnectReq { req });
733 Ok(())
734 }
735 fn roam(&self, req: fidl_fullmac::WlanFullmacImplRoamRequest) -> anyhow::Result<()> {
736 self.driver_call_sender.send(DriverCall::RoamReq { req });
737 Ok(())
738 }
739 fn auth_resp(
740 &self,
741 resp: fidl_fullmac::WlanFullmacImplAuthRespRequest,
742 ) -> anyhow::Result<()> {
743 self.driver_call_sender.send(DriverCall::AuthResp { resp });
744 Ok(())
745 }
746 fn deauth(&self, req: fidl_fullmac::WlanFullmacImplDeauthRequest) -> anyhow::Result<()> {
747 self.driver_call_sender.send(DriverCall::DeauthReq { req });
748 Ok(())
749 }
750 fn assoc_resp(
751 &self,
752 resp: fidl_fullmac::WlanFullmacImplAssocRespRequest,
753 ) -> anyhow::Result<()> {
754 self.driver_call_sender.send(DriverCall::AssocResp { resp });
755 Ok(())
756 }
757 fn disassoc(
758 &self,
759 req: fidl_fullmac::WlanFullmacImplDisassocRequest,
760 ) -> anyhow::Result<()> {
761 self.driver_call_sender.send(DriverCall::Disassoc { req });
762 Ok(())
763 }
764 fn start_bss(
765 &self,
766 req: fidl_fullmac::WlanFullmacImplStartBssRequest,
767 ) -> anyhow::Result<()> {
768 self.driver_call_sender.send(DriverCall::StartBss { req });
769 Ok(())
770 }
771 fn stop_bss(&self, req: fidl_fullmac::WlanFullmacImplStopBssRequest) -> anyhow::Result<()> {
772 self.driver_call_sender.send(DriverCall::StopBss { req });
773 Ok(())
774 }
775 fn set_keys(
776 &self,
777 req: fidl_fullmac::WlanFullmacImplSetKeysRequest,
778 ) -> anyhow::Result<fidl_fullmac::WlanFullmacSetKeysResp> {
779 let num_keys = req.keylist.as_ref().unwrap().len();
780 self.driver_call_sender.send(DriverCall::SetKeys { req });
781 match &self.mocks.lock().set_keys_resp_mock {
782 Some(resp) => Ok(resp.clone()),
783 None => {
784 Ok(fidl_fullmac::WlanFullmacSetKeysResp { statuslist: vec![0i32; num_keys] })
785 }
786 }
787 }
788 fn eapol_tx(&self, req: fidl_fullmac::WlanFullmacImplEapolTxRequest) -> anyhow::Result<()> {
789 self.driver_call_sender.send(DriverCall::EapolTx { req });
790 Ok(())
791 }
792 fn get_iface_stats(&self) -> anyhow::Result<fidl_mlme::GetIfaceStatsResponse> {
793 self.driver_call_sender.send(DriverCall::GetIfaceStats);
794 Ok(self.mocks.lock().get_iface_stats_mock.clone().unwrap_or(
795 fidl_mlme::GetIfaceStatsResponse::ErrorStatus(zx::sys::ZX_ERR_NOT_SUPPORTED),
796 ))
797 }
798 fn get_iface_histogram_stats(
799 &self,
800 ) -> anyhow::Result<fidl_mlme::GetIfaceHistogramStatsResponse> {
801 self.driver_call_sender.send(DriverCall::GetIfaceHistogramStats);
802 Ok(self.mocks.lock().get_iface_histogram_stats_mock.clone().unwrap_or(
803 fidl_mlme::GetIfaceHistogramStatsResponse::ErrorStatus(
804 zx::sys::ZX_ERR_NOT_SUPPORTED,
805 ),
806 ))
807 }
808 fn get_signal_report(&self) -> anyhow::Result<Result<fidl_stats::SignalReport, i32>> {
809 self.driver_call_sender.send(DriverCall::GetSignalReport);
810 self.mocks.lock().get_signal_report_mock.clone().ok_or_else(|| format_err!(""))
811 }
812 fn sae_handshake_resp(
813 &self,
814 resp: fidl_fullmac::WlanFullmacImplSaeHandshakeRespRequest,
815 ) -> anyhow::Result<()> {
816 self.driver_call_sender.send(DriverCall::SaeHandshakeResp { resp });
817 Ok(())
818 }
819 fn sae_frame_tx(&self, frame: fidl_fullmac::SaeFrame) -> anyhow::Result<()> {
820 self.driver_call_sender.send(DriverCall::SaeFrameTx { frame });
821 Ok(())
822 }
823 fn wmm_status_req(&self) -> anyhow::Result<()> {
824 self.driver_call_sender.send(DriverCall::WmmStatusReq);
825 Ok(())
826 }
827 fn on_link_state_changed(
828 &self,
829 req: fidl_fullmac::WlanFullmacImplOnLinkStateChangedRequest,
830 ) -> anyhow::Result<()> {
831 self.driver_call_sender.send(DriverCall::OnLinkStateChanged { req });
832 Ok(())
833 }
834 fn set_mac_address(
835 &self,
836 req: fidl_fuchsia_wlan_fullmac::WlanFullmacImplSetMacAddressRequest,
837 ) -> anyhow::Result<Result<(), i32>> {
838 self.driver_call_sender.send(DriverCall::SetMacAddress { req });
839 Ok(Ok(()))
840 }
841
842 fn install_apf_packet_filter(
843 &self,
844 req: fidl_fullmac::WlanFullmacImplInstallApfPacketFilterRequest,
845 ) -> anyhow::Result<Result<(), i32>> {
846 self.driver_call_sender.send(DriverCall::InstallApfPacketFilter { req });
847 self.mocks.lock().install_apf_packet_filter_mock.clone().ok_or_else(|| {
848 format_err!("install_apf_packet_filter_mock is None in FakeFullmacDevice")
849 })
850 }
851
852 fn read_apf_packet_filter_data(
853 &self,
854 ) -> anyhow::Result<Result<fidl_fullmac::WlanFullmacImplReadApfPacketFilterDataResponse, i32>>
855 {
856 self.driver_call_sender.send(DriverCall::ReadApfPacketFilterData);
857 self.mocks.lock().read_apf_packet_filter_data_mock.clone().ok_or_else(|| {
858 format_err!("read_apf_packet_filter_data_mock is None in FakeFullmacDevice")
859 })
860 }
861
862 fn set_apf_packet_filter_enabled(
863 &self,
864 req: fidl_fullmac::WlanFullmacImplSetApfPacketFilterEnabledRequest,
865 ) -> anyhow::Result<Result<(), i32>> {
866 self.driver_call_sender.send(DriverCall::SetApfPacketFilterEnabled { req });
867 self.mocks.lock().set_apf_packet_filter_enabled_mock.clone().ok_or_else(|| {
868 format_err!("set_apf_packet_filter_enabled_mock is None in FakeFullmacDevice")
869 })
870 }
871
872 fn get_apf_packet_filter_enabled(
873 &self,
874 ) -> anyhow::Result<
875 Result<fidl_fullmac::WlanFullmacImplGetApfPacketFilterEnabledResponse, i32>,
876 > {
877 self.driver_call_sender.send(DriverCall::GetApfPacketFilterEnabled);
878 self.mocks.lock().get_apf_packet_filter_enabled_mock.clone().ok_or_else(|| {
879 format_err!("get_apf_packet_filter_enabled_mock is None in FakeFullmacDevice")
880 })
881 }
882
883 fn get_scheduled_scan_enabled(
884 &self,
885 ) -> anyhow::Result<Result<fidl_fullmac::WlanFullmacImplGetScheduledScanEnabledResponse, i32>>
886 {
887 self.driver_call_sender.send(DriverCall::GetScheduledScanEnabled);
888 self.mocks.lock().get_scheduled_scan_enabled_mock.clone().ok_or_else(|| {
889 format_err!("get_scheduled_scan_enabled_mock is None in FakeFullmacDevice")
890 })
891 }
892
893 fn start_scheduled_scan(
894 &self,
895 req: fidl_fullmac::WlanFullmacImplStartScheduledScanRequest,
896 ) -> anyhow::Result<Result<(), i32>> {
897 self.driver_call_sender.send(DriverCall::StartScheduledScan { req });
898 Ok(Ok(()))
899 }
900
901 fn stop_scheduled_scan(
902 &self,
903 req: fidl_fullmac::WlanFullmacImplStopScheduledScanRequest,
904 ) -> anyhow::Result<Result<(), i32>> {
905 self.driver_call_sender.send(DriverCall::StopScheduledScan { req });
906 Ok(Ok(()))
907 }
908
909 fn start_rssi_monitor(
910 &self,
911 req: fidl_fullmac::WlanFullmacImplStartRssiMonitorRequest,
912 ) -> anyhow::Result<Result<(), i32>> {
913 self.driver_call_sender.send(DriverCall::StartRssiMonitor { req });
914 self.mocks
915 .lock()
916 .start_rssi_monitor_mock
917 .clone()
918 .ok_or_else(|| format_err!("start_rssi_monitor_mock is None in FakeFullmacDevice"))
919 }
920
921 fn stop_rssi_monitor(&self) -> anyhow::Result<Result<(), i32>> {
922 self.driver_call_sender.send(DriverCall::StopRssiMonitor);
923 self.mocks
924 .lock()
925 .stop_rssi_monitor_mock
926 .clone()
927 .ok_or_else(|| format_err!("stop_rssi_monitor_mock is None in FakeFullmacDevice"))
928 }
929 }
930}