From e6450d3588de61533ad407e2fb22cd57041d663c Mon Sep 17 00:00:00 2001 From: Julien Vincent Date: Mon, 9 Dec 2024 17:34:45 +0000 Subject: [PATCH] Expose src_addr and des_addr in espnow recv cb Currently the espnow bindings for `register_recv_cb` only give a handle on the src_addr from the sending peer. This makes it impossible to determine if the frame was sent on the BROADCAST address. This change updates the first argument to the receive cb to accept a new ReceiveInfo struct containing `src_addr` and `des_addr`. The terminology was taken directly from the esp-idf docs. --- src/espnow.rs | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/espnow.rs b/src/espnow.rs index 0bae195c41f..5c3f3485427 100644 --- a/src/espnow.rs +++ b/src/espnow.rs @@ -20,8 +20,14 @@ type Singleton = Mutex>>; pub const BROADCAST: [u8; 6] = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]; +#[derive(Debug)] +pub struct ReceiveInfo<'a> { + pub src_addr: &'a [u8; 6], + pub des_addr: &'a [u8; 6], +} + #[allow(clippy::type_complexity)] -static RECV_CALLBACK: Singleton = Mutex::new(None); +static RECV_CALLBACK: Singleton = Mutex::new(None); #[allow(clippy::type_complexity)] static SEND_CALLBACK: Singleton = Mutex::new(None); @@ -168,12 +174,12 @@ impl<'a> EspNow<'a> { pub fn register_recv_cb(&self, callback: F) -> Result<(), EspError> where - F: FnMut(&[u8], &[u8]) + Send + 'a, + F: FnMut(&ReceiveInfo, &[u8]) + Send + 'a, { #[allow(clippy::type_complexity)] - let callback: Box = Box::new(callback); + let callback: Box = Box::new(callback); #[allow(clippy::type_complexity)] - let callback: Box = + let callback: Box = unsafe { core::mem::transmute(callback) }; *RECV_CALLBACK.lock() = Some(Box::new(callback)); @@ -229,12 +235,20 @@ impl<'a> EspNow<'a> { data_len: core::ffi::c_int, ) { #[cfg(not(any(esp_idf_version_major = "4")))] - let mac_addr = unsafe { *esp_now_info }.src_addr.cast_const(); - let c_mac = unsafe { core::slice::from_raw_parts(mac_addr, 6usize) }; + let src_addr = unsafe { *esp_now_info }.src_addr.cast_const(); + let des_addr = unsafe { *esp_now_info }.des_addr.cast_const(); + let c_src_addr = unsafe { &*(src_addr as *const [u8; 6]) }; + let c_des_addr = unsafe { &*(des_addr as *const [u8; 6]) }; let c_data = unsafe { core::slice::from_raw_parts(data, data_len as usize) }; if let Some(ref mut callback) = *RECV_CALLBACK.lock() { - callback(c_mac, c_data) + callback( + &ReceiveInfo { + src_addr: c_src_addr, + des_addr: c_des_addr, + }, + c_data, + ) } else { panic!("EspNow callback not available"); }