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 b4424f3
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 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, Clone)]
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 @@ -223,18 +229,31 @@ impl<'a> EspNow<'a> {
}

extern "C" fn recv_callback(
#[cfg(esp_idf_version_major = "4")] mac_addr: *const u8,
#[cfg(esp_idf_version_major = "4")] src_addr: *const u8,
#[cfg(not(esp_idf_version_major = "4"))] esp_now_info: *const esp_now_recv_info_t,
data: *const u8,
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();
#[cfg(not(any(esp_idf_version_major = "4")))]
let des_addr = unsafe { *esp_now_info }.des_addr.cast_const();
let c_src_addr = unsafe { &*(src_addr as *const [u8; 6]) };
#[cfg(not(any(esp_idf_version_major = "4")))]
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,
#[cfg(esp_idf_version_major = "4")]
des_addr: &[0u8; 6],
#[cfg(not(any(esp_idf_version_major = "4")))]
des_addr: c_des_addr,
},
c_data,
)
} else {
panic!("EspNow callback not available");
}
Expand Down

0 comments on commit b4424f3

Please sign in to comment.