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