2023-07-20 00:49:08 +02:00
|
|
|
use core::{mem, ops};
|
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-16 22:09:30 +02:00
|
|
|
use crate::evt::EvtBox;
|
2023-07-15 21:47:34 +02:00
|
|
|
use crate::mac::opcodes::OpcodeM0ToM4;
|
2023-07-16 22:09:30 +02:00
|
|
|
use crate::sub::mac::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 00:49:08 +02:00
|
|
|
pub struct Event<'a> {
|
|
|
|
#[allow(dead_code)]
|
2023-07-16 22:09:30 +02:00
|
|
|
event_box: EvtBox<Mac>,
|
2023-07-20 00:49:08 +02:00
|
|
|
mac_event: MacEvent<'a>,
|
2023-07-12 16:06:56 +02:00
|
|
|
}
|
|
|
|
|
2023-07-20 00:49:08 +02:00
|
|
|
impl<'a> Event<'a> {
|
|
|
|
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 _) })
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(Self { event_box, mac_event })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> ops::Deref for Event<'a> {
|
|
|
|
type Target = MacEvent<'a>;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.mac_event
|
2023-07-12 16:06:56 +02:00
|
|
|
}
|
|
|
|
}
|
2023-07-16 16:32:54 +02:00
|
|
|
|
2023-07-16 22:09:30 +02:00
|
|
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
|
|
|
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),
|
|
|
|
}
|