PUS Event Generation #17
@ -41,7 +41,7 @@ use std::vec::Vec;
|
|||||||
/// let mut sph = SpHeader::tc(0x02, 0, 0).unwrap();
|
/// let mut sph = SpHeader::tc(0x02, 0, 0).unwrap();
|
||||||
/// let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
/// let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
||||||
/// let len = pus_tc
|
/// let len = pus_tc
|
||||||
/// .write_to(&mut buf)
|
/// .write_to_bytes(&mut buf)
|
||||||
/// .expect("Error writing PUS TC packet");
|
/// .expect("Error writing PUS TC packet");
|
||||||
/// assert_eq!(len, 13);
|
/// assert_eq!(len, 13);
|
||||||
/// let client = UdpSocket::bind("127.0.0.1:7778").expect("Connecting to UDP server failed");
|
/// let client = UdpSocket::bind("127.0.0.1:7778").expect("Connecting to UDP server failed");
|
||||||
@ -166,7 +166,7 @@ mod tests {
|
|||||||
let mut sph = SpHeader::tc(0x02, 0, 0).unwrap();
|
let mut sph = SpHeader::tc(0x02, 0, 0).unwrap();
|
||||||
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
||||||
let len = pus_tc
|
let len = pus_tc
|
||||||
.write_to(&mut buf)
|
.write_to_bytes(&mut buf)
|
||||||
.expect("Error writing PUS TC packet");
|
.expect("Error writing PUS TC packet");
|
||||||
let client = UdpSocket::bind("127.0.0.1:7778").expect("Connecting to UDP server failed");
|
let client = UdpSocket::bind("127.0.0.1:7778").expect("Connecting to UDP server failed");
|
||||||
client
|
client
|
||||||
|
115
fsrc-core/src/pus/event.rs
Normal file
115
fsrc-core/src/pus/event.rs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
use crate::pus::{source_buffer_large_enough, EcssTmError, EcssTmSender};
|
||||||
|
use spacepackets::ecss::EcssEnumeration;
|
||||||
|
use spacepackets::tm::PusTm;
|
||||||
|
use spacepackets::tm::PusTmSecondaryHeader;
|
||||||
|
use spacepackets::{SpHeader, MAX_APID};
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
pub use allocvec::EventReporterWithVec;
|
||||||
|
|
||||||
|
pub struct EventReporter {
|
||||||
|
msg_count: u16,
|
||||||
|
apid: u16,
|
||||||
|
pub dest_id: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventReporter {
|
||||||
|
pub fn new(apid: u16) -> Option<Self> {
|
||||||
|
if apid > MAX_APID {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(Self {
|
||||||
|
msg_count: 0,
|
||||||
|
dest_id: 0,
|
||||||
|
apid,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn event_info<E>(
|
||||||
|
&mut self,
|
||||||
|
buf: &mut [u8],
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
time_stamp: &[u8],
|
||||||
|
event_id: impl EcssEnumeration,
|
||||||
|
aux_data: Option<&[u8]>,
|
||||||
|
) -> Result<(), EcssTmError<E>> {
|
||||||
|
let mut src_data_len = event_id.byte_width();
|
||||||
|
if let Some(aux_data) = aux_data {
|
||||||
|
src_data_len += aux_data.len();
|
||||||
|
}
|
||||||
|
source_buffer_large_enough(buf.len(), src_data_len)?;
|
||||||
|
let mut sp_header = SpHeader::tm(self.apid, 0, 0).unwrap();
|
||||||
|
let sec_header = PusTmSecondaryHeader::new(5, 0, self.msg_count, self.dest_id, time_stamp);
|
||||||
|
let mut current_idx = 0;
|
||||||
|
event_id.write_to_bytes(&mut buf[0..event_id.byte_width()])?;
|
||||||
|
current_idx += event_id.byte_width();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
let tm = PusTm::new(&mut sp_header, sec_header, Some(&buf[0..current_idx]), true);
|
||||||
|
sender.send_tm(tm)?;
|
||||||
|
self.msg_count += 1;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
mod allocvec {
|
||||||
|
use super::*;
|
||||||
|
use alloc::vec;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
|
pub struct EventReporterWithVec {
|
||||||
|
source_data_buf: Vec<u8>,
|
||||||
|
pub reporter: EventReporter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventReporterWithVec {
|
||||||
|
pub fn new(apid: u16, max_event_id_and_aux_data: usize) -> Option<Self> {
|
||||||
|
let reporter = EventReporter::new(apid)?;
|
||||||
|
Some(Self {
|
||||||
|
source_data_buf: vec![0; max_event_id_and_aux_data],
|
||||||
|
reporter,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn event_info<E>(
|
||||||
|
&mut self,
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
time_stamp: &[u8],
|
||||||
|
event_id: impl EcssEnumeration,
|
||||||
|
aux_data: Option<&[u8]>,
|
||||||
|
) -> Result<(), EcssTmError<E>> {
|
||||||
|
self.reporter.event_info(
|
||||||
|
self.source_data_buf.as_mut_slice(),
|
||||||
|
sender,
|
||||||
|
time_stamp,
|
||||||
|
event_id,
|
||||||
|
aux_data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// pub fn event_low_severity<E>(
|
||||||
|
// &mut self,
|
||||||
|
// _sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
// _event_id: impl EcssEnumeration,
|
||||||
|
// _aux_data: Option<&[u8]>,
|
||||||
|
// ) {
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub fn event_medium_severity<E>(
|
||||||
|
// &mut self,
|
||||||
|
// _sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
// _event_id: impl EcssEnumeration,
|
||||||
|
// _aux_data: Option<&[u8]>,
|
||||||
|
// ) {
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub fn event_high_severity<E>(
|
||||||
|
// &mut self,
|
||||||
|
// _sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
// _event_id: impl EcssEnumeration,
|
||||||
|
// _aux_data: Option<&[u8]>,
|
||||||
|
// ) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
@ -3,5 +3,52 @@
|
|||||||
//! Currenty includes:
|
//! Currenty includes:
|
||||||
//!
|
//!
|
||||||
//! 1. PUS Verification Service 1 module inside [verification]. Requires [alloc] support.
|
//! 1. PUS Verification Service 1 module inside [verification]. Requires [alloc] support.
|
||||||
#[cfg(feature = "alloc")]
|
use downcast_rs::{impl_downcast, Downcast};
|
||||||
|
use spacepackets::ecss::PusError;
|
||||||
|
use spacepackets::time::TimestampError;
|
||||||
|
use spacepackets::tm::PusTm;
|
||||||
|
use spacepackets::{ByteConversionError, SizeMissmatch};
|
||||||
|
|
||||||
|
pub mod event;
|
||||||
pub mod verification;
|
pub mod verification;
|
||||||
|
|
||||||
|
/// Generic error type which is also able to wrap a user send error with the user supplied type E.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum EcssTmError<E> {
|
||||||
|
/// Errors related to sending the verification telemetry to a TM recipient
|
||||||
|
SendError(E),
|
||||||
|
/// 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
|
||||||
|
ByteConversionError(ByteConversionError),
|
||||||
|
/// Errors related to PUS packet format
|
||||||
|
PusError(PusError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E> From<ByteConversionError> for EcssTmError<E> {
|
||||||
|
fn from(e: ByteConversionError) -> Self {
|
||||||
|
EcssTmError::ByteConversionError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generic trait for a user supplied sender object. 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
|
||||||
|
/// concrete type at a later point.
|
||||||
|
pub trait EcssTmSender<E>: Downcast + Send {
|
||||||
|
fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<E>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_downcast!(EcssTmSender<E>);
|
||||||
|
|
||||||
|
pub(crate) fn source_buffer_large_enough<E>(cap: usize, len: usize) -> Result<(), EcssTmError<E>> {
|
||||||
|
if len > cap {
|
||||||
|
return Err(EcssTmError::ByteConversionError(
|
||||||
|
ByteConversionError::ToSliceTooSmall(SizeMissmatch {
|
||||||
|
found: cap,
|
||||||
|
expected: len,
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
//! 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);
|
//! let cfg = VerificationReporterCfg::new(TEST_APID, 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();
|
||||||
@ -71,21 +71,20 @@
|
|||||||
//! The [integration test](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/main/fsrc-core/tests/verification_test.rs)
|
//! The [integration test](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/main/fsrc-core/tests/verification_test.rs)
|
||||||
//! for the verification module contains examples how this module could be used in a more complex
|
//! for the verification module contains examples how this module could be used in a more complex
|
||||||
//! context involving multiple threads
|
//! context involving multiple threads
|
||||||
use alloc::boxed::Box;
|
use crate::pus::{source_buffer_large_enough, EcssTmError, EcssTmSender};
|
||||||
use alloc::vec;
|
|
||||||
use alloc::vec::Vec;
|
|
||||||
use core::fmt::{Display, Formatter};
|
use core::fmt::{Display, Formatter};
|
||||||
use core::hash::{Hash, Hasher};
|
use core::hash::{Hash, Hasher};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
use delegate::delegate;
|
use delegate::delegate;
|
||||||
use downcast_rs::{impl_downcast, Downcast};
|
use spacepackets::ecss::EcssEnumeration;
|
||||||
use spacepackets::ecss::{EcssEnumeration, PusError};
|
|
||||||
use spacepackets::tc::PusTc;
|
use spacepackets::tc::PusTc;
|
||||||
use spacepackets::time::TimestampError;
|
|
||||||
use spacepackets::tm::{PusTm, PusTmSecondaryHeader};
|
use spacepackets::tm::{PusTm, PusTmSecondaryHeader};
|
||||||
use spacepackets::{ByteConversionError, SizeMissmatch, SpHeader};
|
|
||||||
use spacepackets::{CcsdsPacket, PacketId, PacketSequenceCtrl};
|
use spacepackets::{CcsdsPacket, PacketId, PacketSequenceCtrl};
|
||||||
|
use spacepackets::{SpHeader, MAX_APID};
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
pub use allocmod::{VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use stdmod::{
|
pub use stdmod::{
|
||||||
@ -160,39 +159,10 @@ impl RequestId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic error type which is also able to wrap a user send error with the user supplied type E.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum VerificationError<E> {
|
|
||||||
/// Errors related to sending the verification telemetry to a TM recipient
|
|
||||||
SendError(E),
|
|
||||||
/// Errors related to the time stamp format of the telemetry
|
|
||||||
TimestampError(TimestampError),
|
|
||||||
/// Errors related to byte conversion, for example unsufficient buffer size for given data
|
|
||||||
ByteConversionError(ByteConversionError),
|
|
||||||
/// Errors related to PUS packet format
|
|
||||||
PusError(PusError),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E> From<ByteConversionError> for VerificationError<E> {
|
|
||||||
fn from(e: ByteConversionError) -> Self {
|
|
||||||
VerificationError::ByteConversionError(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If a verification operation fails, the passed token will be returned as well. This allows
|
/// If a verification operation fails, the passed token will be returned as well. This allows
|
||||||
/// re-trying the operation at a later point.
|
/// re-trying the operation at a later point.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct VerificationErrorWithToken<E, T>(VerificationError<E>, VerificationToken<T>);
|
pub struct VerificationErrorWithToken<E, T>(EcssTmError<E>, VerificationToken<T>);
|
||||||
|
|
||||||
/// Generic trait for a user supplied sender object. This sender object is responsible for sending
|
|
||||||
/// PUS Service 1 Verification Telemetry to a verification TM recipient. The [Downcast] trait
|
|
||||||
/// is implemented to allow passing the sender as a boxed trait object and still retrieve the
|
|
||||||
/// concrete type at a later point.
|
|
||||||
pub trait VerificationSender<E>: Downcast + Send {
|
|
||||||
fn send_verification_tm(&mut self, tm: PusTm) -> Result<(), VerificationError<E>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_downcast!(VerificationSender<E>);
|
|
||||||
|
|
||||||
/// Support token to allow type-state programming. This prevents calling the verification
|
/// Support token to allow type-state programming. This prevents calling the verification
|
||||||
/// steps in an invalid order.
|
/// steps in an invalid order.
|
||||||
@ -222,41 +192,6 @@ impl<STATE> VerificationToken<STATE> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VerificationReporterCfg {
|
|
||||||
pub apid: u16,
|
|
||||||
pub dest_id: u16,
|
|
||||||
pub step_field_width: usize,
|
|
||||||
pub fail_code_field_width: usize,
|
|
||||||
pub max_fail_data_len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VerificationReporterCfg {
|
|
||||||
/// Create a new configuration for the verification reporter. This includes following parameters:
|
|
||||||
///
|
|
||||||
/// 1. Destination ID and APID, which could remain constant after construction. These parameters
|
|
||||||
/// can be tweaked in the reporter after construction.
|
|
||||||
/// 2. Maximum expected field sizes. The parameters of this configuration struct will be used
|
|
||||||
/// to determine required maximum buffer sizes and there will be no addition allocation or
|
|
||||||
/// configurable buffer parameters after [VerificationReporter] construction.
|
|
||||||
///
|
|
||||||
/// This means the user has supply the maximum expected field sizes of verification messages
|
|
||||||
/// before constructing the reporter.
|
|
||||||
pub fn new(
|
|
||||||
apid: u16,
|
|
||||||
step_field_width: usize,
|
|
||||||
fail_code_field_width: usize,
|
|
||||||
max_fail_data_len: usize,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
apid,
|
|
||||||
dest_id: 0,
|
|
||||||
step_field_width,
|
|
||||||
fail_code_field_width,
|
|
||||||
max_fail_data_len,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Composite helper struct to pass failure parameters to the [VerificationReporter]
|
/// Composite helper struct to pass failure parameters to the [VerificationReporter]
|
||||||
pub struct FailParams<'a> {
|
pub struct FailParams<'a> {
|
||||||
time_stamp: &'a [u8],
|
time_stamp: &'a [u8],
|
||||||
@ -298,33 +233,42 @@ impl<'a> FailParamsWithStep<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Primary verification handler. It provides an API to send PUS 1 verification telemetry packets
|
pub struct VerificationReporterBasic {
|
||||||
/// and verify the various steps of telecommand handling as specified in the PUS standard.
|
|
||||||
pub struct VerificationReporter {
|
|
||||||
pub apid: u16,
|
|
||||||
pub dest_id: u16,
|
pub dest_id: u16,
|
||||||
|
apid: u16,
|
||||||
msg_count: u16,
|
msg_count: u16,
|
||||||
source_data_buf: Vec<u8>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VerificationReporter {
|
impl VerificationReporterBasic {
|
||||||
pub fn new(cfg: VerificationReporterCfg) -> Self {
|
pub fn new(apid: u16) -> Option<Self> {
|
||||||
Self {
|
if apid > MAX_APID {
|
||||||
apid: cfg.apid,
|
return None;
|
||||||
dest_id: cfg.dest_id,
|
|
||||||
msg_count: 0,
|
|
||||||
source_data_buf: vec![
|
|
||||||
0;
|
|
||||||
RequestId::SIZE_AS_BYTES
|
|
||||||
+ cfg.step_field_width as usize
|
|
||||||
+ cfg.fail_code_field_width as usize
|
|
||||||
+ cfg.max_fail_data_len
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
Some(Self {
|
||||||
|
apid,
|
||||||
|
msg_count: 0,
|
||||||
|
dest_id: 0,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allowed_source_data_len(&self) -> usize {
|
pub fn set_apid(&mut self, apid: u16) -> bool {
|
||||||
self.source_data_buf.capacity()
|
if apid > MAX_APID {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self.apid = apid;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apid(&self) -> u16 {
|
||||||
|
self.apid
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dest_id(&self) -> u16 {
|
||||||
|
self.dest_id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_dest_id(&mut self, dest_id: u16) {
|
||||||
|
self.dest_id = dest_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize verification handling by passing a TC reference. This returns a token required
|
/// Initialize verification handling by passing a TC reference. This returns a token required
|
||||||
@ -342,12 +286,14 @@ impl VerificationReporter {
|
|||||||
/// Package and send a PUS TM\[1, 1\] packet, see 8.1.2.1 of the PUS standard
|
/// Package and send a PUS TM\[1, 1\] packet, see 8.1.2.1 of the PUS standard
|
||||||
pub fn acceptance_success<E>(
|
pub fn acceptance_success<E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
buf: &mut [u8],
|
||||||
token: VerificationToken<StateNone>,
|
token: VerificationToken<StateNone>,
|
||||||
sender: &mut (impl VerificationSender<E> + ?Sized),
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
) -> Result<VerificationToken<StateAccepted>, VerificationErrorWithToken<E, StateNone>> {
|
) -> Result<VerificationToken<StateAccepted>, VerificationErrorWithToken<E, StateNone>> {
|
||||||
let tm = self
|
let tm = self
|
||||||
.create_pus_verif_success_tm(
|
.create_pus_verif_success_tm(
|
||||||
|
buf,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
&token.req_id,
|
&token.req_id,
|
||||||
@ -356,7 +302,7 @@ impl VerificationReporter {
|
|||||||
)
|
)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
sender
|
sender
|
||||||
.send_verification_tm(tm)
|
.send_tm(tm)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
self.msg_count += 1;
|
self.msg_count += 1;
|
||||||
Ok(VerificationToken {
|
Ok(VerificationToken {
|
||||||
@ -368,15 +314,23 @@ impl VerificationReporter {
|
|||||||
/// Package and send a PUS TM\[1, 2\] packet, see 8.1.2.2 of the PUS standard
|
/// Package and send a PUS TM\[1, 2\] packet, see 8.1.2.2 of the PUS standard
|
||||||
pub fn acceptance_failure<E>(
|
pub fn acceptance_failure<E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
buf: &mut [u8],
|
||||||
token: VerificationToken<StateNone>,
|
token: VerificationToken<StateNone>,
|
||||||
sender: &mut (impl VerificationSender<E> + ?Sized),
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
params: FailParams,
|
params: FailParams,
|
||||||
) -> Result<(), VerificationErrorWithToken<E, StateNone>> {
|
) -> Result<(), VerificationErrorWithToken<E, StateNone>> {
|
||||||
let tm = self
|
let tm = self
|
||||||
.create_pus_verif_fail_tm(1, 2, &token.req_id, None::<&dyn EcssEnumeration>, ¶ms)
|
.create_pus_verif_fail_tm(
|
||||||
|
buf,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
&token.req_id,
|
||||||
|
None::<&dyn EcssEnumeration>,
|
||||||
|
¶ms,
|
||||||
|
)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
sender
|
sender
|
||||||
.send_verification_tm(tm)
|
.send_tm(tm)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
self.msg_count += 1;
|
self.msg_count += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -387,12 +341,14 @@ impl VerificationReporter {
|
|||||||
/// Requires a token previously acquired by calling [Self::acceptance_success].
|
/// Requires a token previously acquired by calling [Self::acceptance_success].
|
||||||
pub fn start_success<E>(
|
pub fn start_success<E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
buf: &mut [u8],
|
||||||
token: VerificationToken<StateAccepted>,
|
token: VerificationToken<StateAccepted>,
|
||||||
sender: &mut (impl VerificationSender<E> + ?Sized),
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
) -> Result<VerificationToken<StateStarted>, VerificationErrorWithToken<E, StateAccepted>> {
|
) -> Result<VerificationToken<StateStarted>, VerificationErrorWithToken<E, StateAccepted>> {
|
||||||
let tm = self
|
let tm = self
|
||||||
.create_pus_verif_success_tm(
|
.create_pus_verif_success_tm(
|
||||||
|
buf,
|
||||||
1,
|
1,
|
||||||
3,
|
3,
|
||||||
&token.req_id,
|
&token.req_id,
|
||||||
@ -401,7 +357,7 @@ impl VerificationReporter {
|
|||||||
)
|
)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
sender
|
sender
|
||||||
.send_verification_tm(tm)
|
.send_tm(tm)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
self.msg_count += 1;
|
self.msg_count += 1;
|
||||||
Ok(VerificationToken {
|
Ok(VerificationToken {
|
||||||
@ -416,15 +372,23 @@ impl VerificationReporter {
|
|||||||
/// the token because verification handling is done.
|
/// the token because verification handling is done.
|
||||||
pub fn start_failure<E>(
|
pub fn start_failure<E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
buf: &mut [u8],
|
||||||
token: VerificationToken<StateAccepted>,
|
token: VerificationToken<StateAccepted>,
|
||||||
sender: &mut (impl VerificationSender<E> + ?Sized),
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
params: FailParams,
|
params: FailParams,
|
||||||
) -> Result<(), VerificationErrorWithToken<E, StateAccepted>> {
|
) -> Result<(), VerificationErrorWithToken<E, StateAccepted>> {
|
||||||
let tm = self
|
let tm = self
|
||||||
.create_pus_verif_fail_tm(1, 4, &token.req_id, None::<&dyn EcssEnumeration>, ¶ms)
|
.create_pus_verif_fail_tm(
|
||||||
|
buf,
|
||||||
|
1,
|
||||||
|
4,
|
||||||
|
&token.req_id,
|
||||||
|
None::<&dyn EcssEnumeration>,
|
||||||
|
¶ms,
|
||||||
|
)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
sender
|
sender
|
||||||
.send_verification_tm(tm)
|
.send_tm(tm)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
self.msg_count += 1;
|
self.msg_count += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -435,13 +399,15 @@ impl VerificationReporter {
|
|||||||
/// Requires a token previously acquired by calling [Self::start_success].
|
/// Requires a token previously acquired by calling [Self::start_success].
|
||||||
pub fn step_success<E>(
|
pub fn step_success<E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
buf: &mut [u8],
|
||||||
token: &VerificationToken<StateStarted>,
|
token: &VerificationToken<StateStarted>,
|
||||||
sender: &mut (impl VerificationSender<E> + ?Sized),
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
step: impl EcssEnumeration,
|
step: impl EcssEnumeration,
|
||||||
) -> Result<(), VerificationError<E>> {
|
) -> Result<(), EcssTmError<E>> {
|
||||||
let tm = self.create_pus_verif_success_tm(1, 5, &token.req_id, time_stamp, Some(&step))?;
|
let tm =
|
||||||
sender.send_verification_tm(tm)?;
|
self.create_pus_verif_success_tm(buf, 1, 5, &token.req_id, time_stamp, Some(&step))?;
|
||||||
|
sender.send_tm(tm)?;
|
||||||
self.msg_count += 1;
|
self.msg_count += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -452,15 +418,16 @@ impl VerificationReporter {
|
|||||||
/// token because verification handling is done.
|
/// token because verification handling is done.
|
||||||
pub fn step_failure<E>(
|
pub fn step_failure<E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
buf: &mut [u8],
|
||||||
token: VerificationToken<StateStarted>,
|
token: VerificationToken<StateStarted>,
|
||||||
sender: &mut (impl VerificationSender<E> + ?Sized),
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
params: FailParamsWithStep,
|
params: FailParamsWithStep,
|
||||||
) -> Result<(), VerificationErrorWithToken<E, StateStarted>> {
|
) -> Result<(), VerificationErrorWithToken<E, StateStarted>> {
|
||||||
let tm = self
|
let tm = self
|
||||||
.create_pus_verif_fail_tm(1, 6, &token.req_id, Some(params.step), ¶ms.bp)
|
.create_pus_verif_fail_tm(buf, 1, 6, &token.req_id, Some(params.step), ¶ms.bp)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
sender
|
sender
|
||||||
.send_verification_tm(tm)
|
.send_tm(tm)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
self.msg_count += 1;
|
self.msg_count += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -472,12 +439,14 @@ impl VerificationReporter {
|
|||||||
/// token because verification handling is done.
|
/// token because verification handling is done.
|
||||||
pub fn completion_success<E>(
|
pub fn completion_success<E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
buf: &mut [u8],
|
||||||
token: VerificationToken<StateStarted>,
|
token: VerificationToken<StateStarted>,
|
||||||
sender: &mut (impl VerificationSender<E> + ?Sized),
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
) -> Result<(), VerificationErrorWithToken<E, StateStarted>> {
|
) -> Result<(), VerificationErrorWithToken<E, StateStarted>> {
|
||||||
let tm = self
|
let tm = self
|
||||||
.create_pus_verif_success_tm(
|
.create_pus_verif_success_tm(
|
||||||
|
buf,
|
||||||
1,
|
1,
|
||||||
7,
|
7,
|
||||||
&token.req_id,
|
&token.req_id,
|
||||||
@ -486,7 +455,7 @@ impl VerificationReporter {
|
|||||||
)
|
)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
sender
|
sender
|
||||||
.send_verification_tm(tm)
|
.send_tm(tm)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
self.msg_count += 1;
|
self.msg_count += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -498,15 +467,23 @@ impl VerificationReporter {
|
|||||||
/// token because verification handling is done.
|
/// token because verification handling is done.
|
||||||
pub fn completion_failure<E>(
|
pub fn completion_failure<E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
buf: &mut [u8],
|
||||||
token: VerificationToken<StateStarted>,
|
token: VerificationToken<StateStarted>,
|
||||||
sender: &mut (impl VerificationSender<E> + ?Sized),
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
params: FailParams,
|
params: FailParams,
|
||||||
) -> Result<(), VerificationErrorWithToken<E, StateStarted>> {
|
) -> Result<(), VerificationErrorWithToken<E, StateStarted>> {
|
||||||
let tm = self
|
let tm = self
|
||||||
.create_pus_verif_fail_tm(1, 8, &token.req_id, None::<&dyn EcssEnumeration>, ¶ms)
|
.create_pus_verif_fail_tm(
|
||||||
|
buf,
|
||||||
|
1,
|
||||||
|
8,
|
||||||
|
&token.req_id,
|
||||||
|
None::<&dyn EcssEnumeration>,
|
||||||
|
¶ms,
|
||||||
|
)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
sender
|
sender
|
||||||
.send_verification_tm(tm)
|
.send_tm(tm)
|
||||||
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
.map_err(|e| VerificationErrorWithToken(e, token))?;
|
||||||
self.msg_count += 1;
|
self.msg_count += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -514,27 +491,29 @@ impl VerificationReporter {
|
|||||||
|
|
||||||
fn create_pus_verif_success_tm<'a, E>(
|
fn create_pus_verif_success_tm<'a, E>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
|
buf: &'a mut [u8],
|
||||||
service: u8,
|
service: u8,
|
||||||
subservice: u8,
|
subservice: u8,
|
||||||
req_id: &RequestId,
|
req_id: &RequestId,
|
||||||
time_stamp: &'a [u8],
|
time_stamp: &'a [u8],
|
||||||
step: Option<&(impl EcssEnumeration + ?Sized)>,
|
step: Option<&(impl EcssEnumeration + ?Sized)>,
|
||||||
) -> Result<PusTm, VerificationError<E>> {
|
) -> Result<PusTm, EcssTmError<E>> {
|
||||||
let mut source_data_len = size_of::<u32>();
|
let mut source_data_len = size_of::<u32>();
|
||||||
if let Some(step) = step {
|
if let Some(step) = step {
|
||||||
source_data_len += step.byte_width() as usize;
|
source_data_len += step.byte_width() as usize;
|
||||||
}
|
}
|
||||||
self.source_buffer_large_enough(source_data_len)?;
|
source_buffer_large_enough(buf.len(), source_data_len)?;
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
req_id.to_bytes(&mut self.source_data_buf[0..RequestId::SIZE_AS_BYTES]);
|
req_id.to_bytes(&mut buf[0..RequestId::SIZE_AS_BYTES]);
|
||||||
idx += RequestId::SIZE_AS_BYTES;
|
idx += RequestId::SIZE_AS_BYTES;
|
||||||
if let Some(step) = step {
|
if let Some(step) = step {
|
||||||
// Size check was done beforehand
|
// Size check was done beforehand
|
||||||
step.to_bytes(&mut self.source_data_buf[idx..idx + step.byte_width() as usize])
|
step.write_to_bytes(&mut buf[idx..idx + step.byte_width() as usize])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
let mut sp_header = SpHeader::tm(self.apid, 0, 0).unwrap();
|
let mut sp_header = SpHeader::tm(self.apid(), 0, 0).unwrap();
|
||||||
Ok(self.create_pus_verif_tm_base(
|
Ok(self.create_pus_verif_tm_base(
|
||||||
|
buf,
|
||||||
service,
|
service,
|
||||||
subservice,
|
subservice,
|
||||||
&mut sp_header,
|
&mut sp_header,
|
||||||
@ -545,12 +524,13 @@ impl VerificationReporter {
|
|||||||
|
|
||||||
fn create_pus_verif_fail_tm<'a, E>(
|
fn create_pus_verif_fail_tm<'a, E>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
|
buf: &'a mut [u8],
|
||||||
service: u8,
|
service: u8,
|
||||||
subservice: u8,
|
subservice: u8,
|
||||||
req_id: &RequestId,
|
req_id: &RequestId,
|
||||||
step: Option<&(impl EcssEnumeration + ?Sized)>,
|
step: Option<&(impl EcssEnumeration + ?Sized)>,
|
||||||
params: &'a FailParams,
|
params: &'a FailParams,
|
||||||
) -> Result<PusTm, VerificationError<E>> {
|
) -> Result<PusTm, EcssTmError<E>> {
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
let mut source_data_len =
|
let mut source_data_len =
|
||||||
RequestId::SIZE_AS_BYTES + params.failure_code.byte_width() as usize;
|
RequestId::SIZE_AS_BYTES + params.failure_code.byte_width() as usize;
|
||||||
@ -560,24 +540,25 @@ impl VerificationReporter {
|
|||||||
if let Some(failure_data) = params.failure_data {
|
if let Some(failure_data) = params.failure_data {
|
||||||
source_data_len += failure_data.len();
|
source_data_len += failure_data.len();
|
||||||
}
|
}
|
||||||
self.source_buffer_large_enough(source_data_len)?;
|
source_buffer_large_enough(buf.len(), source_data_len)?;
|
||||||
req_id.to_bytes(&mut self.source_data_buf[0..RequestId::SIZE_AS_BYTES]);
|
req_id.to_bytes(&mut buf[0..RequestId::SIZE_AS_BYTES]);
|
||||||
idx += RequestId::SIZE_AS_BYTES;
|
idx += RequestId::SIZE_AS_BYTES;
|
||||||
if let Some(step) = step {
|
if let Some(step) = step {
|
||||||
// Size check done beforehand
|
// Size check done beforehand
|
||||||
step.to_bytes(&mut self.source_data_buf[idx..idx + step.byte_width() as usize])
|
step.write_to_bytes(&mut buf[idx..idx + step.byte_width() as usize])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
idx += step.byte_width() as usize;
|
idx += step.byte_width() as usize;
|
||||||
}
|
}
|
||||||
params.failure_code.to_bytes(
|
params
|
||||||
&mut self.source_data_buf[idx..idx + params.failure_code.byte_width() as usize],
|
.failure_code
|
||||||
)?;
|
.write_to_bytes(&mut buf[idx..idx + params.failure_code.byte_width() as usize])?;
|
||||||
idx += params.failure_code.byte_width() as usize;
|
idx += params.failure_code.byte_width() as usize;
|
||||||
if let Some(failure_data) = params.failure_data {
|
if let Some(failure_data) = params.failure_data {
|
||||||
self.source_data_buf[idx..idx + failure_data.len()].copy_from_slice(failure_data);
|
buf[idx..idx + failure_data.len()].copy_from_slice(failure_data);
|
||||||
}
|
}
|
||||||
let mut sp_header = SpHeader::tm(self.apid, 0, 0).unwrap();
|
let mut sp_header = SpHeader::tm(self.apid(), 0, 0).unwrap();
|
||||||
Ok(self.create_pus_verif_tm_base(
|
Ok(self.create_pus_verif_tm_base(
|
||||||
|
buf,
|
||||||
service,
|
service,
|
||||||
subservice,
|
subservice,
|
||||||
&mut sp_header,
|
&mut sp_header,
|
||||||
@ -586,20 +567,9 @@ impl VerificationReporter {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn source_buffer_large_enough<E>(&self, len: usize) -> Result<(), VerificationError<E>> {
|
|
||||||
if len > self.source_data_buf.capacity() {
|
|
||||||
return Err(VerificationError::ByteConversionError(
|
|
||||||
ByteConversionError::ToSliceTooSmall(SizeMissmatch {
|
|
||||||
found: self.source_data_buf.capacity(),
|
|
||||||
expected: len,
|
|
||||||
}),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_pus_verif_tm_base<'a>(
|
fn create_pus_verif_tm_base<'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
|
buf: &'a mut [u8],
|
||||||
service: u8,
|
service: u8,
|
||||||
subservice: u8,
|
subservice: u8,
|
||||||
sp_header: &mut SpHeader,
|
sp_header: &mut SpHeader,
|
||||||
@ -616,35 +586,243 @@ impl VerificationReporter {
|
|||||||
PusTm::new(
|
PusTm::new(
|
||||||
sp_header,
|
sp_header,
|
||||||
tm_sec_header,
|
tm_sec_header,
|
||||||
Some(&self.source_data_buf[0..source_data_len]),
|
Some(&buf[0..source_data_len]),
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper object which caches the sender passed as a trait object. Provides the same
|
#[cfg(feature = "alloc")]
|
||||||
/// API as [VerificationReporter] but without the explicit sender arguments.
|
mod allocmod {
|
||||||
pub struct VerificationReporterWithSender<E> {
|
use super::*;
|
||||||
reporter: VerificationReporter,
|
use alloc::boxed::Box;
|
||||||
pub sender: Box<dyn VerificationSender<E>>,
|
use alloc::vec;
|
||||||
}
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
impl<E: 'static> VerificationReporterWithSender<E> {
|
pub struct VerificationReporterCfg {
|
||||||
pub fn new(cfg: VerificationReporterCfg, sender: Box<dyn VerificationSender<E>>) -> Self {
|
apid: u16,
|
||||||
Self::new_from_reporter(VerificationReporter::new(cfg), sender)
|
pub step_field_width: usize,
|
||||||
|
pub fail_code_field_width: usize,
|
||||||
|
pub max_fail_data_len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VerificationReporterCfg {
|
||||||
|
pub fn new(
|
||||||
|
apid: u16,
|
||||||
|
step_field_width: usize,
|
||||||
|
fail_code_field_width: usize,
|
||||||
|
max_fail_data_len: usize,
|
||||||
|
) -> Option<Self> {
|
||||||
|
if apid > MAX_APID {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(Self {
|
||||||
|
apid,
|
||||||
|
step_field_width,
|
||||||
|
fail_code_field_width,
|
||||||
|
max_fail_data_len,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
pub struct VerificationReporter {
|
||||||
|
source_data_buf: Vec<u8>,
|
||||||
|
pub reporter: VerificationReporterBasic,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VerificationReporter {
|
||||||
|
pub fn new(cfg: VerificationReporterCfg) -> Self {
|
||||||
|
let reporter = VerificationReporterBasic::new(cfg.apid).unwrap();
|
||||||
|
Self {
|
||||||
|
source_data_buf: vec![
|
||||||
|
0;
|
||||||
|
RequestId::SIZE_AS_BYTES
|
||||||
|
+ cfg.step_field_width as usize
|
||||||
|
+ cfg.fail_code_field_width as usize
|
||||||
|
+ cfg.max_fail_data_len
|
||||||
|
],
|
||||||
|
reporter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate!(
|
||||||
|
to self.reporter {
|
||||||
|
pub fn set_apid(&mut self, apid: u16) -> bool;
|
||||||
|
pub fn apid(&self) -> u16;
|
||||||
|
pub fn add_tc(&mut self, pus_tc: &PusTc) -> VerificationToken<StateNone>;
|
||||||
|
pub fn add_tc_with_req_id(&mut self, req_id: RequestId) -> VerificationToken<StateNone>;
|
||||||
|
pub fn dest_id(&self) -> u16;
|
||||||
|
pub fn set_dest_id(&mut self, dest_id: u16);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
pub fn allowed_source_data_len(&self) -> usize {
|
||||||
|
self.source_data_buf.capacity()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Package and send a PUS TM\[1, 1\] packet, see 8.1.2.1 of the PUS standard
|
||||||
|
pub fn acceptance_success<E>(
|
||||||
|
&mut self,
|
||||||
|
token: VerificationToken<StateNone>,
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
time_stamp: &[u8],
|
||||||
|
) -> Result<VerificationToken<StateAccepted>, VerificationErrorWithToken<E, StateNone>>
|
||||||
|
{
|
||||||
|
self.reporter.acceptance_success(
|
||||||
|
self.source_data_buf.as_mut_slice(),
|
||||||
|
token,
|
||||||
|
sender,
|
||||||
|
time_stamp,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Package and send a PUS TM\[1, 2\] packet, see 8.1.2.2 of the PUS standard
|
||||||
|
pub fn acceptance_failure<E>(
|
||||||
|
&mut self,
|
||||||
|
token: VerificationToken<StateNone>,
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
params: FailParams,
|
||||||
|
) -> Result<(), VerificationErrorWithToken<E, StateNone>> {
|
||||||
|
self.reporter.acceptance_failure(
|
||||||
|
self.source_data_buf.as_mut_slice(),
|
||||||
|
token,
|
||||||
|
sender,
|
||||||
|
params,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Package and send a PUS TM\[1, 3\] packet, see 8.1.2.3 of the PUS standard.
|
||||||
|
///
|
||||||
|
/// Requires a token previously acquired by calling [Self::acceptance_success].
|
||||||
|
pub fn start_success<E>(
|
||||||
|
&mut self,
|
||||||
|
token: VerificationToken<StateAccepted>,
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
time_stamp: &[u8],
|
||||||
|
) -> Result<VerificationToken<StateStarted>, VerificationErrorWithToken<E, StateAccepted>>
|
||||||
|
{
|
||||||
|
self.reporter.start_success(
|
||||||
|
self.source_data_buf.as_mut_slice(),
|
||||||
|
token,
|
||||||
|
sender,
|
||||||
|
time_stamp,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Package and send a PUS TM\[1, 4\] packet, see 8.1.2.4 of the PUS standard.
|
||||||
|
///
|
||||||
|
/// Requires a token previously acquired by calling [Self::acceptance_success]. It consumes
|
||||||
|
/// the token because verification handling is done.
|
||||||
|
pub fn start_failure<E>(
|
||||||
|
&mut self,
|
||||||
|
token: VerificationToken<StateAccepted>,
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
params: FailParams,
|
||||||
|
) -> Result<(), VerificationErrorWithToken<E, StateAccepted>> {
|
||||||
|
self.reporter
|
||||||
|
.start_failure(self.source_data_buf.as_mut_slice(), token, sender, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Package and send a PUS TM\[1, 5\] packet, see 8.1.2.5 of the PUS standard.
|
||||||
|
///
|
||||||
|
/// Requires a token previously acquired by calling [Self::start_success].
|
||||||
|
pub fn step_success<E>(
|
||||||
|
&mut self,
|
||||||
|
token: &VerificationToken<StateStarted>,
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
time_stamp: &[u8],
|
||||||
|
step: impl EcssEnumeration,
|
||||||
|
) -> Result<(), EcssTmError<E>> {
|
||||||
|
self.reporter.step_success(
|
||||||
|
self.source_data_buf.as_mut_slice(),
|
||||||
|
token,
|
||||||
|
sender,
|
||||||
|
time_stamp,
|
||||||
|
step,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Package and send a PUS TM\[1, 6\] packet, see 8.1.2.6 of the PUS standard.
|
||||||
|
///
|
||||||
|
/// Requires a token previously acquired by calling [Self::start_success]. It consumes the
|
||||||
|
/// token because verification handling is done.
|
||||||
|
pub fn step_failure<E>(
|
||||||
|
&mut self,
|
||||||
|
token: VerificationToken<StateStarted>,
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
params: FailParamsWithStep,
|
||||||
|
) -> Result<(), VerificationErrorWithToken<E, StateStarted>> {
|
||||||
|
self.reporter
|
||||||
|
.step_failure(self.source_data_buf.as_mut_slice(), token, sender, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Package and send a PUS TM\[1, 7\] packet, see 8.1.2.7 of the PUS standard.
|
||||||
|
///
|
||||||
|
/// Requires a token previously acquired by calling [Self::start_success]. It consumes the
|
||||||
|
/// token because verification handling is done.
|
||||||
|
pub fn completion_success<E>(
|
||||||
|
&mut self,
|
||||||
|
token: VerificationToken<StateStarted>,
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
time_stamp: &[u8],
|
||||||
|
) -> Result<(), VerificationErrorWithToken<E, StateStarted>> {
|
||||||
|
self.reporter.completion_success(
|
||||||
|
self.source_data_buf.as_mut_slice(),
|
||||||
|
token,
|
||||||
|
sender,
|
||||||
|
time_stamp,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Package and send a PUS TM\[1, 8\] packet, see 8.1.2.8 of the PUS standard.
|
||||||
|
///
|
||||||
|
/// Requires a token previously acquired by calling [Self::start_success]. It consumes the
|
||||||
|
/// token because verification handling is done.
|
||||||
|
pub fn completion_failure<E>(
|
||||||
|
&mut self,
|
||||||
|
token: VerificationToken<StateStarted>,
|
||||||
|
sender: &mut (impl EcssTmSender<E> + ?Sized),
|
||||||
|
params: FailParams,
|
||||||
|
) -> Result<(), VerificationErrorWithToken<E, StateStarted>> {
|
||||||
|
self.reporter.completion_failure(
|
||||||
|
self.source_data_buf.as_mut_slice(),
|
||||||
|
token,
|
||||||
|
sender,
|
||||||
|
params,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper object which caches the sender passed as a trait object. Provides the same
|
||||||
|
/// API as [VerificationReporter] but without the explicit sender arguments.
|
||||||
|
pub struct VerificationReporterWithSender<E> {
|
||||||
|
pub reporter: VerificationReporter,
|
||||||
|
pub sender: Box<dyn EcssTmSender<E>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: 'static> VerificationReporterWithSender<E> {
|
||||||
|
pub fn new(cfg: VerificationReporterCfg, sender: Box<dyn EcssTmSender<E>>) -> Self {
|
||||||
|
let reporter = VerificationReporter::new(cfg);
|
||||||
|
Self::new_from_reporter(reporter, sender)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_from_reporter(
|
pub fn new_from_reporter(
|
||||||
reporter: VerificationReporter,
|
reporter: VerificationReporter,
|
||||||
sender: Box<dyn VerificationSender<E>>,
|
sender: Box<dyn EcssTmSender<E>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { reporter, sender }
|
Self { reporter, sender }
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate! {
|
delegate! {
|
||||||
to self.reporter {
|
to self.reporter {
|
||||||
|
pub fn set_apid(&mut self, apid: u16) -> bool;
|
||||||
|
pub fn apid(&self) -> u16;
|
||||||
pub fn add_tc(&mut self, pus_tc: &PusTc) -> VerificationToken<StateNone>;
|
pub fn add_tc(&mut self, pus_tc: &PusTc) -> VerificationToken<StateNone>;
|
||||||
pub fn add_tc_with_req_id(&mut self, req_id: RequestId) -> VerificationToken<StateNone>;
|
pub fn add_tc_with_req_id(&mut self, req_id: RequestId) -> VerificationToken<StateNone>;
|
||||||
|
pub fn dest_id(&self) -> u16;
|
||||||
|
pub fn set_dest_id(&mut self, dest_id: u16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,7 +830,8 @@ impl<E: 'static> VerificationReporterWithSender<E> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
token: VerificationToken<StateNone>,
|
token: VerificationToken<StateNone>,
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
) -> Result<VerificationToken<StateAccepted>, VerificationErrorWithToken<E, StateNone>> {
|
) -> Result<VerificationToken<StateAccepted>, VerificationErrorWithToken<E, StateNone>>
|
||||||
|
{
|
||||||
self.reporter
|
self.reporter
|
||||||
.acceptance_success(token, self.sender.as_mut(), time_stamp)
|
.acceptance_success(token, self.sender.as_mut(), time_stamp)
|
||||||
}
|
}
|
||||||
@ -670,7 +849,8 @@ impl<E: 'static> VerificationReporterWithSender<E> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
token: VerificationToken<StateAccepted>,
|
token: VerificationToken<StateAccepted>,
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
) -> Result<VerificationToken<StateStarted>, VerificationErrorWithToken<E, StateAccepted>> {
|
) -> Result<VerificationToken<StateStarted>, VerificationErrorWithToken<E, StateAccepted>>
|
||||||
|
{
|
||||||
self.reporter
|
self.reporter
|
||||||
.start_success(token, self.sender.as_mut(), time_stamp)
|
.start_success(token, self.sender.as_mut(), time_stamp)
|
||||||
}
|
}
|
||||||
@ -689,7 +869,7 @@ impl<E: 'static> VerificationReporterWithSender<E> {
|
|||||||
token: &VerificationToken<StateStarted>,
|
token: &VerificationToken<StateStarted>,
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
step: impl EcssEnumeration,
|
step: impl EcssEnumeration,
|
||||||
) -> Result<(), VerificationError<E>> {
|
) -> Result<(), EcssTmError<E>> {
|
||||||
self.reporter
|
self.reporter
|
||||||
.step_success(token, self.sender.as_mut(), time_stamp, step)
|
.step_success(token, self.sender.as_mut(), time_stamp, step)
|
||||||
}
|
}
|
||||||
@ -720,14 +900,14 @@ impl<E: 'static> VerificationReporterWithSender<E> {
|
|||||||
self.reporter
|
self.reporter
|
||||||
.completion_failure(token, self.sender.as_mut(), params)
|
.completion_failure(token, self.sender.as_mut(), params)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
mod stdmod {
|
mod stdmod {
|
||||||
|
use super::allocmod::VerificationReporterWithSender;
|
||||||
|
use super::*;
|
||||||
use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError};
|
use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError};
|
||||||
use crate::pus::verification::{
|
|
||||||
VerificationError, VerificationReporterWithSender, VerificationSender,
|
|
||||||
};
|
|
||||||
use delegate::delegate;
|
use delegate::delegate;
|
||||||
use spacepackets::tm::PusTm;
|
use spacepackets::tm::PusTm;
|
||||||
use std::sync::{mpsc, Arc, Mutex, RwLockWriteGuard};
|
use std::sync::{mpsc, Arc, Mutex, RwLockWriteGuard};
|
||||||
@ -748,9 +928,9 @@ mod stdmod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StoreError> for VerificationError<StdVerifSenderError> {
|
impl From<StoreError> for EcssTmError<StdVerifSenderError> {
|
||||||
fn from(e: StoreError) -> Self {
|
fn from(e: StoreError) -> Self {
|
||||||
VerificationError::SendError(e.into())
|
EcssTmError::SendError(e.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,10 +978,10 @@ mod stdmod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//noinspection RsTraitImplementation
|
//noinspection RsTraitImplementation
|
||||||
impl VerificationSender<StdVerifSenderError> for MpscVerifSender {
|
impl EcssTmSender<StdVerifSenderError> for MpscVerifSender {
|
||||||
delegate!(
|
delegate!(
|
||||||
to self.base {
|
to self.base {
|
||||||
fn send_verification_tm(&mut self, tm: PusTm) -> Result<(), VerificationError<StdVerifSenderError>>;
|
fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<StdVerifSenderError>>;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -829,10 +1009,10 @@ mod stdmod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//noinspection RsTraitImplementation
|
//noinspection RsTraitImplementation
|
||||||
impl VerificationSender<StdVerifSenderError> for CrossbeamVerifSender {
|
impl EcssTmSender<StdVerifSenderError> for CrossbeamVerifSender {
|
||||||
delegate!(
|
delegate!(
|
||||||
to self.base {
|
to self.base {
|
||||||
fn send_verification_tm(&mut self, tm: PusTm) -> Result<(), VerificationError<StdVerifSenderError>>;
|
fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<StdVerifSenderError>>;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -840,17 +1020,14 @@ 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> VerificationSender<StdVerifSenderError> for StdSenderBase<S> {
|
impl<S: SendBackend + 'static> EcssTmSender<StdVerifSenderError> for StdSenderBase<S> {
|
||||||
fn send_verification_tm(
|
fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<StdVerifSenderError>> {
|
||||||
&mut self,
|
|
||||||
tm: PusTm,
|
|
||||||
) -> Result<(), VerificationError<StdVerifSenderError>> {
|
|
||||||
let operation = |mut mg: RwLockWriteGuard<ShareablePoolProvider>| {
|
let operation = |mut mg: RwLockWriteGuard<ShareablePoolProvider>| {
|
||||||
let (addr, buf) = mg.free_element(tm.len_packed())?;
|
let (addr, buf) = mg.free_element(tm.len_packed())?;
|
||||||
tm.write_to(buf).map_err(VerificationError::PusError)?;
|
tm.write_to_bytes(buf).map_err(EcssTmError::PusError)?;
|
||||||
drop(mg);
|
drop(mg);
|
||||||
self.tx.send(addr).map_err(|_| {
|
self.tx.send(addr).map_err(|_| {
|
||||||
VerificationError::SendError(StdVerifSenderError::RxDisconnected(addr))
|
EcssTmError::SendError(StdVerifSenderError::RxDisconnected(addr))
|
||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
@ -860,9 +1037,7 @@ mod stdmod {
|
|||||||
if self.ignore_poison_error {
|
if self.ignore_poison_error {
|
||||||
operation(poison_error.into_inner())
|
operation(poison_error.into_inner())
|
||||||
} else {
|
} else {
|
||||||
Err(VerificationError::SendError(
|
Err(EcssTmError::SendError(StdVerifSenderError::PoisonError))
|
||||||
StdVerifSenderError::PoisonError,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -873,9 +1048,9 @@ mod stdmod {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::pus::verification::{
|
use crate::pus::verification::{
|
||||||
FailParams, FailParamsWithStep, RequestId, StateNone, VerificationError,
|
EcssTmError, EcssTmSender, FailParams, FailParamsWithStep, RequestId, StateNone,
|
||||||
VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender,
|
VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender,
|
||||||
VerificationSender, VerificationToken,
|
VerificationToken,
|
||||||
};
|
};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
@ -905,8 +1080,8 @@ mod tests {
|
|||||||
pub service_queue: VecDeque<TmInfo>,
|
pub service_queue: VecDeque<TmInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VerificationSender<()> for TestSender {
|
impl EcssTmSender<()> for TestSender {
|
||||||
fn send_verification_tm(&mut self, tm: PusTm) -> Result<(), VerificationError<()>> {
|
fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<()>> {
|
||||||
assert_eq!(PusPacket::service(&tm), 1);
|
assert_eq!(PusPacket::service(&tm), 1);
|
||||||
assert!(tm.source_data().is_some());
|
assert!(tm.source_data().is_some());
|
||||||
let mut time_stamp = [0; 7];
|
let mut time_stamp = [0; 7];
|
||||||
@ -938,9 +1113,9 @@ mod tests {
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct FallibleSender {}
|
struct FallibleSender {}
|
||||||
|
|
||||||
impl VerificationSender<DummyError> for FallibleSender {
|
impl EcssTmSender<DummyError> for FallibleSender {
|
||||||
fn send_verification_tm(&mut self, _: PusTm) -> Result<(), VerificationError<DummyError>> {
|
fn send_tm(&mut self, _: PusTm) -> Result<(), EcssTmError<DummyError>> {
|
||||||
Err(VerificationError::SendError(DummyError {}))
|
Err(EcssTmError::SendError(DummyError {}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -968,7 +1143,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn base_reporter() -> VerificationReporter {
|
fn base_reporter() -> VerificationReporter {
|
||||||
let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8);
|
let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
|
||||||
VerificationReporter::new(cfg)
|
VerificationReporter::new(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1019,6 +1194,14 @@ mod tests {
|
|||||||
assert_eq!(info, cmp_info);
|
assert_eq!(info, cmp_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_state() {
|
||||||
|
let (mut b, _) = base_init(false);
|
||||||
|
assert_eq!(b.vr.apid(), TEST_APID);
|
||||||
|
b.vr.set_apid(TEST_APID + 1);
|
||||||
|
assert_eq!(b.vr.apid(), TEST_APID + 1);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basic_acceptance_success() {
|
fn test_basic_acceptance_success() {
|
||||||
let (mut b, tok) = base_init(false);
|
let (mut b, tok) = base_init(false);
|
||||||
@ -1048,7 +1231,7 @@ mod tests {
|
|||||||
let err = res.unwrap_err();
|
let err = res.unwrap_err();
|
||||||
assert_eq!(err.1, tok);
|
assert_eq!(err.1, tok);
|
||||||
match err.0 {
|
match err.0 {
|
||||||
VerificationError::SendError(e) => {
|
EcssTmError::SendError(e) => {
|
||||||
assert_eq!(e, DummyError {})
|
assert_eq!(e, DummyError {})
|
||||||
}
|
}
|
||||||
_ => panic!("{}", format!("Unexpected error {:?}", err.0)),
|
_ => panic!("{}", format!("Unexpected error {:?}", err.0)),
|
||||||
@ -1073,7 +1256,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_basic_acceptance_failure() {
|
fn test_basic_acceptance_failure() {
|
||||||
let (mut b, tok) = base_init(true);
|
let (mut b, tok) = base_init(true);
|
||||||
b.rep().dest_id = 5;
|
b.rep().reporter.dest_id = 5;
|
||||||
let stamp_buf = [1, 2, 3, 4, 5, 6, 7];
|
let stamp_buf = [1, 2, 3, 4, 5, 6, 7];
|
||||||
let mut sender = TestSender::default();
|
let mut sender = TestSender::default();
|
||||||
let fail_code = EcssEnumU16::new(2);
|
let fail_code = EcssEnumU16::new(2);
|
||||||
@ -1086,7 +1269,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_basic_acceptance_failure_with_helper() {
|
fn test_basic_acceptance_failure_with_helper() {
|
||||||
let (mut b, tok) = base_with_helper_init();
|
let (mut b, tok) = base_with_helper_init();
|
||||||
b.rep().dest_id = 5;
|
b.rep().reporter.dest_id = 5;
|
||||||
let stamp_buf = [1, 2, 3, 4, 5, 6, 7];
|
let stamp_buf = [1, 2, 3, 4, 5, 6, 7];
|
||||||
let fail_code = EcssEnumU16::new(2);
|
let fail_code = EcssEnumU16::new(2);
|
||||||
let fail_params = FailParams::new(stamp_buf.as_slice(), &fail_code, None);
|
let fail_params = FailParams::new(stamp_buf.as_slice(), &fail_code, None);
|
||||||
@ -1100,7 +1283,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_acceptance_fail_data_too_large() {
|
fn test_acceptance_fail_data_too_large() {
|
||||||
let (mut b, tok) = base_with_helper_init();
|
let (mut b, tok) = base_with_helper_init();
|
||||||
b.rep().dest_id = 5;
|
b.rep().reporter.dest_id = 5;
|
||||||
let stamp_buf = [1, 2, 3, 4, 5, 6, 7];
|
let stamp_buf = [1, 2, 3, 4, 5, 6, 7];
|
||||||
let fail_code = EcssEnumU16::new(2);
|
let fail_code = EcssEnumU16::new(2);
|
||||||
let fail_data: [u8; 16] = [0; 16];
|
let fail_data: [u8; 16] = [0; 16];
|
||||||
@ -1113,7 +1296,7 @@ mod tests {
|
|||||||
let err_with_token = res.unwrap_err();
|
let err_with_token = res.unwrap_err();
|
||||||
assert_eq!(err_with_token.1, tok);
|
assert_eq!(err_with_token.1, tok);
|
||||||
match err_with_token.0 {
|
match err_with_token.0 {
|
||||||
VerificationError::ByteConversionError(e) => match e {
|
EcssTmError::ByteConversionError(e) => match e {
|
||||||
ByteConversionError::ToSliceTooSmall(missmatch) => {
|
ByteConversionError::ToSliceTooSmall(missmatch) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
missmatch.expected,
|
missmatch.expected,
|
||||||
@ -1138,7 +1321,7 @@ mod tests {
|
|||||||
let fail_code = EcssEnumU8::new(10);
|
let fail_code = EcssEnumU8::new(10);
|
||||||
let fail_data = EcssEnumU32::new(12);
|
let fail_data = EcssEnumU32::new(12);
|
||||||
let mut fail_data_raw = [0; 4];
|
let mut fail_data_raw = [0; 4];
|
||||||
fail_data.to_bytes(&mut fail_data_raw).unwrap();
|
fail_data.write_to_bytes(&mut fail_data_raw).unwrap();
|
||||||
let fail_params = FailParams::new(&EMPTY_STAMP, &fail_code, Some(fail_data_raw.as_slice()));
|
let fail_params = FailParams::new(&EMPTY_STAMP, &fail_code, Some(fail_data_raw.as_slice()));
|
||||||
b.vr.acceptance_failure(tok, &mut sender, fail_params)
|
b.vr.acceptance_failure(tok, &mut sender, fail_params)
|
||||||
.expect("Sending acceptance success failed");
|
.expect("Sending acceptance success failed");
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
//! let mut pus_tc = PusTc::new_simple(&mut space_packet_header, 17, 1, None, true);
|
//! let mut pus_tc = PusTc::new_simple(&mut space_packet_header, 17, 1, None, true);
|
||||||
//! let mut test_buf: [u8; 32] = [0; 32];
|
//! let mut test_buf: [u8; 32] = [0; 32];
|
||||||
//! let mut size = pus_tc
|
//! let mut size = pus_tc
|
||||||
//! .write_to(test_buf.as_mut_slice())
|
//! .write_to_bytes(test_buf.as_mut_slice())
|
||||||
//! .expect("Error writing TC to buffer");
|
//! .expect("Error writing TC to buffer");
|
||||||
//! let tc_slice = &test_buf[0..size];
|
//! let tc_slice = &test_buf[0..size];
|
||||||
//! ccsds_distributor.pass_tc(&tc_slice).expect("Passing TC slice failed");
|
//! ccsds_distributor.pass_tc(&tc_slice).expect("Passing TC slice failed");
|
||||||
@ -66,7 +66,7 @@
|
|||||||
//! // Now pass a packet with an unknown APID to the distributor
|
//! // Now pass a packet with an unknown APID to the distributor
|
||||||
//! pus_tc.set_apid(0x003);
|
//! pus_tc.set_apid(0x003);
|
||||||
//! size = pus_tc
|
//! size = pus_tc
|
||||||
//! .write_to(test_buf.as_mut_slice())
|
//! .write_to_bytes(test_buf.as_mut_slice())
|
||||||
//! .expect("Error writing TC to buffer");
|
//! .expect("Error writing TC to buffer");
|
||||||
//! let tc_slice = &test_buf[0..size];
|
//! let tc_slice = &test_buf[0..size];
|
||||||
//! ccsds_distributor.pass_tc(&tc_slice).expect("Passing TC slice failed");
|
//! ccsds_distributor.pass_tc(&tc_slice).expect("Passing TC slice failed");
|
||||||
@ -201,7 +201,9 @@ pub(crate) mod tests {
|
|||||||
pub fn generate_ping_tc(buf: &mut [u8]) -> &[u8] {
|
pub fn generate_ping_tc(buf: &mut [u8]) -> &[u8] {
|
||||||
let mut sph = SpHeader::tc(0x002, 0x34, 0).unwrap();
|
let mut sph = SpHeader::tc(0x002, 0x34, 0).unwrap();
|
||||||
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
||||||
let size = pus_tc.write_to(buf).expect("Error writing TC to buffer");
|
let size = pus_tc
|
||||||
|
.write_to_bytes(buf)
|
||||||
|
.expect("Error writing TC to buffer");
|
||||||
assert_eq!(size, 13);
|
assert_eq!(size, 13);
|
||||||
&buf[0..size]
|
&buf[0..size]
|
||||||
}
|
}
|
||||||
@ -314,7 +316,7 @@ pub(crate) mod tests {
|
|||||||
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
|
||||||
let mut test_buf: [u8; 32] = [0; 32];
|
let mut test_buf: [u8; 32] = [0; 32];
|
||||||
pus_tc
|
pus_tc
|
||||||
.write_to(test_buf.as_mut_slice())
|
.write_to_bytes(test_buf.as_mut_slice())
|
||||||
.expect("Error writing TC to buffer");
|
.expect("Error writing TC to buffer");
|
||||||
ccsds_distrib.pass_tc(&test_buf).expect("Passing TC failed");
|
ccsds_distrib.pass_tc(&test_buf).expect("Passing TC failed");
|
||||||
let recvd = unknown_packet_queue.lock().unwrap().pop_front();
|
let recvd = unknown_packet_queue.lock().unwrap().pop_front();
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
//! let mut pus_tc = PusTc::new_simple(&mut space_packet_header, 17, 1, None, true);
|
//! let mut pus_tc = PusTc::new_simple(&mut space_packet_header, 17, 1, None, true);
|
||||||
//! let mut test_buf: [u8; 32] = [0; 32];
|
//! let mut test_buf: [u8; 32] = [0; 32];
|
||||||
//! let mut size = pus_tc
|
//! let mut size = pus_tc
|
||||||
//! .write_to(test_buf.as_mut_slice())
|
//! .write_to_bytes(test_buf.as_mut_slice())
|
||||||
//! .expect("Error writing TC to buffer");
|
//! .expect("Error writing TC to buffer");
|
||||||
//! let tc_slice = &test_buf[0..size];
|
//! let tc_slice = &test_buf[0..size];
|
||||||
//!
|
//!
|
||||||
|
@ -25,7 +25,7 @@ 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);
|
let cfg = VerificationReporterCfg::new(TEST_APID, 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 =
|
||||||
@ -53,14 +53,14 @@ fn test_shared_reporter() {
|
|||||||
let pus_tc_0 = PusTc::new(&mut sph, tc_header, None, true);
|
let pus_tc_0 = PusTc::new(&mut sph, tc_header, None, true);
|
||||||
req_id_0 = RequestId::new(&pus_tc_0);
|
req_id_0 = RequestId::new(&pus_tc_0);
|
||||||
let (addr, mut buf) = tc_guard.free_element(pus_tc_0.len_packed()).unwrap();
|
let (addr, mut buf) = tc_guard.free_element(pus_tc_0.len_packed()).unwrap();
|
||||||
pus_tc_0.write_to(&mut buf).unwrap();
|
pus_tc_0.write_to_bytes(&mut buf).unwrap();
|
||||||
tx_tc_0.send(addr).unwrap();
|
tx_tc_0.send(addr).unwrap();
|
||||||
let mut sph = SpHeader::tc(TEST_APID, 1, 0).unwrap();
|
let mut sph = SpHeader::tc(TEST_APID, 1, 0).unwrap();
|
||||||
let tc_header = PusTcSecondaryHeader::new_simple(5, 1);
|
let tc_header = PusTcSecondaryHeader::new_simple(5, 1);
|
||||||
let pus_tc_1 = PusTc::new(&mut sph, tc_header, None, true);
|
let pus_tc_1 = PusTc::new(&mut sph, tc_header, None, true);
|
||||||
req_id_1 = RequestId::new(&pus_tc_1);
|
req_id_1 = RequestId::new(&pus_tc_1);
|
||||||
let (addr, mut buf) = tc_guard.free_element(pus_tc_0.len_packed()).unwrap();
|
let (addr, mut buf) = tc_guard.free_element(pus_tc_0.len_packed()).unwrap();
|
||||||
pus_tc_1.write_to(&mut buf).unwrap();
|
pus_tc_1.write_to_bytes(&mut buf).unwrap();
|
||||||
tx_tc_1.send(addr).unwrap();
|
tx_tc_1.send(addr).unwrap();
|
||||||
}
|
}
|
||||||
let verif_sender_0 = thread::spawn(move || {
|
let verif_sender_0 = thread::spawn(move || {
|
||||||
|
@ -18,7 +18,9 @@ fn main() {
|
|||||||
"Packing and sending PUS ping command TC[17,1] with request ID {}",
|
"Packing and sending PUS ping command TC[17,1] with request ID {}",
|
||||||
tc_req_id
|
tc_req_id
|
||||||
);
|
);
|
||||||
let size = pus_tc.write_to(&mut buf).expect("Creating PUS TC failed");
|
let size = pus_tc
|
||||||
|
.write_to_bytes(&mut buf)
|
||||||
|
.expect("Creating PUS TC failed");
|
||||||
client
|
client
|
||||||
.send_to(&buf[0..size], &addr)
|
.send_to(&buf[0..size], &addr)
|
||||||
.expect(&*format!("Sending to {:?} failed", addr));
|
.expect(&*format!("Sending to {:?} failed", addr));
|
||||||
|
@ -39,7 +39,7 @@ fn main() {
|
|||||||
let (tm_funnel_tx, tm_funnel_rx) = mpsc::channel();
|
let (tm_funnel_tx, tm_funnel_rx) = mpsc::channel();
|
||||||
let (tm_server_tx, tm_server_rx) = mpsc::channel();
|
let (tm_server_tx, tm_server_rx) = mpsc::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);
|
let verif_cfg = VerificationReporterCfg::new(PUS_APID, 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),
|
||||||
|
@ -24,7 +24,7 @@ impl TmStore {
|
|||||||
let mut pg = self.pool.write().expect("Error locking TM store");
|
let mut pg = self.pool.write().expect("Error locking TM store");
|
||||||
let (addr, buf) = pg.free_element(pus_tm.len_packed()).expect("Store error");
|
let (addr, buf) = pg.free_element(pus_tm.len_packed()).expect("Store error");
|
||||||
pus_tm
|
pus_tm
|
||||||
.write_to(buf)
|
.write_to_bytes(buf)
|
||||||
.expect("Writing PUS TM to store failed");
|
.expect("Writing PUS TM to store failed");
|
||||||
addr
|
addr
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 94489da00323dc6caf24e05e240c80fc10b5d8cc
|
Subproject commit fe1a30327bcc9a914cd2695b6af74b869a8b23a2
|
Loading…
Reference in New Issue
Block a user