dyn-clone also requires alloc..
This commit is contained in:
parent
1fcc8d3f57
commit
f8cd28c4f5
@ -8,9 +8,12 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
delegate = "0.8"
|
delegate = "0.8"
|
||||||
paste = "1.0"
|
paste = "1.0"
|
||||||
dyn-clone = "1.0"
|
|
||||||
embed-doc-image = "0.1"
|
embed-doc-image = "0.1"
|
||||||
|
|
||||||
|
[dependencies.dyn-clone]
|
||||||
|
version = "1.0"
|
||||||
|
optional = true
|
||||||
|
|
||||||
[dependencies.hashbrown]
|
[dependencies.hashbrown]
|
||||||
version = "0.13"
|
version = "0.13"
|
||||||
optional = true
|
optional = true
|
||||||
@ -58,7 +61,7 @@ version = "1.0"
|
|||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
std = ["downcast-rs/std", "alloc", "bus", "postcard/use-std", "crossbeam-channel/std", "serde/std", "spacepackets/std"]
|
std = ["downcast-rs/std", "alloc", "bus", "postcard/use-std", "crossbeam-channel/std", "serde/std", "spacepackets/std"]
|
||||||
alloc = ["serde/alloc", "spacepackets/alloc", "hashbrown"]
|
alloc = ["serde/alloc", "spacepackets/alloc", "hashbrown", "dyn-clone"]
|
||||||
serde = ["dep:serde", "spacepackets/serde"]
|
serde = ["dep:serde", "spacepackets/serde"]
|
||||||
crossbeam = ["crossbeam-channel"]
|
crossbeam = ["crossbeam-channel"]
|
||||||
heapless = ["dep:heapless"]
|
heapless = ["dep:heapless"]
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
use crate::pus::{source_buffer_large_enough, EcssTmError, EcssTmSender};
|
use crate::pus::{source_buffer_large_enough, EcssTmError};
|
||||||
use spacepackets::ecss::EcssEnumeration;
|
use spacepackets::ecss::EcssEnumeration;
|
||||||
use spacepackets::tm::PusTm;
|
use spacepackets::tm::PusTm;
|
||||||
use spacepackets::tm::PusTmSecondaryHeader;
|
use spacepackets::tm::PusTmSecondaryHeader;
|
||||||
use spacepackets::{SpHeader, MAX_APID};
|
use spacepackets::{SpHeader, MAX_APID};
|
||||||
|
|
||||||
|
use crate::pus::EcssTmSender;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub use allocvec::EventReporter;
|
pub use allocvec::EventReporter;
|
||||||
|
|
||||||
|
@ -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};
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
use dyn_clone::DynClone;
|
use dyn_clone::DynClone;
|
||||||
use spacepackets::ecss::PusError;
|
use spacepackets::ecss::PusError;
|
||||||
use spacepackets::time::TimestampError;
|
use spacepackets::time::TimestampError;
|
||||||
@ -45,14 +46,22 @@ 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 + DynClone {
|
pub trait EcssTmSender: Downcast + Send {
|
||||||
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>);
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
pub mod alloc_mod {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub trait EcssTmSenderClonable: EcssTmSender + Downcast + DynClone {}
|
||||||
|
dyn_clone::clone_trait_object!(<T> EcssTmSenderClonable<Error=T>);
|
||||||
|
impl_downcast!(EcssTmSenderClonable assoc Error);
|
||||||
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
@ -664,6 +664,8 @@ impl VerificationReporterBasic {
|
|||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
mod alloc_mod {
|
mod alloc_mod {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::pus::alloc_mod::EcssTmSenderClonable;
|
||||||
|
use crate::seq_count::SequenceCountProviderClonable;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
@ -671,7 +673,7 @@ mod alloc_mod {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct VerificationReporterCfg {
|
pub struct VerificationReporterCfg {
|
||||||
apid: u16,
|
apid: u16,
|
||||||
seq_counter: Box<dyn SequenceCountProvider<u16> + Send>,
|
seq_counter: Box<dyn SequenceCountProviderClonable<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,
|
||||||
@ -680,7 +682,7 @@ mod alloc_mod {
|
|||||||
impl VerificationReporterCfg {
|
impl VerificationReporterCfg {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
apid: u16,
|
apid: u16,
|
||||||
seq_counter: Box<dyn SequenceCountProvider<u16> + Send>,
|
seq_counter: Box<dyn SequenceCountProviderClonable<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,
|
||||||
@ -703,7 +705,7 @@ mod alloc_mod {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct VerificationReporterWithBuf {
|
pub struct VerificationReporterWithBuf {
|
||||||
source_data_buf: Vec<u8>,
|
source_data_buf: Vec<u8>,
|
||||||
seq_counter: Box<dyn SequenceCountProvider<u16> + Send + 'static>,
|
seq_counter: Box<dyn SequenceCountProviderClonable<u16> + Send + 'static>,
|
||||||
pub reporter: VerificationReporterBasic,
|
pub reporter: VerificationReporterBasic,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -892,13 +894,13 @@ mod alloc_mod {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct VerificationReporterWithSender<E> {
|
pub struct VerificationReporterWithSender<E> {
|
||||||
pub reporter: VerificationReporterWithBuf,
|
pub reporter: VerificationReporterWithBuf,
|
||||||
pub sender: Box<dyn EcssTmSender<Error = E>>,
|
pub sender: Box<dyn EcssTmSenderClonable<Error = E>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: 'static> VerificationReporterWithSender<E> {
|
impl<E: 'static> VerificationReporterWithSender<E> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
cfg: &VerificationReporterCfg,
|
cfg: &VerificationReporterCfg,
|
||||||
sender: Box<dyn EcssTmSender<Error = E>>,
|
sender: Box<dyn EcssTmSenderClonable<Error = E>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let reporter = VerificationReporterWithBuf::new(cfg);
|
let reporter = VerificationReporterWithBuf::new(cfg);
|
||||||
Self::new_from_reporter(reporter, sender)
|
Self::new_from_reporter(reporter, sender)
|
||||||
@ -906,7 +908,7 @@ mod alloc_mod {
|
|||||||
|
|
||||||
pub fn new_from_reporter(
|
pub fn new_from_reporter(
|
||||||
reporter: VerificationReporterWithBuf,
|
reporter: VerificationReporterWithBuf,
|
||||||
sender: Box<dyn EcssTmSender<Error = E>>,
|
sender: Box<dyn EcssTmSenderClonable<Error = E>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { reporter, sender }
|
Self { reporter, sender }
|
||||||
}
|
}
|
||||||
@ -1004,6 +1006,7 @@ mod stdmod {
|
|||||||
use super::alloc_mod::VerificationReporterWithSender;
|
use super::alloc_mod::VerificationReporterWithSender;
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError};
|
use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError};
|
||||||
|
use crate::pus::alloc_mod::EcssTmSenderClonable;
|
||||||
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};
|
||||||
@ -1085,8 +1088,8 @@ mod stdmod {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
unsafe impl Sync for MpscVerifSender {}
|
|
||||||
unsafe impl Send for MpscVerifSender {}
|
impl EcssTmSenderClonable for MpscVerifSender {}
|
||||||
|
|
||||||
impl SendBackend for crossbeam_channel::Sender<StoreAddr> {
|
impl SendBackend for crossbeam_channel::Sender<StoreAddr> {
|
||||||
fn send(&self, addr: StoreAddr) -> Result<(), StoreAddr> {
|
fn send(&self, addr: StoreAddr) -> Result<(), StoreAddr> {
|
||||||
@ -1123,11 +1126,8 @@ mod stdmod {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Are those really necessary? Check with test..
|
|
||||||
#[cfg(feature = "crossbeam")]
|
#[cfg(feature = "crossbeam")]
|
||||||
unsafe impl Sync for CrossbeamVerifSender {}
|
impl EcssTmSenderClonable for CrossbeamVerifSender {}
|
||||||
#[cfg(feature = "crossbeam")]
|
|
||||||
unsafe impl Send for CrossbeamVerifSender {}
|
|
||||||
|
|
||||||
impl<S: SendBackend + Clone + 'static> EcssTmSender for StdSenderBase<S> {
|
impl<S: SendBackend + Clone + 'static> EcssTmSender for StdSenderBase<S> {
|
||||||
type Error = StdVerifSenderError;
|
type Error = StdVerifSenderError;
|
||||||
@ -1157,11 +1157,13 @@ mod stdmod {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::pool::{LocalPool, PoolCfg, SharedPool};
|
||||||
|
use crate::pus::alloc_mod::EcssTmSenderClonable;
|
||||||
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, MpscVerifSender, RequestId,
|
||||||
VerificationReporterCfg, VerificationReporterWithBuf, VerificationReporterWithSender,
|
TcStateNone, VerificationReporterCfg, VerificationReporterWithBuf,
|
||||||
VerificationToken,
|
VerificationReporterWithSender, VerificationToken,
|
||||||
};
|
};
|
||||||
use crate::seq_count::SimpleSeqCountProvider;
|
use crate::seq_count::SimpleSeqCountProvider;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
@ -1171,8 +1173,14 @@ mod tests {
|
|||||||
use spacepackets::tm::PusTm;
|
use spacepackets::tm::PusTm;
|
||||||
use spacepackets::{ByteConversionError, SpHeader};
|
use spacepackets::{ByteConversionError, SpHeader};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
use std::sync::{mpsc, Arc, RwLock};
|
||||||
|
use std::vec;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
|
fn is_send<T: Send>(_: &T) {}
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn is_sync<T: Sync>(_: &T) {}
|
||||||
|
|
||||||
const TEST_APID: u16 = 0x02;
|
const TEST_APID: u16 = 0x02;
|
||||||
const EMPTY_STAMP: [u8; 7] = [0; 7];
|
const EMPTY_STAMP: [u8; 7] = [0; 7];
|
||||||
|
|
||||||
@ -1213,6 +1221,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EcssTmSenderClonable for TestSender {}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
struct DummyError {}
|
struct DummyError {}
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
@ -1225,6 +1235,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EcssTmSenderClonable for FallibleSender {}
|
||||||
|
|
||||||
struct TestBase<'a> {
|
struct TestBase<'a> {
|
||||||
vr: VerificationReporterWithBuf,
|
vr: VerificationReporterWithBuf,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -1309,6 +1321,15 @@ mod tests {
|
|||||||
assert_eq!(info, cmp_info);
|
assert_eq!(info, cmp_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mpsc_verif_send_sync() {
|
||||||
|
let pool = LocalPool::new(PoolCfg::new(vec![(8, 8)]));
|
||||||
|
let shared_pool: SharedPool = Arc::new(RwLock::new(Box::new(pool)));
|
||||||
|
let (tx, _) = mpsc::channel();
|
||||||
|
let mpsc_verif_sender = MpscVerifSender::new(shared_pool, tx);
|
||||||
|
is_send(&mpsc_verif_sender);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_state() {
|
fn test_state() {
|
||||||
let (mut b, _) = base_init(false);
|
let (mut b, _) = base_init(false);
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
#[cfg(feature = "alloc")]
|
||||||
use dyn_clone::DynClone;
|
use dyn_clone::DynClone;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use stdmod::*;
|
pub use stdmod::*;
|
||||||
|
|
||||||
pub trait SequenceCountProvider<Raw>: DynClone {
|
pub trait SequenceCountProvider<Raw> {
|
||||||
fn get(&self) -> Raw;
|
fn get(&self) -> Raw;
|
||||||
fn increment(&mut self);
|
fn increment(&mut self);
|
||||||
fn get_and_increment(&mut self) -> Raw {
|
fn get_and_increment(&mut self) -> Raw {
|
||||||
@ -12,13 +13,16 @@ pub trait SequenceCountProvider<Raw>: DynClone {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
pub trait SequenceCountProviderClonable<Raw>: SequenceCountProvider<Raw> + DynClone {}
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
dyn_clone::clone_trait_object!(SequenceCountProviderClonable<u16>);
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct SimpleSeqCountProvider {
|
pub struct SimpleSeqCountProvider {
|
||||||
seq_count: u16,
|
seq_count: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
dyn_clone::clone_trait_object!(SequenceCountProvider<u16>);
|
|
||||||
|
|
||||||
impl SequenceCountProvider<u16> for SimpleSeqCountProvider {
|
impl SequenceCountProvider<u16> for SimpleSeqCountProvider {
|
||||||
fn get(&self) -> u16 {
|
fn get(&self) -> u16 {
|
||||||
self.seq_count
|
self.seq_count
|
||||||
@ -33,6 +37,9 @@ impl SequenceCountProvider<u16> for SimpleSeqCountProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
impl SequenceCountProviderClonable<u16> for SimpleSeqCountProvider {}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub mod stdmod {
|
pub mod stdmod {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -57,4 +64,6 @@ pub mod stdmod {
|
|||||||
self.seq_count.fetch_add(1, Ordering::SeqCst)
|
self.seq_count.fetch_add(1, Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SequenceCountProviderClonable<u16> for SyncSeqCountProvider {}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user