2023-07-21 03:51:49 +02:00
|
|
|
use core::cell::RefCell;
|
|
|
|
|
2023-07-19 03:52:03 +02:00
|
|
|
use embassy_futures::join;
|
2023-07-21 03:51:49 +02:00
|
|
|
use embassy_sync::blocking_mutex;
|
|
|
|
use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex};
|
2023-07-19 01:28:12 +02:00
|
|
|
use embassy_sync::channel::Channel;
|
2023-07-21 03:51:49 +02:00
|
|
|
use embassy_sync::mutex::Mutex;
|
|
|
|
use embassy_sync::signal::Signal;
|
2023-07-16 02:15:01 +02:00
|
|
|
|
2023-07-19 03:52:03 +02:00
|
|
|
use crate::mac::commands::DataRequest;
|
2023-07-20 23:45:04 +02:00
|
|
|
use crate::mac::event::MacEvent;
|
2023-07-19 03:52:03 +02:00
|
|
|
use crate::mac::typedefs::{AddressMode, MacAddress, PanId, SecurityLevel};
|
2023-07-16 16:32:54 +02:00
|
|
|
use crate::mac::MTU;
|
2023-07-16 02:15:01 +02:00
|
|
|
use crate::sub::mac::Mac;
|
|
|
|
|
2023-07-21 23:10:34 +02:00
|
|
|
type ZeroCopyPubSub<M, T> = blocking_mutex::Mutex<M, RefCell<Option<Signal<NoopRawMutex, T>>>>;
|
|
|
|
|
2023-07-19 01:28:12 +02:00
|
|
|
pub struct Runner<'a> {
|
2023-07-21 03:51:49 +02:00
|
|
|
pub(crate) mac_subsystem: Mac,
|
|
|
|
// rx event backpressure is already provided through the MacEvent drop mechanism
|
2023-07-21 23:10:34 +02:00
|
|
|
// therefore, we don't need to worry about overwriting events
|
|
|
|
pub(crate) rx_event_channel: ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>,
|
2023-07-21 03:51:49 +02:00
|
|
|
pub(crate) read_mutex: Mutex<CriticalSectionRawMutex, ()>,
|
|
|
|
pub(crate) write_mutex: Mutex<CriticalSectionRawMutex, ()>,
|
2023-07-20 23:45:04 +02:00
|
|
|
pub(crate) rx_channel: Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>,
|
2023-07-20 00:49:08 +02:00
|
|
|
pub(crate) tx_channel: Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), 5>,
|
|
|
|
pub(crate) tx_buf_channel: Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], 5>,
|
2023-07-16 02:15:01 +02:00
|
|
|
}
|
|
|
|
|
2023-07-19 01:28:12 +02:00
|
|
|
impl<'a> Runner<'a> {
|
2023-07-19 03:52:03 +02:00
|
|
|
pub fn new(mac: Mac, tx_buf_queue: [&'a mut [u8; MTU]; 5]) -> Self {
|
|
|
|
let this = Self {
|
2023-07-18 03:14:06 +02:00
|
|
|
mac_subsystem: mac,
|
2023-07-21 03:51:49 +02:00
|
|
|
rx_event_channel: blocking_mutex::Mutex::new(RefCell::new(None)),
|
|
|
|
read_mutex: Mutex::new(()),
|
|
|
|
write_mutex: Mutex::new(()),
|
2023-07-19 01:28:12 +02:00
|
|
|
rx_channel: Channel::new(),
|
|
|
|
tx_channel: Channel::new(),
|
2023-07-19 03:52:03 +02:00
|
|
|
tx_buf_channel: Channel::new(),
|
|
|
|
};
|
|
|
|
|
|
|
|
for buf in tx_buf_queue {
|
|
|
|
this.tx_buf_channel.try_send(buf).unwrap();
|
2023-07-18 03:14:06 +02:00
|
|
|
}
|
2023-07-16 02:15:01 +02:00
|
|
|
|
2023-07-19 03:52:03 +02:00
|
|
|
this
|
2023-07-16 02:15:01 +02:00
|
|
|
}
|
|
|
|
|
2023-07-20 00:49:08 +02:00
|
|
|
pub async fn run(&'a self) -> ! {
|
2023-07-19 03:52:03 +02:00
|
|
|
join::join(
|
|
|
|
async {
|
|
|
|
loop {
|
2023-07-20 00:49:08 +02:00
|
|
|
if let Ok(mac_event) = self.mac_subsystem.read().await {
|
2023-07-20 23:45:04 +02:00
|
|
|
match mac_event {
|
2023-07-19 03:52:03 +02:00
|
|
|
MacEvent::McpsDataInd(_) => {
|
2023-07-20 00:49:08 +02:00
|
|
|
self.rx_channel.send(mac_event).await;
|
2023-07-19 03:52:03 +02:00
|
|
|
}
|
2023-07-21 03:51:49 +02:00
|
|
|
_ => {
|
|
|
|
self.rx_event_channel.lock(|s| {
|
|
|
|
match &*s.borrow() {
|
|
|
|
Some(signal) => {
|
|
|
|
signal.signal(mac_event);
|
|
|
|
}
|
|
|
|
None => {}
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
2023-07-19 03:52:03 +02:00
|
|
|
}
|
2023-07-18 03:14:06 +02:00
|
|
|
}
|
|
|
|
}
|
2023-07-19 03:52:03 +02:00
|
|
|
},
|
|
|
|
async {
|
2023-07-21 00:00:03 +02:00
|
|
|
let mut msdu_handle = 0x02;
|
|
|
|
|
2023-07-19 03:52:03 +02:00
|
|
|
loop {
|
2023-08-11 11:58:22 +02:00
|
|
|
let (buf, len) = self.tx_channel.receive().await;
|
2023-07-21 03:51:49 +02:00
|
|
|
let _wm = self.write_mutex.lock().await;
|
2023-07-18 03:14:06 +02:00
|
|
|
|
2023-07-21 03:51:49 +02:00
|
|
|
// The mutex should be dropped on the next loop iteration
|
2023-07-19 03:52:03 +02:00
|
|
|
self.mac_subsystem
|
|
|
|
.send_command(
|
|
|
|
DataRequest {
|
|
|
|
src_addr_mode: AddressMode::Short,
|
|
|
|
dst_addr_mode: AddressMode::Short,
|
|
|
|
dst_pan_id: PanId([0x1A, 0xAA]),
|
|
|
|
dst_address: MacAddress::BROADCAST,
|
2023-07-21 00:00:03 +02:00
|
|
|
msdu_handle: msdu_handle,
|
2023-07-19 03:52:03 +02:00
|
|
|
ack_tx: 0x00,
|
|
|
|
gts_tx: false,
|
|
|
|
security_level: SecurityLevel::Unsecure,
|
|
|
|
..Default::default()
|
|
|
|
}
|
2023-07-20 00:49:08 +02:00
|
|
|
.set_buffer(&buf[..len]),
|
2023-07-19 03:52:03 +02:00
|
|
|
)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
2023-07-22 00:02:36 +02:00
|
|
|
msdu_handle = msdu_handle.wrapping_add(1);
|
2023-07-21 00:00:03 +02:00
|
|
|
|
2023-07-19 03:52:03 +02:00
|
|
|
// The tx channel should always be of equal capacity to the tx_buf channel
|
|
|
|
self.tx_buf_channel.try_send(buf).unwrap();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
|
|
|
|
loop {}
|
2023-07-16 02:15:01 +02:00
|
|
|
}
|
|
|
|
}
|