allow hooking into verification TM generation
Some checks failed
Rust/sat-rs/pipeline/pr-main There was a failure building this commit

This commit is contained in:
Robin Müller 2024-04-02 17:45:12 +02:00
parent 9c5327aa16
commit 4ef7caefd8

View File

@ -397,6 +397,12 @@ impl<'stamp, 'fargs> FailParamsWithStep<'stamp, 'fargs> {
} }
} }
/// This is a generic trait implemented by an object which can perform the ECSS PUS 1 verification
/// process according to PUS standard ECSS-E-ST-70-41C.
///
/// This trait allows using different message queue backends for the verification reporting process
/// or to swap the actual reporter with a test reporter for unit tests.
/// For general purposes, the [VerificationReporter] should be sufficient.
pub trait VerificationReportingProvider { pub trait VerificationReportingProvider {
fn set_apid(&mut self, apid: Apid); fn set_apid(&mut self, apid: Apid);
fn apid(&self) -> Apid; fn apid(&self) -> Apid;
@ -476,8 +482,8 @@ pub trait VerificationReportingProvider {
) -> Result<(), EcssTmtcError>; ) -> Result<(), EcssTmtcError>;
} }
/// Primary verification handler. It provides an API to generate PUS 1 verification telemetry /// Low level object which generates ECSS PUS 1 verification packets to verify the various steps
/// packets and verify the various steps of telecommand handling as specified in the PUS standard. /// of telecommand handling as specified in the PUS standard.
/// ///
/// This is the core component which can be used without [`alloc`] support. Please note that /// This is the core component which can be used without [`alloc`] support. Please note that
/// the buffer passed to the API exposes by this struct will be used to serialize the source data. /// the buffer passed to the API exposes by this struct will be used to serialize the source data.
@ -909,19 +915,36 @@ pub mod alloc_mod {
} }
} }
/// Primary verification handler. It provides an API to send PUS 1 verification telemetry packets pub trait VerificationHookProvider {
/// and verify the various steps of telecommand handling as specified in the PUS standard. fn modify_tm(&self, tm: &mut PusTmCreator);
}
#[derive(Default)]
pub struct DummyVerificationHook {}
impl VerificationHookProvider for DummyVerificationHook {
fn modify_tm(&self, _tm: &mut PusTmCreator) {}
}
/// Primary verification reportewr object. 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.
///
/// It is assumed that the sequence counter and message counters are updated in a central /// It is assumed that the sequence counter and message counters are updated in a central
/// TM funnel. This helper will always set those fields to 0. /// TM funnel or TM inlet. This helper will always set those fields to 0. The APID and
/// destination fields are assumed to be constant for a given repoter instance.
#[derive(Clone)] #[derive(Clone)]
pub struct VerificationReporter { pub struct VerificationReporter<
VerificationHook: VerificationHookProvider = DummyVerificationHook,
> {
// TODO: We could add a hook object which allows users to manipulate the verification // TODO: We could add a hook object which allows users to manipulate the verification
// report TM before it is sent.. // report TM before it is sent..
source_data_buf: RefCell<alloc::vec::Vec<u8>>, source_data_buf: RefCell<alloc::vec::Vec<u8>>,
pub reporter_creator: VerificationReportCreator, pub reporter_creator: VerificationReportCreator,
pub tm_hook: VerificationHook,
} }
impl VerificationReporter { impl VerificationReporter<DummyVerificationHook> {
pub fn new(cfg: &VerificationReporterCfg) -> Self { pub fn new(cfg: &VerificationReporterCfg) -> Self {
let reporter = VerificationReportCreator::new(cfg.apid).unwrap(); let reporter = VerificationReportCreator::new(cfg.apid).unwrap();
Self { Self {
@ -932,9 +955,25 @@ pub mod alloc_mod {
+ cfg.fail_code_field_width + cfg.fail_code_field_width
+ cfg.max_fail_data_len + cfg.max_fail_data_len
]), ]),
// seq_count_provider: None,
// msg_count_provider: None,
reporter_creator: reporter, reporter_creator: reporter,
tm_hook: DummyVerificationHook::default(),
}
}
}
impl<VerificationHook: VerificationHookProvider> VerificationReporter<VerificationHook> {
pub fn new_with_hook(cfg: &VerificationReporterCfg, tm_hook: VerificationHook) -> Self {
let reporter = VerificationReportCreator::new(cfg.apid).unwrap();
Self {
source_data_buf: RefCell::new(alloc::vec![
0;
RequestId::SIZE_AS_BYTES
+ cfg.step_field_width
+ cfg.fail_code_field_width
+ cfg.max_fail_data_len
]),
reporter_creator: reporter,
tm_hook,
} }
} }
@ -973,10 +1012,11 @@ pub mod alloc_mod {
time_stamp: &[u8], time_stamp: &[u8],
) -> Result<VerificationToken<TcStateAccepted>, EcssTmtcError> { ) -> Result<VerificationToken<TcStateAccepted>, EcssTmtcError> {
let mut source_data_buf = self.source_data_buf.borrow_mut(); let mut source_data_buf = self.source_data_buf.borrow_mut();
let (tm_creator, token) = self let (mut tm_creator, token) = self
.reporter_creator .reporter_creator
.acceptance_success(source_data_buf.as_mut_slice(), token, 0, 0, time_stamp) .acceptance_success(source_data_buf.as_mut_slice(), token, 0, 0, time_stamp)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(sender_id, PusTmVariant::Direct(tm_creator))?; sender.send_tm(sender_id, PusTmVariant::Direct(tm_creator))?;
Ok(token) Ok(token)
} }
@ -990,11 +1030,12 @@ pub mod alloc_mod {
params: FailParams, params: FailParams,
) -> Result<(), EcssTmtcError> { ) -> Result<(), EcssTmtcError> {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let sendable = self let mut tm_creator = self
.reporter_creator .reporter_creator
.acceptance_failure(buf.as_mut_slice(), token, 0, 0, params) .acceptance_failure(buf.as_mut_slice(), token, 0, 0, params)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
sender.send_tm(sender_id, PusTmVariant::Direct(sendable))?; self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(sender_id, PusTmVariant::Direct(tm_creator))?;
Ok(()) Ok(())
} }
@ -1009,10 +1050,11 @@ pub mod alloc_mod {
time_stamp: &[u8], time_stamp: &[u8],
) -> Result<VerificationToken<TcStateStarted>, EcssTmtcError> { ) -> Result<VerificationToken<TcStateStarted>, EcssTmtcError> {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let (tm_creator, started_token) = self let (mut tm_creator, started_token) = self
.reporter_creator .reporter_creator
.start_success(buf.as_mut_slice(), token, 0, 0, time_stamp) .start_success(buf.as_mut_slice(), token, 0, 0, time_stamp)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(sender_id, PusTmVariant::Direct(tm_creator))?; sender.send_tm(sender_id, PusTmVariant::Direct(tm_creator))?;
Ok(started_token) Ok(started_token)
} }
@ -1029,11 +1071,12 @@ pub mod alloc_mod {
params: FailParams, params: FailParams,
) -> Result<(), EcssTmtcError> { ) -> Result<(), EcssTmtcError> {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let sendable = self let mut tm_creator = self
.reporter_creator .reporter_creator
.start_failure(buf.as_mut_slice(), token, 0, 0, params) .start_failure(buf.as_mut_slice(), token, 0, 0, params)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
sender.send_tm(sender_id, PusTmVariant::Direct(sendable))?; self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(sender_id, PusTmVariant::Direct(tm_creator))?;
Ok(()) Ok(())
} }
@ -1049,11 +1092,12 @@ pub mod alloc_mod {
step: impl EcssEnumeration, step: impl EcssEnumeration,
) -> Result<(), EcssTmtcError> { ) -> Result<(), EcssTmtcError> {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let sendable = self let mut tm_creator = self
.reporter_creator .reporter_creator
.step_success(buf.as_mut_slice(), token, 0, 0, time_stamp, step) .step_success(buf.as_mut_slice(), token, 0, 0, time_stamp, step)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
sender.send_tm(sender_id, PusTmVariant::Direct(sendable))?; self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(sender_id, PusTmVariant::Direct(tm_creator))?;
Ok(()) Ok(())
} }
@ -1069,11 +1113,12 @@ pub mod alloc_mod {
params: FailParamsWithStep, params: FailParamsWithStep,
) -> Result<(), EcssTmtcError> { ) -> Result<(), EcssTmtcError> {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let sendable = self let mut tm_creator = self
.reporter_creator .reporter_creator
.step_failure(buf.as_mut_slice(), token, 0, 0, params) .step_failure(buf.as_mut_slice(), token, 0, 0, params)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
sender.send_tm(sender_id, PusTmVariant::Direct(sendable))?; self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(sender_id, PusTmVariant::Direct(tm_creator))?;
Ok(()) Ok(())
} }
@ -1089,11 +1134,12 @@ pub mod alloc_mod {
time_stamp: &[u8], time_stamp: &[u8],
) -> Result<(), EcssTmtcError> { ) -> Result<(), EcssTmtcError> {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let sendable = self let mut tm_creator = self
.reporter_creator .reporter_creator
.completion_success(buf.as_mut_slice(), token, 0, 0, time_stamp) .completion_success(buf.as_mut_slice(), token, 0, 0, time_stamp)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
sender.send_tm(sender_id, PusTmVariant::Direct(sendable))?; self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(sender_id, PusTmVariant::Direct(tm_creator))?;
Ok(()) Ok(())
} }
@ -1109,11 +1155,12 @@ pub mod alloc_mod {
params: FailParams, params: FailParams,
) -> Result<(), EcssTmtcError> { ) -> Result<(), EcssTmtcError> {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let sendable = self let mut tm_creator = self
.reporter_creator .reporter_creator
.completion_failure(buf.as_mut_slice(), token, 0, 00, params) .completion_failure(buf.as_mut_slice(), token, 0, 00, params)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
sender.send_tm(sender_id, PusTmVariant::Direct(sendable))?; self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(sender_id, PusTmVariant::Direct(tm_creator))?;
Ok(()) Ok(())
} }
} }