2023-07-20 23:45:04 +02:00
|
|
|
use core::{mem, ptr};
|
2023-07-16 22:09:30 +02:00
|
|
|
|
2023-07-12 16:06:56 +02:00
|
|
|
use super::indications::{
|
|
|
|
AssociateIndication, BeaconNotifyIndication, CommStatusIndication, DataIndication, DisassociateIndication,
|
|
|
|
DpsIndication, GtsIndication, OrphanIndication, PollIndication, SyncLossIndication,
|
|
|
|
};
|
|
|
|
use super::responses::{
|
|
|
|
AssociateConfirm, CalibrateConfirm, DataConfirm, DisassociateConfirm, DpsConfirm, GetConfirm, GtsConfirm,
|
|
|
|
PollConfirm, PurgeConfirm, ResetConfirm, RxEnableConfirm, ScanConfirm, SetConfirm, SoundingConfirm, StartConfirm,
|
|
|
|
};
|
2023-07-20 23:45:04 +02:00
|
|
|
use crate::evt::{EvtBox, MemoryManager};
|
2023-07-15 21:47:34 +02:00
|
|
|
use crate::mac::opcodes::OpcodeM0ToM4;
|
2023-07-20 23:45:04 +02:00
|
|
|
use crate::sub::mac::{self, Mac};
|
2023-07-12 16:06:56 +02:00
|
|
|
|
2023-07-16 22:09:30 +02:00
|
|
|
pub(crate) trait ParseableMacEvent: Sized {
|
|
|
|
fn from_buffer<'a>(buf: &'a [u8]) -> Result<&'a Self, ()> {
|
|
|
|
if buf.len() < mem::size_of::<Self>() {
|
|
|
|
Err(())
|
|
|
|
} else {
|
|
|
|
Ok(unsafe { &*(buf as *const _ as *const Self) })
|
2023-07-12 16:06:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-20 23:45:04 +02:00
|
|
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
2023-07-21 02:52:36 +02:00
|
|
|
#[derive(Debug)]
|
2023-07-20 23:45:04 +02:00
|
|
|
pub enum MacEvent<'a> {
|
|
|
|
MlmeAssociateCnf(&'a AssociateConfirm),
|
|
|
|
MlmeDisassociateCnf(&'a DisassociateConfirm),
|
|
|
|
MlmeGetCnf(&'a GetConfirm),
|
|
|
|
MlmeGtsCnf(&'a GtsConfirm),
|
|
|
|
MlmeResetCnf(&'a ResetConfirm),
|
|
|
|
MlmeRxEnableCnf(&'a RxEnableConfirm),
|
|
|
|
MlmeScanCnf(&'a ScanConfirm),
|
|
|
|
MlmeSetCnf(&'a SetConfirm),
|
|
|
|
MlmeStartCnf(&'a StartConfirm),
|
|
|
|
MlmePollCnf(&'a PollConfirm),
|
|
|
|
MlmeDpsCnf(&'a DpsConfirm),
|
|
|
|
MlmeSoundingCnf(&'a SoundingConfirm),
|
|
|
|
MlmeCalibrateCnf(&'a CalibrateConfirm),
|
|
|
|
McpsDataCnf(&'a DataConfirm),
|
|
|
|
McpsPurgeCnf(&'a PurgeConfirm),
|
|
|
|
MlmeAssociateInd(&'a AssociateIndication),
|
|
|
|
MlmeDisassociateInd(&'a DisassociateIndication),
|
|
|
|
MlmeBeaconNotifyInd(&'a BeaconNotifyIndication),
|
|
|
|
MlmeCommStatusInd(&'a CommStatusIndication),
|
|
|
|
MlmeGtsInd(&'a GtsIndication),
|
|
|
|
MlmeOrphanInd(&'a OrphanIndication),
|
|
|
|
MlmeSyncLossInd(&'a SyncLossIndication),
|
|
|
|
MlmeDpsInd(&'a DpsIndication),
|
|
|
|
McpsDataInd(&'a DataIndication),
|
|
|
|
MlmePollInd(&'a PollIndication),
|
2023-07-12 16:06:56 +02:00
|
|
|
}
|
|
|
|
|
2023-07-20 23:45:04 +02:00
|
|
|
impl<'a> MacEvent<'a> {
|
2023-07-20 00:49:08 +02:00
|
|
|
pub(crate) fn new(event_box: EvtBox<Mac>) -> Result<Self, ()> {
|
|
|
|
let payload = event_box.payload();
|
2023-07-16 22:09:30 +02:00
|
|
|
let opcode = u16::from_le_bytes(payload[0..2].try_into().unwrap());
|
2023-07-12 16:06:56 +02:00
|
|
|
|
|
|
|
let opcode = OpcodeM0ToM4::try_from(opcode)?;
|
2023-07-17 00:28:34 +02:00
|
|
|
let buf = &payload[2..];
|
2023-07-12 16:06:56 +02:00
|
|
|
|
2023-07-20 00:49:08 +02:00
|
|
|
// To avoid re-parsing the opcode, we store the result of the parse
|
|
|
|
// this requires use of unsafe because rust cannot assume that a reference will become
|
|
|
|
// invalid when the underlying result is moved. However, because we refer to a "heap"
|
|
|
|
// allocation, the underlying reference will not move until the struct is dropped.
|
|
|
|
|
|
|
|
let mac_event = match opcode {
|
|
|
|
OpcodeM0ToM4::MlmeAssociateCnf => {
|
|
|
|
MacEvent::MlmeAssociateCnf(unsafe { &*(AssociateConfirm::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
2023-07-17 00:28:34 +02:00
|
|
|
OpcodeM0ToM4::MlmeDisassociateCnf => {
|
2023-07-20 00:49:08 +02:00
|
|
|
MacEvent::MlmeDisassociateCnf(unsafe { &*(DisassociateConfirm::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeGetCnf => MacEvent::MlmeGetCnf(unsafe { &*(GetConfirm::from_buffer(buf)? as *const _) }),
|
|
|
|
OpcodeM0ToM4::MlmeGtsCnf => MacEvent::MlmeGtsCnf(unsafe { &*(GtsConfirm::from_buffer(buf)? as *const _) }),
|
|
|
|
OpcodeM0ToM4::MlmeResetCnf => {
|
|
|
|
MacEvent::MlmeResetCnf(unsafe { &*(ResetConfirm::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeRxEnableCnf => {
|
|
|
|
MacEvent::MlmeRxEnableCnf(unsafe { &*(RxEnableConfirm::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeScanCnf => {
|
|
|
|
MacEvent::MlmeScanCnf(unsafe { &*(ScanConfirm::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeSetCnf => MacEvent::MlmeSetCnf(unsafe { &*(SetConfirm::from_buffer(buf)? as *const _) }),
|
|
|
|
OpcodeM0ToM4::MlmeStartCnf => {
|
|
|
|
MacEvent::MlmeStartCnf(unsafe { &*(StartConfirm::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmePollCnf => {
|
|
|
|
MacEvent::MlmePollCnf(unsafe { &*(PollConfirm::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeDpsCnf => MacEvent::MlmeDpsCnf(unsafe { &*(DpsConfirm::from_buffer(buf)? as *const _) }),
|
|
|
|
OpcodeM0ToM4::MlmeSoundingCnf => {
|
|
|
|
MacEvent::MlmeSoundingCnf(unsafe { &*(SoundingConfirm::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeCalibrateCnf => {
|
|
|
|
MacEvent::MlmeCalibrateCnf(unsafe { &*(CalibrateConfirm::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::McpsDataCnf => {
|
|
|
|
MacEvent::McpsDataCnf(unsafe { &*(DataConfirm::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::McpsPurgeCnf => {
|
|
|
|
MacEvent::McpsPurgeCnf(unsafe { &*(PurgeConfirm::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeAssociateInd => {
|
|
|
|
MacEvent::MlmeAssociateInd(unsafe { &*(AssociateIndication::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
2023-07-17 00:28:34 +02:00
|
|
|
OpcodeM0ToM4::MlmeDisassociateInd => {
|
2023-07-20 00:49:08 +02:00
|
|
|
MacEvent::MlmeDisassociateInd(unsafe { &*(DisassociateIndication::from_buffer(buf)? as *const _) })
|
2023-07-16 22:09:30 +02:00
|
|
|
}
|
2023-07-17 00:28:34 +02:00
|
|
|
OpcodeM0ToM4::MlmeBeaconNotifyInd => {
|
2023-07-20 00:49:08 +02:00
|
|
|
MacEvent::MlmeBeaconNotifyInd(unsafe { &*(BeaconNotifyIndication::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeCommStatusInd => {
|
|
|
|
MacEvent::MlmeCommStatusInd(unsafe { &*(CommStatusIndication::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeGtsInd => {
|
|
|
|
MacEvent::MlmeGtsInd(unsafe { &*(GtsIndication::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeOrphanInd => {
|
|
|
|
MacEvent::MlmeOrphanInd(unsafe { &*(OrphanIndication::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeSyncLossInd => {
|
|
|
|
MacEvent::MlmeSyncLossInd(unsafe { &*(SyncLossIndication::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmeDpsInd => {
|
|
|
|
MacEvent::MlmeDpsInd(unsafe { &*(DpsIndication::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::McpsDataInd => {
|
|
|
|
MacEvent::McpsDataInd(unsafe { &*(DataIndication::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
OpcodeM0ToM4::MlmePollInd => {
|
|
|
|
MacEvent::MlmePollInd(unsafe { &*(PollIndication::from_buffer(buf)? as *const _) })
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-07-20 23:45:04 +02:00
|
|
|
// Forget the event box so that drop isn't called
|
|
|
|
// We want to handle the lifetime ourselves
|
2023-07-20 00:49:08 +02:00
|
|
|
|
2023-07-20 23:45:04 +02:00
|
|
|
mem::forget(event_box);
|
2023-07-20 00:49:08 +02:00
|
|
|
|
2023-07-20 23:45:04 +02:00
|
|
|
Ok(mac_event)
|
2023-07-12 16:06:56 +02:00
|
|
|
}
|
|
|
|
}
|
2023-07-16 16:32:54 +02:00
|
|
|
|
2023-07-20 23:45:04 +02:00
|
|
|
impl<'a> Drop for MacEvent<'a> {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe { mac::Mac::drop_event_packet(ptr::null_mut()) };
|
|
|
|
}
|
2023-07-16 22:09:30 +02:00
|
|
|
}
|