1use alloc::{boxed::Box, collections::vec_deque::VecDeque};
13use core::{cell::RefCell, fmt::Debug, marker::PhantomData};
14
15use critical_section::Mutex;
16use enumset::EnumSet;
17use portable_atomic::{AtomicBool, AtomicU8, Ordering};
18
19#[cfg(feature = "csi")]
20use crate::wifi::CsiConfig;
21use crate::{
22    binary::include::*,
23    config::PowerSaveMode,
24    hal::peripheral::{Peripheral, PeripheralRef},
25    wifi::{Protocol, RxControlInfo, WifiError},
26    EspWifiController,
27};
28
29const RECEIVE_QUEUE_SIZE: usize = 10;
30
31pub const ESP_NOW_MAX_DATA_LEN: usize = 250;
33
34pub const BROADCAST_ADDRESS: [u8; 6] = [0xffu8, 0xffu8, 0xffu8, 0xffu8, 0xffu8, 0xffu8];
36
37static RECEIVE_QUEUE: Mutex<RefCell<VecDeque<ReceivedData>>> =
39    Mutex::new(RefCell::new(VecDeque::new()));
40
41static ESP_NOW_SEND_CB_INVOKED: AtomicBool = AtomicBool::new(false);
47static ESP_NOW_SEND_STATUS: AtomicBool = AtomicBool::new(true);
49
50macro_rules! check_error {
51    ($block:block) => {
52        match unsafe { $block } {
53            0 => Ok(()),
54            res => Err(EspNowError::Error(Error::from_code(res as u32))),
55        }
56    };
57}
58
59#[repr(u32)]
61#[derive(Debug)]
62#[cfg_attr(feature = "defmt", derive(defmt::Format))]
63#[allow(clippy::enum_variant_names)] pub enum Error {
65    NotInitialized  = 12389,
67
68    InvalidArgument = 12390,
70
71    OutOfMemory     = 12391,
73
74    PeerListFull    = 12392,
76
77    NotFound        = 12393,
79
80    InternalError   = 12394,
82
83    PeerExists      = 12395,
85
86    InterfaceError  = 12396,
88
89    Other(u32),
92}
93
94impl Error {
95    pub fn from_code(code: u32) -> Error {
96        match code {
97            12389 => Error::NotInitialized,
98            12390 => Error::InvalidArgument,
99            12391 => Error::OutOfMemory,
100            12392 => Error::PeerListFull,
101            12393 => Error::NotFound,
102            12394 => Error::InternalError,
103            12395 => Error::PeerExists,
104            12396 => Error::InterfaceError,
105            _ => Error::Other(code),
106        }
107    }
108}
109
110#[derive(Debug)]
112#[cfg_attr(feature = "defmt", derive(defmt::Format))]
113pub enum EspNowError {
114    Error(Error),
116    SendFailed,
118    DuplicateInstance,
120    Initialization(WifiError),
122}
123
124impl From<WifiError> for EspNowError {
125    fn from(f: WifiError) -> Self {
126        Self::Initialization(f)
127    }
128}
129
130#[derive(Debug)]
132#[cfg_attr(feature = "defmt", derive(defmt::Format))]
133pub struct PeerCount {
134    pub total_count: i32,
136
137    pub encrypted_count: i32,
139}
140
141#[repr(u32)]
143#[cfg_attr(feature = "defmt", derive(defmt::Format))]
144pub enum WifiPhyRate {
145    Rate1mL = 0,
147    Rate2m,
149    Rate5mL,
151    Rate11mL,
153    Rate2mS,
155    Rate5mS,
157    Rate11mS,
159    Rate48m,
161    Rate24m,
163    Rate12m,
165    Rate6m,
167    Rate54m,
169    Rate36m,
171    Rate18m,
173    Rate9m,
175    RateMcs0Lgi,
177    RateMcs1Lgi,
179    RateMcs2Lgi,
181    RateMcs3Lgi,
183    RateMcs4Lgi,
185    RateMcs5Lgi,
187    RateMcs6Lgi,
189    RateMcs7Lgi,
191    RateMcs0Sgi,
193    RateMcs1Sgi,
195    RateMcs2Sgi,
197    RateMcs3Sgi,
199    RateMcs4Sgi,
201    RateMcs5Sgi,
203    RateMcs6Sgi,
205    RateMcs7Sgi,
207    RateLora250k,
209    RateLora500k,
211    RateMax,
213}
214
215#[derive(Debug, Clone, Copy)]
217#[cfg_attr(feature = "defmt", derive(defmt::Format))]
218pub struct PeerInfo {
219    pub peer_address: [u8; 6],
222
223    pub lmk: Option<[u8; 16]>,
225
226    pub channel: Option<u8>,
228
229    pub encrypt: bool,
231    }
233
234#[derive(Debug, Clone, Copy)]
236#[cfg_attr(feature = "defmt", derive(defmt::Format))]
237pub struct ReceiveInfo {
238    pub src_address: [u8; 6],
240
241    pub dst_address: [u8; 6],
243
244    pub rx_control: RxControlInfo,
246}
247
248#[derive(Clone)]
251pub struct ReceivedData {
252    data: Box<[u8]>,
253    pub info: ReceiveInfo,
254}
255
256impl ReceivedData {
257    pub fn data(&self) -> &[u8] {
259        &self.data
260    }
261}
262
263#[cfg(feature = "defmt")]
264impl defmt::Format for ReceivedData {
265    fn format(&self, fmt: defmt::Formatter<'_>) {
266        defmt::write!(fmt, "ReceivedData {}, Info {}", &self.data[..], &self.info,)
267    }
268}
269
270impl Debug for ReceivedData {
271    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
272        f.debug_struct("ReceivedData")
273            .field("data", &self.data())
274            .field("info", &self.info)
275            .finish()
276    }
277}
278
279pub struct EspNowWithWifiCreateToken {
281    _private: (),
282}
283
284pub fn enable_esp_now_with_wifi(
286    device: crate::hal::peripherals::WIFI,
287) -> (crate::hal::peripherals::WIFI, EspNowWithWifiCreateToken) {
288    (device, EspNowWithWifiCreateToken { _private: () })
289}
290
291pub struct EspNowManager<'d> {
293    _rc: EspNowRc<'d>,
294}
295
296impl EspNowManager<'_> {
297    pub fn set_protocol(&self, protocols: EnumSet<Protocol>) -> Result<(), EspNowError> {
305        let mut protocol = 0u8;
306
307        protocols.into_iter().for_each(|v| match v {
308            Protocol::P802D11B => protocol |= WIFI_PROTOCOL_11B as u8,
309            Protocol::P802D11BG => protocol |= WIFI_PROTOCOL_11B as u8 | WIFI_PROTOCOL_11G as u8,
310            Protocol::P802D11BGN => {
311                protocol |=
312                    WIFI_PROTOCOL_11B as u8 | WIFI_PROTOCOL_11G as u8 | WIFI_PROTOCOL_11N as u8
313            }
314            Protocol::P802D11BGNLR => {
315                protocol |= WIFI_PROTOCOL_11B as u8
316                    | WIFI_PROTOCOL_11G as u8
317                    | WIFI_PROTOCOL_11N as u8
318                    | WIFI_PROTOCOL_LR as u8
319            }
320            Protocol::P802D11LR => protocol |= WIFI_PROTOCOL_LR as u8,
321            Protocol::P802D11BGNAX => {
322                protocol |= WIFI_PROTOCOL_11B as u8
323                    | WIFI_PROTOCOL_11G as u8
324                    | WIFI_PROTOCOL_11N as u8
325                    | WIFI_PROTOCOL_11AX as u8
326            }
327        });
328
329        let mut mode = wifi_mode_t_WIFI_MODE_NULL;
330        check_error!({ esp_wifi_get_mode(&mut mode) })?;
331
332        if mode == wifi_mode_t_WIFI_MODE_STA || mode == wifi_mode_t_WIFI_MODE_APSTA {
333            check_error!({ esp_wifi_set_protocol(wifi_interface_t_WIFI_IF_STA, protocol) })?;
334        }
335        if mode == wifi_mode_t_WIFI_MODE_AP || mode == wifi_mode_t_WIFI_MODE_APSTA {
336            check_error!({ esp_wifi_set_protocol(wifi_interface_t_WIFI_IF_AP, protocol) })?;
337        }
338
339        Ok(())
340    }
341
342    pub fn set_power_saving(&self, ps: PowerSaveMode) -> Result<(), WifiError> {
344        crate::wifi::apply_power_saving(ps)
345    }
346
347    pub fn set_channel(&self, channel: u8) -> Result<(), EspNowError> {
350        check_error!({ esp_wifi_set_channel(channel, 0) })
351    }
352
353    pub fn version(&self) -> Result<u32, EspNowError> {
355        let mut version = 0u32;
356        check_error!({ esp_now_get_version(&mut version as *mut u32) })?;
357        Ok(version)
358    }
359
360    pub fn add_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
362        let raw_peer = esp_now_peer_info_t {
363            peer_addr: peer.peer_address,
364            lmk: peer.lmk.unwrap_or([0u8; 16]),
365            channel: peer.channel.unwrap_or(0),
366            ifidx: wifi_interface_t_WIFI_IF_STA,
367            encrypt: peer.encrypt,
368            priv_: core::ptr::null_mut(),
369        };
370        check_error!({ esp_now_add_peer(&raw_peer as *const _) })
371    }
372
373    #[cfg(feature = "csi")]
375    pub fn set_csi(
376        &mut self,
377        mut csi: CsiConfig,
378        cb: impl FnMut(crate::wifi::wifi_csi_info_t) + Send,
379    ) -> Result<(), WifiError> {
380        csi.apply_config()?;
381        csi.set_receive_cb(cb)?;
382        csi.set_csi(true)?;
383
384        Ok(())
385    }
386
387    pub fn remove_peer(&self, peer_address: &[u8; 6]) -> Result<(), EspNowError> {
389        check_error!({ esp_now_del_peer(peer_address.as_ptr()) })
390    }
391
392    pub fn modify_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
394        let raw_peer = esp_now_peer_info_t {
395            peer_addr: peer.peer_address,
396            lmk: peer.lmk.unwrap_or([0u8; 16]),
397            channel: peer.channel.unwrap_or(0),
398            ifidx: wifi_interface_t_WIFI_IF_STA,
399            encrypt: peer.encrypt,
400            priv_: core::ptr::null_mut(),
401        };
402        check_error!({ esp_now_mod_peer(&raw_peer as *const _) })
403    }
404
405    pub fn peer(&self, peer_address: &[u8; 6]) -> Result<PeerInfo, EspNowError> {
407        let mut raw_peer = esp_now_peer_info_t {
408            peer_addr: [0u8; 6],
409            lmk: [0u8; 16],
410            channel: 0,
411            ifidx: 0,
412            encrypt: false,
413            priv_: core::ptr::null_mut(),
414        };
415        check_error!({ esp_now_get_peer(peer_address.as_ptr(), &mut raw_peer as *mut _) })?;
416
417        Ok(PeerInfo {
418            peer_address: raw_peer.peer_addr,
419            lmk: if raw_peer.lmk.is_empty() {
420                None
421            } else {
422                Some(raw_peer.lmk)
423            },
424            channel: if raw_peer.channel != 0 {
425                Some(raw_peer.channel)
426            } else {
427                None
428            },
429            encrypt: raw_peer.encrypt,
430        })
431    }
432
433    pub fn fetch_peer(&self, from_head: bool) -> Result<PeerInfo, EspNowError> {
439        let mut raw_peer = esp_now_peer_info_t {
440            peer_addr: [0u8; 6],
441            lmk: [0u8; 16],
442            channel: 0,
443            ifidx: 0,
444            encrypt: false,
445            priv_: core::ptr::null_mut(),
446        };
447        check_error!({ esp_now_fetch_peer(from_head, &mut raw_peer as *mut _) })?;
448
449        Ok(PeerInfo {
450            peer_address: raw_peer.peer_addr,
451            lmk: if raw_peer.lmk.is_empty() {
452                None
453            } else {
454                Some(raw_peer.lmk)
455            },
456            channel: if raw_peer.channel != 0 {
457                Some(raw_peer.channel)
458            } else {
459                None
460            },
461            encrypt: raw_peer.encrypt,
462        })
463    }
464
465    pub fn peer_exists(&self, peer_address: &[u8; 6]) -> bool {
467        unsafe { esp_now_is_peer_exist(peer_address.as_ptr()) }
468    }
469
470    pub fn peer_count(&self) -> Result<PeerCount, EspNowError> {
472        let mut peer_num = esp_now_peer_num_t {
473            total_num: 0,
474            encrypt_num: 0,
475        };
476        check_error!({ esp_now_get_peer_num(&mut peer_num as *mut _) })?;
477
478        Ok(PeerCount {
479            total_count: peer_num.total_num,
480            encrypted_count: peer_num.encrypt_num,
481        })
482    }
483
484    pub fn set_pmk(&self, pmk: &[u8; 16]) -> Result<(), EspNowError> {
486        check_error!({ esp_now_set_pmk(pmk.as_ptr()) })
487    }
488
489    pub fn set_wake_window(&self, wake_window: u16) -> Result<(), EspNowError> {
494        check_error!({ esp_now_set_wake_window(wake_window) })
495    }
496
497    pub fn set_rate(&self, rate: WifiPhyRate) -> Result<(), EspNowError> {
499        check_error!({ esp_wifi_config_espnow_rate(wifi_interface_t_WIFI_IF_STA, rate as u32,) })
500    }
501}
502
503impl Drop for EspNowManager<'_> {
504    fn drop(&mut self) {
505        if unwrap!(
506            crate::flags::WIFI.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
507                Some(x.saturating_sub(1))
508            })
509        ) == 0
510        {
511            if let Err(e) = crate::wifi::wifi_deinit() {
512                warn!("Failed to cleanly deinit wifi: {:?}", e);
513            }
514        }
515    }
516}
517
518pub struct EspNowSender<'d> {
526    _rc: EspNowRc<'d>,
527}
528
529impl EspNowSender<'_> {
530    pub fn send<'s>(
534        &'s mut self,
535        dst_addr: &[u8; 6],
536        data: &[u8],
537    ) -> Result<SendWaiter<'s>, EspNowError> {
538        ESP_NOW_SEND_CB_INVOKED.store(false, Ordering::Release);
539        check_error!({ esp_now_send(dst_addr.as_ptr(), data.as_ptr(), data.len()) })?;
540        Ok(SendWaiter(PhantomData))
541    }
542}
543
544#[allow(unknown_lints)]
545#[allow(clippy::too_long_first_doc_paragraph)]
546#[must_use]
557pub struct SendWaiter<'s>(PhantomData<&'s mut EspNowSender<'s>>);
558
559impl SendWaiter<'_> {
560    pub fn wait(self) -> Result<(), EspNowError> {
563        core::mem::forget(self);
566        while !ESP_NOW_SEND_CB_INVOKED.load(Ordering::Acquire) {}
567
568        if ESP_NOW_SEND_STATUS.load(Ordering::Relaxed) {
569            Ok(())
570        } else {
571            Err(EspNowError::SendFailed)
572        }
573    }
574}
575
576impl Drop for SendWaiter<'_> {
577    fn drop(&mut self) {
580        while !ESP_NOW_SEND_CB_INVOKED.load(Ordering::Acquire) {}
581    }
582}
583
584pub struct EspNowReceiver<'d> {
587    _rc: EspNowRc<'d>,
588}
589
590impl EspNowReceiver<'_> {
591    pub fn receive(&self) -> Option<ReceivedData> {
593        critical_section::with(|cs| {
594            let mut queue = RECEIVE_QUEUE.borrow_ref_mut(cs);
595            queue.pop_front()
596        })
597    }
598}
599
600struct EspNowRc<'d> {
603    rc: &'static AtomicU8,
604    inner: PhantomData<EspNow<'d>>,
605}
606
607impl EspNowRc<'_> {
608    fn new() -> Result<Self, EspNowError> {
609        static ESP_NOW_RC: AtomicU8 = AtomicU8::new(0);
610        if ESP_NOW_RC.fetch_add(1, Ordering::AcqRel) != 0 {
613            return Err(EspNowError::DuplicateInstance);
614        }
615
616        Ok(Self {
617            rc: &ESP_NOW_RC,
618            inner: PhantomData,
619        })
620    }
621}
622
623impl Clone for EspNowRc<'_> {
624    fn clone(&self) -> Self {
625        self.rc.fetch_add(1, Ordering::Release);
626        Self {
627            rc: self.rc,
628            inner: PhantomData,
629        }
630    }
631}
632
633impl Drop for EspNowRc<'_> {
634    fn drop(&mut self) {
635        if self.rc.fetch_sub(1, Ordering::AcqRel) == 1 {
636            unsafe {
637                esp_now_unregister_recv_cb();
638                esp_now_deinit();
639            }
640        }
641    }
642}
643
644#[allow(unknown_lints)]
645#[allow(clippy::too_long_first_doc_paragraph)]
646pub struct EspNow<'d> {
656    manager: EspNowManager<'d>,
657    sender: EspNowSender<'d>,
658    receiver: EspNowReceiver<'d>,
659    _phantom: PhantomData<&'d ()>,
660}
661
662impl<'d> EspNow<'d> {
663    pub fn new(
665        inited: &'d EspWifiController<'d>,
666        device: impl Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
667    ) -> Result<EspNow<'d>, EspNowError> {
668        EspNow::new_internal(inited, Some(device.into_ref()))
669    }
670
671    pub fn new_with_wifi(
673        inited: &'d EspWifiController<'d>,
674        _token: EspNowWithWifiCreateToken,
675    ) -> Result<EspNow<'d>, EspNowError> {
676        EspNow::new_internal(
677            inited,
678            None::<PeripheralRef<'d, crate::hal::peripherals::WIFI>>,
679        )
680    }
681
682    fn new_internal(
683        inited: &'d EspWifiController<'d>,
684        device: Option<PeripheralRef<'d, crate::hal::peripherals::WIFI>>,
685    ) -> Result<EspNow<'d>, EspNowError> {
686        if !inited.wifi() {
687            assert!(device.is_some());
689            crate::wifi::wifi_init()?;
690        }
691
692        let espnow_rc = EspNowRc::new()?;
693        let esp_now = EspNow {
694            manager: EspNowManager {
695                _rc: espnow_rc.clone(),
696            },
697            sender: EspNowSender {
698                _rc: espnow_rc.clone(),
699            },
700            receiver: EspNowReceiver { _rc: espnow_rc },
701            _phantom: PhantomData,
702        };
703        check_error!({ esp_wifi_set_mode(wifi_mode_t_WIFI_MODE_STA) })?;
704        check_error!({ esp_wifi_start() })?;
705        check_error!({
706            esp_wifi_set_inactive_time(wifi_interface_t_WIFI_IF_STA, crate::CONFIG.beacon_timeout)
707        })?;
708        check_error!({ esp_now_init() })?;
709        check_error!({ esp_now_register_recv_cb(Some(rcv_cb)) })?;
710        check_error!({ esp_now_register_send_cb(Some(send_cb)) })?;
711
712        esp_now.add_peer(PeerInfo {
713            peer_address: BROADCAST_ADDRESS,
714            lmk: None,
715            channel: None,
716            encrypt: false,
717        })?;
718
719        Ok(esp_now)
720    }
721
722    pub fn split(self) -> (EspNowManager<'d>, EspNowSender<'d>, EspNowReceiver<'d>) {
725        (self.manager, self.sender, self.receiver)
726    }
727
728    pub fn set_protocol(&self, protocols: EnumSet<Protocol>) -> Result<(), EspNowError> {
736        self.manager.set_protocol(protocols)
737    }
738
739    pub fn set_channel(&self, channel: u8) -> Result<(), EspNowError> {
742        self.manager.set_channel(channel)
743    }
744
745    pub fn version(&self) -> Result<u32, EspNowError> {
747        self.manager.version()
748    }
749
750    pub fn add_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
752        self.manager.add_peer(peer)
753    }
754
755    pub fn remove_peer(&self, peer_address: &[u8; 6]) -> Result<(), EspNowError> {
757        self.manager.remove_peer(peer_address)
758    }
759
760    pub fn modify_peer(&self, peer: PeerInfo) -> Result<(), EspNowError> {
762        self.manager.modify_peer(peer)
763    }
764
765    pub fn peer(&self, peer_address: &[u8; 6]) -> Result<PeerInfo, EspNowError> {
767        self.manager.peer(peer_address)
768    }
769
770    pub fn fetch_peer(&self, from_head: bool) -> Result<PeerInfo, EspNowError> {
776        self.manager.fetch_peer(from_head)
777    }
778
779    pub fn peer_exists(&self, peer_address: &[u8; 6]) -> bool {
781        self.manager.peer_exists(peer_address)
782    }
783
784    pub fn peer_count(&self) -> Result<PeerCount, EspNowError> {
786        self.manager.peer_count()
787    }
788
789    pub fn set_pmk(&self, pmk: &[u8; 16]) -> Result<(), EspNowError> {
791        self.manager.set_pmk(pmk)
792    }
793
794    pub fn set_wake_window(&self, wake_window: u16) -> Result<(), EspNowError> {
799        self.manager.set_wake_window(wake_window)
800    }
801
802    pub fn set_rate(&self, rate: WifiPhyRate) -> Result<(), EspNowError> {
804        self.manager.set_rate(rate)
805    }
806
807    pub fn send<'s>(
811        &'s mut self,
812        dst_addr: &[u8; 6],
813        data: &[u8],
814    ) -> Result<SendWaiter<'s>, EspNowError> {
815        self.sender.send(dst_addr, data)
816    }
817
818    pub fn receive(&self) -> Option<ReceivedData> {
820        self.receiver.receive()
821    }
822}
823
824unsafe extern "C" fn send_cb(_mac_addr: *const u8, status: esp_now_send_status_t) {
825    critical_section::with(|_| {
826        let is_success = status == esp_now_send_status_t_ESP_NOW_SEND_SUCCESS;
827        ESP_NOW_SEND_STATUS.store(is_success, Ordering::Relaxed);
828
829        ESP_NOW_SEND_CB_INVOKED.store(true, Ordering::Release);
830
831        asynch::ESP_NOW_TX_WAKER.wake();
832    })
833}
834
835unsafe extern "C" fn rcv_cb(
836    esp_now_info: *const esp_now_recv_info_t,
837    data: *const u8,
838    data_len: i32,
839) {
840    let src = [
841        (*esp_now_info).src_addr.offset(0).read(),
842        (*esp_now_info).src_addr.offset(1).read(),
843        (*esp_now_info).src_addr.offset(2).read(),
844        (*esp_now_info).src_addr.offset(3).read(),
845        (*esp_now_info).src_addr.offset(4).read(),
846        (*esp_now_info).src_addr.offset(5).read(),
847    ];
848
849    let dst = [
850        (*esp_now_info).des_addr.offset(0).read(),
851        (*esp_now_info).des_addr.offset(1).read(),
852        (*esp_now_info).des_addr.offset(2).read(),
853        (*esp_now_info).des_addr.offset(3).read(),
854        (*esp_now_info).des_addr.offset(4).read(),
855        (*esp_now_info).des_addr.offset(5).read(),
856    ];
857
858    let rx_cntl = (*esp_now_info).rx_ctrl;
859    let rx_control = RxControlInfo::from_raw(rx_cntl);
860
861    let info = ReceiveInfo {
862        src_address: src,
863        dst_address: dst,
864        rx_control,
865    };
866    let slice = core::slice::from_raw_parts(data, data_len as usize);
867    critical_section::with(|cs| {
868        let mut queue = RECEIVE_QUEUE.borrow_ref_mut(cs);
869        let data = Box::from(slice);
870
871        if queue.len() >= RECEIVE_QUEUE_SIZE {
872            queue.pop_front();
873        }
874
875        queue.push_back(ReceivedData { data, info });
876
877        asynch::ESP_NOW_RX_WAKER.wake();
878    });
879}
880
881pub use asynch::SendFuture;
882
883mod asynch {
884    use core::task::{Context, Poll};
885
886    use esp_hal::asynch::AtomicWaker;
887
888    use super::*;
889
890    pub(super) static ESP_NOW_TX_WAKER: AtomicWaker = AtomicWaker::new();
891    pub(super) static ESP_NOW_RX_WAKER: AtomicWaker = AtomicWaker::new();
892
893    impl EspNowReceiver<'_> {
894        pub fn receive_async(&mut self) -> ReceiveFuture<'_> {
898            ReceiveFuture(PhantomData)
899        }
900    }
901
902    impl EspNowSender<'_> {
903        pub fn send_async<'s, 'r>(
905            &'s mut self,
906            addr: &'r [u8; 6],
907            data: &'r [u8],
908        ) -> SendFuture<'s, 'r> {
909            SendFuture {
910                _sender: PhantomData,
911                addr,
912                data,
913                sent: false,
914            }
915        }
916    }
917
918    impl EspNow<'_> {
919        pub fn receive_async(&mut self) -> ReceiveFuture<'_> {
923            self.receiver.receive_async()
924        }
925
926        pub fn send_async<'s, 'r>(
929            &'s mut self,
930            dst_addr: &'r [u8; 6],
931            data: &'r [u8],
932        ) -> SendFuture<'s, 'r> {
933            self.sender.send_async(dst_addr, data)
934        }
935    }
936
937    #[must_use = "futures do nothing unless you `.await` or poll them"]
940    pub struct SendFuture<'s, 'r> {
941        _sender: PhantomData<&'s mut EspNowSender<'s>>,
942        addr: &'r [u8; 6],
943        data: &'r [u8],
944        sent: bool,
945    }
946
947    impl core::future::Future for SendFuture<'_, '_> {
948        type Output = Result<(), EspNowError>;
949
950        fn poll(mut self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
951            if !self.sent {
952                ESP_NOW_TX_WAKER.register(cx.waker());
953                ESP_NOW_SEND_CB_INVOKED.store(false, Ordering::Release);
954                if let Err(e) = check_error!({
955                    esp_now_send(self.addr.as_ptr(), self.data.as_ptr(), self.data.len())
956                }) {
957                    return Poll::Ready(Err(e));
958                }
959                self.sent = true;
960            }
961
962            if !ESP_NOW_SEND_CB_INVOKED.load(Ordering::Acquire) {
963                Poll::Pending
964            } else {
965                Poll::Ready(if ESP_NOW_SEND_STATUS.load(Ordering::Relaxed) {
966                    Ok(())
967                } else {
968                    Err(EspNowError::SendFailed)
969                })
970            }
971        }
972    }
973
974    #[must_use = "futures do nothing unless you `.await` or poll them"]
978    pub struct ReceiveFuture<'r>(PhantomData<&'r mut EspNowReceiver<'r>>);
979
980    impl core::future::Future for ReceiveFuture<'_> {
981        type Output = ReceivedData;
982
983        fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
984            ESP_NOW_RX_WAKER.register(cx.waker());
985
986            if let Some(data) = critical_section::with(|cs| {
987                let mut queue = RECEIVE_QUEUE.borrow_ref_mut(cs);
988                queue.pop_front()
989            }) {
990                Poll::Ready(data)
991            } else {
992                Poll::Pending
993            }
994        }
995    }
996}