Skip to content

Commit

Permalink
Expose src_addr and des_addr in espnow recv cb
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
julienvincent committed Dec 9, 2024
1 parent fb39090 commit e6450d3
Showing 1 changed file with 21 additions and 7 deletions.
28 changes: 21 additions & 7 deletions src/espnow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@ type Singleton<T> = Mutex<Option<Box<T>>>;

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<dyn FnMut(&[u8], &[u8]) + Send + 'static> = Mutex::new(None);
static RECV_CALLBACK: Singleton<dyn FnMut(&ReceiveInfo, &[u8]) + Send + 'static> = Mutex::new(None);
#[allow(clippy::type_complexity)]
static SEND_CALLBACK: Singleton<dyn FnMut(&[u8], SendStatus) + Send + 'static> = Mutex::new(None);

Expand Down Expand Up @@ -168,12 +174,12 @@ impl<'a> EspNow<'a> {

pub fn register_recv_cb<F>(&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<dyn FnMut(&[u8], &[u8]) + Send + 'a> = Box::new(callback);
let callback: Box<dyn FnMut(&ReceiveInfo, &[u8]) + Send + 'a> = Box::new(callback);
#[allow(clippy::type_complexity)]
let callback: Box<dyn FnMut(&[u8], &[u8]) + Send + 'static> =
let callback: Box<dyn FnMut(&ReceiveInfo, &[u8]) + Send + 'static> =
unsafe { core::mem::transmute(callback) };

*RECV_CALLBACK.lock() = Some(Box::new(callback));
Expand Down Expand Up @@ -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");
}
Expand Down

0 comments on commit e6450d3

Please sign in to comment.