esp_radio/wifi/
event.rs

1//! Wi-Fi event handlers.
2
3use alloc::boxed::Box;
4
5use esp_sync::NonReentrantMutex;
6
7use super::WifiEvent;
8use crate::wifi::include::{
9    wifi_event_sta_wps_er_success_t__bindgen_ty_1,
10    wifi_ftm_report_entry_t,
11};
12
13pub(crate) mod sealed {
14    use super::*;
15
16    pub trait Event {
17        /// Get the static reference to the handler for this event.
18        fn handler() -> &'static NonReentrantMutex<Option<Box<Handler<Self>>>>;
19        /// # Safety
20        /// `ptr` must be a valid for casting to this event's inner event data.
21        unsafe fn from_raw_event_data(ptr: *mut crate::binary::c_types::c_void) -> Self;
22    }
23}
24
25/// The type of handlers of events.
26#[instability::unstable]
27pub type Handler<T> = dyn FnMut(&T) + Sync + Send;
28
29fn default_handler<Event: 'static>() -> Box<Handler<Event>> {
30    fn drop_ref<T>(_: &T) {}
31    // perf: `drop_ref` is a ZST [function item](https://doc.rust-lang.org/reference/types/function-item.html)
32    // so this doesn't actually allocate.
33    Box::new(drop_ref)
34}
35
36/// Extension trait for setting handlers for an event.
37///
38/// Register a new event handler like:
39///
40/// ```rust, no_run
41/// # use esp_radio::wifi::event::{self, *};
42/// # fn new_handler(_: &ApStaConnected) {}
43/// event::ApStaConnected::update_handler(|_cs, event| {
44///     new_handler(event);
45/// })
46/// ```
47// Implemented like this instead of free functions because the syntax would be
48// ```
49// event::update_handler::<event::ApStaConnected, _>(...)
50// ```
51#[instability::unstable]
52pub trait EventExt: sealed::Event + Sized + 'static {
53    /// Get the handler for this event, replacing it with the default handler.
54    fn take_handler() -> Box<Handler<Self>> {
55        Self::handler().with(|handler| handler.take().unwrap_or_else(default_handler::<Self>))
56    }
57
58    /// Set the handler for this event, returning the old handler.
59    fn replace_handler<F: FnMut(&Self) + Sync + Send + 'static>(f: F) -> Box<Handler<Self>> {
60        Self::handler().with(|handler| {
61            handler
62                .replace(Box::new(f))
63                .unwrap_or_else(default_handler::<Self>)
64        })
65    }
66
67    /// Atomic combination of [`Self::take_handler`] and
68    /// [`Self::replace_handler`]. Use this to add a new handler which runs
69    /// after the previously registered handlers.
70    fn update_handler<F: FnMut(&Self) + Sync + Send + 'static>(mut f: F) {
71        Self::handler().with(|handler| {
72            let mut prev: Box<Handler<Self>> =
73                handler.take().unwrap_or_else(default_handler::<Self>);
74            handler.replace(Box::new(move |event| {
75                prev(event);
76                f(event)
77            }));
78        })
79    }
80}
81
82impl<T: sealed::Event + 'static> EventExt for T {}
83
84macro_rules! impl_wifi_event {
85    // no data
86    ($newtype:ident) => {
87        /// See [`WifiEvent`].
88        #[derive(Copy, Clone)]
89        pub struct $newtype;
90
91        impl sealed::Event for $newtype {
92            unsafe fn from_raw_event_data(_: *mut crate::binary::c_types::c_void) -> Self {
93                Self
94            }
95            fn handler() -> &'static NonReentrantMutex<Option<Box<Handler<Self>>>> {
96                static HANDLE: NonReentrantMutex<Option<Box<Handler<$newtype>>>> =
97                    NonReentrantMutex::new(None);
98                &HANDLE
99            }
100        }
101    };
102
103    ($newtype:ident, $data:ident) => {
104        use esp_wifi_sys::include::$data;
105        /// See [`WifiEvent`].
106        #[derive(Copy, Clone)]
107        pub struct $newtype<'a>(&'a $data);
108
109        impl sealed::Event for $newtype<'_> {
110            unsafe fn from_raw_event_data(ptr: *mut crate::binary::c_types::c_void) -> Self {
111                Self(unsafe { &*ptr.cast() })
112            }
113
114            fn handler() -> &'static NonReentrantMutex<Option<Box<Handler<Self>>>> {
115                static HANDLE: NonReentrantMutex<Option<Box<Handler<$newtype<'_>>>>> =
116                    NonReentrantMutex::new(None);
117                &HANDLE
118            }
119        }
120    };
121}
122
123impl_wifi_event!(WifiReady);
124impl_wifi_event!(ScanDone, wifi_event_sta_scan_done_t);
125impl_wifi_event!(StaStart);
126impl_wifi_event!(StaStop);
127impl_wifi_event!(StaConnected, wifi_event_sta_connected_t);
128impl_wifi_event!(StaDisconnected, wifi_event_sta_disconnected_t);
129impl_wifi_event!(StaAuthmodeChange, wifi_event_sta_authmode_change_t);
130impl_wifi_event!(StaWpsErSuccess, wifi_event_sta_wps_er_success_t);
131impl_wifi_event!(StaWpsErFailed);
132impl_wifi_event!(StaWpsErTimeout);
133impl_wifi_event!(StaWpsErPin, wifi_event_sta_wps_er_pin_t);
134impl_wifi_event!(StaWpsErPbcOverlap);
135impl_wifi_event!(ApStart);
136impl_wifi_event!(ApStop);
137impl_wifi_event!(ApStaConnected, wifi_event_ap_staconnected_t);
138impl_wifi_event!(ApStaDisconnected, wifi_event_ap_stadisconnected_t);
139impl_wifi_event!(ApProbeReqReceived, wifi_event_ap_probe_req_rx_t);
140impl_wifi_event!(FtmReport, wifi_event_ftm_report_t);
141impl_wifi_event!(StaBssRssiLow, wifi_event_bss_rssi_low_t);
142impl_wifi_event!(ActionTxStatus, wifi_event_action_tx_status_t);
143impl_wifi_event!(RocDone, wifi_event_roc_done_t);
144impl_wifi_event!(StaBeaconTimeout);
145impl_wifi_event!(ConnectionlessModuleWakeIntervalStart);
146impl_wifi_event!(ApWpsRgSuccess, wifi_event_ap_wps_rg_success_t);
147impl_wifi_event!(ApWpsRgFailed, wifi_event_ap_wps_rg_fail_reason_t);
148impl_wifi_event!(ApWpsRgTimeout);
149impl_wifi_event!(ApWpsRgPin, wifi_event_ap_wps_rg_pin_t);
150impl_wifi_event!(ApWpsRgPbcOverlap);
151impl_wifi_event!(ItwtSetup);
152impl_wifi_event!(ItwtTeardown);
153impl_wifi_event!(ItwtProbe);
154impl_wifi_event!(ItwtSuspend);
155impl_wifi_event!(TwtWakeup);
156impl_wifi_event!(BtwtSetup);
157impl_wifi_event!(BtwtTeardown);
158impl_wifi_event!(NanStarted);
159impl_wifi_event!(NanStopped);
160impl_wifi_event!(NanSvcMatch, wifi_event_nan_svc_match_t);
161impl_wifi_event!(NanReplied, wifi_event_nan_replied_t);
162impl_wifi_event!(NanReceive, wifi_event_nan_receive_t);
163impl_wifi_event!(NdpIndication, wifi_event_ndp_indication_t);
164impl_wifi_event!(NdpConfirm, wifi_event_ndp_confirm_t);
165impl_wifi_event!(NdpTerminated, wifi_event_ndp_terminated_t);
166impl_wifi_event!(HomeChannelChange, wifi_event_home_channel_change_t);
167impl_wifi_event!(StaNeighborRep, wifi_event_neighbor_report_t);
168
169impl ApStaConnected<'_> {
170    /// Get the MAC address of the connected station.
171    pub fn mac(&self) -> &[u8] {
172        &self.0.mac
173    }
174
175    /// Get the AID (Association Identifier) of the connected station.
176    pub fn aid(&self) -> u8 {
177        self.0.aid
178    }
179
180    /// Flag indicating whether the connected station is a mesh child.
181    pub fn is_mesh_child(&self) -> bool {
182        self.0.is_mesh_child
183    }
184}
185
186impl ApStaDisconnected<'_> {
187    /// Get the MAC address of the disconnected station.
188    pub fn mac(&self) -> &[u8] {
189        &self.0.mac
190    }
191
192    /// Get the reason for the disconnection.
193    pub fn reason(&self) -> u16 {
194        self.0.reason
195    }
196
197    /// AID that the Soft-AP assigned to the disconnected station.
198    pub fn aid(&self) -> u8 {
199        self.0.aid
200    }
201
202    /// Flag indicating whether the connected station is a mesh child.
203    pub fn is_mesh_child(&self) -> bool {
204        self.0.is_mesh_child
205    }
206}
207
208impl ScanDone<'_> {
209    /// Get the status of the scan operation.
210    pub fn status(&self) -> u32 {
211        self.0.status
212    }
213
214    /// Get the number of found APs.
215    pub fn number(&self) -> u8 {
216        self.0.number
217    }
218
219    /// Get the scan ID associated with this scan operation.
220    pub fn id(&self) -> u8 {
221        self.0.scan_id
222    }
223}
224
225impl StaConnected<'_> {
226    /// Get the SSID of the connected station.
227    pub fn ssid(&self) -> &[u8] {
228        &self.0.ssid
229    }
230
231    /// Get the length of the SSID.
232    pub fn ssid_len(&self) -> u8 {
233        self.0.ssid_len
234    }
235
236    /// Get the BSSID (MAC address) of the connected station.
237    pub fn bssid(&self) -> &[u8] {
238        &self.0.bssid
239    }
240
241    /// Get the channel on which the station is connected.
242    pub fn channel(&self) -> u8 {
243        self.0.channel
244    }
245
246    /// Get the authentication mode used for the connection.
247    pub fn authmode(&self) -> u32 {
248        self.0.authmode
249    }
250
251    /// Get the AID (Association Identifier) of the connected station.
252    pub fn aid(&self) -> u16 {
253        self.0.aid
254    }
255}
256
257impl StaDisconnected<'_> {
258    /// Get the SSID of the disconnected station.
259    pub fn ssid(&self) -> &[u8] {
260        &self.0.ssid
261    }
262
263    /// Get the length of the SSID.
264    pub fn ssid_len(&self) -> u8 {
265        self.0.ssid_len
266    }
267
268    /// Get the BSSID (MAC address) of the disconnected station.
269    pub fn bssid(&self) -> &[u8] {
270        &self.0.bssid
271    }
272
273    /// Get the reason for the disconnection.
274    pub fn reason(&self) -> u8 {
275        self.0.reason
276    }
277
278    /// Get the authentication mode used for the disconnection.
279    pub fn rssi(&self) -> i8 {
280        self.0.rssi
281    }
282}
283
284/// All AP credentials received from WPS handshake.
285#[repr(transparent)]
286pub struct ApCredential(wifi_event_sta_wps_er_success_t__bindgen_ty_1);
287
288impl ApCredential {
289    /// Get the SSID of an AP.
290    pub fn ssid(&self) -> &[u8] {
291        &self.0.ssid
292    }
293
294    /// Get passphrase for the AP.
295    pub fn passphrase(&self) -> &[u8] {
296        &self.0.passphrase
297    }
298}
299
300impl StaAuthmodeChange<'_> {
301    /// Get the old authentication mode.
302    pub fn old_mode(&self) -> u32 {
303        self.0.old_mode
304    }
305
306    /// Get the new authentication mode.
307    pub fn new_mode(&self) -> u32 {
308        self.0.new_mode
309    }
310}
311
312impl StaWpsErSuccess<'_> {
313    /// Get number of AP credentials received.
314    pub fn ap_cred_cnt(&self) -> u8 {
315        self.0.ap_cred_cnt
316    }
317
318    /// Get all AP credentials received.
319    pub fn ap_cred(&self) -> &[ApCredential] {
320        let array_ref: &[ApCredential; 3] =
321            // cast reference of fixed-size array to wrapper type
322            unsafe { &*(&self.0.ap_cred as *const _ as *const [ApCredential; 3]) };
323
324        &array_ref[..]
325    }
326}
327
328impl StaWpsErPin<'_> {
329    /// Get the PIN code received from the WPS.
330    pub fn pin(&self) -> &[u8] {
331        &self.0.pin_code
332    }
333}
334
335/// A safe, read-only wrapper for a single FTM report entry.
336#[repr(transparent)]
337pub struct FtmReportEntry<'a>(&'a wifi_ftm_report_entry_t);
338
339impl FtmReportEntry<'_> {
340    /// Gets the Dialog Token of the FTM frame.
341    pub fn dialog_token(&self) -> u8 {
342        self.0.dlog_token
343    }
344
345    /// Gets the Received Signal Strength Indicator (RSSI) of the FTM frame.
346    pub fn rssi(&self) -> i8 {
347        self.0.rssi
348    }
349
350    /// Gets the Round Trip Time (RTT) in picoseconds.
351    pub fn rtt(&self) -> u32 {
352        self.0.rtt
353    }
354
355    /// Gets T1: Time of departure of the FTM frame from the Responder (in picoseconds).
356    pub fn t1(&self) -> u64 {
357        self.0.t1
358    }
359
360    /// Gets T2: Time of arrival of the FTM frame at the Initiator (in picoseconds).
361    pub fn t2(&self) -> u64 {
362        self.0.t2
363    }
364
365    /// Gets T3: Time of departure of the ACK from the Initiator (in picoseconds).
366    pub fn t3(&self) -> u64 {
367        self.0.t3
368    }
369
370    /// Gets T4: Time of arrival of the ACK at the Responder (in picoseconds).
371    pub fn t4(&self) -> u64 {
372        self.0.t4
373    }
374}
375
376impl FtmReport<'_> {
377    /// Get the MAC address of the FTM peer.
378    pub fn peer_mac(&self) -> &[u8] {
379        &self.0.peer_mac
380    }
381
382    /// Get the status of the FTM operation.
383    pub fn status(&self) -> u32 {
384        self.0.status
385    }
386
387    /// Get the raw round-trip time (RTT) in nanoseconds.
388    pub fn rtt_raw(&self) -> u32 {
389        self.0.rtt_raw
390    }
391
392    /// Get the estimated round-trip time (RTT) in nanoseconds.
393    pub fn rtt_est(&self) -> u32 {
394        self.0.rtt_est
395    }
396
397    /// Get the distance estimate in centimeters.
398    pub fn dist_est(&self) -> u32 {
399        self.0.dist_est
400    }
401
402    /// Get the number of entries in the FTM report data.
403    pub fn report_num_entries(&self) -> u8 {
404        self.0.ftm_report_num_entries
405    }
406
407    /// Returns an iterator over the detailed FTM report entries.
408    pub fn entries(&self) -> impl Iterator<Item = FtmReportEntry<'_>> + '_ {
409        let ptr = self.0.ftm_report_data;
410        let len = self.0.ftm_report_num_entries as usize;
411
412        // Return an empty slice when there are no entries.
413        let entries_slice = if ptr.is_null() || len == 0 {
414            &[]
415        } else {
416            // Otherwise, it's the slice from the data.
417            // Can we trust the C API to provide a valid pointer and length?
418            unsafe { core::slice::from_raw_parts(ptr, len) }
419        };
420
421        entries_slice.iter().map(FtmReportEntry)
422    }
423}
424
425impl ApProbeReqReceived<'_> {
426    /// Get received probe request SSID.
427    pub fn rssi(&self) -> i32 {
428        self.0.rssi
429    }
430
431    /// Get the MAC address of the station which send probe request.
432    pub fn mac(&self) -> &[u8] {
433        &self.0.mac
434    }
435}
436
437impl StaBssRssiLow<'_> {
438    /// Get received probe request SSID of bss.
439    pub fn rssi(&self) -> i32 {
440        self.0.rssi
441    }
442}
443
444impl ActionTxStatus<'_> {
445    /// Get Wi-Fi interface to send request to.
446    pub fn ifx(&self) -> u32 {
447        self.0.ifx
448    }
449
450    /// Get context to identify the request.
451    pub fn context(&self) -> u32 {
452        self.0.context
453    }
454
455    /// ID of the corresponding operation that was provided during action tx request.
456    pub fn op_id(&self) -> u8 {
457        self.0.op_id
458    }
459
460    /// Channel provided in tx request.
461    pub fn channel(&self) -> u8 {
462        self.0.channel
463    }
464
465    /// Get the status of the operation.
466    pub fn status(&self) -> u32 {
467        self.0.status
468    }
469}
470
471impl RocDone<'_> {
472    /// Get context to identify the request.
473    pub fn context(&self) -> u32 {
474        self.0.context
475    }
476}
477
478impl ApWpsRgSuccess<'_> {
479    /// Get enrollee mac address.
480    pub fn peer_mac(&self) -> &[u8] {
481        &self.0.peer_macaddr
482    }
483}
484
485impl ApWpsRgFailed<'_> {
486    /// Get WPS failure reason.
487    pub fn reason(&self) -> u32 {
488        self.0.reason
489    }
490
491    /// Get enrollee mac address.
492    pub fn peer_macaddr(&self) -> &[u8; 6] {
493        &self.0.peer_macaddr
494    }
495}
496
497impl ApWpsRgPin<'_> {
498    /// Get the PIN code of station in enrollee mode.
499    pub fn pin_code(&self) -> &[u8] {
500        &self.0.pin_code
501    }
502}
503
504impl NanSvcMatch<'_> {
505    /// Get the Subscribe Service ID.
506    pub fn subscribe_id(&self) -> u8 {
507        self.0.subscribe_id
508    }
509
510    /// Get the Publish Service ID.
511    pub fn publish_id(&self) -> u8 {
512        self.0.publish_id
513    }
514
515    /// Get the NAN Interface MAC of the Publisher.
516    pub fn pub_if_mac(&self) -> &[u8] {
517        &self.0.pub_if_mac
518    }
519
520    /// Indicates whether publisher’s service ID needs to be updated.
521    pub fn update_pub_id(&self) -> bool {
522        self.0.update_pub_id
523    }
524}
525
526impl NanReplied<'_> {
527    /// Get the Subscribe Service ID.
528    pub fn subscribe_id(&self) -> u8 {
529        self.0.subscribe_id
530    }
531
532    /// Get the Publish Service ID.
533    pub fn publish_id(&self) -> u8 {
534        self.0.publish_id
535    }
536
537    /// Get the NAN Interface MAC of the Subscriber.
538    pub fn sub_if_mac(&self) -> &[u8] {
539        &self.0.sub_if_mac
540    }
541}
542
543impl NanReceive<'_> {
544    /// Get Our Service Identifier.
545    pub fn inst_id(&self) -> u8 {
546        self.0.inst_id
547    }
548
549    /// Get Peer's Service Identifier.
550    pub fn peer_inst_id(&self) -> u8 {
551        self.0.peer_inst_id
552    }
553
554    /// Get Peer’s NAN Interface MAC
555    pub fn peer_if_mac(&self) -> &[u8; 6] {
556        &self.0.peer_if_mac
557    }
558
559    /// Get Peer Service Info.
560    pub fn peer_svc_info(&self) -> &[u8; 64] {
561        &self.0.peer_svc_info
562    }
563}
564
565impl NdpIndication<'_> {
566    /// Get Publish ID for NAN Service.
567    pub fn publish_id(&self) -> u8 {
568        self.0.publish_id
569    }
570
571    /// Get NDF instance ID.
572    pub fn ndp_id(&self) -> u8 {
573        self.0.ndp_id
574    }
575
576    /// Get Peer’s NAN Interface MAC.
577    pub fn peer_nmi(&self) -> &[u8; 6] {
578        &self.0.peer_nmi
579    }
580
581    /// Get Peer’s NAN Data Interface MAC.
582    pub fn peer_ndi(&self) -> &[u8; 6] {
583        &self.0.peer_ndi
584    }
585
586    /// Get Service Specific Info.
587    pub fn svc_info(&self) -> &[u8; 64] {
588        &self.0.svc_info
589    }
590}
591
592impl NdpConfirm<'_> {
593    /// Get NDP status code.
594    pub fn status(&self) -> u8 {
595        self.0.status
596    }
597
598    /// Get NDP instance ID.
599    pub fn id(&self) -> u8 {
600        self.0.ndp_id
601    }
602
603    /// Get Peer’s NAN Management Interface MAC.
604    pub fn peer_nmi(&self) -> &[u8; 6] {
605        &self.0.peer_nmi
606    }
607
608    /// Get Peer’s NAN Data Interface MAC.
609    pub fn peer_ndi(&self) -> &[u8; 6] {
610        &self.0.peer_ndi
611    }
612
613    /// Get Own NAN Data Interface MAC.
614    pub fn own_ndi(&self) -> &[u8; 6] {
615        &self.0.own_ndi
616    }
617
618    /// Get Service Specific Info.
619    pub fn svc_info(&self) -> &[u8; 64] {
620        &self.0.svc_info
621    }
622}
623
624impl NdpTerminated<'_> {
625    /// Get termination reason code.
626    pub fn reason(&self) -> u8 {
627        self.0.reason
628    }
629
630    /// Get NDP instance ID.
631    pub fn id(&self) -> u8 {
632        self.0.ndp_id
633    }
634
635    /// Get Initiator’s NAN Data Interface MAC
636    pub fn init_ndi(&self) -> &[u8; 6] {
637        &self.0.init_ndi
638    }
639}
640
641impl HomeChannelChange<'_> {
642    /// Get the old home channel of the device.
643    pub fn old_chan(&self) -> u8 {
644        self.0.old_chan
645    }
646
647    /// Get the old second channel of the device.
648    pub fn old_snd(&self) -> u32 {
649        self.0.old_snd
650    }
651
652    /// Get the new home channel of the device.
653    pub fn new_chan(&self) -> u8 {
654        self.0.new_chan
655    }
656
657    /// Get the new second channel of the device.
658    pub fn new_snd(&self) -> u32 {
659        self.0.new_snd
660    }
661}
662
663impl StaNeighborRep<'_> {
664    /// Get the Neighbor Report received from the AP.
665    pub fn report(&self) -> &[u8] {
666        &self.0.report[..self.0.report_len as usize]
667    }
668
669    /// Get the length of report.
670    pub fn report_len(&self) -> u16 {
671        self.0.report_len
672    }
673}
674
675/// Handle the given event using the registered event handlers.
676#[instability::unstable]
677pub fn handle<Event: EventExt>(event_data: &Event) -> bool {
678    Event::handler().with(|handler| {
679        if let Some(handler) = handler {
680            handler(event_data);
681            true
682        } else {
683            false
684        }
685    })
686}
687
688/// Handle an event given the raw pointers.
689///
690/// # Safety
691/// The pointer should be valid to cast to `Event`'s inner type (if it has one)
692pub(crate) unsafe fn handle_raw<Event: EventExt>(
693    event_data: *mut crate::binary::c_types::c_void,
694    _event_data_size: usize,
695) -> bool {
696    let event = unsafe { Event::from_raw_event_data(event_data) };
697    handle::<Event>(&event)
698}
699
700/// Handle event regardless of its type.
701///
702/// # Safety
703/// Arguments should be self-consistent.
704#[rustfmt::skip]
705pub(crate) unsafe fn dispatch_event_handler(
706    event: WifiEvent,
707    event_data: *mut crate::binary::c_types::c_void,
708    event_data_size: usize,
709) -> bool { unsafe {
710    match event {
711        WifiEvent::WifiReady => {
712            handle_raw::<WifiReady>(event_data, event_data_size)
713        }
714        WifiEvent::ScanDone => {
715            handle_raw::<ScanDone<'_>>(event_data, event_data_size)
716        }
717        WifiEvent::StaStart => {
718            handle_raw::<StaStart>(event_data, event_data_size)
719        }
720        WifiEvent::StaStop => {
721            handle_raw::<StaStop>(event_data, event_data_size)
722        }
723        WifiEvent::StaConnected => {
724            handle_raw::<StaConnected<'_>>(event_data, event_data_size)
725        }
726        WifiEvent::StaDisconnected => {
727            handle_raw::<StaDisconnected<'_>>(event_data, event_data_size)
728        }
729        WifiEvent::StaAuthmodeChange => {
730            handle_raw::<StaAuthmodeChange<'_>>(event_data, event_data_size)
731        }
732        WifiEvent::StaWpsErSuccess => {
733            handle_raw::<StaWpsErSuccess<'_>>(event_data, event_data_size)
734        }
735        WifiEvent::StaWpsErFailed => {
736            handle_raw::<StaWpsErFailed>(event_data, event_data_size)
737        }
738        WifiEvent::StaWpsErTimeout => {
739            handle_raw::<StaWpsErTimeout>(event_data, event_data_size)
740        }
741        WifiEvent::StaWpsErPin => {
742            handle_raw::<StaWpsErPin<'_>>(event_data, event_data_size)
743        }
744        WifiEvent::StaWpsErPbcOverlap => {
745            handle_raw::<StaWpsErPbcOverlap>(event_data, event_data_size)
746        }
747        WifiEvent::ApStart => {
748            handle_raw::<ApStart>(event_data, event_data_size)
749        }
750        WifiEvent::ApStop => {
751            handle_raw::<ApStop>(event_data, event_data_size)
752        }
753        WifiEvent::ApStaConnected => {
754            handle_raw::<ApStaConnected<'_>>(event_data, event_data_size)
755        }
756        WifiEvent::ApStaDisconnected => {
757            handle_raw::<ApStaDisconnected<'_>>(event_data, event_data_size)
758        }
759        WifiEvent::ApProbeReqReceived => {
760            handle_raw::<ApProbeReqReceived<'_>>(event_data, event_data_size)
761        }
762        WifiEvent::FtmReport => {
763            handle_raw::<FtmReport<'_>>(event_data, event_data_size)
764        }
765        WifiEvent::StaBssRssiLow => {
766            handle_raw::<StaBssRssiLow<'_>>(event_data, event_data_size)
767        }
768        WifiEvent::ActionTxStatus => {
769            handle_raw::<ActionTxStatus<'_>>(event_data, event_data_size)
770        }
771        WifiEvent::RocDone => {
772            handle_raw::<RocDone<'_>>(event_data, event_data_size)
773        }
774        WifiEvent::StaBeaconTimeout => {
775            handle_raw::<StaBeaconTimeout>(event_data, event_data_size)
776        }
777        WifiEvent::ConnectionlessModuleWakeIntervalStart => {
778            handle_raw::<ConnectionlessModuleWakeIntervalStart>(event_data, event_data_size)
779        }
780        WifiEvent::ApWpsRgSuccess => {
781            handle_raw::<ApWpsRgSuccess<'_>>(event_data, event_data_size)
782        }
783        WifiEvent::ApWpsRgFailed => {
784            handle_raw::<ApWpsRgFailed<'_>>(event_data, event_data_size)
785        }
786        WifiEvent::ApWpsRgTimeout => {
787            handle_raw::<ApWpsRgTimeout>(event_data, event_data_size)
788        }
789        WifiEvent::ApWpsRgPin => {
790            handle_raw::<ApWpsRgPin<'_>>(event_data, event_data_size)
791        }
792        WifiEvent::ApWpsRgPbcOverlap => {
793            handle_raw::<ApWpsRgPbcOverlap>(event_data, event_data_size)
794        }
795        WifiEvent::ItwtSetup => {
796            handle_raw::<ItwtSetup>(event_data, event_data_size)
797        }
798        WifiEvent::ItwtTeardown => {
799            handle_raw::<ItwtTeardown>(event_data, event_data_size)
800        }
801        WifiEvent::ItwtProbe => {
802            handle_raw::<ItwtProbe>(event_data, event_data_size)
803        }
804        WifiEvent::ItwtSuspend => {
805            handle_raw::<ItwtSuspend>(event_data, event_data_size)
806        }
807        WifiEvent::TwtWakeup => {
808            handle_raw::<TwtWakeup>(event_data, event_data_size)
809        }
810        WifiEvent::BtwtSetup => {
811            handle_raw::<BtwtSetup>(event_data, event_data_size)
812        }
813        WifiEvent::BtwtTeardown => {
814            handle_raw::<BtwtTeardown>(event_data, event_data_size)
815        }
816        WifiEvent::NanStarted => {
817            handle_raw::<NanStarted>(event_data, event_data_size)
818        }
819        WifiEvent::NanStopped => {
820            handle_raw::<NanStopped>(event_data, event_data_size)
821        }
822        WifiEvent::NanSvcMatch => {
823            handle_raw::<NanSvcMatch<'_>>(event_data, event_data_size)
824        }
825        WifiEvent::NanReplied => {
826            handle_raw::<NanReplied<'_>>(event_data, event_data_size)
827        }
828        WifiEvent::NanReceive => {
829            handle_raw::<NanReceive<'_>>(event_data, event_data_size)
830        }
831        WifiEvent::NdpIndication => {
832            handle_raw::<NdpIndication<'_>>(event_data, event_data_size)
833        }
834        WifiEvent::NdpConfirm => {
835            handle_raw::<NdpConfirm<'_>>(event_data, event_data_size)
836        }
837        WifiEvent::NdpTerminated => {
838            handle_raw::<NdpTerminated<'_>>(event_data, event_data_size)
839        }
840        WifiEvent::HomeChannelChange => {
841            handle_raw::<HomeChannelChange<'_>>(event_data, event_data_size)
842        }
843        WifiEvent::StaNeighborRep => {
844            handle_raw::<StaNeighborRep<'_>>(event_data, event_data_size)
845        }
846    }
847}}