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),