use core::cell::RefCell;
use core::mem::MaybeUninit;
use super::Radio;
use crate::phy::config::{RxConfig, TxConfig};
struct OnDrop<F: FnOnce()> {
f: MaybeUninit<F>, }
impl<F: FnOnce()> OnDrop<F> {
pub fn new(f: F) -> Self {
Self {
f: MaybeUninit::new(f),
}
}
pub fn defuse(mut self) {
unsafe { self.f.assume_init_drop() };
core::mem::forget(self)
}
}
impl<F: FnOnce()> Drop for OnDrop<F> {
fn drop(&mut self) {
unsafe { self.f.as_ptr().read()() };
}
}
#[allow(clippy::await_holding_refcell_ref)]
pub async fn transmit<'task, T: AsMut<[u8]>, R: Radio>(
radio: &'task mut R,
data: &'task mut T,
config: TxConfig,
) -> bool {
let radio = RefCell::new(radio);
let on_drop = OnDrop::new(|| radio.borrow_mut().cancel_current_opperation());
let mut radio = radio.borrow_mut();
unsafe {
radio.prepare_transmit(&config, data.as_mut()).await;
}
let result = radio.transmit().await;
on_drop.defuse(); result
}
#[allow(clippy::await_holding_refcell_ref)]
pub async fn receive<'task, R: Radio>(
radio: &'task mut R,
data: &'task mut [u8; 128],
config: RxConfig,
) -> bool {
let radio = RefCell::new(radio);
let on_drop = OnDrop::new(|| radio.borrow_mut().cancel_current_opperation());
let mut radio = radio.borrow_mut();
unsafe {
radio.prepare_receive(&config, data).await;
}
let result = radio.receive().await;
on_drop.defuse(); result
}