Merge pull request 'Clonable Verification Reporter' (#24) from clonable_verification_structs into main

Reviewed-on: rust/satrs-launchpad#24
This commit is contained in:
Robin Müller 2022-11-21 15:02:01 +01:00
commit b8efa8e518
12 changed files with 246 additions and 84 deletions

7
Cargo.lock generated
View File

@ -284,6 +284,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]]
name = "dyn-clone"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2"
[[package]] [[package]]
name = "embed-doc-image" name = "embed-doc-image"
version = "0.1.4" version = "0.1.4"
@ -597,6 +603,7 @@ dependencies = [
"crossbeam-channel", "crossbeam-channel",
"delegate 0.8.0", "delegate 0.8.0",
"downcast-rs", "downcast-rs",
"dyn-clone",
"embed-doc-image", "embed-doc-image",
"hashbrown", "hashbrown",
"heapless", "heapless",

View File

@ -10,6 +10,7 @@ delegate = "0.8"
hashbrown = "0.13" hashbrown = "0.13"
heapless = "0.7" heapless = "0.7"
paste = "1.0" paste = "1.0"
dyn-clone = "1.0.9"
embed-doc-image = "0.1" embed-doc-image = "0.1"
[dependencies.num-traits] [dependencies.num-traits]

View File

@ -29,4 +29,5 @@ pub mod params;
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
pub mod pool; pub mod pool;
pub mod pus; pub mod pus;
pub mod seq_count;
pub mod tmtc; pub mod tmtc;

View File

@ -298,14 +298,14 @@ mod tests {
#[allow(dead_code)] #[allow(dead_code)]
const EXAMPLE_EVENT_ID_1: u16 = 2; const EXAMPLE_EVENT_ID_1: u16 = 2;
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq, Clone)]
struct TmInfo { struct TmInfo {
pub common: CommonTmInfo, pub common: CommonTmInfo,
pub event: EventU32, pub event: EventU32,
pub aux_data: Vec<u8>, pub aux_data: Vec<u8>,
} }
#[derive(Default)] #[derive(Default, Clone)]
struct TestSender { struct TestSender {
pub service_queue: VecDeque<TmInfo>, pub service_queue: VecDeque<TmInfo>,
} }

View File

@ -233,6 +233,7 @@ mod tests {
const LOW_SEV_EVENT: EventU32 = EventU32::const_new(Severity::LOW, 1, 5); const LOW_SEV_EVENT: EventU32 = EventU32::const_new(Severity::LOW, 1, 5);
const EMPTY_STAMP: [u8; 7] = [0; 7]; const EMPTY_STAMP: [u8; 7] = [0; 7];
#[derive(Clone)]
struct EventTmSender { struct EventTmSender {
sender: std::sync::mpsc::Sender<Vec<u8>>, sender: std::sync::mpsc::Sender<Vec<u8>>,
} }

View File

@ -4,6 +4,7 @@
//! //!
//! 1. PUS Verification Service 1 module inside [verification]. Requires [alloc] support. //! 1. PUS Verification Service 1 module inside [verification]. Requires [alloc] support.
use downcast_rs::{impl_downcast, Downcast}; use downcast_rs::{impl_downcast, Downcast};
use dyn_clone::DynClone;
use spacepackets::ecss::PusError; use spacepackets::ecss::PusError;
use spacepackets::time::TimestampError; use spacepackets::time::TimestampError;
use spacepackets::tm::PusTm; use spacepackets::tm::PusTm;
@ -43,13 +44,14 @@ impl<E> From<ByteConversionError> for EcssTmError<E> {
/// This sender object is responsible for sending telemetry to a TM sink. The [Downcast] trait /// This sender object is responsible for sending telemetry to a TM sink. The [Downcast] trait
/// is implemented to allow passing the sender as a boxed trait object and still retrieve the /// is implemented to allow passing the sender as a boxed trait object and still retrieve the
/// concrete type at a later point. /// concrete type at a later point.
pub trait EcssTmSender: Downcast + Send { pub trait EcssTmSender: Downcast + Send + DynClone {
type Error; type Error;
fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<Self::Error>>; fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<Self::Error>>;
} }
impl_downcast!(EcssTmSender assoc Error); impl_downcast!(EcssTmSender assoc Error);
dyn_clone::clone_trait_object!(<T> EcssTmSender<Error=T>);
pub(crate) fn source_buffer_large_enough<E>(cap: usize, len: usize) -> Result<(), EcssTmError<E>> { pub(crate) fn source_buffer_large_enough<E>(cap: usize, len: usize) -> Result<(), EcssTmError<E>> {
if len > cap { if len > cap {
@ -68,7 +70,7 @@ pub(crate) mod tests {
use spacepackets::tm::{PusTm, PusTmSecondaryHeaderT}; use spacepackets::tm::{PusTm, PusTmSecondaryHeaderT};
use spacepackets::CcsdsPacket; use spacepackets::CcsdsPacket;
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq, Clone)]
pub(crate) struct CommonTmInfo { pub(crate) struct CommonTmInfo {
pub subservice: u8, pub subservice: u8,
pub apid: u16, pub apid: u16,

View File

@ -17,6 +17,7 @@
//! use std::time::Duration; //! use std::time::Duration;
//! use satrs_core::pool::{LocalPool, PoolCfg, PoolProvider, SharedPool}; //! use satrs_core::pool::{LocalPool, PoolCfg, PoolProvider, SharedPool};
//! use satrs_core::pus::verification::{CrossbeamVerifSender, VerificationReporterCfg, VerificationReporterWithSender}; //! use satrs_core::pus::verification::{CrossbeamVerifSender, VerificationReporterCfg, VerificationReporterWithSender};
//! use satrs_core::seq_count::SimpleSeqCountProvider;
//! use spacepackets::ecss::PusPacket; //! use spacepackets::ecss::PusPacket;
//! use spacepackets::SpHeader; //! use spacepackets::SpHeader;
//! use spacepackets::tc::{PusTc, PusTcSecondaryHeader}; //! use spacepackets::tc::{PusTc, PusTcSecondaryHeader};
@ -29,8 +30,8 @@
//! let shared_tm_pool: SharedPool = Arc::new(RwLock::new(Box::new(LocalPool::new(pool_cfg.clone())))); //! let shared_tm_pool: SharedPool = Arc::new(RwLock::new(Box::new(LocalPool::new(pool_cfg.clone()))));
//! let (verif_tx, verif_rx) = crossbeam_channel::bounded(10); //! let (verif_tx, verif_rx) = crossbeam_channel::bounded(10);
//! let sender = CrossbeamVerifSender::new(shared_tm_pool.clone(), verif_tx); //! let sender = CrossbeamVerifSender::new(shared_tm_pool.clone(), verif_tx);
//! let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap(); //! let cfg = VerificationReporterCfg::new(TEST_APID, Box::new(SimpleSeqCountProvider::default()), 1, 2, 8).unwrap();
//! let mut reporter = VerificationReporterWithSender::new(cfg , Box::new(sender)); //! let mut reporter = VerificationReporterWithSender::new(&cfg , Box::new(sender));
//! //!
//! let mut sph = SpHeader::tc(TEST_APID, 0, 0).unwrap(); //! let mut sph = SpHeader::tc(TEST_APID, 0, 0).unwrap();
//! let tc_header = PusTcSecondaryHeader::new_simple(17, 1); //! let tc_header = PusTcSecondaryHeader::new_simple(17, 1);
@ -83,9 +84,14 @@ use spacepackets::tm::{PusTm, PusTmSecondaryHeader};
use spacepackets::{CcsdsPacket, PacketId, PacketSequenceCtrl}; use spacepackets::{CcsdsPacket, PacketId, PacketSequenceCtrl};
use spacepackets::{SpHeader, MAX_APID}; use spacepackets::{SpHeader, MAX_APID};
#[cfg(feature = "alloc")] pub use crate::seq_count::SimpleSeqCountProvider;
pub use allocmod::{VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender};
#[cfg(feature = "alloc")]
pub use allocmod::{
VerificationReporterCfg, VerificationReporterWithBuf, VerificationReporterWithSender,
};
use crate::seq_count::SequenceCountProvider;
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use stdmod::{ pub use stdmod::{
CrossbeamVerifSender, MpscVerifSender, SharedStdVerifReporterWithSender, CrossbeamVerifSender, MpscVerifSender, SharedStdVerifReporterWithSender,
@ -276,10 +282,10 @@ impl<'a> FailParamsWithStep<'a> {
} }
} }
#[derive(Clone)]
pub struct VerificationReporterBasic { pub struct VerificationReporterBasic {
pub dest_id: u16, pub dest_id: u16,
apid: u16, apid: u16,
msg_count: u16,
} }
impl VerificationReporterBasic { impl VerificationReporterBasic {
@ -287,11 +293,7 @@ impl VerificationReporterBasic {
if apid > MAX_APID { if apid > MAX_APID {
return None; return None;
} }
Some(Self { Some(Self { apid, dest_id: 0 })
apid,
msg_count: 0,
dest_id: 0,
})
} }
pub fn set_apid(&mut self, apid: u16) -> bool { pub fn set_apid(&mut self, apid: u16) -> bool {
@ -332,6 +334,7 @@ impl VerificationReporterBasic {
buf: &mut [u8], buf: &mut [u8],
token: VerificationToken<TcStateNone>, token: VerificationToken<TcStateNone>,
sender: &mut (impl EcssTmSender<Error = E> + ?Sized), sender: &mut (impl EcssTmSender<Error = E> + ?Sized),
seq_counter: &mut (impl SequenceCountProvider<u16> + ?Sized),
time_stamp: &[u8], time_stamp: &[u8],
) -> Result<VerificationToken<TcStateAccepted>, VerificationErrorWithToken<E, TcStateNone>> ) -> Result<VerificationToken<TcStateAccepted>, VerificationErrorWithToken<E, TcStateNone>>
{ {
@ -339,6 +342,7 @@ impl VerificationReporterBasic {
.create_pus_verif_success_tm( .create_pus_verif_success_tm(
buf, buf,
Subservices::TmAcceptanceSuccess.into(), Subservices::TmAcceptanceSuccess.into(),
seq_counter.get(),
&token.req_id, &token.req_id,
time_stamp, time_stamp,
None::<&dyn EcssEnumeration>, None::<&dyn EcssEnumeration>,
@ -347,7 +351,8 @@ impl VerificationReporterBasic {
sender sender
.send_tm(tm) .send_tm(tm)
.map_err(|e| VerificationErrorWithToken(e, token))?; .map_err(|e| VerificationErrorWithToken(e, token))?;
self.msg_count += 1; seq_counter.increment();
//seq_counter.get_and_increment()
Ok(VerificationToken { Ok(VerificationToken {
state: PhantomData, state: PhantomData,
req_id: token.req_id, req_id: token.req_id,
@ -360,12 +365,14 @@ impl VerificationReporterBasic {
buf: &mut [u8], buf: &mut [u8],
token: VerificationToken<TcStateNone>, token: VerificationToken<TcStateNone>,
sender: &mut (impl EcssTmSender<Error = E> + ?Sized), sender: &mut (impl EcssTmSender<Error = E> + ?Sized),
seq_counter: &mut (impl SequenceCountProvider<u16> + ?Sized),
params: FailParams, params: FailParams,
) -> Result<(), VerificationErrorWithToken<E, TcStateNone>> { ) -> Result<(), VerificationErrorWithToken<E, TcStateNone>> {
let tm = self let tm = self
.create_pus_verif_fail_tm( .create_pus_verif_fail_tm(
buf, buf,
Subservices::TmAcceptanceFailure.into(), Subservices::TmAcceptanceFailure.into(),
seq_counter.get(),
&token.req_id, &token.req_id,
None::<&dyn EcssEnumeration>, None::<&dyn EcssEnumeration>,
&params, &params,
@ -374,7 +381,7 @@ impl VerificationReporterBasic {
sender sender
.send_tm(tm) .send_tm(tm)
.map_err(|e| VerificationErrorWithToken(e, token))?; .map_err(|e| VerificationErrorWithToken(e, token))?;
self.msg_count += 1; seq_counter.increment();
Ok(()) Ok(())
} }
@ -386,6 +393,7 @@ impl VerificationReporterBasic {
buf: &mut [u8], buf: &mut [u8],
token: VerificationToken<TcStateAccepted>, token: VerificationToken<TcStateAccepted>,
sender: &mut (impl EcssTmSender<Error = E> + ?Sized), sender: &mut (impl EcssTmSender<Error = E> + ?Sized),
seq_counter: &mut (impl SequenceCountProvider<u16> + ?Sized),
time_stamp: &[u8], time_stamp: &[u8],
) -> Result<VerificationToken<TcStateStarted>, VerificationErrorWithToken<E, TcStateAccepted>> ) -> Result<VerificationToken<TcStateStarted>, VerificationErrorWithToken<E, TcStateAccepted>>
{ {
@ -393,6 +401,7 @@ impl VerificationReporterBasic {
.create_pus_verif_success_tm( .create_pus_verif_success_tm(
buf, buf,
Subservices::TmStartSuccess.into(), Subservices::TmStartSuccess.into(),
seq_counter.get(),
&token.req_id, &token.req_id,
time_stamp, time_stamp,
None::<&dyn EcssEnumeration>, None::<&dyn EcssEnumeration>,
@ -401,7 +410,7 @@ impl VerificationReporterBasic {
sender sender
.send_tm(tm) .send_tm(tm)
.map_err(|e| VerificationErrorWithToken(e, token))?; .map_err(|e| VerificationErrorWithToken(e, token))?;
self.msg_count += 1; seq_counter.increment();
Ok(VerificationToken { Ok(VerificationToken {
state: PhantomData, state: PhantomData,
req_id: token.req_id, req_id: token.req_id,
@ -417,12 +426,14 @@ impl VerificationReporterBasic {
buf: &mut [u8], buf: &mut [u8],
token: VerificationToken<TcStateAccepted>, token: VerificationToken<TcStateAccepted>,
sender: &mut (impl EcssTmSender<Error = E> + ?Sized), sender: &mut (impl EcssTmSender<Error = E> + ?Sized),
seq_counter: &mut (impl SequenceCountProvider<u16> + ?Sized),
params: FailParams, params: FailParams,
) -> Result<(), VerificationErrorWithToken<E, TcStateAccepted>> { ) -> Result<(), VerificationErrorWithToken<E, TcStateAccepted>> {
let tm = self let tm = self
.create_pus_verif_fail_tm( .create_pus_verif_fail_tm(
buf, buf,
Subservices::TmStartFailure.into(), Subservices::TmStartFailure.into(),
seq_counter.get(),
&token.req_id, &token.req_id,
None::<&dyn EcssEnumeration>, None::<&dyn EcssEnumeration>,
&params, &params,
@ -431,7 +442,7 @@ impl VerificationReporterBasic {
sender sender
.send_tm(tm) .send_tm(tm)
.map_err(|e| VerificationErrorWithToken(e, token))?; .map_err(|e| VerificationErrorWithToken(e, token))?;
self.msg_count += 1; seq_counter.increment();
Ok(()) Ok(())
} }
@ -443,18 +454,20 @@ impl VerificationReporterBasic {
buf: &mut [u8], buf: &mut [u8],
token: &VerificationToken<TcStateStarted>, token: &VerificationToken<TcStateStarted>,
sender: &mut (impl EcssTmSender<Error = E> + ?Sized), sender: &mut (impl EcssTmSender<Error = E> + ?Sized),
seq_counter: &mut (impl SequenceCountProvider<u16> + ?Sized),
time_stamp: &[u8], time_stamp: &[u8],
step: impl EcssEnumeration, step: impl EcssEnumeration,
) -> Result<(), EcssTmError<E>> { ) -> Result<(), EcssTmError<E>> {
let tm = self.create_pus_verif_success_tm( let tm = self.create_pus_verif_success_tm(
buf, buf,
Subservices::TmStepSuccess.into(), Subservices::TmStepSuccess.into(),
seq_counter.get(),
&token.req_id, &token.req_id,
time_stamp, time_stamp,
Some(&step), Some(&step),
)?; )?;
sender.send_tm(tm)?; sender.send_tm(tm)?;
self.msg_count += 1; seq_counter.increment();
Ok(()) Ok(())
} }
@ -467,12 +480,14 @@ impl VerificationReporterBasic {
buf: &mut [u8], buf: &mut [u8],
token: VerificationToken<TcStateStarted>, token: VerificationToken<TcStateStarted>,
sender: &mut (impl EcssTmSender<Error = E> + ?Sized), sender: &mut (impl EcssTmSender<Error = E> + ?Sized),
seq_counter: &mut (impl SequenceCountProvider<u16> + ?Sized),
params: FailParamsWithStep, params: FailParamsWithStep,
) -> Result<(), VerificationErrorWithToken<E, TcStateStarted>> { ) -> Result<(), VerificationErrorWithToken<E, TcStateStarted>> {
let tm = self let tm = self
.create_pus_verif_fail_tm( .create_pus_verif_fail_tm(
buf, buf,
Subservices::TmStepFailure.into(), Subservices::TmStepFailure.into(),
seq_counter.get(),
&token.req_id, &token.req_id,
Some(params.step), Some(params.step),
&params.bp, &params.bp,
@ -481,7 +496,7 @@ impl VerificationReporterBasic {
sender sender
.send_tm(tm) .send_tm(tm)
.map_err(|e| VerificationErrorWithToken(e, token))?; .map_err(|e| VerificationErrorWithToken(e, token))?;
self.msg_count += 1; seq_counter.increment();
Ok(()) Ok(())
} }
@ -494,12 +509,14 @@ impl VerificationReporterBasic {
buf: &mut [u8], buf: &mut [u8],
token: VerificationToken<TcStateStarted>, token: VerificationToken<TcStateStarted>,
sender: &mut (impl EcssTmSender<Error = E> + ?Sized), sender: &mut (impl EcssTmSender<Error = E> + ?Sized),
seq_counter: &mut (impl SequenceCountProvider<u16> + ?Sized),
time_stamp: &[u8], time_stamp: &[u8],
) -> Result<(), VerificationErrorWithToken<E, TcStateStarted>> { ) -> Result<(), VerificationErrorWithToken<E, TcStateStarted>> {
let tm = self let tm = self
.create_pus_verif_success_tm( .create_pus_verif_success_tm(
buf, buf,
Subservices::TmCompletionSuccess.into(), Subservices::TmCompletionSuccess.into(),
seq_counter.get(),
&token.req_id, &token.req_id,
time_stamp, time_stamp,
None::<&dyn EcssEnumeration>, None::<&dyn EcssEnumeration>,
@ -508,7 +525,7 @@ impl VerificationReporterBasic {
sender sender
.send_tm(tm) .send_tm(tm)
.map_err(|e| VerificationErrorWithToken(e, token))?; .map_err(|e| VerificationErrorWithToken(e, token))?;
self.msg_count += 1; seq_counter.increment();
Ok(()) Ok(())
} }
@ -521,12 +538,14 @@ impl VerificationReporterBasic {
buf: &mut [u8], buf: &mut [u8],
token: VerificationToken<TcStateStarted>, token: VerificationToken<TcStateStarted>,
sender: &mut (impl EcssTmSender<Error = E> + ?Sized), sender: &mut (impl EcssTmSender<Error = E> + ?Sized),
seq_counter: &mut (impl SequenceCountProvider<u16> + ?Sized),
params: FailParams, params: FailParams,
) -> Result<(), VerificationErrorWithToken<E, TcStateStarted>> { ) -> Result<(), VerificationErrorWithToken<E, TcStateStarted>> {
let tm = self let tm = self
.create_pus_verif_fail_tm( .create_pus_verif_fail_tm(
buf, buf,
Subservices::TmCompletionFailure.into(), Subservices::TmCompletionFailure.into(),
seq_counter.get(),
&token.req_id, &token.req_id,
None::<&dyn EcssEnumeration>, None::<&dyn EcssEnumeration>,
&params, &params,
@ -535,7 +554,7 @@ impl VerificationReporterBasic {
sender sender
.send_tm(tm) .send_tm(tm)
.map_err(|e| VerificationErrorWithToken(e, token))?; .map_err(|e| VerificationErrorWithToken(e, token))?;
self.msg_count += 1; seq_counter.increment();
Ok(()) Ok(())
} }
@ -543,6 +562,7 @@ impl VerificationReporterBasic {
&'a mut self, &'a mut self,
buf: &'a mut [u8], buf: &'a mut [u8],
subservice: u8, subservice: u8,
msg_counter: u16,
req_id: &RequestId, req_id: &RequestId,
time_stamp: &'a [u8], time_stamp: &'a [u8],
step: Option<&(impl EcssEnumeration + ?Sized)>, step: Option<&(impl EcssEnumeration + ?Sized)>,
@ -564,6 +584,7 @@ impl VerificationReporterBasic {
Ok(self.create_pus_verif_tm_base( Ok(self.create_pus_verif_tm_base(
buf, buf,
subservice, subservice,
msg_counter,
&mut sp_header, &mut sp_header,
time_stamp, time_stamp,
source_data_len, source_data_len,
@ -574,6 +595,7 @@ impl VerificationReporterBasic {
&'a mut self, &'a mut self,
buf: &'a mut [u8], buf: &'a mut [u8],
subservice: u8, subservice: u8,
msg_counter: u16,
req_id: &RequestId, req_id: &RequestId,
step: Option<&(impl EcssEnumeration + ?Sized)>, step: Option<&(impl EcssEnumeration + ?Sized)>,
params: &'a FailParams, params: &'a FailParams,
@ -607,6 +629,7 @@ impl VerificationReporterBasic {
Ok(self.create_pus_verif_tm_base( Ok(self.create_pus_verif_tm_base(
buf, buf,
subservice, subservice,
msg_counter,
&mut sp_header, &mut sp_header,
params.time_stamp, params.time_stamp,
source_data_len, source_data_len,
@ -617,12 +640,13 @@ impl VerificationReporterBasic {
&'a mut self, &'a mut self,
buf: &'a mut [u8], buf: &'a mut [u8],
subservice: u8, subservice: u8,
msg_counter: u16,
sp_header: &mut SpHeader, sp_header: &mut SpHeader,
time_stamp: &'a [u8], time_stamp: &'a [u8],
source_data_len: usize, source_data_len: usize,
) -> PusTm { ) -> PusTm {
let tm_sec_header = let tm_sec_header =
PusTmSecondaryHeader::new(1, subservice, self.msg_count, self.dest_id, time_stamp); PusTmSecondaryHeader::new(1, subservice, msg_counter, self.dest_id, time_stamp);
PusTm::new( PusTm::new(
sp_header, sp_header,
tm_sec_header, tm_sec_header,
@ -639,8 +663,10 @@ mod allocmod {
use alloc::vec; use alloc::vec;
use alloc::vec::Vec; use alloc::vec::Vec;
#[derive(Clone)]
pub struct VerificationReporterCfg { pub struct VerificationReporterCfg {
apid: u16, apid: u16,
seq_counter: Box<dyn SequenceCountProvider<u16> + Send>,
pub step_field_width: usize, pub step_field_width: usize,
pub fail_code_field_width: usize, pub fail_code_field_width: usize,
pub max_fail_data_len: usize, pub max_fail_data_len: usize,
@ -649,6 +675,7 @@ mod allocmod {
impl VerificationReporterCfg { impl VerificationReporterCfg {
pub fn new( pub fn new(
apid: u16, apid: u16,
seq_counter: Box<dyn SequenceCountProvider<u16> + Send>,
step_field_width: usize, step_field_width: usize,
fail_code_field_width: usize, fail_code_field_width: usize,
max_fail_data_len: usize, max_fail_data_len: usize,
@ -658,6 +685,7 @@ mod allocmod {
} }
Some(Self { Some(Self {
apid, apid,
seq_counter,
step_field_width, step_field_width,
fail_code_field_width, fail_code_field_width,
max_fail_data_len, max_fail_data_len,
@ -667,13 +695,15 @@ mod allocmod {
/// Primary verification handler. It provides an API to send PUS 1 verification telemetry packets /// Primary verification handler. It provides an API to send PUS 1 verification telemetry packets
/// and verify the various steps of telecommand handling as specified in the PUS standard. /// and verify the various steps of telecommand handling as specified in the PUS standard.
pub struct VerificationReporter { #[derive(Clone)]
pub struct VerificationReporterWithBuf {
source_data_buf: Vec<u8>, source_data_buf: Vec<u8>,
seq_counter: Box<dyn SequenceCountProvider<u16> + Send + 'static>,
pub reporter: VerificationReporterBasic, pub reporter: VerificationReporterBasic,
} }
impl VerificationReporter { impl VerificationReporterWithBuf {
pub fn new(cfg: VerificationReporterCfg) -> Self { pub fn new(cfg: &VerificationReporterCfg) -> Self {
let reporter = VerificationReporterBasic::new(cfg.apid).unwrap(); let reporter = VerificationReporterBasic::new(cfg.apid).unwrap();
Self { Self {
source_data_buf: vec![ source_data_buf: vec![
@ -683,6 +713,7 @@ mod allocmod {
+ cfg.fail_code_field_width as usize + cfg.fail_code_field_width as usize
+ cfg.max_fail_data_len + cfg.max_fail_data_len
], ],
seq_counter: cfg.seq_counter.clone(),
reporter, reporter,
} }
} }
@ -714,6 +745,7 @@ mod allocmod {
self.source_data_buf.as_mut_slice(), self.source_data_buf.as_mut_slice(),
token, token,
sender, sender,
self.seq_counter.as_mut(),
time_stamp, time_stamp,
) )
} }
@ -729,6 +761,7 @@ mod allocmod {
self.source_data_buf.as_mut_slice(), self.source_data_buf.as_mut_slice(),
token, token,
sender, sender,
self.seq_counter.as_mut(),
params, params,
) )
} }
@ -747,6 +780,7 @@ mod allocmod {
self.source_data_buf.as_mut_slice(), self.source_data_buf.as_mut_slice(),
token, token,
sender, sender,
self.seq_counter.as_mut(),
time_stamp, time_stamp,
) )
} }
@ -761,8 +795,13 @@ mod allocmod {
sender: &mut (impl EcssTmSender<Error = E> + ?Sized), sender: &mut (impl EcssTmSender<Error = E> + ?Sized),
params: FailParams, params: FailParams,
) -> Result<(), VerificationErrorWithToken<E, TcStateAccepted>> { ) -> Result<(), VerificationErrorWithToken<E, TcStateAccepted>> {
self.reporter self.reporter.start_failure(
.start_failure(self.source_data_buf.as_mut_slice(), token, sender, params) self.source_data_buf.as_mut_slice(),
token,
sender,
self.seq_counter.as_mut(),
params,
)
} }
/// Package and send a PUS TM\[1, 5\] packet, see 8.1.2.5 of the PUS standard. /// Package and send a PUS TM\[1, 5\] packet, see 8.1.2.5 of the PUS standard.
@ -779,6 +818,7 @@ mod allocmod {
self.source_data_buf.as_mut_slice(), self.source_data_buf.as_mut_slice(),
token, token,
sender, sender,
self.seq_counter.as_mut(),
time_stamp, time_stamp,
step, step,
) )
@ -794,8 +834,13 @@ mod allocmod {
sender: &mut (impl EcssTmSender<Error = E> + ?Sized), sender: &mut (impl EcssTmSender<Error = E> + ?Sized),
params: FailParamsWithStep, params: FailParamsWithStep,
) -> Result<(), VerificationErrorWithToken<E, TcStateStarted>> { ) -> Result<(), VerificationErrorWithToken<E, TcStateStarted>> {
self.reporter self.reporter.step_failure(
.step_failure(self.source_data_buf.as_mut_slice(), token, sender, params) self.source_data_buf.as_mut_slice(),
token,
sender,
self.seq_counter.as_mut(),
params,
)
} }
/// Package and send a PUS TM\[1, 7\] packet, see 8.1.2.7 of the PUS standard. /// Package and send a PUS TM\[1, 7\] packet, see 8.1.2.7 of the PUS standard.
@ -812,6 +857,7 @@ mod allocmod {
self.source_data_buf.as_mut_slice(), self.source_data_buf.as_mut_slice(),
token, token,
sender, sender,
self.seq_counter.as_mut(),
time_stamp, time_stamp,
) )
} }
@ -830,6 +876,7 @@ mod allocmod {
self.source_data_buf.as_mut_slice(), self.source_data_buf.as_mut_slice(),
token, token,
sender, sender,
self.seq_counter.as_mut(),
params, params,
) )
} }
@ -837,19 +884,23 @@ mod allocmod {
/// Helper object which caches the sender passed as a trait object. Provides the same /// Helper object which caches the sender passed as a trait object. Provides the same
/// API as [VerificationReporter] but without the explicit sender arguments. /// API as [VerificationReporter] but without the explicit sender arguments.
#[derive(Clone)]
pub struct VerificationReporterWithSender<E> { pub struct VerificationReporterWithSender<E> {
pub reporter: VerificationReporter, pub reporter: VerificationReporterWithBuf,
pub sender: Box<dyn EcssTmSender<Error = E>>, pub sender: Box<dyn EcssTmSender<Error = E>>,
} }
impl<E: 'static> VerificationReporterWithSender<E> { impl<E: 'static> VerificationReporterWithSender<E> {
pub fn new(cfg: VerificationReporterCfg, sender: Box<dyn EcssTmSender<Error = E>>) -> Self { pub fn new(
let reporter = VerificationReporter::new(cfg); cfg: &VerificationReporterCfg,
sender: Box<dyn EcssTmSender<Error = E>>,
) -> Self {
let reporter = VerificationReporterWithBuf::new(cfg);
Self::new_from_reporter(reporter, sender) Self::new_from_reporter(reporter, sender)
} }
pub fn new_from_reporter( pub fn new_from_reporter(
reporter: VerificationReporter, reporter: VerificationReporterWithBuf,
sender: Box<dyn EcssTmSender<Error = E>>, sender: Box<dyn EcssTmSender<Error = E>>,
) -> Self { ) -> Self {
Self { reporter, sender } Self { reporter, sender }
@ -955,7 +1006,7 @@ mod stdmod {
pub type StdVerifReporterWithSender = VerificationReporterWithSender<StdVerifSenderError>; pub type StdVerifReporterWithSender = VerificationReporterWithSender<StdVerifSenderError>;
pub type SharedStdVerifReporterWithSender = Arc<Mutex<StdVerifReporterWithSender>>; pub type SharedStdVerifReporterWithSender = Arc<Mutex<StdVerifReporterWithSender>>;
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq, Clone)]
pub enum StdVerifSenderError { pub enum StdVerifSenderError {
PoisonError, PoisonError,
StoreError(StoreError), StoreError(StoreError),
@ -978,6 +1029,7 @@ mod stdmod {
fn send(&self, addr: StoreAddr) -> Result<(), StoreAddr>; fn send(&self, addr: StoreAddr) -> Result<(), StoreAddr>;
} }
#[derive(Clone)]
struct StdSenderBase<S> { struct StdSenderBase<S> {
pub ignore_poison_error: bool, pub ignore_poison_error: bool,
tm_store: SharedPool, tm_store: SharedPool,
@ -1003,6 +1055,7 @@ mod stdmod {
} }
} }
#[derive(Clone)]
pub struct MpscVerifSender { pub struct MpscVerifSender {
base: StdSenderBase<mpsc::Sender<StoreAddr>>, base: StdSenderBase<mpsc::Sender<StoreAddr>>,
} }
@ -1038,6 +1091,7 @@ mod stdmod {
/// Verification sender with a [crossbeam_channel::Sender] backend. /// Verification sender with a [crossbeam_channel::Sender] backend.
/// It implements the [EcssTmSender] trait to be used as PUS Verification TM sender /// It implements the [EcssTmSender] trait to be used as PUS Verification TM sender
#[derive(Clone)]
pub struct CrossbeamVerifSender { pub struct CrossbeamVerifSender {
base: StdSenderBase<crossbeam_channel::Sender<StoreAddr>>, base: StdSenderBase<crossbeam_channel::Sender<StoreAddr>>,
} }
@ -1064,7 +1118,7 @@ mod stdmod {
unsafe impl Sync for CrossbeamVerifSender {} unsafe impl Sync for CrossbeamVerifSender {}
unsafe impl Send for CrossbeamVerifSender {} unsafe impl Send for CrossbeamVerifSender {}
impl<S: SendBackend + 'static> EcssTmSender for StdSenderBase<S> { impl<S: SendBackend + Clone + 'static> EcssTmSender for StdSenderBase<S> {
type Error = StdVerifSenderError; type Error = StdVerifSenderError;
fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<Self::Error>> { fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<Self::Error>> {
let operation = |mut mg: RwLockWriteGuard<ShareablePoolProvider>| { let operation = |mut mg: RwLockWriteGuard<ShareablePoolProvider>| {
@ -1095,9 +1149,10 @@ mod tests {
use crate::pus::tests::CommonTmInfo; use crate::pus::tests::CommonTmInfo;
use crate::pus::verification::{ use crate::pus::verification::{
EcssTmError, EcssTmSender, FailParams, FailParamsWithStep, RequestId, TcStateNone, EcssTmError, EcssTmSender, FailParams, FailParamsWithStep, RequestId, TcStateNone,
VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender, VerificationReporterCfg, VerificationReporterWithBuf, VerificationReporterWithSender,
VerificationToken, VerificationToken,
}; };
use crate::seq_count::SimpleSeqCountProvider;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::format; use alloc::format;
use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU8, EcssEnumeration, PusPacket}; use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU8, EcssEnumeration, PusPacket};
@ -1110,14 +1165,14 @@ mod tests {
const TEST_APID: u16 = 0x02; const TEST_APID: u16 = 0x02;
const EMPTY_STAMP: [u8; 7] = [0; 7]; const EMPTY_STAMP: [u8; 7] = [0; 7];
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq, Clone)]
struct TmInfo { struct TmInfo {
pub common: CommonTmInfo, pub common: CommonTmInfo,
pub req_id: RequestId, pub req_id: RequestId,
pub additional_data: Option<Vec<u8>>, pub additional_data: Option<Vec<u8>>,
} }
#[derive(Default)] #[derive(Default, Clone)]
struct TestSender { struct TestSender {
pub service_queue: VecDeque<TmInfo>, pub service_queue: VecDeque<TmInfo>,
} }
@ -1149,7 +1204,7 @@ mod tests {
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
struct DummyError {} struct DummyError {}
#[derive(Default)] #[derive(Default, Clone)]
struct FallibleSender {} struct FallibleSender {}
impl EcssTmSender for FallibleSender { impl EcssTmSender for FallibleSender {
@ -1160,13 +1215,13 @@ mod tests {
} }
struct TestBase<'a> { struct TestBase<'a> {
vr: VerificationReporter, vr: VerificationReporterWithBuf,
#[allow(dead_code)] #[allow(dead_code)]
tc: PusTc<'a>, tc: PusTc<'a>,
} }
impl<'a> TestBase<'a> { impl<'a> TestBase<'a> {
fn rep(&mut self) -> &mut VerificationReporter { fn rep(&mut self) -> &mut VerificationReporterWithBuf {
&mut self.vr &mut self.vr
} }
} }
@ -1177,14 +1232,21 @@ mod tests {
} }
impl<'a, E> TestBaseWithHelper<'a, E> { impl<'a, E> TestBaseWithHelper<'a, E> {
fn rep(&mut self) -> &mut VerificationReporter { fn rep(&mut self) -> &mut VerificationReporterWithBuf {
&mut self.helper.reporter &mut self.helper.reporter
} }
} }
fn base_reporter() -> VerificationReporter { fn base_reporter() -> VerificationReporterWithBuf {
let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap(); let cfg = VerificationReporterCfg::new(
VerificationReporter::new(cfg) TEST_APID,
Box::new(SimpleSeqCountProvider::default()),
1,
2,
8,
)
.unwrap();
VerificationReporterWithBuf::new(&cfg)
} }
fn base_tc_init(app_data: Option<&[u8]>) -> (PusTc, RequestId) { fn base_tc_init(app_data: Option<&[u8]>) -> (PusTc, RequestId) {

View File

@ -0,0 +1,60 @@
use dyn_clone::DynClone;
#[cfg(feature = "std")]
pub use stdmod::*;
pub trait SequenceCountProvider<Raw>: DynClone {
fn get(&self) -> Raw;
fn increment(&mut self);
fn get_and_increment(&mut self) -> Raw {
let val = self.get();
self.increment();
val
}
}
#[derive(Default, Clone)]
pub struct SimpleSeqCountProvider {
seq_count: u16,
}
dyn_clone::clone_trait_object!(SequenceCountProvider<u16>);
impl SequenceCountProvider<u16> for SimpleSeqCountProvider {
fn get(&self) -> u16 {
self.seq_count
}
fn increment(&mut self) {
if self.seq_count == u16::MAX {
self.seq_count = 0;
return;
}
self.seq_count += 1;
}
}
#[cfg(feature = "std")]
pub mod stdmod {
use super::*;
use std::sync::atomic::{AtomicU16, Ordering};
use std::sync::Arc;
#[derive(Clone, Default)]
pub struct SyncSeqCountProvider {
seq_count: Arc<AtomicU16>,
}
impl SequenceCountProvider<u16> for SyncSeqCountProvider {
fn get(&self) -> u16 {
self.seq_count.load(Ordering::SeqCst)
}
fn increment(&mut self) {
self.seq_count.fetch_add(1, Ordering::SeqCst);
}
fn get_and_increment(&mut self) -> u16 {
self.seq_count.fetch_add(1, Ordering::SeqCst)
}
}
}

View File

@ -4,7 +4,9 @@ use satrs_core::event_man::{
use satrs_core::events::{EventU32, EventU32TypedSev, Severity, SeverityInfo}; use satrs_core::events::{EventU32, EventU32TypedSev, Severity, SeverityInfo};
use satrs_core::params::U32Pair; use satrs_core::params::U32Pair;
use satrs_core::params::{Params, ParamsHeapless, WritableToBeBytes}; use satrs_core::params::{Params, ParamsHeapless, WritableToBeBytes};
use satrs_core::pus::event_man::{DefaultPusMgmtBackendProvider, EventReporter, PusEventDispatcher}; use satrs_core::pus::event_man::{
DefaultPusMgmtBackendProvider, EventReporter, PusEventDispatcher,
};
use satrs_core::pus::{EcssTmError, EcssTmSender}; use satrs_core::pus::{EcssTmError, EcssTmSender};
use spacepackets::ecss::PusPacket; use spacepackets::ecss::PusPacket;
use spacepackets::tm::PusTm; use spacepackets::tm::PusTm;
@ -16,6 +18,7 @@ const INFO_EVENT: EventU32TypedSev<SeverityInfo> =
const LOW_SEV_EVENT: EventU32 = EventU32::const_new(Severity::LOW, 1, 5); const LOW_SEV_EVENT: EventU32 = EventU32::const_new(Severity::LOW, 1, 5);
const EMPTY_STAMP: [u8; 7] = [0; 7]; const EMPTY_STAMP: [u8; 7] = [0; 7];
#[derive(Clone)]
struct EventTmSender { struct EventTmSender {
sender: std::sync::mpsc::Sender<Vec<u8>>, sender: std::sync::mpsc::Sender<Vec<u8>>,
} }

View File

@ -1,14 +1,15 @@
use hashbrown::HashMap;
use satrs_core::pool::{LocalPool, PoolCfg, PoolProvider, SharedPool}; use satrs_core::pool::{LocalPool, PoolCfg, PoolProvider, SharedPool};
use satrs_core::pus::verification::{ use satrs_core::pus::verification::{
CrossbeamVerifSender, FailParams, RequestId, VerificationReporterCfg, CrossbeamVerifSender, FailParams, RequestId, VerificationReporterCfg,
VerificationReporterWithSender, VerificationReporterWithSender,
}; };
use hashbrown::HashMap; use satrs_core::seq_count::SyncSeqCountProvider;
use spacepackets::ecss::{EcssEnumU16, EcssEnumU8, PusPacket}; use spacepackets::ecss::{EcssEnumU16, EcssEnumU8, PusPacket};
use spacepackets::tc::{PusTc, PusTcSecondaryHeader}; use spacepackets::tc::{PusTc, PusTcSecondaryHeader};
use spacepackets::tm::PusTm; use spacepackets::tm::PusTm;
use spacepackets::SpHeader; use spacepackets::SpHeader;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, RwLock};
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
@ -25,7 +26,17 @@ const PACKETS_SENT: u8 = 8;
/// threads have sent the correct expected verification reports /// threads have sent the correct expected verification reports
#[test] #[test]
fn test_shared_reporter() { fn test_shared_reporter() {
let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap(); // We use a synced sequence count provider here because both verification reporters have the
// the same APID. If they had distinct APIDs, the more correct approach would be to have
// each reporter have an own sequence count provider.
let cfg = VerificationReporterCfg::new(
TEST_APID,
Box::new(SyncSeqCountProvider::default()),
1,
2,
8,
)
.unwrap();
// Shared pool object to store the verification PUS telemetry // Shared pool object to store the verification PUS telemetry
let pool_cfg = PoolCfg::new(vec![(10, 32), (10, 64), (10, 128), (10, 1024)]); let pool_cfg = PoolCfg::new(vec![(10, 32), (10, 64), (10, 128), (10, 1024)]);
let shared_tm_pool: SharedPool = let shared_tm_pool: SharedPool =
@ -34,11 +45,8 @@ fn test_shared_reporter() {
let shared_tc_pool_1 = shared_tc_pool_0.clone(); let shared_tc_pool_1 = shared_tc_pool_0.clone();
let (tx, rx) = crossbeam_channel::bounded(5); let (tx, rx) = crossbeam_channel::bounded(5);
let sender = CrossbeamVerifSender::new(shared_tm_pool.clone(), tx.clone()); let sender = CrossbeamVerifSender::new(shared_tm_pool.clone(), tx.clone());
let reporter_with_sender_0 = Arc::new(Mutex::new(VerificationReporterWithSender::new( let mut reporter_with_sender_0 = VerificationReporterWithSender::new(&cfg, Box::new(sender));
cfg, let mut reporter_with_sender_1 = reporter_with_sender_0.clone();
Box::new(sender),
)));
let reporter_with_sender_1 = reporter_with_sender_0.clone();
// For test purposes, we retrieve the request ID from the TCs and pass them to the receiver // For test purposes, we retrieve the request ID from the TCs and pass them to the receiver
// tread. // tread.
let req_id_0; let req_id_0;
@ -78,29 +86,28 @@ fn test_shared_reporter() {
} }
let (_tc, _) = PusTc::from_bytes(&tc_buf[0..tc_len]).unwrap(); let (_tc, _) = PusTc::from_bytes(&tc_buf[0..tc_len]).unwrap();
let accepted_token; let accepted_token;
{
let mut mg = reporter_with_sender_0.lock().expect("Locking mutex failed"); let token = reporter_with_sender_0.add_tc_with_req_id(req_id_0);
let token = mg.add_tc_with_req_id(req_id_0); accepted_token = reporter_with_sender_0
accepted_token = mg
.acceptance_success(token, &FIXED_STAMP) .acceptance_success(token, &FIXED_STAMP)
.expect("Acceptance success failed"); .expect("Acceptance success failed");
}
// Do some start handling here // Do some start handling here
let started_token; let started_token;
{ started_token = reporter_with_sender_0
let mut mg = reporter_with_sender_0.lock().expect("Locking mutex failed");
started_token = mg
.start_success(accepted_token, &FIXED_STAMP) .start_success(accepted_token, &FIXED_STAMP)
.expect("Start success failed"); .expect("Start success failed");
// Do some step handling here // Do some step handling here
mg.step_success(&started_token, &FIXED_STAMP, EcssEnumU8::new(0)) reporter_with_sender_0
.step_success(&started_token, &FIXED_STAMP, EcssEnumU8::new(0))
.expect("Start success failed"); .expect("Start success failed");
}
// Finish up // Finish up
let mut mg = reporter_with_sender_0.lock().expect("Locking mutex failed"); reporter_with_sender_0
mg.step_success(&started_token, &FIXED_STAMP, EcssEnumU8::new(1)) .step_success(&started_token, &FIXED_STAMP, EcssEnumU8::new(1))
.expect("Start success failed"); .expect("Start success failed");
mg.completion_success(started_token, &FIXED_STAMP) reporter_with_sender_0
.completion_success(started_token, &FIXED_STAMP)
.expect("Completion success failed"); .expect("Completion success failed");
}); });
@ -118,19 +125,17 @@ fn test_shared_reporter() {
tc_buf[0..tc_len].copy_from_slice(buf); tc_buf[0..tc_len].copy_from_slice(buf);
} }
let (tc, _) = PusTc::from_bytes(&tc_buf[0..tc_len]).unwrap(); let (tc, _) = PusTc::from_bytes(&tc_buf[0..tc_len]).unwrap();
let mut mg = reporter_with_sender_1 let token = reporter_with_sender_1.add_tc(&tc);
.lock() let accepted_token = reporter_with_sender_1
.expect("Locking reporter failed");
let token = mg.add_tc(&tc);
let accepted_token = mg
.acceptance_success(token, &FIXED_STAMP) .acceptance_success(token, &FIXED_STAMP)
.expect("Acceptance success failed"); .expect("Acceptance success failed");
let started_token = mg let started_token = reporter_with_sender_1
.start_success(accepted_token, &FIXED_STAMP) .start_success(accepted_token, &FIXED_STAMP)
.expect("Start success failed"); .expect("Start success failed");
let fail_code = EcssEnumU16::new(2); let fail_code = EcssEnumU16::new(2);
let params = FailParams::new(&FIXED_STAMP, &fail_code, None); let params = FailParams::new(&FIXED_STAMP, &fail_code, None);
mg.completion_failure(started_token, params) reporter_with_sender_1
.completion_failure(started_token, params)
.expect("Completion success failed"); .expect("Completion success failed");
}); });

View File

@ -1,5 +1,7 @@
#![allow(dead_code)] #![allow(dead_code)]
use crossbeam_channel::{bounded, Receiver, Sender}; use crossbeam_channel::{bounded, Receiver, Sender};
use std::sync::atomic::{AtomicU16, Ordering};
use std::thread; use std::thread;
use zerocopy::{AsBytes, FromBytes, NetworkEndian, Unaligned, U16}; use zerocopy::{AsBytes, FromBytes, NetworkEndian, Unaligned, U16};
@ -52,4 +54,13 @@ fn main() {
let jh1 = thread::spawn(|| {}); let jh1 = thread::spawn(|| {});
jh0.join().unwrap(); jh0.join().unwrap();
jh1.join().unwrap(); jh1.join().unwrap();
//let mut max_val: u16 = u16::MAX;
//max_val += 1;
//println!("Max val: {}", max_val);
let atomic_u16: AtomicU16 = AtomicU16::new(u16::MAX);
atomic_u16.fetch_add(1, Ordering::SeqCst);
println!(
"atomic after overflow: {}",
atomic_u16.load(Ordering::SeqCst)
);
} }

View File

@ -17,6 +17,7 @@ use satrs_core::pus::verification::{
MpscVerifSender, VerificationReporterCfg, VerificationReporterWithSender, MpscVerifSender, VerificationReporterCfg, VerificationReporterWithSender,
}; };
use satrs_core::pus::{EcssTmError, EcssTmSender}; use satrs_core::pus::{EcssTmError, EcssTmSender};
use satrs_core::seq_count::SimpleSeqCountProvider;
use satrs_core::tmtc::CcsdsError; use satrs_core::tmtc::CcsdsError;
use satrs_example::{OBSW_SERVER_ADDR, SERVER_PORT}; use satrs_example::{OBSW_SERVER_ADDR, SERVER_PORT};
use spacepackets::time::{CdsShortTimeProvider, TimeWriter}; use spacepackets::time::{CdsShortTimeProvider, TimeWriter};
@ -39,6 +40,7 @@ struct UdpTmtcServer {
unsafe impl Send for UdpTmtcServer {} unsafe impl Send for UdpTmtcServer {}
#[derive(Clone)]
struct EventTmSender { struct EventTmSender {
store_helper: TmStore, store_helper: TmStore,
sender: mpsc::Sender<StoreAddr>, sender: mpsc::Sender<StoreAddr>,
@ -73,9 +75,16 @@ fn main() {
let (tm_funnel_tx, tm_funnel_rx) = channel(); let (tm_funnel_tx, tm_funnel_rx) = channel();
let (tm_server_tx, tm_server_rx) = channel(); let (tm_server_tx, tm_server_rx) = channel();
let sender = MpscVerifSender::new(tm_store.clone(), tm_funnel_tx.clone()); let sender = MpscVerifSender::new(tm_store.clone(), tm_funnel_tx.clone());
let verif_cfg = VerificationReporterCfg::new(PUS_APID, 1, 2, 8).unwrap(); let verif_cfg = VerificationReporterCfg::new(
PUS_APID,
Box::new(SimpleSeqCountProvider::default()),
1,
2,
8,
)
.unwrap();
let reporter_with_sender_0 = Arc::new(Mutex::new(VerificationReporterWithSender::new( let reporter_with_sender_0 = Arc::new(Mutex::new(VerificationReporterWithSender::new(
verif_cfg, &verif_cfg,
Box::new(sender), Box::new(sender),
))); )));