This commit is contained in:
2022-12-30 23:10:06 +01:00
11 changed files with 369 additions and 87 deletions

View File

@ -89,6 +89,14 @@ impl<E: PartialEq> PartialEq for ReceiveResult<E> {
impl<E: Eq + PartialEq> Eq for ReceiveResult<E> {}
impl<E: 'static> ReceivesTc for UdpTcServer<E> {
type Error = E;
fn pass_tc(&mut self, tc_raw: &[u8]) -> Result<(), Self::Error> {
self.tc_receiver.pass_tc(tc_raw)
}
}
impl<E: 'static> UdpTcServer<E> {
pub fn new<A: ToSocketAddrs>(
addr: A,
@ -140,6 +148,8 @@ mod tests {
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
use std::vec::Vec;
fn is_send<T: Send>(_: &T) {}
#[derive(Default)]
struct PingReceiver {
pub sent_cmds: VecDeque<Vec<u8>>,
@ -161,8 +171,10 @@ mod tests {
let mut buf = [0; 32];
let dest_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7777);
let ping_receiver = PingReceiver::default();
is_send(&ping_receiver);
let mut udp_tc_server = UdpTcServer::new(dest_addr, 2048, Box::new(ping_receiver))
.expect("Creating UDP TMTC server failed");
is_send(&udp_tc_server);
let mut sph = SpHeader::tc_unseg(0x02, 0, 0).unwrap();
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
let len = pus_tc

View File

@ -77,10 +77,13 @@ use alloc::format;
use alloc::string::String;
use alloc::vec;
use alloc::vec::Vec;
use core::fmt::{Display, Formatter};
use delegate::delegate;
#[cfg(feature = "std")]
use std::boxed::Box;
#[cfg(feature = "std")]
use std::error::Error;
#[cfg(feature = "std")]
use std::sync::{Arc, RwLock};
type NumBlocks = u16;
@ -146,6 +149,22 @@ pub enum StoreIdError {
InvalidPacketIdx(u16),
}
impl Display for StoreIdError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
StoreIdError::InvalidSubpool(pool) => {
write!(f, "invalid subpool, index: {}", pool)
}
StoreIdError::InvalidPacketIdx(packet_idx) => {
write!(f, "invalid packet index: {}", packet_idx)
}
}
}
}
#[cfg(feature = "std")]
impl Error for StoreIdError {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum StoreError {
/// Requested data block is too large
@ -160,6 +179,38 @@ pub enum StoreError {
InternalError(String),
}
impl Display for StoreError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
StoreError::DataTooLarge(size) => {
write!(f, "data to store with size {} is too large", size)
}
StoreError::StoreFull(u16) => {
write!(f, "store is too full. index for full subpool: {}", u16)
}
StoreError::InvalidStoreId(id_e, addr) => {
write!(f, "invalid store ID: {}, address: {:?}", id_e, addr)
}
StoreError::DataDoesNotExist(addr) => {
write!(f, "no data exists at address {:?}", addr)
}
StoreError::InternalError(e) => {
write!(f, "internal error: {}", e)
}
}
}
}
#[cfg(feature = "std")]
impl Error for StoreError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
if let StoreError::InvalidStoreId(e, _) = self {
return Some(e);
}
None
}
}
pub trait PoolProvider {
/// Add new data to the pool. The provider should attempt to reserve a memory block with the
/// appropriate size and then copy the given data to the block. Yields a [StoreAddr] which can

View File

@ -99,7 +99,7 @@ use spacepackets::{ByteConversionError, CcsdsPacket, SizeMissmatch, SpHeader};
/// This trait automatically implements the [downcast_rs::Downcast] to allow a more convenient API
/// to cast trait objects back to their concrete type after the handler was passed to the
/// distributor.
pub trait CcsdsPacketHandler: Downcast {
pub trait CcsdsPacketHandler: Downcast + Send {
type Error;
fn valid_apids(&self) -> &'static [u16];
@ -199,6 +199,8 @@ pub(crate) mod tests {
use std::sync::{Arc, Mutex};
use std::vec::Vec;
fn is_send<T: Send>(_: &T) {}
pub fn generate_ping_tc(buf: &mut [u8]) -> &[u8] {
let mut sph = SpHeader::tc_unseg(0x002, 0x34, 0).unwrap();
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
@ -292,6 +294,7 @@ pub(crate) mod tests {
unknown_packet_queue: unknown_packet_queue.clone(),
};
let mut ccsds_distrib = CcsdsDistributor::new(Box::new(apid_handler));
is_send(&ccsds_distrib);
let mut test_buf: [u8; 32] = [0; 32];
let tc_slice = generate_ping_tc(test_buf.as_mut_slice());

View File

@ -42,6 +42,18 @@ impl AddressableId {
unique_id: u32::from_be_bytes(buf[4..8].try_into().unwrap()),
})
}
pub fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> {
if buf.len() < 8 {
return Err(ByteConversionError::ToSliceTooSmall(SizeMissmatch {
found: buf.len(),
expected: 8,
}));
}
buf[0..4].copy_from_slice(&self.target_id.to_be_bytes());
buf[4..8].copy_from_slice(&self.unique_id.to_be_bytes());
Ok(8)
}
}
/// Generic trait for object which can receive any telecommands in form of a raw bytestream, with
@ -50,7 +62,7 @@ impl AddressableId {
/// This trait is implemented by both the [crate::tmtc::pus_distrib::PusDistributor] and the
/// [crate::tmtc::ccsds_distrib::CcsdsDistributor] which allows to pass the respective packets in
/// raw byte format into them.
pub trait ReceivesTc: Downcast {
pub trait ReceivesTc: Downcast + Send {
type Error;
fn pass_tc(&mut self, tc_raw: &[u8]) -> Result<(), Self::Error>;
}

View File

@ -67,7 +67,7 @@ use spacepackets::ecss::{PusError, PusPacket};
use spacepackets::tc::PusTc;
use spacepackets::SpHeader;
pub trait PusServiceProvider: Downcast {
pub trait PusServiceProvider: Downcast + Send {
type Error;
fn handle_pus_tc_packet(
&mut self,
@ -147,6 +147,8 @@ mod tests {
#[cfg(feature = "std")]
use std::sync::{Arc, Mutex};
fn is_send<T: Send>(_: &T) {}
struct PusHandlerSharedQueue {
pub pus_queue: Arc<Mutex<VecDeque<(u8, u16, Vec<u8>)>>>,
}
@ -263,7 +265,7 @@ mod tests {
let pus_distrib = PusDistributor {
service_provider: Box::new(pus_handler),
};
is_send(&pus_distrib);
let apid_handler = ApidHandlerShared {
pus_distrib,
handler_base,