From 478673327b98193c787e3bfbe0a6742f801714a5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 24 Oct 2022 01:51:33 +0200 Subject: [PATCH] basic PUS event manager --- fsrc-core/src/event_man.rs | 80 +++++---- fsrc-core/src/events.rs | 309 ++++++++++++++++++++++++++------- fsrc-core/src/pus/event.rs | 14 +- fsrc-core/src/pus/event_man.rs | 83 +++++++-- fsrc-core/tests/pus_events.rs | 50 +++--- 5 files changed, 385 insertions(+), 151 deletions(-) diff --git a/fsrc-core/src/event_man.rs b/fsrc-core/src/event_man.rs index 4fe4092..5d1c6ba 100644 --- a/fsrc-core/src/event_man.rs +++ b/fsrc-core/src/event_man.rs @@ -1,5 +1,5 @@ //! [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::vec; use alloc::vec::Vec; @@ -11,34 +11,34 @@ enum ListenerType { Group(u16), } -pub trait EventListener { +pub trait EventListener { type Error; fn id(&self) -> u32; fn send_to(&mut self, event: Provider) -> Result<(), Self::Error>; } -struct Listener { +struct Listener { ltype: ListenerType, dest: Box>, } -pub trait ReceivesAllEvent { +pub trait ReceivesAllEvent { fn receive(&mut self) -> Option; } -pub struct EventManager { +pub struct EventManager { listeners: HashMap>>, event_receiver: Box>, } -pub enum HandlerResult { +pub enum HandlerResult { Empty, Handled(u32, Provider), } -impl EventManager { - pub fn new(event_receiver: Box>) -> Self { +impl EventManager { + pub fn new(event_receiver: Box>) -> Self { EventManager { listeners: HashMap::new(), event_receiver, @@ -46,43 +46,43 @@ impl EventManager { } } -impl EventManager { +impl EventManager { pub fn subscribe_single( &mut self, - event: Event, - dest: impl EventListener + 'static, + event: EventU32, + dest: impl EventListener + 'static, ) { self.update_listeners(ListenerType::Single(event.raw_as_largest_type()), dest); } pub fn subscribe_group( &mut self, - group_id: ::GroupId, - dest: impl EventListener + 'static, + group_id: ::GroupId, + dest: impl EventListener + 'static, ) { self.update_listeners(ListenerType::Group(group_id), dest); } } -impl EventManager { +impl EventManager> { pub fn subscribe_single( &mut self, - event: EventSmall, - dest: impl EventListener + 'static, + event: EventU16TypedSev, + dest: impl EventListener, Error = E> + 'static, ) { self.update_listeners(ListenerType::Single(event.raw_as_largest_type()), dest); } pub fn subscribe_group( &mut self, - group_id: ::GroupId, - dest: impl EventListener + 'static, + group_id: as GenericEvent>::GroupId, + dest: impl EventListener, Error = E> + 'static, ) { self.update_listeners(ListenerType::Group(group_id.into()), dest); } } -impl EventManager { +impl EventManager { fn update_listeners( &mut self, key: ListenerType, @@ -145,17 +145,17 @@ impl EventManager { mod tests { use super::{EventListener, HandlerResult, ReceivesAllEvent}; use crate::event_man::EventManager; - use crate::events::{Event, EventProvider, Severity}; + use crate::events::{EventU32, GenericEvent, Severity}; use alloc::boxed::Box; use std::sync::mpsc::{channel, Receiver, SendError, Sender}; use std::thread; use std::time::Duration; struct EventReceiver { - mpsc_receiver: Receiver, + mpsc_receiver: Receiver, } - impl ReceivesAllEvent for EventReceiver { - fn receive(&mut self) -> Option { + impl ReceivesAllEvent for EventReceiver { + fn receive(&mut self) -> Option { self.mpsc_receiver.try_recv().ok() } } @@ -163,21 +163,21 @@ mod tests { #[derive(Clone)] struct MpscEventSenderQueue { id: u32, - mpsc_sender: Sender, + mpsc_sender: Sender, } - impl EventListener for MpscEventSenderQueue { - type Error = SendError; + impl EventListener for MpscEventSenderQueue { + type Error = SendError; fn id(&self) -> u32 { 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) } } - fn check_next_event(expected: Event, receiver: &Receiver) { + fn check_next_event(expected: EventU32, receiver: &Receiver) { for _ in 0..5 { if let Ok(event) = receiver.try_recv() { 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, + expected: EventU32, + expected_num_sent: u32, + ) { assert!(matches!(res, HandlerResult::Handled { .. })); if let HandlerResult::Handled(num_recipients, event) = res { assert_eq!(event, expected); @@ -201,10 +205,10 @@ mod tests { let event_man_receiver = EventReceiver { mpsc_receiver: manager_queue, }; - let mut event_man: EventManager, Event> = + let mut event_man: EventManager, EventU32> = EventManager::new(Box::new(event_man_receiver)); - let event_grp_0 = Event::new(Severity::INFO, 0, 0).unwrap(); - let event_grp_1_0 = Event::new(Severity::HIGH, 1, 0).unwrap(); + let event_grp_0 = EventU32::new(Severity::INFO, 0, 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_listener = MpscEventSenderQueue { id: 0, @@ -244,15 +248,15 @@ mod tests { let event_man_receiver = EventReceiver { mpsc_receiver: manager_queue, }; - let mut event_man: EventManager, Event> = + let mut event_man: EventManager, EventU32> = EventManager::new(Box::new(event_man_receiver)); let res = event_man.try_event_handling(); assert!(res.is_ok()); let hres = res.unwrap(); assert!(matches!(hres, HandlerResult::Empty)); - let event_grp_0 = Event::new(Severity::INFO, 0, 0).unwrap(); - let event_grp_1_0 = Event::new(Severity::HIGH, 1, 0).unwrap(); + let event_grp_0 = EventU32::new(Severity::INFO, 0, 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_and_1_listener = MpscEventSenderQueue { id: 0, @@ -286,10 +290,10 @@ mod tests { let event_man_receiver = EventReceiver { mpsc_receiver: manager_queue, }; - let mut event_man: EventManager, Event> = + let mut event_man: EventManager, EventU32> = EventManager::new(Box::new(event_man_receiver)); - let event_0 = Event::new(Severity::INFO, 0, 5).unwrap(); - let event_1 = Event::new(Severity::HIGH, 1, 0).unwrap(); + let event_0 = EventU32::new(Severity::INFO, 0, 5).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_1, event_0_rx_1) = channel(); let event_listener_0 = MpscEventSenderQueue { diff --git a/fsrc-core/src/events.rs b/fsrc-core/src/events.rs index a74cb01..4a27cf0 100644 --- a/fsrc-core/src/events.rs +++ b/fsrc-core/src/events.rs @@ -1,6 +1,7 @@ //! Event support module use core::hash::Hash; +use delegate::delegate; use spacepackets::ecss::{EcssEnumeration, ToBeBytes}; use spacepackets::{ByteConversionError, SizeMissmatch}; use std::marker::PhantomData; @@ -18,7 +19,34 @@ pub enum Severity { 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 GroupId; type UniqueId; @@ -149,43 +177,78 @@ macro_rules! event_provider_impl { } }; } + +macro_rules! impl_event_provider { + ($BaseIdent: ident, $TypedIdent: ident, $raw: ty, $gid: ty, $uid: ty) => { + impl GenericEvent for $BaseIdent { + type Raw = $raw; + type GroupId = $gid; + type UniqueId = $uid; + + event_provider_impl!(); + + fn raw_as_largest_type(&self) -> LargestEventRaw { + self.raw().into() + } + + fn group_id_as_largest_type(&self) -> LargestGroupIdRaw { + self.group_id().into() + } + } + + impl GenericEvent for $TypedIdent { + 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; + }); + } + } +} + +macro_rules! try_from_impls { + ($SevIdent: ident, $severity: path, $raw: ty, $TypedSevIdent: ident) => { + impl TryFrom<$raw> for $TypedSevIdent<$SevIdent> { + type Error = Severity; + + fn try_from(raw: $raw) -> Result { + Self::try_from_generic($severity, raw) + } + } + }; +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub struct Event { +pub struct EventU32 { base: EventBase, } -impl EventProvider for Event { - type Raw = u32; - type GroupId = u16; - type UniqueId = u16; +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct EventU32TypedSev { + event: EventU32, + phantom: PhantomData, +} - event_provider_impl!(); - - fn raw_as_largest_type(&self) -> LargestEventRaw { - self.raw() - } - - fn group_id_as_largest_type(&self) -> LargestGroupIdRaw { - self.group_id() +impl From> for EventU32 { + fn from(e: EventU32TypedSev) -> Self { + Self { base: e.event.base } } } -impl Event { - /// 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 +impl_event_provider!(EventU32, EventU32TypedSev, u32, u16, u16); + +impl EventU32 { pub fn new( severity: Severity, - group_id: ::GroupId, - unique_id: ::UniqueId, + group_id: ::GroupId, + unique_id: ::UniqueId, ) -> Option { if group_id > (2u16.pow(14) - 1) { 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( severity: Severity, - group_id: ::GroupId, - unique_id: ::UniqueId, + group_id: ::GroupId, + unique_id: ::UniqueId, ) -> Self { if group_id > (2u16.pow(14) - 1) { panic!("Group ID too large"); @@ -220,7 +281,54 @@ impl Event { } } -impl From for Event { +impl EventU32TypedSev { + /// 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: ::GroupId, + unique_id: ::UniqueId, + ) -> Option { + 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: ::GroupId, + unique_id: ::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 { + 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 for EventU32 { fn from(raw: u32) -> Self { // Severity conversion from u8 should never fail let severity = Severity::try_from(((raw >> 30) & 0b11) as u8).unwrap(); @@ -231,7 +339,12 @@ impl From 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 { 32 } @@ -241,12 +354,26 @@ impl EcssEnumeration for Event { } } +//noinspection RsTraitImplementation +impl EcssEnumeration for EventU32TypedSev { + 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)] -pub struct EventSmall { +pub struct EventU16 { base: EventBase, } -impl EventSmall { +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct EventU16TypedSev { + event: EventU16, + phantom: PhantomData, +} + +impl EventU16 { /// 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 /// @@ -260,8 +387,8 @@ impl EventSmall { /// raw event ID pub fn new( severity: Severity, - group_id: ::GroupId, - unique_id: ::UniqueId, + group_id: ::GroupId, + unique_id: ::UniqueId, ) -> Option { if group_id > (2u8.pow(6) - 1) { return None; @@ -278,8 +405,8 @@ impl EventSmall { pub const fn const_new( severity: Severity, - group_id: ::GroupId, - unique_id: ::UniqueId, + group_id: ::GroupId, + unique_id: ::UniqueId, ) -> Self { if group_id > (2u8.pow(6) - 1) { panic!("Group ID too large"); @@ -294,24 +421,55 @@ impl EventSmall { } } } - -impl EventProvider for EventSmall { - type Raw = u16; - type GroupId = u8; - type UniqueId = u8; - - event_provider_impl!(); - - fn raw_as_largest_type(&self) -> LargestEventRaw { - self.raw().into() +impl EventU16TypedSev { + /// 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 + /// + /// # 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 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: ::GroupId, + unique_id: ::UniqueId, + ) -> Option { + let event = EventU16::new(SEVERITY::SEVERITY, group_id, unique_id)?; + Some(Self { + event, + phantom: PhantomData, + }) } - fn group_id_as_largest_type(&self) -> LargestGroupIdRaw { - self.group_id().into() + pub const fn const_new( + group_id: ::GroupId, + unique_id: ::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 { + 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 { 16 } @@ -321,8 +479,16 @@ impl EcssEnumeration for EventSmall { } } -impl From for EventSmall { - fn from(raw: ::Raw) -> Self { +//noinspection RsTraitImplementation +impl EcssEnumeration for EventU16TypedSev { + delegate!(to self.event { + fn pfc(&self) -> u8; + fn write_to_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError>; + }); +} + +impl From for EventU16 { + fn from(raw: ::Raw) -> Self { let severity = Severity::try_from(((raw >> 14) & 0b11) as u8).unwrap(); let group_id = ((raw >> 8) & 0x3F) as u8; let unique_id = (raw & 0xFF) as u8; @@ -331,10 +497,15 @@ impl From 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)] mod tests { - use super::Event; - use crate::events::{EventProvider, EventSmall, Severity}; + use super::EventU32TypedSev; + use super::*; use spacepackets::ecss::EcssEnumeration; use spacepackets::ByteConversionError; use std::mem::size_of; @@ -343,20 +514,24 @@ mod tests { assert_eq!(size_of::(), val); } - const INFO_EVENT: Event = Event::const_new(Severity::INFO, 0, 0); - const INFO_EVENT_SMALL: EventSmall = EventSmall::const_new(Severity::INFO, 0, 0); - const HIGH_SEV_EVENT: Event = Event::const_new(Severity::HIGH, 0x3FFF, 0xFFFF); - const HIGH_SEV_EVENT_SMALL: EventSmall = EventSmall::const_new(Severity::HIGH, 0x3F, 0xff); + const INFO_EVENT: EventU32TypedSev = EventU32TypedSev::const_new(0, 0); + const INFO_EVENT_SMALL: EventU16TypedSev = EventU16TypedSev::const_new(0, 0); + const HIGH_SEV_EVENT: EventU32TypedSev = + EventU32TypedSev::const_new(0x3FFF, 0xFFFF); + const HIGH_SEV_EVENT_SMALL: EventU16TypedSev = + EventU16TypedSev::const_new(0x3F, 0xff); #[test] fn test_normal_from_raw_conversion() { - let conv_from_raw = Event::from(INFO_EVENT.raw()); + let conv_from_raw = EventU32TypedSev::::try_from(INFO_EVENT.raw()) + .expect("Creating typed EventU32 failed"); assert_eq!(conv_from_raw, INFO_EVENT); } #[test] fn test_small_from_raw_conversion() { - let conv_from_raw = EventSmall::from(INFO_EVENT_SMALL.raw()); + let conv_from_raw = EventU16TypedSev::::try_from(INFO_EVENT_SMALL.raw()) + .expect("Creating typed EventU16 failed"); assert_eq!(conv_from_raw, INFO_EVENT_SMALL); } @@ -408,18 +583,18 @@ mod tests { #[test] fn invalid_group_id_normal() { - assert!(Event::new(Severity::MEDIUM, 2_u16.pow(14), 0).is_none()); + assert!(EventU32TypedSev::::new(2_u16.pow(14), 0).is_none()); } #[test] fn invalid_group_id_small() { - assert!(EventSmall::new(Severity::MEDIUM, 2_u8.pow(6), 0).is_none()); + assert!(EventU16TypedSev::::new(2_u8.pow(6), 0).is_none()); } #[test] fn regular_new() { assert_eq!( - Event::new(Severity::INFO, 0, 0).expect("Creating regular event failed"), + EventU32TypedSev::::new(0, 0).expect("Creating regular event failed"), INFO_EVENT ); } @@ -427,7 +602,7 @@ mod tests { #[test] fn small_new() { assert_eq!( - EventSmall::new(Severity::INFO, 0, 0).expect("Creating regular event failed"), + EventU16TypedSev::::new(0, 0).expect("Creating regular event failed"), INFO_EVENT_SMALL ); } diff --git a/fsrc-core/src/pus/event.rs b/fsrc-core/src/pus/event.rs index bea74a4..bfc3fa0 100644 --- a/fsrc-core/src/pus/event.rs +++ b/fsrc-core/src/pus/event.rs @@ -255,7 +255,7 @@ mod allocvec { #[cfg(test)] mod tests { use super::*; - use crate::events::{Event, Severity}; + use crate::events::{EventU32, Severity}; use crate::pus::tests::CommonTmInfo; use spacepackets::ByteConversionError; use std::collections::VecDeque; @@ -270,7 +270,7 @@ mod tests { #[derive(Debug, Eq, PartialEq)] struct TmInfo { pub common: CommonTmInfo, - pub event: Event, + pub event: EventU32, pub aux_data: Vec, } @@ -284,9 +284,7 @@ mod tests { assert!(tm.source_data().is_some()); let src_data = tm.source_data().unwrap(); assert!(src_data.len() >= 4); - let event = Event::try_from(u32::from_be_bytes(src_data[0..4].try_into().unwrap())); - assert!(event.is_ok()); - let event = event.unwrap(); + let event = EventU32::from(u32::from_be_bytes(src_data[0..4].try_into().unwrap())); let mut aux_data = Vec::new(); if src_data.len() > 4 { aux_data.extend_from_slice(&src_data[4..]); @@ -313,7 +311,7 @@ mod tests { reporter: &mut EventReporter, sender: &mut TestSender, time_stamp: &[u8], - event: Event, + event: EventU32, severity: Severity, aux_data: Option<&[u8]>, ) { @@ -355,7 +353,7 @@ mod tests { if let Some(err_data) = error_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"); report_basic_event( &mut reporter, @@ -418,7 +416,7 @@ mod tests { expected_found_len: usize, ) { 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"); let err = reporter.event_info(sender, &time_stamp_empty, event, None); assert!(err.is_err()); diff --git a/fsrc-core/src/pus/event_man.rs b/fsrc-core/src/pus/event_man.rs index 8195b04..86581f6 100644 --- a/fsrc-core/src/pus/event_man.rs +++ b/fsrc-core/src/pus/event_man.rs @@ -1,5 +1,6 @@ -use crate::events::EventProvider; +use crate::events::{EventU16TypedSev, EventU32TypedSev, GenericEvent, HasSeverity, Severity}; use alloc::boxed::Box; +use core::hash::Hash; use hashbrown::HashSet; use crate::pus::event::EventReporter; @@ -17,7 +18,7 @@ pub use heapless_mod::*; /// 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 /// the disabled events. -pub trait PusEventMgmtBackendProvider { +pub trait PusEventMgmtBackendProvider { type Error; fn event_enabled(&self, event: &Provider) -> bool; @@ -31,12 +32,12 @@ pub trait PusEventMgmtBackendProvider { /// 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. #[derive(Default)] -pub struct DefaultPusMgmtBackendProvider { +pub struct DefaultPusMgmtBackendProvider { disabled: HashSet, } -impl PusEventMgmtBackendProvider - for DefaultPusMgmtBackendProvider +impl + PusEventMgmtBackendProvider for DefaultPusMgmtBackendProvider { type Error = (); fn event_enabled(&self, event: &Provider) -> bool { @@ -55,18 +56,18 @@ impl PusEventMgmtBackendProvider #[cfg(feature = "heapless")] pub mod heapless_mod { use super::*; - use crate::events::{EventProvider, LargestEventRaw}; + use crate::events::{GenericEvent, LargestEventRaw}; use std::marker::PhantomData; // TODO: After a new version of heapless is released which uses hash32 version 0.3, try using // regular Event type again. #[derive(Default)] - pub struct HeaplessPusMgmtBckendProvider { + pub struct HeaplessPusMgmtBckendProvider { disabled: heapless::FnvIndexSet, phantom: PhantomData, } - impl PusEventMgmtBackendProvider + impl PusEventMgmtBackendProvider for HeaplessPusMgmtBckendProvider { type Error = (); @@ -87,24 +88,76 @@ pub mod heapless_mod { } } -pub struct PusEventManager { +pub struct PusEventManager { reporter: EventReporter, backend: Box>, } -impl PusEventManager { - pub fn handle_event( +impl PusEventManager { + pub fn enable_tm_for_event(&mut self, event: &Event) -> Result { + self.backend.enable_event_reporting(event) + } + + pub fn disable_tm_for_event(&mut self, event: &Event) -> Result { + self.backend.disable_event_reporting(event) + } + + pub fn generate_pus_event_tm_generic( &mut self, + severity: Severity, sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], - event: Provider, + event: Event, aux_data: Option<&[u8]>, ) -> Result> { if !self.backend.event_enabled(&event) { return Ok(false); } - self.reporter - .event_info(sender, time_stamp, event, aux_data) - .map(|_| true) + match severity { + Severity::INFO => self + .reporter + .event_info(sender, time_stamp, event, aux_data) + .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 + PusEventManager> +{ + pub fn generate_pus_event_tm( + &mut self, + sender: &mut (impl EcssTmSender + ?Sized), + time_stamp: &[u8], + event: EventU32TypedSev, + aux_data: Option<&[u8]>, + ) -> Result> { + self.generate_pus_event_tm_generic(SEVERITY::SEVERITY, sender, time_stamp, event, aux_data) + } +} + +impl + PusEventManager> +{ + pub fn generate_pus_event_tm( + &mut self, + sender: &mut (impl EcssTmSender + ?Sized), + time_stamp: &[u8], + event: EventU16TypedSev, + aux_data: Option<&[u8]>, + ) -> Result> { + self.generate_pus_event_tm_generic(SEVERITY::SEVERITY, sender, time_stamp, event, aux_data) } } diff --git a/fsrc-core/tests/pus_events.rs b/fsrc-core/tests/pus_events.rs index 2f554c1..db82b52 100644 --- a/fsrc-core/tests/pus_events.rs +++ b/fsrc-core/tests/pus_events.rs @@ -1,23 +1,26 @@ #![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 { name: &'static str, id: LargestGroupIdRaw, } -struct EventIntrospection { +struct EventIntrospection { name: &'static str, group_id: GroupIdIntrospection, - event: &'static Event, + event: &'static EventU32TypedSev, info: &'static str, } //#[event(descr="This is some info event")] -const INFO_EVENT_0: Event = Event::const_new(Severity::INFO, 0, 0); +const INFO_EVENT_0: EventU32TypedSev = EventU32TypedSev::const_new(0, 0); // This is ideally auto-generated -const INFO_EVENT_0_INTROSPECTION: EventIntrospection = EventIntrospection { +const INFO_EVENT_0_INTROSPECTION: EventIntrospection = EventIntrospection { name: "INFO_EVENT_0", group_id: GroupIdIntrospection { id: 0, @@ -28,9 +31,9 @@ const INFO_EVENT_0_INTROSPECTION: EventIntrospection = EventIntrospection { }; //#[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 = 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] const TEST_GROUP_NAME: u16 = 1; @@ -38,26 +41,27 @@ const TEST_GROUP_NAME: u16 = 1; const TEST_GROUP_NAME_NAME: &'static str = "TEST_GROUP_NAME"; //#[event(desc="Some medium severity event")] -const MEDIUM_SEV_EVENT_IN_OTHER_GROUP: Event = - Event::const_new(Severity::MEDIUM, TEST_GROUP_NAME, 0); +const MEDIUM_SEV_EVENT_IN_OTHER_GROUP: EventU32TypedSev = + EventU32TypedSev::const_new(TEST_GROUP_NAME, 0); // Also auto-generated -const MEDIUM_SEV_EVENT_IN_OTHER_GROUP_INTROSPECTION: EventIntrospection = EventIntrospection { - name: "MEDIUM_SEV_EVENT_IN_OTHER_GROUP", - group_id: GroupIdIntrospection { - name: TEST_GROUP_NAME_NAME, - id: TEST_GROUP_NAME, - }, - event: &MEDIUM_SEV_EVENT_IN_OTHER_GROUP, - info: "Some medium severity event", -}; +const MEDIUM_SEV_EVENT_IN_OTHER_GROUP_INTROSPECTION: EventIntrospection = + EventIntrospection { + name: "MEDIUM_SEV_EVENT_IN_OTHER_GROUP", + group_id: GroupIdIntrospection { + name: TEST_GROUP_NAME_NAME, + id: TEST_GROUP_NAME, + }, + event: &MEDIUM_SEV_EVENT_IN_OTHER_GROUP, + info: "Some medium severity event", + }; #[test] fn main() { - let test = stringify!(INFO_EVENT); - println!("{:?}", test); - for event in EVENT_LIST { - println!("{:?}", event); - } + //let test = stringify!(INFO_EVENT); + //println!("{:?}", test); + //for event in EVENT_LIST { + // println!("{:?}", event); + //} //let test_struct = }