From def176bed8e0aa3cfb7f4bfce1afa40936c6b808 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 2 Jul 2023 20:49:45 +0200 Subject: [PATCH 1/3] large update --- satrs-core/Cargo.toml | 6 +- satrs-core/src/events.rs | 54 +++++++++--- satrs-core/src/params.rs | 48 +++++++++-- satrs-core/src/pus/event.rs | 32 +++---- satrs-core/src/pus/event_man.rs | 10 +-- satrs-core/src/pus/mod.rs | 133 +++++++++++++++++++++-------- satrs-core/src/pus/verification.rs | 88 +++++++++++-------- satrs-core/src/res_code.rs | 17 ++-- satrs-example/Cargo.toml | 4 +- satrs-example/src/main.rs | 4 +- satrs-example/src/pus.rs | 5 +- satrs-mib/Cargo.toml | 2 +- satrs-mib/codegen/Cargo.toml | 4 +- 13 files changed, 277 insertions(+), 130 deletions(-) diff --git a/satrs-core/Cargo.toml b/satrs-core/Cargo.toml index a97872e..6353f5d 100644 --- a/satrs-core/Cargo.toml +++ b/satrs-core/Cargo.toml @@ -57,10 +57,10 @@ default-features = false optional = true [dependencies.spacepackets] -version = "0.5.4" +# version = "0.5.4" # path = "../spacepackets" -# git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git" -# rev = "" +git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git" +rev = "ec5d98a9b5ec" default-features = false diff --git a/satrs-core/src/events.rs b/satrs-core/src/events.rs index d5763a9..9641025 100644 --- a/satrs-core/src/events.rs +++ b/satrs-core/src/events.rs @@ -31,7 +31,8 @@ use core::fmt::Debug; use core::hash::Hash; use core::marker::PhantomData; use delegate::delegate; -use spacepackets::ecss::{EcssEnumeration, ToBeBytes}; +use spacepackets::ecss::EcssEnumeration; +use spacepackets::util::{ToBeBytes, UnsignedEnum}; use spacepackets::{ByteConversionError, SizeMissmatch}; /// Using a type definition allows to change this to u64 in the future more easily @@ -121,7 +122,7 @@ impl EventBase { raw: RAW, buf: &mut [u8], width: usize, - ) -> Result<(), ByteConversionError> { + ) -> Result { if buf.len() < width { return Err(ByteConversionError::ToSliceTooSmall(SizeMissmatch { found: buf.len(), @@ -129,7 +130,7 @@ impl EventBase { })); } buf.copy_from_slice(raw.to_be_bytes().as_ref()); - Ok(()) + Ok(raw.written_len()) } } @@ -403,21 +404,34 @@ try_from_impls!(SeverityLow, Severity::LOW, u32, EventU32TypedSev); try_from_impls!(SeverityMedium, Severity::MEDIUM, u32, EventU32TypedSev); try_from_impls!(SeverityHigh, Severity::HIGH, u32, EventU32TypedSev); -impl EcssEnumeration for EventU32 { - fn pfc(&self) -> u8 { - 32 +impl UnsignedEnum for EventU32 { + fn len(&self) -> usize { + core::mem::size_of::() } - fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError> { - self.base.write_to_bytes(self.raw(), buf, self.byte_width()) + fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { + self.base.write_to_bytes(self.raw(), buf, self.len()) } } +impl EcssEnumeration for EventU32 { + fn pfc(&self) -> u8 { + u32::BITS as u8 + } +} + +//noinspection RsTraitImplementation +impl UnsignedEnum for EventU32TypedSev { + delegate!(to self.event { + fn len(&self) -> usize; + fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result; + }); +} + //noinspection RsTraitImplementation impl EcssEnumeration for EventU32TypedSev { delegate!(to self.event { fn pfc(&self) -> u8; - fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError>; }); } @@ -538,22 +552,34 @@ impl EventU16TypedSev { impl_event_provider!(EventU16, EventU16TypedSev, u16, u8, u8); +impl UnsignedEnum for EventU16 { + fn len(&self) -> usize { + core::mem::size_of::() + } + + fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { + self.base.write_to_bytes(self.raw(), buf, self.len()) + } +} impl EcssEnumeration for EventU16 { #[inline] fn pfc(&self) -> u8 { - 16 + u16::BITS as u8 } +} - fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError> { - self.base.write_to_bytes(self.raw(), buf, self.byte_width()) - } +//noinspection RsTraitImplementation +impl UnsignedEnum for EventU16TypedSev { + delegate!(to self.event { + fn len(&self) -> usize; + fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result; + }); } //noinspection RsTraitImplementation impl EcssEnumeration for EventU16TypedSev { delegate!(to self.event { fn pfc(&self) -> u8; - fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError>; }); } diff --git a/satrs-core/src/params.rs b/satrs-core/src/params.rs index bd616bd..647d8ae 100644 --- a/satrs-core/src/params.rs +++ b/satrs-core/src/params.rs @@ -52,13 +52,14 @@ use alloc::vec::Vec; use core::fmt::Debug; use core::mem::size_of; use paste::paste; -use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU64, EcssEnumU8, EcssEnumeration}; +use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU64, EcssEnumU8}; +use spacepackets::util::UnsignedEnum; use spacepackets::ByteConversionError; use spacepackets::SizeMissmatch; #[cfg(feature = "alloc")] pub use alloc_mod::*; -pub use spacepackets::ecss::ToBeBytes; +pub use spacepackets::util::ToBeBytes; /// Generic trait which is used for objects which can be converted into a raw network (big) endian /// byte format. @@ -170,6 +171,11 @@ macro_rules! scalar_byte_conversions_impl { paste! { impl ToBeBytes for [<$ty:upper>] { type ByteArray = [u8; size_of::<$ty>()]; + + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { self.0.to_be_bytes() } @@ -199,6 +205,11 @@ macro_rules! pair_byte_conversions_impl { paste! { impl ToBeBytes for [<$ty:upper Pair>] { type ByteArray = [u8; size_of::<$ty>() * 2]; + + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; size_of::<$ty>() * 2]; array[0..size_of::<$ty>()].copy_from_slice(&self.0.to_be_bytes()); @@ -236,6 +247,11 @@ macro_rules! triplet_to_be_bytes_impl { paste! { impl ToBeBytes for [<$ty:upper Triplet>] { type ByteArray = [u8; size_of::<$ty>() * 3]; + + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; size_of::<$ty>() * 3]; array[0..size_of::<$ty>()].copy_from_slice(&self.0.to_be_bytes()); @@ -275,6 +291,10 @@ scalar_byte_conversions_impl!(u8, u16, u32, u64, i8, i16, i32, i64, f32, f64,); impl ToBeBytes for U8Pair { type ByteArray = [u8; 2]; + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; 2]; array[0] = self.0; @@ -286,6 +306,10 @@ impl ToBeBytes for U8Pair { impl ToBeBytes for I8Pair { type ByteArray = [u8; 2]; + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; 2]; array[0] = self.0 as u8; @@ -297,6 +321,10 @@ impl ToBeBytes for I8Pair { impl ToBeBytes for U8Triplet { type ByteArray = [u8; 3]; + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; 3]; array[0] = self.0; @@ -309,6 +337,10 @@ impl ToBeBytes for U8Triplet { impl ToBeBytes for I8Triplet { type ByteArray = [u8; 3]; + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; 3]; array[0] = self.0 as u8; @@ -443,11 +475,11 @@ macro_rules! writable_as_be_bytes_ecss_enum_impl { ($EnumIdent: ident) => { impl WritableToBeBytes for $EnumIdent { fn raw_len(&self) -> usize { - self.byte_width() + self.len() } fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { - EcssEnumeration::write_to_be_bytes(self, buf).map(|_| self.byte_width()) + ::write_to_be_bytes(self, buf).map(|_| self.raw_len()) } } }; @@ -461,10 +493,10 @@ writable_as_be_bytes_ecss_enum_impl!(EcssEnumU64); impl WritableToBeBytes for EcssEnumParams { fn raw_len(&self) -> usize { match self { - EcssEnumParams::U8(e) => e.byte_width(), - EcssEnumParams::U16(e) => e.byte_width(), - EcssEnumParams::U32(e) => e.byte_width(), - EcssEnumParams::U64(e) => e.byte_width(), + EcssEnumParams::U8(e) => e.raw_len(), + EcssEnumParams::U16(e) => e.raw_len(), + EcssEnumParams::U32(e) => e.raw_len(), + EcssEnumParams::U64(e) => e.raw_len(), } } diff --git a/satrs-core/src/pus/event.rs b/satrs-core/src/pus/event.rs index 5bbc63b..f6e6ea9 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, EcssTmError, EcssTmErrorWithSend}; +use crate::pus::{source_buffer_large_enough, EcssTmtcError, EcssTmtcErrorWithSend}; use spacepackets::ecss::EcssEnumeration; 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<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { 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<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { 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<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { 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<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.generate_and_send_generic_tm( buf, Subservice::TmHighSeverityReport, @@ -107,11 +107,11 @@ impl EventReporterBase { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { let tm = self.generate_generic_event_tm(buf, subservice, time_stamp, event_id, aux_data)?; sender .send_tm(tm) - .map_err(|e| EcssTmErrorWithSend::SendError(e))?; + .map_err(|e| EcssTmtcErrorWithSend::SendError(e))?; self.msg_count += 1; Ok(()) } @@ -123,8 +123,8 @@ impl EventReporterBase { time_stamp: &'a [u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result { - let mut src_data_len = event_id.byte_width(); + ) -> Result { + let mut src_data_len = event_id.len(); if let Some(aux_data) = aux_data { src_data_len += aux_data.len(); } @@ -138,8 +138,8 @@ impl EventReporterBase { Some(time_stamp), ); let mut current_idx = 0; - event_id.write_to_be_bytes(&mut buf[0..event_id.byte_width()])?; - current_idx += event_id.byte_width(); + event_id.write_to_be_bytes(&mut buf[0..event_id.len()])?; + current_idx += event_id.len(); if let Some(aux_data) = aux_data { buf[current_idx..current_idx + aux_data.len()].copy_from_slice(aux_data); current_idx += aux_data.len(); @@ -178,7 +178,7 @@ mod allocvec { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_info( self.source_data_buf.as_mut_slice(), sender, @@ -194,7 +194,7 @@ mod allocvec { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_low_severity( self.source_data_buf.as_mut_slice(), sender, @@ -210,7 +210,7 @@ mod allocvec { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_medium_severity( self.source_data_buf.as_mut_slice(), sender, @@ -226,7 +226,7 @@ mod allocvec { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_high_severity( self.source_data_buf.as_mut_slice(), sender, @@ -413,7 +413,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 EcssTmErrorWithSend::EcssTmError(EcssTmError::ByteConversionError( + if let EcssTmErrorWithSend::EcssTmError(EcssTmtcError::ByteConversionError( ByteConversionError::ToSliceTooSmall(missmatch), )) = err { diff --git a/satrs-core/src/pus/event_man.rs b/satrs-core/src/pus/event_man.rs index ecb4b59..dbde7fd 100644 --- a/satrs-core/src/pus/event_man.rs +++ b/satrs-core/src/pus/event_man.rs @@ -11,9 +11,9 @@ use hashbrown::HashSet; #[cfg(feature = "alloc")] pub use crate::pus::event::EventReporter; use crate::pus::verification::{TcStateStarted, VerificationToken}; -use crate::pus::EcssTmErrorWithSend; #[cfg(feature = "alloc")] use crate::pus::EcssTmSenderCore; +use crate::pus::EcssTmtcErrorWithSend; #[cfg(feature = "alloc")] #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] pub use alloc_mod::*; @@ -96,13 +96,13 @@ pub struct EventRequestWithToken { #[derive(Debug)] pub enum EventManError { - EcssTmError(EcssTmErrorWithSend), + EcssTmtcError(EcssTmtcErrorWithSend), SeverityMissmatch(Severity, Severity), } -impl From> for EventManError { - fn from(v: EcssTmErrorWithSend) -> Self { - Self::EcssTmError(v) +impl From> for EventManError { + fn from(v: EcssTmtcErrorWithSend) -> Self { + Self::EcssTmtcError(v) } } diff --git a/satrs-core/src/pus/mod.rs b/satrs-core/src/pus/mod.rs index 4543fb4..9396e03 100644 --- a/satrs-core/src/pus/mod.rs +++ b/satrs-core/src/pus/mod.rs @@ -4,6 +4,7 @@ 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}; @@ -24,21 +25,21 @@ use crate::SenderId; pub use std_mod::*; #[derive(Debug, Clone)] -pub enum EcssTmErrorWithSend { - /// Errors related to sending the telemetry to a TM recipient +pub enum EcssTmtcErrorWithSend { + /// Errors related to sending the telemetry to a TMTC recipient SendError(E), - EcssTmError(EcssTmError), + EcssTmtcError(EcssTmtcError), } -impl From for EcssTmErrorWithSend { - fn from(value: EcssTmError) -> Self { - Self::EcssTmError(value) +impl From for EcssTmtcErrorWithSend { + fn from(value: EcssTmtcError) -> Self { + Self::EcssTmtcError(value) } } /// Generic error type for PUS TM handling. #[derive(Debug, Clone)] -pub enum EcssTmError { +pub enum EcssTmtcError { /// Errors related to the time stamp format of the telemetry TimestampError(TimestampError), /// Errors related to byte conversion, for example insufficient buffer size for given data @@ -47,30 +48,41 @@ pub enum EcssTmError { PusError(PusError), } -impl From for EcssTmError { +impl From for EcssTmtcError { fn from(e: PusError) -> Self { - EcssTmError::PusError(e) + EcssTmtcError::PusError(e) } } -impl From for EcssTmError { +impl From for EcssTmtcError { fn from(e: ByteConversionError) -> Self { - EcssTmError::ByteConversionError(e) + EcssTmtcError::ByteConversionError(e) } } +pub trait EcssSender: Send { + /// Each sender can have an ID associated with it + fn id(&self) -> SenderId; + fn name(&self) -> &'static str { + "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(&mut self, tm: PusTm) -> Result<(), Self::Error>; +} + /// Generic trait for a user supplied sender object. /// -/// This sender object is responsible for sending telemetry to a TM sink. -pub trait EcssTmSenderCore: Send { +/// This sender object is responsible for sending PUS telecommands to a TC recipient. +pub trait EcssTcSenderCore: EcssSender { type Error; - /// Each sender can have an ID associated with it - fn id(&self) -> SenderId; - fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error>; - fn name(&self) -> &'static str { - "unset" - } + fn send_tc(&mut self, tc: PusTc) -> Result<(), Self::Error>; } #[cfg(feature = "alloc")] @@ -96,15 +108,36 @@ mod alloc_mod { dyn_clone::clone_trait_object!( EcssTmSender); impl_downcast!(EcssTmSender assoc Error); + + /// Extension trait for [EcssTcSenderCore]. + /// + /// 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 EcssTcSender: EcssTcSenderCore + Downcast + DynClone {} + + /// 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); } #[cfg(feature = "std")] pub mod std_mod { use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError}; - use crate::pus::EcssTmSenderCore; + use crate::pus::{EcssSender, EcssTcSenderCore, EcssTmSenderCore}; use crate::SenderId; use alloc::vec::Vec; - use spacepackets::ecss::PusError; + use spacepackets::ecss::{PusError, SerializablePusPacket}; + use spacepackets::tc::PusTc; use spacepackets::tm::PusTm; use std::sync::mpsc::SendError; use std::sync::{mpsc, RwLockWriteGuard}; @@ -135,7 +168,7 @@ pub mod std_mod { } #[derive(Clone)] - pub struct MpscTmInStoreSender { + pub struct MpscTmtcInStoreSender { id: SenderId, name: &'static str, store_helper: SharedPool, @@ -143,13 +176,19 @@ pub mod std_mod { pub ignore_poison_errors: bool, } - impl EcssTmSenderCore for MpscTmInStoreSender { - type Error = MpscPusInStoreSendError; - + impl EcssSender for MpscTmtcInStoreSender { fn id(&self) -> SenderId { self.id } + fn name(&self) -> &'static str { + self.name + } + } + + impl EcssTmSenderCore for MpscTmtcInStoreSender { + type Error = MpscPusInStoreSendError; + fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error> { let operation = |mut store: RwLockWriteGuard| { let (addr, slice) = store.free_element(tm.len_packed())?; @@ -168,13 +207,32 @@ pub mod std_mod { } } } + } - fn name(&self) -> &'static str { - self.name + impl EcssTcSenderCore for MpscTmtcInStoreSender { + type Error = MpscPusInStoreSendError; + + fn send_tc(&mut self, tc: PusTc) -> Result<(), Self::Error> { + let operation = |mut store: RwLockWriteGuard| { + let (addr, slice) = store.free_element(tc.len_packed())?; + tc.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(MpscPusInStoreSendError::LockError) + } + } + } } } - impl MpscTmInStoreSender { + impl MpscTmtcInStoreSender { pub fn new( id: SenderId, name: &'static str, @@ -209,11 +267,18 @@ pub mod std_mod { Self { id, sender, name } } } - impl EcssTmSenderCore for MpscTmAsVecSender { - type Error = MpscAsVecSenderError; + + impl EcssSender for MpscTmAsVecSender { fn id(&self) -> SenderId { self.id } + fn name(&self) -> &'static str { + self.name + } + } + + impl EcssTmSenderCore for MpscTmAsVecSender { + type Error = MpscAsVecSenderError; fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error> { let mut vec = Vec::new(); @@ -224,10 +289,6 @@ pub mod std_mod { .map_err(MpscAsVecSenderError::SendError)?; Ok(()) } - - fn name(&self) -> &'static str { - self.name - } } } @@ -237,9 +298,9 @@ pub enum GenericTcCheckError { InvalidSubservice, } -pub(crate) fn source_buffer_large_enough(cap: usize, len: usize) -> Result<(), EcssTmError> { +pub(crate) fn source_buffer_large_enough(cap: usize, len: usize) -> Result<(), EcssTmtcError> { if len > cap { - return Err(EcssTmError::ByteConversionError( + return Err(EcssTmtcError::ByteConversionError( ByteConversionError::ToSliceTooSmall(SizeMissmatch { found: cap, expected: len, diff --git a/satrs-core/src/pus/verification.rs b/satrs-core/src/pus/verification.rs index b60bc3f..c0d9167 100644 --- a/satrs-core/src/pus/verification.rs +++ b/satrs-core/src/pus/verification.rs @@ -73,7 +73,7 @@ //! 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, EcssTmError, EcssTmErrorWithSend, EcssTmSenderCore, + source_buffer_large_enough, EcssTmSenderCore, EcssTmtcError, EcssTmtcErrorWithSend, GenericTcCheckError, }; use core::fmt::{Debug, Display, Formatter}; @@ -179,12 +179,12 @@ impl RequestId { /// re-trying the operation at a later point. #[derive(Debug, Clone)] pub struct VerificationOrSendErrorWithToken( - pub EcssTmErrorWithSend, + pub EcssTmtcErrorWithSend, pub VerificationToken, ); #[derive(Debug, Clone)] -pub struct VerificationErrorWithToken(pub EcssTmError, pub VerificationToken); +pub struct VerificationErrorWithToken(pub EcssTmtcError, pub VerificationToken); impl From> for VerificationOrSendErrorWithToken { fn from(value: VerificationErrorWithToken) -> Self { @@ -543,7 +543,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -561,7 +561,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -630,7 +630,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -674,7 +674,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -693,7 +693,7 @@ impl VerificationReporterCore { msg_counter: &(impl SequenceCountProviderCore + ?Sized), time_stamp: Option<&'src_data [u8]>, step: impl EcssEnumeration, - ) -> Result, EcssTmError> { + ) -> Result, EcssTmtcError> { Ok(VerificationSendable::new_no_token( self.create_pus_verif_success_tm( src_data_buf, @@ -799,7 +799,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -818,7 +818,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -837,10 +837,10 @@ impl VerificationReporterCore { req_id: &RequestId, time_stamp: Option<&'src_data [u8]>, step: Option<&(impl EcssEnumeration + ?Sized)>, - ) -> Result, EcssTmError> { + ) -> Result, EcssTmtcError> { let mut source_data_len = size_of::(); if let Some(step) = step { - source_data_len += step.byte_width(); + source_data_len += step.len(); } source_buffer_large_enough(src_data_buf.len(), source_data_len)?; let mut idx = 0; @@ -848,7 +848,7 @@ impl VerificationReporterCore { idx += RequestId::SIZE_AS_BYTES; if let Some(step) = step { // Size check was done beforehand - step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.byte_width()]) + step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.len()]) .unwrap(); } let mut sp_header = SpHeader::tm_unseg(self.apid(), seq_count, 0).unwrap(); @@ -873,11 +873,11 @@ impl VerificationReporterCore { req_id: &RequestId, step: Option<&(impl EcssEnumeration + ?Sized)>, params: &FailParams<'src_data, '_>, - ) -> Result, EcssTmError> { + ) -> Result, EcssTmtcError> { let mut idx = 0; - let mut source_data_len = RequestId::SIZE_AS_BYTES + params.failure_code.byte_width(); + let mut source_data_len = RequestId::SIZE_AS_BYTES + params.failure_code.len(); if let Some(step) = step { - source_data_len += step.byte_width(); + source_data_len += step.len(); } if let Some(failure_data) = params.failure_data { source_data_len += failure_data.len(); @@ -887,14 +887,14 @@ impl VerificationReporterCore { idx += RequestId::SIZE_AS_BYTES; if let Some(step) = step { // Size check done beforehand - step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.byte_width()]) + step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.len()]) .unwrap(); - idx += step.byte_width(); + idx += step.len(); } params .failure_code - .write_to_be_bytes(&mut src_data_buf[idx..idx + params.failure_code.byte_width()])?; - idx += params.failure_code.byte_width(); + .write_to_be_bytes(&mut src_data_buf[idx..idx + params.failure_code.len()])?; + idx += params.failure_code.len(); if let Some(failure_data) = params.failure_data { src_data_buf[idx..idx + failure_data.len()].copy_from_slice(failure_data); } @@ -1121,7 +1121,7 @@ mod alloc_mod { sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: Option<&[u8]>, step: impl EcssEnumeration, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { let sendable = self.reporter.step_success( self.source_data_buf.as_mut_slice(), token, @@ -1298,7 +1298,7 @@ mod alloc_mod { token: &VerificationToken, time_stamp: Option<&[u8]>, step: impl EcssEnumeration, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter .step_success(token, self.sender.as_mut(), time_stamp, step) } @@ -1337,9 +1337,10 @@ mod stdmod { use super::alloc_mod::VerificationReporterWithSender; use super::*; use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr}; - use crate::pus::MpscPusInStoreSendError; + use crate::pus::{EcssSender, MpscPusInStoreSendError}; use crate::SenderId; use delegate::delegate; + use spacepackets::ecss::SerializablePusPacket; use spacepackets::tm::PusTm; use std::sync::{mpsc, Arc, Mutex, RwLockWriteGuard}; @@ -1400,14 +1401,22 @@ mod stdmod { } } + //noinspection RsTraitImplementation + impl EcssSender for MpscVerifSender { + delegate!( + to self.base { + fn id(&self) -> SenderId; + fn name(&self) -> &'static str; + } + ); + } + //noinspection RsTraitImplementation impl EcssTmSenderCore for MpscVerifSender { type Error = MpscPusInStoreSendError; delegate!( to self.base { - fn id(&self) -> SenderId; - fn name(&self) -> &'static str; fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error>; } ); @@ -1441,6 +1450,17 @@ mod stdmod { } } + //noinspection RsTraitImplementation + #[cfg(feature = "crossbeam")] + impl EcssSender for CrossbeamVerifSender { + delegate!( + to self.base { + fn id(&self) -> SenderId; + fn name(&self) -> &'static str; + } + ); + } + //noinspection RsTraitImplementation #[cfg(feature = "crossbeam")] impl EcssTmSenderCore for CrossbeamVerifSender { @@ -1448,19 +1468,21 @@ mod stdmod { delegate!( to self.base { - fn id(&self) -> SenderId; - fn name(&self) -> &'static str; fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error>; } ); } - impl EcssTmSenderCore for StdSenderBase { - type Error = MpscPusInStoreSendError; - + impl EcssSender for StdSenderBase { fn id(&self) -> SenderId { self.id } + fn name(&self) -> &'static str { + self.name + } + } + impl EcssTmSenderCore for StdSenderBase { + type Error = MpscPusInStoreSendError; fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error> { let operation = |mut mg: RwLockWriteGuard| { @@ -1484,10 +1506,6 @@ mod stdmod { } } } - - fn name(&self) -> &'static str { - self.name - } } } @@ -1799,7 +1817,7 @@ mod tests { let err_with_token = res.unwrap_err(); assert_eq!(err_with_token.1, tok); match err_with_token.0 { - EcssTmErrorWithSend::EcssTmError(EcssTmError::ByteConversionError(e)) => match e { + EcssTmErrorWithSend::EcssTmError(EcssTmtcError::ByteConversionError(e)) => match e { ByteConversionError::ToSliceTooSmall(missmatch) => { assert_eq!( missmatch.expected, diff --git a/satrs-core/src/res_code.rs b/satrs-core/src/res_code.rs index 9918ecf..bb0cc13 100644 --- a/satrs-core/src/res_code.rs +++ b/satrs-core/src/res_code.rs @@ -1,6 +1,7 @@ #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use spacepackets::ecss::{EcssEnumU16, EcssEnumeration}; +use spacepackets::util::UnsignedEnum; use spacepackets::{ByteConversionError, SizeMissmatch}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -34,12 +35,12 @@ impl From for EcssEnumU16 { } } -impl EcssEnumeration for ResultU16 { - fn pfc(&self) -> u8 { - 16 +impl UnsignedEnum for ResultU16 { + fn len(&self) -> usize { + core::mem::size_of::() } - fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError> { + fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { if buf.len() < 2 { return Err(ByteConversionError::ToSliceTooSmall(SizeMissmatch { found: buf.len(), @@ -48,6 +49,12 @@ impl EcssEnumeration for ResultU16 { } buf[0] = self.group_id; buf[1] = self.unique_id; - Ok(()) + Ok(self.len()) + } +} + +impl EcssEnumeration for ResultU16 { + fn pfc(&self) -> u8 { + 16 } } diff --git a/satrs-example/Cargo.toml b/satrs-example/Cargo.toml index ac403e2..a5c559b 100644 --- a/satrs-example/Cargo.toml +++ b/satrs-example/Cargo.toml @@ -10,10 +10,10 @@ fern = "0.6" chrono = "0.4" log = "0.4" crossbeam-channel = "0.5" -delegate = "0.9" +delegate = "0.10" zerocopy = "0.6" csv = "1" -num_enum = "0.5" +num_enum = "0.6" [dependencies.satrs-core] path = "../satrs-core" diff --git a/satrs-example/src/main.rs b/satrs-example/src/main.rs index 86d79e3..450c694 100644 --- a/satrs-example/src/main.rs +++ b/satrs-example/src/main.rs @@ -27,7 +27,7 @@ use satrs_core::pus::hk::Subservice as HkSubservice; use satrs_core::pus::verification::{ MpscVerifSender, VerificationReporterCfg, VerificationReporterWithSender, }; -use satrs_core::pus::MpscTmInStoreSender; +use satrs_core::pus::MpscTmtcInStoreSender; use satrs_core::seq_count::{SeqCountProviderSimple, SeqCountProviderSyncClonable}; use satrs_core::spacepackets::{ time::cds::TimeProvider, @@ -185,7 +185,7 @@ fn main() { .spawn(move || { let mut timestamp: [u8; 7] = [0; 7]; let mut sender = - MpscTmInStoreSender::new(1, "event_sender", tm_store.pool, tm_funnel_tx); + MpscTmtcInStoreSender::new(1, "event_sender", tm_store.pool, 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 diff --git a/satrs-example/src/pus.rs b/satrs-example/src/pus.rs index e2dd2f2..64664a5 100644 --- a/satrs-example/src/pus.rs +++ b/satrs-example/src/pus.rs @@ -7,7 +7,6 @@ use satrs_core::mode::{ModeAndSubmode, ModeRequest}; use satrs_core::params::Params; use satrs_core::pool::{PoolProvider, StoreAddr}; use satrs_core::pus::event_man::{EventRequest, EventRequestWithToken}; -use satrs_core::pus::hk; use satrs_core::pus::mode; use satrs_core::pus::mode::Subservice; use satrs_core::pus::scheduling::PusScheduler; @@ -16,6 +15,7 @@ use satrs_core::pus::verification::{ VerificationToken, }; use satrs_core::pus::{event, GenericTcCheckError}; +use satrs_core::pus::{hk, EcssTmSender, EcssTmSenderCore}; use satrs_core::res_code::ResultU16; use satrs_core::seq_count::{SeqCountProviderSyncClonable, SequenceCountProviderCore}; use satrs_core::spacepackets::ecss::{scheduling, PusServiceId}; @@ -33,6 +33,9 @@ use std::convert::TryFrom; use std::rc::Rc; use std::sync::mpsc::{Receiver, Sender}; +pub trait PusTcMultiplexer { + fn route_pus_tc(tc: &PusTc, apid: u16, service: u8, subservice: u8); +} pub struct PusReceiver { pub tm_helper: PusTmWithCdsShortHelper, pub tm_args: PusTmArgs, diff --git a/satrs-mib/Cargo.toml b/satrs-mib/Cargo.toml index 8be0562..e736fec 100644 --- a/satrs-mib/Cargo.toml +++ b/satrs-mib/Cargo.toml @@ -19,7 +19,7 @@ path = "../satrs-core" path = "codegen" [dependencies.serde] -version = "1.0" +version = "1" default-features = false [features] diff --git a/satrs-mib/codegen/Cargo.toml b/satrs-mib/codegen/Cargo.toml index 7a1d882..894996f 100644 --- a/satrs-mib/codegen/Cargo.toml +++ b/satrs-mib/codegen/Cargo.toml @@ -12,7 +12,7 @@ name = "tests" path = "tests/tests.rs" [dependencies] -quote = "1.0" +quote = "1" proc-macro2 = "1.0" [dependencies.satrs-core] @@ -25,5 +25,5 @@ trybuild = { version = "1.0", features = ["diff"] } path = ".." [dependencies.syn] -version = "1.0" +version = "2" features = ["extra-traits"] From 6f02c5279cc88991f98d03b7f7f127123a1362fc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 2 Jul 2023 21:03:29 +0200 Subject: [PATCH 2/3] better names --- satrs-core/Cargo.toml | 3 +-- satrs-core/src/events.rs | 12 ++++++------ satrs-core/src/params.rs | 2 +- satrs-core/src/pus/event.rs | 6 +++--- satrs-core/src/pus/verification.rs | 16 ++++++++-------- satrs-core/src/res_code.rs | 4 ++-- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/satrs-core/Cargo.toml b/satrs-core/Cargo.toml index 6353f5d..bf95cef 100644 --- a/satrs-core/Cargo.toml +++ b/satrs-core/Cargo.toml @@ -60,8 +60,7 @@ optional = true # version = "0.5.4" # path = "../spacepackets" git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git" -rev = "ec5d98a9b5ec" - +rev = "ef4244c8cb5c" default-features = false [dev-dependencies] diff --git a/satrs-core/src/events.rs b/satrs-core/src/events.rs index 9641025..2c53fcd 100644 --- a/satrs-core/src/events.rs +++ b/satrs-core/src/events.rs @@ -405,12 +405,12 @@ try_from_impls!(SeverityMedium, Severity::MEDIUM, u32, EventU32TypedSev); try_from_impls!(SeverityHigh, Severity::HIGH, u32, EventU32TypedSev); impl UnsignedEnum for EventU32 { - fn len(&self) -> usize { + fn size(&self) -> usize { core::mem::size_of::() } fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { - self.base.write_to_bytes(self.raw(), buf, self.len()) + self.base.write_to_bytes(self.raw(), buf, self.size()) } } @@ -423,7 +423,7 @@ impl EcssEnumeration for EventU32 { //noinspection RsTraitImplementation impl UnsignedEnum for EventU32TypedSev { delegate!(to self.event { - fn len(&self) -> usize; + fn size(&self) -> usize; fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result; }); } @@ -553,12 +553,12 @@ impl EventU16TypedSev { impl_event_provider!(EventU16, EventU16TypedSev, u16, u8, u8); impl UnsignedEnum for EventU16 { - fn len(&self) -> usize { + fn size(&self) -> usize { core::mem::size_of::() } fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { - self.base.write_to_bytes(self.raw(), buf, self.len()) + self.base.write_to_bytes(self.raw(), buf, self.size()) } } impl EcssEnumeration for EventU16 { @@ -571,7 +571,7 @@ impl EcssEnumeration for EventU16 { //noinspection RsTraitImplementation impl UnsignedEnum for EventU16TypedSev { delegate!(to self.event { - fn len(&self) -> usize; + fn size(&self) -> usize; fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result; }); } diff --git a/satrs-core/src/params.rs b/satrs-core/src/params.rs index 647d8ae..9df929b 100644 --- a/satrs-core/src/params.rs +++ b/satrs-core/src/params.rs @@ -475,7 +475,7 @@ macro_rules! writable_as_be_bytes_ecss_enum_impl { ($EnumIdent: ident) => { impl WritableToBeBytes for $EnumIdent { fn raw_len(&self) -> usize { - self.len() + self.size() } fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { diff --git a/satrs-core/src/pus/event.rs b/satrs-core/src/pus/event.rs index f6e6ea9..146986c 100644 --- a/satrs-core/src/pus/event.rs +++ b/satrs-core/src/pus/event.rs @@ -124,7 +124,7 @@ impl EventReporterBase { event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, ) -> Result { - let mut src_data_len = event_id.len(); + let mut src_data_len = event_id.size(); if let Some(aux_data) = aux_data { src_data_len += aux_data.len(); } @@ -138,8 +138,8 @@ impl EventReporterBase { Some(time_stamp), ); let mut current_idx = 0; - event_id.write_to_be_bytes(&mut buf[0..event_id.len()])?; - current_idx += event_id.len(); + event_id.write_to_be_bytes(&mut buf[0..event_id.size()])?; + 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); current_idx += aux_data.len(); diff --git a/satrs-core/src/pus/verification.rs b/satrs-core/src/pus/verification.rs index c0d9167..c42e758 100644 --- a/satrs-core/src/pus/verification.rs +++ b/satrs-core/src/pus/verification.rs @@ -840,7 +840,7 @@ impl VerificationReporterCore { ) -> Result, EcssTmtcError> { let mut source_data_len = size_of::(); if let Some(step) = step { - source_data_len += step.len(); + source_data_len += step.size(); } source_buffer_large_enough(src_data_buf.len(), source_data_len)?; let mut idx = 0; @@ -848,7 +848,7 @@ impl VerificationReporterCore { idx += RequestId::SIZE_AS_BYTES; if let Some(step) = step { // Size check was done beforehand - step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.len()]) + step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.size()]) .unwrap(); } let mut sp_header = SpHeader::tm_unseg(self.apid(), seq_count, 0).unwrap(); @@ -875,9 +875,9 @@ impl VerificationReporterCore { params: &FailParams<'src_data, '_>, ) -> Result, EcssTmtcError> { let mut idx = 0; - let mut source_data_len = RequestId::SIZE_AS_BYTES + params.failure_code.len(); + let mut source_data_len = RequestId::SIZE_AS_BYTES + params.failure_code.size(); if let Some(step) = step { - source_data_len += step.len(); + source_data_len += step.size(); } if let Some(failure_data) = params.failure_data { source_data_len += failure_data.len(); @@ -887,14 +887,14 @@ impl VerificationReporterCore { idx += RequestId::SIZE_AS_BYTES; if let Some(step) = step { // Size check done beforehand - step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.len()]) + step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.size()]) .unwrap(); - idx += step.len(); + idx += step.size(); } params .failure_code - .write_to_be_bytes(&mut src_data_buf[idx..idx + params.failure_code.len()])?; - idx += params.failure_code.len(); + .write_to_be_bytes(&mut src_data_buf[idx..idx + params.failure_code.size()])?; + 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); } diff --git a/satrs-core/src/res_code.rs b/satrs-core/src/res_code.rs index bb0cc13..5b0c64e 100644 --- a/satrs-core/src/res_code.rs +++ b/satrs-core/src/res_code.rs @@ -36,7 +36,7 @@ impl From for EcssEnumU16 { } impl UnsignedEnum for ResultU16 { - fn len(&self) -> usize { + fn size(&self) -> usize { core::mem::size_of::() } @@ -49,7 +49,7 @@ impl UnsignedEnum for ResultU16 { } buf[0] = self.group_id; buf[1] = self.unique_id; - Ok(self.len()) + Ok(self.size()) } } From 148fc29b9516470a0497b6bd86f11d9ff63c9e03 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 3 Jul 2023 00:42:20 +0200 Subject: [PATCH 3/3] update syn to v2.0, large update --- satrs-core/Cargo.toml | 7 +- satrs-core/src/events.rs | 54 ++++++--- satrs-core/src/params.rs | 48 ++++++-- satrs-core/src/pus/event.rs | 32 ++--- satrs-core/src/pus/event_man.rs | 10 +- satrs-core/src/pus/mod.rs | 133 +++++++++++++++------ satrs-core/src/pus/verification.rs | 88 ++++++++------ satrs-core/src/res_code.rs | 17 ++- satrs-example/Cargo.toml | 4 +- satrs-example/src/bin/simpleclient.rs | 4 +- satrs-example/src/main.rs | 4 +- satrs-example/src/pus.rs | 3 + satrs-example/src/tmtc.rs | 1 + satrs-mib/Cargo.toml | 2 +- satrs-mib/codegen/Cargo.toml | 10 +- satrs-mib/codegen/src/lib.rs | 127 +++++--------------- satrs-mib/codegen/tests/basic.rs | 2 +- satrs-mib/codegen/tests/basic_with_info.rs | 8 ++ satrs-mib/codegen/tests/tests.rs | 1 + 19 files changed, 325 insertions(+), 230 deletions(-) create mode 100644 satrs-mib/codegen/tests/basic_with_info.rs diff --git a/satrs-core/Cargo.toml b/satrs-core/Cargo.toml index a97872e..bf95cef 100644 --- a/satrs-core/Cargo.toml +++ b/satrs-core/Cargo.toml @@ -57,11 +57,10 @@ default-features = false optional = true [dependencies.spacepackets] -version = "0.5.4" +# version = "0.5.4" # path = "../spacepackets" -# git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git" -# rev = "" - +git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git" +rev = "ef4244c8cb5c" default-features = false [dev-dependencies] diff --git a/satrs-core/src/events.rs b/satrs-core/src/events.rs index d5763a9..2c53fcd 100644 --- a/satrs-core/src/events.rs +++ b/satrs-core/src/events.rs @@ -31,7 +31,8 @@ use core::fmt::Debug; use core::hash::Hash; use core::marker::PhantomData; use delegate::delegate; -use spacepackets::ecss::{EcssEnumeration, ToBeBytes}; +use spacepackets::ecss::EcssEnumeration; +use spacepackets::util::{ToBeBytes, UnsignedEnum}; use spacepackets::{ByteConversionError, SizeMissmatch}; /// Using a type definition allows to change this to u64 in the future more easily @@ -121,7 +122,7 @@ impl EventBase { raw: RAW, buf: &mut [u8], width: usize, - ) -> Result<(), ByteConversionError> { + ) -> Result { if buf.len() < width { return Err(ByteConversionError::ToSliceTooSmall(SizeMissmatch { found: buf.len(), @@ -129,7 +130,7 @@ impl EventBase { })); } buf.copy_from_slice(raw.to_be_bytes().as_ref()); - Ok(()) + Ok(raw.written_len()) } } @@ -403,21 +404,34 @@ try_from_impls!(SeverityLow, Severity::LOW, u32, EventU32TypedSev); try_from_impls!(SeverityMedium, Severity::MEDIUM, u32, EventU32TypedSev); try_from_impls!(SeverityHigh, Severity::HIGH, u32, EventU32TypedSev); -impl EcssEnumeration for EventU32 { - fn pfc(&self) -> u8 { - 32 +impl UnsignedEnum for EventU32 { + fn size(&self) -> usize { + core::mem::size_of::() } - fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError> { - self.base.write_to_bytes(self.raw(), buf, self.byte_width()) + fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { + self.base.write_to_bytes(self.raw(), buf, self.size()) } } +impl EcssEnumeration for EventU32 { + fn pfc(&self) -> u8 { + u32::BITS as u8 + } +} + +//noinspection RsTraitImplementation +impl UnsignedEnum for EventU32TypedSev { + delegate!(to self.event { + fn size(&self) -> usize; + fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result; + }); +} + //noinspection RsTraitImplementation impl EcssEnumeration for EventU32TypedSev { delegate!(to self.event { fn pfc(&self) -> u8; - fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError>; }); } @@ -538,22 +552,34 @@ impl EventU16TypedSev { impl_event_provider!(EventU16, EventU16TypedSev, u16, u8, u8); +impl UnsignedEnum for EventU16 { + fn size(&self) -> usize { + core::mem::size_of::() + } + + fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { + self.base.write_to_bytes(self.raw(), buf, self.size()) + } +} impl EcssEnumeration for EventU16 { #[inline] fn pfc(&self) -> u8 { - 16 + u16::BITS as u8 } +} - fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError> { - self.base.write_to_bytes(self.raw(), buf, self.byte_width()) - } +//noinspection RsTraitImplementation +impl UnsignedEnum for EventU16TypedSev { + delegate!(to self.event { + fn size(&self) -> usize; + fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result; + }); } //noinspection RsTraitImplementation impl EcssEnumeration for EventU16TypedSev { delegate!(to self.event { fn pfc(&self) -> u8; - fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError>; }); } diff --git a/satrs-core/src/params.rs b/satrs-core/src/params.rs index bd616bd..9df929b 100644 --- a/satrs-core/src/params.rs +++ b/satrs-core/src/params.rs @@ -52,13 +52,14 @@ use alloc::vec::Vec; use core::fmt::Debug; use core::mem::size_of; use paste::paste; -use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU64, EcssEnumU8, EcssEnumeration}; +use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU64, EcssEnumU8}; +use spacepackets::util::UnsignedEnum; use spacepackets::ByteConversionError; use spacepackets::SizeMissmatch; #[cfg(feature = "alloc")] pub use alloc_mod::*; -pub use spacepackets::ecss::ToBeBytes; +pub use spacepackets::util::ToBeBytes; /// Generic trait which is used for objects which can be converted into a raw network (big) endian /// byte format. @@ -170,6 +171,11 @@ macro_rules! scalar_byte_conversions_impl { paste! { impl ToBeBytes for [<$ty:upper>] { type ByteArray = [u8; size_of::<$ty>()]; + + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { self.0.to_be_bytes() } @@ -199,6 +205,11 @@ macro_rules! pair_byte_conversions_impl { paste! { impl ToBeBytes for [<$ty:upper Pair>] { type ByteArray = [u8; size_of::<$ty>() * 2]; + + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; size_of::<$ty>() * 2]; array[0..size_of::<$ty>()].copy_from_slice(&self.0.to_be_bytes()); @@ -236,6 +247,11 @@ macro_rules! triplet_to_be_bytes_impl { paste! { impl ToBeBytes for [<$ty:upper Triplet>] { type ByteArray = [u8; size_of::<$ty>() * 3]; + + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; size_of::<$ty>() * 3]; array[0..size_of::<$ty>()].copy_from_slice(&self.0.to_be_bytes()); @@ -275,6 +291,10 @@ scalar_byte_conversions_impl!(u8, u16, u32, u64, i8, i16, i32, i64, f32, f64,); impl ToBeBytes for U8Pair { type ByteArray = [u8; 2]; + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; 2]; array[0] = self.0; @@ -286,6 +306,10 @@ impl ToBeBytes for U8Pair { impl ToBeBytes for I8Pair { type ByteArray = [u8; 2]; + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; 2]; array[0] = self.0 as u8; @@ -297,6 +321,10 @@ impl ToBeBytes for I8Pair { impl ToBeBytes for U8Triplet { type ByteArray = [u8; 3]; + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; 3]; array[0] = self.0; @@ -309,6 +337,10 @@ impl ToBeBytes for U8Triplet { impl ToBeBytes for I8Triplet { type ByteArray = [u8; 3]; + fn written_len(&self) -> usize { + size_of::() + } + fn to_be_bytes(&self) -> Self::ByteArray { let mut array = [0; 3]; array[0] = self.0 as u8; @@ -443,11 +475,11 @@ macro_rules! writable_as_be_bytes_ecss_enum_impl { ($EnumIdent: ident) => { impl WritableToBeBytes for $EnumIdent { fn raw_len(&self) -> usize { - self.byte_width() + self.size() } fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { - EcssEnumeration::write_to_be_bytes(self, buf).map(|_| self.byte_width()) + ::write_to_be_bytes(self, buf).map(|_| self.raw_len()) } } }; @@ -461,10 +493,10 @@ writable_as_be_bytes_ecss_enum_impl!(EcssEnumU64); impl WritableToBeBytes for EcssEnumParams { fn raw_len(&self) -> usize { match self { - EcssEnumParams::U8(e) => e.byte_width(), - EcssEnumParams::U16(e) => e.byte_width(), - EcssEnumParams::U32(e) => e.byte_width(), - EcssEnumParams::U64(e) => e.byte_width(), + EcssEnumParams::U8(e) => e.raw_len(), + EcssEnumParams::U16(e) => e.raw_len(), + EcssEnumParams::U32(e) => e.raw_len(), + EcssEnumParams::U64(e) => e.raw_len(), } } diff --git a/satrs-core/src/pus/event.rs b/satrs-core/src/pus/event.rs index 5bbc63b..146986c 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, EcssTmError, EcssTmErrorWithSend}; +use crate::pus::{source_buffer_large_enough, EcssTmtcError, EcssTmtcErrorWithSend}; use spacepackets::ecss::EcssEnumeration; 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<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { 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<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { 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<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { 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<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.generate_and_send_generic_tm( buf, Subservice::TmHighSeverityReport, @@ -107,11 +107,11 @@ impl EventReporterBase { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { let tm = self.generate_generic_event_tm(buf, subservice, time_stamp, event_id, aux_data)?; sender .send_tm(tm) - .map_err(|e| EcssTmErrorWithSend::SendError(e))?; + .map_err(|e| EcssTmtcErrorWithSend::SendError(e))?; self.msg_count += 1; Ok(()) } @@ -123,8 +123,8 @@ impl EventReporterBase { time_stamp: &'a [u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result { - let mut src_data_len = event_id.byte_width(); + ) -> Result { + let mut src_data_len = event_id.size(); if let Some(aux_data) = aux_data { src_data_len += aux_data.len(); } @@ -138,8 +138,8 @@ impl EventReporterBase { Some(time_stamp), ); let mut current_idx = 0; - event_id.write_to_be_bytes(&mut buf[0..event_id.byte_width()])?; - current_idx += event_id.byte_width(); + event_id.write_to_be_bytes(&mut buf[0..event_id.size()])?; + 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); current_idx += aux_data.len(); @@ -178,7 +178,7 @@ mod allocvec { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_info( self.source_data_buf.as_mut_slice(), sender, @@ -194,7 +194,7 @@ mod allocvec { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_low_severity( self.source_data_buf.as_mut_slice(), sender, @@ -210,7 +210,7 @@ mod allocvec { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_medium_severity( self.source_data_buf.as_mut_slice(), sender, @@ -226,7 +226,7 @@ mod allocvec { time_stamp: &[u8], event_id: impl EcssEnumeration, aux_data: Option<&[u8]>, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter.event_high_severity( self.source_data_buf.as_mut_slice(), sender, @@ -413,7 +413,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 EcssTmErrorWithSend::EcssTmError(EcssTmError::ByteConversionError( + if let EcssTmErrorWithSend::EcssTmError(EcssTmtcError::ByteConversionError( ByteConversionError::ToSliceTooSmall(missmatch), )) = err { diff --git a/satrs-core/src/pus/event_man.rs b/satrs-core/src/pus/event_man.rs index ecb4b59..dbde7fd 100644 --- a/satrs-core/src/pus/event_man.rs +++ b/satrs-core/src/pus/event_man.rs @@ -11,9 +11,9 @@ use hashbrown::HashSet; #[cfg(feature = "alloc")] pub use crate::pus::event::EventReporter; use crate::pus::verification::{TcStateStarted, VerificationToken}; -use crate::pus::EcssTmErrorWithSend; #[cfg(feature = "alloc")] use crate::pus::EcssTmSenderCore; +use crate::pus::EcssTmtcErrorWithSend; #[cfg(feature = "alloc")] #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] pub use alloc_mod::*; @@ -96,13 +96,13 @@ pub struct EventRequestWithToken { #[derive(Debug)] pub enum EventManError { - EcssTmError(EcssTmErrorWithSend), + EcssTmtcError(EcssTmtcErrorWithSend), SeverityMissmatch(Severity, Severity), } -impl From> for EventManError { - fn from(v: EcssTmErrorWithSend) -> Self { - Self::EcssTmError(v) +impl From> for EventManError { + fn from(v: EcssTmtcErrorWithSend) -> Self { + Self::EcssTmtcError(v) } } diff --git a/satrs-core/src/pus/mod.rs b/satrs-core/src/pus/mod.rs index 4543fb4..9396e03 100644 --- a/satrs-core/src/pus/mod.rs +++ b/satrs-core/src/pus/mod.rs @@ -4,6 +4,7 @@ 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}; @@ -24,21 +25,21 @@ use crate::SenderId; pub use std_mod::*; #[derive(Debug, Clone)] -pub enum EcssTmErrorWithSend { - /// Errors related to sending the telemetry to a TM recipient +pub enum EcssTmtcErrorWithSend { + /// Errors related to sending the telemetry to a TMTC recipient SendError(E), - EcssTmError(EcssTmError), + EcssTmtcError(EcssTmtcError), } -impl From for EcssTmErrorWithSend { - fn from(value: EcssTmError) -> Self { - Self::EcssTmError(value) +impl From for EcssTmtcErrorWithSend { + fn from(value: EcssTmtcError) -> Self { + Self::EcssTmtcError(value) } } /// Generic error type for PUS TM handling. #[derive(Debug, Clone)] -pub enum EcssTmError { +pub enum EcssTmtcError { /// Errors related to the time stamp format of the telemetry TimestampError(TimestampError), /// Errors related to byte conversion, for example insufficient buffer size for given data @@ -47,30 +48,41 @@ pub enum EcssTmError { PusError(PusError), } -impl From for EcssTmError { +impl From for EcssTmtcError { fn from(e: PusError) -> Self { - EcssTmError::PusError(e) + EcssTmtcError::PusError(e) } } -impl From for EcssTmError { +impl From for EcssTmtcError { fn from(e: ByteConversionError) -> Self { - EcssTmError::ByteConversionError(e) + EcssTmtcError::ByteConversionError(e) } } +pub trait EcssSender: Send { + /// Each sender can have an ID associated with it + fn id(&self) -> SenderId; + fn name(&self) -> &'static str { + "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(&mut self, tm: PusTm) -> Result<(), Self::Error>; +} + /// Generic trait for a user supplied sender object. /// -/// This sender object is responsible for sending telemetry to a TM sink. -pub trait EcssTmSenderCore: Send { +/// This sender object is responsible for sending PUS telecommands to a TC recipient. +pub trait EcssTcSenderCore: EcssSender { type Error; - /// Each sender can have an ID associated with it - fn id(&self) -> SenderId; - fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error>; - fn name(&self) -> &'static str { - "unset" - } + fn send_tc(&mut self, tc: PusTc) -> Result<(), Self::Error>; } #[cfg(feature = "alloc")] @@ -96,15 +108,36 @@ mod alloc_mod { dyn_clone::clone_trait_object!( EcssTmSender); impl_downcast!(EcssTmSender assoc Error); + + /// Extension trait for [EcssTcSenderCore]. + /// + /// 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 EcssTcSender: EcssTcSenderCore + Downcast + DynClone {} + + /// 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); } #[cfg(feature = "std")] pub mod std_mod { use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError}; - use crate::pus::EcssTmSenderCore; + use crate::pus::{EcssSender, EcssTcSenderCore, EcssTmSenderCore}; use crate::SenderId; use alloc::vec::Vec; - use spacepackets::ecss::PusError; + use spacepackets::ecss::{PusError, SerializablePusPacket}; + use spacepackets::tc::PusTc; use spacepackets::tm::PusTm; use std::sync::mpsc::SendError; use std::sync::{mpsc, RwLockWriteGuard}; @@ -135,7 +168,7 @@ pub mod std_mod { } #[derive(Clone)] - pub struct MpscTmInStoreSender { + pub struct MpscTmtcInStoreSender { id: SenderId, name: &'static str, store_helper: SharedPool, @@ -143,13 +176,19 @@ pub mod std_mod { pub ignore_poison_errors: bool, } - impl EcssTmSenderCore for MpscTmInStoreSender { - type Error = MpscPusInStoreSendError; - + impl EcssSender for MpscTmtcInStoreSender { fn id(&self) -> SenderId { self.id } + fn name(&self) -> &'static str { + self.name + } + } + + impl EcssTmSenderCore for MpscTmtcInStoreSender { + type Error = MpscPusInStoreSendError; + fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error> { let operation = |mut store: RwLockWriteGuard| { let (addr, slice) = store.free_element(tm.len_packed())?; @@ -168,13 +207,32 @@ pub mod std_mod { } } } + } - fn name(&self) -> &'static str { - self.name + impl EcssTcSenderCore for MpscTmtcInStoreSender { + type Error = MpscPusInStoreSendError; + + fn send_tc(&mut self, tc: PusTc) -> Result<(), Self::Error> { + let operation = |mut store: RwLockWriteGuard| { + let (addr, slice) = store.free_element(tc.len_packed())?; + tc.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(MpscPusInStoreSendError::LockError) + } + } + } } } - impl MpscTmInStoreSender { + impl MpscTmtcInStoreSender { pub fn new( id: SenderId, name: &'static str, @@ -209,11 +267,18 @@ pub mod std_mod { Self { id, sender, name } } } - impl EcssTmSenderCore for MpscTmAsVecSender { - type Error = MpscAsVecSenderError; + + impl EcssSender for MpscTmAsVecSender { fn id(&self) -> SenderId { self.id } + fn name(&self) -> &'static str { + self.name + } + } + + impl EcssTmSenderCore for MpscTmAsVecSender { + type Error = MpscAsVecSenderError; fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error> { let mut vec = Vec::new(); @@ -224,10 +289,6 @@ pub mod std_mod { .map_err(MpscAsVecSenderError::SendError)?; Ok(()) } - - fn name(&self) -> &'static str { - self.name - } } } @@ -237,9 +298,9 @@ pub enum GenericTcCheckError { InvalidSubservice, } -pub(crate) fn source_buffer_large_enough(cap: usize, len: usize) -> Result<(), EcssTmError> { +pub(crate) fn source_buffer_large_enough(cap: usize, len: usize) -> Result<(), EcssTmtcError> { if len > cap { - return Err(EcssTmError::ByteConversionError( + return Err(EcssTmtcError::ByteConversionError( ByteConversionError::ToSliceTooSmall(SizeMissmatch { found: cap, expected: len, diff --git a/satrs-core/src/pus/verification.rs b/satrs-core/src/pus/verification.rs index b60bc3f..c42e758 100644 --- a/satrs-core/src/pus/verification.rs +++ b/satrs-core/src/pus/verification.rs @@ -73,7 +73,7 @@ //! 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, EcssTmError, EcssTmErrorWithSend, EcssTmSenderCore, + source_buffer_large_enough, EcssTmSenderCore, EcssTmtcError, EcssTmtcErrorWithSend, GenericTcCheckError, }; use core::fmt::{Debug, Display, Formatter}; @@ -179,12 +179,12 @@ impl RequestId { /// re-trying the operation at a later point. #[derive(Debug, Clone)] pub struct VerificationOrSendErrorWithToken( - pub EcssTmErrorWithSend, + pub EcssTmtcErrorWithSend, pub VerificationToken, ); #[derive(Debug, Clone)] -pub struct VerificationErrorWithToken(pub EcssTmError, pub VerificationToken); +pub struct VerificationErrorWithToken(pub EcssTmtcError, pub VerificationToken); impl From> for VerificationOrSendErrorWithToken { fn from(value: VerificationErrorWithToken) -> Self { @@ -543,7 +543,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -561,7 +561,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -630,7 +630,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -674,7 +674,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -693,7 +693,7 @@ impl VerificationReporterCore { msg_counter: &(impl SequenceCountProviderCore + ?Sized), time_stamp: Option<&'src_data [u8]>, step: impl EcssEnumeration, - ) -> Result, EcssTmError> { + ) -> Result, EcssTmtcError> { Ok(VerificationSendable::new_no_token( self.create_pus_verif_success_tm( src_data_buf, @@ -799,7 +799,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -818,7 +818,7 @@ impl VerificationReporterCore { .send_tm(sendable.pus_tm.take().unwrap()) .map_err(|e| { VerificationOrSendErrorWithToken( - EcssTmErrorWithSend::SendError(e), + EcssTmtcErrorWithSend::SendError(e), sendable.token.unwrap(), ) })?; @@ -837,10 +837,10 @@ impl VerificationReporterCore { req_id: &RequestId, time_stamp: Option<&'src_data [u8]>, step: Option<&(impl EcssEnumeration + ?Sized)>, - ) -> Result, EcssTmError> { + ) -> Result, EcssTmtcError> { let mut source_data_len = size_of::(); if let Some(step) = step { - source_data_len += step.byte_width(); + source_data_len += step.size(); } source_buffer_large_enough(src_data_buf.len(), source_data_len)?; let mut idx = 0; @@ -848,7 +848,7 @@ impl VerificationReporterCore { idx += RequestId::SIZE_AS_BYTES; if let Some(step) = step { // Size check was done beforehand - step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.byte_width()]) + step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.size()]) .unwrap(); } let mut sp_header = SpHeader::tm_unseg(self.apid(), seq_count, 0).unwrap(); @@ -873,11 +873,11 @@ impl VerificationReporterCore { req_id: &RequestId, step: Option<&(impl EcssEnumeration + ?Sized)>, params: &FailParams<'src_data, '_>, - ) -> Result, EcssTmError> { + ) -> Result, EcssTmtcError> { let mut idx = 0; - let mut source_data_len = RequestId::SIZE_AS_BYTES + params.failure_code.byte_width(); + let mut source_data_len = RequestId::SIZE_AS_BYTES + params.failure_code.size(); if let Some(step) = step { - source_data_len += step.byte_width(); + source_data_len += step.size(); } if let Some(failure_data) = params.failure_data { source_data_len += failure_data.len(); @@ -887,14 +887,14 @@ impl VerificationReporterCore { idx += RequestId::SIZE_AS_BYTES; if let Some(step) = step { // Size check done beforehand - step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.byte_width()]) + step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.size()]) .unwrap(); - idx += step.byte_width(); + idx += step.size(); } params .failure_code - .write_to_be_bytes(&mut src_data_buf[idx..idx + params.failure_code.byte_width()])?; - idx += params.failure_code.byte_width(); + .write_to_be_bytes(&mut src_data_buf[idx..idx + params.failure_code.size()])?; + 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); } @@ -1121,7 +1121,7 @@ mod alloc_mod { sender: &mut (impl EcssTmSenderCore + ?Sized), time_stamp: Option<&[u8]>, step: impl EcssEnumeration, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { let sendable = self.reporter.step_success( self.source_data_buf.as_mut_slice(), token, @@ -1298,7 +1298,7 @@ mod alloc_mod { token: &VerificationToken, time_stamp: Option<&[u8]>, step: impl EcssEnumeration, - ) -> Result<(), EcssTmErrorWithSend> { + ) -> Result<(), EcssTmtcErrorWithSend> { self.reporter .step_success(token, self.sender.as_mut(), time_stamp, step) } @@ -1337,9 +1337,10 @@ mod stdmod { use super::alloc_mod::VerificationReporterWithSender; use super::*; use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr}; - use crate::pus::MpscPusInStoreSendError; + use crate::pus::{EcssSender, MpscPusInStoreSendError}; use crate::SenderId; use delegate::delegate; + use spacepackets::ecss::SerializablePusPacket; use spacepackets::tm::PusTm; use std::sync::{mpsc, Arc, Mutex, RwLockWriteGuard}; @@ -1400,14 +1401,22 @@ mod stdmod { } } + //noinspection RsTraitImplementation + impl EcssSender for MpscVerifSender { + delegate!( + to self.base { + fn id(&self) -> SenderId; + fn name(&self) -> &'static str; + } + ); + } + //noinspection RsTraitImplementation impl EcssTmSenderCore for MpscVerifSender { type Error = MpscPusInStoreSendError; delegate!( to self.base { - fn id(&self) -> SenderId; - fn name(&self) -> &'static str; fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error>; } ); @@ -1441,6 +1450,17 @@ mod stdmod { } } + //noinspection RsTraitImplementation + #[cfg(feature = "crossbeam")] + impl EcssSender for CrossbeamVerifSender { + delegate!( + to self.base { + fn id(&self) -> SenderId; + fn name(&self) -> &'static str; + } + ); + } + //noinspection RsTraitImplementation #[cfg(feature = "crossbeam")] impl EcssTmSenderCore for CrossbeamVerifSender { @@ -1448,19 +1468,21 @@ mod stdmod { delegate!( to self.base { - fn id(&self) -> SenderId; - fn name(&self) -> &'static str; fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error>; } ); } - impl EcssTmSenderCore for StdSenderBase { - type Error = MpscPusInStoreSendError; - + impl EcssSender for StdSenderBase { fn id(&self) -> SenderId { self.id } + fn name(&self) -> &'static str { + self.name + } + } + impl EcssTmSenderCore for StdSenderBase { + type Error = MpscPusInStoreSendError; fn send_tm(&mut self, tm: PusTm) -> Result<(), Self::Error> { let operation = |mut mg: RwLockWriteGuard| { @@ -1484,10 +1506,6 @@ mod stdmod { } } } - - fn name(&self) -> &'static str { - self.name - } } } @@ -1799,7 +1817,7 @@ mod tests { let err_with_token = res.unwrap_err(); assert_eq!(err_with_token.1, tok); match err_with_token.0 { - EcssTmErrorWithSend::EcssTmError(EcssTmError::ByteConversionError(e)) => match e { + EcssTmErrorWithSend::EcssTmError(EcssTmtcError::ByteConversionError(e)) => match e { ByteConversionError::ToSliceTooSmall(missmatch) => { assert_eq!( missmatch.expected, diff --git a/satrs-core/src/res_code.rs b/satrs-core/src/res_code.rs index 9918ecf..5b0c64e 100644 --- a/satrs-core/src/res_code.rs +++ b/satrs-core/src/res_code.rs @@ -1,6 +1,7 @@ #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use spacepackets::ecss::{EcssEnumU16, EcssEnumeration}; +use spacepackets::util::UnsignedEnum; use spacepackets::{ByteConversionError, SizeMissmatch}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -34,12 +35,12 @@ impl From for EcssEnumU16 { } } -impl EcssEnumeration for ResultU16 { - fn pfc(&self) -> u8 { - 16 +impl UnsignedEnum for ResultU16 { + fn size(&self) -> usize { + core::mem::size_of::() } - fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<(), ByteConversionError> { + fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { if buf.len() < 2 { return Err(ByteConversionError::ToSliceTooSmall(SizeMissmatch { found: buf.len(), @@ -48,6 +49,12 @@ impl EcssEnumeration for ResultU16 { } buf[0] = self.group_id; buf[1] = self.unique_id; - Ok(()) + Ok(self.size()) + } +} + +impl EcssEnumeration for ResultU16 { + fn pfc(&self) -> u8 { + 16 } } diff --git a/satrs-example/Cargo.toml b/satrs-example/Cargo.toml index ac403e2..a5c559b 100644 --- a/satrs-example/Cargo.toml +++ b/satrs-example/Cargo.toml @@ -10,10 +10,10 @@ fern = "0.6" chrono = "0.4" log = "0.4" crossbeam-channel = "0.5" -delegate = "0.9" +delegate = "0.10" zerocopy = "0.6" csv = "1" -num_enum = "0.5" +num_enum = "0.6" [dependencies.satrs-core] path = "../satrs-core" diff --git a/satrs-example/src/bin/simpleclient.rs b/satrs-example/src/bin/simpleclient.rs index 83ec49f..d28eeb8 100644 --- a/satrs-example/src/bin/simpleclient.rs +++ b/satrs-example/src/bin/simpleclient.rs @@ -1,6 +1,8 @@ use satrs_core::pus::verification::RequestId; use satrs_core::{ - spacepackets::ecss::PusPacket, spacepackets::tc::PusTc, spacepackets::tm::PusTm, + spacepackets::ecss::{PusPacket, SerializablePusPacket}, + spacepackets::tc::PusTc, + spacepackets::tm::PusTm, spacepackets::SpHeader, }; use satrs_example::{OBSW_SERVER_ADDR, SERVER_PORT}; diff --git a/satrs-example/src/main.rs b/satrs-example/src/main.rs index 86d79e3..450c694 100644 --- a/satrs-example/src/main.rs +++ b/satrs-example/src/main.rs @@ -27,7 +27,7 @@ use satrs_core::pus::hk::Subservice as HkSubservice; use satrs_core::pus::verification::{ MpscVerifSender, VerificationReporterCfg, VerificationReporterWithSender, }; -use satrs_core::pus::MpscTmInStoreSender; +use satrs_core::pus::MpscTmtcInStoreSender; use satrs_core::seq_count::{SeqCountProviderSimple, SeqCountProviderSyncClonable}; use satrs_core::spacepackets::{ time::cds::TimeProvider, @@ -185,7 +185,7 @@ fn main() { .spawn(move || { let mut timestamp: [u8; 7] = [0; 7]; let mut sender = - MpscTmInStoreSender::new(1, "event_sender", tm_store.pool, tm_funnel_tx); + MpscTmtcInStoreSender::new(1, "event_sender", tm_store.pool, 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 diff --git a/satrs-example/src/pus.rs b/satrs-example/src/pus.rs index e2dd2f2..e677055 100644 --- a/satrs-example/src/pus.rs +++ b/satrs-example/src/pus.rs @@ -33,6 +33,9 @@ use std::convert::TryFrom; use std::rc::Rc; use std::sync::mpsc::{Receiver, Sender}; +pub trait PusTcMultiplexer { + fn route_pus_tc(tc: &PusTc, apid: u16, service: u8, subservice: u8); +} pub struct PusReceiver { pub tm_helper: PusTmWithCdsShortHelper, pub tm_args: PusTmArgs, diff --git a/satrs-example/src/tmtc.rs b/satrs-example/src/tmtc.rs index 8b07856..0124cc2 100644 --- a/satrs-example/src/tmtc.rs +++ b/satrs-example/src/tmtc.rs @@ -20,6 +20,7 @@ use satrs_core::pus::event_man::EventRequestWithToken; use satrs_core::pus::scheduling::{PusScheduler, TcInfo}; use satrs_core::pus::verification::StdVerifReporterWithSender; use satrs_core::seq_count::SeqCountProviderSyncClonable; +use satrs_core::spacepackets::ecss::SerializablePusPacket; use satrs_core::spacepackets::{ecss::PusPacket, tc::PusTc, tm::PusTm, SpHeader}; use satrs_core::tmtc::{ CcsdsDistributor, CcsdsError, PusServiceProvider, ReceivesCcsdsTc, ReceivesEcssPusTc, diff --git a/satrs-mib/Cargo.toml b/satrs-mib/Cargo.toml index 8be0562..e736fec 100644 --- a/satrs-mib/Cargo.toml +++ b/satrs-mib/Cargo.toml @@ -19,7 +19,7 @@ path = "../satrs-core" path = "codegen" [dependencies.serde] -version = "1.0" +version = "1" default-features = false [features] diff --git a/satrs-mib/codegen/Cargo.toml b/satrs-mib/codegen/Cargo.toml index 7a1d882..bd014f5 100644 --- a/satrs-mib/codegen/Cargo.toml +++ b/satrs-mib/codegen/Cargo.toml @@ -12,18 +12,18 @@ name = "tests" path = "tests/tests.rs" [dependencies] -quote = "1.0" -proc-macro2 = "1.0" +quote = "1" +proc-macro2 = "1" [dependencies.satrs-core] path = "../../satrs-core" [dev-dependencies] -trybuild = { version = "1.0", features = ["diff"] } +trybuild = { version = "1", features = ["diff"] } [dev-dependencies.satrs-mib] path = ".." [dependencies.syn] -version = "1.0" -features = ["extra-traits"] +version = "2" +features = ["full", "extra-traits"] diff --git a/satrs-mib/codegen/src/lib.rs b/satrs-mib/codegen/src/lib.rs index 2fa36ee..3f144c6 100644 --- a/satrs-mib/codegen/src/lib.rs +++ b/satrs-mib/codegen/src/lib.rs @@ -1,105 +1,42 @@ -use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote, ToTokens}; -use syn::spanned::Spanned; -use syn::{parse_macro_input, AttributeArgs, Item, Lit, LitStr, Meta, NestedMeta, Type}; - -#[derive(Default)] -struct ResultExtGenerator { - name_str: Option, - info_str: Option, -} +use syn::{parse_macro_input, ItemConst, LitStr}; #[proc_macro_attribute] pub fn resultcode( args: proc_macro::TokenStream, item: proc_macro::TokenStream, ) -> proc_macro::TokenStream { - let args = parse_macro_input!(args as AttributeArgs); - let input = parse_macro_input!(item as Item); - let mut result_ext_generator = ResultExtGenerator::default(); - result_ext_generator.parse(args, input).into() -} - -impl ResultExtGenerator { - pub fn parse(&mut self, args: AttributeArgs, input: Item) -> TokenStream { - let mut output = input.to_token_stream(); - if let Err(e) = self.parse_args(args) { - output.extend(e.into_compile_error()); - return output; - } - match self.gen_ext_struct(input) { - Ok(ts) => output.extend(ts), - Err(e) => output.extend(e.into_compile_error()), - } - output - } - - pub fn parse_args(&mut self, args: AttributeArgs) -> syn::Result<()> { - for arg in args { - if let NestedMeta::Meta(Meta::NameValue(nvm)) = arg { - if let Some(path) = nvm.path.segments.first() { - if path.ident == "info" { - if let Lit::Str(str) = nvm.lit { - self.info_str = Some(str); - } else { - return Err(syn::Error::new( - nvm.lit.span(), - "Only literal strings are allowed as information", - )); - } - } else { - return Err(syn::Error::new( - path.span(), - format!("Unknown attribute argument name {}", path.ident), - )); - } - } - } - } - Ok(()) - } - - pub fn gen_ext_struct(&mut self, input: Item) -> syn::Result { - if let Item::Const(const_item) = &input { - self.name_str = Some(const_item.ident.clone()); - if let Type::Path(p) = &const_item.ty.as_ref() { - let mut valid_type_found = false; - for seg in &p.path.segments { - if seg.ident == "ResultU16" { - valid_type_found = true; - } - } - if !valid_type_found { - return Err(syn::Error::new( - p.span(), - "Can only be applied on items of type ResultU16", - )); - } - } + // Handle attributes first. + let mut info_str: Option = None; + let res_code_parser = syn::meta::parser(|meta| { + if meta.path.is_ident("info") { + info_str = Some(meta.value()?.parse()?); + Ok(()) } else { - return Err(syn::Error::new( - input.span(), - "Only const items are allowed to be use with this attribute", - )); + Err(meta.error("unsupported property for resultcode attribute")) } - let result_code_name = self.name_str.to_owned().unwrap(); - let name_as_str = result_code_name.to_string(); - let gen_struct_name = format_ident!("{}_EXT", result_code_name); - let info_str = if let Some(info_str) = &self.info_str { - info_str.value() - } else { - String::from("") - }; - // TODO: Group string - let gen_struct = quote! { - const #gen_struct_name: satrs_mib::res_code::ResultU16Info = - satrs_mib::res_code::ResultU16Info::const_new( - #name_as_str, - &#result_code_name, - "", - #info_str - ); - }; - Ok(gen_struct) - } + }); + parse_macro_input!(args with res_code_parser); + let item = parse_macro_input!(item as ItemConst); + + // Generate additional generated info struct used for introspection. + let result_code_name = item.ident.clone(); + let name_as_str = result_code_name.to_string(); + let gen_struct_name = format_ident!("{}_EXT", result_code_name); + let info_str = info_str.map_or(String::from(""), |v| v.value()); + // TODO: Group string + let generated_struct = quote! { + const #gen_struct_name: satrs_mib::res_code::ResultU16Info = + satrs_mib::res_code::ResultU16Info::const_new( + #name_as_str, + &#result_code_name, + "", + #info_str + ); + }; + + // The input constant returncode is written to the output in any case. + let mut output = item.to_token_stream(); + output.extend(generated_struct); + output.into() } diff --git a/satrs-mib/codegen/tests/basic.rs b/satrs-mib/codegen/tests/basic.rs index 2030920..d4cf1ab 100644 --- a/satrs-mib/codegen/tests/basic.rs +++ b/satrs-mib/codegen/tests/basic.rs @@ -2,7 +2,7 @@ use satrs_core::res_code::ResultU16; use satrs_mib::resultcode; -#[resultcode(info = "This is a test result where the first parameter is foo")] +#[resultcode] const _TEST_RESULT: ResultU16 = ResultU16::const_new(0, 1); fn main() {} diff --git a/satrs-mib/codegen/tests/basic_with_info.rs b/satrs-mib/codegen/tests/basic_with_info.rs new file mode 100644 index 0000000..2030920 --- /dev/null +++ b/satrs-mib/codegen/tests/basic_with_info.rs @@ -0,0 +1,8 @@ +//! Basic check which just verifies that everything compiles +use satrs_core::res_code::ResultU16; +use satrs_mib::resultcode; + +#[resultcode(info = "This is a test result where the first parameter is foo")] +const _TEST_RESULT: ResultU16 = ResultU16::const_new(0, 1); + +fn main() {} diff --git a/satrs-mib/codegen/tests/tests.rs b/satrs-mib/codegen/tests/tests.rs index daf9fc7..f5bd36c 100644 --- a/satrs-mib/codegen/tests/tests.rs +++ b/satrs-mib/codegen/tests/tests.rs @@ -2,6 +2,7 @@ fn tests() { let t = trybuild::TestCases::new(); t.pass("tests/basic.rs"); + t.pass("tests/basic_with_info.rs"); t.pass("tests/verify_gen_struct.rs"); //t.pass("tests/group_in_enum.rs"); }