basic PUS event manager
This commit is contained in:
parent
6fe3738364
commit
478673327b
@ -1,5 +1,5 @@
|
|||||||
//! [Event][crate::events::Event] management and forwarding
|
//! [Event][crate::events::Event] management and forwarding
|
||||||
use crate::events::{Event, EventProvider, EventSmall};
|
use crate::events::{EventU16TypedSev, EventU32, GenericEvent, HasSeverity};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
@ -11,34 +11,34 @@ enum ListenerType {
|
|||||||
Group(u16),
|
Group(u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait EventListener<Provider: EventProvider = Event> {
|
pub trait EventListener<Provider: GenericEvent> {
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
fn id(&self) -> u32;
|
fn id(&self) -> u32;
|
||||||
fn send_to(&mut self, event: Provider) -> Result<(), Self::Error>;
|
fn send_to(&mut self, event: Provider) -> Result<(), Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Listener<E, Provider: EventProvider = Event> {
|
struct Listener<E, Provider: GenericEvent> {
|
||||||
ltype: ListenerType,
|
ltype: ListenerType,
|
||||||
dest: Box<dyn EventListener<Provider, Error = E>>,
|
dest: Box<dyn EventListener<Provider, Error = E>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ReceivesAllEvent<Provider: EventProvider = Event> {
|
pub trait ReceivesAllEvent<Provider: GenericEvent> {
|
||||||
fn receive(&mut self) -> Option<Provider>;
|
fn receive(&mut self) -> Option<Provider>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventManager<E, Provider: EventProvider = Event> {
|
pub struct EventManager<E, Provider: GenericEvent> {
|
||||||
listeners: HashMap<ListenerType, Vec<Listener<E, Provider>>>,
|
listeners: HashMap<ListenerType, Vec<Listener<E, Provider>>>,
|
||||||
event_receiver: Box<dyn ReceivesAllEvent<Provider>>,
|
event_receiver: Box<dyn ReceivesAllEvent<Provider>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum HandlerResult<Provider: EventProvider = Event> {
|
pub enum HandlerResult<Provider: GenericEvent> {
|
||||||
Empty,
|
Empty,
|
||||||
Handled(u32, Provider),
|
Handled(u32, Provider),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> EventManager<E, Event> {
|
impl<E> EventManager<E, EventU32> {
|
||||||
pub fn new(event_receiver: Box<dyn ReceivesAllEvent<Event>>) -> Self {
|
pub fn new(event_receiver: Box<dyn ReceivesAllEvent<EventU32>>) -> Self {
|
||||||
EventManager {
|
EventManager {
|
||||||
listeners: HashMap::new(),
|
listeners: HashMap::new(),
|
||||||
event_receiver,
|
event_receiver,
|
||||||
@ -46,43 +46,43 @@ impl<E> EventManager<E, Event> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> EventManager<E, Event> {
|
impl<E> EventManager<E, EventU32> {
|
||||||
pub fn subscribe_single(
|
pub fn subscribe_single(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: EventU32,
|
||||||
dest: impl EventListener<Event, Error = E> + 'static,
|
dest: impl EventListener<EventU32, Error = E> + 'static,
|
||||||
) {
|
) {
|
||||||
self.update_listeners(ListenerType::Single(event.raw_as_largest_type()), dest);
|
self.update_listeners(ListenerType::Single(event.raw_as_largest_type()), dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn subscribe_group(
|
pub fn subscribe_group(
|
||||||
&mut self,
|
&mut self,
|
||||||
group_id: <Event as EventProvider>::GroupId,
|
group_id: <EventU32 as GenericEvent>::GroupId,
|
||||||
dest: impl EventListener<Event, Error = E> + 'static,
|
dest: impl EventListener<EventU32, Error = E> + 'static,
|
||||||
) {
|
) {
|
||||||
self.update_listeners(ListenerType::Group(group_id), dest);
|
self.update_listeners(ListenerType::Group(group_id), dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> EventManager<E, EventSmall> {
|
impl<E, SEVERITY: HasSeverity + Copy> EventManager<E, EventU16TypedSev<SEVERITY>> {
|
||||||
pub fn subscribe_single(
|
pub fn subscribe_single(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: EventSmall,
|
event: EventU16TypedSev<SEVERITY>,
|
||||||
dest: impl EventListener<EventSmall, Error = E> + 'static,
|
dest: impl EventListener<EventU16TypedSev<SEVERITY>, Error = E> + 'static,
|
||||||
) {
|
) {
|
||||||
self.update_listeners(ListenerType::Single(event.raw_as_largest_type()), dest);
|
self.update_listeners(ListenerType::Single(event.raw_as_largest_type()), dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn subscribe_group(
|
pub fn subscribe_group(
|
||||||
&mut self,
|
&mut self,
|
||||||
group_id: <EventSmall as EventProvider>::GroupId,
|
group_id: <EventU16TypedSev<SEVERITY> as GenericEvent>::GroupId,
|
||||||
dest: impl EventListener<EventSmall, Error = E> + 'static,
|
dest: impl EventListener<EventU16TypedSev<SEVERITY>, Error = E> + 'static,
|
||||||
) {
|
) {
|
||||||
self.update_listeners(ListenerType::Group(group_id.into()), dest);
|
self.update_listeners(ListenerType::Group(group_id.into()), dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, Provider: EventProvider> EventManager<E, Provider> {
|
impl<E, Provider: GenericEvent + Copy> EventManager<E, Provider> {
|
||||||
fn update_listeners(
|
fn update_listeners(
|
||||||
&mut self,
|
&mut self,
|
||||||
key: ListenerType,
|
key: ListenerType,
|
||||||
@ -145,17 +145,17 @@ impl<E, Provider: EventProvider> EventManager<E, Provider> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::{EventListener, HandlerResult, ReceivesAllEvent};
|
use super::{EventListener, HandlerResult, ReceivesAllEvent};
|
||||||
use crate::event_man::EventManager;
|
use crate::event_man::EventManager;
|
||||||
use crate::events::{Event, EventProvider, Severity};
|
use crate::events::{EventU32, GenericEvent, Severity};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use std::sync::mpsc::{channel, Receiver, SendError, Sender};
|
use std::sync::mpsc::{channel, Receiver, SendError, Sender};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
struct EventReceiver {
|
struct EventReceiver {
|
||||||
mpsc_receiver: Receiver<Event>,
|
mpsc_receiver: Receiver<EventU32>,
|
||||||
}
|
}
|
||||||
impl ReceivesAllEvent<Event> for EventReceiver {
|
impl ReceivesAllEvent<EventU32> for EventReceiver {
|
||||||
fn receive(&mut self) -> Option<Event> {
|
fn receive(&mut self) -> Option<EventU32> {
|
||||||
self.mpsc_receiver.try_recv().ok()
|
self.mpsc_receiver.try_recv().ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,21 +163,21 @@ mod tests {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct MpscEventSenderQueue {
|
struct MpscEventSenderQueue {
|
||||||
id: u32,
|
id: u32,
|
||||||
mpsc_sender: Sender<Event>,
|
mpsc_sender: Sender<EventU32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventListener<Event> for MpscEventSenderQueue {
|
impl EventListener<EventU32> for MpscEventSenderQueue {
|
||||||
type Error = SendError<Event>;
|
type Error = SendError<EventU32>;
|
||||||
|
|
||||||
fn id(&self) -> u32 {
|
fn id(&self) -> u32 {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
fn send_to(&mut self, event: Event) -> Result<(), Self::Error> {
|
fn send_to(&mut self, event: EventU32) -> Result<(), Self::Error> {
|
||||||
self.mpsc_sender.send(event)
|
self.mpsc_sender.send(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_next_event(expected: Event, receiver: &Receiver<Event>) {
|
fn check_next_event(expected: EventU32, receiver: &Receiver<EventU32>) {
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
if let Ok(event) = receiver.try_recv() {
|
if let Ok(event) = receiver.try_recv() {
|
||||||
assert_eq!(event, expected);
|
assert_eq!(event, expected);
|
||||||
@ -187,7 +187,11 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_handled_event(res: HandlerResult, expected: Event, expected_num_sent: u32) {
|
fn check_handled_event(
|
||||||
|
res: HandlerResult<EventU32>,
|
||||||
|
expected: EventU32,
|
||||||
|
expected_num_sent: u32,
|
||||||
|
) {
|
||||||
assert!(matches!(res, HandlerResult::Handled { .. }));
|
assert!(matches!(res, HandlerResult::Handled { .. }));
|
||||||
if let HandlerResult::Handled(num_recipients, event) = res {
|
if let HandlerResult::Handled(num_recipients, event) = res {
|
||||||
assert_eq!(event, expected);
|
assert_eq!(event, expected);
|
||||||
@ -201,10 +205,10 @@ mod tests {
|
|||||||
let event_man_receiver = EventReceiver {
|
let event_man_receiver = EventReceiver {
|
||||||
mpsc_receiver: manager_queue,
|
mpsc_receiver: manager_queue,
|
||||||
};
|
};
|
||||||
let mut event_man: EventManager<SendError<Event>, Event> =
|
let mut event_man: EventManager<SendError<EventU32>, EventU32> =
|
||||||
EventManager::new(Box::new(event_man_receiver));
|
EventManager::new(Box::new(event_man_receiver));
|
||||||
let event_grp_0 = Event::new(Severity::INFO, 0, 0).unwrap();
|
let event_grp_0 = EventU32::new(Severity::INFO, 0, 0).unwrap();
|
||||||
let event_grp_1_0 = Event::new(Severity::HIGH, 1, 0).unwrap();
|
let event_grp_1_0 = EventU32::new(Severity::HIGH, 1, 0).unwrap();
|
||||||
let (single_event_sender, single_event_receiver) = channel();
|
let (single_event_sender, single_event_receiver) = channel();
|
||||||
let single_event_listener = MpscEventSenderQueue {
|
let single_event_listener = MpscEventSenderQueue {
|
||||||
id: 0,
|
id: 0,
|
||||||
@ -244,15 +248,15 @@ mod tests {
|
|||||||
let event_man_receiver = EventReceiver {
|
let event_man_receiver = EventReceiver {
|
||||||
mpsc_receiver: manager_queue,
|
mpsc_receiver: manager_queue,
|
||||||
};
|
};
|
||||||
let mut event_man: EventManager<SendError<Event>, Event> =
|
let mut event_man: EventManager<SendError<EventU32>, EventU32> =
|
||||||
EventManager::new(Box::new(event_man_receiver));
|
EventManager::new(Box::new(event_man_receiver));
|
||||||
let res = event_man.try_event_handling();
|
let res = event_man.try_event_handling();
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
let hres = res.unwrap();
|
let hres = res.unwrap();
|
||||||
assert!(matches!(hres, HandlerResult::Empty));
|
assert!(matches!(hres, HandlerResult::Empty));
|
||||||
|
|
||||||
let event_grp_0 = Event::new(Severity::INFO, 0, 0).unwrap();
|
let event_grp_0 = EventU32::new(Severity::INFO, 0, 0).unwrap();
|
||||||
let event_grp_1_0 = Event::new(Severity::HIGH, 1, 0).unwrap();
|
let event_grp_1_0 = EventU32::new(Severity::HIGH, 1, 0).unwrap();
|
||||||
let (event_grp_0_sender, event_grp_0_receiver) = channel();
|
let (event_grp_0_sender, event_grp_0_receiver) = channel();
|
||||||
let event_grp_0_and_1_listener = MpscEventSenderQueue {
|
let event_grp_0_and_1_listener = MpscEventSenderQueue {
|
||||||
id: 0,
|
id: 0,
|
||||||
@ -286,10 +290,10 @@ mod tests {
|
|||||||
let event_man_receiver = EventReceiver {
|
let event_man_receiver = EventReceiver {
|
||||||
mpsc_receiver: manager_queue,
|
mpsc_receiver: manager_queue,
|
||||||
};
|
};
|
||||||
let mut event_man: EventManager<SendError<Event>, Event> =
|
let mut event_man: EventManager<SendError<EventU32>, EventU32> =
|
||||||
EventManager::new(Box::new(event_man_receiver));
|
EventManager::new(Box::new(event_man_receiver));
|
||||||
let event_0 = Event::new(Severity::INFO, 0, 5).unwrap();
|
let event_0 = EventU32::new(Severity::INFO, 0, 5).unwrap();
|
||||||
let event_1 = Event::new(Severity::HIGH, 1, 0).unwrap();
|
let event_1 = EventU32::new(Severity::HIGH, 1, 0).unwrap();
|
||||||
let (event_0_tx_0, event_0_rx_0) = channel();
|
let (event_0_tx_0, event_0_rx_0) = channel();
|
||||||
let (event_0_tx_1, event_0_rx_1) = channel();
|
let (event_0_tx_1, event_0_rx_1) = channel();
|
||||||
let event_listener_0 = MpscEventSenderQueue {
|
let event_listener_0 = MpscEventSenderQueue {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Event support module
|
//! Event support module
|
||||||
|
|
||||||
use core::hash::Hash;
|
use core::hash::Hash;
|
||||||
|
use delegate::delegate;
|
||||||
use spacepackets::ecss::{EcssEnumeration, ToBeBytes};
|
use spacepackets::ecss::{EcssEnumeration, ToBeBytes};
|
||||||
use spacepackets::{ByteConversionError, SizeMissmatch};
|
use spacepackets::{ByteConversionError, SizeMissmatch};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
@ -18,7 +19,34 @@ pub enum Severity {
|
|||||||
HIGH = 3,
|
HIGH = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait EventProvider: EcssEnumeration + PartialEq + Eq + Copy + Clone + Hash {
|
pub trait HasSeverity {
|
||||||
|
const SEVERITY: Severity;
|
||||||
|
}
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct SeverityInfo {}
|
||||||
|
impl HasSeverity for SeverityInfo {
|
||||||
|
const SEVERITY: Severity = Severity::INFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct SeverityLow {}
|
||||||
|
impl HasSeverity for SeverityLow {
|
||||||
|
const SEVERITY: Severity = Severity::LOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct SeverityMedium {}
|
||||||
|
impl HasSeverity for SeverityMedium {
|
||||||
|
const SEVERITY: Severity = Severity::MEDIUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct SeverityHigh {}
|
||||||
|
impl HasSeverity for SeverityHigh {
|
||||||
|
const SEVERITY: Severity = Severity::HIGH;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GenericEvent: EcssEnumeration {
|
||||||
type Raw;
|
type Raw;
|
||||||
type GroupId;
|
type GroupId;
|
||||||
type UniqueId;
|
type UniqueId;
|
||||||
@ -149,43 +177,78 @@ macro_rules! event_provider_impl {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub struct Event {
|
|
||||||
base: EventBase<u32, u16, u16>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventProvider for Event {
|
macro_rules! impl_event_provider {
|
||||||
type Raw = u32;
|
($BaseIdent: ident, $TypedIdent: ident, $raw: ty, $gid: ty, $uid: ty) => {
|
||||||
type GroupId = u16;
|
impl GenericEvent for $BaseIdent {
|
||||||
type UniqueId = u16;
|
type Raw = $raw;
|
||||||
|
type GroupId = $gid;
|
||||||
|
type UniqueId = $uid;
|
||||||
|
|
||||||
event_provider_impl!();
|
event_provider_impl!();
|
||||||
|
|
||||||
fn raw_as_largest_type(&self) -> LargestEventRaw {
|
fn raw_as_largest_type(&self) -> LargestEventRaw {
|
||||||
self.raw()
|
self.raw().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn group_id_as_largest_type(&self) -> LargestGroupIdRaw {
|
fn group_id_as_largest_type(&self) -> LargestGroupIdRaw {
|
||||||
self.group_id()
|
self.group_id().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<SEVERITY: HasSeverity> GenericEvent for $TypedIdent<SEVERITY> {
|
||||||
|
type Raw = $raw;
|
||||||
|
type GroupId = $gid;
|
||||||
|
type UniqueId = $uid;
|
||||||
|
|
||||||
|
delegate!(to self.event {
|
||||||
|
fn raw(&self) -> Self::Raw;
|
||||||
|
fn severity(&self) -> Severity;
|
||||||
|
fn group_id(&self) -> Self::GroupId;
|
||||||
|
fn unique_id(&self) -> Self::UniqueId;
|
||||||
|
fn raw_as_largest_type(&self) -> LargestEventRaw;
|
||||||
|
fn group_id_as_largest_type(&self) -> LargestGroupIdRaw;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Event {
|
macro_rules! try_from_impls {
|
||||||
/// Generate an event. The raw representation of an event has 32 bits.
|
($SevIdent: ident, $severity: path, $raw: ty, $TypedSevIdent: ident) => {
|
||||||
/// If the passed group ID is invalid (too large), None wil be returned
|
impl TryFrom<$raw> for $TypedSevIdent<$SevIdent> {
|
||||||
///
|
type Error = Severity;
|
||||||
/// # Parameter
|
|
||||||
///
|
fn try_from(raw: $raw) -> Result<Self, Self::Error> {
|
||||||
/// * `severity`: Each event has a [severity][Severity]. The raw value of the severity will
|
Self::try_from_generic($severity, raw)
|
||||||
/// be stored inside the uppermost 2 bits of the raw event ID
|
}
|
||||||
/// * `group_id`: Related events can be grouped using a group ID. The group ID will occupy the
|
}
|
||||||
/// next 14 bits after the severity. Therefore, the size is limited by dec 16383 hex 0x3FFF.
|
};
|
||||||
/// * `unique_id`: Each event has a unique 16 bit ID occupying the last 16 bits of the
|
}
|
||||||
/// raw event ID
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub struct EventU32 {
|
||||||
|
base: EventBase<u32, u16, u16>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub struct EventU32TypedSev<SEVERITY> {
|
||||||
|
event: EventU32,
|
||||||
|
phantom: PhantomData<SEVERITY>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<SEVERITY: HasSeverity> From<EventU32TypedSev<SEVERITY>> for EventU32 {
|
||||||
|
fn from(e: EventU32TypedSev<SEVERITY>) -> Self {
|
||||||
|
Self { base: e.event.base }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_event_provider!(EventU32, EventU32TypedSev, u32, u16, u16);
|
||||||
|
|
||||||
|
impl EventU32 {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
group_id: <Self as EventProvider>::GroupId,
|
group_id: <Self as GenericEvent>::GroupId,
|
||||||
unique_id: <Self as EventProvider>::UniqueId,
|
unique_id: <Self as GenericEvent>::UniqueId,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
if group_id > (2u16.pow(14) - 1) {
|
if group_id > (2u16.pow(14) - 1) {
|
||||||
return None;
|
return None;
|
||||||
@ -199,12 +262,10 @@ impl Event {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Const version of [new], but panics on invalid group ID input values.
|
|
||||||
pub const fn const_new(
|
pub const fn const_new(
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
group_id: <Self as EventProvider>::GroupId,
|
group_id: <Self as GenericEvent>::GroupId,
|
||||||
unique_id: <Self as EventProvider>::UniqueId,
|
unique_id: <Self as GenericEvent>::UniqueId,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
if group_id > (2u16.pow(14) - 1) {
|
if group_id > (2u16.pow(14) - 1) {
|
||||||
panic!("Group ID too large");
|
panic!("Group ID too large");
|
||||||
@ -220,7 +281,54 @@ impl Event {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u32> for Event {
|
impl<SEVERITY: HasSeverity> EventU32TypedSev<SEVERITY> {
|
||||||
|
/// Generate an event. The raw representation of an event has 32 bits.
|
||||||
|
/// If the passed group ID is invalid (too large), None wil be returned
|
||||||
|
///
|
||||||
|
/// # Parameter
|
||||||
|
///
|
||||||
|
/// * `severity`: Each event has a [severity][Severity]. The raw value of the severity will
|
||||||
|
/// be stored inside the uppermost 2 bits of the raw event ID
|
||||||
|
/// * `group_id`: Related events can be grouped using a group ID. The group ID will occupy the
|
||||||
|
/// next 14 bits after the severity. Therefore, the size is limited by dec 16383 hex 0x3FFF.
|
||||||
|
/// * `unique_id`: Each event has a unique 16 bit ID occupying the last 16 bits of the
|
||||||
|
/// raw event ID
|
||||||
|
pub fn new(
|
||||||
|
group_id: <Self as GenericEvent>::GroupId,
|
||||||
|
unique_id: <Self as GenericEvent>::UniqueId,
|
||||||
|
) -> Option<Self> {
|
||||||
|
let event = EventU32::new(SEVERITY::SEVERITY, group_id, unique_id)?;
|
||||||
|
Some(Self {
|
||||||
|
event,
|
||||||
|
phantom: PhantomData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Const version of [new], but panics on invalid group ID input values.
|
||||||
|
pub const fn const_new(
|
||||||
|
group_id: <Self as GenericEvent>::GroupId,
|
||||||
|
unique_id: <Self as GenericEvent>::UniqueId,
|
||||||
|
) -> Self {
|
||||||
|
let event = EventU32::const_new(SEVERITY::SEVERITY, group_id, unique_id);
|
||||||
|
Self {
|
||||||
|
event,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_from_generic(expected: Severity, raw: u32) -> Result<Self, Severity> {
|
||||||
|
let severity = Severity::try_from(((raw >> 30) & 0b11) as u8).unwrap();
|
||||||
|
if severity != expected {
|
||||||
|
return Err(severity);
|
||||||
|
}
|
||||||
|
Ok(Self::const_new(
|
||||||
|
((raw >> 16) & 0x3FFF) as u16,
|
||||||
|
(raw & 0xFFFF) as u16,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u32> for EventU32 {
|
||||||
fn from(raw: u32) -> Self {
|
fn from(raw: u32) -> Self {
|
||||||
// Severity conversion from u8 should never fail
|
// Severity conversion from u8 should never fail
|
||||||
let severity = Severity::try_from(((raw >> 30) & 0b11) as u8).unwrap();
|
let severity = Severity::try_from(((raw >> 30) & 0b11) as u8).unwrap();
|
||||||
@ -231,7 +339,12 @@ impl From<u32> for Event {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EcssEnumeration for Event {
|
try_from_impls!(SeverityInfo, Severity::INFO, u32, EventU32TypedSev);
|
||||||
|
try_from_impls!(SeverityLow, Severity::LOW, u32, EventU32TypedSev);
|
||||||
|
try_from_impls!(SeverityMedium, Severity::MEDIUM, u32, EventU32TypedSev);
|
||||||
|
try_from_impls!(SeverityHigh, Severity::HIGH, u32, EventU32TypedSev);
|
||||||
|
|
||||||
|
impl EcssEnumeration for EventU32 {
|
||||||
fn pfc(&self) -> u8 {
|
fn pfc(&self) -> u8 {
|
||||||
32
|
32
|
||||||
}
|
}
|
||||||
@ -241,12 +354,26 @@ impl EcssEnumeration for Event {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//noinspection RsTraitImplementation
|
||||||
|
impl<SEVERITY: HasSeverity> EcssEnumeration for EventU32TypedSev<SEVERITY> {
|
||||||
|
delegate!(to self.event {
|
||||||
|
fn pfc(&self) -> u8;
|
||||||
|
fn write_to_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError>;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct EventSmall {
|
pub struct EventU16 {
|
||||||
base: EventBase<u16, u8, u8>,
|
base: EventBase<u16, u8, u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventSmall {
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub struct EventU16TypedSev<SEVERITY> {
|
||||||
|
event: EventU16,
|
||||||
|
phantom: PhantomData<SEVERITY>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventU16 {
|
||||||
/// Generate a small event. The raw representation of a small event has 16 bits.
|
/// Generate a small event. The raw representation of a small event has 16 bits.
|
||||||
/// If the passed group ID is invalid (too large), [None] wil be returned
|
/// If the passed group ID is invalid (too large), [None] wil be returned
|
||||||
///
|
///
|
||||||
@ -260,8 +387,8 @@ impl EventSmall {
|
|||||||
/// raw event ID
|
/// raw event ID
|
||||||
pub fn new(
|
pub fn new(
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
group_id: <Self as EventProvider>::GroupId,
|
group_id: <Self as GenericEvent>::GroupId,
|
||||||
unique_id: <Self as EventProvider>::UniqueId,
|
unique_id: <Self as GenericEvent>::UniqueId,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
if group_id > (2u8.pow(6) - 1) {
|
if group_id > (2u8.pow(6) - 1) {
|
||||||
return None;
|
return None;
|
||||||
@ -278,8 +405,8 @@ impl EventSmall {
|
|||||||
|
|
||||||
pub const fn const_new(
|
pub const fn const_new(
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
group_id: <Self as EventProvider>::GroupId,
|
group_id: <Self as GenericEvent>::GroupId,
|
||||||
unique_id: <Self as EventProvider>::UniqueId,
|
unique_id: <Self as GenericEvent>::UniqueId,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
if group_id > (2u8.pow(6) - 1) {
|
if group_id > (2u8.pow(6) - 1) {
|
||||||
panic!("Group ID too large");
|
panic!("Group ID too large");
|
||||||
@ -294,24 +421,55 @@ impl EventSmall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<SEVERITY: HasSeverity> EventU16TypedSev<SEVERITY> {
|
||||||
impl EventProvider for EventSmall {
|
/// Generate a small event. The raw representation of a small event has 16 bits.
|
||||||
type Raw = u16;
|
/// If the passed group ID is invalid (too large), [None] wil be returned
|
||||||
type GroupId = u8;
|
///
|
||||||
type UniqueId = u8;
|
/// # Parameter
|
||||||
|
///
|
||||||
event_provider_impl!();
|
/// * `severity`: Each event has a [severity][Severity]. The raw value of the severity will
|
||||||
|
/// be stored inside the uppermost 2 bits of the raw event ID
|
||||||
fn raw_as_largest_type(&self) -> LargestEventRaw {
|
/// * `group_id`: Related events can be grouped using a group ID. The group ID will occupy the
|
||||||
self.raw().into()
|
/// next 6 bits after the severity. Therefore, the size is limited by dec 63 hex 0x3F.
|
||||||
|
/// * `unique_id`: Each event has a unique 8 bit ID occupying the last 8 bits of the
|
||||||
|
/// raw event ID
|
||||||
|
pub fn new(
|
||||||
|
group_id: <Self as GenericEvent>::GroupId,
|
||||||
|
unique_id: <Self as GenericEvent>::UniqueId,
|
||||||
|
) -> Option<Self> {
|
||||||
|
let event = EventU16::new(SEVERITY::SEVERITY, group_id, unique_id)?;
|
||||||
|
Some(Self {
|
||||||
|
event,
|
||||||
|
phantom: PhantomData,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn group_id_as_largest_type(&self) -> LargestGroupIdRaw {
|
pub const fn const_new(
|
||||||
self.group_id().into()
|
group_id: <Self as GenericEvent>::GroupId,
|
||||||
|
unique_id: <Self as GenericEvent>::UniqueId,
|
||||||
|
) -> Self {
|
||||||
|
let event = EventU16::const_new(SEVERITY::SEVERITY, group_id, unique_id);
|
||||||
|
Self {
|
||||||
|
event,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_from_generic(expected: Severity, raw: u16) -> Result<Self, Severity> {
|
||||||
|
let severity = Severity::try_from(((raw >> 14) & 0b11) as u8).unwrap();
|
||||||
|
if severity != expected {
|
||||||
|
return Err(severity);
|
||||||
|
}
|
||||||
|
Ok(Self::const_new(
|
||||||
|
((raw >> 8) & 0x3F) as u8,
|
||||||
|
(raw & 0xFF) as u8,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EcssEnumeration for EventSmall {
|
impl_event_provider!(EventU16, EventU16TypedSev, u16, u8, u8);
|
||||||
|
|
||||||
|
impl EcssEnumeration for EventU16 {
|
||||||
fn pfc(&self) -> u8 {
|
fn pfc(&self) -> u8 {
|
||||||
16
|
16
|
||||||
}
|
}
|
||||||
@ -321,8 +479,16 @@ impl EcssEnumeration for EventSmall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u16> for EventSmall {
|
//noinspection RsTraitImplementation
|
||||||
fn from(raw: <Self as EventProvider>::Raw) -> Self {
|
impl<SEVERITY: HasSeverity> EcssEnumeration for EventU16TypedSev<SEVERITY> {
|
||||||
|
delegate!(to self.event {
|
||||||
|
fn pfc(&self) -> u8;
|
||||||
|
fn write_to_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError>;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u16> for EventU16 {
|
||||||
|
fn from(raw: <Self as GenericEvent>::Raw) -> Self {
|
||||||
let severity = Severity::try_from(((raw >> 14) & 0b11) as u8).unwrap();
|
let severity = Severity::try_from(((raw >> 14) & 0b11) as u8).unwrap();
|
||||||
let group_id = ((raw >> 8) & 0x3F) as u8;
|
let group_id = ((raw >> 8) & 0x3F) as u8;
|
||||||
let unique_id = (raw & 0xFF) as u8;
|
let unique_id = (raw & 0xFF) as u8;
|
||||||
@ -331,10 +497,15 @@ impl From<u16> for EventSmall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try_from_impls!(SeverityInfo, Severity::INFO, u16, EventU16TypedSev);
|
||||||
|
try_from_impls!(SeverityLow, Severity::LOW, u16, EventU16TypedSev);
|
||||||
|
try_from_impls!(SeverityMedium, Severity::MEDIUM, u16, EventU16TypedSev);
|
||||||
|
try_from_impls!(SeverityHigh, Severity::HIGH, u16, EventU16TypedSev);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::Event;
|
use super::EventU32TypedSev;
|
||||||
use crate::events::{EventProvider, EventSmall, Severity};
|
use super::*;
|
||||||
use spacepackets::ecss::EcssEnumeration;
|
use spacepackets::ecss::EcssEnumeration;
|
||||||
use spacepackets::ByteConversionError;
|
use spacepackets::ByteConversionError;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
@ -343,20 +514,24 @@ mod tests {
|
|||||||
assert_eq!(size_of::<T>(), val);
|
assert_eq!(size_of::<T>(), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const INFO_EVENT: Event = Event::const_new(Severity::INFO, 0, 0);
|
const INFO_EVENT: EventU32TypedSev<SeverityInfo> = EventU32TypedSev::const_new(0, 0);
|
||||||
const INFO_EVENT_SMALL: EventSmall = EventSmall::const_new(Severity::INFO, 0, 0);
|
const INFO_EVENT_SMALL: EventU16TypedSev<SeverityInfo> = EventU16TypedSev::const_new(0, 0);
|
||||||
const HIGH_SEV_EVENT: Event = Event::const_new(Severity::HIGH, 0x3FFF, 0xFFFF);
|
const HIGH_SEV_EVENT: EventU32TypedSev<SeverityHigh> =
|
||||||
const HIGH_SEV_EVENT_SMALL: EventSmall = EventSmall::const_new(Severity::HIGH, 0x3F, 0xff);
|
EventU32TypedSev::const_new(0x3FFF, 0xFFFF);
|
||||||
|
const HIGH_SEV_EVENT_SMALL: EventU16TypedSev<SeverityHigh> =
|
||||||
|
EventU16TypedSev::const_new(0x3F, 0xff);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_normal_from_raw_conversion() {
|
fn test_normal_from_raw_conversion() {
|
||||||
let conv_from_raw = Event::from(INFO_EVENT.raw());
|
let conv_from_raw = EventU32TypedSev::<SeverityInfo>::try_from(INFO_EVENT.raw())
|
||||||
|
.expect("Creating typed EventU32 failed");
|
||||||
assert_eq!(conv_from_raw, INFO_EVENT);
|
assert_eq!(conv_from_raw, INFO_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_small_from_raw_conversion() {
|
fn test_small_from_raw_conversion() {
|
||||||
let conv_from_raw = EventSmall::from(INFO_EVENT_SMALL.raw());
|
let conv_from_raw = EventU16TypedSev::<SeverityInfo>::try_from(INFO_EVENT_SMALL.raw())
|
||||||
|
.expect("Creating typed EventU16 failed");
|
||||||
assert_eq!(conv_from_raw, INFO_EVENT_SMALL);
|
assert_eq!(conv_from_raw, INFO_EVENT_SMALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,18 +583,18 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn invalid_group_id_normal() {
|
fn invalid_group_id_normal() {
|
||||||
assert!(Event::new(Severity::MEDIUM, 2_u16.pow(14), 0).is_none());
|
assert!(EventU32TypedSev::<SeverityMedium>::new(2_u16.pow(14), 0).is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn invalid_group_id_small() {
|
fn invalid_group_id_small() {
|
||||||
assert!(EventSmall::new(Severity::MEDIUM, 2_u8.pow(6), 0).is_none());
|
assert!(EventU16TypedSev::<SeverityMedium>::new(2_u8.pow(6), 0).is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn regular_new() {
|
fn regular_new() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Event::new(Severity::INFO, 0, 0).expect("Creating regular event failed"),
|
EventU32TypedSev::<SeverityInfo>::new(0, 0).expect("Creating regular event failed"),
|
||||||
INFO_EVENT
|
INFO_EVENT
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -427,7 +602,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn small_new() {
|
fn small_new() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
EventSmall::new(Severity::INFO, 0, 0).expect("Creating regular event failed"),
|
EventU16TypedSev::<SeverityInfo>::new(0, 0).expect("Creating regular event failed"),
|
||||||
INFO_EVENT_SMALL
|
INFO_EVENT_SMALL
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,7 @@ mod allocvec {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::events::{Event, Severity};
|
use crate::events::{EventU32, Severity};
|
||||||
use crate::pus::tests::CommonTmInfo;
|
use crate::pus::tests::CommonTmInfo;
|
||||||
use spacepackets::ByteConversionError;
|
use spacepackets::ByteConversionError;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
@ -270,7 +270,7 @@ mod tests {
|
|||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
struct TmInfo {
|
struct TmInfo {
|
||||||
pub common: CommonTmInfo,
|
pub common: CommonTmInfo,
|
||||||
pub event: Event,
|
pub event: EventU32,
|
||||||
pub aux_data: Vec<u8>,
|
pub aux_data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,9 +284,7 @@ mod tests {
|
|||||||
assert!(tm.source_data().is_some());
|
assert!(tm.source_data().is_some());
|
||||||
let src_data = tm.source_data().unwrap();
|
let src_data = tm.source_data().unwrap();
|
||||||
assert!(src_data.len() >= 4);
|
assert!(src_data.len() >= 4);
|
||||||
let event = Event::try_from(u32::from_be_bytes(src_data[0..4].try_into().unwrap()));
|
let event = EventU32::from(u32::from_be_bytes(src_data[0..4].try_into().unwrap()));
|
||||||
assert!(event.is_ok());
|
|
||||||
let event = event.unwrap();
|
|
||||||
let mut aux_data = Vec::new();
|
let mut aux_data = Vec::new();
|
||||||
if src_data.len() > 4 {
|
if src_data.len() > 4 {
|
||||||
aux_data.extend_from_slice(&src_data[4..]);
|
aux_data.extend_from_slice(&src_data[4..]);
|
||||||
@ -313,7 +311,7 @@ mod tests {
|
|||||||
reporter: &mut EventReporter,
|
reporter: &mut EventReporter,
|
||||||
sender: &mut TestSender,
|
sender: &mut TestSender,
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
event: Event,
|
event: EventU32,
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
aux_data: Option<&[u8]>,
|
aux_data: Option<&[u8]>,
|
||||||
) {
|
) {
|
||||||
@ -355,7 +353,7 @@ mod tests {
|
|||||||
if let Some(err_data) = error_data {
|
if let Some(err_data) = error_data {
|
||||||
error_copy.extend_from_slice(err_data);
|
error_copy.extend_from_slice(err_data);
|
||||||
}
|
}
|
||||||
let event = Event::new(severity, EXAMPLE_GROUP_ID, EXAMPLE_EVENT_ID_0)
|
let event = EventU32::new(severity, EXAMPLE_GROUP_ID, EXAMPLE_EVENT_ID_0)
|
||||||
.expect("Error creating example event");
|
.expect("Error creating example event");
|
||||||
report_basic_event(
|
report_basic_event(
|
||||||
&mut reporter,
|
&mut reporter,
|
||||||
@ -418,7 +416,7 @@ mod tests {
|
|||||||
expected_found_len: usize,
|
expected_found_len: usize,
|
||||||
) {
|
) {
|
||||||
let time_stamp_empty: [u8; 7] = [0; 7];
|
let time_stamp_empty: [u8; 7] = [0; 7];
|
||||||
let event = Event::new(Severity::INFO, EXAMPLE_GROUP_ID, EXAMPLE_EVENT_ID_0)
|
let event = EventU32::new(Severity::INFO, EXAMPLE_GROUP_ID, EXAMPLE_EVENT_ID_0)
|
||||||
.expect("Error creating example event");
|
.expect("Error creating example event");
|
||||||
let err = reporter.event_info(sender, &time_stamp_empty, event, None);
|
let err = reporter.event_info(sender, &time_stamp_empty, event, None);
|
||||||
assert!(err.is_err());
|
assert!(err.is_err());
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::events::EventProvider;
|
use crate::events::{EventU16TypedSev, EventU32TypedSev, GenericEvent, HasSeverity, Severity};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
use core::hash::Hash;
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
|
|
||||||
use crate::pus::event::EventReporter;
|
use crate::pus::event::EventReporter;
|
||||||
@ -17,7 +18,7 @@ pub use heapless_mod::*;
|
|||||||
/// structure to track disabled events. A more primitive and embedded friendly
|
/// structure to track disabled events. A more primitive and embedded friendly
|
||||||
/// solution could track this information in a static or pre-allocated list which contains
|
/// solution could track this information in a static or pre-allocated list which contains
|
||||||
/// the disabled events.
|
/// the disabled events.
|
||||||
pub trait PusEventMgmtBackendProvider<Provider: EventProvider> {
|
pub trait PusEventMgmtBackendProvider<Provider: GenericEvent> {
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
fn event_enabled(&self, event: &Provider) -> bool;
|
fn event_enabled(&self, event: &Provider) -> bool;
|
||||||
@ -31,12 +32,12 @@ pub trait PusEventMgmtBackendProvider<Provider: EventProvider> {
|
|||||||
/// This provider is a good option for host systems or larger embedded systems where
|
/// This provider is a good option for host systems or larger embedded systems where
|
||||||
/// the expected occasional memory allocation performed by the [HashSet] is not an issue.
|
/// the expected occasional memory allocation performed by the [HashSet] is not an issue.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DefaultPusMgmtBackendProvider<Provider: EventProvider> {
|
pub struct DefaultPusMgmtBackendProvider<Provider: GenericEvent> {
|
||||||
disabled: HashSet<Provider>,
|
disabled: HashSet<Provider>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Provider: EventProvider> PusEventMgmtBackendProvider<Provider>
|
impl<Provider: GenericEvent + PartialEq + Eq + Hash + Copy + Clone>
|
||||||
for DefaultPusMgmtBackendProvider<Provider>
|
PusEventMgmtBackendProvider<Provider> for DefaultPusMgmtBackendProvider<Provider>
|
||||||
{
|
{
|
||||||
type Error = ();
|
type Error = ();
|
||||||
fn event_enabled(&self, event: &Provider) -> bool {
|
fn event_enabled(&self, event: &Provider) -> bool {
|
||||||
@ -55,18 +56,18 @@ impl<Provider: EventProvider> PusEventMgmtBackendProvider<Provider>
|
|||||||
#[cfg(feature = "heapless")]
|
#[cfg(feature = "heapless")]
|
||||||
pub mod heapless_mod {
|
pub mod heapless_mod {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::events::{EventProvider, LargestEventRaw};
|
use crate::events::{GenericEvent, LargestEventRaw};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
// TODO: After a new version of heapless is released which uses hash32 version 0.3, try using
|
// TODO: After a new version of heapless is released which uses hash32 version 0.3, try using
|
||||||
// regular Event type again.
|
// regular Event type again.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct HeaplessPusMgmtBckendProvider<const N: usize, Provider: EventProvider> {
|
pub struct HeaplessPusMgmtBckendProvider<const N: usize, Provider: GenericEvent> {
|
||||||
disabled: heapless::FnvIndexSet<LargestEventRaw, N>,
|
disabled: heapless::FnvIndexSet<LargestEventRaw, N>,
|
||||||
phantom: PhantomData<Provider>,
|
phantom: PhantomData<Provider>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize, Provider: EventProvider> PusEventMgmtBackendProvider<Provider>
|
impl<const N: usize, Provider: GenericEvent> PusEventMgmtBackendProvider<Provider>
|
||||||
for HeaplessPusMgmtBckendProvider<N, Provider>
|
for HeaplessPusMgmtBckendProvider<N, Provider>
|
||||||
{
|
{
|
||||||
type Error = ();
|
type Error = ();
|
||||||
@ -87,24 +88,76 @@ pub mod heapless_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PusEventManager<BackendError, Provider: EventProvider> {
|
pub struct PusEventManager<BackendError, Provider: GenericEvent> {
|
||||||
reporter: EventReporter,
|
reporter: EventReporter,
|
||||||
backend: Box<dyn PusEventMgmtBackendProvider<Provider, Error = BackendError>>,
|
backend: Box<dyn PusEventMgmtBackendProvider<Provider, Error = BackendError>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<BackendError, Provider: EventProvider> PusEventManager<BackendError, Provider> {
|
impl<BackendError, Event: GenericEvent> PusEventManager<BackendError, Event> {
|
||||||
pub fn handle_event<E>(
|
pub fn enable_tm_for_event(&mut self, event: &Event) -> Result<bool, BackendError> {
|
||||||
|
self.backend.enable_event_reporting(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn disable_tm_for_event(&mut self, event: &Event) -> Result<bool, BackendError> {
|
||||||
|
self.backend.disable_event_reporting(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_pus_event_tm_generic<E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
severity: Severity,
|
||||||
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
event: Provider,
|
event: Event,
|
||||||
aux_data: Option<&[u8]>,
|
aux_data: Option<&[u8]>,
|
||||||
) -> Result<bool, EcssTmError<E>> {
|
) -> Result<bool, EcssTmError<E>> {
|
||||||
if !self.backend.event_enabled(&event) {
|
if !self.backend.event_enabled(&event) {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
self.reporter
|
match severity {
|
||||||
|
Severity::INFO => self
|
||||||
|
.reporter
|
||||||
.event_info(sender, time_stamp, event, aux_data)
|
.event_info(sender, time_stamp, event, aux_data)
|
||||||
.map(|_| true)
|
.map(|_| true),
|
||||||
|
Severity::LOW => self
|
||||||
|
.reporter
|
||||||
|
.event_low_severity(sender, time_stamp, event, aux_data)
|
||||||
|
.map(|_| true),
|
||||||
|
Severity::MEDIUM => self
|
||||||
|
.reporter
|
||||||
|
.event_medium_severity(sender, time_stamp, event, aux_data)
|
||||||
|
.map(|_| true),
|
||||||
|
Severity::HIGH => self
|
||||||
|
.reporter
|
||||||
|
.event_high_severity(sender, time_stamp, event, aux_data)
|
||||||
|
.map(|_| true),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<BackendError, SEVERITY: HasSeverity>
|
||||||
|
PusEventManager<BackendError, EventU32TypedSev<SEVERITY>>
|
||||||
|
{
|
||||||
|
pub fn generate_pus_event_tm<E>(
|
||||||
|
&mut self,
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
time_stamp: &[u8],
|
||||||
|
event: EventU32TypedSev<SEVERITY>,
|
||||||
|
aux_data: Option<&[u8]>,
|
||||||
|
) -> Result<bool, EcssTmError<E>> {
|
||||||
|
self.generate_pus_event_tm_generic(SEVERITY::SEVERITY, sender, time_stamp, event, aux_data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<BackendError, SEVERITY: HasSeverity>
|
||||||
|
PusEventManager<BackendError, EventU16TypedSev<SEVERITY>>
|
||||||
|
{
|
||||||
|
pub fn generate_pus_event_tm<E>(
|
||||||
|
&mut self,
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
time_stamp: &[u8],
|
||||||
|
event: EventU16TypedSev<SEVERITY>,
|
||||||
|
aux_data: Option<&[u8]>,
|
||||||
|
) -> Result<bool, EcssTmError<E>> {
|
||||||
|
self.generate_pus_event_tm_generic(SEVERITY::SEVERITY, sender, time_stamp, event, aux_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,26 @@
|
|||||||
#![allow(dead_code, unused_imports)]
|
#![allow(dead_code, unused_imports)]
|
||||||
use fsrc_core::events::{Event, EventProvider, LargestEventRaw, LargestGroupIdRaw, Severity};
|
use fsrc_core::events::{
|
||||||
|
EventU32TypedSev, GenericEvent, HasSeverity, LargestEventRaw, LargestGroupIdRaw, Severity,
|
||||||
|
SeverityInfo, SeverityLow, SeverityMedium,
|
||||||
|
};
|
||||||
|
|
||||||
struct GroupIdIntrospection {
|
struct GroupIdIntrospection {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
id: LargestGroupIdRaw,
|
id: LargestGroupIdRaw,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EventIntrospection {
|
struct EventIntrospection<SEVERITY: HasSeverity + 'static> {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
group_id: GroupIdIntrospection,
|
group_id: GroupIdIntrospection,
|
||||||
event: &'static Event,
|
event: &'static EventU32TypedSev<SEVERITY>,
|
||||||
info: &'static str,
|
info: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[event(descr="This is some info event")]
|
//#[event(descr="This is some info event")]
|
||||||
const INFO_EVENT_0: Event = Event::const_new(Severity::INFO, 0, 0);
|
const INFO_EVENT_0: EventU32TypedSev<SeverityInfo> = EventU32TypedSev::const_new(0, 0);
|
||||||
|
|
||||||
// This is ideally auto-generated
|
// This is ideally auto-generated
|
||||||
const INFO_EVENT_0_INTROSPECTION: EventIntrospection = EventIntrospection {
|
const INFO_EVENT_0_INTROSPECTION: EventIntrospection<SeverityInfo> = EventIntrospection {
|
||||||
name: "INFO_EVENT_0",
|
name: "INFO_EVENT_0",
|
||||||
group_id: GroupIdIntrospection {
|
group_id: GroupIdIntrospection {
|
||||||
id: 0,
|
id: 0,
|
||||||
@ -28,9 +31,9 @@ const INFO_EVENT_0_INTROSPECTION: EventIntrospection = EventIntrospection {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//#[event(descr="This is some low severity event")]
|
//#[event(descr="This is some low severity event")]
|
||||||
const SOME_LOW_SEV_EVENT: Event = Event::const_new(Severity::LOW, 0, 12);
|
const SOME_LOW_SEV_EVENT: EventU32TypedSev<SeverityLow> = EventU32TypedSev::const_new(0, 12);
|
||||||
|
|
||||||
const EVENT_LIST: [&'static Event; 2] = [&INFO_EVENT_0, &SOME_LOW_SEV_EVENT];
|
//const EVENT_LIST: [&'static Event; 2] = [&INFO_EVENT_0, &SOME_LOW_SEV_EVENT];
|
||||||
|
|
||||||
//#[event_group]
|
//#[event_group]
|
||||||
const TEST_GROUP_NAME: u16 = 1;
|
const TEST_GROUP_NAME: u16 = 1;
|
||||||
@ -38,11 +41,12 @@ const TEST_GROUP_NAME: u16 = 1;
|
|||||||
const TEST_GROUP_NAME_NAME: &'static str = "TEST_GROUP_NAME";
|
const TEST_GROUP_NAME_NAME: &'static str = "TEST_GROUP_NAME";
|
||||||
|
|
||||||
//#[event(desc="Some medium severity event")]
|
//#[event(desc="Some medium severity event")]
|
||||||
const MEDIUM_SEV_EVENT_IN_OTHER_GROUP: Event =
|
const MEDIUM_SEV_EVENT_IN_OTHER_GROUP: EventU32TypedSev<SeverityMedium> =
|
||||||
Event::const_new(Severity::MEDIUM, TEST_GROUP_NAME, 0);
|
EventU32TypedSev::const_new(TEST_GROUP_NAME, 0);
|
||||||
|
|
||||||
// Also auto-generated
|
// Also auto-generated
|
||||||
const MEDIUM_SEV_EVENT_IN_OTHER_GROUP_INTROSPECTION: EventIntrospection = EventIntrospection {
|
const MEDIUM_SEV_EVENT_IN_OTHER_GROUP_INTROSPECTION: EventIntrospection<SeverityMedium> =
|
||||||
|
EventIntrospection {
|
||||||
name: "MEDIUM_SEV_EVENT_IN_OTHER_GROUP",
|
name: "MEDIUM_SEV_EVENT_IN_OTHER_GROUP",
|
||||||
group_id: GroupIdIntrospection {
|
group_id: GroupIdIntrospection {
|
||||||
name: TEST_GROUP_NAME_NAME,
|
name: TEST_GROUP_NAME_NAME,
|
||||||
@ -50,14 +54,14 @@ const MEDIUM_SEV_EVENT_IN_OTHER_GROUP_INTROSPECTION: EventIntrospection = EventI
|
|||||||
},
|
},
|
||||||
event: &MEDIUM_SEV_EVENT_IN_OTHER_GROUP,
|
event: &MEDIUM_SEV_EVENT_IN_OTHER_GROUP,
|
||||||
info: "Some medium severity event",
|
info: "Some medium severity event",
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn main() {
|
fn main() {
|
||||||
let test = stringify!(INFO_EVENT);
|
//let test = stringify!(INFO_EVENT);
|
||||||
println!("{:?}", test);
|
//println!("{:?}", test);
|
||||||
for event in EVENT_LIST {
|
//for event in EVENT_LIST {
|
||||||
println!("{:?}", event);
|
// println!("{:?}", event);
|
||||||
}
|
//}
|
||||||
//let test_struct =
|
//let test_struct =
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user