From 1389ee462e3031103b34d1c6133a44d7ef81c135 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 9 Jul 2023 13:04:00 +0200 Subject: [PATCH 01/11] well this simplifies a lot.. --- satrs-core/src/pus/event.rs | 58 +++++------ satrs-core/src/pus/event_man.rs | 16 +-- satrs-core/src/pus/mod.rs | 157 ++++++++++++++-------------- satrs-core/src/pus/verification.rs | 158 +++++++++++++---------------- 4 files changed, 186 insertions(+), 203 deletions(-) diff --git a/satrs-core/src/pus/event.rs b/satrs-core/src/pus/event.rs index 57f378a..e0677aa 100644 --- a/satrs-core/src/pus/event.rs +++ b/satrs-core/src/pus/event.rs @@ -1,4 +1,4 @@ -use crate::pus::{source_buffer_large_enough, EcssTmtcError, EcssTmtcErrorWithSend}; +use crate::pus::{source_buffer_large_enough, EcssTmtcErrorWithSend}; use spacepackets::ecss::EcssEnumeration; use spacepackets::tm::PusTm; use spacepackets::tm::PusTmSecondaryHeader; @@ -6,7 +6,7 @@ use spacepackets::{SpHeader, MAX_APID}; use crate::pus::EcssTmSenderCore; #[cfg(feature = "alloc")] -pub use allocvec::EventReporter; +pub use alloc_mod::EventReporter; pub use spacepackets::ecss::event::*; pub struct EventReporterBase { @@ -27,14 +27,14 @@ impl EventReporterBase { }) } - pub fn event_info( + pub fn event_info( &mut self, buf: &mut [u8], - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.generate_and_send_generic_tm( buf, Subservice::TmInfoReport, @@ -45,14 +45,14 @@ impl EventReporterBase { ) } - pub fn event_low_severity( + pub fn event_low_severity( &mut self, buf: &mut [u8], - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.generate_and_send_generic_tm( buf, Subservice::TmLowSeverityReport, @@ -63,14 +63,14 @@ impl EventReporterBase { ) } - pub fn event_medium_severity( + pub fn event_medium_severity( &mut self, buf: &mut [u8], - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.generate_and_send_generic_tm( buf, Subservice::TmMediumSeverityReport, @@ -81,14 +81,14 @@ impl EventReporterBase { ) } - pub fn event_high_severity( + pub fn event_high_severity( &mut self, buf: &mut [u8], - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.generate_and_send_generic_tm( buf, Subservice::TmHighSeverityReport, @@ -103,11 +103,11 @@ impl EventReporterBase { &mut self, buf: &mut [u8], subservice: Subservice, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { let tm = self.generate_generic_event_tm(buf, subservice, time_stamp, event_id, aux_data)?; sender .send_tm(tm.into()) @@ -123,7 +123,7 @@ impl EventReporterBase { time_stamp: &'a [u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result { + ) -> Result { let mut src_data_len = event_id.size(); if let Some(aux_data) = aux_data { src_data_len += aux_data.len(); @@ -154,7 +154,7 @@ impl EventReporterBase { } #[cfg(feature = "alloc")] -mod allocvec { +mod alloc_mod { use super::*; use alloc::vec; use alloc::vec::Vec; @@ -174,11 +174,11 @@ mod allocvec { } pub fn event_info( &mut self, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_info( self.source_data_buf.as_mut_slice(), sender, @@ -190,11 +190,11 @@ mod allocvec { pub fn event_low_severity( &mut self, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_low_severity( self.source_data_buf.as_mut_slice(), sender, @@ -206,11 +206,11 @@ mod allocvec { pub fn event_medium_severity( &mut self, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_medium_severity( self.source_data_buf.as_mut_slice(), sender, @@ -222,11 +222,11 @@ mod allocvec { pub fn event_high_severity( &mut self, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_high_severity( self.source_data_buf.as_mut_slice(), sender, @@ -275,9 +275,7 @@ mod tests { } impl EcssTmSenderCore for TestSender { - type Error = (); - - fn send_tm(&self, tm: PusTmWrapper) -> Result<(), Self::Error> { + fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcErrorWithSend> { match tm { PusTmWrapper::InStore(_) => { panic!("TestSender: unexpected call with address"); @@ -427,7 +425,7 @@ mod tests { let err = reporter.event_info(sender, &time_stamp_empty, event, None); assert!(err.is_err()); let err = err.unwrap_err(); - if let EcssTmtcErrorWithSend::EcssTmtcError(EcssTmtcError::ByteConversion( + if let EcssTmtcErrorWithSend::EcssTmtcError(EcssTmtcErrorWithSend::ByteConversion( ByteConversionError::ToSliceTooSmall(missmatch), )) = err { diff --git a/satrs-core/src/pus/event_man.rs b/satrs-core/src/pus/event_man.rs index 0c701e6..968673d 100644 --- a/satrs-core/src/pus/event_man.rs +++ b/satrs-core/src/pus/event_man.rs @@ -95,13 +95,13 @@ pub struct EventRequestWithToken { } #[derive(Debug)] -pub enum EventManError { - EcssTmtcError(EcssTmtcErrorWithSend), +pub enum EventManError { + EcssTmtcError(EcssTmtcErrorWithSend), SeverityMissmatch(Severity, Severity), } -impl From> for EventManError { - fn from(v: EcssTmtcErrorWithSend) -> Self { +impl From for EventManError { + fn from(v: EcssTmtcErrorWithSend) -> Self { Self::EcssTmtcError(v) } } @@ -175,11 +175,11 @@ pub mod alloc_mod { pub fn generate_pus_event_tm_generic( &mut self, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], event: Event, aux_data: Option<&[u8]>, - ) -> Result> { + ) -> Result { if !self.backend.event_enabled(&event) { return Ok(false); } @@ -225,11 +225,11 @@ pub mod alloc_mod { pub fn generate_pus_event_tm( &mut self, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], event: EventU32TypedSev, aux_data: Option<&[u8]>, - ) -> Result> { + ) -> Result { self.generate_pus_event_tm_generic(sender, time_stamp, event.into(), aux_data) } } diff --git a/satrs-core/src/pus/mod.rs b/satrs-core/src/pus/mod.rs index cc5f9ce..5340046 100644 --- a/satrs-core/src/pus/mod.rs +++ b/satrs-core/src/pus/mod.rs @@ -50,41 +50,36 @@ impl<'tm> From> for PusTmWrapper<'tm> { } } -#[derive(Debug, Clone)] -pub enum EcssTmtcErrorWithSend { - /// Errors related to sending the telemetry to a TMTC recipient - SendError(E), - EcssTmtcError(EcssTmtcError), -} - -impl From for EcssTmtcErrorWithSend { - fn from(value: EcssTmtcError) -> Self { - Self::EcssTmtcError(value) - } -} - /// Generic error type for PUS TM handling. -#[derive(Debug, Clone)] -pub enum EcssTmtcError { - /// Errors related to the time stamp format of the telemetry - Timestamp(TimestampError), - /// Errors related to byte conversion, for example insufficient buffer size for given data - ByteConversion(ByteConversionError), - /// Errors related to PUS packet format - Pus(PusError), +#[derive(Debug, Copy, Clone)] +pub enum EcssTmtcSendError { + RxDisconnected, + QueueFull(u32), } -impl From for EcssTmtcError { - fn from(e: PusError) -> Self { - EcssTmtcError::Pus(e) - } -} - -impl From for EcssTmtcError { - fn from(e: ByteConversionError) -> Self { - EcssTmtcError::ByteConversion(e) - } -} +// /// Generic error type for PUS TMTC handling. +// #[derive(Debug, Clone)] +// pub enum EcssTmtcErrorWithSend { +// /// Errors related to the time stamp format of the telemetry +// Timestamp(TimestampError), +// /// Errors related to byte conversion, for example insufficient buffer size for given data +// ByteConversion(ByteConversionError), +// /// Errors related to PUS packet format +// Pus(PusError), +// Send(EcssTmtcSendError) +// } +// +// impl From for EcssTmtcErrorWithSend { +// fn from(e: PusError) -> Self { +// EcssTmtcErrorWithSend::Pus(e) +// } +// } +// +// impl From for EcssTmtcErrorWithSend { +// fn from(e: ByteConversionError) -> Self { +// EcssTmtcErrorWithSend::ByteConversion(e) +// } +// } pub trait EcssSender: Send { /// Each sender can have an ID associated with it @@ -93,24 +88,6 @@ pub trait EcssSender: Send { "unset" } } -/// Generic trait for a user supplied sender object. -/// -/// This sender object is responsible for sending PUS telemetry to a TM sink. -pub trait EcssTmSenderCore: EcssSender { - type Error; - - fn send_tm(&self, tm: PusTmWrapper) -> Result<(), Self::Error>; -} - -/// Generic trait for a user supplied sender object. -/// -/// This sender object is responsible for sending PUS telecommands to a TC recipient. Each -/// telecommand can optionally have a token which contains its verification state. -pub trait EcssTcSenderCore: EcssSender { - type Error; - - fn send_tc(&self, tc: PusTc, token: Option) -> Result<(), Self::Error>; -} #[cfg(feature = "alloc")] mod alloc_mod { @@ -133,8 +110,8 @@ mod alloc_mod { /// Blanket implementation for all types which implement [EcssTmSenderCore] and are clonable. impl EcssTmSender for T where T: EcssTmSenderCore + Clone + 'static {} - dyn_clone::clone_trait_object!( EcssTmSender); - impl_downcast!(EcssTmSender assoc Error); + dyn_clone::clone_trait_object!(EcssTmSender); + impl_downcast!(EcssTmSender); /// Extension trait for [EcssTcSenderCore]. /// @@ -153,21 +130,22 @@ mod alloc_mod { /// Blanket implementation for all types which implement [EcssTcSenderCore] and are clonable. impl EcssTcSender for T where T: EcssTcSenderCore + Clone + 'static {} - dyn_clone::clone_trait_object!( EcssTcSender); - impl_downcast!(EcssTcSender assoc Error); + dyn_clone::clone_trait_object!(EcssTcSender); + impl_downcast!(EcssTcSender); } #[cfg(feature = "std")] pub mod std_mod { use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError}; use crate::pus::verification::{ - StdVerifReporterWithSender, TcStateAccepted, VerificationToken, + StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken, }; - use crate::pus::{EcssSender, EcssTmSenderCore, PusTmWrapper}; + use crate::pus::{EcssSender, EcssTmtcSendError, PusTmWrapper}; use crate::tmtc::tm_helper::SharedTmStore; use crate::SenderId; use alloc::vec::Vec; use spacepackets::ecss::{PusError, SerializablePusPacket}; + use spacepackets::tc::PusTc; use spacepackets::time::cds::TimeProvider; use spacepackets::time::{StdTimestampError, TimeWriter}; use std::cell::RefCell; @@ -177,17 +155,36 @@ pub mod std_mod { use thiserror::Error; #[derive(Debug, Clone, Error)] - pub enum MpscTmInStoreSenderError { - #[error("RwGuard lock error")] + pub enum EcssTmtcErrorWithSend { + #[error("store locking error")] StoreLock, - #[error("Generic PUS error: {0}")] - Pus(#[from] PusError), - #[error("Generic store error: {0}")] + #[error("generic store error: {0}")] Store(#[from] StoreError), - #[error("MPSC channel send error: {0}")] - Send(#[from] mpsc::SendError), - #[error("RX handle has disconnected")] - RxDisconnected, + #[error("generic PUS error: {0}")] + Pus(#[from] PusError), + #[error("not able to send address {0}")] + CantSendAddr(StoreAddr), + #[error("generic channel send error: {0}")] + Send(#[from] EcssTmtcSendError), + } + + /// Generic trait for a user supplied sender object. + /// + /// This sender object is responsible for sending PUS telemetry to a TM sink. + pub trait EcssTmSenderCore: EcssSender { + fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcErrorWithSend>; + } + + /// Generic trait for a user supplied sender object. + /// + /// This sender object is responsible for sending PUS telecommands to a TC recipient. Each + /// telecommand can optionally have a token which contains its verification state. + pub trait EcssTcSenderCore: EcssSender { + fn send_tc( + &self, + tc: PusTc, + token: Option, + ) -> Result<(), EcssTmtcErrorWithSend>; } #[derive(Clone)] @@ -213,7 +210,7 @@ pub mod std_mod { pub fn send_direct_tm( &self, tmtc: impl SerializablePusPacket, - ) -> Result<(), MpscTmInStoreSenderError> { + ) -> Result<(), EcssTmtcErrorWithSend> { let operation = |mut store: RwLockWriteGuard| { let (addr, slice) = store.free_element(tmtc.len_packed())?; tmtc.write_to_bytes(slice)?; @@ -226,7 +223,9 @@ pub mod std_mod { if self.ignore_poison_errors { operation(e.into_inner()) } else { - Err(MpscTmInStoreSenderError::StoreLock) + Err(EcssTmtcErrorWithSend::Send( + EcssTmtcSendError::RxDisconnected, + )) } } } @@ -234,14 +233,11 @@ pub mod std_mod { } impl EcssTmSenderCore for MpscTmInStoreSender { - type Error = MpscTmInStoreSenderError; - - fn send_tm(&self, tm: PusTmWrapper) -> Result<(), Self::Error> { + fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcErrorWithSend> { match tm { - PusTmWrapper::InStore(addr) => self - .sender - .send(addr) - .map_err(MpscTmInStoreSenderError::Send), + PusTmWrapper::InStore(addr) => self.sender.send(addr).map_err( + EcssTmtcErrorWithSend::Send(EcssTmtcSendError::RxDisconnected), + ), PusTmWrapper::Direct(tm) => self.send_direct_tm(tm), } } @@ -303,11 +299,9 @@ pub mod std_mod { } impl EcssTmSenderCore for MpscTmAsVecSender { - type Error = MpscTmAsVecSenderError; - - fn send_tm(&self, tm: PusTmWrapper) -> Result<(), Self::Error> { + fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcErrorWithSend> { match tm { - PusTmWrapper::InStore(addr) => Err(MpscTmAsVecSenderError::CantSendAddr(addr)), + PusTmWrapper::InStore(addr) => Err(EcssTmtcErrorWithSend::CantSendAddr(addr)), PusTmWrapper::Direct(tm) => { let mut vec = Vec::new(); tm.append_to_vec(&mut vec) @@ -470,9 +464,12 @@ pub mod std_mod { } } -pub(crate) fn source_buffer_large_enough(cap: usize, len: usize) -> Result<(), EcssTmtcError> { +pub(crate) fn source_buffer_large_enough( + cap: usize, + len: usize, +) -> Result<(), EcssTmtcErrorWithSend> { if len > cap { - return Err(EcssTmtcError::ByteConversion( + return Err(EcssTmtcErrorWithSend::ByteConversion( ByteConversionError::ToSliceTooSmall(SizeMissmatch { found: cap, expected: len, diff --git a/satrs-core/src/pus/verification.rs b/satrs-core/src/pus/verification.rs index 445f10b..b6d1028 100644 --- a/satrs-core/src/pus/verification.rs +++ b/satrs-core/src/pus/verification.rs @@ -73,9 +73,7 @@ //! The [integration test](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/main/fsrc-core/tests/verification_test.rs) //! for the verification module contains examples how this module could be used in a more complex //! context involving multiple threads -use crate::pus::{ - source_buffer_large_enough, EcssTmSenderCore, EcssTmtcError, EcssTmtcErrorWithSend, -}; +use crate::pus::{source_buffer_large_enough, EcssTmSenderCore, EcssTmtcErrorWithSend}; use core::fmt::{Debug, Display, Formatter}; use core::hash::{Hash, Hasher}; use core::marker::PhantomData; @@ -174,15 +172,12 @@ impl RequestId { /// If a verification operation fails, the passed token will be returned as well. This allows /// re-trying the operation at a later point. #[derive(Debug, Clone)] -pub struct VerificationOrSendErrorWithToken( - pub EcssTmtcErrorWithSend, - pub VerificationToken, -); +pub struct VerificationOrSendErrorWithToken(pub EcssTmtcErrorWithSend, pub VerificationToken); #[derive(Debug, Clone)] -pub struct VerificationErrorWithToken(pub EcssTmtcError, pub VerificationToken); +pub struct VerificationErrorWithToken(pub EcssTmtcErrorWithSend, pub VerificationToken); -impl From> for VerificationOrSendErrorWithToken { +impl From> for VerificationOrSendErrorWithToken { fn from(value: VerificationErrorWithToken) -> Self { VerificationOrSendErrorWithToken(value.0.into(), value.1) } @@ -517,8 +512,8 @@ impl VerificationReporterCore { pub fn send_acceptance_success( &self, mut sendable: VerificationSendable<'_, TcStateNone, VerifSuccess>, - sender: &mut (impl EcssTmSenderCore + ?Sized), - ) -> Result, VerificationOrSendErrorWithToken> + sender: &mut (impl EcssTmSenderCore + ?Sized), + ) -> Result, VerificationOrSendErrorWithToken> { sender .send_tm(sendable.pus_tm.take().unwrap().into()) @@ -534,8 +529,8 @@ impl VerificationReporterCore { pub fn send_acceptance_failure( &self, mut sendable: VerificationSendable<'_, TcStateNone, VerifFailure>, - sender: &mut (impl EcssTmSenderCore + ?Sized), - ) -> Result<(), VerificationOrSendErrorWithToken> { + sender: &mut (impl EcssTmSenderCore + ?Sized), + ) -> Result<(), VerificationOrSendErrorWithToken> { sender .send_tm(sendable.pus_tm.take().unwrap().into()) .map_err(|e| { @@ -598,11 +593,9 @@ impl VerificationReporterCore { pub fn send_start_success( &self, mut sendable: VerificationSendable<'_, TcStateAccepted, VerifSuccess>, - sender: &mut (impl EcssTmSenderCore + ?Sized), - ) -> Result< - VerificationToken, - VerificationOrSendErrorWithToken, - > { + sender: &mut (impl EcssTmSenderCore + ?Sized), + ) -> Result, VerificationOrSendErrorWithToken> + { sender .send_tm(sendable.pus_tm.take().unwrap().into()) .map_err(|e| { @@ -643,8 +636,8 @@ impl VerificationReporterCore { pub fn send_start_failure( &self, mut sendable: VerificationSendable<'_, TcStateAccepted, VerifFailure>, - sender: &mut (impl EcssTmSenderCore + ?Sized), - ) -> Result<(), VerificationOrSendErrorWithToken> { + sender: &mut (impl EcssTmSenderCore + ?Sized), + ) -> Result<(), VerificationOrSendErrorWithToken> { sender .send_tm(sendable.pus_tm.take().unwrap().into()) .map_err(|e| { @@ -668,7 +661,8 @@ impl VerificationReporterCore { msg_count: u16, time_stamp: Option<&'src_data [u8]>, step: impl EcssEnumeration, - ) -> Result, EcssTmtcError> { + ) -> Result, EcssTmtcErrorWithSend> + { Ok(VerificationSendable::new_no_token( self.create_pus_verif_success_tm( src_data_buf, @@ -763,11 +757,11 @@ impl VerificationReporterCore { ) } - pub fn send_step_or_completion_success( + pub fn send_step_or_completion_success( &self, mut sendable: VerificationSendable<'_, TcState, VerifSuccess>, - sender: &mut (impl EcssTmSenderCore + ?Sized), - ) -> Result<(), VerificationOrSendErrorWithToken> { + sender: &mut (impl EcssTmSenderCore + ?Sized), + ) -> Result<(), VerificationOrSendErrorWithToken> { sender .send_tm(sendable.pus_tm.take().unwrap().into()) .map_err(|e| { @@ -780,11 +774,11 @@ impl VerificationReporterCore { Ok(()) } - pub fn send_step_or_completion_failure( + pub fn send_step_or_completion_failure( &self, mut sendable: VerificationSendable<'_, TcState, VerifFailure>, - sender: &mut (impl EcssTmSenderCore + ?Sized), - ) -> Result<(), VerificationOrSendErrorWithToken> { + sender: &mut (impl EcssTmSenderCore + ?Sized), + ) -> Result<(), VerificationOrSendErrorWithToken> { sender .send_tm(sendable.pus_tm.take().unwrap().into()) .map_err(|e| { @@ -808,7 +802,7 @@ impl VerificationReporterCore { req_id: &RequestId, time_stamp: Option<&'src_data [u8]>, step: Option<&(impl EcssEnumeration + ?Sized)>, - ) -> Result, EcssTmtcError> { + ) -> Result, EcssTmtcErrorWithSend> { let mut source_data_len = size_of::(); if let Some(step) = step { source_data_len += step.size(); @@ -844,7 +838,7 @@ impl VerificationReporterCore { req_id: &RequestId, step: Option<&(impl EcssEnumeration + ?Sized)>, params: &FailParams<'src_data, '_>, - ) -> Result, EcssTmtcError> { + ) -> Result, EcssTmtcErrorWithSend> { let mut idx = 0; let mut source_data_len = RequestId::SIZE_AS_BYTES + params.failure_code.size(); if let Some(step) = step { @@ -981,15 +975,13 @@ mod alloc_mod { } /// Package and send a PUS TM\[1, 1\] packet, see 8.1.2.1 of the PUS standard - pub fn acceptance_success( + pub fn acceptance_success( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: Option<&[u8]>, - ) -> Result< - VerificationToken, - VerificationOrSendErrorWithToken, - > { + ) -> Result, VerificationOrSendErrorWithToken> + { let seq_count = self .seq_count_provider .as_ref() @@ -1012,9 +1004,9 @@ mod alloc_mod { pub fn acceptance_failure( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), params: FailParams, - ) -> Result<(), VerificationOrSendErrorWithToken> { + ) -> Result<(), VerificationOrSendErrorWithToken> { let seq_count = self .seq_count_provider .as_ref() @@ -1039,11 +1031,11 @@ mod alloc_mod { pub fn start_success( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: Option<&[u8]>, ) -> Result< VerificationToken, - VerificationOrSendErrorWithToken, + VerificationOrSendErrorWithToken, > { let seq_count = self .seq_count_provider @@ -1070,9 +1062,9 @@ mod alloc_mod { pub fn start_failure( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), params: FailParams, - ) -> Result<(), VerificationOrSendErrorWithToken> { + ) -> Result<(), VerificationOrSendErrorWithToken> { let seq_count = self .seq_count_provider .as_ref() @@ -1097,10 +1089,10 @@ mod alloc_mod { pub fn step_success( &mut self, token: &VerificationToken, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: Option<&[u8]>, step: impl EcssEnumeration, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { let seq_count = self .seq_count_provider .as_ref() @@ -1129,9 +1121,9 @@ mod alloc_mod { pub fn step_failure( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), params: FailParamsWithStep, - ) -> Result<(), VerificationOrSendErrorWithToken> { + ) -> Result<(), VerificationOrSendErrorWithToken> { let seq_count = self .seq_count_provider .as_ref() @@ -1155,12 +1147,12 @@ mod alloc_mod { /// /// Requires a token previously acquired by calling [Self::start_success]. It consumes the /// token because verification handling is done. - pub fn completion_success( + pub fn completion_success( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: Option<&[u8]>, - ) -> Result<(), VerificationOrSendErrorWithToken> { + ) -> Result<(), VerificationOrSendErrorWithToken> { let seq_count = self .seq_count_provider .as_ref() @@ -1184,12 +1176,12 @@ mod alloc_mod { /// /// Requires a token previously acquired by calling [Self::start_success]. It consumes the /// token because verification handling is done. - pub fn completion_failure( + pub fn completion_failure( &mut self, token: VerificationToken, - sender: &mut (impl EcssTmSenderCore + ?Sized), + sender: &mut (impl EcssTmSenderCore + ?Sized), params: FailParams, - ) -> Result<(), VerificationOrSendErrorWithToken> { + ) -> Result<(), VerificationOrSendErrorWithToken> { let seq_count = self .seq_count_provider .as_ref() @@ -1213,23 +1205,20 @@ mod alloc_mod { /// Helper object which caches the sender passed as a trait object. Provides the same /// API as [VerificationReporter] but without the explicit sender arguments. #[derive(Clone)] - pub struct VerificationReporterWithSender { + pub struct VerificationReporterWithSender { pub reporter: VerificationReporter, - pub sender: Box>, + pub sender: Box, } - impl VerificationReporterWithSender { - pub fn new( - cfg: &VerificationReporterCfg, - sender: Box>, - ) -> Self { + impl VerificationReporterWithSender { + 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 } } @@ -1249,10 +1238,8 @@ mod alloc_mod { &mut self, token: VerificationToken, time_stamp: Option<&[u8]>, - ) -> Result< - VerificationToken, - VerificationOrSendErrorWithToken, - > { + ) -> Result, VerificationOrSendErrorWithToken> + { self.reporter .acceptance_success(token, self.sender.as_mut(), time_stamp) } @@ -1261,7 +1248,7 @@ mod alloc_mod { &mut self, token: VerificationToken, params: FailParams, - ) -> Result<(), VerificationOrSendErrorWithToken> { + ) -> Result<(), VerificationOrSendErrorWithToken> { self.reporter .acceptance_failure(token, self.sender.as_mut(), params) } @@ -1272,7 +1259,7 @@ mod alloc_mod { time_stamp: Option<&[u8]>, ) -> Result< VerificationToken, - VerificationOrSendErrorWithToken, + VerificationOrSendErrorWithToken, > { self.reporter .start_success(token, self.sender.as_mut(), time_stamp) @@ -1282,7 +1269,7 @@ mod alloc_mod { &mut self, token: VerificationToken, params: FailParams, - ) -> Result<(), VerificationOrSendErrorWithToken> { + ) -> Result<(), VerificationOrSendErrorWithToken> { self.reporter .start_failure(token, self.sender.as_mut(), params) } @@ -1292,7 +1279,7 @@ mod alloc_mod { token: &VerificationToken, time_stamp: Option<&[u8]>, step: impl EcssEnumeration, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter .step_success(token, self.sender.as_mut(), time_stamp, step) } @@ -1301,7 +1288,7 @@ mod alloc_mod { &mut self, token: VerificationToken, params: FailParamsWithStep, - ) -> Result<(), VerificationOrSendErrorWithToken> { + ) -> Result<(), VerificationOrSendErrorWithToken> { self.reporter .step_failure(token, self.sender.as_mut(), params) } @@ -1310,7 +1297,7 @@ mod alloc_mod { &mut self, token: VerificationToken, time_stamp: Option<&[u8]>, - ) -> Result<(), VerificationOrSendErrorWithToken> { + ) -> Result<(), VerificationOrSendErrorWithToken> { self.reporter .completion_success(token, self.sender.as_mut(), time_stamp) } @@ -1319,7 +1306,7 @@ mod alloc_mod { &mut self, token: VerificationToken, params: FailParams, - ) -> Result<(), VerificationOrSendErrorWithToken> { + ) -> Result<(), VerificationOrSendErrorWithToken> { self.reporter .completion_failure(token, self.sender.as_mut(), params) } @@ -1329,7 +1316,6 @@ mod alloc_mod { #[cfg(feature = "std")] mod std_mod { use crate::pus::verification::VerificationReporterWithSender; - use crate::pus::MpscTmInStoreSenderError; use std::sync::{Arc, Mutex}; // use super::alloc_mod::VerificationReporterWithSender; @@ -1341,7 +1327,7 @@ mod std_mod { // use spacepackets::ecss::SerializablePusPacket; // use std::sync::{mpsc, Arc, Mutex, RwLockWriteGuard}; // - pub type StdVerifReporterWithSender = VerificationReporterWithSender; + pub type StdVerifReporterWithSender = VerificationReporterWithSender; pub type SharedStdVerifReporterWithSender = Arc>; // // trait SendBackend: Send { @@ -1525,8 +1511,8 @@ mod tests { use crate::pool::{LocalPool, PoolCfg, SharedPool}; use crate::pus::tests::CommonTmInfo; use crate::pus::verification::{ - EcssTmSenderCore, EcssTmtcError, FailParams, FailParamsWithStep, RequestId, TcStateNone, - VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender, + EcssTmSenderCore, EcssTmtcErrorWithSend, FailParams, FailParamsWithStep, RequestId, + TcStateNone, VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender, VerificationToken, }; use crate::pus::{EcssSender, EcssTmtcErrorWithSend, MpscTmInStoreSender, PusTmWrapper}; @@ -1819,18 +1805,20 @@ mod tests { let err_with_token = res.unwrap_err(); assert_eq!(err_with_token.1, tok); match err_with_token.0 { - EcssTmtcErrorWithSend::EcssTmtcError(EcssTmtcError::ByteConversion(e)) => match e { - ByteConversionError::ToSliceTooSmall(missmatch) => { - assert_eq!( - missmatch.expected, - fail_data.len() + RequestId::SIZE_AS_BYTES + fail_code.size() - ); - assert_eq!(missmatch.found, b.rep().allowed_source_data_len()); + EcssTmtcErrorWithSend::EcssTmtcError(EcssTmtcErrorWithSend::ByteConversion(e)) => { + match e { + ByteConversionError::ToSliceTooSmall(missmatch) => { + assert_eq!( + missmatch.expected, + fail_data.len() + RequestId::SIZE_AS_BYTES + fail_code.size() + ); + assert_eq!(missmatch.found, b.rep().allowed_source_data_len()); + } + _ => { + panic!("{}", format!("Unexpected error {:?}", e)) + } } - _ => { - panic!("{}", format!("Unexpected error {:?}", e)) - } - }, + } _ => { panic!("{}", format!("Unexpected error {:?}", err_with_token.0)) } From 1d752251f5e363ebc60cbe5be3a69ec9db40d664 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 9 Jul 2023 13:23:34 +0200 Subject: [PATCH 02/11] it compiles again --- satrs-core/src/pus/event.rs | 20 ++-- satrs-core/src/pus/event_man.rs | 2 +- satrs-core/src/pus/mod.rs | 170 +++++++++++++++++------------ satrs-core/src/pus/verification.rs | 67 ++++-------- 4 files changed, 132 insertions(+), 127 deletions(-) diff --git a/satrs-core/src/pus/event.rs b/satrs-core/src/pus/event.rs index e0677aa..5ab85f7 100644 --- a/satrs-core/src/pus/event.rs +++ b/satrs-core/src/pus/event.rs @@ -1,5 +1,5 @@ use crate::pus::{source_buffer_large_enough, EcssTmtcErrorWithSend}; -use spacepackets::ecss::EcssEnumeration; +use spacepackets::ecss::{EcssEnumeration, PusError}; use spacepackets::tm::PusTm; use spacepackets::tm::PusTmSecondaryHeader; use spacepackets::{SpHeader, MAX_APID}; @@ -99,7 +99,7 @@ impl EventReporterBase { ) } - fn generate_and_send_generic_tm( + fn generate_and_send_generic_tm( &mut self, buf: &mut [u8], subservice: Subservice, @@ -109,9 +109,7 @@ impl EventReporterBase { aux_data: Option<&[u8]>, ) -> Result<(), EcssTmtcErrorWithSend> { let tm = self.generate_generic_event_tm(buf, subservice, time_stamp, event_id, aux_data)?; - sender - .send_tm(tm.into()) - .map_err(|e| EcssTmtcErrorWithSend::SendError(e))?; + sender.send_tm(tm.into())?; self.msg_count += 1; Ok(()) } @@ -138,7 +136,9 @@ impl EventReporterBase { Some(time_stamp), ); let mut current_idx = 0; - event_id.write_to_be_bytes(&mut buf[0..event_id.size()])?; + event_id + .write_to_be_bytes(&mut buf[0..event_id.size()]) + .map_err(PusError::ByteConversionError)?; current_idx += event_id.size(); if let Some(aux_data) = aux_data { buf[current_idx..current_idx + aux_data.len()].copy_from_slice(aux_data); @@ -172,7 +172,7 @@ mod alloc_mod { reporter, }) } - pub fn event_info( + pub fn event_info( &mut self, sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], @@ -188,7 +188,7 @@ mod alloc_mod { ) } - pub fn event_low_severity( + pub fn event_low_severity( &mut self, sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], @@ -204,7 +204,7 @@ mod alloc_mod { ) } - pub fn event_medium_severity( + pub fn event_medium_severity( &mut self, sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], @@ -220,7 +220,7 @@ mod alloc_mod { ) } - pub fn event_high_severity( + pub fn event_high_severity( &mut self, sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], diff --git a/satrs-core/src/pus/event_man.rs b/satrs-core/src/pus/event_man.rs index 968673d..f3231b4 100644 --- a/satrs-core/src/pus/event_man.rs +++ b/satrs-core/src/pus/event_man.rs @@ -173,7 +173,7 @@ pub mod alloc_mod { self.backend.disable_event_reporting(event) } - pub fn generate_pus_event_tm_generic( + pub fn generate_pus_event_tm_generic( &mut self, sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], diff --git a/satrs-core/src/pus/mod.rs b/satrs-core/src/pus/mod.rs index 5340046..574b40e 100644 --- a/satrs-core/src/pus/mod.rs +++ b/satrs-core/src/pus/mod.rs @@ -2,17 +2,16 @@ //! //! This module contains structures to make working with the PUS C standard easier. //! The satrs-example application contains various usage examples of these components. -use crate::pus::verification::TcStateToken; use crate::SenderId; +use core::fmt::{Display, Formatter}; #[cfg(feature = "alloc")] use downcast_rs::{impl_downcast, Downcast}; #[cfg(feature = "alloc")] use dyn_clone::DynClone; use spacepackets::ecss::PusError; -use spacepackets::tc::PusTc; -use spacepackets::time::TimestampError; use spacepackets::tm::PusTm; use spacepackets::{ByteConversionError, SizeMissmatch}; +use std::error::Error; pub mod event; pub mod event_man; @@ -28,7 +27,7 @@ pub mod verification; #[cfg(feature = "alloc")] pub use alloc_mod::*; -use crate::pool::StoreAddr; +use crate::pool::{StoreAddr, StoreError}; #[cfg(feature = "std")] pub use std_mod::*; @@ -50,37 +49,89 @@ impl<'tm> From> for PusTmWrapper<'tm> { } } -/// Generic error type for PUS TM handling. +/// Generic error type for sending something via a message queue. #[derive(Debug, Copy, Clone)] -pub enum EcssTmtcSendError { +pub enum GenericSendError { RxDisconnected, QueueFull(u32), } -// /// Generic error type for PUS TMTC handling. -// #[derive(Debug, Clone)] -// pub enum EcssTmtcErrorWithSend { -// /// Errors related to the time stamp format of the telemetry -// Timestamp(TimestampError), -// /// Errors related to byte conversion, for example insufficient buffer size for given data -// ByteConversion(ByteConversionError), -// /// Errors related to PUS packet format -// Pus(PusError), -// Send(EcssTmtcSendError) -// } -// -// impl From for EcssTmtcErrorWithSend { -// fn from(e: PusError) -> Self { -// EcssTmtcErrorWithSend::Pus(e) -// } -// } -// -// impl From for EcssTmtcErrorWithSend { -// fn from(e: ByteConversionError) -> Self { -// EcssTmtcErrorWithSend::ByteConversion(e) -// } -// } +impl Display for GenericSendError { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + GenericSendError::RxDisconnected => { + write!(f, "rx side has disconnected") + } + GenericSendError::QueueFull(max_cap) => { + write!(f, "queue with max capacity of {max_cap} is full") + } + } + } +} +#[cfg(feature = "std")] +impl Error for GenericSendError {} + +#[derive(Debug, Clone)] +pub enum EcssTmtcErrorWithSend { + StoreLock, + Store(StoreError), + Pus(PusError), + CantSendAddr(StoreAddr), + Send(GenericSendError), +} + +impl Display for EcssTmtcErrorWithSend { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + EcssTmtcErrorWithSend::StoreLock => { + write!(f, "store lock error") + } + EcssTmtcErrorWithSend::Store(store) => { + write!(f, "store error: {store}") + } + EcssTmtcErrorWithSend::Pus(pus_e) => { + write!(f, "PUS error: {pus_e}") + } + EcssTmtcErrorWithSend::CantSendAddr(addr) => { + write!(f, "can not send address {addr}") + } + EcssTmtcErrorWithSend::Send(send_e) => { + write!(f, "send error {send_e}") + } + } + } +} + +impl From for EcssTmtcErrorWithSend { + fn from(value: StoreError) -> Self { + Self::Store(value) + } +} + +impl From for EcssTmtcErrorWithSend { + fn from(value: PusError) -> Self { + Self::Pus(value) + } +} + +impl From for EcssTmtcErrorWithSend { + fn from(value: GenericSendError) -> Self { + Self::Send(value) + } +} + +#[cfg(feature = "std")] +impl Error for EcssTmtcErrorWithSend { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + EcssTmtcErrorWithSend::Store(e) => Some(e), + EcssTmtcErrorWithSend::Pus(e) => Some(e), + EcssTmtcErrorWithSend::Send(e) => Some(e), + _ => None, + } + } +} pub trait EcssSender: Send { /// Each sender can have an ID associated with it fn id(&self) -> SenderId; @@ -140,7 +191,7 @@ pub mod std_mod { use crate::pus::verification::{ StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken, }; - use crate::pus::{EcssSender, EcssTmtcSendError, PusTmWrapper}; + use crate::pus::{EcssSender, EcssTmtcErrorWithSend, GenericSendError, PusTmWrapper}; use crate::tmtc::tm_helper::SharedTmStore; use crate::SenderId; use alloc::vec::Vec; @@ -151,23 +202,10 @@ pub mod std_mod { use std::cell::RefCell; use std::format; use std::string::String; + use std::sync::mpsc::SendError; use std::sync::{mpsc, RwLockWriteGuard}; use thiserror::Error; - #[derive(Debug, Clone, Error)] - pub enum EcssTmtcErrorWithSend { - #[error("store locking error")] - StoreLock, - #[error("generic store error: {0}")] - Store(#[from] StoreError), - #[error("generic PUS error: {0}")] - Pus(#[from] PusError), - #[error("not able to send address {0}")] - CantSendAddr(StoreAddr), - #[error("generic channel send error: {0}")] - Send(#[from] EcssTmtcSendError), - } - /// Generic trait for a user supplied sender object. /// /// This sender object is responsible for sending PUS telemetry to a TM sink. @@ -206,6 +244,11 @@ pub mod std_mod { } } + impl From> for EcssTmtcErrorWithSend { + fn from(_: SendError) -> Self { + Self::Send(GenericSendError::RxDisconnected) + } + } impl MpscTmInStoreSender { pub fn send_direct_tm( &self, @@ -224,7 +267,7 @@ pub mod std_mod { operation(e.into_inner()) } else { Err(EcssTmtcErrorWithSend::Send( - EcssTmtcSendError::RxDisconnected, + GenericSendError::RxDisconnected, )) } } @@ -235,9 +278,7 @@ pub mod std_mod { impl EcssTmSenderCore for MpscTmInStoreSender { fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcErrorWithSend> { match tm { - PusTmWrapper::InStore(addr) => self.sender.send(addr).map_err( - EcssTmtcErrorWithSend::Send(EcssTmtcSendError::RxDisconnected), - ), + PusTmWrapper::InStore(addr) => self.sender.send(addr).map_err(|e| e.into()), PusTmWrapper::Direct(tm) => self.send_direct_tm(tm), } } @@ -260,18 +301,6 @@ pub mod std_mod { } } - #[derive(Debug, Clone, Error)] - pub enum MpscTmAsVecSenderError { - #[error("Generic PUS error: {0}")] - Pus(#[from] PusError), - #[error("MPSC channel send error: {0}")] - Send(#[from] mpsc::SendError>), - #[error("can not handle store addresses")] - CantSendAddr(StoreAddr), - #[error("RX handle has disconnected")] - RxDisconnected, - } - /// This class can be used if frequent heap allocations during run-time are not an issue. /// PUS TM packets will be sent around as [Vec]s. Please note that the current implementation /// of this class can not deal with store addresses, so it is assumed that is is always @@ -283,6 +312,12 @@ pub mod std_mod { name: &'static str, } + impl From>> for EcssTmtcErrorWithSend { + fn from(_: SendError>) -> Self { + Self::Send(GenericSendError::RxDisconnected) + } + } + impl MpscTmAsVecSender { pub fn new(id: u32, name: &'static str, sender: mpsc::Sender>) -> Self { Self { id, sender, name } @@ -305,10 +340,8 @@ pub mod std_mod { PusTmWrapper::Direct(tm) => { let mut vec = Vec::new(); tm.append_to_vec(&mut vec) - .map_err(MpscTmAsVecSenderError::Pus)?; - self.sender - .send(vec) - .map_err(MpscTmAsVecSenderError::Send)?; + .map_err(EcssTmtcErrorWithSend::Pus)?; + self.sender.send(vec)?; Ok(()) } } @@ -469,12 +502,13 @@ pub(crate) fn source_buffer_large_enough( len: usize, ) -> Result<(), EcssTmtcErrorWithSend> { if len > cap { - return Err(EcssTmtcErrorWithSend::ByteConversion( - ByteConversionError::ToSliceTooSmall(SizeMissmatch { + return Err( + PusError::ByteConversionError(ByteConversionError::ToSliceTooSmall(SizeMissmatch { found: cap, expected: len, - }), - )); + })) + .into(), + ); } Ok(()) } diff --git a/satrs-core/src/pus/verification.rs b/satrs-core/src/pus/verification.rs index b6d1028..83307a1 100644 --- a/satrs-core/src/pus/verification.rs +++ b/satrs-core/src/pus/verification.rs @@ -82,7 +82,7 @@ use core::mem::size_of; use delegate::delegate; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use spacepackets::ecss::{EcssEnumeration, SerializablePusPacket}; +use spacepackets::ecss::{EcssEnumeration, PusError, SerializablePusPacket}; use spacepackets::tc::PusTc; use spacepackets::tm::{PusTm, PusTmSecondaryHeader}; use spacepackets::{CcsdsPacket, PacketId, PacketSequenceCtrl}; @@ -179,7 +179,7 @@ pub struct VerificationErrorWithToken(pub EcssTmtcErrorWithSend, pub Verifica impl From> for VerificationOrSendErrorWithToken { fn from(value: VerificationErrorWithToken) -> Self { - VerificationOrSendErrorWithToken(value.0.into(), value.1) + VerificationOrSendErrorWithToken(value.0, value.1) } } /// Support token to allow type-state programming. This prevents calling the verification @@ -509,7 +509,7 @@ impl VerificationReporterCore { ) } - pub fn send_acceptance_success( + pub fn send_acceptance_success( &self, mut sendable: VerificationSendable<'_, TcStateNone, VerifSuccess>, sender: &mut (impl EcssTmSenderCore + ?Sized), @@ -517,28 +517,18 @@ impl VerificationReporterCore { { sender .send_tm(sendable.pus_tm.take().unwrap().into()) - .map_err(|e| { - VerificationOrSendErrorWithToken( - EcssTmtcErrorWithSend::SendError(e), - sendable.token.unwrap(), - ) - })?; + .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?; Ok(sendable.send_success_acceptance_success()) } - pub fn send_acceptance_failure( + pub fn send_acceptance_failure( &self, mut sendable: VerificationSendable<'_, TcStateNone, VerifFailure>, sender: &mut (impl EcssTmSenderCore + ?Sized), ) -> Result<(), VerificationOrSendErrorWithToken> { sender .send_tm(sendable.pus_tm.take().unwrap().into()) - .map_err(|e| { - VerificationOrSendErrorWithToken( - EcssTmtcErrorWithSend::SendError(e), - sendable.token.unwrap(), - ) - })?; + .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?; sendable.send_success_verif_failure(); Ok(()) } @@ -590,7 +580,7 @@ impl VerificationReporterCore { ) } - pub fn send_start_success( + pub fn send_start_success( &self, mut sendable: VerificationSendable<'_, TcStateAccepted, VerifSuccess>, sender: &mut (impl EcssTmSenderCore + ?Sized), @@ -598,12 +588,7 @@ impl VerificationReporterCore { { sender .send_tm(sendable.pus_tm.take().unwrap().into()) - .map_err(|e| { - VerificationOrSendErrorWithToken( - EcssTmtcErrorWithSend::SendError(e), - sendable.token.unwrap(), - ) - })?; + .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?; Ok(sendable.send_success_start_success()) } @@ -633,19 +618,14 @@ impl VerificationReporterCore { ) } - pub fn send_start_failure( + pub fn send_start_failure( &self, mut sendable: VerificationSendable<'_, TcStateAccepted, VerifFailure>, sender: &mut (impl EcssTmSenderCore + ?Sized), ) -> Result<(), VerificationOrSendErrorWithToken> { sender .send_tm(sendable.pus_tm.take().unwrap().into()) - .map_err(|e| { - VerificationOrSendErrorWithToken( - EcssTmtcErrorWithSend::SendError(e), - sendable.token.unwrap(), - ) - })?; + .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?; sendable.send_success_verif_failure(); Ok(()) } @@ -764,12 +744,7 @@ impl VerificationReporterCore { ) -> Result<(), VerificationOrSendErrorWithToken> { sender .send_tm(sendable.pus_tm.take().unwrap().into()) - .map_err(|e| { - VerificationOrSendErrorWithToken( - EcssTmtcErrorWithSend::SendError(e), - sendable.token.unwrap(), - ) - })?; + .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?; sendable.send_success_step_or_completion_success(); Ok(()) } @@ -781,12 +756,7 @@ impl VerificationReporterCore { ) -> Result<(), VerificationOrSendErrorWithToken> { sender .send_tm(sendable.pus_tm.take().unwrap().into()) - .map_err(|e| { - VerificationOrSendErrorWithToken( - EcssTmtcErrorWithSend::SendError(e), - sendable.token.unwrap(), - ) - })?; + .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?; sendable.send_success_verif_failure(); Ok(()) } @@ -858,7 +828,8 @@ impl VerificationReporterCore { } params .failure_code - .write_to_be_bytes(&mut src_data_buf[idx..idx + params.failure_code.size()])?; + .write_to_be_bytes(&mut src_data_buf[idx..idx + params.failure_code.size()]) + .map_err(PusError::ByteConversionError)?; idx += params.failure_code.size(); if let Some(failure_data) = params.failure_data { src_data_buf[idx..idx + failure_data.len()].copy_from_slice(failure_data); @@ -1001,7 +972,7 @@ mod alloc_mod { } /// Package and send a PUS TM\[1, 2\] packet, see 8.1.2.2 of the PUS standard - pub fn acceptance_failure( + pub fn acceptance_failure( &mut self, token: VerificationToken, sender: &mut (impl EcssTmSenderCore + ?Sized), @@ -1028,7 +999,7 @@ mod alloc_mod { /// Package and send a PUS TM\[1, 3\] packet, see 8.1.2.3 of the PUS standard. /// /// Requires a token previously acquired by calling [Self::acceptance_success]. - pub fn start_success( + pub fn start_success( &mut self, token: VerificationToken, sender: &mut (impl EcssTmSenderCore + ?Sized), @@ -1059,7 +1030,7 @@ mod alloc_mod { /// /// Requires a token previously acquired by calling [Self::acceptance_success]. It consumes /// the token because verification handling is done. - pub fn start_failure( + pub fn start_failure( &mut self, token: VerificationToken, sender: &mut (impl EcssTmSenderCore + ?Sized), @@ -1086,7 +1057,7 @@ mod alloc_mod { /// Package and send a PUS TM\[1, 5\] packet, see 8.1.2.5 of the PUS standard. /// /// Requires a token previously acquired by calling [Self::start_success]. - pub fn step_success( + pub fn step_success( &mut self, token: &VerificationToken, sender: &mut (impl EcssTmSenderCore + ?Sized), @@ -1118,7 +1089,7 @@ mod alloc_mod { /// /// Requires a token previously acquired by calling [Self::start_success]. It consumes the /// token because verification handling is done. - pub fn step_failure( + pub fn step_failure( &mut self, token: VerificationToken, sender: &mut (impl EcssTmSenderCore + ?Sized), From 1f4e6714bacf132c9b2813bf1112e45e7659f542 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 9 Jul 2023 13:32:59 +0200 Subject: [PATCH 03/11] try to use new abstractions --- satrs-core/src/pus/event_srv.rs | 17 +++------ satrs-core/src/pus/mod.rs | 55 ++++++++++++++--------------- satrs-core/src/pus/scheduler_srv.rs | 16 +++------ satrs-core/src/pus/test.rs | 28 ++++----------- 4 files changed, 44 insertions(+), 72 deletions(-) diff --git a/satrs-core/src/pus/event_srv.rs b/satrs-core/src/pus/event_srv.rs index 0ff81ee..5e714e2 100644 --- a/satrs-core/src/pus/event_srv.rs +++ b/satrs-core/src/pus/event_srv.rs @@ -5,13 +5,14 @@ use crate::pus::verification::{ StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken, }; use crate::pus::{ - AcceptedTc, PartialPusHandlingError, PusPacketHandlerResult, PusPacketHandlingError, - PusServiceBase, PusServiceHandler, + AcceptedTc, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, + PusPacketHandlingError, PusServiceBase, PusServiceHandler, }; use crate::tmtc::tm_helper::SharedTmStore; use spacepackets::ecss::event::Subservice; use spacepackets::ecss::PusPacket; use spacepackets::tc::PusTc; +use std::boxed::Box; use std::sync::mpsc::{Receiver, Sender}; pub struct PusService5EventHandler { @@ -23,21 +24,13 @@ impl PusService5EventHandler { pub fn new( receiver: Receiver, tc_pool: SharedPool, - tm_tx: Sender, - tm_store: SharedTmStore, + tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, event_request_tx: Sender, ) -> Self { Self { - psb: PusServiceBase::new( - receiver, - tc_pool, - tm_tx, - tm_store, - tm_apid, - verification_handler, - ), + psb: PusServiceBase::new(receiver, tc_pool, tm_sender, tm_apid, verification_handler), event_request_tx, } } diff --git a/satrs-core/src/pus/mod.rs b/satrs-core/src/pus/mod.rs index 574b40e..4e19e28 100644 --- a/satrs-core/src/pus/mod.rs +++ b/satrs-core/src/pus/mod.rs @@ -9,6 +9,7 @@ use downcast_rs::{impl_downcast, Downcast}; #[cfg(feature = "alloc")] use dyn_clone::DynClone; use spacepackets::ecss::PusError; +use spacepackets::tc::PusTc; use spacepackets::tm::PusTm; use spacepackets::{ByteConversionError, SizeMissmatch}; use std::error::Error; @@ -28,6 +29,7 @@ pub mod verification; pub use alloc_mod::*; use crate::pool::{StoreAddr, StoreError}; +use crate::pus::verification::TcStateToken; #[cfg(feature = "std")] pub use std_mod::*; @@ -140,6 +142,21 @@ pub trait EcssSender: Send { } } +/// Generic trait for a user supplied sender object. +/// +/// This sender object is responsible for sending PUS telemetry to a TM sink. +pub trait EcssTmSenderCore: EcssSender { + fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcErrorWithSend>; +} + +/// Generic trait for a user supplied sender object. +/// +/// This sender object is responsible for sending PUS telecommands to a TC recipient. Each +/// telecommand can optionally have a token which contains its verification state. +pub trait EcssTcSenderCore: EcssSender { + fn send_tc(&self, tc: PusTc, token: Option) -> Result<(), EcssTmtcErrorWithSend>; +} + #[cfg(feature = "alloc")] mod alloc_mod { use super::*; @@ -191,9 +208,13 @@ pub mod std_mod { use crate::pus::verification::{ StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken, }; - use crate::pus::{EcssSender, EcssTmtcErrorWithSend, GenericSendError, PusTmWrapper}; + use crate::pus::{ + EcssSender, EcssTmSender, EcssTmSenderCore, EcssTmtcErrorWithSend, GenericSendError, + PusTmWrapper, + }; use crate::tmtc::tm_helper::SharedTmStore; use crate::SenderId; + use alloc::boxed::Box; use alloc::vec::Vec; use spacepackets::ecss::{PusError, SerializablePusPacket}; use spacepackets::tc::PusTc; @@ -206,25 +227,6 @@ pub mod std_mod { use std::sync::{mpsc, RwLockWriteGuard}; use thiserror::Error; - /// Generic trait for a user supplied sender object. - /// - /// This sender object is responsible for sending PUS telemetry to a TM sink. - pub trait EcssTmSenderCore: EcssSender { - fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcErrorWithSend>; - } - - /// Generic trait for a user supplied sender object. - /// - /// This sender object is responsible for sending PUS telecommands to a TC recipient. Each - /// telecommand can optionally have a token which contains its verification state. - pub trait EcssTcSenderCore: EcssSender { - fn send_tc( - &self, - tc: PusTc, - token: Option, - ) -> Result<(), EcssTmtcErrorWithSend>; - } - #[derive(Clone)] pub struct MpscTmInStoreSender { id: SenderId, @@ -375,9 +377,9 @@ pub mod std_mod { #[derive(Debug, Clone, Error)] pub enum PartialPusHandlingError { #[error("Generic timestamp generation error")] - Time(StdTimestampError), + Time(#[from] StdTimestampError), #[error("Error sending telemetry: {0}")] - TmSend(String), + TmSend(#[from] EcssTmtcErrorWithSend), #[error("Error sending verification message")] Verification, } @@ -408,8 +410,7 @@ pub mod std_mod { pub struct PusServiceBase { pub tc_rx: mpsc::Receiver, pub tc_store: SharedPool, - pub tm_tx: mpsc::Sender, - pub tm_store: SharedTmStore, + pub tm_sender: Box, pub tm_apid: u16, /// The verification handler is wrapped in a [RefCell] to allow the interior mutability /// pattern. This makes writing methods which are not mutable a lot easier. @@ -422,8 +423,7 @@ pub mod std_mod { pub fn new( receiver: mpsc::Receiver, tc_pool: SharedPool, - tm_tx: mpsc::Sender, - tm_store: SharedTmStore, + tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, ) -> Self { @@ -431,8 +431,7 @@ pub mod std_mod { tc_rx: receiver, tc_store: tc_pool, tm_apid, - tm_tx, - tm_store, + tm_sender, verification_handler: RefCell::new(verification_handler), pus_buf: [0; 2048], pus_size: 0, diff --git a/satrs-core/src/pus/scheduler_srv.rs b/satrs-core/src/pus/scheduler_srv.rs index 87f0830..94cb90b 100644 --- a/satrs-core/src/pus/scheduler_srv.rs +++ b/satrs-core/src/pus/scheduler_srv.rs @@ -2,12 +2,14 @@ use crate::pool::{SharedPool, StoreAddr}; use crate::pus::scheduler::PusScheduler; use crate::pus::verification::{StdVerifReporterWithSender, TcStateAccepted, VerificationToken}; use crate::pus::{ - AcceptedTc, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, PusServiceHandler, + AcceptedTc, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, + PusServiceHandler, }; use crate::tmtc::tm_helper::SharedTmStore; use spacepackets::ecss::{scheduling, PusPacket}; use spacepackets::tc::PusTc; use spacepackets::time::cds::TimeProvider; +use std::boxed::Box; use std::sync::mpsc::{Receiver, Sender}; /// This is a helper class for [std] environments to handle generic PUS 11 (scheduling service) @@ -27,21 +29,13 @@ impl PusService11SchedHandler { pub fn new( receiver: Receiver, tc_pool: SharedPool, - tm_tx: Sender, - tm_store: SharedTmStore, + tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, scheduler: PusScheduler, ) -> Self { Self { - psb: PusServiceBase::new( - receiver, - tc_pool, - tm_tx, - tm_store, - tm_apid, - verification_handler, - ), + psb: PusServiceBase::new(receiver, tc_pool, tm_sender, tm_apid, verification_handler), scheduler, } } diff --git a/satrs-core/src/pus/test.rs b/satrs-core/src/pus/test.rs index 0e596fa..6269767 100644 --- a/satrs-core/src/pus/test.rs +++ b/satrs-core/src/pus/test.rs @@ -1,14 +1,15 @@ use crate::pool::{SharedPool, StoreAddr}; use crate::pus::verification::{StdVerifReporterWithSender, TcStateAccepted, VerificationToken}; use crate::pus::{ - AcceptedTc, PartialPusHandlingError, PusPacketHandlerResult, PusPacketHandlingError, - PusServiceBase, PusServiceHandler, + AcceptedTc, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, + PusPacketHandlingError, PusServiceBase, PusServiceHandler, PusTmWrapper, }; use crate::tmtc::tm_helper::SharedTmStore; use spacepackets::ecss::PusPacket; use spacepackets::tc::PusTc; use spacepackets::tm::{PusTm, PusTmSecondaryHeader}; use spacepackets::SpHeader; +use std::boxed::Box; use std::format; use std::sync::mpsc::{Receiver, Sender}; @@ -22,20 +23,12 @@ impl PusService17TestHandler { pub fn new( receiver: Receiver, tc_pool: SharedPool, - tm_tx: Sender, - tm_store: SharedTmStore, + tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, ) -> Self { Self { - psb: PusServiceBase::new( - receiver, - tc_pool, - tm_tx, - tm_store, - tm_apid, - verification_handler, - ), + psb: PusServiceBase::new(receiver, tc_pool, tm_sender, tm_apid, verification_handler), } } } @@ -77,15 +70,8 @@ impl PusServiceHandler for PusService17TestHandler { let mut reply_header = SpHeader::tm_unseg(self.psb.tm_apid, 0, 0).unwrap(); let tc_header = PusTmSecondaryHeader::new_simple(17, 2, &time_stamp); let ping_reply = PusTm::new(&mut reply_header, tc_header, None, true); - let addr = self.psb.tm_store.add_pus_tm(&ping_reply); - if let Err(e) = self - .psb - .tm_tx - .send(addr) - .map_err(|e| PartialPusHandlingError::TmSend(format!("{e}"))) - { - partial_error = Some(e); - } + let result = self.psb.tm_sender.send_tm(PusTmWrapper::Direct(ping_reply)); + if let Some(start_token) = start_token { if self .psb From 2783442f91b2d51e6451a951653b38e3e8744812 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 9 Jul 2023 17:04:18 +0200 Subject: [PATCH 04/11] use new sender abstraction --- satrs-core/Cargo.toml | 6 ++-- satrs-core/src/pus/event_srv.rs | 1 - satrs-core/src/pus/mod.rs | 7 ++-- satrs-core/src/pus/scheduler_srv.rs | 3 +- satrs-core/src/pus/test.rs | 13 +++++--- satrs-example/src/lib.rs | 11 ++++++ satrs-example/src/main.rs | 52 ++++++++++++++++++++++------- satrs-example/src/pus/action.rs | 16 +++------ satrs-example/src/pus/hk.rs | 16 +++------ 9 files changed, 75 insertions(+), 50 deletions(-) diff --git a/satrs-core/Cargo.toml b/satrs-core/Cargo.toml index 895be4f..687340c 100644 --- a/satrs-core/Cargo.toml +++ b/satrs-core/Cargo.toml @@ -61,10 +61,10 @@ default-features = false optional = true [dependencies.spacepackets] -version = "0.6" +# version = "0.6" # path = "../spacepackets" -# git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git" -# rev = "4485ed26699d32" +git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git" +rev = "4969d6c33c6" default-features = false [dev-dependencies] diff --git a/satrs-core/src/pus/event_srv.rs b/satrs-core/src/pus/event_srv.rs index 5e714e2..dee2747 100644 --- a/satrs-core/src/pus/event_srv.rs +++ b/satrs-core/src/pus/event_srv.rs @@ -8,7 +8,6 @@ use crate::pus::{ AcceptedTc, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, PusServiceHandler, }; -use crate::tmtc::tm_helper::SharedTmStore; use spacepackets::ecss::event::Subservice; use spacepackets::ecss::PusPacket; use spacepackets::tc::PusTc; diff --git a/satrs-core/src/pus/mod.rs b/satrs-core/src/pus/mod.rs index 4e19e28..117dc08 100644 --- a/satrs-core/src/pus/mod.rs +++ b/satrs-core/src/pus/mod.rs @@ -206,20 +206,19 @@ mod alloc_mod { pub mod std_mod { use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError}; use crate::pus::verification::{ - StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken, + StdVerifReporterWithSender, TcStateAccepted, VerificationToken, }; use crate::pus::{ EcssSender, EcssTmSender, EcssTmSenderCore, EcssTmtcErrorWithSend, GenericSendError, PusTmWrapper, }; - use crate::tmtc::tm_helper::SharedTmStore; use crate::SenderId; use alloc::boxed::Box; use alloc::vec::Vec; use spacepackets::ecss::{PusError, SerializablePusPacket}; - use spacepackets::tc::PusTc; use spacepackets::time::cds::TimeProvider; - use spacepackets::time::{StdTimestampError, TimeWriter}; + use spacepackets::time::std_mod::StdTimestampError; + use spacepackets::time::TimeWriter; use std::cell::RefCell; use std::format; use std::string::String; diff --git a/satrs-core/src/pus/scheduler_srv.rs b/satrs-core/src/pus/scheduler_srv.rs index 94cb90b..0b72feb 100644 --- a/satrs-core/src/pus/scheduler_srv.rs +++ b/satrs-core/src/pus/scheduler_srv.rs @@ -5,12 +5,11 @@ use crate::pus::{ AcceptedTc, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, PusServiceHandler, }; -use crate::tmtc::tm_helper::SharedTmStore; use spacepackets::ecss::{scheduling, PusPacket}; use spacepackets::tc::PusTc; use spacepackets::time::cds::TimeProvider; use std::boxed::Box; -use std::sync::mpsc::{Receiver, Sender}; +use std::sync::mpsc::Receiver; /// This is a helper class for [std] environments to handle generic PUS 11 (scheduling service) /// packets. This handler is constrained to using the [PusScheduler], but is able to process diff --git a/satrs-core/src/pus/test.rs b/satrs-core/src/pus/test.rs index 6269767..ced2461 100644 --- a/satrs-core/src/pus/test.rs +++ b/satrs-core/src/pus/test.rs @@ -4,14 +4,12 @@ use crate::pus::{ AcceptedTc, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, PusServiceHandler, PusTmWrapper, }; -use crate::tmtc::tm_helper::SharedTmStore; use spacepackets::ecss::PusPacket; use spacepackets::tc::PusTc; use spacepackets::tm::{PusTm, PusTmSecondaryHeader}; use spacepackets::SpHeader; use std::boxed::Box; -use std::format; -use std::sync::mpsc::{Receiver, Sender}; +use std::sync::mpsc::Receiver; /// This is a helper class for [std] environments to handle generic PUS 17 (test service) packets. /// This handler only processes ping requests and generates a ping reply for them accordingly. @@ -70,7 +68,14 @@ impl PusServiceHandler for PusService17TestHandler { let mut reply_header = SpHeader::tm_unseg(self.psb.tm_apid, 0, 0).unwrap(); let tc_header = PusTmSecondaryHeader::new_simple(17, 2, &time_stamp); let ping_reply = PusTm::new(&mut reply_header, tc_header, None, true); - let result = self.psb.tm_sender.send_tm(PusTmWrapper::Direct(ping_reply)); + let result = self + .psb + .tm_sender + .send_tm(PusTmWrapper::Direct(ping_reply)) + .map_err(PartialPusHandlingError::TmSend); + if let Err(err) = result { + partial_error = Some(err); + } if let Some(start_token) = start_token { if self diff --git a/satrs-example/src/lib.rs b/satrs-example/src/lib.rs index 754be9b..0e77dad 100644 --- a/satrs-example/src/lib.rs +++ b/satrs-example/src/lib.rs @@ -73,3 +73,14 @@ pub mod hk_err { #[resultcode] pub const COLLECTION_INTERVAL_MISSING: ResultU16 = ResultU16::const_new(GroupId::Hk as u8, 3); } + +#[allow(clippy::enum_variant_names)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum TmSenderId { + PusVerification = 0, + PusTest = 1, + PusEvent = 2, + PusHk = 3, + PusAction = 4, + PusSched = 5, +} diff --git a/satrs-example/src/main.rs b/satrs-example/src/main.rs index 85346c3..f29f95a 100644 --- a/satrs-example/src/main.rs +++ b/satrs-example/src/main.rs @@ -44,7 +44,8 @@ use satrs_core::spacepackets::{ }; use satrs_core::tmtc::tm_helper::SharedTmStore; use satrs_core::tmtc::{AddressableId, TargetId}; -use satrs_example::{RequestTargetId, OBSW_SERVER_ADDR, SERVER_PORT}; +use satrs_core::SenderId; +use satrs_example::{RequestTargetId, TmSenderId, OBSW_SERVER_ADDR, SERVER_PORT}; use std::collections::HashMap; use std::net::{IpAddr, SocketAddr}; use std::sync::mpsc::{channel, TryRecvError}; @@ -84,7 +85,7 @@ fn main() { let (tm_funnel_tx, tm_funnel_rx) = channel(); let (tm_server_tx, tm_server_rx) = channel(); let verif_sender = MpscTmInStoreSender::new( - 0, + TmSenderId::PusVerification as SenderId, "verif_sender", tm_store.backing_pool(), tm_funnel_tx.clone(), @@ -154,11 +155,16 @@ fn main() { hk_service_receiver: pus_hk_tx, action_service_receiver: pus_action_tx, }; + let test_srv_tm_sender = MpscTmInStoreSender::new( + TmSenderId::PusTest as SenderId, + "PUS_17_TM_SENDER", + tm_store.backing_pool().clone(), + tm_funnel_tx.clone(), + ); let pus17_handler = PusService17TestHandler::new( pus_test_rx, tc_store.pool.clone(), - tm_funnel_tx.clone(), - tm_store.clone(), + Box::new(test_srv_tm_sender), PUS_APID, verif_reporter.clone(), ); @@ -166,13 +172,19 @@ fn main() { pus17_handler, test_srv_event_sender, }; + + let sched_srv_tm_sender = MpscTmInStoreSender::new( + TmSenderId::PusSched as SenderId, + "PUS_11_TM_SENDER", + tm_store.backing_pool().clone(), + tm_funnel_tx.clone(), + ); let scheduler = PusScheduler::new_with_current_init_time(Duration::from_secs(5)) .expect("Creating PUS Scheduler failed"); let pus_11_handler = PusService11SchedHandler::new( pus_sched_rx, tc_store.pool.clone(), - tm_funnel_tx.clone(), - tm_store.clone(), + Box::new(sched_srv_tm_sender), PUS_APID, verif_reporter.clone(), scheduler, @@ -181,33 +193,49 @@ fn main() { pus_11_handler, tc_source_wrapper, }; + + let event_srv_tm_sender = MpscTmInStoreSender::new( + TmSenderId::PusEvent as SenderId, + "PUS_5_TM_SENDER", + tm_store.backing_pool().clone(), + tm_funnel_tx.clone(), + ); let pus_5_handler = PusService5EventHandler::new( pus_event_rx, tc_store.pool.clone(), - tm_funnel_tx.clone(), - tm_store.clone(), + Box::new(event_srv_tm_sender), PUS_APID, verif_reporter.clone(), event_request_tx, ); let mut pus_5_wrapper = Pus5Wrapper { pus_5_handler }; + let action_srv_tm_sender = MpscTmInStoreSender::new( + TmSenderId::PusAction as SenderId, + "PUS_8_TM_SENDER", + tm_store.backing_pool().clone(), + tm_funnel_tx.clone(), + ); let pus_8_handler = PusService8ActionHandler::new( pus_action_rx, tc_store.pool.clone(), - tm_funnel_tx.clone(), - tm_store.clone(), + Box::new(action_srv_tm_sender), PUS_APID, verif_reporter.clone(), request_map.clone(), ); let mut pus_8_wrapper = Pus8Wrapper { pus_8_handler }; + let hk_srv_tm_sender = MpscTmInStoreSender::new( + TmSenderId::PusHk as SenderId, + "PUS_3_TM_SENDER", + tm_store.backing_pool().clone(), + tm_funnel_tx.clone(), + ); let pus_3_handler = PusService3HkHandler::new( pus_hk_rx, tc_store.pool.clone(), - tm_funnel_tx.clone(), - tm_store.clone(), + Box::new(hk_srv_tm_sender), PUS_APID, verif_reporter.clone(), request_map, diff --git a/satrs-example/src/pus/action.rs b/satrs-example/src/pus/action.rs index 0975c79..ed69c35 100644 --- a/satrs-example/src/pus/action.rs +++ b/satrs-example/src/pus/action.rs @@ -5,11 +5,11 @@ use satrs_core::pus::verification::{ FailParams, StdVerifReporterWithSender, TcStateAccepted, VerificationToken, }; use satrs_core::pus::{ - AcceptedTc, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, PusServiceHandler, + AcceptedTc, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, + PusServiceHandler, }; use satrs_core::spacepackets::ecss::PusPacket; use satrs_core::spacepackets::tc::PusTc; -use satrs_core::tmtc::tm_helper::SharedTmStore; use satrs_core::tmtc::TargetId; use satrs_example::tmtc_err; use std::collections::HashMap; @@ -24,21 +24,13 @@ impl PusService8ActionHandler { pub fn new( receiver: Receiver, tc_pool: SharedPool, - tm_tx: Sender, - tm_store: SharedTmStore, + tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, request_handlers: HashMap>, ) -> Self { Self { - psb: PusServiceBase::new( - receiver, - tc_pool, - tm_tx, - tm_store, - tm_apid, - verification_handler, - ), + psb: PusServiceBase::new(receiver, tc_pool, tm_sender, tm_apid, verification_handler), request_handlers, } } diff --git a/satrs-example/src/pus/hk.rs b/satrs-example/src/pus/hk.rs index 56e0b4b..a56ed6b 100644 --- a/satrs-example/src/pus/hk.rs +++ b/satrs-example/src/pus/hk.rs @@ -6,11 +6,11 @@ use satrs_core::pus::verification::{ FailParams, StdVerifReporterWithSender, TcStateAccepted, VerificationToken, }; use satrs_core::pus::{ - AcceptedTc, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, PusServiceHandler, + AcceptedTc, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, + PusServiceHandler, }; use satrs_core::spacepackets::ecss::{hk, PusPacket}; use satrs_core::spacepackets::tc::PusTc; -use satrs_core::tmtc::tm_helper::SharedTmStore; use satrs_core::tmtc::{AddressableId, TargetId}; use satrs_example::{hk_err, tmtc_err}; use std::collections::HashMap; @@ -25,21 +25,13 @@ impl PusService3HkHandler { pub fn new( receiver: Receiver, tc_pool: SharedPool, - tm_tx: Sender, - tm_store: SharedTmStore, + tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, request_handlers: HashMap>, ) -> Self { Self { - psb: PusServiceBase::new( - receiver, - tc_pool, - tm_tx, - tm_store, - tm_apid, - verification_handler, - ), + psb: PusServiceBase::new(receiver, tc_pool, tm_sender, tm_apid, verification_handler), request_handlers, } } From 16d495aa5cd385b8e66ecae98703c70f3cdc5001 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 9 Jul 2023 18:31:56 +0200 Subject: [PATCH 05/11] remove some more muts --- satrs-core/src/event_man.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/satrs-core/src/event_man.rs b/satrs-core/src/event_man.rs index c556e99..3fb8d68 100644 --- a/satrs-core/src/event_man.rs +++ b/satrs-core/src/event_man.rs @@ -89,14 +89,10 @@ pub trait SendEventProvider { type Error; fn id(&self) -> SenderId; - fn send_no_data(&mut self, event: Provider) -> Result<(), Self::Error> { + fn send_no_data(&self, event: Provider) -> Result<(), Self::Error> { self.send(event, None) } - fn send( - &mut self, - event: Provider, - aux_data: Option, - ) -> Result<(), Self::Error>; + fn send(&self, event: Provider, aux_data: Option) -> Result<(), Self::Error>; } /// Generic abstraction for an event receiver. @@ -107,7 +103,7 @@ pub trait EventReceiver { /// To allow returning arbitrary additional auxiliary data, a mutable slice is passed to the /// [Self::receive] call as well. Receivers can write data to this slice, but care must be taken /// to avoid panics due to size missmatches or out of bound writes. - fn receive(&mut self) -> Option<(Event, Option)>; + fn receive(&self) -> Option<(Event, Option)>; } pub trait ListenerTable { @@ -424,7 +420,7 @@ pub mod stdmod { } } impl EventReceiver for MpscEventReceiver { - fn receive(&mut self) -> Option> { + fn receive(&self) -> Option> { if let Ok(event_and_data) = self.mpsc_receiver.try_recv() { return Some(event_and_data); } @@ -453,7 +449,7 @@ pub mod stdmod { fn id(&self) -> u32 { self.id } - fn send(&mut self, event: Event, aux_data: Option) -> Result<(), Self::Error> { + fn send(&self, event: Event, aux_data: Option) -> Result<(), Self::Error> { self.sender.send((event, aux_data)) } } From 180e77039294873ec274b42f6a01631e4731243b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 9 Jul 2023 18:38:09 +0200 Subject: [PATCH 06/11] moved a trait --- satrs-core/src/pus/mod.rs | 10 +++++++++- satrs-core/src/tmtc/mod.rs | 9 --------- satrs-core/src/tmtc/pus_distrib.rs | 3 ++- satrs-example/src/tmtc.rs | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/satrs-core/src/pus/mod.rs b/satrs-core/src/pus/mod.rs index 117dc08..4160f0a 100644 --- a/satrs-core/src/pus/mod.rs +++ b/satrs-core/src/pus/mod.rs @@ -11,7 +11,7 @@ use dyn_clone::DynClone; use spacepackets::ecss::PusError; use spacepackets::tc::PusTc; use spacepackets::tm::PusTm; -use spacepackets::{ByteConversionError, SizeMissmatch}; +use spacepackets::{ByteConversionError, SizeMissmatch, SpHeader}; use std::error::Error; pub mod event; @@ -202,6 +202,14 @@ mod alloc_mod { impl_downcast!(EcssTcSender); } +/// Generic trait for objects which can receive ECSS PUS telecommands. This trait is +/// implemented by the [crate::tmtc::pus_distrib::PusDistributor] objects to allow passing PUS TC +/// packets into it. +pub trait ReceivesEcssPusTc { + type Error; + fn pass_pus_tc(&mut self, header: &SpHeader, pus_tc: &PusTc) -> Result<(), Self::Error>; +} + #[cfg(feature = "std")] pub mod std_mod { use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError}; diff --git a/satrs-core/src/tmtc/mod.rs b/satrs-core/src/tmtc/mod.rs index c2a0aa6..5d5f306 100644 --- a/satrs-core/src/tmtc/mod.rs +++ b/satrs-core/src/tmtc/mod.rs @@ -9,7 +9,6 @@ use downcast_rs::{impl_downcast, Downcast}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use spacepackets::tc::PusTc; use spacepackets::{ByteConversionError, SizeMissmatch, SpHeader}; #[cfg(feature = "alloc")] @@ -93,11 +92,3 @@ pub trait ReceivesCcsdsTc { type Error; fn pass_ccsds(&mut self, header: &SpHeader, tc_raw: &[u8]) -> Result<(), Self::Error>; } - -/// Generic trait for objects which can receive ECSS PUS telecommands. This trait is -/// implemented by the [crate::tmtc::pus_distrib::PusDistributor] objects to allow passing PUS TC -/// packets into it. -pub trait ReceivesEcssPusTc { - type Error; - fn pass_pus_tc(&mut self, header: &SpHeader, pus_tc: &PusTc) -> Result<(), Self::Error>; -} diff --git a/satrs-core/src/tmtc/pus_distrib.rs b/satrs-core/src/tmtc/pus_distrib.rs index bf591da..88b8f1f 100644 --- a/satrs-core/src/tmtc/pus_distrib.rs +++ b/satrs-core/src/tmtc/pus_distrib.rs @@ -61,7 +61,8 @@ //! .expect("Casting back to concrete type failed"); //! assert_eq!(concrete_handler_ref.handler_call_count, 1); //! ``` -use crate::tmtc::{ReceivesCcsdsTc, ReceivesEcssPusTc, ReceivesTcCore}; +use crate::pus::ReceivesEcssPusTc; +use crate::tmtc::{ReceivesCcsdsTc, ReceivesTcCore}; use alloc::boxed::Box; use core::fmt::{Display, Formatter}; use downcast_rs::Downcast; diff --git a/satrs-example/src/tmtc.rs b/satrs-example/src/tmtc.rs index 864b40b..95b9590 100644 --- a/satrs-example/src/tmtc.rs +++ b/satrs-example/src/tmtc.rs @@ -10,12 +10,12 @@ use crate::ccsds::CcsdsReceiver; use crate::pus::{PusReceiver, PusTcMpscRouter}; use satrs_core::pool::{SharedPool, StoreAddr, StoreError}; use satrs_core::pus::verification::StdVerifReporterWithSender; -use satrs_core::pus::AcceptedTc; +use satrs_core::pus::{AcceptedTc, ReceivesEcssPusTc}; use satrs_core::spacepackets::ecss::{PusPacket, SerializablePusPacket}; use satrs_core::spacepackets::tc::PusTc; use satrs_core::spacepackets::SpHeader; use satrs_core::tmtc::tm_helper::SharedTmStore; -use satrs_core::tmtc::{CcsdsDistributor, CcsdsError, ReceivesCcsdsTc, ReceivesEcssPusTc}; +use satrs_core::tmtc::{CcsdsDistributor, CcsdsError, ReceivesCcsdsTc}; pub const PUS_APID: u16 = 0x02; From e46b88384f9935e7e95ccb9f4873ca19226b7a55 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 9 Jul 2023 20:05:45 +0200 Subject: [PATCH 07/11] getting there.. --- satrs-core/Cargo.toml | 2 +- satrs-core/src/pus/event.rs | 32 +-- satrs-core/src/pus/event_man.rs | 8 +- satrs-core/src/pus/event_srv.rs | 26 ++- satrs-core/src/pus/mod.rs | 320 ++++++++++++++++++---------- satrs-core/src/pus/scheduler_srv.rs | 19 +- satrs-core/src/pus/test.rs | 12 +- satrs-core/src/pus/verification.rs | 70 +++--- satrs-core/src/tmtc/pus_distrib.rs | 2 +- satrs-core/src/tmtc/tm_helper.rs | 18 +- satrs-example/src/main.rs | 34 ++- satrs-example/src/pus/action.rs | 2 +- 12 files changed, 326 insertions(+), 219 deletions(-) diff --git a/satrs-core/Cargo.toml b/satrs-core/Cargo.toml index 687340c..41e977e 100644 --- a/satrs-core/Cargo.toml +++ b/satrs-core/Cargo.toml @@ -64,7 +64,7 @@ optional = true # version = "0.6" # path = "../spacepackets" git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git" -rev = "4969d6c33c6" +rev = "e3d2d885385" default-features = false [dev-dependencies] diff --git a/satrs-core/src/pus/event.rs b/satrs-core/src/pus/event.rs index 5ab85f7..b1faf74 100644 --- a/satrs-core/src/pus/event.rs +++ b/satrs-core/src/pus/event.rs @@ -1,4 +1,4 @@ -use crate::pus::{source_buffer_large_enough, EcssTmtcErrorWithSend}; +use crate::pus::{source_buffer_large_enough, EcssTmtcError}; use spacepackets::ecss::{EcssEnumeration, PusError}; use spacepackets::tm::PusTm; use spacepackets::tm::PusTmSecondaryHeader; @@ -34,7 +34,7 @@ impl EventReporterBase { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcError> { self.generate_and_send_generic_tm( buf, Subservice::TmInfoReport, @@ -52,7 +52,7 @@ impl EventReporterBase { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcError> { self.generate_and_send_generic_tm( buf, Subservice::TmLowSeverityReport, @@ -70,7 +70,7 @@ impl EventReporterBase { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcError> { self.generate_and_send_generic_tm( buf, Subservice::TmMediumSeverityReport, @@ -88,7 +88,7 @@ impl EventReporterBase { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcError> { self.generate_and_send_generic_tm( buf, Subservice::TmHighSeverityReport, @@ -107,7 +107,7 @@ impl EventReporterBase { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcError> { let tm = self.generate_generic_event_tm(buf, subservice, time_stamp, event_id, aux_data)?; sender.send_tm(tm.into())?; self.msg_count += 1; @@ -121,7 +121,7 @@ impl EventReporterBase { time_stamp: &'a [u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result { + ) -> Result { let mut src_data_len = event_id.size(); if let Some(aux_data) = aux_data { src_data_len += aux_data.len(); @@ -138,7 +138,7 @@ impl EventReporterBase { let mut current_idx = 0; event_id .write_to_be_bytes(&mut buf[0..event_id.size()]) - .map_err(PusError::ByteConversionError)?; + .map_err(PusError::ByteConversion)?; current_idx += event_id.size(); if let Some(aux_data) = aux_data { buf[current_idx..current_idx + aux_data.len()].copy_from_slice(aux_data); @@ -178,7 +178,7 @@ mod alloc_mod { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcError> { self.reporter.event_info( self.source_data_buf.as_mut_slice(), sender, @@ -194,7 +194,7 @@ mod alloc_mod { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcError> { self.reporter.event_low_severity( self.source_data_buf.as_mut_slice(), sender, @@ -210,7 +210,7 @@ mod alloc_mod { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcError> { self.reporter.event_medium_severity( self.source_data_buf.as_mut_slice(), sender, @@ -226,7 +226,7 @@ mod alloc_mod { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcError> { self.reporter.event_high_severity( self.source_data_buf.as_mut_slice(), sender, @@ -243,7 +243,7 @@ mod tests { use super::*; use crate::events::{EventU32, Severity}; use crate::pus::tests::CommonTmInfo; - use crate::pus::{EcssSender, PusTmWrapper}; + use crate::pus::{EcssChannel, PusTmWrapper}; use crate::SenderId; use spacepackets::ByteConversionError; use std::cell::RefCell; @@ -268,14 +268,14 @@ mod tests { pub service_queue: RefCell>, } - impl EcssSender for TestSender { + impl EcssChannel for TestSender { fn id(&self) -> SenderId { 0 } } impl EcssTmSenderCore for TestSender { - fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcErrorWithSend> { + fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcError> { match tm { PusTmWrapper::InStore(_) => { panic!("TestSender: unexpected call with address"); @@ -425,7 +425,7 @@ mod tests { let err = reporter.event_info(sender, &time_stamp_empty, event, None); assert!(err.is_err()); let err = err.unwrap_err(); - if let EcssTmtcErrorWithSend::EcssTmtcError(EcssTmtcErrorWithSend::ByteConversion( + if let EcssTmtcError::EcssTmtcError(EcssTmtcError::ByteConversion( ByteConversionError::ToSliceTooSmall(missmatch), )) = err { diff --git a/satrs-core/src/pus/event_man.rs b/satrs-core/src/pus/event_man.rs index f3231b4..4c9b6d8 100644 --- a/satrs-core/src/pus/event_man.rs +++ b/satrs-core/src/pus/event_man.rs @@ -13,7 +13,7 @@ pub use crate::pus::event::EventReporter; use crate::pus::verification::TcStateToken; #[cfg(feature = "alloc")] use crate::pus::EcssTmSenderCore; -use crate::pus::EcssTmtcErrorWithSend; +use crate::pus::EcssTmtcError; #[cfg(feature = "alloc")] #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] pub use alloc_mod::*; @@ -96,12 +96,12 @@ pub struct EventRequestWithToken { #[derive(Debug)] pub enum EventManError { - EcssTmtcError(EcssTmtcErrorWithSend), + EcssTmtcError(EcssTmtcError), SeverityMissmatch(Severity, Severity), } -impl From for EventManError { - fn from(v: EcssTmtcErrorWithSend) -> Self { +impl From for EventManError { + fn from(v: EcssTmtcError) -> Self { Self::EcssTmtcError(v) } } diff --git a/satrs-core/src/pus/event_srv.rs b/satrs-core/src/pus/event_srv.rs index dee2747..acf3537 100644 --- a/satrs-core/src/pus/event_srv.rs +++ b/satrs-core/src/pus/event_srv.rs @@ -5,8 +5,8 @@ use crate::pus::verification::{ StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken, }; use crate::pus::{ - AcceptedTc, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, - PusPacketHandlingError, PusServiceBase, PusServiceHandler, + AcceptedTc, EcssTcReceiver, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, + PusPacketHandlingError, PusServiceBase, PusServiceHandler, ReceivedTcWrapper, }; use spacepackets::ecss::event::Subservice; use spacepackets::ecss::PusPacket; @@ -21,15 +21,14 @@ pub struct PusService5EventHandler { impl PusService5EventHandler { pub fn new( - receiver: Receiver, - tc_pool: SharedPool, + tc_receiver: Box, tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, event_request_tx: Sender, ) -> Self { Self { - psb: PusServiceBase::new(receiver, tc_pool, tm_sender, tm_apid, verification_handler), + psb: PusServiceBase::new(tc_receiver, tm_sender, tm_apid, verification_handler), event_request_tx, } } @@ -45,11 +44,16 @@ impl PusServiceHandler for PusService5EventHandler { fn handle_one_tc( &mut self, - addr: StoreAddr, - token: VerificationToken, + tc_in_store_with_token: ReceivedTcWrapper, ) -> Result { - self.copy_tc_to_buf(addr)?; - let (tc, _) = PusTc::from_bytes(&self.psb.pus_buf).unwrap(); + let ReceivedTcWrapper { + tc, + token, + pool_guard, + } = tc_in_store_with_token; + // TODO: Better token handling.. + let token = token.expect("invalid token"); + let accepted_token = VerificationToken::::try_from(token).unwrap(); let subservice = tc.subservice(); let srv = Subservice::try_from(subservice); if srv.is_err() { @@ -70,7 +74,7 @@ impl PusServiceHandler for PusService5EventHandler { .psb .verification_handler .borrow_mut() - .start_success(token, Some(&stamp)) + .start_success(accepted_token, Some(&stamp)) .map_err(|_| PartialPusHandlingError::Verification); let partial_error = start_token.clone().err(); let mut token: TcStateToken = token.into(); @@ -91,7 +95,7 @@ impl PusServiceHandler for PusService5EventHandler { self.event_request_tx .send(event_req_with_token) .map_err(|_| { - PusPacketHandlingError::SendError("Forwarding event request failed".into()) + PusPacketHandlingError::Other("Forwarding event request failed".into()) })?; if let Some(partial_error) = partial_error { return Ok(PusPacketHandlerResult::RequestHandledPartialSuccess( diff --git a/satrs-core/src/pus/mod.rs b/satrs-core/src/pus/mod.rs index 4160f0a..7d7fc71 100644 --- a/satrs-core/src/pus/mod.rs +++ b/satrs-core/src/pus/mod.rs @@ -28,8 +28,8 @@ pub mod verification; #[cfg(feature = "alloc")] pub use alloc_mod::*; -use crate::pool::{StoreAddr, StoreError}; -use crate::pus::verification::TcStateToken; +use crate::pool::{PoolGuard, PoolRwGuard, StoreAddr, StoreError}; +use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken}; #[cfg(feature = "std")] pub use std_mod::*; @@ -51,6 +51,12 @@ impl<'tm> From> for PusTmWrapper<'tm> { } } +pub type TcAddrWithToken = (StoreAddr, TcStateToken); + +/// Generic abstraction for a telecommand being sent around after is has been accepted. +/// The actual telecommand is stored inside a pre-allocated pool structure. +pub type AcceptedTc = (StoreAddr, VerificationToken); + /// Generic error type for sending something via a message queue. #[derive(Debug, Copy, Clone)] pub enum GenericSendError { @@ -74,67 +80,100 @@ impl Display for GenericSendError { #[cfg(feature = "std")] impl Error for GenericSendError {} +/// Generic error type for sending something via a message queue. +#[derive(Debug, Copy, Clone)] +pub enum GenericRecvError { + Empty, + TxDisconnected, +} + +impl Display for GenericRecvError { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + Self::TxDisconnected => { + write!(f, "tx side has disconnected") + } + Self::Empty => { + write!(f, "nothing to receive") + } + } + } +} + +#[cfg(feature = "std")] +impl Error for GenericRecvError {} + #[derive(Debug, Clone)] -pub enum EcssTmtcErrorWithSend { +pub enum EcssTmtcError { StoreLock, Store(StoreError), Pus(PusError), CantSendAddr(StoreAddr), Send(GenericSendError), + Recv(GenericRecvError), } -impl Display for EcssTmtcErrorWithSend { +impl Display for EcssTmtcError { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self { - EcssTmtcErrorWithSend::StoreLock => { + EcssTmtcError::StoreLock => { write!(f, "store lock error") } - EcssTmtcErrorWithSend::Store(store) => { + EcssTmtcError::Store(store) => { write!(f, "store error: {store}") } - EcssTmtcErrorWithSend::Pus(pus_e) => { + EcssTmtcError::Pus(pus_e) => { write!(f, "PUS error: {pus_e}") } - EcssTmtcErrorWithSend::CantSendAddr(addr) => { + EcssTmtcError::CantSendAddr(addr) => { write!(f, "can not send address {addr}") } - EcssTmtcErrorWithSend::Send(send_e) => { + EcssTmtcError::Send(send_e) => { write!(f, "send error {send_e}") } + EcssTmtcError::Recv(recv_e) => { + write!(f, "recv error {recv_e}") + } } } } -impl From for EcssTmtcErrorWithSend { +impl From for EcssTmtcError { fn from(value: StoreError) -> Self { Self::Store(value) } } -impl From for EcssTmtcErrorWithSend { +impl From for EcssTmtcError { fn from(value: PusError) -> Self { Self::Pus(value) } } -impl From for EcssTmtcErrorWithSend { +impl From for EcssTmtcError { fn from(value: GenericSendError) -> Self { Self::Send(value) } } +impl From for EcssTmtcError { + fn from(value: GenericRecvError) -> Self { + Self::Recv(value) + } +} + #[cfg(feature = "std")] -impl Error for EcssTmtcErrorWithSend { +impl Error for EcssTmtcError { fn source(&self) -> Option<&(dyn Error + 'static)> { match self { - EcssTmtcErrorWithSend::Store(e) => Some(e), - EcssTmtcErrorWithSend::Pus(e) => Some(e), - EcssTmtcErrorWithSend::Send(e) => Some(e), + EcssTmtcError::Store(e) => Some(e), + EcssTmtcError::Pus(e) => Some(e), + EcssTmtcError::Send(e) => Some(e), _ => None, } } } -pub trait EcssSender: Send { +pub trait EcssChannel: Send { /// Each sender can have an ID associated with it fn id(&self) -> SenderId; fn name(&self) -> &'static str { @@ -145,16 +184,35 @@ pub trait EcssSender: Send { /// Generic trait for a user supplied sender object. /// /// This sender object is responsible for sending PUS telemetry to a TM sink. -pub trait EcssTmSenderCore: EcssSender { - fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcErrorWithSend>; +pub trait EcssTmSenderCore: EcssChannel { + fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcError>; } /// Generic trait for a user supplied sender object. /// /// This sender object is responsible for sending PUS telecommands to a TC recipient. Each /// telecommand can optionally have a token which contains its verification state. -pub trait EcssTcSenderCore: EcssSender { - fn send_tc(&self, tc: PusTc, token: Option) -> Result<(), EcssTmtcErrorWithSend>; +pub trait EcssTcSenderCore: EcssChannel { + fn send_tc(&self, tc: PusTc, token: Option) -> Result<(), EcssTmtcError>; +} + +pub struct ReceivedTcWrapper<'raw_tc> { + pub pool_guard: PoolGuard<'raw_tc>, + pub tc: PusTc<'raw_tc>, + pub token: Option, +} + +/// Generic trait for a user supplied receiver object. +pub trait EcssTcReceiverCore: EcssChannel { + fn recv_tc<'buf>(&self, buf: &'buf mut [u8]) -> Result, EcssTmtcError>; +} + +/// Generic trait for objects which can receive ECSS PUS telecommands. This trait is +/// implemented by the [crate::tmtc::pus_distrib::PusDistributor] objects to allow passing PUS TC +/// packets into it. +pub trait ReceivesEcssPusTc { + type Error; + fn pass_pus_tc(&mut self, header: &SpHeader, pus_tc: &PusTc) -> Result<(), Self::Error>; } #[cfg(feature = "alloc")] @@ -200,50 +258,66 @@ mod alloc_mod { dyn_clone::clone_trait_object!(EcssTcSender); impl_downcast!(EcssTcSender); -} -/// Generic trait for objects which can receive ECSS PUS telecommands. This trait is -/// implemented by the [crate::tmtc::pus_distrib::PusDistributor] objects to allow passing PUS TC -/// packets into it. -pub trait ReceivesEcssPusTc { - type Error; - fn pass_pus_tc(&mut self, header: &SpHeader, pus_tc: &PusTc) -> Result<(), Self::Error>; + /// Extension trait for [EcssTcReceiverCore]. + /// + /// It provides additional functionality, for example by implementing the [Downcast] trait + /// and the [DynClone] trait. + /// + /// [Downcast] is implemented to allow passing the sender as a boxed trait object and still + /// retrieve the concrete type at a later point. + /// + /// [DynClone] allows cloning the trait object as long as the boxed object implements + /// [Clone]. + #[cfg(feature = "alloc")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] + pub trait EcssTcReceiver: EcssTcReceiverCore + Downcast + DynClone {} + + /// Blanket implementation for all types which implement [EcssTcReceiverCore] and are clonable. + impl EcssTcReceiver for T where T: EcssTcReceiverCore + Clone + 'static {} + + dyn_clone::clone_trait_object!(EcssTcReceiver); + impl_downcast!(EcssTcReceiver); } #[cfg(feature = "std")] pub mod std_mod { - use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError}; + use crate::pool::{SharedPool, StoreAddr}; use crate::pus::verification::{ - StdVerifReporterWithSender, TcStateAccepted, VerificationToken, + StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken, }; use crate::pus::{ - EcssSender, EcssTmSender, EcssTmSenderCore, EcssTmtcErrorWithSend, GenericSendError, - PusTmWrapper, + AcceptedTc, EcssChannel, EcssTcReceiver, EcssTcReceiverCore, EcssTmSender, + EcssTmSenderCore, EcssTmtcError, GenericRecvError, GenericSendError, PusTmWrapper, + ReceivedTcWrapper, TcAddrWithToken, }; + use crate::tmtc::tm_helper::SharedTmStore; use crate::SenderId; use alloc::boxed::Box; use alloc::vec::Vec; - use spacepackets::ecss::{PusError, SerializablePusPacket}; + use spacepackets::ecss::PusError; + use spacepackets::tc::PusTc; use spacepackets::time::cds::TimeProvider; use spacepackets::time::std_mod::StdTimestampError; use spacepackets::time::TimeWriter; + use spacepackets::tm::PusTm; + use spacepackets::{ByteConversionError, SizeMissmatch}; use std::cell::RefCell; - use std::format; use std::string::String; - use std::sync::mpsc::SendError; - use std::sync::{mpsc, RwLockWriteGuard}; + use std::sync::mpsc; + use std::sync::mpsc::{SendError, TryRecvError}; use thiserror::Error; #[derive(Clone)] pub struct MpscTmInStoreSender { id: SenderId, name: &'static str, - store_helper: SharedPool, + shared_tm_store: SharedTmStore, sender: mpsc::Sender, pub ignore_poison_errors: bool, } - impl EcssSender for MpscTmInStoreSender { + impl EcssChannel for MpscTmInStoreSender { fn id(&self) -> SenderId { self.id } @@ -253,39 +327,22 @@ pub mod std_mod { } } - impl From> for EcssTmtcErrorWithSend { + impl From> for EcssTmtcError { fn from(_: SendError) -> Self { Self::Send(GenericSendError::RxDisconnected) } } impl MpscTmInStoreSender { - pub fn send_direct_tm( - &self, - tmtc: impl SerializablePusPacket, - ) -> Result<(), EcssTmtcErrorWithSend> { - let operation = |mut store: RwLockWriteGuard| { - let (addr, slice) = store.free_element(tmtc.len_packed())?; - tmtc.write_to_bytes(slice)?; - self.sender.send(addr)?; - Ok(()) - }; - match self.store_helper.write() { - Ok(pool) => operation(pool), - Err(e) => { - if self.ignore_poison_errors { - operation(e.into_inner()) - } else { - Err(EcssTmtcErrorWithSend::Send( - GenericSendError::RxDisconnected, - )) - } - } - } + pub fn send_direct_tm(&self, tm: PusTm) -> Result<(), EcssTmtcError> { + let addr = self.shared_tm_store.add_pus_tm(&tm)?; + self.sender + .send(addr) + .map_err(|_| EcssTmtcError::Send(GenericSendError::RxDisconnected)) } } impl EcssTmSenderCore for MpscTmInStoreSender { - fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcErrorWithSend> { + fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcError> { match tm { PusTmWrapper::InStore(addr) => self.sender.send(addr).map_err(|e| e.into()), PusTmWrapper::Direct(tm) => self.send_direct_tm(tm), @@ -297,19 +354,66 @@ pub mod std_mod { pub fn new( id: SenderId, name: &'static str, - store_helper: SharedPool, + shared_tm_store: SharedTmStore, sender: mpsc::Sender, ) -> Self { Self { id, name, - store_helper, + shared_tm_store, sender, ignore_poison_errors: false, } } } + pub struct MpscTcInStoreReceiver { + id: SenderId, + name: &'static str, + shared_tc_pool: SharedPool, + receiver: mpsc::Receiver, + pub ignore_poison_errors: bool, + } + + impl EcssChannel for MpscTcInStoreReceiver { + fn id(&self) -> SenderId { + self.id + } + + fn name(&self) -> &'static str { + self.name + } + } + + impl EcssTcReceiverCore for MpscTcInStoreReceiver { + fn recv_tc<'buf>( + &self, + buf: &'buf mut [u8], + ) -> Result, EcssTmtcError> { + let (addr, token) = self.receiver.try_recv().map_err(|e| match e { + TryRecvError::Empty => GenericRecvError::Empty, + TryRecvError::Disconnected => GenericRecvError::TxDisconnected, + })?; + let shared_tc_pool = self + .shared_tc_pool + .read() + .map_err(|_| EcssTmtcError::StoreLock)?; + let tc_raw = shared_tc_pool.read(&addr)?; + if buf.len() < tc_raw.len() { + return Err( + PusError::ByteConversion(ByteConversionError::ToSliceTooSmall(SizeMissmatch { + found: buf.len(), + expected: tc_raw.len(), + })) + .into(), + ); + } + buf[..tc_raw.len()].copy_from_slice(tc_raw); + let (tc, _) = PusTc::from_bytes(buf)?; + Ok((tc, token)) + } + } + /// This class can be used if frequent heap allocations during run-time are not an issue. /// PUS TM packets will be sent around as [Vec]s. Please note that the current implementation /// of this class can not deal with store addresses, so it is assumed that is is always @@ -321,7 +425,7 @@ pub mod std_mod { name: &'static str, } - impl From>> for EcssTmtcErrorWithSend { + impl From>> for EcssTmtcError { fn from(_: SendError>) -> Self { Self::Send(GenericSendError::RxDisconnected) } @@ -333,7 +437,7 @@ pub mod std_mod { } } - impl EcssSender for MpscTmAsVecSender { + impl EcssChannel for MpscTmAsVecSender { fn id(&self) -> SenderId { self.id } @@ -343,13 +447,12 @@ pub mod std_mod { } impl EcssTmSenderCore for MpscTmAsVecSender { - fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcErrorWithSend> { + fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcError> { match tm { - PusTmWrapper::InStore(addr) => Err(EcssTmtcErrorWithSend::CantSendAddr(addr)), + PusTmWrapper::InStore(addr) => Err(EcssTmtcError::CantSendAddr(addr)), PusTmWrapper::Direct(tm) => { let mut vec = Vec::new(); - tm.append_to_vec(&mut vec) - .map_err(EcssTmtcErrorWithSend::Pus)?; + tm.append_to_vec(&mut vec).map_err(EcssTmtcError::Pus)?; self.sender.send(vec)?; Ok(()) } @@ -359,36 +462,32 @@ pub mod std_mod { #[derive(Debug, Clone, Error)] pub enum PusPacketHandlingError { - #[error("Generic PUS error: {0}")] - PusError(#[from] PusError), - #[error("Wrong service number {0} for packet handler")] + #[error("generic PUS error: {0}")] + Pus(#[from] PusError), + #[error("wrong service number {0} for packet handler")] WrongService(u8), - #[error("Invalid subservice {0}")] + #[error("invalid subservice {0}")] InvalidSubservice(u8), - #[error("Not enough application data available: {0}")] + #[error("not enough application data available: {0}")] NotEnoughAppData(String), - #[error("Invalid application data")] + #[error("invalid application data")] InvalidAppData(String), - #[error("Generic store error: {0}")] - StoreError(#[from] StoreError), - #[error("Error with the pool RwGuard: {0}")] - RwGuardError(String), - #[error("MQ send error: {0}")] - SendError(String), - #[error("TX message queue side has disconnected")] - QueueDisconnected, - #[error("Other error {0}")] - OtherError(String), + #[error("generic ECSS tmtc error: {0}")] + EcssTmtc(#[from] EcssTmtcError), + #[error("other error {0}")] + Other(String), } #[derive(Debug, Clone, Error)] pub enum PartialPusHandlingError { - #[error("Generic timestamp generation error")] + #[error("generic timestamp generation error")] Time(#[from] StdTimestampError), - #[error("Error sending telemetry: {0}")] - TmSend(#[from] EcssTmtcErrorWithSend), - #[error("Error sending verification message")] + #[error("error sending telemetry: {0}")] + TmSend(#[from] EcssTmtcError), + #[error("error sending verification message")] Verification, + #[error("invalid verification token")] + NoVerificationToken, } /// Generic result type for handlers which can process PUS packets. @@ -396,8 +495,8 @@ pub mod std_mod { pub enum PusPacketHandlerResult { RequestHandled, RequestHandledPartialSuccess(PartialPusHandlingError), - SubserviceNotImplemented(u8, VerificationToken), - CustomSubservice(u8, VerificationToken), + SubserviceNotImplemented(u8, TcStateToken), + CustomSubservice(u8, TcStateToken), Empty, } @@ -407,16 +506,11 @@ pub mod std_mod { } } - /// Generic abstraction for a telecommand being sent around after is has been accepted. - /// The actual telecommand is stored inside a pre-allocated pool structure. - pub type AcceptedTc = (StoreAddr, VerificationToken); - /// Base class for handlers which can handle PUS TC packets. Right now, the message queue /// backend is constrained to [mpsc::channel]s and the verification reporter /// is constrained to the [StdVerifReporterWithSender]. pub struct PusServiceBase { - pub tc_rx: mpsc::Receiver, - pub tc_store: SharedPool, + pub tc_receiver: Box, pub tm_sender: Box, pub tm_apid: u16, /// The verification handler is wrapped in a [RefCell] to allow the interior mutability @@ -428,15 +522,13 @@ pub mod std_mod { impl PusServiceBase { pub fn new( - receiver: mpsc::Receiver, - tc_pool: SharedPool, + tc_receiver: Box, tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, ) -> Self { Self { - tc_rx: receiver, - tc_store: tc_pool, + tc_receiver, tm_apid, tm_sender, verification_handler: RefCell::new(verification_handler), @@ -472,8 +564,7 @@ pub mod std_mod { fn psb(&self) -> &PusServiceBase; fn handle_one_tc( &mut self, - addr: StoreAddr, - token: VerificationToken, + tc_in_store_with_token: ReceivedTcWrapper, ) -> Result; fn copy_tc_to_buf(&mut self, addr: StoreAddr) -> Result<(), PusPacketHandlingError> { @@ -482,7 +573,7 @@ pub mod std_mod { let mut tc_pool = psb_mut .tc_store .write() - .map_err(|e| PusPacketHandlingError::RwGuardError(format!("{e}")))?; + .map_err(|_| PusPacketHandlingError::EcssTmtc(EcssTmtcError::StoreLock))?; let tc_guard = tc_pool.read_with_guard(addr); let tc_raw = tc_guard.read().unwrap(); psb_mut.pus_buf[0..tc_raw.len()].copy_from_slice(tc_raw); @@ -490,26 +581,23 @@ pub mod std_mod { } fn handle_next_packet(&mut self) -> Result { - return match self.psb().tc_rx.try_recv() { + match self.psb().tc_receiver.recv_tc()? { Ok((addr, token)) => self.handle_one_tc(addr, token), Err(e) => match e { - mpsc::TryRecvError::Empty => Ok(PusPacketHandlerResult::Empty), - mpsc::TryRecvError::Disconnected => { - Err(PusPacketHandlingError::QueueDisconnected) - } + TryRecvError::Empty => Ok(PusPacketHandlerResult::Empty), + TryRecvError::Disconnected => Err(PusPacketHandlingError::EcssTmtc( + EcssTmtcError::Recv(GenericRecvError::TxDisconnected), + )), }, - }; + } } } } -pub(crate) fn source_buffer_large_enough( - cap: usize, - len: usize, -) -> Result<(), EcssTmtcErrorWithSend> { +pub(crate) fn source_buffer_large_enough(cap: usize, len: usize) -> Result<(), EcssTmtcError> { if len > cap { return Err( - PusError::ByteConversionError(ByteConversionError::ToSliceTooSmall(SizeMissmatch { + PusError::ByteConversion(ByteConversionError::ToSliceTooSmall(SizeMissmatch { found: cap, expected: len, })) diff --git a/satrs-core/src/pus/scheduler_srv.rs b/satrs-core/src/pus/scheduler_srv.rs index 0b72feb..46c1e99 100644 --- a/satrs-core/src/pus/scheduler_srv.rs +++ b/satrs-core/src/pus/scheduler_srv.rs @@ -2,8 +2,8 @@ use crate::pool::{SharedPool, StoreAddr}; use crate::pus::scheduler::PusScheduler; use crate::pus::verification::{StdVerifReporterWithSender, TcStateAccepted, VerificationToken}; use crate::pus::{ - AcceptedTc, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, - PusServiceHandler, + AcceptedTc, EcssTcReceiver, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, + PusServiceBase, PusServiceHandler, ReceivedTcWrapper, }; use spacepackets::ecss::{scheduling, PusPacket}; use spacepackets::tc::PusTc; @@ -26,15 +26,14 @@ pub struct PusService11SchedHandler { impl PusService11SchedHandler { pub fn new( - receiver: Receiver, - tc_pool: SharedPool, + tc_receiver: Box, tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, scheduler: PusScheduler, ) -> Self { Self { - psb: PusServiceBase::new(receiver, tc_pool, tm_sender, tm_apid, verification_handler), + psb: PusServiceBase::new(tc_receiver, tm_sender, tm_apid, verification_handler), scheduler, } } @@ -58,11 +57,13 @@ impl PusServiceHandler for PusService11SchedHandler { fn handle_one_tc( &mut self, - addr: StoreAddr, - token: VerificationToken, + tc_in_store_with_token: ReceivedTcWrapper, ) -> Result { - self.copy_tc_to_buf(addr)?; - let (tc, _) = PusTc::from_bytes(&self.psb.pus_buf).unwrap(); + let ReceivedTcWrapper { + tc, + pool_guard, + token, + } = tc_in_store_with_token; let std_service = scheduling::Subservice::try_from(tc.subservice()); if std_service.is_err() { return Ok(PusPacketHandlerResult::CustomSubservice( diff --git a/satrs-core/src/pus/test.rs b/satrs-core/src/pus/test.rs index ced2461..d1317dd 100644 --- a/satrs-core/src/pus/test.rs +++ b/satrs-core/src/pus/test.rs @@ -2,7 +2,7 @@ use crate::pool::{SharedPool, StoreAddr}; use crate::pus::verification::{StdVerifReporterWithSender, TcStateAccepted, VerificationToken}; use crate::pus::{ AcceptedTc, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, - PusPacketHandlingError, PusServiceBase, PusServiceHandler, PusTmWrapper, + PusPacketHandlingError, PusServiceBase, PusServiceHandler, PusTmWrapper, ReceivedTcWrapper, }; use spacepackets::ecss::PusPacket; use spacepackets::tc::PusTc; @@ -41,11 +41,13 @@ impl PusServiceHandler for PusService17TestHandler { fn handle_one_tc( &mut self, - addr: StoreAddr, - token: VerificationToken, + tc_in_store_with_token: ReceivedTcWrapper, ) -> Result { - self.copy_tc_to_buf(addr)?; - let (tc, _) = PusTc::from_bytes(&self.psb.pus_buf)?; + let ReceivedTcWrapper { + tc, + pool_guard, + token, + } = tc_in_store_with_token; if tc.service() != 17 { return Err(PusPacketHandlingError::WrongService(tc.service())); } diff --git a/satrs-core/src/pus/verification.rs b/satrs-core/src/pus/verification.rs index 83307a1..53f0c8f 100644 --- a/satrs-core/src/pus/verification.rs +++ b/satrs-core/src/pus/verification.rs @@ -73,7 +73,7 @@ //! The [integration test](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/main/fsrc-core/tests/verification_test.rs) //! for the verification module contains examples how this module could be used in a more complex //! context involving multiple threads -use crate::pus::{source_buffer_large_enough, EcssTmSenderCore, EcssTmtcErrorWithSend}; +use crate::pus::{source_buffer_large_enough, EcssTmSenderCore, EcssTmtcError}; use core::fmt::{Debug, Display, Formatter}; use core::hash::{Hash, Hasher}; use core::marker::PhantomData; @@ -172,10 +172,10 @@ impl RequestId { /// If a verification operation fails, the passed token will be returned as well. This allows /// re-trying the operation at a later point. #[derive(Debug, Clone)] -pub struct VerificationOrSendErrorWithToken(pub EcssTmtcErrorWithSend, pub VerificationToken); +pub struct VerificationOrSendErrorWithToken(pub EcssTmtcError, pub VerificationToken); #[derive(Debug, Clone)] -pub struct VerificationErrorWithToken(pub EcssTmtcErrorWithSend, pub VerificationToken); +pub struct VerificationErrorWithToken(pub EcssTmtcError, pub VerificationToken); impl From> for VerificationOrSendErrorWithToken { fn from(value: VerificationErrorWithToken) -> Self { @@ -205,7 +205,7 @@ impl WasAtLeastAccepted for TcStateAccepted {} impl WasAtLeastAccepted for TcStateStarted {} impl WasAtLeastAccepted for TcStateCompleted {} -#[derive(Debug, Eq, PartialEq)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum TcStateToken { None(VerificationToken), Accepted(VerificationToken), @@ -230,6 +230,19 @@ impl TryFrom for VerificationToken { } } } + +impl TryFrom for VerificationToken { + type Error = (); + + fn try_from(value: TcStateToken) -> Result { + if let TcStateToken::Started(token) = value { + Ok(token) + } else { + Err(()) + } + } +} + impl From> for TcStateToken { fn from(t: VerificationToken) -> Self { TcStateToken::Accepted(t) @@ -641,8 +654,7 @@ impl VerificationReporterCore { msg_count: u16, time_stamp: Option<&'src_data [u8]>, step: impl EcssEnumeration, - ) -> Result, EcssTmtcErrorWithSend> - { + ) -> Result, EcssTmtcError> { Ok(VerificationSendable::new_no_token( self.create_pus_verif_success_tm( src_data_buf, @@ -772,7 +784,7 @@ impl VerificationReporterCore { req_id: &RequestId, time_stamp: Option<&'src_data [u8]>, step: Option<&(impl EcssEnumeration + ?Sized)>, - ) -> Result, EcssTmtcErrorWithSend> { + ) -> Result, EcssTmtcError> { let mut source_data_len = size_of::(); if let Some(step) = step { source_data_len += step.size(); @@ -808,7 +820,7 @@ impl VerificationReporterCore { req_id: &RequestId, step: Option<&(impl EcssEnumeration + ?Sized)>, params: &FailParams<'src_data, '_>, - ) -> Result, EcssTmtcErrorWithSend> { + ) -> Result, EcssTmtcError> { let mut idx = 0; let mut source_data_len = RequestId::SIZE_AS_BYTES + params.failure_code.size(); if let Some(step) = step { @@ -829,7 +841,7 @@ impl VerificationReporterCore { params .failure_code .write_to_be_bytes(&mut src_data_buf[idx..idx + params.failure_code.size()]) - .map_err(PusError::ByteConversionError)?; + .map_err(PusError::ByteConversion)?; idx += params.failure_code.size(); if let Some(failure_data) = params.failure_data { src_data_buf[idx..idx + failure_data.len()].copy_from_slice(failure_data); @@ -1063,7 +1075,7 @@ mod alloc_mod { sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: Option<&[u8]>, step: impl EcssEnumeration, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcError> { let seq_count = self .seq_count_provider .as_ref() @@ -1250,7 +1262,7 @@ mod alloc_mod { token: &VerificationToken, time_stamp: Option<&[u8]>, step: impl EcssEnumeration, - ) -> Result<(), EcssTmtcErrorWithSend> { + ) -> Result<(), EcssTmtcError> { self.reporter .step_success(token, self.sender.as_mut(), time_stamp, step) } @@ -1482,11 +1494,11 @@ mod tests { use crate::pool::{LocalPool, PoolCfg, SharedPool}; use crate::pus::tests::CommonTmInfo; use crate::pus::verification::{ - EcssTmSenderCore, EcssTmtcErrorWithSend, FailParams, FailParamsWithStep, RequestId, - TcStateNone, VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender, + EcssTmSenderCore, EcssTmtcError, FailParams, FailParamsWithStep, RequestId, TcStateNone, + VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender, VerificationToken, }; - use crate::pus::{EcssSender, EcssTmtcErrorWithSend, MpscTmInStoreSender, PusTmWrapper}; + use crate::pus::{EcssChannel, EcssTmtcError, MpscTmInStoreSender, PusTmWrapper}; use crate::SenderId; use alloc::boxed::Box; use alloc::format; @@ -1521,7 +1533,7 @@ mod tests { pub service_queue: RefCell>, } - impl EcssSender for TestSender { + impl EcssChannel for TestSender { fn id(&self) -> SenderId { 0 } @@ -1569,7 +1581,7 @@ mod tests { #[derive(Default, Clone)] struct FallibleSender {} - impl EcssSender for FallibleSender { + impl EcssChannel for FallibleSender { fn id(&self) -> SenderId { 0 } @@ -1705,7 +1717,7 @@ mod tests { let err = res.unwrap_err(); assert_eq!(err.1, tok); match err.0 { - EcssTmtcErrorWithSend::SendError(e) => { + EcssTmtcError::SendError(e) => { assert_eq!(e, DummyError {}) } _ => panic!("{}", format!("Unexpected error {:?}", err.0)), @@ -1776,20 +1788,18 @@ mod tests { let err_with_token = res.unwrap_err(); assert_eq!(err_with_token.1, tok); match err_with_token.0 { - EcssTmtcErrorWithSend::EcssTmtcError(EcssTmtcErrorWithSend::ByteConversion(e)) => { - match e { - ByteConversionError::ToSliceTooSmall(missmatch) => { - assert_eq!( - missmatch.expected, - fail_data.len() + RequestId::SIZE_AS_BYTES + fail_code.size() - ); - assert_eq!(missmatch.found, b.rep().allowed_source_data_len()); - } - _ => { - panic!("{}", format!("Unexpected error {:?}", e)) - } + EcssTmtcError::EcssTmtcError(EcssTmtcError::ByteConversion(e)) => match e { + ByteConversionError::ToSliceTooSmall(missmatch) => { + assert_eq!( + missmatch.expected, + fail_data.len() + RequestId::SIZE_AS_BYTES + fail_code.size() + ); + assert_eq!(missmatch.found, b.rep().allowed_source_data_len()); } - } + _ => { + panic!("{}", format!("Unexpected error {:?}", e)) + } + }, _ => { panic!("{}", format!("Unexpected error {:?}", err_with_token.0)) } diff --git a/satrs-core/src/tmtc/pus_distrib.rs b/satrs-core/src/tmtc/pus_distrib.rs index 88b8f1f..b6a5eab 100644 --- a/satrs-core/src/tmtc/pus_distrib.rs +++ b/satrs-core/src/tmtc/pus_distrib.rs @@ -133,7 +133,7 @@ impl ReceivesTcCore for PusDistributor { fn pass_tc(&mut self, tm_raw: &[u8]) -> Result<(), Self::Error> { // Convert to ccsds and call pass_ccsds let (sp_header, _) = SpHeader::from_be_bytes(tm_raw) - .map_err(|e| PusDistribError::PusError(PusError::ByteConversionError(e)))?; + .map_err(|e| PusDistribError::PusError(PusError::ByteConversion(e)))?; self.pass_ccsds(&sp_header, tm_raw) } } diff --git a/satrs-core/src/tmtc/tm_helper.rs b/satrs-core/src/tmtc/tm_helper.rs index 2ef099c..5c960b9 100644 --- a/satrs-core/src/tmtc/tm_helper.rs +++ b/satrs-core/src/tmtc/tm_helper.rs @@ -8,9 +8,11 @@ pub use std_mod::*; #[cfg(feature = "std")] pub mod std_mod { - use crate::pool::{SharedPool, StoreAddr}; + use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr}; + use crate::pus::EcssTmtcError; use spacepackets::ecss::SerializablePusPacket; use spacepackets::tm::PusTm; + use std::sync::{Arc, RwLock}; #[derive(Clone)] pub struct SharedTmStore { @@ -18,21 +20,23 @@ pub mod std_mod { } impl SharedTmStore { - pub fn new(backing_pool: SharedPool) -> Self { - Self { pool: backing_pool } + pub fn new(backing_pool: ShareablePoolProvider) -> Self { + Self { + pool: Arc::new(RwLock::new(backing_pool)), + } } pub fn backing_pool(&self) -> SharedPool { self.pool.clone() } - pub fn add_pus_tm(&mut self, pus_tm: &PusTm) -> StoreAddr { - let mut pg = self.pool.write().expect("error locking TM store"); - let (addr, buf) = pg.free_element(pus_tm.len_packed()).expect("Store error"); + pub fn add_pus_tm(&self, pus_tm: &PusTm) -> Result { + let mut pg = self.pool.write().map_err(|_| EcssTmtcError::StoreLock)?; + let (addr, buf) = pg.free_element(pus_tm.len_packed())?; pus_tm .write_to_bytes(buf) .expect("writing PUS TM to store failed"); - addr + Ok(addr) } } } diff --git a/satrs-example/src/main.rs b/satrs-example/src/main.rs index f29f95a..9f1be77 100644 --- a/satrs-example/src/main.rs +++ b/satrs-example/src/main.rs @@ -64,8 +64,8 @@ fn main() { (15, 1024), (15, 2048), ])); - let tm_store = SharedTmStore::new(Arc::new(RwLock::new(Box::new(tm_pool)))); - let tm_store_event = tm_store.clone(); + let shared_tm_store = SharedTmStore::new(Box::new(tm_pool)); + let tm_store_event = shared_tm_store.clone(); let tc_pool = LocalPool::new(PoolCfg::new(vec![ (30, 32), (15, 64), @@ -87,7 +87,7 @@ fn main() { let verif_sender = MpscTmInStoreSender::new( TmSenderId::PusVerification as SenderId, "verif_sender", - tm_store.backing_pool(), + shared_tm_store.clone(), tm_funnel_tx.clone(), ); let verif_cfg = VerificationReporterCfg::new(PUS_APID, 1, 2, 8).unwrap(); @@ -135,13 +135,13 @@ fn main() { tc_receiver: tc_source_rx, }; let tm_args = TmArgs { - tm_store: tm_store.clone(), + tm_store: shared_tm_store.clone(), tm_sink_sender: tm_funnel_tx.clone(), tm_server_rx, }; let aocs_tm_funnel = tm_funnel_tx.clone(); - let mut aocs_tm_store = tm_store.clone(); + let aocs_tm_store = shared_tm_store.clone(); let (pus_test_tx, pus_test_rx) = channel(); let (pus_event_tx, pus_event_rx) = channel(); @@ -158,7 +158,7 @@ fn main() { let test_srv_tm_sender = MpscTmInStoreSender::new( TmSenderId::PusTest as SenderId, "PUS_17_TM_SENDER", - tm_store.backing_pool().clone(), + shared_tm_store.clone(), tm_funnel_tx.clone(), ); let pus17_handler = PusService17TestHandler::new( @@ -176,7 +176,7 @@ fn main() { let sched_srv_tm_sender = MpscTmInStoreSender::new( TmSenderId::PusSched as SenderId, "PUS_11_TM_SENDER", - tm_store.backing_pool().clone(), + shared_tm_store.clone(), tm_funnel_tx.clone(), ); let scheduler = PusScheduler::new_with_current_init_time(Duration::from_secs(5)) @@ -197,7 +197,7 @@ fn main() { let event_srv_tm_sender = MpscTmInStoreSender::new( TmSenderId::PusEvent as SenderId, "PUS_5_TM_SENDER", - tm_store.backing_pool().clone(), + shared_tm_store.clone(), tm_funnel_tx.clone(), ); let pus_5_handler = PusService5EventHandler::new( @@ -213,7 +213,7 @@ fn main() { let action_srv_tm_sender = MpscTmInStoreSender::new( TmSenderId::PusAction as SenderId, "PUS_8_TM_SENDER", - tm_store.backing_pool().clone(), + shared_tm_store.clone(), tm_funnel_tx.clone(), ); let pus_8_handler = PusService8ActionHandler::new( @@ -229,7 +229,7 @@ fn main() { let hk_srv_tm_sender = MpscTmInStoreSender::new( TmSenderId::PusHk as SenderId, "PUS_3_TM_SENDER", - tm_store.backing_pool().clone(), + shared_tm_store.clone(), tm_funnel_tx.clone(), ); let pus_3_handler = PusService3HkHandler::new( @@ -262,7 +262,7 @@ fn main() { if let Ok(addr) = tm_funnel.tm_funnel_rx.recv() { // Read the TM, set sequence counter and message counter, and finally update // the CRC. - let shared_pool = tm_store.backing_pool(); + let shared_pool = shared_tm_store.backing_pool(); let mut pool_guard = shared_pool.write().expect("Locking TM pool failed"); let tm_raw = pool_guard .modify(&addr) @@ -297,12 +297,8 @@ fn main() { .name("Event".to_string()) .spawn(move || { let mut timestamp: [u8; 7] = [0; 7]; - let mut sender = MpscTmInStoreSender::new( - 1, - "event_sender", - tm_store_event.backing_pool(), - tm_funnel_tx, - ); + let mut sender = + MpscTmInStoreSender::new(1, "event_sender", tm_store_event.clone(), tm_funnel_tx); let mut time_provider = TimeProvider::new_with_u16_days(0, 0); let mut report_completion = |event_req: EventRequestWithToken, timestamp: &[u8]| { reporter_event_handler @@ -393,7 +389,9 @@ fn main() { Some(&buf), true, ); - let addr = aocs_tm_store.add_pus_tm(&pus_tm); + let addr = aocs_tm_store + .add_pus_tm(&pus_tm) + .expect("Adding PUS TM failed"); aocs_tm_funnel.send(addr).expect("Sending HK TM failed"); } } diff --git a/satrs-example/src/pus/action.rs b/satrs-example/src/pus/action.rs index ed69c35..ab7885b 100644 --- a/satrs-example/src/pus/action.rs +++ b/satrs-example/src/pus/action.rs @@ -86,7 +86,7 @@ impl PusService8ActionHandler { ), ) .expect("Sending start failure failed"); - return Err(PusPacketHandlingError::OtherError(format!( + return Err(PusPacketHandlingError::Other(format!( "Unknown target ID {target_id}" ))); } From 92147a00b315e2295598a3c162e5e2967c051802 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 9 Jul 2023 20:19:53 +0200 Subject: [PATCH 08/11] im done --- satrs-core/src/pus/event_srv.rs | 21 +++++------ satrs-core/src/pus/mod.rs | 56 ++++++++++++++++------------- satrs-core/src/pus/scheduler_srv.rs | 24 ++++++------- satrs-core/src/pus/test.rs | 20 +++++------ 4 files changed, 60 insertions(+), 61 deletions(-) diff --git a/satrs-core/src/pus/event_srv.rs b/satrs-core/src/pus/event_srv.rs index acf3537..2230200 100644 --- a/satrs-core/src/pus/event_srv.rs +++ b/satrs-core/src/pus/event_srv.rs @@ -1,5 +1,5 @@ use crate::events::EventU32; -use crate::pool::{SharedPool, StoreAddr}; +use crate::pool::{PoolGuard, SharedPool, StoreAddr}; use crate::pus::event_man::{EventRequest, EventRequestWithToken}; use crate::pus::verification::{ StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken, @@ -44,22 +44,16 @@ impl PusServiceHandler for PusService5EventHandler { fn handle_one_tc( &mut self, - tc_in_store_with_token: ReceivedTcWrapper, + tc: PusTc, + _tc_guard: PoolGuard, + token: VerificationToken, ) -> Result { - let ReceivedTcWrapper { - tc, - token, - pool_guard, - } = tc_in_store_with_token; - // TODO: Better token handling.. - let token = token.expect("invalid token"); - let accepted_token = VerificationToken::::try_from(token).unwrap(); let subservice = tc.subservice(); let srv = Subservice::try_from(subservice); if srv.is_err() { return Ok(PusPacketHandlerResult::CustomSubservice( tc.subservice(), - token, + token.into(), )); } let handle_enable_disable_request = |enable: bool, stamp: [u8; 7]| { @@ -74,7 +68,7 @@ impl PusServiceHandler for PusService5EventHandler { .psb .verification_handler .borrow_mut() - .start_success(accepted_token, Some(&stamp)) + .start_success(token, Some(&stamp)) .map_err(|_| PartialPusHandlingError::Verification); let partial_error = start_token.clone().err(); let mut token: TcStateToken = token.into(); @@ -121,7 +115,8 @@ impl PusServiceHandler for PusService5EventHandler { } Subservice::TcReportDisabledList | Subservice::TmDisabledEventsReport => { return Ok(PusPacketHandlerResult::SubserviceNotImplemented( - subservice, token, + subservice, + token.into(), )); } } diff --git a/satrs-core/src/pus/mod.rs b/satrs-core/src/pus/mod.rs index 7d7fc71..565aecf 100644 --- a/satrs-core/src/pus/mod.rs +++ b/satrs-core/src/pus/mod.rs @@ -282,7 +282,7 @@ mod alloc_mod { #[cfg(feature = "std")] pub mod std_mod { - use crate::pool::{SharedPool, StoreAddr}; + use crate::pool::{PoolGuard, SharedPool, StoreAddr}; use crate::pus::verification::{ StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken, }; @@ -394,11 +394,12 @@ pub mod std_mod { TryRecvError::Empty => GenericRecvError::Empty, TryRecvError::Disconnected => GenericRecvError::TxDisconnected, })?; - let shared_tc_pool = self + let mut shared_tc_pool = self .shared_tc_pool .read() .map_err(|_| EcssTmtcError::StoreLock)?; - let tc_raw = shared_tc_pool.read(&addr)?; + let pool_guard = shared_tc_pool.read_with_guard(addr); + let tc_raw = pool_guard.read()?; if buf.len() < tc_raw.len() { return Err( PusError::ByteConversion(ByteConversionError::ToSliceTooSmall(SizeMissmatch { @@ -410,7 +411,11 @@ pub mod std_mod { } buf[..tc_raw.len()].copy_from_slice(tc_raw); let (tc, _) = PusTc::from_bytes(buf)?; - Ok((tc, token)) + Ok((ReceivedTcWrapper { + tc, + pool_guard, + token: Some(token), + })) } } @@ -474,6 +479,8 @@ pub mod std_mod { InvalidAppData(String), #[error("generic ECSS tmtc error: {0}")] EcssTmtc(#[from] EcssTmtcError), + #[error("invalid verification token")] + InvalidVerificationToken, #[error("other error {0}")] Other(String), } @@ -564,30 +571,31 @@ pub mod std_mod { fn psb(&self) -> &PusServiceBase; fn handle_one_tc( &mut self, - tc_in_store_with_token: ReceivedTcWrapper, + tc: PusTc, + tc_guard: PoolGuard, + token: VerificationToken, ) -> Result; - fn copy_tc_to_buf(&mut self, addr: StoreAddr) -> Result<(), PusPacketHandlingError> { - // Keep locked section as short as possible. - let psb_mut = self.psb_mut(); - let mut tc_pool = psb_mut - .tc_store - .write() - .map_err(|_| PusPacketHandlingError::EcssTmtc(EcssTmtcError::StoreLock))?; - let tc_guard = tc_pool.read_with_guard(addr); - let tc_raw = tc_guard.read().unwrap(); - psb_mut.pus_buf[0..tc_raw.len()].copy_from_slice(tc_raw); - Ok(()) - } - fn handle_next_packet(&mut self) -> Result { - match self.psb().tc_receiver.recv_tc()? { - Ok((addr, token)) => self.handle_one_tc(addr, token), + match self.psb().tc_receiver.recv_tc(&mut self.psb_mut().pus_buf) { + Ok(ReceivedTcWrapper { + tc, + pool_guard, + token, + }) => { + if token.is_none() { + return Err(PusPacketHandlingError::InvalidVerificationToken); + } + let token = token.unwrap(); + self.handle_one_tc(tc, pool_guard, token.try_into().unwrap()) + } Err(e) => match e { - TryRecvError::Empty => Ok(PusPacketHandlerResult::Empty), - TryRecvError::Disconnected => Err(PusPacketHandlingError::EcssTmtc( - EcssTmtcError::Recv(GenericRecvError::TxDisconnected), - )), + EcssTmtcError::StoreLock => {} + EcssTmtcError::Store(_) => {} + EcssTmtcError::Pus(_) => {} + EcssTmtcError::CantSendAddr(_) => {} + EcssTmtcError::Send(_) => {} + EcssTmtcError::Recv(_) => {} }, } } diff --git a/satrs-core/src/pus/scheduler_srv.rs b/satrs-core/src/pus/scheduler_srv.rs index 46c1e99..059a66d 100644 --- a/satrs-core/src/pus/scheduler_srv.rs +++ b/satrs-core/src/pus/scheduler_srv.rs @@ -1,4 +1,4 @@ -use crate::pool::{SharedPool, StoreAddr}; +use crate::pool::{PoolGuard, SharedPool, StoreAddr}; use crate::pus::scheduler::PusScheduler; use crate::pus::verification::{StdVerifReporterWithSender, TcStateAccepted, VerificationToken}; use crate::pus::{ @@ -21,6 +21,7 @@ use std::sync::mpsc::Receiver; /// telecommands when applicable. pub struct PusService11SchedHandler { psb: PusServiceBase, + shared_tc_store: SharedPool, scheduler: PusScheduler, } @@ -30,10 +31,12 @@ impl PusService11SchedHandler { tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, + shared_tc_store: SharedPool, scheduler: PusScheduler, ) -> Self { Self { psb: PusServiceBase::new(tc_receiver, tm_sender, tm_apid, verification_handler), + shared_tc_store, scheduler, } } @@ -57,18 +60,15 @@ impl PusServiceHandler for PusService11SchedHandler { fn handle_one_tc( &mut self, - tc_in_store_with_token: ReceivedTcWrapper, + tc: PusTc, + tc_guard: PoolGuard, + token: VerificationToken, ) -> Result { - let ReceivedTcWrapper { - tc, - pool_guard, - token, - } = tc_in_store_with_token; let std_service = scheduling::Subservice::try_from(tc.subservice()); if std_service.is_err() { return Ok(PusPacketHandlerResult::CustomSubservice( tc.subservice(), - token, + token.into(), )); } let mut partial_error = None; @@ -120,7 +120,7 @@ impl PusServiceHandler for PusService11SchedHandler { .start_success(token, Some(&time_stamp)) .expect("Error sending start success"); - let mut pool = self.psb.tc_store.write().expect("Locking pool failed"); + let mut pool = self.shared_tc_store.write().expect("Locking pool failed"); self.scheduler .reset(pool.as_mut()) @@ -140,7 +140,7 @@ impl PusServiceHandler for PusService11SchedHandler { .start_success(token, Some(&time_stamp)) .expect("error sending start success"); - let mut pool = self.psb.tc_store.write().expect("locking pool failed"); + let mut pool = self.shared_tc_store.write().expect("locking pool failed"); self.scheduler .insert_wrapped_tc::(&tc, pool.as_mut()) .expect("insertion of activity into pool failed"); @@ -154,7 +154,7 @@ impl PusServiceHandler for PusService11SchedHandler { _ => { return Ok(PusPacketHandlerResult::CustomSubservice( tc.subservice(), - token, + token.into(), )); } } @@ -165,7 +165,7 @@ impl PusServiceHandler for PusService11SchedHandler { } Ok(PusPacketHandlerResult::CustomSubservice( tc.subservice(), - token, + token.into(), )) } } diff --git a/satrs-core/src/pus/test.rs b/satrs-core/src/pus/test.rs index d1317dd..f593b3e 100644 --- a/satrs-core/src/pus/test.rs +++ b/satrs-core/src/pus/test.rs @@ -1,7 +1,7 @@ -use crate::pool::{SharedPool, StoreAddr}; +use crate::pool::{PoolGuard, SharedPool, StoreAddr}; use crate::pus::verification::{StdVerifReporterWithSender, TcStateAccepted, VerificationToken}; use crate::pus::{ - AcceptedTc, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, + AcceptedTc, EcssTcReceiver, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, PusServiceHandler, PusTmWrapper, ReceivedTcWrapper, }; use spacepackets::ecss::PusPacket; @@ -19,14 +19,13 @@ pub struct PusService17TestHandler { impl PusService17TestHandler { pub fn new( - receiver: Receiver, - tc_pool: SharedPool, + tc_receiver: Box, tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, ) -> Self { Self { - psb: PusServiceBase::new(receiver, tc_pool, tm_sender, tm_apid, verification_handler), + psb: PusServiceBase::new(tc_receiver, tm_sender, tm_apid, verification_handler), } } } @@ -41,13 +40,10 @@ impl PusServiceHandler for PusService17TestHandler { fn handle_one_tc( &mut self, - tc_in_store_with_token: ReceivedTcWrapper, + tc: PusTc, + _tc_guard: PoolGuard, + token: VerificationToken, ) -> Result { - let ReceivedTcWrapper { - tc, - pool_guard, - token, - } = tc_in_store_with_token; if tc.service() != 17 { return Err(PusPacketHandlingError::WrongService(tc.service())); } @@ -99,7 +95,7 @@ impl PusServiceHandler for PusService17TestHandler { } Ok(PusPacketHandlerResult::CustomSubservice( tc.subservice(), - token, + token.into(), )) } } From fffd1af81facd78fc2f1855c8e720a52241aba36 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 10 Jul 2023 00:29:31 +0200 Subject: [PATCH 09/11] that was insane --- satrs-core/Cargo.toml | 2 +- satrs-core/src/event_man.rs | 36 +++--- satrs-core/src/lib.rs | 4 +- satrs-core/src/pus/event.rs | 10 +- satrs-core/src/pus/event_man.rs | 2 +- satrs-core/src/pus/event_srv.rs | 27 +++-- satrs-core/src/pus/mod.rs | 168 +++++++++++++++------------ satrs-core/src/pus/scheduler_srv.rs | 45 ++++--- satrs-core/src/pus/test.rs | 48 ++++---- satrs-core/src/pus/verification.rs | 86 +++++--------- satrs-core/src/tmtc/tm_helper.rs | 2 +- satrs-core/tests/pus_verification.rs | 11 +- satrs-example/src/lib.rs | 10 ++ satrs-example/src/main.rs | 70 ++++++++--- satrs-example/src/pus/action.rs | 16 ++- satrs-example/src/pus/hk.rs | 16 ++- satrs-example/src/pus/mod.rs | 20 ++-- satrs-example/src/tmtc.rs | 6 +- 18 files changed, 324 insertions(+), 255 deletions(-) diff --git a/satrs-core/Cargo.toml b/satrs-core/Cargo.toml index 41e977e..22e9d5b 100644 --- a/satrs-core/Cargo.toml +++ b/satrs-core/Cargo.toml @@ -64,7 +64,7 @@ optional = true # version = "0.6" # path = "../spacepackets" git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git" -rev = "e3d2d885385" +rev = "784564a20ed" default-features = false [dev-dependencies] diff --git a/satrs-core/src/event_man.rs b/satrs-core/src/event_man.rs index 3fb8d68..c3d6182 100644 --- a/satrs-core/src/event_man.rs +++ b/satrs-core/src/event_man.rs @@ -66,7 +66,7 @@ use core::slice::Iter; #[cfg(feature = "alloc")] use hashbrown::HashMap; -use crate::SenderId; +use crate::ChannelId; #[cfg(feature = "std")] pub use stdmod::*; @@ -88,7 +88,7 @@ pub type EventU16WithAuxData = EventWithAuxData; pub trait SendEventProvider { type Error; - fn id(&self) -> SenderId; + fn id(&self) -> ChannelId; fn send_no_data(&self, event: Provider) -> Result<(), Self::Error> { self.send(event, None) } @@ -109,16 +109,16 @@ pub trait EventReceiver { pub trait ListenerTable { fn get_listeners(&self) -> Vec; fn contains_listener(&self, key: &ListenerKey) -> bool; - fn get_listener_ids(&self, key: &ListenerKey) -> Option>; - fn add_listener(&mut self, key: ListenerKey, sender_id: SenderId) -> bool; + fn get_listener_ids(&self, key: &ListenerKey) -> Option>; + fn add_listener(&mut self, key: ListenerKey, sender_id: ChannelId) -> bool; fn remove_duplicates(&mut self, key: &ListenerKey); } pub trait SenderTable { - fn contains_send_event_provider(&self, id: &SenderId) -> bool; + fn contains_send_event_provider(&self, id: &ChannelId) -> bool; fn get_send_event_provider( &mut self, - id: &SenderId, + id: &ChannelId, ) -> Option<&mut Box>>; fn add_send_event_provider( &mut self, @@ -171,7 +171,7 @@ pub enum EventRoutingResult { pub enum EventRoutingError { SendError(E), NoSendersForKey(ListenerKey), - NoSenderForId(SenderId), + NoSenderForId(ChannelId), } #[derive(Debug)] @@ -186,12 +186,12 @@ impl EventManager { } /// Subscribe for a unique event. - pub fn subscribe_single(&mut self, event: &Event, sender_id: SenderId) { + pub fn subscribe_single(&mut self, event: &Event, sender_id: ChannelId) { self.update_listeners(ListenerKey::Single(event.raw_as_largest_type()), sender_id); } /// Subscribe for an event group. - pub fn subscribe_group(&mut self, group_id: LargestGroupIdRaw, sender_id: SenderId) { + pub fn subscribe_group(&mut self, group_id: LargestGroupIdRaw, sender_id: ChannelId) { self.update_listeners(ListenerKey::Group(group_id), sender_id); } @@ -199,7 +199,7 @@ impl EventManager { /// /// For example, this can be useful for a handler component which sends every event as /// a telemetry packet. - pub fn subscribe_all(&mut self, sender_id: SenderId) { + pub fn subscribe_all(&mut self, sender_id: ChannelId) { self.update_listeners(ListenerKey::All, sender_id); } } @@ -245,7 +245,7 @@ impl } } - fn update_listeners(&mut self, key: ListenerKey, sender_id: SenderId) { + fn update_listeners(&mut self, key: ListenerKey, sender_id: ChannelId) { self.listener_table.add_listener(key, sender_id); } @@ -311,7 +311,7 @@ impl #[derive(Default)] pub struct DefaultListenerTableProvider { - listeners: HashMap>, + listeners: HashMap>, } pub struct DefaultSenderTableProvider< @@ -320,7 +320,7 @@ pub struct DefaultSenderTableProvider< AuxDataProvider = Params, > { senders: HashMap< - SenderId, + ChannelId, Box>, >, } @@ -348,11 +348,11 @@ impl ListenerTable for DefaultListenerTableProvider { self.listeners.contains_key(key) } - fn get_listener_ids(&self, key: &ListenerKey) -> Option> { + fn get_listener_ids(&self, key: &ListenerKey) -> Option> { self.listeners.get(key).map(|vec| vec.iter()) } - fn add_listener(&mut self, key: ListenerKey, sender_id: SenderId) -> bool { + fn add_listener(&mut self, key: ListenerKey, sender_id: ChannelId) -> bool { if let Some(existing_list) = self.listeners.get_mut(&key) { existing_list.push(sender_id); } else { @@ -374,13 +374,13 @@ impl SenderTable for DefaultSenderTableProvider { - fn contains_send_event_provider(&self, id: &SenderId) -> bool { + fn contains_send_event_provider(&self, id: &ChannelId) -> bool { self.senders.contains_key(id) } fn get_send_event_provider( &mut self, - id: &SenderId, + id: &ChannelId, ) -> Option<&mut Box>> { self.senders.get_mut(id).filter(|sender| sender.id() == *id) @@ -486,7 +486,7 @@ mod tests { fn id(&self) -> u32 { self.id } - fn send(&mut self, event: EventU32, aux_data: Option) -> Result<(), Self::Error> { + fn send(&self, event: EventU32, aux_data: Option) -> Result<(), Self::Error> { self.mpsc_sender.send((event, aux_data)) } } diff --git a/satrs-core/src/lib.rs b/satrs-core/src/lib.rs index 4fed5c6..940300e 100644 --- a/satrs-core/src/lib.rs +++ b/satrs-core/src/lib.rs @@ -45,5 +45,5 @@ pub mod tmtc; pub use spacepackets; -// Generic sender ID type. -pub type SenderId = u32; +// Generic channel ID type. +pub type ChannelId = u32; diff --git a/satrs-core/src/pus/event.rs b/satrs-core/src/pus/event.rs index b1faf74..c1dfc5d 100644 --- a/satrs-core/src/pus/event.rs +++ b/satrs-core/src/pus/event.rs @@ -244,7 +244,7 @@ mod tests { use crate::events::{EventU32, Severity}; use crate::pus::tests::CommonTmInfo; use crate::pus::{EcssChannel, PusTmWrapper}; - use crate::SenderId; + use crate::ChannelId; use spacepackets::ByteConversionError; use std::cell::RefCell; use std::collections::VecDeque; @@ -269,7 +269,7 @@ mod tests { } impl EcssChannel for TestSender { - fn id(&self) -> SenderId { + fn id(&self) -> ChannelId { 0 } } @@ -425,9 +425,9 @@ mod tests { let err = reporter.event_info(sender, &time_stamp_empty, event, None); assert!(err.is_err()); let err = err.unwrap_err(); - if let EcssTmtcError::EcssTmtcError(EcssTmtcError::ByteConversion( - ByteConversionError::ToSliceTooSmall(missmatch), - )) = err + if let EcssTmtcError::Pus(PusError::ByteConversion(ByteConversionError::ToSliceTooSmall( + missmatch, + ))) = err { assert_eq!(missmatch.expected, 4); assert_eq!(missmatch.found, expected_found_len); diff --git a/satrs-core/src/pus/event_man.rs b/satrs-core/src/pus/event_man.rs index 4c9b6d8..132e24c 100644 --- a/satrs-core/src/pus/event_man.rs +++ b/satrs-core/src/pus/event_man.rs @@ -223,7 +223,7 @@ pub mod alloc_mod { self.backend.disable_event_reporting(event.as_ref()) } - pub fn generate_pus_event_tm( + pub fn generate_pus_event_tm( &mut self, sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: &[u8], diff --git a/satrs-core/src/pus/event_srv.rs b/satrs-core/src/pus/event_srv.rs index 2230200..8f3abb4 100644 --- a/satrs-core/src/pus/event_srv.rs +++ b/satrs-core/src/pus/event_srv.rs @@ -1,18 +1,18 @@ use crate::events::EventU32; -use crate::pool::{PoolGuard, SharedPool, StoreAddr}; +use crate::pool::{SharedPool, StoreAddr}; use crate::pus::event_man::{EventRequest, EventRequestWithToken}; use crate::pus::verification::{ StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken, }; use crate::pus::{ - AcceptedTc, EcssTcReceiver, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, - PusPacketHandlingError, PusServiceBase, PusServiceHandler, ReceivedTcWrapper, + EcssTcReceiver, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, + PusPacketHandlingError, PusServiceBase, PusServiceHandler, }; use spacepackets::ecss::event::Subservice; use spacepackets::ecss::PusPacket; use spacepackets::tc::PusTc; use std::boxed::Box; -use std::sync::mpsc::{Receiver, Sender}; +use std::sync::mpsc::Sender; pub struct PusService5EventHandler { psb: PusServiceBase, @@ -22,13 +22,20 @@ pub struct PusService5EventHandler { impl PusService5EventHandler { pub fn new( tc_receiver: Box, + shared_tc_store: SharedPool, tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, event_request_tx: Sender, ) -> Self { Self { - psb: PusServiceBase::new(tc_receiver, tm_sender, tm_apid, verification_handler), + psb: PusServiceBase::new( + tc_receiver, + shared_tc_store, + tm_sender, + tm_apid, + verification_handler, + ), event_request_tx, } } @@ -44,16 +51,17 @@ impl PusServiceHandler for PusService5EventHandler { fn handle_one_tc( &mut self, - tc: PusTc, - _tc_guard: PoolGuard, + addr: StoreAddr, token: VerificationToken, ) -> Result { + self.copy_tc_to_buf(addr)?; + let (tc, _) = PusTc::from_bytes(&self.psb.pus_buf)?; let subservice = tc.subservice(); let srv = Subservice::try_from(subservice); if srv.is_err() { return Ok(PusPacketHandlerResult::CustomSubservice( tc.subservice(), - token.into(), + token, )); } let handle_enable_disable_request = |enable: bool, stamp: [u8; 7]| { @@ -115,8 +123,7 @@ impl PusServiceHandler for PusService5EventHandler { } Subservice::TcReportDisabledList | Subservice::TmDisabledEventsReport => { return Ok(PusPacketHandlerResult::SubserviceNotImplemented( - subservice, - token.into(), + subservice, token, )); } } diff --git a/satrs-core/src/pus/mod.rs b/satrs-core/src/pus/mod.rs index 565aecf..0defc10 100644 --- a/satrs-core/src/pus/mod.rs +++ b/satrs-core/src/pus/mod.rs @@ -2,7 +2,7 @@ //! //! This module contains structures to make working with the PUS C standard easier. //! The satrs-example application contains various usage examples of these components. -use crate::SenderId; +use crate::ChannelId; use core::fmt::{Display, Formatter}; #[cfg(feature = "alloc")] use downcast_rs::{impl_downcast, Downcast}; @@ -28,7 +28,7 @@ pub mod verification; #[cfg(feature = "alloc")] pub use alloc_mod::*; -use crate::pool::{PoolGuard, PoolRwGuard, StoreAddr, StoreError}; +use crate::pool::{StoreAddr, StoreError}; use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken}; #[cfg(feature = "std")] pub use std_mod::*; @@ -175,7 +175,7 @@ impl Error for EcssTmtcError { } pub trait EcssChannel: Send { /// Each sender can have an ID associated with it - fn id(&self) -> SenderId; + fn id(&self) -> ChannelId; fn name(&self) -> &'static str { "unset" } @@ -196,15 +196,38 @@ pub trait EcssTcSenderCore: EcssChannel { fn send_tc(&self, tc: PusTc, token: Option) -> Result<(), EcssTmtcError>; } -pub struct ReceivedTcWrapper<'raw_tc> { - pub pool_guard: PoolGuard<'raw_tc>, - pub tc: PusTc<'raw_tc>, +pub struct ReceivedTcWrapper { + pub store_addr: StoreAddr, pub token: Option, } +#[derive(Debug, Clone)] +pub enum TryRecvTmtcError { + Error(EcssTmtcError), + Empty, +} + +impl From for TryRecvTmtcError { + fn from(value: EcssTmtcError) -> Self { + Self::Error(value) + } +} + +impl From for TryRecvTmtcError { + fn from(value: PusError) -> Self { + Self::Error(value.into()) + } +} + +impl From for TryRecvTmtcError { + fn from(value: StoreError) -> Self { + Self::Error(value.into()) + } +} + /// Generic trait for a user supplied receiver object. pub trait EcssTcReceiverCore: EcssChannel { - fn recv_tc<'buf>(&self, buf: &'buf mut [u8]) -> Result, EcssTmtcError>; + fn recv_tc(&self) -> Result; } /// Generic trait for objects which can receive ECSS PUS telecommands. This trait is @@ -271,37 +294,34 @@ mod alloc_mod { /// [Clone]. #[cfg(feature = "alloc")] #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] - pub trait EcssTcReceiver: EcssTcReceiverCore + Downcast + DynClone {} + pub trait EcssTcReceiver: EcssTcReceiverCore + Downcast {} /// Blanket implementation for all types which implement [EcssTcReceiverCore] and are clonable. - impl EcssTcReceiver for T where T: EcssTcReceiverCore + Clone + 'static {} + impl EcssTcReceiver for T where T: EcssTcReceiverCore + 'static {} - dyn_clone::clone_trait_object!(EcssTcReceiver); impl_downcast!(EcssTcReceiver); } #[cfg(feature = "std")] pub mod std_mod { - use crate::pool::{PoolGuard, SharedPool, StoreAddr}; + use crate::pool::{SharedPool, StoreAddr}; use crate::pus::verification::{ - StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken, + StdVerifReporterWithSender, TcStateAccepted, VerificationToken, }; use crate::pus::{ - AcceptedTc, EcssChannel, EcssTcReceiver, EcssTcReceiverCore, EcssTmSender, - EcssTmSenderCore, EcssTmtcError, GenericRecvError, GenericSendError, PusTmWrapper, - ReceivedTcWrapper, TcAddrWithToken, + EcssChannel, EcssTcReceiver, EcssTcReceiverCore, EcssTmSender, EcssTmSenderCore, + EcssTmtcError, GenericRecvError, GenericSendError, PusTmWrapper, ReceivedTcWrapper, + TcAddrWithToken, TryRecvTmtcError, }; use crate::tmtc::tm_helper::SharedTmStore; - use crate::SenderId; + use crate::ChannelId; use alloc::boxed::Box; use alloc::vec::Vec; use spacepackets::ecss::PusError; - use spacepackets::tc::PusTc; use spacepackets::time::cds::TimeProvider; - use spacepackets::time::std_mod::StdTimestampError; + use spacepackets::time::StdTimestampError; use spacepackets::time::TimeWriter; use spacepackets::tm::PusTm; - use spacepackets::{ByteConversionError, SizeMissmatch}; use std::cell::RefCell; use std::string::String; use std::sync::mpsc; @@ -310,7 +330,7 @@ pub mod std_mod { #[derive(Clone)] pub struct MpscTmInStoreSender { - id: SenderId, + id: ChannelId, name: &'static str, shared_tm_store: SharedTmStore, sender: mpsc::Sender, @@ -318,7 +338,7 @@ pub mod std_mod { } impl EcssChannel for MpscTmInStoreSender { - fn id(&self) -> SenderId { + fn id(&self) -> ChannelId { self.id } @@ -352,7 +372,7 @@ pub mod std_mod { impl MpscTmInStoreSender { pub fn new( - id: SenderId, + id: ChannelId, name: &'static str, shared_tm_store: SharedTmStore, sender: mpsc::Sender, @@ -368,15 +388,14 @@ pub mod std_mod { } pub struct MpscTcInStoreReceiver { - id: SenderId, + id: ChannelId, name: &'static str, - shared_tc_pool: SharedPool, receiver: mpsc::Receiver, pub ignore_poison_errors: bool, } impl EcssChannel for MpscTcInStoreReceiver { - fn id(&self) -> SenderId { + fn id(&self) -> ChannelId { self.id } @@ -386,36 +405,32 @@ pub mod std_mod { } impl EcssTcReceiverCore for MpscTcInStoreReceiver { - fn recv_tc<'buf>( - &self, - buf: &'buf mut [u8], - ) -> Result, EcssTmtcError> { - let (addr, token) = self.receiver.try_recv().map_err(|e| match e { - TryRecvError::Empty => GenericRecvError::Empty, - TryRecvError::Disconnected => GenericRecvError::TxDisconnected, + fn recv_tc(&self) -> Result { + let (store_addr, token) = self.receiver.try_recv().map_err(|e| match e { + TryRecvError::Empty => TryRecvTmtcError::Empty, + TryRecvError::Disconnected => { + TryRecvTmtcError::Error(EcssTmtcError::from(GenericRecvError::TxDisconnected)) + } })?; - let mut shared_tc_pool = self - .shared_tc_pool - .read() - .map_err(|_| EcssTmtcError::StoreLock)?; - let pool_guard = shared_tc_pool.read_with_guard(addr); - let tc_raw = pool_guard.read()?; - if buf.len() < tc_raw.len() { - return Err( - PusError::ByteConversion(ByteConversionError::ToSliceTooSmall(SizeMissmatch { - found: buf.len(), - expected: tc_raw.len(), - })) - .into(), - ); - } - buf[..tc_raw.len()].copy_from_slice(tc_raw); - let (tc, _) = PusTc::from_bytes(buf)?; - Ok((ReceivedTcWrapper { - tc, - pool_guard, + Ok(ReceivedTcWrapper { + store_addr, token: Some(token), - })) + }) + } + } + + impl MpscTcInStoreReceiver { + pub fn new( + id: ChannelId, + name: &'static str, + receiver: mpsc::Receiver, + ) -> Self { + Self { + id, + name, + receiver, + ignore_poison_errors: false, + } } } @@ -425,7 +440,7 @@ pub mod std_mod { /// going to be called with direct packets. #[derive(Clone)] pub struct MpscTmAsVecSender { - id: SenderId, + id: ChannelId, sender: mpsc::Sender>, name: &'static str, } @@ -443,7 +458,7 @@ pub mod std_mod { } impl EcssChannel for MpscTmAsVecSender { - fn id(&self) -> SenderId { + fn id(&self) -> ChannelId { self.id } fn name(&self) -> &'static str { @@ -502,8 +517,8 @@ pub mod std_mod { pub enum PusPacketHandlerResult { RequestHandled, RequestHandledPartialSuccess(PartialPusHandlingError), - SubserviceNotImplemented(u8, TcStateToken), - CustomSubservice(u8, TcStateToken), + SubserviceNotImplemented(u8, VerificationToken), + CustomSubservice(u8, VerificationToken), Empty, } @@ -518,6 +533,7 @@ pub mod std_mod { /// is constrained to the [StdVerifReporterWithSender]. pub struct PusServiceBase { pub tc_receiver: Box, + pub shared_tc_store: SharedPool, pub tm_sender: Box, pub tm_apid: u16, /// The verification handler is wrapped in a [RefCell] to allow the interior mutability @@ -530,12 +546,14 @@ pub mod std_mod { impl PusServiceBase { pub fn new( tc_receiver: Box, + shared_tc_store: SharedPool, tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, ) -> Self { Self { tc_receiver, + shared_tc_store, tm_apid, tm_sender, verification_handler: RefCell::new(verification_handler), @@ -571,31 +589,37 @@ pub mod std_mod { fn psb(&self) -> &PusServiceBase; fn handle_one_tc( &mut self, - tc: PusTc, - tc_guard: PoolGuard, + addr: StoreAddr, token: VerificationToken, ) -> Result; + fn copy_tc_to_buf(&mut self, addr: StoreAddr) -> Result<(), PusPacketHandlingError> { + // Keep locked section as short as possible. + let psb_mut = self.psb_mut(); + let mut tc_pool = psb_mut + .shared_tc_store + .write() + .map_err(|_| PusPacketHandlingError::EcssTmtc(EcssTmtcError::StoreLock))?; + let tc_guard = tc_pool.read_with_guard(addr); + let tc_raw = tc_guard.read().unwrap(); + psb_mut.pus_buf[0..tc_raw.len()].copy_from_slice(tc_raw); + Ok(()) + } + fn handle_next_packet(&mut self) -> Result { - match self.psb().tc_receiver.recv_tc(&mut self.psb_mut().pus_buf) { - Ok(ReceivedTcWrapper { - tc, - pool_guard, - token, - }) => { + match self.psb().tc_receiver.recv_tc() { + Ok(ReceivedTcWrapper { store_addr, token }) => { if token.is_none() { return Err(PusPacketHandlingError::InvalidVerificationToken); } let token = token.unwrap(); - self.handle_one_tc(tc, pool_guard, token.try_into().unwrap()) + let accepted_token = VerificationToken::::try_from(token) + .map_err(|_| PusPacketHandlingError::InvalidVerificationToken)?; + self.handle_one_tc(store_addr, accepted_token) } Err(e) => match e { - EcssTmtcError::StoreLock => {} - EcssTmtcError::Store(_) => {} - EcssTmtcError::Pus(_) => {} - EcssTmtcError::CantSendAddr(_) => {} - EcssTmtcError::Send(_) => {} - EcssTmtcError::Recv(_) => {} + TryRecvTmtcError::Error(e) => Err(PusPacketHandlingError::EcssTmtc(e)), + TryRecvTmtcError::Empty => Ok(PusPacketHandlerResult::Empty), }, } } diff --git a/satrs-core/src/pus/scheduler_srv.rs b/satrs-core/src/pus/scheduler_srv.rs index 059a66d..52fc33a 100644 --- a/satrs-core/src/pus/scheduler_srv.rs +++ b/satrs-core/src/pus/scheduler_srv.rs @@ -1,15 +1,14 @@ -use crate::pool::{PoolGuard, SharedPool, StoreAddr}; +use crate::pool::{SharedPool, StoreAddr}; use crate::pus::scheduler::PusScheduler; use crate::pus::verification::{StdVerifReporterWithSender, TcStateAccepted, VerificationToken}; use crate::pus::{ - AcceptedTc, EcssTcReceiver, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, - PusServiceBase, PusServiceHandler, ReceivedTcWrapper, + EcssTcReceiver, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, + PusServiceHandler, }; use spacepackets::ecss::{scheduling, PusPacket}; use spacepackets::tc::PusTc; use spacepackets::time::cds::TimeProvider; use std::boxed::Box; -use std::sync::mpsc::Receiver; /// This is a helper class for [std] environments to handle generic PUS 11 (scheduling service) /// packets. This handler is constrained to using the [PusScheduler], but is able to process @@ -21,22 +20,26 @@ use std::sync::mpsc::Receiver; /// telecommands when applicable. pub struct PusService11SchedHandler { psb: PusServiceBase, - shared_tc_store: SharedPool, scheduler: PusScheduler, } impl PusService11SchedHandler { pub fn new( tc_receiver: Box, + shared_tc_store: SharedPool, tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, - shared_tc_store: SharedPool, scheduler: PusScheduler, ) -> Self { Self { - psb: PusServiceBase::new(tc_receiver, tm_sender, tm_apid, verification_handler), - shared_tc_store, + psb: PusServiceBase::new( + tc_receiver, + shared_tc_store, + tm_sender, + tm_apid, + verification_handler, + ), scheduler, } } @@ -60,15 +63,17 @@ impl PusServiceHandler for PusService11SchedHandler { fn handle_one_tc( &mut self, - tc: PusTc, - tc_guard: PoolGuard, + addr: StoreAddr, token: VerificationToken, ) -> Result { - let std_service = scheduling::Subservice::try_from(tc.subservice()); + self.copy_tc_to_buf(addr)?; + let (tc, _) = PusTc::from_bytes(&self.psb.pus_buf)?; + let subservice = tc.subservice(); + let std_service = scheduling::Subservice::try_from(subservice); if std_service.is_err() { return Ok(PusPacketHandlerResult::CustomSubservice( tc.subservice(), - token.into(), + token, )); } let mut partial_error = None; @@ -120,7 +125,11 @@ impl PusServiceHandler for PusService11SchedHandler { .start_success(token, Some(&time_stamp)) .expect("Error sending start success"); - let mut pool = self.shared_tc_store.write().expect("Locking pool failed"); + let mut pool = self + .psb + .shared_tc_store + .write() + .expect("Locking pool failed"); self.scheduler .reset(pool.as_mut()) @@ -140,7 +149,11 @@ impl PusServiceHandler for PusService11SchedHandler { .start_success(token, Some(&time_stamp)) .expect("error sending start success"); - let mut pool = self.shared_tc_store.write().expect("locking pool failed"); + let mut pool = self + .psb + .shared_tc_store + .write() + .expect("locking pool failed"); self.scheduler .insert_wrapped_tc::(&tc, pool.as_mut()) .expect("insertion of activity into pool failed"); @@ -154,7 +167,7 @@ impl PusServiceHandler for PusService11SchedHandler { _ => { return Ok(PusPacketHandlerResult::CustomSubservice( tc.subservice(), - token.into(), + token, )); } } @@ -165,7 +178,7 @@ impl PusServiceHandler for PusService11SchedHandler { } Ok(PusPacketHandlerResult::CustomSubservice( tc.subservice(), - token.into(), + token, )) } } diff --git a/satrs-core/src/pus/test.rs b/satrs-core/src/pus/test.rs index f593b3e..178493b 100644 --- a/satrs-core/src/pus/test.rs +++ b/satrs-core/src/pus/test.rs @@ -1,15 +1,14 @@ -use crate::pool::{PoolGuard, SharedPool, StoreAddr}; +use crate::pool::{SharedPool, StoreAddr}; use crate::pus::verification::{StdVerifReporterWithSender, TcStateAccepted, VerificationToken}; use crate::pus::{ - AcceptedTc, EcssTcReceiver, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, - PusPacketHandlingError, PusServiceBase, PusServiceHandler, PusTmWrapper, ReceivedTcWrapper, + EcssTcReceiver, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult, + PusPacketHandlingError, PusServiceBase, PusServiceHandler, PusTmWrapper, }; use spacepackets::ecss::PusPacket; use spacepackets::tc::PusTc; use spacepackets::tm::{PusTm, PusTmSecondaryHeader}; use spacepackets::SpHeader; use std::boxed::Box; -use std::sync::mpsc::Receiver; /// This is a helper class for [std] environments to handle generic PUS 17 (test service) packets. /// This handler only processes ping requests and generates a ping reply for them accordingly. @@ -20,12 +19,19 @@ pub struct PusService17TestHandler { impl PusService17TestHandler { pub fn new( tc_receiver: Box, + shared_tc_store: SharedPool, tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, ) -> Self { Self { - psb: PusServiceBase::new(tc_receiver, tm_sender, tm_apid, verification_handler), + psb: PusServiceBase::new( + tc_receiver, + shared_tc_store, + tm_sender, + tm_apid, + verification_handler, + ), } } } @@ -40,10 +46,11 @@ impl PusServiceHandler for PusService17TestHandler { fn handle_one_tc( &mut self, - tc: PusTc, - _tc_guard: PoolGuard, + addr: StoreAddr, token: VerificationToken, ) -> Result { + self.copy_tc_to_buf(addr)?; + let (tc, _) = PusTc::from_bytes(&self.psb.pus_buf)?; if tc.service() != 17 { return Err(PusPacketHandlingError::WrongService(tc.service())); } @@ -95,7 +102,7 @@ impl PusServiceHandler for PusService17TestHandler { } Ok(PusPacketHandlerResult::CustomSubservice( tc.subservice(), - token.into(), + token, )) } } @@ -107,7 +114,7 @@ mod tests { use crate::pus::verification::{ RequestId, StdVerifReporterWithSender, VerificationReporterCfg, }; - use crate::pus::{MpscTmInStoreSender, PusServiceHandler}; + use crate::pus::{MpscTcInStoreReceiver, MpscTmInStoreSender, PusServiceHandler}; use crate::tmtc::tm_helper::SharedTmStore; use spacepackets::ecss::{PusPacket, SerializablePusPacket}; use spacepackets::tc::{PusTc, PusTcSecondaryHeader}; @@ -126,24 +133,21 @@ mod tests { let tc_pool = LocalPool::new(pool_cfg.clone()); let tm_pool = LocalPool::new(pool_cfg); let tc_pool_shared = SharedPool::new(RwLock::new(Box::new(tc_pool))); - let tm_pool_shared = SharedPool::new(RwLock::new(Box::new(tm_pool))); - let shared_tm_store = SharedTmStore::new(tm_pool_shared.clone()); - let (test_srv_tx, test_srv_rx) = mpsc::channel(); + let shared_tm_store = SharedTmStore::new(Box::new(tm_pool)); + let tm_pool_shared = shared_tm_store.clone_backing_pool(); + let (test_srv_tc_tx, test_srv_tc_rx) = mpsc::channel(); let (tm_tx, tm_rx) = mpsc::channel(); - let verif_sender = MpscTmInStoreSender::new( - 0, - "verif_sender", - shared_tm_store.backing_pool(), - tm_tx.clone(), - ); + let verif_sender = + MpscTmInStoreSender::new(0, "verif_sender", shared_tm_store.clone(), tm_tx.clone()); let verif_cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap(); let mut verification_handler = StdVerifReporterWithSender::new(&verif_cfg, Box::new(verif_sender)); + let test_srv_tm_sender = MpscTmInStoreSender::new(0, "TEST_SENDER", shared_tm_store, tm_tx); + let test_srv_tc_receiver = MpscTcInStoreReceiver::new(0, "TEST_RECEIVER", test_srv_tc_rx); let mut pus_17_handler = PusService17TestHandler::new( - test_srv_rx, + Box::new(test_srv_tc_receiver), tc_pool_shared.clone(), - tm_tx, - shared_tm_store, + Box::new(test_srv_tm_sender), TEST_APID, verification_handler.clone(), ); @@ -160,7 +164,7 @@ mod tests { let addr = tc_pool.add(&pus_buf[..tc_size]).unwrap(); drop(tc_pool); // Send accepted TC to test service handler. - test_srv_tx.send((addr, token)).unwrap(); + test_srv_tc_tx.send((addr, token.into())).unwrap(); let result = pus_17_handler.handle_next_packet(); assert!(result.is_ok()); // We should see 4 replies in the TM queue now: Acceptance TM, Start TM, ping reply and diff --git a/satrs-core/src/pus/verification.rs b/satrs-core/src/pus/verification.rs index 53f0c8f..1f25c90 100644 --- a/satrs-core/src/pus/verification.rs +++ b/satrs-core/src/pus/verification.rs @@ -19,6 +19,7 @@ //! use satrs_core::pus::verification::{VerificationReporterCfg, VerificationReporterWithSender}; //! use satrs_core::seq_count::SeqCountProviderSimple; //! use satrs_core::pus::MpscTmInStoreSender; +//! use satrs_core::tmtc::tm_helper::SharedTmStore; //! use spacepackets::ecss::PusPacket; //! use spacepackets::SpHeader; //! use spacepackets::tc::{PusTc, PusTcSecondaryHeader}; @@ -28,9 +29,11 @@ //! const TEST_APID: u16 = 0x02; //! //! let pool_cfg = PoolCfg::new(vec![(10, 32), (10, 64), (10, 128), (10, 1024)]); -//! let shared_tm_pool: SharedPool = Arc::new(RwLock::new(Box::new(LocalPool::new(pool_cfg.clone())))); +//! let tm_pool = LocalPool::new(pool_cfg.clone()); +//! let shared_tm_store = SharedTmStore::new(Box::new(tm_pool)); +//! let tm_store = shared_tm_store.clone_backing_pool(); //! let (verif_tx, verif_rx) = mpsc::channel(); -//! let sender = MpscTmInStoreSender::new(0, "Test Sender", shared_tm_pool.clone(), verif_tx); +//! let sender = MpscTmInStoreSender::new(0, "Test Sender", shared_tm_store, verif_tx); //! let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap(); //! let mut reporter = VerificationReporterWithSender::new(&cfg , Box::new(sender)); //! @@ -51,7 +54,7 @@ //! let addr = verif_rx.recv_timeout(Duration::from_millis(10)).unwrap(); //! let tm_len; //! { -//! let mut rg = shared_tm_pool.write().expect("Error locking shared pool"); +//! let mut rg = tm_store.write().expect("Error locking shared pool"); //! let store_guard = rg.read_with_guard(addr); //! let slice = store_guard.read().expect("Error reading TM slice"); //! tm_len = slice.len(); @@ -1491,25 +1494,26 @@ mod std_mod { #[cfg(test)] mod tests { - use crate::pool::{LocalPool, PoolCfg, SharedPool}; + use crate::pool::{LocalPool, PoolCfg}; use crate::pus::tests::CommonTmInfo; use crate::pus::verification::{ EcssTmSenderCore, EcssTmtcError, FailParams, FailParamsWithStep, RequestId, TcStateNone, VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender, VerificationToken, }; - use crate::pus::{EcssChannel, EcssTmtcError, MpscTmInStoreSender, PusTmWrapper}; - use crate::SenderId; + use crate::pus::{EcssChannel, MpscTmInStoreSender, PusTmWrapper}; + use crate::tmtc::tm_helper::SharedTmStore; + use crate::ChannelId; use alloc::boxed::Box; use alloc::format; - use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU8, PusPacket}; + use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU8, PusError, PusPacket}; use spacepackets::tc::{PusTc, PusTcSecondaryHeader}; use spacepackets::tm::PusTm; use spacepackets::util::UnsignedEnum; use spacepackets::{ByteConversionError, CcsdsPacket, SpHeader}; use std::cell::RefCell; use std::collections::VecDeque; - use std::sync::{mpsc, Arc, RwLock}; + use std::sync::mpsc; use std::time::Duration; use std::vec; use std::vec::Vec; @@ -1534,7 +1538,7 @@ mod tests { } impl EcssChannel for TestSender { - fn id(&self) -> SenderId { + fn id(&self) -> ChannelId { 0 } fn name(&self) -> &'static str { @@ -1543,9 +1547,7 @@ mod tests { } impl EcssTmSenderCore for TestSender { - type Error = (); - - fn send_tm(&self, tm: PusTmWrapper) -> Result<(), Self::Error> { + fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcError> { match tm { PusTmWrapper::InStore(_) => { panic!("TestSender: Can not deal with addresses"); @@ -1576,23 +1578,6 @@ mod tests { } } - #[derive(Debug, Copy, Clone, Eq, PartialEq)] - struct DummyError {} - #[derive(Default, Clone)] - struct FallibleSender {} - - impl EcssChannel for FallibleSender { - fn id(&self) -> SenderId { - 0 - } - } - impl EcssTmSenderCore for FallibleSender { - type Error = DummyError; - fn send_tm(&self, _: PusTmWrapper) -> Result<(), Self::Error> { - Err(DummyError {}) - } - } - struct TestBase<'a> { vr: VerificationReporter, #[allow(dead_code)] @@ -1604,13 +1589,13 @@ mod tests { &mut self.vr } } - struct TestBaseWithHelper<'a, E> { - helper: VerificationReporterWithSender, + struct TestBaseWithHelper<'a> { + helper: VerificationReporterWithSender, #[allow(dead_code)] tc: PusTc<'a>, } - impl<'a, E> TestBaseWithHelper<'a, E> { + impl<'a> TestBaseWithHelper<'a> { fn rep(&mut self) -> &mut VerificationReporter { &mut self.helper.reporter } @@ -1641,10 +1626,7 @@ mod tests { (TestBase { vr: reporter, tc }, init_tok) } - fn base_with_helper_init() -> ( - TestBaseWithHelper<'static, ()>, - VerificationToken, - ) { + fn base_with_helper_init() -> (TestBaseWithHelper<'static>, VerificationToken) { let mut reporter = base_reporter(); let (tc, _) = base_tc_init(None); let init_tok = reporter.add_tc(&tc); @@ -1674,9 +1656,10 @@ mod tests { #[test] fn test_mpsc_verif_send_sync() { let pool = LocalPool::new(PoolCfg::new(vec![(8, 8)])); - let shared_pool: SharedPool = Arc::new(RwLock::new(Box::new(pool))); + let tm_store = Box::new(pool); + let shared_tm_store = SharedTmStore::new(tm_store); let (tx, _) = mpsc::channel(); - let mpsc_verif_sender = MpscTmInStoreSender::new(0, "verif_sender", shared_pool, tx); + let mpsc_verif_sender = MpscTmInStoreSender::new(0, "verif_sender", shared_tm_store, tx); is_send(&mpsc_verif_sender); } @@ -1707,23 +1690,6 @@ mod tests { acceptance_check(sender, &tok.req_id); } - #[test] - fn test_acceptance_send_fails() { - let (mut b, tok) = base_init(false); - let mut faulty_sender = FallibleSender::default(); - let res = - b.vr.acceptance_success(tok, &mut faulty_sender, Some(&EMPTY_STAMP)); - assert!(res.is_err()); - let err = res.unwrap_err(); - assert_eq!(err.1, tok); - match err.0 { - EcssTmtcError::SendError(e) => { - assert_eq!(e, DummyError {}) - } - _ => panic!("{}", format!("Unexpected error {:?}", err.0)), - } - } - fn acceptance_fail_check(sender: &mut TestSender, req_id: RequestId, stamp_buf: [u8; 7]) { let cmp_info = TmInfo { common: CommonTmInfo { @@ -1788,7 +1754,7 @@ mod tests { let err_with_token = res.unwrap_err(); assert_eq!(err_with_token.1, tok); match err_with_token.0 { - EcssTmtcError::EcssTmtcError(EcssTmtcError::ByteConversion(e)) => match e { + EcssTmtcError::Pus(PusError::ByteConversion(e)) => match e { ByteConversionError::ToSliceTooSmall(missmatch) => { assert_eq!( missmatch.expected, @@ -2357,11 +2323,11 @@ mod tests { // TODO: maybe a bit more extensive testing, all I have time for right now fn test_seq_count_increment() { let pool_cfg = PoolCfg::new(vec![(10, 32), (10, 64), (10, 128), (10, 1024)]); - let shared_tm_pool: SharedPool = - Arc::new(RwLock::new(Box::new(LocalPool::new(pool_cfg.clone())))); + let tm_pool = Box::new(LocalPool::new(pool_cfg.clone())); + let shared_tm_store = SharedTmStore::new(tm_pool); + let shared_tm_pool = shared_tm_store.clone_backing_pool(); let (verif_tx, verif_rx) = mpsc::channel(); - let sender = - MpscTmInStoreSender::new(0, "Verification Sender", shared_tm_pool.clone(), verif_tx); + let sender = MpscTmInStoreSender::new(0, "Verification Sender", shared_tm_store, verif_tx); let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap(); let mut reporter = VerificationReporterWithSender::new(&cfg, Box::new(sender)); diff --git a/satrs-core/src/tmtc/tm_helper.rs b/satrs-core/src/tmtc/tm_helper.rs index 5c960b9..da2bc1e 100644 --- a/satrs-core/src/tmtc/tm_helper.rs +++ b/satrs-core/src/tmtc/tm_helper.rs @@ -26,7 +26,7 @@ pub mod std_mod { } } - pub fn backing_pool(&self) -> SharedPool { + pub fn clone_backing_pool(&self) -> SharedPool { self.pool.clone() } diff --git a/satrs-core/tests/pus_verification.rs b/satrs-core/tests/pus_verification.rs index 313bc84..a533dbc 100644 --- a/satrs-core/tests/pus_verification.rs +++ b/satrs-core/tests/pus_verification.rs @@ -3,11 +3,12 @@ #[cfg(feature = "crossbeam")] pub mod crossbeam_test { use hashbrown::HashMap; - use satrs_core::pool::{LocalPool, PoolCfg, PoolProvider, SharedPool}; + use satrs_core::pool::{LocalPool, PoolCfg, PoolProvider}; use satrs_core::pus::verification::{ FailParams, RequestId, VerificationReporterCfg, VerificationReporterWithSender, }; use satrs_core::pus::MpscTmInStoreSender; + use satrs_core::tmtc::tm_helper::SharedTmStore; use spacepackets::ecss::{EcssEnumU16, EcssEnumU8, PusPacket, SerializablePusPacket}; use spacepackets::tc::{PusTc, PusTcSecondaryHeader}; use spacepackets::tm::PusTm; @@ -35,13 +36,12 @@ pub mod crossbeam_test { let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap(); // Shared pool object to store the verification PUS telemetry let pool_cfg = PoolCfg::new(vec![(10, 32), (10, 64), (10, 128), (10, 1024)]); - let shared_tm_pool: SharedPool = - Arc::new(RwLock::new(Box::new(LocalPool::new(pool_cfg.clone())))); + let shared_tm_store = SharedTmStore::new(Box::new(LocalPool::new(pool_cfg.clone()))); let shared_tc_pool_0 = Arc::new(RwLock::new(LocalPool::new(pool_cfg))); let shared_tc_pool_1 = shared_tc_pool_0.clone(); let (tx, rx) = mpsc::channel(); let sender = - MpscTmInStoreSender::new(0, "verif_sender", shared_tm_pool.clone(), tx.clone()); + MpscTmInStoreSender::new(0, "verif_sender", shared_tm_store.clone(), tx.clone()); let mut reporter_with_sender_0 = VerificationReporterWithSender::new(&cfg, Box::new(sender)); let mut reporter_with_sender_1 = reporter_with_sender_0.clone(); @@ -146,8 +146,9 @@ pub mod crossbeam_test { .recv_timeout(Duration::from_millis(50)) .expect("Packet reception timeout"); let tm_len; + let shared_tm_store = shared_tm_store.clone_backing_pool(); { - let mut rg = shared_tm_pool.write().expect("Error locking shared pool"); + let mut rg = shared_tm_store.write().expect("Error locking shared pool"); let store_guard = rg.read_with_guard(verif_addr); let slice = store_guard.read().expect("Error reading TM slice"); tm_len = slice.len(); diff --git a/satrs-example/src/lib.rs b/satrs-example/src/lib.rs index 0e77dad..31fb63d 100644 --- a/satrs-example/src/lib.rs +++ b/satrs-example/src/lib.rs @@ -83,4 +83,14 @@ pub enum TmSenderId { PusHk = 3, PusAction = 4, PusSched = 5, + AllEvents = 6, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum TcReceiverId { + PusTest = 1, + PusEvent = 2, + PusHk = 3, + PusAction = 4, + PusSched = 5, } diff --git a/satrs-example/src/main.rs b/satrs-example/src/main.rs index 9f1be77..e6a4241 100644 --- a/satrs-example/src/main.rs +++ b/satrs-example/src/main.rs @@ -32,8 +32,10 @@ use satrs_core::pus::hk::Subservice as HkSubservice; use satrs_core::pus::scheduler::PusScheduler; use satrs_core::pus::scheduler_srv::PusService11SchedHandler; use satrs_core::pus::test::PusService17TestHandler; -use satrs_core::pus::verification::{VerificationReporterCfg, VerificationReporterWithSender}; -use satrs_core::pus::MpscTmInStoreSender; +use satrs_core::pus::verification::{ + TcStateStarted, VerificationReporterCfg, VerificationReporterWithSender, VerificationToken, +}; +use satrs_core::pus::{MpscTcInStoreReceiver, MpscTmInStoreSender}; use satrs_core::seq_count::{CcsdsSimpleSeqCountProvider, SequenceCountProviderCore}; use satrs_core::spacepackets::tm::PusTmZeroCopyWriter; use satrs_core::spacepackets::{ @@ -44,8 +46,8 @@ use satrs_core::spacepackets::{ }; use satrs_core::tmtc::tm_helper::SharedTmStore; use satrs_core::tmtc::{AddressableId, TargetId}; -use satrs_core::SenderId; -use satrs_example::{RequestTargetId, TmSenderId, OBSW_SERVER_ADDR, SERVER_PORT}; +use satrs_core::ChannelId; +use satrs_example::{RequestTargetId, TcReceiverId, TmSenderId, OBSW_SERVER_ADDR, SERVER_PORT}; use std::collections::HashMap; use std::net::{IpAddr, SocketAddr}; use std::sync::mpsc::{channel, TryRecvError}; @@ -85,7 +87,7 @@ fn main() { let (tm_funnel_tx, tm_funnel_rx) = channel(); let (tm_server_tx, tm_server_rx) = channel(); let verif_sender = MpscTmInStoreSender::new( - TmSenderId::PusVerification as SenderId, + TmSenderId::PusVerification as ChannelId, "verif_sender", shared_tm_store.clone(), tm_funnel_tx.clone(), @@ -156,13 +158,18 @@ fn main() { action_service_receiver: pus_action_tx, }; let test_srv_tm_sender = MpscTmInStoreSender::new( - TmSenderId::PusTest as SenderId, + TmSenderId::PusTest as ChannelId, "PUS_17_TM_SENDER", shared_tm_store.clone(), tm_funnel_tx.clone(), ); - let pus17_handler = PusService17TestHandler::new( + let test_srv_receiver = MpscTcInStoreReceiver::new( + TcReceiverId::PusTest as ChannelId, + "PUS_17_TC_RECV", pus_test_rx, + ); + let pus17_handler = PusService17TestHandler::new( + Box::new(test_srv_receiver), tc_store.pool.clone(), Box::new(test_srv_tm_sender), PUS_APID, @@ -174,15 +181,20 @@ fn main() { }; let sched_srv_tm_sender = MpscTmInStoreSender::new( - TmSenderId::PusSched as SenderId, + TmSenderId::PusSched as ChannelId, "PUS_11_TM_SENDER", shared_tm_store.clone(), tm_funnel_tx.clone(), ); + let sched_srv_receiver = MpscTcInStoreReceiver::new( + TcReceiverId::PusSched as ChannelId, + "PUS_11_TC_RECV", + pus_sched_rx, + ); let scheduler = PusScheduler::new_with_current_init_time(Duration::from_secs(5)) .expect("Creating PUS Scheduler failed"); let pus_11_handler = PusService11SchedHandler::new( - pus_sched_rx, + Box::new(sched_srv_receiver), tc_store.pool.clone(), Box::new(sched_srv_tm_sender), PUS_APID, @@ -195,13 +207,18 @@ fn main() { }; let event_srv_tm_sender = MpscTmInStoreSender::new( - TmSenderId::PusEvent as SenderId, + TmSenderId::PusEvent as ChannelId, "PUS_5_TM_SENDER", shared_tm_store.clone(), tm_funnel_tx.clone(), ); - let pus_5_handler = PusService5EventHandler::new( + let event_srv_receiver = MpscTcInStoreReceiver::new( + TcReceiverId::PusEvent as ChannelId, + "PUS_5_TC_RECV", pus_event_rx, + ); + let pus_5_handler = PusService5EventHandler::new( + Box::new(event_srv_receiver), tc_store.pool.clone(), Box::new(event_srv_tm_sender), PUS_APID, @@ -211,13 +228,18 @@ fn main() { let mut pus_5_wrapper = Pus5Wrapper { pus_5_handler }; let action_srv_tm_sender = MpscTmInStoreSender::new( - TmSenderId::PusAction as SenderId, + TmSenderId::PusAction as ChannelId, "PUS_8_TM_SENDER", shared_tm_store.clone(), tm_funnel_tx.clone(), ); - let pus_8_handler = PusService8ActionHandler::new( + let action_srv_receiver = MpscTcInStoreReceiver::new( + TcReceiverId::PusAction as ChannelId, + "PUS_8_TC_RECV", pus_action_rx, + ); + let pus_8_handler = PusService8ActionHandler::new( + Box::new(action_srv_receiver), tc_store.pool.clone(), Box::new(action_srv_tm_sender), PUS_APID, @@ -227,13 +249,15 @@ fn main() { let mut pus_8_wrapper = Pus8Wrapper { pus_8_handler }; let hk_srv_tm_sender = MpscTmInStoreSender::new( - TmSenderId::PusHk as SenderId, + TmSenderId::PusHk as ChannelId, "PUS_3_TM_SENDER", shared_tm_store.clone(), tm_funnel_tx.clone(), ); + let hk_srv_receiver = + MpscTcInStoreReceiver::new(TcReceiverId::PusHk as ChannelId, "PUS_8_TC_RECV", pus_hk_rx); let pus_3_handler = PusService3HkHandler::new( - pus_hk_rx, + Box::new(hk_srv_receiver), tc_store.pool.clone(), Box::new(hk_srv_tm_sender), PUS_APID, @@ -262,7 +286,7 @@ fn main() { if let Ok(addr) = tm_funnel.tm_funnel_rx.recv() { // Read the TM, set sequence counter and message counter, and finally update // the CRC. - let shared_pool = shared_tm_store.backing_pool(); + let shared_pool = shared_tm_store.clone_backing_pool(); let mut pool_guard = shared_pool.write().expect("Locking TM pool failed"); let tm_raw = pool_guard .modify(&addr) @@ -297,12 +321,20 @@ fn main() { .name("Event".to_string()) .spawn(move || { let mut timestamp: [u8; 7] = [0; 7]; - let mut sender = - MpscTmInStoreSender::new(1, "event_sender", tm_store_event.clone(), tm_funnel_tx); + let mut sender = MpscTmInStoreSender::new( + TmSenderId::AllEvents as ChannelId, + "ALL_EVENTS_TX", + tm_store_event.clone(), + tm_funnel_tx, + ); let mut time_provider = TimeProvider::new_with_u16_days(0, 0); let mut report_completion = |event_req: EventRequestWithToken, timestamp: &[u8]| { + let started_token: VerificationToken = event_req + .token + .try_into() + .expect("expected start verification token"); reporter_event_handler - .completion_success(event_req.token.try_into().unwrap(), Some(timestamp)) + .completion_success(started_token, Some(timestamp)) .expect("Sending completion success failed"); }; loop { diff --git a/satrs-example/src/pus/action.rs b/satrs-example/src/pus/action.rs index ab7885b..4dd3e55 100644 --- a/satrs-example/src/pus/action.rs +++ b/satrs-example/src/pus/action.rs @@ -5,7 +5,7 @@ use satrs_core::pus::verification::{ FailParams, StdVerifReporterWithSender, TcStateAccepted, VerificationToken, }; use satrs_core::pus::{ - AcceptedTc, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, + EcssTcReceiver, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, PusServiceHandler, }; use satrs_core::spacepackets::ecss::PusPacket; @@ -13,7 +13,7 @@ use satrs_core::spacepackets::tc::PusTc; use satrs_core::tmtc::TargetId; use satrs_example::tmtc_err; use std::collections::HashMap; -use std::sync::mpsc::{Receiver, Sender}; +use std::sync::mpsc::Sender; pub struct PusService8ActionHandler { psb: PusServiceBase, @@ -22,15 +22,21 @@ pub struct PusService8ActionHandler { impl PusService8ActionHandler { pub fn new( - receiver: Receiver, - tc_pool: SharedPool, + tc_receiver: Box, + shared_tc_pool: SharedPool, tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, request_handlers: HashMap>, ) -> Self { Self { - psb: PusServiceBase::new(receiver, tc_pool, tm_sender, tm_apid, verification_handler), + psb: PusServiceBase::new( + tc_receiver, + shared_tc_pool, + tm_sender, + tm_apid, + verification_handler, + ), request_handlers, } } diff --git a/satrs-example/src/pus/hk.rs b/satrs-example/src/pus/hk.rs index a56ed6b..b7e70c2 100644 --- a/satrs-example/src/pus/hk.rs +++ b/satrs-example/src/pus/hk.rs @@ -6,7 +6,7 @@ use satrs_core::pus::verification::{ FailParams, StdVerifReporterWithSender, TcStateAccepted, VerificationToken, }; use satrs_core::pus::{ - AcceptedTc, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, + EcssTcReceiver, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, PusServiceHandler, }; use satrs_core::spacepackets::ecss::{hk, PusPacket}; @@ -14,7 +14,7 @@ use satrs_core::spacepackets::tc::PusTc; use satrs_core::tmtc::{AddressableId, TargetId}; use satrs_example::{hk_err, tmtc_err}; use std::collections::HashMap; -use std::sync::mpsc::{Receiver, Sender}; +use std::sync::mpsc::Sender; pub struct PusService3HkHandler { psb: PusServiceBase, @@ -23,15 +23,21 @@ pub struct PusService3HkHandler { impl PusService3HkHandler { pub fn new( - receiver: Receiver, - tc_pool: SharedPool, + tc_receiver: Box, + shared_tc_pool: SharedPool, tm_sender: Box, tm_apid: u16, verification_handler: StdVerifReporterWithSender, request_handlers: HashMap>, ) -> Self { Self { - psb: PusServiceBase::new(receiver, tc_pool, tm_sender, tm_apid, verification_handler), + psb: PusServiceBase::new( + tc_receiver, + shared_tc_pool, + tm_sender, + tm_apid, + verification_handler, + ), request_handlers, } } diff --git a/satrs-example/src/pus/mod.rs b/satrs-example/src/pus/mod.rs index 0a879f8..d8b1c5b 100644 --- a/satrs-example/src/pus/mod.rs +++ b/satrs-example/src/pus/mod.rs @@ -2,7 +2,7 @@ use crate::tmtc::MpscStoreAndSendError; use log::warn; use satrs_core::pool::StoreAddr; use satrs_core::pus::verification::{FailParams, StdVerifReporterWithSender}; -use satrs_core::pus::{AcceptedTc, PusPacketHandlerResult}; +use satrs_core::pus::{PusPacketHandlerResult, TcAddrWithToken}; use satrs_core::spacepackets::ecss::PusServiceId; use satrs_core::spacepackets::tc::PusTc; use satrs_core::spacepackets::time::cds::TimeProvider; @@ -17,11 +17,11 @@ pub mod scheduler; pub mod test; pub struct PusTcMpscRouter { - pub test_service_receiver: Sender, - pub event_service_receiver: Sender, - pub sched_service_receiver: Sender, - pub hk_service_receiver: Sender, - pub action_service_receiver: Sender, + pub test_service_receiver: Sender, + pub event_service_receiver: Sender, + pub sched_service_receiver: Sender, + pub hk_service_receiver: Sender, + pub action_service_receiver: Sender, } pub struct PusReceiver { @@ -86,20 +86,20 @@ impl PusReceiver { PusServiceId::Test => { self.pus_router .test_service_receiver - .send((store_addr, accepted_token))?; + .send((store_addr, accepted_token.into()))?; } PusServiceId::Housekeeping => self .pus_router .hk_service_receiver - .send((store_addr, accepted_token))?, + .send((store_addr, accepted_token.into()))?, PusServiceId::Event => self .pus_router .event_service_receiver - .send((store_addr, accepted_token))?, + .send((store_addr, accepted_token.into()))?, PusServiceId::Scheduling => self .pus_router .sched_service_receiver - .send((store_addr, accepted_token))?, + .send((store_addr, accepted_token.into()))?, _ => { let result = self.verif_reporter.start_failure( accepted_token, diff --git a/satrs-example/src/tmtc.rs b/satrs-example/src/tmtc.rs index 95b9590..2a18dd3 100644 --- a/satrs-example/src/tmtc.rs +++ b/satrs-example/src/tmtc.rs @@ -10,7 +10,7 @@ use crate::ccsds::CcsdsReceiver; use crate::pus::{PusReceiver, PusTcMpscRouter}; use satrs_core::pool::{SharedPool, StoreAddr, StoreError}; use satrs_core::pus::verification::StdVerifReporterWithSender; -use satrs_core::pus::{AcceptedTc, ReceivesEcssPusTc}; +use satrs_core::pus::{ReceivesEcssPusTc, TcAddrWithToken}; use satrs_core::spacepackets::ecss::{PusPacket, SerializablePusPacket}; use satrs_core::spacepackets::tc::PusTc; use satrs_core::spacepackets::SpHeader; @@ -42,7 +42,7 @@ pub enum MpscStoreAndSendError { #[error("Store error: {0}")] Store(#[from] StoreError), #[error("TC send error: {0}")] - TcSend(#[from] SendError), + TcSend(#[from] SendError), #[error("TMTC send error: {0}")] TmTcSend(#[from] SendError), } @@ -123,7 +123,7 @@ pub fn core_tmtc_task( let mut udp_tmtc_server = UdpTmtcServer { udp_tc_server, tm_rx: tm_args.tm_server_rx, - tm_store: tm_args.tm_store.backing_pool(), + tm_store: tm_args.tm_store.clone_backing_pool(), }; let mut tc_buf: [u8; 4096] = [0; 4096]; From 6567a8367a0b477600531b4f232b90c27446c41b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 10 Jul 2023 00:31:58 +0200 Subject: [PATCH 10/11] docs --- satrs-core/src/pus/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/satrs-core/src/pus/mod.rs b/satrs-core/src/pus/mod.rs index 0defc10..7325b43 100644 --- a/satrs-core/src/pus/mod.rs +++ b/satrs-core/src/pus/mod.rs @@ -528,9 +528,9 @@ pub mod std_mod { } } - /// Base class for handlers which can handle PUS TC packets. Right now, the message queue - /// backend is constrained to [mpsc::channel]s and the verification reporter - /// is constrained to the [StdVerifReporterWithSender]. + /// Base class for handlers which can handle PUS TC packets. Right now, the verification + /// reporter is constrained to the [StdVerifReporterWithSender] and the service handler + /// relies on TMTC packets being exchanged via a [SharedPool]. pub struct PusServiceBase { pub tc_receiver: Box, pub shared_tc_store: SharedPool, From 8b420a5218405330bc2646178e7d0a3beed91c03 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 10 Jul 2023 00:36:35 +0200 Subject: [PATCH 11/11] small docs correction --- satrs-core/src/event_man.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/satrs-core/src/event_man.rs b/satrs-core/src/event_man.rs index c3d6182..5c56b85 100644 --- a/satrs-core/src/event_man.rs +++ b/satrs-core/src/event_man.rs @@ -21,7 +21,7 @@ doc = ::embed_doc_image::embed_image!("event_man_arch", "images/event_man_arch.p //! ![Event flow][event_man_arch] //! //! The event manager has a listener table abstracted by the [ListenerTable], which maps -//! listener groups identified by [ListenerKey]s to a [sender ID][SenderId]. +//! listener groups identified by [ListenerKey]s to a [sender ID][ChannelId]. //! It also contains a sender table abstracted by the [SenderTable] which maps these sender IDs //! to a concrete [SendEventProvider]s. A simple approach would be to use one send event provider //! for each OBSW thread and then subscribe for all interesting events for a particular thread