diff --git a/fsrc-core/src/lib.rs b/fsrc-core/src/lib.rs index 789dc36..5ac3541 100644 --- a/fsrc-core/src/lib.rs +++ b/fsrc-core/src/lib.rs @@ -10,9 +10,9 @@ #![no_std] #[cfg(feature = "alloc")] extern crate alloc; +extern crate downcast_rs; #[cfg(any(feature = "std", test))] extern crate std; -extern crate downcast_rs; pub mod error; #[cfg(feature = "alloc")] diff --git a/fsrc-core/src/pus/event.rs b/fsrc-core/src/pus/event.rs index bfc3fa0..f7b7e36 100644 --- a/fsrc-core/src/pus/event.rs +++ b/fsrc-core/src/pus/event.rs @@ -46,7 +46,7 @@ impl EventReporterBase { pub fn event_info( &mut self, buf: &mut [u8], - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, @@ -64,7 +64,7 @@ impl EventReporterBase { pub fn event_low_severity( &mut self, buf: &mut [u8], - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, @@ -82,7 +82,7 @@ impl EventReporterBase { pub fn event_medium_severity( &mut self, buf: &mut [u8], - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, @@ -100,7 +100,7 @@ impl EventReporterBase { pub fn event_high_severity( &mut self, buf: &mut [u8], - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, @@ -119,7 +119,7 @@ impl EventReporterBase { &mut self, buf: &mut [u8], subservice: Subservices, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, @@ -188,7 +188,7 @@ mod allocvec { } pub fn event_info( &mut self, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, @@ -204,7 +204,7 @@ mod allocvec { pub fn event_low_severity( &mut self, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, @@ -220,7 +220,7 @@ mod allocvec { pub fn event_medium_severity( &mut self, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, @@ -236,7 +236,7 @@ mod allocvec { pub fn event_high_severity( &mut self, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, @@ -279,7 +279,9 @@ mod tests { pub service_queue: VecDeque, } - impl EcssTmSender<()> for TestSender { + impl EcssTmSender for TestSender { + type Error = (); + fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<()>> { assert!(tm.source_data().is_some()); let src_data = tm.source_data().unwrap(); diff --git a/fsrc-core/src/pus/event_man.rs b/fsrc-core/src/pus/event_man.rs index 5b48143..33d860f 100644 --- a/fsrc-core/src/pus/event_man.rs +++ b/fsrc-core/src/pus/event_man.rs @@ -1,9 +1,10 @@ -use crate::events::{EventU16TypedSev, EventU32TypedSev, GenericEvent, HasSeverity, Severity}; +use crate::events::{EventU32, EventU32TypedSev, GenericEvent, HasSeverity, Severity}; use alloc::boxed::Box; use core::hash::Hash; use hashbrown::HashSet; -use crate::pus::event::EventReporter; +#[cfg(feature = "alloc")] +pub use crate::pus::event::EventReporter; use crate::pus::{EcssTmError, EcssTmSender}; #[cfg(feature = "heapless")] #[cfg_attr(doc_cfg, doc(cfg(feature = "heapless")))] @@ -33,9 +34,16 @@ 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 { - disabled: HashSet, +pub struct DefaultPusMgmtBackendProvider { + disabled: HashSet, +} + +impl Default for DefaultPusMgmtBackendProvider { + fn default() -> Self { + Self { + disabled: HashSet::default(), + } + } } impl @@ -91,12 +99,33 @@ pub mod heapless_mod { } } -pub struct PusEventManager { +#[derive(Debug)] +pub enum EventManError { + EcssTmError(EcssTmError), + SeverityMissmatch(Severity, Severity), +} + +impl From> for EventManError { + fn from(v: EcssTmError) -> Self { + Self::EcssTmError(v) + } +} + +pub struct PusEventTmManager { reporter: EventReporter, backend: Box>, } -impl PusEventManager { +impl PusEventTmManager { + pub fn new( + reporter: EventReporter, + backend: Box>, + ) -> Self { + Self { reporter, backend } + } +} + +impl PusEventTmManager { pub fn enable_tm_for_event(&mut self, event: &Event) -> Result { self.backend.enable_event_reporting(event) } @@ -108,59 +137,56 @@ impl PusEventManager { pub fn generate_pus_event_tm_generic( &mut self, severity: Severity, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], event: Event, aux_data: Option<&[u8]>, - ) -> Result> { + ) -> Result> { if !self.backend.event_enabled(&event) { return Ok(false); } + if event.severity() != severity { + return Err(EventManError::SeverityMissmatch(severity, event.severity())); + } match severity { Severity::INFO => self .reporter .event_info(sender, time_stamp, event, aux_data) - .map(|_| true), + .map(|_| true) + .map_err(|e| e.into()), Severity::LOW => self .reporter .event_low_severity(sender, time_stamp, event, aux_data) - .map(|_| true), + .map(|_| true) + .map_err(|e| e.into()), Severity::MEDIUM => self .reporter .event_medium_severity(sender, time_stamp, event, aux_data) - .map(|_| true), + .map(|_| true) + .map_err(|e| e.into()), Severity::HIGH => self .reporter .event_high_severity(sender, time_stamp, event, aux_data) - .map(|_| true), + .map(|_| true) + .map_err(|e| e.into()), } } } -impl - PusEventManager> -{ - pub fn generate_pus_event_tm( +impl PusEventTmManager { + pub fn generate_pus_event_tm( &mut self, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], - event: EventU32TypedSev, + 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) + ) -> Result> { + self.generate_pus_event_tm_generic( + Severity::SEVERITY, + sender, + time_stamp, + event.into(), + aux_data, + ) } } diff --git a/fsrc-core/src/pus/mod.rs b/fsrc-core/src/pus/mod.rs index 82e49f9..0703a8e 100644 --- a/fsrc-core/src/pus/mod.rs +++ b/fsrc-core/src/pus/mod.rs @@ -26,6 +26,12 @@ pub enum EcssTmError { PusError(PusError), } +impl From for EcssTmError { + fn from(e: PusError) -> Self { + EcssTmError::PusError(e) + } +} + impl From for EcssTmError { fn from(e: ByteConversionError) -> Self { EcssTmError::ByteConversionError(e) @@ -37,11 +43,13 @@ impl From for EcssTmError { /// This sender object is responsible for sending telemetry to a TM sink. The [Downcast] trait /// is implemented to allow passing the sender as a boxed trait object and still retrieve the /// concrete type at a later point. -pub trait EcssTmSender: Downcast + Send { - fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError>; +pub trait EcssTmSender: Downcast + Send { + type Error; + + fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError>; } -impl_downcast!(EcssTmSender); +impl_downcast!(EcssTmSender assoc Error); pub(crate) fn source_buffer_large_enough(cap: usize, len: usize) -> Result<(), EcssTmError> { if len > cap { diff --git a/fsrc-core/src/pus/verification.rs b/fsrc-core/src/pus/verification.rs index 41b74e1..996d558 100644 --- a/fsrc-core/src/pus/verification.rs +++ b/fsrc-core/src/pus/verification.rs @@ -312,7 +312,7 @@ impl VerificationReporterBasic { &mut self, buf: &mut [u8], token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], ) -> Result, VerificationErrorWithToken> { let tm = self @@ -339,7 +339,7 @@ impl VerificationReporterBasic { &mut self, buf: &mut [u8], token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), params: FailParams, ) -> Result<(), VerificationErrorWithToken> { let tm = self @@ -365,7 +365,7 @@ impl VerificationReporterBasic { &mut self, buf: &mut [u8], token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], ) -> Result, VerificationErrorWithToken> { let tm = self @@ -395,7 +395,7 @@ impl VerificationReporterBasic { &mut self, buf: &mut [u8], token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), params: FailParams, ) -> Result<(), VerificationErrorWithToken> { let tm = self @@ -421,7 +421,7 @@ impl VerificationReporterBasic { &mut self, buf: &mut [u8], token: &VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], step: impl EcssEnumeration, ) -> Result<(), EcssTmError> { @@ -445,7 +445,7 @@ impl VerificationReporterBasic { &mut self, buf: &mut [u8], token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), params: FailParamsWithStep, ) -> Result<(), VerificationErrorWithToken> { let tm = self @@ -472,7 +472,7 @@ impl VerificationReporterBasic { &mut self, buf: &mut [u8], token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], ) -> Result<(), VerificationErrorWithToken> { let tm = self @@ -499,7 +499,7 @@ impl VerificationReporterBasic { &mut self, buf: &mut [u8], token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), params: FailParams, ) -> Result<(), VerificationErrorWithToken> { let tm = self @@ -685,7 +685,7 @@ mod allocmod { pub fn acceptance_success( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], ) -> Result, VerificationErrorWithToken> { @@ -701,7 +701,7 @@ mod allocmod { pub fn acceptance_failure( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), params: FailParams, ) -> Result<(), VerificationErrorWithToken> { self.reporter.acceptance_failure( @@ -718,7 +718,7 @@ mod allocmod { pub fn start_success( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], ) -> Result, VerificationErrorWithToken> { @@ -737,7 +737,7 @@ mod allocmod { pub fn start_failure( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), params: FailParams, ) -> Result<(), VerificationErrorWithToken> { self.reporter @@ -750,7 +750,7 @@ mod allocmod { pub fn step_success( &mut self, token: &VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], step: impl EcssEnumeration, ) -> Result<(), EcssTmError> { @@ -770,7 +770,7 @@ mod allocmod { pub fn step_failure( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), params: FailParamsWithStep, ) -> Result<(), VerificationErrorWithToken> { self.reporter @@ -784,7 +784,7 @@ mod allocmod { pub fn completion_success( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), time_stamp: &[u8], ) -> Result<(), VerificationErrorWithToken> { self.reporter.completion_success( @@ -802,7 +802,7 @@ mod allocmod { pub fn completion_failure( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSender + ?Sized), + sender: &mut (impl EcssTmSender + ?Sized), params: FailParams, ) -> Result<(), VerificationErrorWithToken> { self.reporter.completion_failure( @@ -818,18 +818,18 @@ mod allocmod { /// API as [VerificationReporter] but without the explicit sender arguments. pub struct VerificationReporterWithSender { pub reporter: VerificationReporter, - pub sender: Box>, + pub sender: Box>, } impl VerificationReporterWithSender { - pub fn new(cfg: VerificationReporterCfg, sender: Box>) -> Self { + pub fn new(cfg: VerificationReporterCfg, sender: Box>) -> Self { let reporter = VerificationReporter::new(cfg); Self::new_from_reporter(reporter, sender) } pub fn new_from_reporter( reporter: VerificationReporter, - sender: Box>, + sender: Box>, ) -> Self { Self { reporter, sender } } @@ -997,7 +997,9 @@ mod stdmod { } //noinspection RsTraitImplementation - impl EcssTmSender for MpscVerifSender { + impl EcssTmSender for MpscVerifSender { + type Error = StdVerifSenderError; + delegate!( to self.base { fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError>; @@ -1028,7 +1030,9 @@ mod stdmod { } //noinspection RsTraitImplementation - impl EcssTmSender for CrossbeamVerifSender { + impl EcssTmSender for CrossbeamVerifSender { + type Error = StdVerifSenderError; + delegate!( to self.base { fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError>; @@ -1039,8 +1043,9 @@ mod stdmod { unsafe impl Sync for CrossbeamVerifSender {} unsafe impl Send for CrossbeamVerifSender {} - impl EcssTmSender for StdSenderBase { - fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError> { + impl EcssTmSender for StdSenderBase { + type Error = StdVerifSenderError; + fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError> { let operation = |mut mg: RwLockWriteGuard| { let (addr, buf) = mg.free_element(tm.len_packed())?; tm.write_to_bytes(buf).map_err(EcssTmError::PusError)?; @@ -1096,8 +1101,9 @@ mod tests { pub service_queue: VecDeque, } - impl EcssTmSender<()> for TestSender { - fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<()>> { + impl EcssTmSender for TestSender { + type Error = (); + fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError> { assert_eq!(PusPacket::service(&tm), 1); assert!(tm.source_data().is_some()); let mut time_stamp = [0; 7]; diff --git a/fsrc-core/tests/pus_events.rs b/fsrc-core/tests/pus_events.rs index 99c13c5..85b8a29 100644 --- a/fsrc-core/tests/pus_events.rs +++ b/fsrc-core/tests/pus_events.rs @@ -1,6 +1,39 @@ +use fsrc_core::events::{EventU32, EventU32TypedSev, Severity, SeverityInfo}; +use fsrc_core::pus::event_man::{DefaultPusMgmtBackendProvider, EventReporter, PusEventTmManager}; +use fsrc_core::pus::{EcssTmError, EcssTmSender}; +use spacepackets::tm::PusTm; +use std::sync::mpsc::{channel, SendError}; + +const INFO_EVENT: EventU32TypedSev = + EventU32TypedSev::::const_new(1, 0); +const LOW_SEV_EVENT: EventU32 = EventU32::const_new(Severity::LOW, 1, 5); +const EMPTY_STAMP: [u8; 7] = [0; 7]; + +struct EventTmSender { + sender: std::sync::mpsc::Sender>, +} + +impl EcssTmSender for EventTmSender { + type Error = SendError>; + fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError> { + let mut vec = Vec::new(); + tm.append_to_vec(&mut vec)?; + self.sender.send(vec).map_err(EcssTmError::SendError)?; + Ok(()) + } +} #[test] fn main() { - + let reporter = EventReporter::new(0x02, 128).expect("Creating event repoter failed"); + let backend = DefaultPusMgmtBackendProvider::::default(); + let mut event_man = PusEventTmManager::new(reporter, Box::new(backend)); + let (event_tx, event_rx) = channel(); + let mut sender = EventTmSender { sender: event_tx }; + event_man + .generate_pus_event_tm(&mut sender, &EMPTY_STAMP, INFO_EVENT, None) + .expect("Sending info event failed"); + let packet = event_rx.recv().expect("Receiving event TM failed"); + println!("{:?}", packet); //let event_man; }