Merge remote-tracking branch 'origin/main' into tricky-pus-abstraction-changes
All checks were successful
Rust/sat-rs/pipeline/head This commit looks good

This commit is contained in:
2024-01-31 12:09:55 +01:00
17 changed files with 232 additions and 164 deletions

View File

@ -1,6 +1,6 @@
use crate::events::EventU32;
use crate::pus::event_man::{EventRequest, EventRequestWithToken};
use crate::pus::verification::{StdVerifReporterWithSender, TcStateToken};
use crate::pus::verification::TcStateToken;
use crate::pus::{
EcssTcReceiver, EcssTmSender, PartialPusHandlingError, PusPacketHandlerResult,
PusPacketHandlingError,
@ -10,6 +10,7 @@ use spacepackets::ecss::event::Subservice;
use spacepackets::ecss::PusPacket;
use std::sync::mpsc::Sender;
use super::verification::VerificationReporterWithSender;
use super::{EcssTcInMemConverter, PusServiceBase, PusServiceHandler};
pub struct PusService5EventHandler<TcInMemConverter: EcssTcInMemConverter> {
@ -22,9 +23,9 @@ impl<TcInMemConverter: EcssTcInMemConverter> PusService5EventHandler<TcInMemConv
tc_receiver: Box<dyn EcssTcReceiver>,
tm_sender: Box<dyn EcssTmSender>,
tm_apid: u16,
verification_handler: StdVerifReporterWithSender,
event_request_tx: Sender<EventRequestWithToken>,
verification_handler: VerificationReporterWithSender,
tc_in_mem_converter: TcInMemConverter,
event_request_tx: Sender<EventRequestWithToken>,
) -> Self {
Self {
psb: PusServiceHandler::new(

View File

@ -646,6 +646,8 @@ pub mod std_mod {
InvalidSubservice(u8),
#[error("not enough application data available: {0}")]
NotEnoughAppData(String),
#[error("PUS packet too large, does not fit in buffer: {0}")]
PusPacketTooLarge(usize),
#[error("invalid application data")]
InvalidAppData(String),
#[error("invalid format of TC in memory: {0:?}")]
@ -687,12 +689,20 @@ pub mod std_mod {
}
pub trait EcssTcInMemConverter {
fn cache_ecss_tc_in_memory<'a>(
&'a mut self,
possible_packet: &'a AcceptedEcssTcAndToken,
) -> Result<(), PusPacketHandlingError>;
fn tc_slice_raw(&self) -> &[u8];
fn convert_ecss_tc_in_memory_to_reader<'a>(
&'a mut self,
possible_packet: &'a AcceptedEcssTcAndToken,
) -> Result<PusTcReader<'a>, PusPacketHandlingError>;
fn tc_slice_raw(&self) -> &[u8];
) -> Result<PusTcReader<'a>, PusPacketHandlingError> {
self.cache_ecss_tc_in_memory(possible_packet)?;
Ok(PusTcReader::new(self.tc_slice_raw())?.0)
}
}
pub struct EcssTcInVecConverter {
@ -700,10 +710,11 @@ pub mod std_mod {
}
impl EcssTcInMemConverter for EcssTcInVecConverter {
fn convert_ecss_tc_in_memory_to_reader<'a>(
fn cache_ecss_tc_in_memory<'a>(
&'a mut self,
possible_packet: &'a AcceptedEcssTcAndToken,
) -> Result<PusTcReader<'a>, PusPacketHandlingError> {
) -> Result<(), PusPacketHandlingError> {
self.pus_tc_raw = None;
match &possible_packet.tc_in_memory {
super::TcInMemory::StoreAddr(_) => {
return Err(PusPacketHandlingError::InvalidTcInMemoryFormat(
@ -714,8 +725,7 @@ pub mod std_mod {
self.pus_tc_raw = Some(vec.clone());
}
};
let (tc, _) = PusTcReader::new(self.pus_tc_raw.as_ref().unwrap())?;
Ok(tc)
Ok(())
}
fn tc_slice_raw(&self) -> &[u8] {
@ -728,14 +738,14 @@ pub mod std_mod {
pub struct EcssTcInStoreConverter {
pub shared_tc_store: SharedPool,
pub pus_buf: [u8; 2048],
pub pus_buf: Vec<u8>,
}
impl EcssTcInStoreConverter {
pub fn new(shared_tc_store: SharedPool) -> Self {
pub fn new(shared_tc_store: SharedPool, max_expected_tc_size: usize) -> Self {
Self {
shared_tc_store,
pus_buf: [0; 2048],
pus_buf: alloc::vec![0; max_expected_tc_size],
}
}
@ -747,27 +757,30 @@ pub mod std_mod {
.map_err(|_| PusPacketHandlingError::EcssTmtc(EcssTmtcError::StoreLock))?;
let tc_guard = tc_pool.read_with_guard(addr);
let tc_raw = tc_guard.read().unwrap();
if tc_raw.len() > self.pus_buf.len() {
return Err(PusPacketHandlingError::PusPacketTooLarge(tc_raw.len()));
}
self.pus_buf[0..tc_raw.len()].copy_from_slice(tc_raw);
Ok(())
}
}
impl EcssTcInMemConverter for EcssTcInStoreConverter {
fn convert_ecss_tc_in_memory_to_reader<'a>(
fn cache_ecss_tc_in_memory<'a>(
&'a mut self,
possible_packet: &'a AcceptedEcssTcAndToken,
) -> Result<PusTcReader<'a>, PusPacketHandlingError> {
Ok(match &possible_packet.tc_in_memory {
) -> Result<(), PusPacketHandlingError> {
match &possible_packet.tc_in_memory {
super::TcInMemory::StoreAddr(addr) => {
self.copy_tc_to_buf(*addr)?;
PusTcReader::new(&self.pus_buf)?.0
}
super::TcInMemory::Vec(_) => {
return Err(PusPacketHandlingError::InvalidTcInMemoryFormat(
possible_packet.tc_in_memory.clone(),
));
}
})
};
Ok(())
}
fn tc_slice_raw(&self) -> &[u8] {

View File

@ -1,11 +1,11 @@
use crate::pool::SharedPool;
use crate::pus::scheduler::PusScheduler;
use crate::pus::verification::StdVerifReporterWithSender;
use crate::pus::{EcssTcReceiver, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError};
use spacepackets::ecss::{scheduling, PusPacket};
use spacepackets::time::cds::TimeProvider;
use std::boxed::Box;
use super::verification::VerificationReporterWithSender;
use super::{EcssTcInMemConverter, PusServiceBase, PusServiceHandler};
/// This is a helper class for [std] environments to handle generic PUS 11 (scheduling service)
@ -27,7 +27,7 @@ impl<TcInMemConverter: EcssTcInMemConverter> PusService11SchedHandler<TcInMemCon
tc_receiver: Box<dyn EcssTcReceiver>,
tm_sender: Box<dyn EcssTmSender>,
tm_apid: u16,
verification_handler: StdVerifReporterWithSender,
verification_handler: VerificationReporterWithSender,
tc_in_mem_converter: TcInMemConverter,
shared_tc_store: SharedPool,
scheduler: PusScheduler,

View File

@ -144,7 +144,7 @@ mod tests {
VerificationReporterWithSender::new(&verif_cfg, Box::new(verif_sender));
let test_srv_tm_sender = MpscTmInStoreSender::new(0, "TEST_SENDER", shared_tm_store, tm_tx);
let test_srv_tc_receiver = MpscTcInStoreReceiver::new(0, "TEST_RECEIVER", test_srv_tc_rx);
let in_store_converter = EcssTcInStoreConverter::new(tc_pool_shared.clone());
let in_store_converter = EcssTcInStoreConverter::new(tc_pool_shared.clone(), 2048);
let mut pus_17_handler = PusService17TestHandler::new(
Box::new(test_srv_tc_receiver),
Box::new(test_srv_tm_sender),

View File

@ -7,9 +7,7 @@
//! routing without the overhead and complication of using message queues. However, it also requires
#[cfg(feature = "alloc")]
use downcast_rs::{impl_downcast, Downcast};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use spacepackets::{ByteConversionError, SpHeader};
use spacepackets::SpHeader;
#[cfg(feature = "alloc")]
pub mod ccsds_distrib;
@ -24,40 +22,6 @@ pub use pus_distrib::{PusDistributor, PusServiceProvider};
pub type TargetId = u32;
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct AddressableId {
pub target_id: TargetId,
pub unique_id: u32,
}
impl AddressableId {
pub fn from_raw_be(buf: &[u8]) -> Result<Self, ByteConversionError> {
if buf.len() < 8 {
return Err(ByteConversionError::FromSliceTooSmall {
found: buf.len(),
expected: 8,
});
}
Ok(Self {
target_id: u32::from_be_bytes(buf[0..4].try_into().unwrap()),
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 {
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
/// no assumptions about the received protocol.
///