From 9bb9bf73e58a7e0c1592c829f8e1bc5ad039db19 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Sun, 3 Nov 2024 04:30:35 -0700 Subject: [PATCH 01/13] implement event handling for apsta{,dis}connect and probe add to wifi_access_point example --- esp-wifi/src/wifi/event.rs | 52 +++++++++++++++++++++++++++ esp-wifi/src/wifi/mod.rs | 1 + esp-wifi/src/wifi/os_adapter.rs | 20 +++++++++++ examples/src/bin/wifi_access_point.rs | 36 +++++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 esp-wifi/src/wifi/event.rs diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs new file mode 100644 index 00000000000..90ab39a4048 --- /dev/null +++ b/esp-wifi/src/wifi/event.rs @@ -0,0 +1,52 @@ +use core::cell::RefCell; + +use critical_section::Mutex; + +mod sealed { + pub trait Sealed {} +} +/// The type of handlers of events. +pub type Handler = dyn FnMut(&T) + Sync + Send; +// fn default_handler<'a, T>(_: &'a T) {} +/// Data for a wifi event which can be handled by an event handler. +pub trait WifiEventData: sealed::Sealed + Sized + 'static { + /// Get the static reference to the handler for this event. + fn get_handler() -> &'static Mutex>>>; + + /// Get the handler for this event, replacing it with the default handler. + fn take_handler() -> Option<&'static mut Handler> { + critical_section::with(|cs| Self::get_handler().borrow_ref_mut(cs).take()) + } + /// Set the handler for this event. + fn set_handler(f: &'static mut Handler) { + critical_section::with(|cs| Self::get_handler().borrow_ref_mut(cs).replace(f)); + } + /// Atomic combination of `set_handler` and `get_handler`. Use this to add a + /// new handler while preserving the previous. + fn update_handler( + f: impl FnOnce(Option<&'static mut Handler>) -> &'static mut Handler, + ) { + critical_section::with(|cs| { + let handler = Self::take_handler(); + Self::get_handler().borrow_ref_mut(cs).replace(f(handler)) + }); + } +} + +macro_rules! impl_wifi_event_data { + ($ty:path) => { + pub use $ty; + impl sealed::Sealed for $ty {} + impl WifiEventData for $ty { + fn get_handler() -> &'static Mutex>>> { + static HANDLE: Mutex>>> = + Mutex::new(RefCell::new(None)); + &HANDLE + } + } + }; +} + +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_probe_req_rx_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_staconnected_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_stadisconnected_t); diff --git a/esp-wifi/src/wifi/mod.rs b/esp-wifi/src/wifi/mod.rs index 3d92900e855..4fea729ac67 100644 --- a/esp-wifi/src/wifi/mod.rs +++ b/esp-wifi/src/wifi/mod.rs @@ -1,5 +1,6 @@ //! WiFi +pub mod event; pub(crate) mod os_adapter; pub(crate) mod state; diff --git a/esp-wifi/src/wifi/os_adapter.rs b/esp-wifi/src/wifi/os_adapter.rs index c059c8c1a5f..fd1af8632bd 100644 --- a/esp-wifi/src/wifi/os_adapter.rs +++ b/esp-wifi/src/wifi/os_adapter.rs @@ -868,6 +868,26 @@ pub unsafe extern "C" fn event_post( trace!("EVENT: {:?}", event); critical_section::with(|cs| WIFI_EVENTS.borrow_ref_mut(cs).insert(event)); + // Call event handlers. + macro_rules! handle { + ($ty:ident) => {{ + use crate::wifi::event::{$ty, WifiEventData}; + assert_eq!(event_data_size, size_of::<$ty>(), "wrong size event data"); + critical_section::with(|cs| { + if let Some(handler) = &mut *$ty::get_handler().borrow_ref_mut(cs) { + // Safety: `event_id` should match the corresponding event data. + handler(unsafe { &*event_data.cast() }) + } + }); + }}; + } + match event { + WifiEvent::ApProbereqrecved => handle!(wifi_event_ap_probe_req_rx_t), + WifiEvent::ApStaconnected => handle!(wifi_event_ap_staconnected_t), + WifiEvent::ApStadisconnected => handle!(wifi_event_ap_stadisconnected_t), + _ => (), + } + super::state::update_state(event); #[cfg(feature = "async")] diff --git a/examples/src/bin/wifi_access_point.rs b/examples/src/bin/wifi_access_point.rs index fec2923ff79..b536b75de3d 100644 --- a/examples/src/bin/wifi_access_point.rs +++ b/examples/src/bin/wifi_access_point.rs @@ -14,6 +14,10 @@ #![no_std] #![no_main] +extern crate alloc; + +use alloc::boxed::Box; + use embedded_io::*; use esp_alloc as _; use esp_backtrace as _; @@ -27,6 +31,7 @@ use esp_println::{print, println}; use esp_wifi::{ init, wifi::{ + event::{self, WifiEventData}, utils::create_network_interface, AccessPointConfiguration, Configuration, @@ -58,6 +63,37 @@ fn main() -> ! { ) .unwrap(); + let mut connections = 0u32; + event::wifi_event_ap_staconnected_t::update_handler(|mut prev| { + Box::leak(Box::new(move |event| { + connections += 1; + esp_println::println!("connected {}, mac: {:?}", connections, event.mac); + if let Some(prev) = &mut prev { + prev(event) + }; + })) + }); + event::wifi_event_ap_staconnected_t::update_handler(|mut prev| { + Box::leak(Box::new(move |event| { + esp_println::println!("connected aid: {}", event.aid); + if let Some(prev) = &mut prev { + prev(event) + }; + })) + }); + event::wifi_event_ap_stadisconnected_t::update_handler(|mut prev| { + Box::leak(Box::new(move |event| { + if let Some(prev) = &mut prev { + prev(event) + }; + esp_println::println!( + "disconnected mac: {:?}, reason: {:?}", + event.mac, + event.reason + ); + })) + }); + let mut wifi = peripherals.WIFI; let mut socket_set_entries: [SocketStorage; 3] = Default::default(); let (iface, device, mut controller, sockets) = From 0c1a3dc539f4c01a9d4cfee3eae0010913342e32 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Sun, 3 Nov 2024 16:19:07 -0700 Subject: [PATCH 02/13] hide internal `Option` to simplify api --- esp-wifi/src/wifi/event.rs | 68 +++++++++++++++++++-------- esp-wifi/src/wifi/os_adapter.rs | 2 +- examples/src/bin/wifi_access_point.rs | 18 +++---- 3 files changed, 55 insertions(+), 33 deletions(-) diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs index 90ab39a4048..9c454327774 100644 --- a/esp-wifi/src/wifi/event.rs +++ b/esp-wifi/src/wifi/event.rs @@ -2,33 +2,61 @@ use core::cell::RefCell; use critical_section::Mutex; -mod sealed { - pub trait Sealed {} +pub(crate) mod sealed { + use super::*; + + pub trait Sealed { + /// Get the static reference to the handler for this event. + fn get_handler() -> &'static Mutex>>>; + } } /// The type of handlers of events. pub type Handler = dyn FnMut(&T) + Sync + Send; -// fn default_handler<'a, T>(_: &'a T) {} + +fn default_handler() -> &'static mut Handler { + fn nop<'a, T>(_: &'a T) {} + fn size_of_val(_: &mut T) -> usize { + core::mem::size_of::() + } + + // Be paranoid about coercing from a zero sized pointee + let a = &mut nop::; + debug_assert_eq!(0, size_of_val(a)); + let a: &mut Handler = a; + // SAFETY: We're extending the lifetime of a borrow of a technically local + // variable, but the pointee is a ZST (and the vtable is static). If exclusive + // references to function item types had the same magic as empty arrays and + // slices, this wouldn't be necessary. See + // and + unsafe { &mut *(a as *mut Handler) } +} + /// Data for a wifi event which can be handled by an event handler. pub trait WifiEventData: sealed::Sealed + Sized + 'static { - /// Get the static reference to the handler for this event. - fn get_handler() -> &'static Mutex>>>; - /// Get the handler for this event, replacing it with the default handler. - fn take_handler() -> Option<&'static mut Handler> { - critical_section::with(|cs| Self::get_handler().borrow_ref_mut(cs).take()) - } - /// Set the handler for this event. - fn set_handler(f: &'static mut Handler) { - critical_section::with(|cs| Self::get_handler().borrow_ref_mut(cs).replace(f)); + fn take_handler() -> &'static mut Handler { + critical_section::with(|cs| { + Self::get_handler() + .borrow_ref_mut(cs) + .take() + .unwrap_or(default_handler::()) + }) } - /// Atomic combination of `set_handler` and `get_handler`. Use this to add a - /// new handler while preserving the previous. - fn update_handler( - f: impl FnOnce(Option<&'static mut Handler>) -> &'static mut Handler, - ) { + /// Set the handler for this event, returning the old handler. + fn replace_handler(f: &'static mut Handler) -> &'static mut Handler { critical_section::with(|cs| { + Self::get_handler() + .borrow_ref_mut(cs) + .replace(f) + .unwrap_or(default_handler::()) + }) + } + /// Atomic combination of `take_handler` and `replace_handler`. Use this to + /// add a new handler while preserving the previous. + fn update_handler(f: impl FnOnce(&'static mut Handler) -> &'static mut Handler) { + critical_section::with(|_cs| { let handler = Self::take_handler(); - Self::get_handler().borrow_ref_mut(cs).replace(f(handler)) + Self::replace_handler(f(handler)); }); } } @@ -36,14 +64,14 @@ pub trait WifiEventData: sealed::Sealed + Sized + 'static { macro_rules! impl_wifi_event_data { ($ty:path) => { pub use $ty; - impl sealed::Sealed for $ty {} - impl WifiEventData for $ty { + impl sealed::Sealed for $ty { fn get_handler() -> &'static Mutex>>> { static HANDLE: Mutex>>> = Mutex::new(RefCell::new(None)); &HANDLE } } + impl WifiEventData for $ty {} }; } diff --git a/esp-wifi/src/wifi/os_adapter.rs b/esp-wifi/src/wifi/os_adapter.rs index fd1af8632bd..c438b5dc52a 100644 --- a/esp-wifi/src/wifi/os_adapter.rs +++ b/esp-wifi/src/wifi/os_adapter.rs @@ -871,7 +871,7 @@ pub unsafe extern "C" fn event_post( // Call event handlers. macro_rules! handle { ($ty:ident) => {{ - use crate::wifi::event::{$ty, WifiEventData}; + use crate::wifi::event::{sealed::Sealed, $ty}; assert_eq!(event_data_size, size_of::<$ty>(), "wrong size event data"); critical_section::with(|cs| { if let Some(handler) = &mut *$ty::get_handler().borrow_ref_mut(cs) { diff --git a/examples/src/bin/wifi_access_point.rs b/examples/src/bin/wifi_access_point.rs index b536b75de3d..05a3ac38122 100644 --- a/examples/src/bin/wifi_access_point.rs +++ b/examples/src/bin/wifi_access_point.rs @@ -64,28 +64,22 @@ fn main() -> ! { .unwrap(); let mut connections = 0u32; - event::wifi_event_ap_staconnected_t::update_handler(|mut prev| { + event::wifi_event_ap_staconnected_t::update_handler(|prev| { Box::leak(Box::new(move |event| { connections += 1; esp_println::println!("connected {}, mac: {:?}", connections, event.mac); - if let Some(prev) = &mut prev { - prev(event) - }; + prev(event); })) }); - event::wifi_event_ap_staconnected_t::update_handler(|mut prev| { + event::wifi_event_ap_staconnected_t::update_handler(|prev| { Box::leak(Box::new(move |event| { esp_println::println!("connected aid: {}", event.aid); - if let Some(prev) = &mut prev { - prev(event) - }; + prev(event) })) }); - event::wifi_event_ap_stadisconnected_t::update_handler(|mut prev| { + event::wifi_event_ap_stadisconnected_t::update_handler(|prev| { Box::leak(Box::new(move |event| { - if let Some(prev) = &mut prev { - prev(event) - }; + prev(event); esp_println::println!( "disconnected mac: {:?}, reason: {:?}", event.mac, From 44dc7fdf9a6b309b3846de74c70c0cdb4a448e07 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:36:55 -0700 Subject: [PATCH 03/13] move handler call logic to event.rs --- esp-wifi/src/wifi/event.rs | 11 +++++++++++ esp-wifi/src/wifi/os_adapter.rs | 17 +++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs index 9c454327774..badde1681e5 100644 --- a/esp-wifi/src/wifi/event.rs +++ b/esp-wifi/src/wifi/event.rs @@ -78,3 +78,14 @@ macro_rules! impl_wifi_event_data { impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_probe_req_rx_t); impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_staconnected_t); impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_stadisconnected_t); + +/// Handle the given event using the registered event handlers. +pub fn handle(event_data: &E, event_data_size: usize) { + debug_assert_eq!(event_data_size, size_of::(), "wrong size event data"); + critical_section::with(|cs| { + if let Some(handler) = &mut *E::get_handler().borrow_ref_mut(cs) { + // Safety: `event_id` should match the corresponding event data. + handler(event_data) + } + }); +} diff --git a/esp-wifi/src/wifi/os_adapter.rs b/esp-wifi/src/wifi/os_adapter.rs index c438b5dc52a..3b1f38bd93f 100644 --- a/esp-wifi/src/wifi/os_adapter.rs +++ b/esp-wifi/src/wifi/os_adapter.rs @@ -870,16 +870,13 @@ pub unsafe extern "C" fn event_post( // Call event handlers. macro_rules! handle { - ($ty:ident) => {{ - use crate::wifi::event::{sealed::Sealed, $ty}; - assert_eq!(event_data_size, size_of::<$ty>(), "wrong size event data"); - critical_section::with(|cs| { - if let Some(handler) = &mut *$ty::get_handler().borrow_ref_mut(cs) { - // Safety: `event_id` should match the corresponding event data. - handler(unsafe { &*event_data.cast() }) - } - }); - }}; + ($ty:ident) => { + crate::wifi::event::handle::( + // Safety: The `event_data` should be correct based on the event_id. + unsafe { &*event_data.cast() }, + event_data_size, + ) + }; } match event { WifiEvent::ApProbereqrecved => handle!(wifi_event_ap_probe_req_rx_t), From 030ec1f3e823f0333e0e7e5de9d25180741e2f21 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Sun, 3 Nov 2024 22:58:45 -0700 Subject: [PATCH 04/13] update_handler_leak --- esp-wifi/src/wifi/event.rs | 10 ++++++++++ examples/src/bin/wifi_access_point.rs | 22 +++++++++------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs index badde1681e5..1bb1ee6eb3d 100644 --- a/esp-wifi/src/wifi/event.rs +++ b/esp-wifi/src/wifi/event.rs @@ -1,3 +1,4 @@ +use alloc::boxed::Box; use core::cell::RefCell; use critical_section::Mutex; @@ -59,6 +60,15 @@ pub trait WifiEventData: sealed::Sealed + Sized + 'static { Self::replace_handler(f(handler)); }); } + /// Same as [`update_handler`] but leaks the handler internally. + fn update_handler_leak( + f: impl FnOnce(&'static mut Handler) -> F, + ) { + critical_section::with(|_cs| { + let handler = Self::take_handler(); + Self::replace_handler(Box::leak(Box::new(f(handler)))); + }); + } } macro_rules! impl_wifi_event_data { diff --git a/examples/src/bin/wifi_access_point.rs b/examples/src/bin/wifi_access_point.rs index 05a3ac38122..bf4feafdb77 100644 --- a/examples/src/bin/wifi_access_point.rs +++ b/examples/src/bin/wifi_access_point.rs @@ -14,10 +14,6 @@ #![no_std] #![no_main] -extern crate alloc; - -use alloc::boxed::Box; - use embedded_io::*; use esp_alloc as _; use esp_backtrace as _; @@ -64,28 +60,28 @@ fn main() -> ! { .unwrap(); let mut connections = 0u32; - event::wifi_event_ap_staconnected_t::update_handler(|prev| { - Box::leak(Box::new(move |event| { + event::wifi_event_ap_staconnected_t::update_handler_leak(|prev| { + move |event| { connections += 1; esp_println::println!("connected {}, mac: {:?}", connections, event.mac); prev(event); - })) + } }); - event::wifi_event_ap_staconnected_t::update_handler(|prev| { - Box::leak(Box::new(move |event| { + event::wifi_event_ap_staconnected_t::update_handler_leak(|prev| { + move |event| { esp_println::println!("connected aid: {}", event.aid); prev(event) - })) + } }); - event::wifi_event_ap_stadisconnected_t::update_handler(|prev| { - Box::leak(Box::new(move |event| { + event::wifi_event_ap_stadisconnected_t::update_handler_leak(|prev| { + move |event| { prev(event); esp_println::println!( "disconnected mac: {:?}, reason: {:?}", event.mac, event.reason ); - })) + } }); let mut wifi = peripherals.WIFI; From 0998748e142e3bcdcd68e9a6f5c46f98769def0b Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:37:50 -0700 Subject: [PATCH 05/13] - Add comments - match simpler api from `std::panic::update_hook` - do not assume size_of in prelude - make all events handleable - box static instead of leak --- esp-wifi/src/wifi/event.rs | 222 ++++++++++++++++++++------ esp-wifi/src/wifi/os_adapter.rs | 17 +- examples/src/bin/wifi_access_point.rs | 36 ++--- 3 files changed, 193 insertions(+), 82 deletions(-) diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs index 1bb1ee6eb3d..88de72911bc 100644 --- a/esp-wifi/src/wifi/event.rs +++ b/esp-wifi/src/wifi/event.rs @@ -3,39 +3,42 @@ use core::cell::RefCell; use critical_section::Mutex; +use super::WifiEvent; + pub(crate) mod sealed { use super::*; - pub trait Sealed { + pub trait Event { /// Get the static reference to the handler for this event. - fn get_handler() -> &'static Mutex>>>; + fn get_handler() -> &'static Mutex>>>>; } } /// The type of handlers of events. pub type Handler = dyn FnMut(&T) + Sync + Send; -fn default_handler() -> &'static mut Handler { +fn default_handler() -> Box> { fn nop<'a, T>(_: &'a T) {} - fn size_of_val(_: &mut T) -> usize { - core::mem::size_of::() - } - - // Be paranoid about coercing from a zero sized pointee - let a = &mut nop::; - debug_assert_eq!(0, size_of_val(a)); - let a: &mut Handler = a; - // SAFETY: We're extending the lifetime of a borrow of a technically local - // variable, but the pointee is a ZST (and the vtable is static). If exclusive - // references to function item types had the same magic as empty arrays and - // slices, this wouldn't be necessary. See - // and - unsafe { &mut *(a as *mut Handler) } + Box::new(nop) } -/// Data for a wifi event which can be handled by an event handler. -pub trait WifiEventData: sealed::Sealed + Sized + 'static { +/// Extension trait for setting handlers for an event. +/// +/// Register a new event handler like: +/// ``` +/// # use esp_wifi::wifi::event::{self, *}; +/// # fn new_handler(_: &wifi_event_ap_stadisconnected_t) {} +/// event::wifi_event_ap_stadisconnected_t::update_handler(|prev, event| { +/// prev(event); +/// new_handler(event); +/// }) +/// ``` +// Implemented like this instead of free functions because the syntax would be +// ``` +// event::update_handler::(...) +// ``` +pub trait EventExt: sealed::Event + Sized + 'static { /// Get the handler for this event, replacing it with the default handler. - fn take_handler() -> &'static mut Handler { + fn take_handler() -> Box> { critical_section::with(|cs| { Self::get_handler() .borrow_ref_mut(cs) @@ -44,58 +47,187 @@ pub trait WifiEventData: sealed::Sealed + Sized + 'static { }) } /// Set the handler for this event, returning the old handler. - fn replace_handler(f: &'static mut Handler) -> &'static mut Handler { + fn replace_handler(f: F) -> Box> { critical_section::with(|cs| { Self::get_handler() .borrow_ref_mut(cs) - .replace(f) + .replace(Box::new(f)) .unwrap_or(default_handler::()) }) } - /// Atomic combination of `take_handler` and `replace_handler`. Use this to - /// add a new handler while preserving the previous. - fn update_handler(f: impl FnOnce(&'static mut Handler) -> &'static mut Handler) { - critical_section::with(|_cs| { - let handler = Self::take_handler(); - Self::replace_handler(f(handler)); - }); - } - /// Same as [`update_handler`] but leaks the handler internally. - fn update_handler_leak( - f: impl FnOnce(&'static mut Handler) -> F, - ) { - critical_section::with(|_cs| { - let handler = Self::take_handler(); - Self::replace_handler(Box::leak(Box::new(f(handler)))); + /// Atomic combination of [`take_handler`] and [`replace_handler`]. Use this + /// to add a new handler while preserving the previous. + fn update_handler, &Self) + Sync + Send + 'static>(mut f: F) { + critical_section::with(move |cs| { + let mut handler: Box> = Self::take_handler(); + Self::get_handler() + .borrow_ref_mut(cs) + .replace(Box::new(move |event| f(&mut handler, event))); }); } } +impl EventExt for T {} macro_rules! impl_wifi_event_data { ($ty:path) => { pub use $ty; - impl sealed::Sealed for $ty { - fn get_handler() -> &'static Mutex>>> { - static HANDLE: Mutex>>> = + impl sealed::Event for $ty { + fn get_handler() -> &'static Mutex>>>> { + static HANDLE: Mutex>>>> = Mutex::new(RefCell::new(None)); &HANDLE } } - impl WifiEventData for $ty {} }; } +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_action_tx_status_t); impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_probe_req_rx_t); impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_staconnected_t); impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_stadisconnected_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_wps_rg_fail_reason_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_wps_rg_pin_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_wps_rg_success_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_bss_rssi_low_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ftm_report_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_home_channel_change_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_nan_receive_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_nan_replied_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_nan_svc_match_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ndp_confirm_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ndp_indication_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ndp_terminated_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_neighbor_report_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_roc_done_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_sta_authmode_change_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_sta_connected_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_sta_disconnected_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_sta_wps_er_pin_t); +impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_sta_wps_er_success_t); /// Handle the given event using the registered event handlers. -pub fn handle(event_data: &E, event_data_size: usize) { - debug_assert_eq!(event_data_size, size_of::(), "wrong size event data"); +pub fn handle(event_data: &Event) { critical_section::with(|cs| { - if let Some(handler) = &mut *E::get_handler().borrow_ref_mut(cs) { - // Safety: `event_id` should match the corresponding event data. + if let Some(handler) = &mut *Event::get_handler().borrow_ref_mut(cs) { handler(event_data) } }); } + +/// Handle an event given the raw pointers. +/// # Safety +/// The pointer should be valid to cast to `Event` +pub(crate) unsafe fn handle_raw( + event_data: *mut crate::binary::c_types::c_void, + event_data_size: usize, +) { + debug_assert_eq!( + event_data_size, + core::mem::size_of::(), + "wrong size event data" + ); + handle::(unsafe { &*event_data.cast() }) +} + +/// Handle event regardless of its type. +/// # Safety +/// Arguments should be self-consistent. +pub(crate) unsafe fn dispatch_event_handler( + event: WifiEvent, + event_data: *mut crate::binary::c_types::c_void, + event_data_size: usize, +) { + match event { + WifiEvent::WifiReady => {} + WifiEvent::ScanDone => {} + WifiEvent::StaStart => {} + WifiEvent::StaStop => {} + WifiEvent::StaConnected => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::StaDisconnected => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::StaAuthmodeChange => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::StaWpsErSuccess => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::StaWpsErFailed => {} + WifiEvent::StaWpsErTimeout => {} + WifiEvent::StaWpsErPin => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::StaWpsErPbcOverlap => {} + WifiEvent::ApStart => {} + WifiEvent::ApStop => {} + WifiEvent::ApStaconnected => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::ApStadisconnected => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::ApProbereqrecved => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::FtmReport => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::StaBssRssiLow => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::ActionTxStatus => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::RocDone => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::StaBeaconTimeout => {} + WifiEvent::ConnectionlessModuleWakeIntervalStart => {} + WifiEvent::ApWpsRgSuccess => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::ApWpsRgFailed => unsafe { + handle_raw::(event_data, event_data_size); + }, + WifiEvent::ApWpsRgTimeout => {} + WifiEvent::ApWpsRgPin => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::ApWpsRgPbcOverlap => {} + WifiEvent::ItwtSetup => {} + WifiEvent::ItwtTeardown => {} + WifiEvent::ItwtProbe => {} + WifiEvent::ItwtSuspend => {} + WifiEvent::TwtWakeup => {} + WifiEvent::BtwtSetup => {} + WifiEvent::BtwtTeardown => {} + WifiEvent::NanStarted => {} + WifiEvent::NanStopped => {} + WifiEvent::NanSvcMatch => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::NanReplied => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::NanReceive => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::NdpIndication => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::NdpConfirm => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::NdpTerminated => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::HomeChannelChange => unsafe { + handle_raw::(event_data, event_data_size) + }, + WifiEvent::StaNeighborRep => unsafe { + handle_raw::(event_data, event_data_size) + }, + } +} diff --git a/esp-wifi/src/wifi/os_adapter.rs b/esp-wifi/src/wifi/os_adapter.rs index 3b1f38bd93f..2aaf8b266c7 100644 --- a/esp-wifi/src/wifi/os_adapter.rs +++ b/esp-wifi/src/wifi/os_adapter.rs @@ -868,22 +868,7 @@ pub unsafe extern "C" fn event_post( trace!("EVENT: {:?}", event); critical_section::with(|cs| WIFI_EVENTS.borrow_ref_mut(cs).insert(event)); - // Call event handlers. - macro_rules! handle { - ($ty:ident) => { - crate::wifi::event::handle::( - // Safety: The `event_data` should be correct based on the event_id. - unsafe { &*event_data.cast() }, - event_data_size, - ) - }; - } - match event { - WifiEvent::ApProbereqrecved => handle!(wifi_event_ap_probe_req_rx_t), - WifiEvent::ApStaconnected => handle!(wifi_event_ap_staconnected_t), - WifiEvent::ApStadisconnected => handle!(wifi_event_ap_stadisconnected_t), - _ => (), - } + super::event::dispatch_event_handler(event, event_data, event_data_size); super::state::update_state(event); diff --git a/examples/src/bin/wifi_access_point.rs b/examples/src/bin/wifi_access_point.rs index bf4feafdb77..e0081c7a4e8 100644 --- a/examples/src/bin/wifi_access_point.rs +++ b/examples/src/bin/wifi_access_point.rs @@ -27,7 +27,7 @@ use esp_println::{print, println}; use esp_wifi::{ init, wifi::{ - event::{self, WifiEventData}, + event::{self, EventExt}, utils::create_network_interface, AccessPointConfiguration, Configuration, @@ -60,28 +60,22 @@ fn main() -> ! { .unwrap(); let mut connections = 0u32; - event::wifi_event_ap_staconnected_t::update_handler_leak(|prev| { - move |event| { - connections += 1; - esp_println::println!("connected {}, mac: {:?}", connections, event.mac); - prev(event); - } + event::wifi_event_ap_staconnected_t::update_handler(move |prev, event| { + connections += 1; + esp_println::println!("connected {}, mac: {:?}", connections, event.mac); + prev(event); }); - event::wifi_event_ap_staconnected_t::update_handler_leak(|prev| { - move |event| { - esp_println::println!("connected aid: {}", event.aid); - prev(event) - } + event::wifi_event_ap_staconnected_t::update_handler(|prev, event| { + esp_println::println!("connected aid: {}", event.aid); + prev(event) }); - event::wifi_event_ap_stadisconnected_t::update_handler_leak(|prev| { - move |event| { - prev(event); - esp_println::println!( - "disconnected mac: {:?}, reason: {:?}", - event.mac, - event.reason - ); - } + event::wifi_event_ap_stadisconnected_t::update_handler(|prev, event| { + prev(event); + esp_println::println!( + "disconnected mac: {:?}, reason: {:?}", + event.mac, + event.reason + ); }); let mut wifi = peripherals.WIFI; From d30caaef5860a40ba5480462a70e6cd658c1291a Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Mon, 4 Nov 2024 18:03:59 -0700 Subject: [PATCH 06/13] update changelog --- esp-wifi/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/esp-wifi/CHANGELOG.md b/esp-wifi/CHANGELOG.md index aa932a0287a..1ba3cbd9079 100644 --- a/esp-wifi/CHANGELOG.md +++ b/esp-wifi/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added `serde` support through the `serde` feature (#2346) +- Enable setting event handlers for wifi events (#2453) ### Changed From ef99a3831cb6857a3e036935d7e6f9df73e5f682 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Mon, 4 Nov 2024 21:41:56 -0700 Subject: [PATCH 07/13] elide lifetime on default handler --- esp-wifi/src/wifi/event.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs index 88de72911bc..5495cb2f836 100644 --- a/esp-wifi/src/wifi/event.rs +++ b/esp-wifi/src/wifi/event.rs @@ -17,8 +17,8 @@ pub(crate) mod sealed { pub type Handler = dyn FnMut(&T) + Sync + Send; fn default_handler() -> Box> { - fn nop<'a, T>(_: &'a T) {} - Box::new(nop) + fn drop_ref(_: &T) {} + Box::new(drop_ref) } /// Extension trait for setting handlers for an event. From 350c4ffd7dff86ca289282e3f153e7047b5b1bb8 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:39:41 -0700 Subject: [PATCH 08/13] newtypes for all event types. --- esp-wifi/src/wifi/event.rs | 332 ++++++++++++++++---------- examples/src/bin/wifi_access_point.rs | 32 +-- 2 files changed, 228 insertions(+), 136 deletions(-) diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs index 5495cb2f836..e8be514c341 100644 --- a/esp-wifi/src/wifi/event.rs +++ b/esp-wifi/src/wifi/event.rs @@ -11,6 +11,9 @@ pub(crate) mod sealed { pub trait Event { /// Get the static reference to the handler for this event. fn get_handler() -> &'static Mutex>>>>; + /// # Safety + /// `ptr` must be a valid for casting to this event's inner event data. + unsafe fn from_raw_event_data(ptr: *mut crate::binary::c_types::c_void) -> Self; } } /// The type of handlers of events. @@ -68,12 +71,33 @@ pub trait EventExt: sealed::Event + Sized + 'static { } impl EventExt for T {} -macro_rules! impl_wifi_event_data { - ($ty:path) => { - pub use $ty; - impl sealed::Event for $ty { +macro_rules! impl_wifi_event { + // no data + ($newtype:ident) => { + #[derive(Copy, Clone)] + pub struct $newtype; + impl sealed::Event for $newtype { + unsafe fn from_raw_event_data(_: *mut crate::binary::c_types::c_void) -> Self { + Self + } + fn get_handler() -> &'static Mutex>>>> { + static HANDLE: Mutex>>>> = + Mutex::new(RefCell::new(None)); + &HANDLE + } + } + }; + // data + ($newtype:ident, $data:ident) => { + pub use esp_wifi_sys::include::$data; + #[derive(Copy, Clone)] + pub struct $newtype(pub $data); + impl sealed::Event for $newtype { + unsafe fn from_raw_event_data(ptr: *mut crate::binary::c_types::c_void) -> Self { + Self(unsafe { *ptr.cast() }) + } fn get_handler() -> &'static Mutex>>>> { - static HANDLE: Mutex>>>> = + static HANDLE: Mutex>>>> = Mutex::new(RefCell::new(None)); &HANDLE } @@ -81,29 +105,51 @@ macro_rules! impl_wifi_event_data { }; } -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_action_tx_status_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_probe_req_rx_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_staconnected_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_stadisconnected_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_wps_rg_fail_reason_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_wps_rg_pin_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ap_wps_rg_success_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_bss_rssi_low_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ftm_report_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_home_channel_change_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_nan_receive_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_nan_replied_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_nan_svc_match_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ndp_confirm_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ndp_indication_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_ndp_terminated_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_neighbor_report_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_roc_done_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_sta_authmode_change_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_sta_connected_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_sta_disconnected_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_sta_wps_er_pin_t); -impl_wifi_event_data!(esp_wifi_sys::include::wifi_event_sta_wps_er_success_t); +impl_wifi_event!(WifiReady); +impl_wifi_event!(ScanDone); +impl_wifi_event!(StaStart); +impl_wifi_event!(StaStop); +impl_wifi_event!(StaConnected, wifi_event_sta_connected_t); +impl_wifi_event!(StaDisconnected, wifi_event_sta_disconnected_t); +impl_wifi_event!(StaAuthmodeChange, wifi_event_sta_authmode_change_t); +impl_wifi_event!(StaWpsErSuccess, wifi_event_sta_wps_er_success_t); +impl_wifi_event!(StaWpsErFailed); +impl_wifi_event!(StaWpsErTimeout); +impl_wifi_event!(StaWpsErPin, wifi_event_sta_wps_er_pin_t); +impl_wifi_event!(StaWpsErPbcOverlap); +impl_wifi_event!(ApStart); +impl_wifi_event!(ApStop); +impl_wifi_event!(ApStaconnected, wifi_event_ap_staconnected_t); +impl_wifi_event!(ApStadisconnected, wifi_event_ap_stadisconnected_t); +impl_wifi_event!(ApProbereqrecved, wifi_event_ap_probe_req_rx_t); +impl_wifi_event!(FtmReport, wifi_event_ftm_report_t); +impl_wifi_event!(StaBssRssiLow, wifi_event_bss_rssi_low_t); +impl_wifi_event!(ActionTxStatus, wifi_event_action_tx_status_t); +impl_wifi_event!(RocDone, wifi_event_roc_done_t); +impl_wifi_event!(StaBeaconTimeout); +impl_wifi_event!(ConnectionlessModuleWakeIntervalStart); +impl_wifi_event!(ApWpsRgSuccess, wifi_event_ap_wps_rg_success_t); +impl_wifi_event!(ApWpsRgFailed, wifi_event_ap_wps_rg_fail_reason_t); +impl_wifi_event!(ApWpsRgTimeout); +impl_wifi_event!(ApWpsRgPin, wifi_event_ap_wps_rg_pin_t); +impl_wifi_event!(ApWpsRgPbcOverlap); +impl_wifi_event!(ItwtSetup); +impl_wifi_event!(ItwtTeardown); +impl_wifi_event!(ItwtProbe); +impl_wifi_event!(ItwtSuspend); +impl_wifi_event!(TwtWakeup); +impl_wifi_event!(BtwtSetup); +impl_wifi_event!(BtwtTeardown); +impl_wifi_event!(NanStarted); +impl_wifi_event!(NanStopped); +impl_wifi_event!(NanSvcMatch, wifi_event_nan_svc_match_t); +impl_wifi_event!(NanReplied, wifi_event_nan_replied_t); +impl_wifi_event!(NanReceive, wifi_event_nan_receive_t); +impl_wifi_event!(NdpIndication, wifi_event_ndp_indication_t); +impl_wifi_event!(NdpConfirm, wifi_event_ndp_confirm_t); +impl_wifi_event!(NdpTerminated, wifi_event_ndp_terminated_t); +impl_wifi_event!(HomeChannelChange, wifi_event_home_channel_change_t); +impl_wifi_event!(StaNeighborRep, wifi_event_neighbor_report_t); /// Handle the given event using the registered event handlers. pub fn handle(event_data: &Event) { @@ -116,7 +162,7 @@ pub fn handle(event_data: &Event) { /// Handle an event given the raw pointers. /// # Safety -/// The pointer should be valid to cast to `Event` +/// The pointer should be valid to cast to `Event`'s inner type (if it has one) pub(crate) unsafe fn handle_raw( event_data: *mut crate::binary::c_types::c_void, event_data_size: usize, @@ -126,7 +172,7 @@ pub(crate) unsafe fn handle_raw( core::mem::size_of::(), "wrong size event data" ); - handle::(unsafe { &*event_data.cast() }) + handle::(unsafe { &Event::from_raw_event_data(event_data) }) } /// Handle event regardless of its type. @@ -138,96 +184,140 @@ pub(crate) unsafe fn dispatch_event_handler( event_data_size: usize, ) { match event { - WifiEvent::WifiReady => {} - WifiEvent::ScanDone => {} - WifiEvent::StaStart => {} - WifiEvent::StaStop => {} - WifiEvent::StaConnected => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::StaDisconnected => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::StaAuthmodeChange => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::StaWpsErSuccess => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::StaWpsErFailed => {} - WifiEvent::StaWpsErTimeout => {} - WifiEvent::StaWpsErPin => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::StaWpsErPbcOverlap => {} - WifiEvent::ApStart => {} - WifiEvent::ApStop => {} - WifiEvent::ApStaconnected => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::ApStadisconnected => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::ApProbereqrecved => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::FtmReport => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::StaBssRssiLow => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::ActionTxStatus => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::RocDone => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::StaBeaconTimeout => {} - WifiEvent::ConnectionlessModuleWakeIntervalStart => {} - WifiEvent::ApWpsRgSuccess => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::ApWpsRgFailed => unsafe { - handle_raw::(event_data, event_data_size); - }, - WifiEvent::ApWpsRgTimeout => {} - WifiEvent::ApWpsRgPin => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::ApWpsRgPbcOverlap => {} - WifiEvent::ItwtSetup => {} - WifiEvent::ItwtTeardown => {} - WifiEvent::ItwtProbe => {} - WifiEvent::ItwtSuspend => {} - WifiEvent::TwtWakeup => {} - WifiEvent::BtwtSetup => {} - WifiEvent::BtwtTeardown => {} - WifiEvent::NanStarted => {} - WifiEvent::NanStopped => {} - WifiEvent::NanSvcMatch => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::NanReplied => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::NanReceive => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::NdpIndication => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::NdpConfirm => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::NdpTerminated => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::HomeChannelChange => unsafe { - handle_raw::(event_data, event_data_size) - }, - WifiEvent::StaNeighborRep => unsafe { - handle_raw::(event_data, event_data_size) - }, + WifiEvent::WifiReady => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ScanDone => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaStart => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaStop => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaConnected => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaDisconnected => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaAuthmodeChange => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaWpsErSuccess => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaWpsErFailed => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaWpsErTimeout => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaWpsErPin => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaWpsErPbcOverlap => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ApStart => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ApStop => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ApStaconnected => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ApStadisconnected => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ApProbereqrecved => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::FtmReport => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaBssRssiLow => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ActionTxStatus => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::RocDone => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaBeaconTimeout => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ConnectionlessModuleWakeIntervalStart => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ApWpsRgSuccess => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ApWpsRgFailed => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ApWpsRgTimeout => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ApWpsRgPin => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ApWpsRgPbcOverlap => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ItwtSetup => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ItwtTeardown => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ItwtProbe => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::ItwtSuspend => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::TwtWakeup => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::BtwtSetup => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::BtwtTeardown => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::NanStarted => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::NanStopped => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::NanSvcMatch => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::NanReplied => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::NanReceive => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::NdpIndication => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::NdpConfirm => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::NdpTerminated => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::HomeChannelChange => { + handle_raw::(event_data, event_data_size); + } + WifiEvent::StaNeighborRep => { + handle_raw::(event_data, event_data_size); + } } } diff --git a/examples/src/bin/wifi_access_point.rs b/examples/src/bin/wifi_access_point.rs index e0081c7a4e8..29e3f38db19 100644 --- a/examples/src/bin/wifi_access_point.rs +++ b/examples/src/bin/wifi_access_point.rs @@ -51,33 +51,35 @@ fn main() -> ! { let timg0 = TimerGroup::new(peripherals.TIMG0); - let init = init( - EspWifiInitFor::Wifi, - timg0.timer0, - Rng::new(peripherals.RNG), - peripherals.RADIO_CLK, - ) - .unwrap(); - + // Set event handlers for wifi before init to avoid missing any. let mut connections = 0u32; - event::wifi_event_ap_staconnected_t::update_handler(move |prev, event| { + _ = event::ApStart::replace_handler(|_| esp_println::println!("ap start event")); + event::ApStaconnected::update_handler(move |prev, event| { connections += 1; - esp_println::println!("connected {}, mac: {:?}", connections, event.mac); + esp_println::println!("connected {}, mac: {:?}", connections, event.0.mac); prev(event); }); - event::wifi_event_ap_staconnected_t::update_handler(|prev, event| { - esp_println::println!("connected aid: {}", event.aid); + event::ApStaconnected::update_handler(|prev, event| { + esp_println::println!("connected aid: {}", event.0.aid); prev(event) }); - event::wifi_event_ap_stadisconnected_t::update_handler(|prev, event| { + event::ApStadisconnected::update_handler(|prev, event| { prev(event); esp_println::println!( "disconnected mac: {:?}, reason: {:?}", - event.mac, - event.reason + event.0.mac, + event.0.reason ); }); + let init = init( + EspWifiInitFor::Wifi, + timg0.timer0, + Rng::new(peripherals.RNG), + peripherals.RADIO_CLK, + ) + .unwrap(); + let mut wifi = peripherals.WIFI; let mut socket_set_entries: [SocketStorage; 3] = Default::default(); let (iface, device, mut controller, sockets) = From f8c46c6cf34c81cfbfa1799f7bc40d94aa886c25 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:50:12 -0700 Subject: [PATCH 09/13] add doc to newtypes --- esp-wifi/src/wifi/event.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs index e8be514c341..e1edc431590 100644 --- a/esp-wifi/src/wifi/event.rs +++ b/esp-wifi/src/wifi/event.rs @@ -74,6 +74,7 @@ impl EventExt for T {} macro_rules! impl_wifi_event { // no data ($newtype:ident) => { + /// See [`WifiEvent`]. #[derive(Copy, Clone)] pub struct $newtype; impl sealed::Event for $newtype { @@ -90,6 +91,7 @@ macro_rules! impl_wifi_event { // data ($newtype:ident, $data:ident) => { pub use esp_wifi_sys::include::$data; + /// See [`WifiEvent`]. #[derive(Copy, Clone)] pub struct $newtype(pub $data); impl sealed::Event for $newtype { From 74c410d6dc922b858a7d8afb5c9fbadaf368cfd9 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:53:30 -0700 Subject: [PATCH 10/13] fix previous doc example --- esp-wifi/src/wifi/event.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs index e1edc431590..0172a399d3b 100644 --- a/esp-wifi/src/wifi/event.rs +++ b/esp-wifi/src/wifi/event.rs @@ -29,15 +29,15 @@ fn default_handler() -> Box> { /// Register a new event handler like: /// ``` /// # use esp_wifi::wifi::event::{self, *}; -/// # fn new_handler(_: &wifi_event_ap_stadisconnected_t) {} -/// event::wifi_event_ap_stadisconnected_t::update_handler(|prev, event| { +/// # fn new_handler(_: &ApStaconnected) {} +/// event::ApStaconnected::update_handler(|prev, event| { /// prev(event); /// new_handler(event); /// }) /// ``` // Implemented like this instead of free functions because the syntax would be // ``` -// event::update_handler::(...) +// event::update_handler::(...) // ``` pub trait EventExt: sealed::Event + Sized + 'static { /// Get the handler for this event, replacing it with the default handler. From 836b9a4ddc0eb7493026f41123c0a301a4e84e01 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:54:31 -0700 Subject: [PATCH 11/13] - `get_handler` -> `handler` - pass critical section to event handlers - comment on perf of Box - don't pass `prev` in `update_handler`, instead call previous handler first unconditionally --- esp-wifi/src/wifi/event.rs | 56 +++++++++++++++++---------- examples/src/bin/wifi_access_point.rs | 11 ++---- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs index 0172a399d3b..bc887f3afbb 100644 --- a/esp-wifi/src/wifi/event.rs +++ b/esp-wifi/src/wifi/event.rs @@ -10,17 +10,19 @@ pub(crate) mod sealed { pub trait Event { /// Get the static reference to the handler for this event. - fn get_handler() -> &'static Mutex>>>>; + fn handler() -> &'static Mutex>>>>; /// # Safety /// `ptr` must be a valid for casting to this event's inner event data. unsafe fn from_raw_event_data(ptr: *mut crate::binary::c_types::c_void) -> Self; } } /// The type of handlers of events. -pub type Handler = dyn FnMut(&T) + Sync + Send; +pub type Handler = dyn FnMut(critical_section::CriticalSection<'_>, &T) + Sync + Send; fn default_handler() -> Box> { - fn drop_ref(_: &T) {} + fn drop_ref(_: critical_section::CriticalSection<'_>, _: &T) {} + // perf: `drop_ref` is a ZST [function item](https://doc.rust-lang.org/reference/types/function-item.html) + // so this doesn't actually allocate. Box::new(drop_ref) } @@ -29,9 +31,8 @@ fn default_handler() -> Box> { /// Register a new event handler like: /// ``` /// # use esp_wifi::wifi::event::{self, *}; -/// # fn new_handler(_: &ApStaconnected) {} -/// event::ApStaconnected::update_handler(|prev, event| { -/// prev(event); +/// # fn new_handler(_: critical_section::CriticalSection<'_>, _: &ApStaconnected) {} +/// event::ApStaconnected::update_handler(|_cs, event| { /// new_handler(event); /// }) /// ``` @@ -43,29 +44,44 @@ pub trait EventExt: sealed::Event + Sized + 'static { /// Get the handler for this event, replacing it with the default handler. fn take_handler() -> Box> { critical_section::with(|cs| { - Self::get_handler() + Self::handler() .borrow_ref_mut(cs) .take() - .unwrap_or(default_handler::()) + .unwrap_or_else(default_handler::) }) } /// Set the handler for this event, returning the old handler. - fn replace_handler(f: F) -> Box> { + fn replace_handler< + F: FnMut(critical_section::CriticalSection<'_>, &Self) + Sync + Send + 'static, + >( + f: F, + ) -> Box> { critical_section::with(|cs| { - Self::get_handler() + Self::handler() .borrow_ref_mut(cs) .replace(Box::new(f)) - .unwrap_or(default_handler::()) + .unwrap_or_else(default_handler::) }) } /// Atomic combination of [`take_handler`] and [`replace_handler`]. Use this - /// to add a new handler while preserving the previous. - fn update_handler, &Self) + Sync + Send + 'static>(mut f: F) { + /// to add a new handler which runs after the previously registered + /// handlers. + fn update_handler< + F: FnMut(critical_section::CriticalSection<'_>, &Self) + Sync + Send + 'static, + >( + mut f: F, + ) { critical_section::with(move |cs| { - let mut handler: Box> = Self::take_handler(); - Self::get_handler() + let mut handler: Box> = Self::handler() .borrow_ref_mut(cs) - .replace(Box::new(move |event| f(&mut handler, event))); + .take() + .unwrap_or_else(default_handler::); + Self::handler().borrow_ref_mut(cs).replace(Box::new( + move |cs: critical_section::CriticalSection<'_>, event| { + handler(cs, event); + f(cs, event) + }, + )); }); } } @@ -81,7 +97,7 @@ macro_rules! impl_wifi_event { unsafe fn from_raw_event_data(_: *mut crate::binary::c_types::c_void) -> Self { Self } - fn get_handler() -> &'static Mutex>>>> { + fn handler() -> &'static Mutex>>>> { static HANDLE: Mutex>>>> = Mutex::new(RefCell::new(None)); &HANDLE @@ -98,7 +114,7 @@ macro_rules! impl_wifi_event { unsafe fn from_raw_event_data(ptr: *mut crate::binary::c_types::c_void) -> Self { Self(unsafe { *ptr.cast() }) } - fn get_handler() -> &'static Mutex>>>> { + fn handler() -> &'static Mutex>>>> { static HANDLE: Mutex>>>> = Mutex::new(RefCell::new(None)); &HANDLE @@ -156,8 +172,8 @@ impl_wifi_event!(StaNeighborRep, wifi_event_neighbor_report_t); /// Handle the given event using the registered event handlers. pub fn handle(event_data: &Event) { critical_section::with(|cs| { - if let Some(handler) = &mut *Event::get_handler().borrow_ref_mut(cs) { - handler(event_data) + if let Some(handler) = &mut *Event::handler().borrow_ref_mut(cs) { + handler(cs, event_data) } }); } diff --git a/examples/src/bin/wifi_access_point.rs b/examples/src/bin/wifi_access_point.rs index 29e3f38db19..11a8a97ea8b 100644 --- a/examples/src/bin/wifi_access_point.rs +++ b/examples/src/bin/wifi_access_point.rs @@ -53,18 +53,15 @@ fn main() -> ! { // Set event handlers for wifi before init to avoid missing any. let mut connections = 0u32; - _ = event::ApStart::replace_handler(|_| esp_println::println!("ap start event")); - event::ApStaconnected::update_handler(move |prev, event| { + _ = event::ApStart::replace_handler(|_, _| esp_println::println!("ap start event")); + event::ApStaconnected::update_handler(move |_, event| { connections += 1; esp_println::println!("connected {}, mac: {:?}", connections, event.0.mac); - prev(event); }); - event::ApStaconnected::update_handler(|prev, event| { + event::ApStaconnected::update_handler(|_, event| { esp_println::println!("connected aid: {}", event.0.aid); - prev(event) }); - event::ApStadisconnected::update_handler(|prev, event| { - prev(event); + event::ApStadisconnected::update_handler(|_, event| { esp_println::println!( "disconnected mac: {:?}, reason: {:?}", event.0.mac, From 67acf94503dcd9a144fe20a8c2ef4c15f4cbed5d Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Wed, 6 Nov 2024 16:36:55 -0700 Subject: [PATCH 12/13] pass cs to dispatch_event_handler --- esp-wifi/src/wifi/event.rs | 104 ++++++++++++++++---------------- esp-wifi/src/wifi/os_adapter.rs | 7 ++- 2 files changed, 56 insertions(+), 55 deletions(-) diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs index bc887f3afbb..bffbd0b7451 100644 --- a/esp-wifi/src/wifi/event.rs +++ b/esp-wifi/src/wifi/event.rs @@ -170,18 +170,17 @@ impl_wifi_event!(HomeChannelChange, wifi_event_home_channel_change_t); impl_wifi_event!(StaNeighborRep, wifi_event_neighbor_report_t); /// Handle the given event using the registered event handlers. -pub fn handle(event_data: &Event) { - critical_section::with(|cs| { - if let Some(handler) = &mut *Event::handler().borrow_ref_mut(cs) { - handler(cs, event_data) - } - }); +pub fn handle(cs: critical_section::CriticalSection<'_>, event_data: &Event) { + if let Some(handler) = &mut *Event::handler().borrow_ref_mut(cs) { + handler(cs, event_data) + }; } /// Handle an event given the raw pointers. /// # Safety /// The pointer should be valid to cast to `Event`'s inner type (if it has one) pub(crate) unsafe fn handle_raw( + cs: critical_section::CriticalSection<'_>, event_data: *mut crate::binary::c_types::c_void, event_data_size: usize, ) { @@ -190,152 +189,153 @@ pub(crate) unsafe fn handle_raw( core::mem::size_of::(), "wrong size event data" ); - handle::(unsafe { &Event::from_raw_event_data(event_data) }) + handle::(cs, unsafe { &Event::from_raw_event_data(event_data) }) } /// Handle event regardless of its type. /// # Safety /// Arguments should be self-consistent. pub(crate) unsafe fn dispatch_event_handler( + cs: critical_section::CriticalSection<'_>, event: WifiEvent, event_data: *mut crate::binary::c_types::c_void, event_data_size: usize, ) { match event { WifiEvent::WifiReady => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ScanDone => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaStart => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaStop => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaConnected => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaDisconnected => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaAuthmodeChange => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaWpsErSuccess => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaWpsErFailed => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaWpsErTimeout => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaWpsErPin => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaWpsErPbcOverlap => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ApStart => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ApStop => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ApStaconnected => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ApStadisconnected => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ApProbereqrecved => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::FtmReport => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaBssRssiLow => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ActionTxStatus => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::RocDone => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaBeaconTimeout => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ConnectionlessModuleWakeIntervalStart => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ApWpsRgSuccess => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ApWpsRgFailed => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ApWpsRgTimeout => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ApWpsRgPin => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ApWpsRgPbcOverlap => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ItwtSetup => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ItwtTeardown => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ItwtProbe => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::ItwtSuspend => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::TwtWakeup => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::BtwtSetup => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::BtwtTeardown => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::NanStarted => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::NanStopped => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::NanSvcMatch => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::NanReplied => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::NanReceive => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::NdpIndication => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::NdpConfirm => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::NdpTerminated => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::HomeChannelChange => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } WifiEvent::StaNeighborRep => { - handle_raw::(event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size); } } } diff --git a/esp-wifi/src/wifi/os_adapter.rs b/esp-wifi/src/wifi/os_adapter.rs index 2aaf8b266c7..d3954e642cb 100644 --- a/esp-wifi/src/wifi/os_adapter.rs +++ b/esp-wifi/src/wifi/os_adapter.rs @@ -866,9 +866,10 @@ pub unsafe extern "C" fn event_post( let event = unwrap!(WifiEvent::from_i32(event_id)); trace!("EVENT: {:?}", event); - critical_section::with(|cs| WIFI_EVENTS.borrow_ref_mut(cs).insert(event)); - - super::event::dispatch_event_handler(event, event_data, event_data_size); + critical_section::with(|cs| { + WIFI_EVENTS.borrow_ref_mut(cs).insert(event); + super::event::dispatch_event_handler(cs, event, event_data, event_data_size); + }); super::state::update_state(event); From 0a939074a9bf5845748b867b6a86cce83069645d Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Thu, 7 Nov 2024 18:22:45 -0700 Subject: [PATCH 13/13] don't print "unhandled event" for handled events. --- esp-wifi/src/wifi/event.rs | 107 +++++++++++++++++--------------- esp-wifi/src/wifi/os_adapter.rs | 6 +- esp-wifi/src/wifi/state.rs | 8 ++- 3 files changed, 67 insertions(+), 54 deletions(-) diff --git a/esp-wifi/src/wifi/event.rs b/esp-wifi/src/wifi/event.rs index bffbd0b7451..f0daf78d4fa 100644 --- a/esp-wifi/src/wifi/event.rs +++ b/esp-wifi/src/wifi/event.rs @@ -170,10 +170,16 @@ impl_wifi_event!(HomeChannelChange, wifi_event_home_channel_change_t); impl_wifi_event!(StaNeighborRep, wifi_event_neighbor_report_t); /// Handle the given event using the registered event handlers. -pub fn handle(cs: critical_section::CriticalSection<'_>, event_data: &Event) { +pub fn handle( + cs: critical_section::CriticalSection<'_>, + event_data: &Event, +) -> bool { if let Some(handler) = &mut *Event::handler().borrow_ref_mut(cs) { - handler(cs, event_data) - }; + handler(cs, event_data); + true + } else { + false + } } /// Handle an event given the raw pointers. @@ -183,7 +189,7 @@ pub(crate) unsafe fn handle_raw( cs: critical_section::CriticalSection<'_>, event_data: *mut crate::binary::c_types::c_void, event_data_size: usize, -) { +) -> bool { debug_assert_eq!( event_data_size, core::mem::size_of::(), @@ -195,147 +201,148 @@ pub(crate) unsafe fn handle_raw( /// Handle event regardless of its type. /// # Safety /// Arguments should be self-consistent. +#[rustfmt::skip] pub(crate) unsafe fn dispatch_event_handler( cs: critical_section::CriticalSection<'_>, event: WifiEvent, event_data: *mut crate::binary::c_types::c_void, event_data_size: usize, -) { +) -> bool { match event { WifiEvent::WifiReady => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ScanDone => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaStart => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaStop => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaConnected => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaDisconnected => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaAuthmodeChange => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaWpsErSuccess => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaWpsErFailed => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaWpsErTimeout => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaWpsErPin => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaWpsErPbcOverlap => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ApStart => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ApStop => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ApStaconnected => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ApStadisconnected => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ApProbereqrecved => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::FtmReport => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaBssRssiLow => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ActionTxStatus => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::RocDone => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaBeaconTimeout => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ConnectionlessModuleWakeIntervalStart => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ApWpsRgSuccess => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ApWpsRgFailed => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ApWpsRgTimeout => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ApWpsRgPin => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ApWpsRgPbcOverlap => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ItwtSetup => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ItwtTeardown => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ItwtProbe => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::ItwtSuspend => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::TwtWakeup => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::BtwtSetup => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::BtwtTeardown => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::NanStarted => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::NanStopped => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::NanSvcMatch => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::NanReplied => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::NanReceive => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::NdpIndication => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::NdpConfirm => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::NdpTerminated => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::HomeChannelChange => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } WifiEvent::StaNeighborRep => { - handle_raw::(cs, event_data, event_data_size); + handle_raw::(cs, event_data, event_data_size) } } } diff --git a/esp-wifi/src/wifi/os_adapter.rs b/esp-wifi/src/wifi/os_adapter.rs index d3954e642cb..e85c2070676 100644 --- a/esp-wifi/src/wifi/os_adapter.rs +++ b/esp-wifi/src/wifi/os_adapter.rs @@ -866,12 +866,14 @@ pub unsafe extern "C" fn event_post( let event = unwrap!(WifiEvent::from_i32(event_id)); trace!("EVENT: {:?}", event); + + let mut handled = false; critical_section::with(|cs| { WIFI_EVENTS.borrow_ref_mut(cs).insert(event); - super::event::dispatch_event_handler(cs, event, event_data, event_data_size); + handled = super::event::dispatch_event_handler(cs, event, event_data, event_data_size); }); - super::state::update_state(event); + super::state::update_state(event, handled); #[cfg(feature = "async")] event.waker().wake(); diff --git a/esp-wifi/src/wifi/state.rs b/esp-wifi/src/wifi/state.rs index 58d8d4441f9..0442bb58fb6 100644 --- a/esp-wifi/src/wifi/state.rs +++ b/esp-wifi/src/wifi/state.rs @@ -47,7 +47,7 @@ pub fn get_sta_state() -> WifiState { STA_STATE.load(Ordering::Relaxed) } -pub(crate) fn update_state(event: WifiEvent) { +pub(crate) fn update_state(event: WifiEvent, handled: bool) { match event { WifiEvent::StaConnected | WifiEvent::StaDisconnected @@ -58,7 +58,11 @@ pub(crate) fn update_state(event: WifiEvent) { AP_STATE.store(WifiState::from(event), Ordering::Relaxed) } - other => debug!("Unhandled event: {:?}", other), + other => { + if !handled { + debug!("Unhandled event: {:?}", other) + } + } } }