all test fixes
Some checks failed
Rust/sat-rs/pipeline/pr-main There was a failure building this commit

This commit is contained in:
Robin Müller 2024-04-15 14:35:06 +02:00
parent 794094ae9f
commit 269324de28
Signed by: muellerr
GPG Key ID: A649FB78196E3849
17 changed files with 260 additions and 200 deletions

View File

@ -465,7 +465,10 @@ mod tests {
.verif_reporter() .verif_reporter()
.check_next_is_acceptance_success(id, accepted_token.request_id()); .check_next_is_acceptance_success(id, accepted_token.request_id());
self.pus_packet_tx self.pus_packet_tx
.send(EcssTcAndToken::new(tc.to_vec().unwrap(), accepted_token)) .send(EcssTcAndToken::new(
PacketAsVec::new(self.service.service_helper.id(), tc.to_vec().unwrap()),
accepted_token,
))
.unwrap(); .unwrap();
} }
} }

View File

@ -1,6 +1,6 @@
use crate::requests::GenericRequestRouter; use crate::requests::GenericRequestRouter;
use log::warn; use log::warn;
use satrs::pool::StoreAddr; use satrs::pool::PoolAddr;
use satrs::pus::verification::{ use satrs::pus::verification::{
self, FailParams, TcStateAccepted, TcStateStarted, VerificationReporter, self, FailParams, TcStateAccepted, TcStateStarted, VerificationReporter,
VerificationReporterCfg, VerificationReportingProvider, VerificationToken, VerificationReporterCfg, VerificationReportingProvider, VerificationToken,
@ -98,7 +98,7 @@ impl<TmSender: EcssTmSender> PusTcDistributor<TmSender> {
pub fn handle_tc_generic( pub fn handle_tc_generic(
&mut self, &mut self,
sender_id: ComponentId, sender_id: ComponentId,
addr_opt: Option<StoreAddr>, addr_opt: Option<PoolAddr>,
raw_tc: &[u8], raw_tc: &[u8],
) -> Result<PusPacketHandlerResult, GenericSendError> { ) -> Result<PusPacketHandlerResult, GenericSendError> {
let pus_tc_result = PusTcReader::new(raw_tc); let pus_tc_result = PusTcReader::new(raw_tc);
@ -119,10 +119,10 @@ impl<TmSender: EcssTmSender> PusTcDistributor<TmSender> {
.acceptance_success(&self.tm_sender, init_token, self.stamp_helper.stamp()) .acceptance_success(&self.tm_sender, init_token, self.stamp_helper.stamp())
.expect("Acceptance success failure"); .expect("Acceptance success failure");
let service = PusServiceId::try_from(pus_tc.service()); let service = PusServiceId::try_from(pus_tc.service());
let tc_in_memory = if let Some(store_addr) = addr_opt { let tc_in_memory: TcInMemory = if let Some(store_addr) = addr_opt {
TcInMemory::StoreAddr(store_addr) PacketInPool::new(sender_id, store_addr).into()
} else { } else {
TcInMemory::Vec(Vec::from(raw_tc)) PacketAsVec::new(sender_id, Vec::from(raw_tc)).into()
}; };
match service { match service {
Ok(standard_service) => match standard_service { Ok(standard_service) => match standard_service {

View File

@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
a `send_raw_tc` method which is not mutable anymore. a `send_raw_tc` method which is not mutable anymore.
- Renamed `TmPacketSourceCore` to `TmPacketSource`. - Renamed `TmPacketSourceCore` to `TmPacketSource`.
- Renamed `EcssTmSenderCore` to `EcssTmSender`. - Renamed `EcssTmSenderCore` to `EcssTmSender`.
- Renamed `StoreAddr` to `PoolAddr`.
- Reanmed `StoreError` to `PoolError`.
- TCP server generics order. The error generics come last now. - TCP server generics order. The error generics come last now.
- `encoding::ccsds::PacketIdValidator` renamed to `ValidatorU16Id`, which lives in the crate root. - `encoding::ccsds::PacketIdValidator` renamed to `ValidatorU16Id`, which lives in the crate root.
It can be used for both CCSDS packet ID and CCSDS APID validation. It can be used for both CCSDS packet ID and CCSDS APID validation.

View File

@ -1,4 +1,4 @@
use crate::{params::Params, pool::StoreAddr}; use crate::{params::Params, pool::PoolAddr};
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub use alloc_mod::*; pub use alloc_mod::*;
@ -21,7 +21,7 @@ impl ActionRequest {
#[derive(Clone, Eq, PartialEq, Debug)] #[derive(Clone, Eq, PartialEq, Debug)]
pub enum ActionRequestVariant { pub enum ActionRequestVariant {
NoData, NoData,
StoreData(StoreAddr), StoreData(PoolAddr),
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
VecData(alloc::vec::Vec<u8>), VecData(alloc::vec::Vec<u8>),
} }

View File

@ -10,7 +10,10 @@ pub(crate) mod tests {
use alloc::collections::VecDeque; use alloc::collections::VecDeque;
use crate::{tmtc::{PacketAsVec, PacketSenderRaw}, ComponentId}; use crate::{
tmtc::{PacketAsVec, PacketSenderRaw},
ComponentId,
};
use super::cobs::encode_packet_with_cobs; use super::cobs::encode_packet_with_cobs;

View File

@ -206,10 +206,14 @@ mod tests {
}; };
use crate::{ use crate::{
encoding::tests::{INVERTED_PACKET, SIMPLE_PACKET}, hal::std::tcp_server::{ encoding::tests::{INVERTED_PACKET, SIMPLE_PACKET},
hal::std::tcp_server::{
tests::{ConnectionFinishedHandler, SyncTmSource}, tests::{ConnectionFinishedHandler, SyncTmSource},
ConnectionResult, ServerConfig, ConnectionResult, ServerConfig,
}, queue::GenericSendError, tmtc::PacketAsVec, ComponentId },
queue::GenericSendError,
tmtc::PacketAsVec,
ComponentId,
}; };
use alloc::sync::Arc; use alloc::sync::Arc;
use cobs::encode; use cobs::encode;

View File

@ -204,7 +204,10 @@ mod tests {
hal::std::tcp_server::{ hal::std::tcp_server::{
tests::{ConnectionFinishedHandler, SyncTmSource}, tests::{ConnectionFinishedHandler, SyncTmSource},
ConnectionResult, ServerConfig, ConnectionResult, ServerConfig,
}, queue::GenericSendError, tmtc::PacketAsVec, ComponentId },
queue::GenericSendError,
tmtc::PacketAsVec,
ComponentId,
}; };
use super::TcpSpacepacketsServer; use super::TcpSpacepacketsServer;

View File

@ -43,7 +43,7 @@
//! This includes the [ParamsHeapless] enumeration for contained values which do not require heap //! This includes the [ParamsHeapless] enumeration for contained values which do not require heap
//! allocation, and the [Params] which enumerates [ParamsHeapless] and some additional types which //! allocation, and the [Params] which enumerates [ParamsHeapless] and some additional types which
//! require [alloc] support but allow for more flexbility. //! require [alloc] support but allow for more flexbility.
use crate::pool::StoreAddr; use crate::pool::PoolAddr;
use core::fmt::Debug; use core::fmt::Debug;
use core::mem::size_of; use core::mem::size_of;
use paste::paste; use paste::paste;
@ -588,15 +588,15 @@ from_conversions_for_raw!(
#[non_exhaustive] #[non_exhaustive]
pub enum Params { pub enum Params {
Heapless(ParamsHeapless), Heapless(ParamsHeapless),
Store(StoreAddr), Store(PoolAddr),
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
Vec(Vec<u8>), Vec(Vec<u8>),
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
String(String), String(String),
} }
impl From<StoreAddr> for Params { impl From<PoolAddr> for Params {
fn from(x: StoreAddr) -> Self { fn from(x: PoolAddr) -> Self {
Self::Store(x) Self::Store(x)
} }
} }

View File

@ -82,7 +82,7 @@ use spacepackets::ByteConversionError;
use std::error::Error; use std::error::Error;
type NumBlocks = u16; type NumBlocks = u16;
pub type StoreAddr = u64; pub type PoolAddr = u64;
/// Simple address type used for transactions with the local pool. /// Simple address type used for transactions with the local pool.
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@ -100,14 +100,14 @@ impl StaticPoolAddr {
} }
} }
impl From<StaticPoolAddr> for StoreAddr { impl From<StaticPoolAddr> for PoolAddr {
fn from(value: StaticPoolAddr) -> Self { fn from(value: StaticPoolAddr) -> Self {
((value.pool_idx as u64) << 16) | value.packet_idx as u64 ((value.pool_idx as u64) << 16) | value.packet_idx as u64
} }
} }
impl From<StoreAddr> for StaticPoolAddr { impl From<PoolAddr> for StaticPoolAddr {
fn from(value: StoreAddr) -> Self { fn from(value: PoolAddr) -> Self {
Self { Self {
pool_idx: ((value >> 16) & 0xff) as u16, pool_idx: ((value >> 16) & 0xff) as u16,
packet_idx: (value & 0xff) as u16, packet_idx: (value & 0xff) as u16,
@ -150,59 +150,59 @@ impl Error for StoreIdError {}
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum StoreError { pub enum PoolError {
/// Requested data block is too large /// Requested data block is too large
DataTooLarge(usize), DataTooLarge(usize),
/// The store is full. Contains the index of the full subpool /// The store is full. Contains the index of the full subpool
StoreFull(u16), StoreFull(u16),
/// Store ID is invalid. This also includes partial errors where only the subpool is invalid /// Store ID is invalid. This also includes partial errors where only the subpool is invalid
InvalidStoreId(StoreIdError, Option<StoreAddr>), InvalidStoreId(StoreIdError, Option<PoolAddr>),
/// Valid subpool and packet index, but no data is stored at the given address /// Valid subpool and packet index, but no data is stored at the given address
DataDoesNotExist(StoreAddr), DataDoesNotExist(PoolAddr),
ByteConversionError(spacepackets::ByteConversionError), ByteConversionError(spacepackets::ByteConversionError),
LockError, LockError,
/// Internal or configuration errors /// Internal or configuration errors
InternalError(u32), InternalError(u32),
} }
impl Display for StoreError { impl Display for PoolError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self { match self {
StoreError::DataTooLarge(size) => { PoolError::DataTooLarge(size) => {
write!(f, "data to store with size {size} is too large") write!(f, "data to store with size {size} is too large")
} }
StoreError::StoreFull(u16) => { PoolError::StoreFull(u16) => {
write!(f, "store is too full. index for full subpool: {u16}") write!(f, "store is too full. index for full subpool: {u16}")
} }
StoreError::InvalidStoreId(id_e, addr) => { PoolError::InvalidStoreId(id_e, addr) => {
write!(f, "invalid store ID: {id_e}, address: {addr:?}") write!(f, "invalid store ID: {id_e}, address: {addr:?}")
} }
StoreError::DataDoesNotExist(addr) => { PoolError::DataDoesNotExist(addr) => {
write!(f, "no data exists at address {addr:?}") write!(f, "no data exists at address {addr:?}")
} }
StoreError::InternalError(e) => { PoolError::InternalError(e) => {
write!(f, "internal error: {e}") write!(f, "internal error: {e}")
} }
StoreError::ByteConversionError(e) => { PoolError::ByteConversionError(e) => {
write!(f, "store error: {e}") write!(f, "store error: {e}")
} }
StoreError::LockError => { PoolError::LockError => {
write!(f, "lock error") write!(f, "lock error")
} }
} }
} }
} }
impl From<ByteConversionError> for StoreError { impl From<ByteConversionError> for PoolError {
fn from(value: ByteConversionError) -> Self { fn from(value: ByteConversionError) -> Self {
Self::ByteConversionError(value) Self::ByteConversionError(value)
} }
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl Error for StoreError { impl Error for PoolError {
fn source(&self) -> Option<&(dyn Error + 'static)> { fn source(&self) -> Option<&(dyn Error + 'static)> {
if let StoreError::InvalidStoreId(e, _) = self { if let PoolError::InvalidStoreId(e, _) = self {
return Some(e); return Some(e);
} }
None None
@ -219,7 +219,7 @@ pub trait PoolProvider {
/// Add new data to the pool. The provider should attempt to reserve a memory block with the /// 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 /// appropriate size and then copy the given data to the block. Yields a [StoreAddr] which can
/// be used to access the data stored in the pool /// be used to access the data stored in the pool
fn add(&mut self, data: &[u8]) -> Result<StoreAddr, StoreError>; fn add(&mut self, data: &[u8]) -> Result<PoolAddr, PoolError>;
/// The provider should attempt to reserve a free memory block with the appropriate size first. /// The provider should attempt to reserve a free memory block with the appropriate size first.
/// It then executes a user-provided closure and passes a mutable reference to that memory /// It then executes a user-provided closure and passes a mutable reference to that memory
@ -230,31 +230,28 @@ pub trait PoolProvider {
&mut self, &mut self,
len: usize, len: usize,
writer: W, writer: W,
) -> Result<StoreAddr, StoreError>; ) -> Result<PoolAddr, PoolError>;
/// Modify data added previously using a given [StoreAddr]. The provider should use the store /// Modify data added previously using a given [StoreAddr]. The provider should use the store
/// address to determine if a memory block exists for that address. If it does, it should /// address to determine if a memory block exists for that address. If it does, it should
/// call the user-provided closure and pass a mutable reference to the memory block /// call the user-provided closure and pass a mutable reference to the memory block
/// to the closure. This allows the user to modify the memory block. /// to the closure. This allows the user to modify the memory block.
fn modify<U: FnMut(&mut [u8])>( fn modify<U: FnMut(&mut [u8])>(&mut self, addr: &PoolAddr, updater: U)
&mut self, -> Result<(), PoolError>;
addr: &StoreAddr,
updater: U,
) -> Result<(), StoreError>;
/// The provider should copy the data from the memory block to the user-provided buffer if /// The provider should copy the data from the memory block to the user-provided buffer if
/// it exists. /// it exists.
fn read(&self, addr: &StoreAddr, buf: &mut [u8]) -> Result<usize, StoreError>; fn read(&self, addr: &PoolAddr, buf: &mut [u8]) -> Result<usize, PoolError>;
/// Delete data inside the pool given a [StoreAddr]. /// Delete data inside the pool given a [StoreAddr].
fn delete(&mut self, addr: StoreAddr) -> Result<(), StoreError>; fn delete(&mut self, addr: PoolAddr) -> Result<(), PoolError>;
fn has_element_at(&self, addr: &StoreAddr) -> Result<bool, StoreError>; fn has_element_at(&self, addr: &PoolAddr) -> Result<bool, PoolError>;
/// Retrieve the length of the data at the given store address. /// Retrieve the length of the data at the given store address.
fn len_of_data(&self, addr: &StoreAddr) -> Result<usize, StoreError>; fn len_of_data(&self, addr: &PoolAddr) -> Result<usize, PoolError>;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
fn read_as_vec(&self, addr: &StoreAddr) -> Result<alloc::vec::Vec<u8>, StoreError> { fn read_as_vec(&self, addr: &PoolAddr) -> Result<alloc::vec::Vec<u8>, PoolError> {
let mut vec = alloc::vec![0; self.len_of_data(addr)?]; let mut vec = alloc::vec![0; self.len_of_data(addr)?];
self.read(addr, &mut vec)?; self.read(addr, &mut vec)?;
Ok(vec) Ok(vec)
@ -271,7 +268,7 @@ pub trait PoolProviderWithGuards: PoolProvider {
/// This can prevent memory leaks. Users can read the data and release the guard /// This can prevent memory leaks. Users can read the data and release the guard
/// if the data in the store is valid for further processing. If the data is faulty, no /// if the data in the store is valid for further processing. If the data is faulty, no
/// manual deletion is necessary when returning from a processing function prematurely. /// manual deletion is necessary when returning from a processing function prematurely.
fn read_with_guard(&mut self, addr: StoreAddr) -> PoolGuard<Self>; fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard<Self>;
/// This function behaves like [PoolProvider::modify], but consumes the provided /// This function behaves like [PoolProvider::modify], but consumes the provided
/// address and returns a RAII conformant guard object. /// address and returns a RAII conformant guard object.
@ -281,20 +278,20 @@ pub trait PoolProviderWithGuards: PoolProvider {
/// This can prevent memory leaks. Users can read (and modify) the data and release the guard /// This can prevent memory leaks. Users can read (and modify) the data and release the guard
/// if the data in the store is valid for further processing. If the data is faulty, no /// if the data in the store is valid for further processing. If the data is faulty, no
/// manual deletion is necessary when returning from a processing function prematurely. /// manual deletion is necessary when returning from a processing function prematurely.
fn modify_with_guard(&mut self, addr: StoreAddr) -> PoolRwGuard<Self>; fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard<Self>;
} }
pub struct PoolGuard<'a, MemProvider: PoolProvider + ?Sized> { pub struct PoolGuard<'a, MemProvider: PoolProvider + ?Sized> {
pool: &'a mut MemProvider, pool: &'a mut MemProvider,
pub addr: StoreAddr, pub addr: PoolAddr,
no_deletion: bool, no_deletion: bool,
deletion_failed_error: Option<StoreError>, deletion_failed_error: Option<PoolError>,
} }
/// This helper object can be used to safely access pool data without worrying about memory /// This helper object can be used to safely access pool data without worrying about memory
/// leaks. /// leaks.
impl<'a, MemProvider: PoolProvider> PoolGuard<'a, MemProvider> { impl<'a, MemProvider: PoolProvider> PoolGuard<'a, MemProvider> {
pub fn new(pool: &'a mut MemProvider, addr: StoreAddr) -> Self { pub fn new(pool: &'a mut MemProvider, addr: PoolAddr) -> Self {
Self { Self {
pool, pool,
addr, addr,
@ -303,12 +300,12 @@ impl<'a, MemProvider: PoolProvider> PoolGuard<'a, MemProvider> {
} }
} }
pub fn read(&self, buf: &mut [u8]) -> Result<usize, StoreError> { pub fn read(&self, buf: &mut [u8]) -> Result<usize, PoolError> {
self.pool.read(&self.addr, buf) self.pool.read(&self.addr, buf)
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub fn read_as_vec(&self) -> Result<alloc::vec::Vec<u8>, StoreError> { pub fn read_as_vec(&self) -> Result<alloc::vec::Vec<u8>, PoolError> {
self.pool.read_as_vec(&self.addr) self.pool.read_as_vec(&self.addr)
} }
@ -334,19 +331,19 @@ pub struct PoolRwGuard<'a, MemProvider: PoolProvider + ?Sized> {
} }
impl<'a, MemProvider: PoolProvider> PoolRwGuard<'a, MemProvider> { impl<'a, MemProvider: PoolProvider> PoolRwGuard<'a, MemProvider> {
pub fn new(pool: &'a mut MemProvider, addr: StoreAddr) -> Self { pub fn new(pool: &'a mut MemProvider, addr: PoolAddr) -> Self {
Self { Self {
guard: PoolGuard::new(pool, addr), guard: PoolGuard::new(pool, addr),
} }
} }
pub fn update<U: FnMut(&mut [u8])>(&mut self, updater: &mut U) -> Result<(), StoreError> { pub fn update<U: FnMut(&mut [u8])>(&mut self, updater: &mut U) -> Result<(), PoolError> {
self.guard.pool.modify(&self.guard.addr, updater) self.guard.pool.modify(&self.guard.addr, updater)
} }
delegate!( delegate!(
to self.guard { to self.guard {
pub fn read(&self, buf: &mut [u8]) -> Result<usize, StoreError>; pub fn read(&self, buf: &mut [u8]) -> Result<usize, PoolError>;
/// Releasing the pool guard will disable the automatic deletion of the data when the guard /// Releasing the pool guard will disable the automatic deletion of the data when the guard
/// is dropped. /// is dropped.
pub fn release(&mut self); pub fn release(&mut self);
@ -357,7 +354,7 @@ impl<'a, MemProvider: PoolProvider> PoolRwGuard<'a, MemProvider> {
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
mod alloc_mod { mod alloc_mod {
use super::{PoolGuard, PoolProvider, PoolProviderWithGuards, PoolRwGuard, StaticPoolAddr}; use super::{PoolGuard, PoolProvider, PoolProviderWithGuards, PoolRwGuard, StaticPoolAddr};
use crate::pool::{NumBlocks, StoreAddr, StoreError, StoreIdError}; use crate::pool::{NumBlocks, PoolAddr, PoolError, StoreIdError};
use alloc::vec; use alloc::vec;
use alloc::vec::Vec; use alloc::vec::Vec;
use spacepackets::ByteConversionError; use spacepackets::ByteConversionError;
@ -452,41 +449,41 @@ mod alloc_mod {
local_pool local_pool
} }
fn addr_check(&self, addr: &StaticPoolAddr) -> Result<usize, StoreError> { fn addr_check(&self, addr: &StaticPoolAddr) -> Result<usize, PoolError> {
self.validate_addr(addr)?; self.validate_addr(addr)?;
let pool_idx = addr.pool_idx as usize; let pool_idx = addr.pool_idx as usize;
let size_list = self.sizes_lists.get(pool_idx).unwrap(); let size_list = self.sizes_lists.get(pool_idx).unwrap();
let curr_size = size_list[addr.packet_idx as usize]; let curr_size = size_list[addr.packet_idx as usize];
if curr_size == STORE_FREE { if curr_size == STORE_FREE {
return Err(StoreError::DataDoesNotExist(StoreAddr::from(*addr))); return Err(PoolError::DataDoesNotExist(PoolAddr::from(*addr)));
} }
Ok(curr_size) Ok(curr_size)
} }
fn validate_addr(&self, addr: &StaticPoolAddr) -> Result<(), StoreError> { fn validate_addr(&self, addr: &StaticPoolAddr) -> Result<(), PoolError> {
let pool_idx = addr.pool_idx as usize; let pool_idx = addr.pool_idx as usize;
if pool_idx >= self.pool_cfg.cfg.len() { if pool_idx >= self.pool_cfg.cfg.len() {
return Err(StoreError::InvalidStoreId( return Err(PoolError::InvalidStoreId(
StoreIdError::InvalidSubpool(addr.pool_idx), StoreIdError::InvalidSubpool(addr.pool_idx),
Some(StoreAddr::from(*addr)), Some(PoolAddr::from(*addr)),
)); ));
} }
if addr.packet_idx >= self.pool_cfg.cfg[addr.pool_idx as usize].0 { if addr.packet_idx >= self.pool_cfg.cfg[addr.pool_idx as usize].0 {
return Err(StoreError::InvalidStoreId( return Err(PoolError::InvalidStoreId(
StoreIdError::InvalidPacketIdx(addr.packet_idx), StoreIdError::InvalidPacketIdx(addr.packet_idx),
Some(StoreAddr::from(*addr)), Some(PoolAddr::from(*addr)),
)); ));
} }
Ok(()) Ok(())
} }
fn reserve(&mut self, data_len: usize) -> Result<StaticPoolAddr, StoreError> { fn reserve(&mut self, data_len: usize) -> Result<StaticPoolAddr, PoolError> {
let mut subpool_idx = self.find_subpool(data_len, 0)?; let mut subpool_idx = self.find_subpool(data_len, 0)?;
if self.pool_cfg.spill_to_higher_subpools { if self.pool_cfg.spill_to_higher_subpools {
while let Err(StoreError::StoreFull(_)) = self.find_empty(subpool_idx) { while let Err(PoolError::StoreFull(_)) = self.find_empty(subpool_idx) {
if (subpool_idx + 1) as usize == self.sizes_lists.len() { if (subpool_idx + 1) as usize == self.sizes_lists.len() {
return Err(StoreError::StoreFull(subpool_idx)); return Err(PoolError::StoreFull(subpool_idx));
} }
subpool_idx += 1; subpool_idx += 1;
} }
@ -500,7 +497,7 @@ mod alloc_mod {
}) })
} }
fn find_subpool(&self, req_size: usize, start_at_subpool: u16) -> Result<u16, StoreError> { fn find_subpool(&self, req_size: usize, start_at_subpool: u16) -> Result<u16, PoolError> {
for (i, &(_, elem_size)) in self.pool_cfg.cfg.iter().enumerate() { for (i, &(_, elem_size)) in self.pool_cfg.cfg.iter().enumerate() {
if i < start_at_subpool as usize { if i < start_at_subpool as usize {
continue; continue;
@ -509,21 +506,21 @@ mod alloc_mod {
return Ok(i as u16); return Ok(i as u16);
} }
} }
Err(StoreError::DataTooLarge(req_size)) Err(PoolError::DataTooLarge(req_size))
} }
fn write(&mut self, addr: &StaticPoolAddr, data: &[u8]) -> Result<(), StoreError> { fn write(&mut self, addr: &StaticPoolAddr, data: &[u8]) -> Result<(), PoolError> {
let packet_pos = self.raw_pos(addr).ok_or(StoreError::InternalError(0))?; let packet_pos = self.raw_pos(addr).ok_or(PoolError::InternalError(0))?;
let subpool = self let subpool = self
.pool .pool
.get_mut(addr.pool_idx as usize) .get_mut(addr.pool_idx as usize)
.ok_or(StoreError::InternalError(1))?; .ok_or(PoolError::InternalError(1))?;
let pool_slice = &mut subpool[packet_pos..packet_pos + data.len()]; let pool_slice = &mut subpool[packet_pos..packet_pos + data.len()];
pool_slice.copy_from_slice(data); pool_slice.copy_from_slice(data);
Ok(()) Ok(())
} }
fn find_empty(&mut self, subpool: u16) -> Result<(u16, &mut usize), StoreError> { fn find_empty(&mut self, subpool: u16) -> Result<(u16, &mut usize), PoolError> {
if let Some(size_list) = self.sizes_lists.get_mut(subpool as usize) { if let Some(size_list) = self.sizes_lists.get_mut(subpool as usize) {
for (i, elem_size) in size_list.iter_mut().enumerate() { for (i, elem_size) in size_list.iter_mut().enumerate() {
if *elem_size == STORE_FREE { if *elem_size == STORE_FREE {
@ -531,12 +528,12 @@ mod alloc_mod {
} }
} }
} else { } else {
return Err(StoreError::InvalidStoreId( return Err(PoolError::InvalidStoreId(
StoreIdError::InvalidSubpool(subpool), StoreIdError::InvalidSubpool(subpool),
None, None,
)); ));
} }
Err(StoreError::StoreFull(subpool)) Err(PoolError::StoreFull(subpool))
} }
fn raw_pos(&self, addr: &StaticPoolAddr) -> Option<usize> { fn raw_pos(&self, addr: &StaticPoolAddr) -> Option<usize> {
@ -546,10 +543,10 @@ mod alloc_mod {
} }
impl PoolProvider for StaticMemoryPool { impl PoolProvider for StaticMemoryPool {
fn add(&mut self, data: &[u8]) -> Result<StoreAddr, StoreError> { fn add(&mut self, data: &[u8]) -> Result<PoolAddr, PoolError> {
let data_len = data.len(); let data_len = data.len();
if data_len > POOL_MAX_SIZE { if data_len > POOL_MAX_SIZE {
return Err(StoreError::DataTooLarge(data_len)); return Err(PoolError::DataTooLarge(data_len));
} }
let addr = self.reserve(data_len)?; let addr = self.reserve(data_len)?;
self.write(&addr, data)?; self.write(&addr, data)?;
@ -560,9 +557,9 @@ mod alloc_mod {
&mut self, &mut self,
len: usize, len: usize,
mut writer: W, mut writer: W,
) -> Result<StoreAddr, StoreError> { ) -> Result<PoolAddr, PoolError> {
if len > POOL_MAX_SIZE { if len > POOL_MAX_SIZE {
return Err(StoreError::DataTooLarge(len)); return Err(PoolError::DataTooLarge(len));
} }
let addr = self.reserve(len)?; let addr = self.reserve(len)?;
let raw_pos = self.raw_pos(&addr).unwrap(); let raw_pos = self.raw_pos(&addr).unwrap();
@ -574,9 +571,9 @@ mod alloc_mod {
fn modify<U: FnMut(&mut [u8])>( fn modify<U: FnMut(&mut [u8])>(
&mut self, &mut self,
addr: &StoreAddr, addr: &PoolAddr,
mut updater: U, mut updater: U,
) -> Result<(), StoreError> { ) -> Result<(), PoolError> {
let addr = StaticPoolAddr::from(*addr); let addr = StaticPoolAddr::from(*addr);
let curr_size = self.addr_check(&addr)?; let curr_size = self.addr_check(&addr)?;
let raw_pos = self.raw_pos(&addr).unwrap(); let raw_pos = self.raw_pos(&addr).unwrap();
@ -586,7 +583,7 @@ mod alloc_mod {
Ok(()) Ok(())
} }
fn read(&self, addr: &StoreAddr, buf: &mut [u8]) -> Result<usize, StoreError> { fn read(&self, addr: &PoolAddr, buf: &mut [u8]) -> Result<usize, PoolError> {
let addr = StaticPoolAddr::from(*addr); let addr = StaticPoolAddr::from(*addr);
let curr_size = self.addr_check(&addr)?; let curr_size = self.addr_check(&addr)?;
if buf.len() < curr_size { if buf.len() < curr_size {
@ -604,7 +601,7 @@ mod alloc_mod {
Ok(curr_size) Ok(curr_size)
} }
fn delete(&mut self, addr: StoreAddr) -> Result<(), StoreError> { fn delete(&mut self, addr: PoolAddr) -> Result<(), PoolError> {
let addr = StaticPoolAddr::from(addr); let addr = StaticPoolAddr::from(addr);
self.addr_check(&addr)?; self.addr_check(&addr)?;
let block_size = self.pool_cfg.cfg.get(addr.pool_idx as usize).unwrap().1; let block_size = self.pool_cfg.cfg.get(addr.pool_idx as usize).unwrap().1;
@ -617,7 +614,7 @@ mod alloc_mod {
Ok(()) Ok(())
} }
fn has_element_at(&self, addr: &StoreAddr) -> Result<bool, StoreError> { fn has_element_at(&self, addr: &PoolAddr) -> Result<bool, PoolError> {
let addr = StaticPoolAddr::from(*addr); let addr = StaticPoolAddr::from(*addr);
self.validate_addr(&addr)?; self.validate_addr(&addr)?;
let pool_idx = addr.pool_idx as usize; let pool_idx = addr.pool_idx as usize;
@ -629,7 +626,7 @@ mod alloc_mod {
Ok(true) Ok(true)
} }
fn len_of_data(&self, addr: &StoreAddr) -> Result<usize, StoreError> { fn len_of_data(&self, addr: &PoolAddr) -> Result<usize, PoolError> {
let addr = StaticPoolAddr::from(*addr); let addr = StaticPoolAddr::from(*addr);
self.validate_addr(&addr)?; self.validate_addr(&addr)?;
let pool_idx = addr.pool_idx as usize; let pool_idx = addr.pool_idx as usize;
@ -643,11 +640,11 @@ mod alloc_mod {
} }
impl PoolProviderWithGuards for StaticMemoryPool { impl PoolProviderWithGuards for StaticMemoryPool {
fn modify_with_guard(&mut self, addr: StoreAddr) -> PoolRwGuard<Self> { fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard<Self> {
PoolRwGuard::new(self, addr) PoolRwGuard::new(self, addr)
} }
fn read_with_guard(&mut self, addr: StoreAddr) -> PoolGuard<Self> { fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard<Self> {
PoolGuard::new(self, addr) PoolGuard::new(self, addr)
} }
} }
@ -656,8 +653,8 @@ mod alloc_mod {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::pool::{ use crate::pool::{
PoolGuard, PoolProvider, PoolProviderWithGuards, PoolRwGuard, StaticMemoryPool, PoolError, PoolGuard, PoolProvider, PoolProviderWithGuards, PoolRwGuard, StaticMemoryPool,
StaticPoolAddr, StaticPoolConfig, StoreError, StoreIdError, POOL_MAX_SIZE, StaticPoolAddr, StaticPoolConfig, StoreIdError, POOL_MAX_SIZE,
}; };
use std::vec; use std::vec;
@ -781,7 +778,7 @@ mod tests {
let res = local_pool.free_element(8, |_| {}); let res = local_pool.free_element(8, |_| {});
assert!(res.is_err()); assert!(res.is_err());
let err = res.unwrap_err(); let err = res.unwrap_err();
assert_eq!(err, StoreError::StoreFull(1)); assert_eq!(err, PoolError::StoreFull(1));
// Verify that the two deletions are successful // Verify that the two deletions are successful
assert!(local_pool.delete(addr0).is_ok()); assert!(local_pool.delete(addr0).is_ok());
@ -803,7 +800,7 @@ mod tests {
assert!(res.is_err()); assert!(res.is_err());
assert!(matches!( assert!(matches!(
res.unwrap_err(), res.unwrap_err(),
StoreError::DataDoesNotExist { .. } PoolError::DataDoesNotExist { .. }
)); ));
} }
@ -816,8 +813,8 @@ mod tests {
let res = local_pool.add(&test_buf); let res = local_pool.add(&test_buf);
assert!(res.is_err()); assert!(res.is_err());
let err = res.unwrap_err(); let err = res.unwrap_err();
assert!(matches!(err, StoreError::StoreFull { .. })); assert!(matches!(err, PoolError::StoreFull { .. }));
if let StoreError::StoreFull(subpool) = err { if let PoolError::StoreFull(subpool) = err {
assert_eq!(subpool, 2); assert_eq!(subpool, 2);
} }
} }
@ -835,7 +832,7 @@ mod tests {
let err = res.unwrap_err(); let err = res.unwrap_err();
assert!(matches!( assert!(matches!(
err, err,
StoreError::InvalidStoreId(StoreIdError::InvalidSubpool(3), Some(_)) PoolError::InvalidStoreId(StoreIdError::InvalidSubpool(3), Some(_))
)); ));
} }
@ -852,7 +849,7 @@ mod tests {
let err = res.unwrap_err(); let err = res.unwrap_err();
assert!(matches!( assert!(matches!(
err, err,
StoreError::InvalidStoreId(StoreIdError::InvalidPacketIdx(1), Some(_)) PoolError::InvalidStoreId(StoreIdError::InvalidPacketIdx(1), Some(_))
)); ));
} }
@ -863,7 +860,7 @@ mod tests {
let res = local_pool.add(&data_too_large); let res = local_pool.add(&data_too_large);
assert!(res.is_err()); assert!(res.is_err());
let err = res.unwrap_err(); let err = res.unwrap_err();
assert_eq!(err, StoreError::DataTooLarge(20)); assert_eq!(err, PoolError::DataTooLarge(20));
} }
#[test] #[test]
@ -871,10 +868,7 @@ mod tests {
let mut local_pool = basic_small_pool(); let mut local_pool = basic_small_pool();
let res = local_pool.free_element(POOL_MAX_SIZE + 1, |_| {}); let res = local_pool.free_element(POOL_MAX_SIZE + 1, |_| {});
assert!(res.is_err()); assert!(res.is_err());
assert_eq!( assert_eq!(res.unwrap_err(), PoolError::DataTooLarge(POOL_MAX_SIZE + 1));
res.unwrap_err(),
StoreError::DataTooLarge(POOL_MAX_SIZE + 1)
);
} }
#[test] #[test]
@ -883,7 +877,7 @@ mod tests {
// Try to request a slot which is too large // Try to request a slot which is too large
let res = local_pool.free_element(20, |_| {}); let res = local_pool.free_element(20, |_| {});
assert!(res.is_err()); assert!(res.is_err());
assert_eq!(res.unwrap_err(), StoreError::DataTooLarge(20)); assert_eq!(res.unwrap_err(), PoolError::DataTooLarge(20));
} }
#[test] #[test]
@ -1003,7 +997,7 @@ mod tests {
let should_fail = local_pool.free_element(8, |_| {}); let should_fail = local_pool.free_element(8, |_| {});
assert!(should_fail.is_err()); assert!(should_fail.is_err());
if let Err(err) = should_fail { if let Err(err) = should_fail {
assert_eq!(err, StoreError::StoreFull(1)); assert_eq!(err, PoolError::StoreFull(1));
} else { } else {
panic!("unexpected store address"); panic!("unexpected store address");
} }
@ -1034,7 +1028,7 @@ mod tests {
let should_fail = local_pool.free_element(8, |_| {}); let should_fail = local_pool.free_element(8, |_| {});
assert!(should_fail.is_err()); assert!(should_fail.is_err());
if let Err(err) = should_fail { if let Err(err) = should_fail {
assert_eq!(err, StoreError::StoreFull(2)); assert_eq!(err, PoolError::StoreFull(2));
} else { } else {
panic!("unexpected store address"); panic!("unexpected store address");
} }

View File

@ -257,8 +257,8 @@ pub mod alloc_mod {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::{events::SeverityInfo, tmtc::PacketAsVec};
use crate::request::UniqueApidTargetId; use crate::request::UniqueApidTargetId;
use crate::{events::SeverityInfo, tmtc::PacketAsVec};
use std::sync::mpsc::{self, TryRecvError}; use std::sync::mpsc::{self, TryRecvError};
const INFO_EVENT: EventU32TypedSev<SeverityInfo> = const INFO_EVENT: EventU32TypedSev<SeverityInfo> =

View File

@ -213,9 +213,13 @@ mod tests {
.expect("acceptance success failure") .expect("acceptance success failure")
} }
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) {
self.common
.send_tc(self.handler.service_helper.id(), token, tc);
}
delegate! { delegate! {
to self.common { to self.common {
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator);
fn read_next_tm(&mut self) -> PusTmReader<'_>; fn read_next_tm(&mut self) -> PusTmReader<'_>;
fn check_no_tm_available(&self) -> bool; fn check_no_tm_available(&self) -> bool;
fn check_next_verification_tm(&self, subservice: u8, expected_request_id: RequestId); fn check_next_verification_tm(&self, subservice: u8, expected_request_id: RequestId);

View File

@ -2,10 +2,11 @@
//! //!
//! This module contains structures to make working with the PUS C standard easier. //! This module contains structures to make working with the PUS C standard easier.
//! The satrs-example application contains various usage examples of these components. //! The satrs-example application contains various usage examples of these components.
use crate::pool::{StoreAddr, StoreError}; use crate::pool::{PoolAddr, PoolError};
use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken}; use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken};
use crate::queue::{GenericReceiveError, GenericSendError}; use crate::queue::{GenericReceiveError, GenericSendError};
use crate::request::{GenericMessage, MessageMetadata, RequestId}; use crate::request::{GenericMessage, MessageMetadata, RequestId};
use crate::tmtc::{PacketAsVec, PacketInPool};
use crate::ComponentId; use crate::ComponentId;
use core::fmt::{Display, Formatter}; use core::fmt::{Display, Formatter};
use core::time::Duration; use core::time::Duration;
@ -44,12 +45,12 @@ use self::verification::VerificationReportingProvider;
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub enum PusTmVariant<'time, 'src_data> { pub enum PusTmVariant<'time, 'src_data> {
InStore(StoreAddr), InStore(PoolAddr),
Direct(PusTmCreator<'time, 'src_data>), Direct(PusTmCreator<'time, 'src_data>),
} }
impl From<StoreAddr> for PusTmVariant<'_, '_> { impl From<PoolAddr> for PusTmVariant<'_, '_> {
fn from(value: StoreAddr) -> Self { fn from(value: PoolAddr) -> Self {
Self::InStore(value) Self::InStore(value)
} }
} }
@ -62,10 +63,10 @@ impl<'time, 'src_data> From<PusTmCreator<'time, 'src_data>> for PusTmVariant<'ti
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum EcssTmtcError { pub enum EcssTmtcError {
Store(StoreError), Store(PoolError),
ByteConversion(ByteConversionError), ByteConversion(ByteConversionError),
Pus(PusError), Pus(PusError),
CantSendAddr(StoreAddr), CantSendAddr(PoolAddr),
CantSendDirectTm, CantSendDirectTm,
Send(GenericSendError), Send(GenericSendError),
Receive(GenericReceiveError), Receive(GenericReceiveError),
@ -99,8 +100,8 @@ impl Display for EcssTmtcError {
} }
} }
impl From<StoreError> for EcssTmtcError { impl From<PoolError> for EcssTmtcError {
fn from(value: StoreError) -> Self { fn from(value: PoolError) -> Self {
Self::Store(value) Self::Store(value)
} }
} }
@ -175,27 +176,26 @@ impl EcssTmSender for EcssTmDummySender {
} }
} }
// TODO: Maybe this should wrap PacketInStore and PacketAsVec instead.. /// A PUS telecommand packet can be stored in memory and sent using different methods. Right now,
/// A PUS telecommand packet can be stored in memory using different methods. Right now,
/// storage inside a pool structure like [crate::pool::StaticMemoryPool], and storage inside a /// storage inside a pool structure like [crate::pool::StaticMemoryPool], and storage inside a
/// `Vec<u8>` are supported. /// `Vec<u8>` are supported.
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum TcInMemory { pub enum TcInMemory {
StoreAddr(StoreAddr), Pool(PacketInPool),
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
Vec(alloc::vec::Vec<u8>), Vec(PacketAsVec),
} }
impl From<StoreAddr> for TcInMemory { impl From<PacketInPool> for TcInMemory {
fn from(value: StoreAddr) -> Self { fn from(value: PacketInPool) -> Self {
Self::StoreAddr(value) Self::Pool(value)
} }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl From<alloc::vec::Vec<u8>> for TcInMemory { impl From<PacketAsVec> for TcInMemory {
fn from(value: alloc::vec::Vec<u8>) -> Self { fn from(value: PacketAsVec) -> Self {
Self::Vec(value) Self::Vec(value)
} }
} }
@ -263,8 +263,8 @@ impl From<PusError> for TryRecvTmtcError {
} }
} }
impl From<StoreError> for TryRecvTmtcError { impl From<PoolError> for TryRecvTmtcError {
fn from(value: StoreError) -> Self { fn from(value: PoolError) -> Self {
Self::Tmtc(value.into()) Self::Tmtc(value.into())
} }
} }
@ -654,7 +654,7 @@ pub mod alloc_mod {
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))] #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
pub mod std_mod { pub mod std_mod {
use crate::pool::{ use crate::pool::{
PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool, StoreAddr, StoreError, PoolAddr, PoolError, PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool,
}; };
use crate::pus::verification::{TcStateAccepted, VerificationToken}; use crate::pus::verification::{TcStateAccepted, VerificationToken};
use crate::pus::{ use crate::pus::{
@ -681,8 +681,8 @@ pub mod std_mod {
use super::{AcceptedEcssTcAndToken, ActiveRequestProvider, TcInMemory}; use super::{AcceptedEcssTcAndToken, ActiveRequestProvider, TcInMemory};
use crate::tmtc::PacketInPool; use crate::tmtc::PacketInPool;
impl From<mpsc::SendError<StoreAddr>> for EcssTmtcError { impl From<mpsc::SendError<PoolAddr>> for EcssTmtcError {
fn from(_: mpsc::SendError<StoreAddr>) -> Self { fn from(_: mpsc::SendError<PoolAddr>) -> Self {
Self::Send(GenericSendError::RxDisconnected) Self::Send(GenericSendError::RxDisconnected)
} }
} }
@ -769,14 +769,14 @@ pub mod std_mod {
use super::*; use super::*;
use crossbeam_channel as cb; use crossbeam_channel as cb;
impl From<cb::SendError<StoreAddr>> for EcssTmtcError { impl From<cb::SendError<PoolAddr>> for EcssTmtcError {
fn from(_: cb::SendError<StoreAddr>) -> Self { fn from(_: cb::SendError<PoolAddr>) -> Self {
Self::Send(GenericSendError::RxDisconnected) Self::Send(GenericSendError::RxDisconnected)
} }
} }
impl From<cb::TrySendError<StoreAddr>> for EcssTmtcError { impl From<cb::TrySendError<PoolAddr>> for EcssTmtcError {
fn from(value: cb::TrySendError<StoreAddr>) -> Self { fn from(value: cb::TrySendError<PoolAddr>) -> Self {
match value { match value {
cb::TrySendError::Full(_) => Self::Send(GenericSendError::QueueFull(None)), cb::TrySendError::Full(_) => Self::Send(GenericSendError::QueueFull(None)),
cb::TrySendError::Disconnected(_) => { cb::TrySendError::Disconnected(_) => {
@ -952,6 +952,8 @@ pub mod std_mod {
fn tc_slice_raw(&self) -> &[u8]; fn tc_slice_raw(&self) -> &[u8];
fn sender_id(&self) -> Option<ComponentId>;
fn cache_and_convert( fn cache_and_convert(
&mut self, &mut self,
possible_packet: &TcInMemory, possible_packet: &TcInMemory,
@ -974,6 +976,7 @@ pub mod std_mod {
/// [SharedStaticMemoryPool]. /// [SharedStaticMemoryPool].
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct EcssTcInVecConverter { pub struct EcssTcInVecConverter {
sender_id: Option<ComponentId>,
pub pus_tc_raw: Option<Vec<u8>>, pub pus_tc_raw: Option<Vec<u8>>,
} }
@ -981,16 +984,21 @@ pub mod std_mod {
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> { fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
self.pus_tc_raw = None; self.pus_tc_raw = None;
match tc_in_memory { match tc_in_memory {
super::TcInMemory::StoreAddr(_) => { super::TcInMemory::Pool(_packet_in_pool) => {
return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone())); return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone()));
} }
super::TcInMemory::Vec(vec) => { super::TcInMemory::Vec(packet_with_sender) => {
self.pus_tc_raw = Some(vec.clone()); self.pus_tc_raw = Some(packet_with_sender.packet.clone());
self.sender_id = Some(packet_with_sender.sender_id);
} }
}; };
Ok(()) Ok(())
} }
fn sender_id(&self) -> Option<ComponentId> {
self.sender_id
}
fn tc_slice_raw(&self) -> &[u8] { fn tc_slice_raw(&self) -> &[u8] {
if self.pus_tc_raw.is_none() { if self.pus_tc_raw.is_none() {
return &[]; return &[];
@ -1004,6 +1012,7 @@ pub mod std_mod {
/// packets should be avoided. Please note that this structure is not able to convert TCs which /// packets should be avoided. Please note that this structure is not able to convert TCs which
/// are stored as a `Vec<u8>`. /// are stored as a `Vec<u8>`.
pub struct EcssTcInSharedStoreConverter { pub struct EcssTcInSharedStoreConverter {
sender_id: Option<ComponentId>,
shared_tc_store: SharedStaticMemoryPool, shared_tc_store: SharedStaticMemoryPool,
pus_buf: Vec<u8>, pus_buf: Vec<u8>,
} }
@ -1011,15 +1020,16 @@ pub mod std_mod {
impl EcssTcInSharedStoreConverter { impl EcssTcInSharedStoreConverter {
pub fn new(shared_tc_store: SharedStaticMemoryPool, max_expected_tc_size: usize) -> Self { pub fn new(shared_tc_store: SharedStaticMemoryPool, max_expected_tc_size: usize) -> Self {
Self { Self {
sender_id: None,
shared_tc_store, shared_tc_store,
pus_buf: alloc::vec![0; max_expected_tc_size], pus_buf: alloc::vec![0; max_expected_tc_size],
} }
} }
pub fn copy_tc_to_buf(&mut self, addr: StoreAddr) -> Result<(), PusTcFromMemError> { pub fn copy_tc_to_buf(&mut self, addr: PoolAddr) -> Result<(), PusTcFromMemError> {
// Keep locked section as short as possible. // Keep locked section as short as possible.
let mut tc_pool = self.shared_tc_store.write().map_err(|_| { let mut tc_pool = self.shared_tc_store.write().map_err(|_| {
PusTcFromMemError::EcssTmtc(EcssTmtcError::Store(StoreError::LockError)) PusTcFromMemError::EcssTmtc(EcssTmtcError::Store(PoolError::LockError))
})?; })?;
let tc_size = tc_pool.len_of_data(&addr).map_err(EcssTmtcError::Store)?; let tc_size = tc_pool.len_of_data(&addr).map_err(EcssTmtcError::Store)?;
if tc_size > self.pus_buf.len() { if tc_size > self.pus_buf.len() {
@ -1041,8 +1051,9 @@ pub mod std_mod {
impl EcssTcInMemConverter for EcssTcInSharedStoreConverter { impl EcssTcInMemConverter for EcssTcInSharedStoreConverter {
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> { fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
match tc_in_memory { match tc_in_memory {
super::TcInMemory::StoreAddr(addr) => { super::TcInMemory::Pool(packet_in_pool) => {
self.copy_tc_to_buf(*addr)?; self.copy_tc_to_buf(packet_in_pool.store_addr)?;
self.sender_id = Some(packet_in_pool.sender_id);
} }
super::TcInMemory::Vec(_) => { super::TcInMemory::Vec(_) => {
return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone())); return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone()));
@ -1054,6 +1065,10 @@ pub mod std_mod {
fn tc_slice_raw(&self) -> &[u8] { fn tc_slice_raw(&self) -> &[u8] {
self.pus_buf.as_ref() self.pus_buf.as_ref()
} }
fn sender_id(&self) -> Option<ComponentId> {
self.sender_id
}
} }
pub struct PusServiceBase< pub struct PusServiceBase<
@ -1364,7 +1379,12 @@ pub mod tests {
), ),
) )
} }
pub fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) { pub fn send_tc(
&self,
sender_id: ComponentId,
token: &VerificationToken<TcStateAccepted>,
tc: &PusTcCreator,
) {
let mut mut_buf = self.pus_buf.borrow_mut(); let mut mut_buf = self.pus_buf.borrow_mut();
let tc_size = tc.write_to_bytes(mut_buf.as_mut_slice()).unwrap(); let tc_size = tc.write_to_bytes(mut_buf.as_mut_slice()).unwrap();
let mut tc_pool = self.tc_pool.write().unwrap(); let mut tc_pool = self.tc_pool.write().unwrap();
@ -1372,7 +1392,10 @@ pub mod tests {
drop(tc_pool); drop(tc_pool);
// Send accepted TC to test service handler. // Send accepted TC to test service handler.
self.tc_sender self.tc_sender
.send(EcssTcAndToken::new(addr, *token)) .send(EcssTcAndToken::new(
PacketInPool::new(sender_id, addr),
*token,
))
.expect("sending tc failed"); .expect("sending tc failed");
} }
@ -1486,11 +1509,19 @@ pub mod tests {
} }
impl PusServiceHandlerWithVecCommon { impl PusServiceHandlerWithVecCommon {
pub fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) { pub fn send_tc(
&self,
sender_id: ComponentId,
token: &VerificationToken<TcStateAccepted>,
tc: &PusTcCreator,
) {
// Send accepted TC to test service handler. // Send accepted TC to test service handler.
self.tc_sender self.tc_sender
.send(EcssTcAndToken::new( .send(EcssTcAndToken::new(
TcInMemory::Vec(tc.to_vec().expect("pus tc conversion to vec failed")), TcInMemory::Vec(PacketAsVec::new(
sender_id,
tc.to_vec().expect("pus tc conversion to vec failed"),
)),
*token, *token,
)) ))
.expect("sending tc failed"); .expect("sending tc failed");

View File

@ -14,7 +14,7 @@ use spacepackets::{ByteConversionError, CcsdsPacket};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::error::Error; use std::error::Error;
use crate::pool::{PoolProvider, StoreError}; use crate::pool::{PoolError, PoolProvider};
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub use alloc_mod::*; pub use alloc_mod::*;
@ -151,7 +151,7 @@ pub enum ScheduleError {
}, },
/// Nested time-tagged commands are not allowed. /// Nested time-tagged commands are not allowed.
NestedScheduledTc, NestedScheduledTc,
StoreError(StoreError), StoreError(PoolError),
TcDataEmpty, TcDataEmpty,
TimestampError(TimestampError), TimestampError(TimestampError),
WrongSubservice(u8), WrongSubservice(u8),
@ -206,8 +206,8 @@ impl From<PusError> for ScheduleError {
} }
} }
impl From<StoreError> for ScheduleError { impl From<PoolError> for ScheduleError {
fn from(e: StoreError) -> Self { fn from(e: PoolError) -> Self {
Self::StoreError(e) Self::StoreError(e)
} }
} }
@ -240,7 +240,7 @@ impl Error for ScheduleError {
pub trait PusSchedulerProvider { pub trait PusSchedulerProvider {
type TimeProvider: CcsdsTimeProvider + TimeReader; type TimeProvider: CcsdsTimeProvider + TimeReader;
fn reset(&mut self, store: &mut (impl PoolProvider + ?Sized)) -> Result<(), StoreError>; fn reset(&mut self, store: &mut (impl PoolProvider + ?Sized)) -> Result<(), PoolError>;
fn is_enabled(&self) -> bool; fn is_enabled(&self) -> bool;
@ -347,7 +347,7 @@ pub mod alloc_mod {
}; };
use spacepackets::time::cds::{self, DaysLen24Bits}; use spacepackets::time::cds::{self, DaysLen24Bits};
use crate::pool::StoreAddr; use crate::pool::PoolAddr;
use super::*; use super::*;
@ -368,8 +368,8 @@ pub mod alloc_mod {
} }
enum DeletionResult { enum DeletionResult {
WithoutStoreDeletion(Option<StoreAddr>), WithoutStoreDeletion(Option<PoolAddr>),
WithStoreDeletion(Result<bool, StoreError>), WithStoreDeletion(Result<bool, PoolError>),
} }
/// This is the core data structure for scheduling PUS telecommands with [alloc] support. /// This is the core data structure for scheduling PUS telecommands with [alloc] support.
@ -525,7 +525,7 @@ pub mod alloc_mod {
&mut self, &mut self,
time_window: TimeWindow<TimeProvider>, time_window: TimeWindow<TimeProvider>,
pool: &mut (impl PoolProvider + ?Sized), pool: &mut (impl PoolProvider + ?Sized),
) -> Result<u64, (u64, StoreError)> { ) -> Result<u64, (u64, PoolError)> {
let range = self.retrieve_by_time_filter(time_window); let range = self.retrieve_by_time_filter(time_window);
let mut del_packets = 0; let mut del_packets = 0;
let mut res_if_fails = None; let mut res_if_fails = None;
@ -555,7 +555,7 @@ pub mod alloc_mod {
pub fn delete_all( pub fn delete_all(
&mut self, &mut self,
pool: &mut (impl PoolProvider + ?Sized), pool: &mut (impl PoolProvider + ?Sized),
) -> Result<u64, (u64, StoreError)> { ) -> Result<u64, (u64, PoolError)> {
self.delete_by_time_filter(TimeWindow::<cds::CdsTime>::new_select_all(), pool) self.delete_by_time_filter(TimeWindow::<cds::CdsTime>::new_select_all(), pool)
} }
@ -601,7 +601,7 @@ pub mod alloc_mod {
/// Please note that this function will stop on the first telecommand with a request ID match. /// Please note that this function will stop on the first telecommand with a request ID match.
/// In case of duplicate IDs (which should generally not happen), this function needs to be /// In case of duplicate IDs (which should generally not happen), this function needs to be
/// called repeatedly. /// called repeatedly.
pub fn delete_by_request_id(&mut self, req_id: &RequestId) -> Option<StoreAddr> { pub fn delete_by_request_id(&mut self, req_id: &RequestId) -> Option<PoolAddr> {
if let DeletionResult::WithoutStoreDeletion(v) = if let DeletionResult::WithoutStoreDeletion(v) =
self.delete_by_request_id_internal_without_store_deletion(req_id) self.delete_by_request_id_internal_without_store_deletion(req_id)
{ {
@ -615,7 +615,7 @@ pub mod alloc_mod {
&mut self, &mut self,
req_id: &RequestId, req_id: &RequestId,
pool: &mut (impl PoolProvider + ?Sized), pool: &mut (impl PoolProvider + ?Sized),
) -> Result<bool, StoreError> { ) -> Result<bool, PoolError> {
if let DeletionResult::WithStoreDeletion(v) = if let DeletionResult::WithStoreDeletion(v) =
self.delete_by_request_id_internal_with_store_deletion(req_id, pool) self.delete_by_request_id_internal_with_store_deletion(req_id, pool)
{ {
@ -693,7 +693,7 @@ pub mod alloc_mod {
releaser: R, releaser: R,
tc_store: &mut (impl PoolProvider + ?Sized), tc_store: &mut (impl PoolProvider + ?Sized),
tc_buf: &mut [u8], tc_buf: &mut [u8],
) -> Result<u64, (u64, StoreError)> { ) -> Result<u64, (u64, PoolError)> {
self.release_telecommands_internal(releaser, tc_store, Some(tc_buf)) self.release_telecommands_internal(releaser, tc_store, Some(tc_buf))
} }
@ -707,7 +707,7 @@ pub mod alloc_mod {
&mut self, &mut self,
releaser: R, releaser: R,
tc_store: &mut (impl PoolProvider + ?Sized), tc_store: &mut (impl PoolProvider + ?Sized),
) -> Result<u64, (u64, StoreError)> { ) -> Result<u64, (u64, PoolError)> {
self.release_telecommands_internal(releaser, tc_store, None) self.release_telecommands_internal(releaser, tc_store, None)
} }
@ -716,7 +716,7 @@ pub mod alloc_mod {
mut releaser: R, mut releaser: R,
tc_store: &mut (impl PoolProvider + ?Sized), tc_store: &mut (impl PoolProvider + ?Sized),
mut tc_buf: Option<&mut [u8]>, mut tc_buf: Option<&mut [u8]>,
) -> Result<u64, (u64, StoreError)> { ) -> Result<u64, (u64, PoolError)> {
let tcs_to_release = self.telecommands_to_release(); let tcs_to_release = self.telecommands_to_release();
let mut released_tcs = 0; let mut released_tcs = 0;
let mut store_error = Ok(()); let mut store_error = Ok(());
@ -762,7 +762,7 @@ pub mod alloc_mod {
mut releaser: R, mut releaser: R,
tc_store: &(impl PoolProvider + ?Sized), tc_store: &(impl PoolProvider + ?Sized),
tc_buf: &mut [u8], tc_buf: &mut [u8],
) -> Result<alloc::vec::Vec<TcInfo>, (alloc::vec::Vec<TcInfo>, StoreError)> { ) -> Result<alloc::vec::Vec<TcInfo>, (alloc::vec::Vec<TcInfo>, PoolError)> {
let tcs_to_release = self.telecommands_to_release(); let tcs_to_release = self.telecommands_to_release();
let mut released_tcs = alloc::vec::Vec::new(); let mut released_tcs = alloc::vec::Vec::new();
for tc in tcs_to_release { for tc in tcs_to_release {
@ -793,7 +793,7 @@ pub mod alloc_mod {
/// The holding store for the telecommands needs to be passed so all the stored telecommands /// The holding store for the telecommands needs to be passed so all the stored telecommands
/// can be deleted to avoid a memory leak. If at last one deletion operation fails, the error /// can be deleted to avoid a memory leak. If at last one deletion operation fails, the error
/// will be returned but the method will still try to delete all the commands in the schedule. /// will be returned but the method will still try to delete all the commands in the schedule.
fn reset(&mut self, store: &mut (impl PoolProvider + ?Sized)) -> Result<(), StoreError> { fn reset(&mut self, store: &mut (impl PoolProvider + ?Sized)) -> Result<(), PoolError> {
self.enabled = false; self.enabled = false;
let mut deletion_ok = Ok(()); let mut deletion_ok = Ok(());
for tc_lists in &mut self.tc_map { for tc_lists in &mut self.tc_map {
@ -851,7 +851,7 @@ pub mod alloc_mod {
mod tests { mod tests {
use super::*; use super::*;
use crate::pool::{ use crate::pool::{
PoolProvider, StaticMemoryPool, StaticPoolAddr, StaticPoolConfig, StoreAddr, StoreError, PoolAddr, PoolError, PoolProvider, StaticMemoryPool, StaticPoolAddr, StaticPoolConfig,
}; };
use alloc::collections::btree_map::Range; use alloc::collections::btree_map::Range;
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader}; use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
@ -990,7 +990,7 @@ mod tests {
.insert_unwrapped_and_stored_tc( .insert_unwrapped_and_stored_tc(
UnixTime::new_only_secs(100), UnixTime::new_only_secs(100),
TcInfo::new( TcInfo::new(
StoreAddr::from(StaticPoolAddr { PoolAddr::from(StaticPoolAddr {
pool_idx: 0, pool_idx: 0,
packet_idx: 1, packet_idx: 1,
}), }),
@ -1007,7 +1007,7 @@ mod tests {
.insert_unwrapped_and_stored_tc( .insert_unwrapped_and_stored_tc(
UnixTime::new_only_secs(100), UnixTime::new_only_secs(100),
TcInfo::new( TcInfo::new(
StoreAddr::from(StaticPoolAddr { PoolAddr::from(StaticPoolAddr {
pool_idx: 0, pool_idx: 0,
packet_idx: 2, packet_idx: 2,
}), }),
@ -1051,8 +1051,8 @@ mod tests {
fn common_check( fn common_check(
enabled: bool, enabled: bool,
store_addr: &StoreAddr, store_addr: &PoolAddr,
expected_store_addrs: Vec<StoreAddr>, expected_store_addrs: Vec<PoolAddr>,
counter: &mut usize, counter: &mut usize,
) { ) {
assert!(enabled); assert!(enabled);
@ -1061,8 +1061,8 @@ mod tests {
} }
fn common_check_disabled( fn common_check_disabled(
enabled: bool, enabled: bool,
store_addr: &StoreAddr, store_addr: &PoolAddr,
expected_store_addrs: Vec<StoreAddr>, expected_store_addrs: Vec<PoolAddr>,
counter: &mut usize, counter: &mut usize,
) { ) {
assert!(!enabled); assert!(!enabled);
@ -1516,7 +1516,7 @@ mod tests {
// TC could not even be read.. // TC could not even be read..
assert_eq!(err.0, 0); assert_eq!(err.0, 0);
match err.1 { match err.1 {
StoreError::DataDoesNotExist(addr) => { PoolError::DataDoesNotExist(addr) => {
assert_eq!(tc_info_0.addr(), addr); assert_eq!(tc_info_0.addr(), addr);
} }
_ => panic!("unexpected error {}", err.1), _ => panic!("unexpected error {}", err.1),
@ -1539,7 +1539,7 @@ mod tests {
assert!(reset_res.is_err()); assert!(reset_res.is_err());
let err = reset_res.unwrap_err(); let err = reset_res.unwrap_err();
match err { match err {
StoreError::DataDoesNotExist(addr) => { PoolError::DataDoesNotExist(addr) => {
assert_eq!(addr, tc_info_0.addr()); assert_eq!(addr, tc_info_0.addr());
} }
_ => panic!("unexpected error {err}"), _ => panic!("unexpected error {err}"),
@ -1641,7 +1641,7 @@ mod tests {
let err = insert_res.unwrap_err(); let err = insert_res.unwrap_err();
match err { match err {
ScheduleError::StoreError(e) => match e { ScheduleError::StoreError(e) => match e {
StoreError::StoreFull(_) => {} PoolError::StoreFull(_) => {}
_ => panic!("unexpected store error {e}"), _ => panic!("unexpected store error {e}"),
}, },
_ => panic!("unexpected error {err}"), _ => panic!("unexpected error {err}"),

View File

@ -315,9 +315,13 @@ mod tests {
.expect("acceptance success failure") .expect("acceptance success failure")
} }
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) {
self.common
.send_tc(self.handler.service_helper.id(), token, tc);
}
delegate! { delegate! {
to self.common { to self.common {
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator);
fn read_next_tm(&mut self) -> PusTmReader<'_>; fn read_next_tm(&mut self) -> PusTmReader<'_>;
fn check_no_tm_available(&self) -> bool; fn check_no_tm_available(&self) -> bool;
fn check_next_verification_tm(&self, subservice: u8, expected_request_id: RequestId); fn check_next_verification_tm(&self, subservice: u8, expected_request_id: RequestId);
@ -340,7 +344,7 @@ mod tests {
fn reset( fn reset(
&mut self, &mut self,
_store: &mut (impl crate::pool::PoolProvider + ?Sized), _store: &mut (impl crate::pool::PoolProvider + ?Sized),
) -> Result<(), crate::pool::StoreError> { ) -> Result<(), crate::pool::PoolError> {
self.reset_count += 1; self.reset_count += 1;
Ok(()) Ok(())
} }

View File

@ -203,10 +203,14 @@ mod tests {
.expect("acceptance success failure") .expect("acceptance success failure")
} }
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) {
self.common
.send_tc(self.handler.service_helper.id(), token, tc);
}
delegate! { delegate! {
to self.common { to self.common {
fn read_next_tm(&mut self) -> PusTmReader<'_>; fn read_next_tm(&mut self) -> PusTmReader<'_>;
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator);
fn check_no_tm_available(&self) -> bool; fn check_no_tm_available(&self) -> bool;
fn check_next_verification_tm( fn check_next_verification_tm(
&self, &self,
@ -254,9 +258,13 @@ mod tests {
.expect("acceptance success failure") .expect("acceptance success failure")
} }
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) {
self.common
.send_tc(self.handler.service_helper.id(), token, tc);
}
delegate! { delegate! {
to self.common { to self.common {
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator);
fn read_next_tm(&mut self) -> PusTmReader<'_>; fn read_next_tm(&mut self) -> PusTmReader<'_>;
fn check_no_tm_available(&self) -> bool; fn check_no_tm_available(&self) -> bool;
fn check_next_verification_tm( fn check_next_verification_tm(

View File

@ -10,7 +10,7 @@
#[cfg(feature = "std")] #[cfg(feature = "std")]
use crate::queue::GenericSendError; use crate::queue::GenericSendError;
use crate::{ use crate::{
pool::{PoolProvider, StoreAddr, StoreError}, pool::{PoolAddr, PoolError, PoolProvider},
ComponentId, ComponentId,
}; };
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -33,14 +33,16 @@ pub use std_mod::*;
pub mod tm_helper; pub mod tm_helper;
#[derive(Debug)] /// Simple type modelling packet stored inside a pool structure. This structure is intended to
/// be used when sending a packet via a message queue, so it also contains the sender ID.
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct PacketInPool { pub struct PacketInPool {
pub sender_id: ComponentId, pub sender_id: ComponentId,
pub store_addr: StoreAddr, pub store_addr: PoolAddr,
} }
impl PacketInPool { impl PacketInPool {
pub fn new(sender_id: ComponentId, store_addr: StoreAddr) -> Self { pub fn new(sender_id: ComponentId, store_addr: PoolAddr) -> Self {
Self { Self {
sender_id, sender_id,
store_addr, store_addr,
@ -183,27 +185,27 @@ impl SharedPacketPool {
/// Helper trait for any generic (static) store which allows storing raw or CCSDS packets. /// Helper trait for any generic (static) store which allows storing raw or CCSDS packets.
pub trait CcsdsPacketPool { pub trait CcsdsPacketPool {
fn add_ccsds_tc(&mut self, _: &SpHeader, tc_raw: &[u8]) -> Result<StoreAddr, StoreError> { fn add_ccsds_tc(&mut self, _: &SpHeader, tc_raw: &[u8]) -> Result<PoolAddr, PoolError> {
self.add_raw_tc(tc_raw) self.add_raw_tc(tc_raw)
} }
fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result<StoreAddr, StoreError>; fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result<PoolAddr, PoolError>;
} }
/// Helper trait for any generic (static) store which allows storing ECSS PUS Telecommand packets. /// Helper trait for any generic (static) store which allows storing ECSS PUS Telecommand packets.
pub trait PusTcPool { pub trait PusTcPool {
fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result<StoreAddr, StoreError>; fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result<PoolAddr, PoolError>;
} }
/// Helper trait for any generic (static) store which allows storing ECSS PUS Telemetry packets. /// Helper trait for any generic (static) store which allows storing ECSS PUS Telemetry packets.
pub trait PusTmPool { pub trait PusTmPool {
fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result<StoreAddr, StoreError>; fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result<PoolAddr, PoolError>;
fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result<StoreAddr, StoreError>; fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result<PoolAddr, PoolError>;
} }
impl PusTcPool for SharedPacketPool { impl PusTcPool for SharedPacketPool {
fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result<StoreAddr, StoreError> { fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result<PoolAddr, PoolError> {
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?; let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
let addr = pg.free_element(pus_tc.len_packed(), |buf| { let addr = pg.free_element(pus_tc.len_packed(), |buf| {
buf[0..pus_tc.len_packed()].copy_from_slice(pus_tc.raw_data()); buf[0..pus_tc.len_packed()].copy_from_slice(pus_tc.raw_data());
})?; })?;
@ -212,16 +214,16 @@ impl PusTcPool for SharedPacketPool {
} }
impl PusTmPool for SharedPacketPool { impl PusTmPool for SharedPacketPool {
fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result<StoreAddr, StoreError> { fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result<PoolAddr, PoolError> {
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?; let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
let addr = pg.free_element(pus_tm.len_packed(), |buf| { let addr = pg.free_element(pus_tm.len_packed(), |buf| {
buf[0..pus_tm.len_packed()].copy_from_slice(pus_tm.raw_data()); buf[0..pus_tm.len_packed()].copy_from_slice(pus_tm.raw_data());
})?; })?;
Ok(addr) Ok(addr)
} }
fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result<StoreAddr, StoreError> { fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result<PoolAddr, PoolError> {
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?; let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
let mut result = Ok(0); let mut result = Ok(0);
let addr = pg.free_element(pus_tm.len_written(), |buf| { let addr = pg.free_element(pus_tm.len_written(), |buf| {
result = pus_tm.write_to_bytes(buf); result = pus_tm.write_to_bytes(buf);
@ -232,8 +234,8 @@ impl PusTmPool for SharedPacketPool {
} }
impl CcsdsPacketPool for SharedPacketPool { impl CcsdsPacketPool for SharedPacketPool {
fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result<StoreAddr, StoreError> { fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result<PoolAddr, PoolError> {
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?; let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
let addr = pg.free_element(tc_raw.len(), |buf| { let addr = pg.free_element(tc_raw.len(), |buf| {
buf[0..tc_raw.len()].copy_from_slice(tc_raw); buf[0..tc_raw.len()].copy_from_slice(tc_raw);
})?; })?;
@ -246,7 +248,7 @@ pub trait PacketInPoolSender: Send {
fn send_packet( fn send_packet(
&self, &self,
sender_id: ComponentId, sender_id: ComponentId,
store_addr: StoreAddr, store_addr: PoolAddr,
) -> Result<(), GenericSendError>; ) -> Result<(), GenericSendError>;
} }
@ -256,7 +258,9 @@ pub mod alloc_mod {
use super::*; use super::*;
#[derive(Debug)] /// Simple type modelling packet stored in the heap. This structure is intended to
/// be used when sending a packet via a message queue, so it also contains the sender ID.
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct PacketAsVec { pub struct PacketAsVec {
pub sender_id: ComponentId, pub sender_id: ComponentId,
pub packet: Vec<u8>, pub packet: Vec<u8>,
@ -305,7 +309,7 @@ pub mod std_mod {
#[derive(Debug, Clone, PartialEq, Eq, Error)] #[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum StoreAndSendError { pub enum StoreAndSendError {
#[error("Store error: {0}")] #[error("Store error: {0}")]
Store(#[from] StoreError), Store(#[from] PoolError),
#[error("Genreric send error: {0}")] #[error("Genreric send error: {0}")]
Send(#[from] GenericSendError), Send(#[from] GenericSendError),
} }
@ -316,7 +320,7 @@ pub mod std_mod {
fn send_packet( fn send_packet(
&self, &self,
sender_id: ComponentId, sender_id: ComponentId,
store_addr: StoreAddr, store_addr: PoolAddr,
) -> Result<(), GenericSendError> { ) -> Result<(), GenericSendError> {
self.send(PacketInPool::new(sender_id, store_addr)) self.send(PacketInPool::new(sender_id, store_addr))
.map_err(|_| GenericSendError::RxDisconnected) .map_err(|_| GenericSendError::RxDisconnected)
@ -327,7 +331,7 @@ pub mod std_mod {
fn send_packet( fn send_packet(
&self, &self,
sender_id: ComponentId, sender_id: ComponentId,
store_addr: StoreAddr, store_addr: PoolAddr,
) -> Result<(), GenericSendError> { ) -> Result<(), GenericSendError> {
self.try_send(PacketInPool::new(sender_id, store_addr)) self.try_send(PacketInPool::new(sender_id, store_addr))
.map_err(|e| match e { .map_err(|e| match e {
@ -342,7 +346,7 @@ pub mod std_mod {
fn send_packet( fn send_packet(
&self, &self,
sender_id: ComponentId, sender_id: ComponentId,
store_addr: StoreAddr, store_addr: PoolAddr,
) -> Result<(), GenericSendError> { ) -> Result<(), GenericSendError> {
self.try_send(PacketInPool::new(sender_id, store_addr)) self.try_send(PacketInPool::new(sender_id, store_addr))
.map_err(|e| match e { .map_err(|e| match e {
@ -455,7 +459,7 @@ pub mod std_mod {
sender_id: crate::ComponentId, sender_id: crate::ComponentId,
tm: crate::pus::PusTmVariant, tm: crate::pus::PusTmVariant,
) -> Result<(), crate::pus::EcssTmtcError> { ) -> Result<(), crate::pus::EcssTmtcError> {
let send_addr = |store_addr: StoreAddr| { let send_addr = |store_addr: PoolAddr| {
self.sender self.sender
.send_packet(sender_id, store_addr) .send_packet(sender_id, store_addr)
.map_err(EcssTmtcError::Send) .map_err(EcssTmtcError::Send)
@ -632,7 +636,7 @@ pub(crate) mod tests {
assert!(result.is_err()); assert!(result.is_err());
matches!( matches!(
result.unwrap_err(), result.unwrap_err(),
StoreAndSendError::Store(StoreError::StoreFull(..)) StoreAndSendError::Store(PoolError::StoreFull(..))
); );
let packet_in_pool = tc_rx.try_recv().unwrap(); let packet_in_pool = tc_rx.try_recv().unwrap();
let mut pool = shared_pool.0.write().unwrap(); let mut pool = shared_pool.0.write().unwrap();

View File

@ -1,4 +1,4 @@
use satrs::pool::{PoolGuard, PoolProvider, StaticMemoryPool, StaticPoolConfig, StoreAddr}; use satrs::pool::{PoolAddr, PoolGuard, PoolProvider, StaticMemoryPool, StaticPoolConfig};
use std::ops::DerefMut; use std::ops::DerefMut;
use std::sync::mpsc; use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender}; use std::sync::mpsc::{Receiver, Sender};
@ -12,7 +12,7 @@ fn threaded_usage() {
let pool_cfg = StaticPoolConfig::new(vec![(16, 6), (32, 3), (8, 12)], false); let pool_cfg = StaticPoolConfig::new(vec![(16, 6), (32, 3), (8, 12)], false);
let shared_pool = Arc::new(RwLock::new(StaticMemoryPool::new(pool_cfg))); let shared_pool = Arc::new(RwLock::new(StaticMemoryPool::new(pool_cfg)));
let shared_clone = shared_pool.clone(); let shared_clone = shared_pool.clone();
let (tx, rx): (Sender<StoreAddr>, Receiver<StoreAddr>) = mpsc::channel(); let (tx, rx): (Sender<PoolAddr>, Receiver<PoolAddr>) = mpsc::channel();
let jh0 = thread::spawn(move || { let jh0 = thread::spawn(move || {
let mut dummy = shared_pool.write().unwrap(); let mut dummy = shared_pool.write().unwrap();
let addr = dummy.add(&DUMMY_DATA).expect("Writing data failed"); let addr = dummy.add(&DUMMY_DATA).expect("Writing data failed");