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()
.check_next_is_acceptance_success(id, accepted_token.request_id());
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();
}
}

View File

@ -1,6 +1,6 @@
use crate::requests::GenericRequestRouter;
use log::warn;
use satrs::pool::StoreAddr;
use satrs::pool::PoolAddr;
use satrs::pus::verification::{
self, FailParams, TcStateAccepted, TcStateStarted, VerificationReporter,
VerificationReporterCfg, VerificationReportingProvider, VerificationToken,
@ -98,7 +98,7 @@ impl<TmSender: EcssTmSender> PusTcDistributor<TmSender> {
pub fn handle_tc_generic(
&mut self,
sender_id: ComponentId,
addr_opt: Option<StoreAddr>,
addr_opt: Option<PoolAddr>,
raw_tc: &[u8],
) -> Result<PusPacketHandlerResult, GenericSendError> {
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())
.expect("Acceptance success failure");
let service = PusServiceId::try_from(pus_tc.service());
let tc_in_memory = if let Some(store_addr) = addr_opt {
TcInMemory::StoreAddr(store_addr)
let tc_in_memory: TcInMemory = if let Some(store_addr) = addr_opt {
PacketInPool::new(sender_id, store_addr).into()
} else {
TcInMemory::Vec(Vec::from(raw_tc))
PacketAsVec::new(sender_id, Vec::from(raw_tc)).into()
};
match 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.
- Renamed `TmPacketSourceCore` to `TmPacketSource`.
- Renamed `EcssTmSenderCore` to `EcssTmSender`.
- Renamed `StoreAddr` to `PoolAddr`.
- Reanmed `StoreError` to `PoolError`.
- TCP server generics order. The error generics come last now.
- `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.

View File

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

View File

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

View File

@ -206,10 +206,14 @@ mod tests {
};
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},
ConnectionResult, ServerConfig,
}, queue::GenericSendError, tmtc::PacketAsVec, ComponentId
},
queue::GenericSendError,
tmtc::PacketAsVec,
ComponentId,
};
use alloc::sync::Arc;
use cobs::encode;

View File

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

View File

@ -43,7 +43,7 @@
//! 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
//! require [alloc] support but allow for more flexbility.
use crate::pool::StoreAddr;
use crate::pool::PoolAddr;
use core::fmt::Debug;
use core::mem::size_of;
use paste::paste;
@ -588,15 +588,15 @@ from_conversions_for_raw!(
#[non_exhaustive]
pub enum Params {
Heapless(ParamsHeapless),
Store(StoreAddr),
Store(PoolAddr),
#[cfg(feature = "alloc")]
Vec(Vec<u8>),
#[cfg(feature = "alloc")]
String(String),
}
impl From<StoreAddr> for Params {
fn from(x: StoreAddr) -> Self {
impl From<PoolAddr> for Params {
fn from(x: PoolAddr) -> Self {
Self::Store(x)
}
}

View File

@ -82,7 +82,7 @@ use spacepackets::ByteConversionError;
use std::error::Error;
type NumBlocks = u16;
pub type StoreAddr = u64;
pub type PoolAddr = u64;
/// Simple address type used for transactions with the local pool.
#[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 {
((value.pool_idx as u64) << 16) | value.packet_idx as u64
}
}
impl From<StoreAddr> for StaticPoolAddr {
fn from(value: StoreAddr) -> Self {
impl From<PoolAddr> for StaticPoolAddr {
fn from(value: PoolAddr) -> Self {
Self {
pool_idx: ((value >> 16) & 0xff) as u16,
packet_idx: (value & 0xff) as u16,
@ -150,59 +150,59 @@ impl Error for StoreIdError {}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum StoreError {
pub enum PoolError {
/// Requested data block is too large
DataTooLarge(usize),
/// The store is full. Contains the index of the full subpool
StoreFull(u16),
/// 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
DataDoesNotExist(StoreAddr),
DataDoesNotExist(PoolAddr),
ByteConversionError(spacepackets::ByteConversionError),
LockError,
/// Internal or configuration errors
InternalError(u32),
}
impl Display for StoreError {
impl Display for PoolError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
StoreError::DataTooLarge(size) => {
PoolError::DataTooLarge(size) => {
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}")
}
StoreError::InvalidStoreId(id_e, addr) => {
PoolError::InvalidStoreId(id_e, addr) => {
write!(f, "invalid store ID: {id_e}, address: {addr:?}")
}
StoreError::DataDoesNotExist(addr) => {
PoolError::DataDoesNotExist(addr) => {
write!(f, "no data exists at address {addr:?}")
}
StoreError::InternalError(e) => {
PoolError::InternalError(e) => {
write!(f, "internal error: {e}")
}
StoreError::ByteConversionError(e) => {
PoolError::ByteConversionError(e) => {
write!(f, "store error: {e}")
}
StoreError::LockError => {
PoolError::LockError => {
write!(f, "lock error")
}
}
}
}
impl From<ByteConversionError> for StoreError {
impl From<ByteConversionError> for PoolError {
fn from(value: ByteConversionError) -> Self {
Self::ByteConversionError(value)
}
}
#[cfg(feature = "std")]
impl Error for StoreError {
impl Error for PoolError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
if let StoreError::InvalidStoreId(e, _) = self {
if let PoolError::InvalidStoreId(e, _) = self {
return Some(e);
}
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
/// 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
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.
/// It then executes a user-provided closure and passes a mutable reference to that memory
@ -230,31 +230,28 @@ pub trait PoolProvider {
&mut self,
len: usize,
writer: W,
) -> Result<StoreAddr, StoreError>;
) -> Result<PoolAddr, PoolError>;
/// 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
/// 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.
fn modify<U: FnMut(&mut [u8])>(
&mut self,
addr: &StoreAddr,
updater: U,
) -> Result<(), StoreError>;
fn modify<U: FnMut(&mut [u8])>(&mut self, addr: &PoolAddr, updater: U)
-> Result<(), PoolError>;
/// The provider should copy the data from the memory block to the user-provided buffer if
/// 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].
fn delete(&mut self, addr: StoreAddr) -> Result<(), StoreError>;
fn has_element_at(&self, addr: &StoreAddr) -> Result<bool, StoreError>;
fn delete(&mut self, addr: PoolAddr) -> Result<(), PoolError>;
fn has_element_at(&self, addr: &PoolAddr) -> Result<bool, PoolError>;
/// 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")]
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)?];
self.read(addr, &mut 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
/// 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.
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
/// 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
/// 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.
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> {
pool: &'a mut MemProvider,
pub addr: StoreAddr,
pub addr: PoolAddr,
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
/// leaks.
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 {
pool,
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)
}
#[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)
}
@ -334,19 +331,19 @@ pub struct PoolRwGuard<'a, MemProvider: PoolProvider + ?Sized> {
}
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 {
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)
}
delegate!(
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
/// is dropped.
pub fn release(&mut self);
@ -357,7 +354,7 @@ impl<'a, MemProvider: PoolProvider> PoolRwGuard<'a, MemProvider> {
#[cfg(feature = "alloc")]
mod alloc_mod {
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::Vec;
use spacepackets::ByteConversionError;
@ -452,41 +449,41 @@ mod alloc_mod {
local_pool
}
fn addr_check(&self, addr: &StaticPoolAddr) -> Result<usize, StoreError> {
fn addr_check(&self, addr: &StaticPoolAddr) -> Result<usize, PoolError> {
self.validate_addr(addr)?;
let pool_idx = addr.pool_idx as usize;
let size_list = self.sizes_lists.get(pool_idx).unwrap();
let curr_size = size_list[addr.packet_idx as usize];
if curr_size == STORE_FREE {
return Err(StoreError::DataDoesNotExist(StoreAddr::from(*addr)));
return Err(PoolError::DataDoesNotExist(PoolAddr::from(*addr)));
}
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;
if pool_idx >= self.pool_cfg.cfg.len() {
return Err(StoreError::InvalidStoreId(
return Err(PoolError::InvalidStoreId(
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 {
return Err(StoreError::InvalidStoreId(
return Err(PoolError::InvalidStoreId(
StoreIdError::InvalidPacketIdx(addr.packet_idx),
Some(StoreAddr::from(*addr)),
Some(PoolAddr::from(*addr)),
));
}
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)?;
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() {
return Err(StoreError::StoreFull(subpool_idx));
return Err(PoolError::StoreFull(subpool_idx));
}
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() {
if i < start_at_subpool as usize {
continue;
@ -509,21 +506,21 @@ mod alloc_mod {
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> {
let packet_pos = self.raw_pos(addr).ok_or(StoreError::InternalError(0))?;
fn write(&mut self, addr: &StaticPoolAddr, data: &[u8]) -> Result<(), PoolError> {
let packet_pos = self.raw_pos(addr).ok_or(PoolError::InternalError(0))?;
let subpool = self
.pool
.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()];
pool_slice.copy_from_slice(data);
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) {
for (i, elem_size) in size_list.iter_mut().enumerate() {
if *elem_size == STORE_FREE {
@ -531,12 +528,12 @@ mod alloc_mod {
}
}
} else {
return Err(StoreError::InvalidStoreId(
return Err(PoolError::InvalidStoreId(
StoreIdError::InvalidSubpool(subpool),
None,
));
}
Err(StoreError::StoreFull(subpool))
Err(PoolError::StoreFull(subpool))
}
fn raw_pos(&self, addr: &StaticPoolAddr) -> Option<usize> {
@ -546,10 +543,10 @@ mod alloc_mod {
}
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();
if data_len > POOL_MAX_SIZE {
return Err(StoreError::DataTooLarge(data_len));
return Err(PoolError::DataTooLarge(data_len));
}
let addr = self.reserve(data_len)?;
self.write(&addr, data)?;
@ -560,9 +557,9 @@ mod alloc_mod {
&mut self,
len: usize,
mut writer: W,
) -> Result<StoreAddr, StoreError> {
) -> Result<PoolAddr, PoolError> {
if len > POOL_MAX_SIZE {
return Err(StoreError::DataTooLarge(len));
return Err(PoolError::DataTooLarge(len));
}
let addr = self.reserve(len)?;
let raw_pos = self.raw_pos(&addr).unwrap();
@ -574,9 +571,9 @@ mod alloc_mod {
fn modify<U: FnMut(&mut [u8])>(
&mut self,
addr: &StoreAddr,
addr: &PoolAddr,
mut updater: U,
) -> Result<(), StoreError> {
) -> Result<(), PoolError> {
let addr = StaticPoolAddr::from(*addr);
let curr_size = self.addr_check(&addr)?;
let raw_pos = self.raw_pos(&addr).unwrap();
@ -586,7 +583,7 @@ mod alloc_mod {
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 curr_size = self.addr_check(&addr)?;
if buf.len() < curr_size {
@ -604,7 +601,7 @@ mod alloc_mod {
Ok(curr_size)
}
fn delete(&mut self, addr: StoreAddr) -> Result<(), StoreError> {
fn delete(&mut self, addr: PoolAddr) -> Result<(), PoolError> {
let addr = StaticPoolAddr::from(addr);
self.addr_check(&addr)?;
let block_size = self.pool_cfg.cfg.get(addr.pool_idx as usize).unwrap().1;
@ -617,7 +614,7 @@ mod alloc_mod {
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);
self.validate_addr(&addr)?;
let pool_idx = addr.pool_idx as usize;
@ -629,7 +626,7 @@ mod alloc_mod {
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);
self.validate_addr(&addr)?;
let pool_idx = addr.pool_idx as usize;
@ -643,11 +640,11 @@ mod alloc_mod {
}
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)
}
fn read_with_guard(&mut self, addr: StoreAddr) -> PoolGuard<Self> {
fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard<Self> {
PoolGuard::new(self, addr)
}
}
@ -656,8 +653,8 @@ mod alloc_mod {
#[cfg(test)]
mod tests {
use crate::pool::{
PoolGuard, PoolProvider, PoolProviderWithGuards, PoolRwGuard, StaticMemoryPool,
StaticPoolAddr, StaticPoolConfig, StoreError, StoreIdError, POOL_MAX_SIZE,
PoolError, PoolGuard, PoolProvider, PoolProviderWithGuards, PoolRwGuard, StaticMemoryPool,
StaticPoolAddr, StaticPoolConfig, StoreIdError, POOL_MAX_SIZE,
};
use std::vec;
@ -781,7 +778,7 @@ mod tests {
let res = local_pool.free_element(8, |_| {});
assert!(res.is_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
assert!(local_pool.delete(addr0).is_ok());
@ -803,7 +800,7 @@ mod tests {
assert!(res.is_err());
assert!(matches!(
res.unwrap_err(),
StoreError::DataDoesNotExist { .. }
PoolError::DataDoesNotExist { .. }
));
}
@ -816,8 +813,8 @@ mod tests {
let res = local_pool.add(&test_buf);
assert!(res.is_err());
let err = res.unwrap_err();
assert!(matches!(err, StoreError::StoreFull { .. }));
if let StoreError::StoreFull(subpool) = err {
assert!(matches!(err, PoolError::StoreFull { .. }));
if let PoolError::StoreFull(subpool) = err {
assert_eq!(subpool, 2);
}
}
@ -835,7 +832,7 @@ mod tests {
let err = res.unwrap_err();
assert!(matches!(
err,
StoreError::InvalidStoreId(StoreIdError::InvalidSubpool(3), Some(_))
PoolError::InvalidStoreId(StoreIdError::InvalidSubpool(3), Some(_))
));
}
@ -852,7 +849,7 @@ mod tests {
let err = res.unwrap_err();
assert!(matches!(
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);
assert!(res.is_err());
let err = res.unwrap_err();
assert_eq!(err, StoreError::DataTooLarge(20));
assert_eq!(err, PoolError::DataTooLarge(20));
}
#[test]
@ -871,10 +868,7 @@ mod tests {
let mut local_pool = basic_small_pool();
let res = local_pool.free_element(POOL_MAX_SIZE + 1, |_| {});
assert!(res.is_err());
assert_eq!(
res.unwrap_err(),
StoreError::DataTooLarge(POOL_MAX_SIZE + 1)
);
assert_eq!(res.unwrap_err(), PoolError::DataTooLarge(POOL_MAX_SIZE + 1));
}
#[test]
@ -883,7 +877,7 @@ mod tests {
// Try to request a slot which is too large
let res = local_pool.free_element(20, |_| {});
assert!(res.is_err());
assert_eq!(res.unwrap_err(), StoreError::DataTooLarge(20));
assert_eq!(res.unwrap_err(), PoolError::DataTooLarge(20));
}
#[test]
@ -1003,7 +997,7 @@ mod tests {
let should_fail = local_pool.free_element(8, |_| {});
assert!(should_fail.is_err());
if let Err(err) = should_fail {
assert_eq!(err, StoreError::StoreFull(1));
assert_eq!(err, PoolError::StoreFull(1));
} else {
panic!("unexpected store address");
}
@ -1034,7 +1028,7 @@ mod tests {
let should_fail = local_pool.free_element(8, |_| {});
assert!(should_fail.is_err());
if let Err(err) = should_fail {
assert_eq!(err, StoreError::StoreFull(2));
assert_eq!(err, PoolError::StoreFull(2));
} else {
panic!("unexpected store address");
}

View File

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

View File

@ -213,9 +213,13 @@ mod tests {
.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! {
to self.common {
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator);
fn read_next_tm(&mut self) -> PusTmReader<'_>;
fn check_no_tm_available(&self) -> bool;
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.
//! 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::queue::{GenericReceiveError, GenericSendError};
use crate::request::{GenericMessage, MessageMetadata, RequestId};
use crate::tmtc::{PacketAsVec, PacketInPool};
use crate::ComponentId;
use core::fmt::{Display, Formatter};
use core::time::Duration;
@ -44,12 +45,12 @@ use self::verification::VerificationReportingProvider;
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum PusTmVariant<'time, 'src_data> {
InStore(StoreAddr),
InStore(PoolAddr),
Direct(PusTmCreator<'time, 'src_data>),
}
impl From<StoreAddr> for PusTmVariant<'_, '_> {
fn from(value: StoreAddr) -> Self {
impl From<PoolAddr> for PusTmVariant<'_, '_> {
fn from(value: PoolAddr) -> Self {
Self::InStore(value)
}
}
@ -62,10 +63,10 @@ impl<'time, 'src_data> From<PusTmCreator<'time, 'src_data>> for PusTmVariant<'ti
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EcssTmtcError {
Store(StoreError),
Store(PoolError),
ByteConversion(ByteConversionError),
Pus(PusError),
CantSendAddr(StoreAddr),
CantSendAddr(PoolAddr),
CantSendDirectTm,
Send(GenericSendError),
Receive(GenericReceiveError),
@ -99,8 +100,8 @@ impl Display for EcssTmtcError {
}
}
impl From<StoreError> for EcssTmtcError {
fn from(value: StoreError) -> Self {
impl From<PoolError> for EcssTmtcError {
fn from(value: PoolError) -> Self {
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 using different methods. Right now,
/// A PUS telecommand packet can be stored in memory and sent using different methods. Right now,
/// storage inside a pool structure like [crate::pool::StaticMemoryPool], and storage inside a
/// `Vec<u8>` are supported.
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TcInMemory {
StoreAddr(StoreAddr),
Pool(PacketInPool),
#[cfg(feature = "alloc")]
Vec(alloc::vec::Vec<u8>),
Vec(PacketAsVec),
}
impl From<StoreAddr> for TcInMemory {
fn from(value: StoreAddr) -> Self {
Self::StoreAddr(value)
impl From<PacketInPool> for TcInMemory {
fn from(value: PacketInPool) -> Self {
Self::Pool(value)
}
}
#[cfg(feature = "alloc")]
impl From<alloc::vec::Vec<u8>> for TcInMemory {
fn from(value: alloc::vec::Vec<u8>) -> Self {
impl From<PacketAsVec> for TcInMemory {
fn from(value: PacketAsVec) -> Self {
Self::Vec(value)
}
}
@ -263,8 +263,8 @@ impl From<PusError> for TryRecvTmtcError {
}
}
impl From<StoreError> for TryRecvTmtcError {
fn from(value: StoreError) -> Self {
impl From<PoolError> for TryRecvTmtcError {
fn from(value: PoolError) -> Self {
Self::Tmtc(value.into())
}
}
@ -654,7 +654,7 @@ pub mod alloc_mod {
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
pub mod std_mod {
use crate::pool::{
PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool, StoreAddr, StoreError,
PoolAddr, PoolError, PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool,
};
use crate::pus::verification::{TcStateAccepted, VerificationToken};
use crate::pus::{
@ -681,8 +681,8 @@ pub mod std_mod {
use super::{AcceptedEcssTcAndToken, ActiveRequestProvider, TcInMemory};
use crate::tmtc::PacketInPool;
impl From<mpsc::SendError<StoreAddr>> for EcssTmtcError {
fn from(_: mpsc::SendError<StoreAddr>) -> Self {
impl From<mpsc::SendError<PoolAddr>> for EcssTmtcError {
fn from(_: mpsc::SendError<PoolAddr>) -> Self {
Self::Send(GenericSendError::RxDisconnected)
}
}
@ -769,14 +769,14 @@ pub mod std_mod {
use super::*;
use crossbeam_channel as cb;
impl From<cb::SendError<StoreAddr>> for EcssTmtcError {
fn from(_: cb::SendError<StoreAddr>) -> Self {
impl From<cb::SendError<PoolAddr>> for EcssTmtcError {
fn from(_: cb::SendError<PoolAddr>) -> Self {
Self::Send(GenericSendError::RxDisconnected)
}
}
impl From<cb::TrySendError<StoreAddr>> for EcssTmtcError {
fn from(value: cb::TrySendError<StoreAddr>) -> Self {
impl From<cb::TrySendError<PoolAddr>> for EcssTmtcError {
fn from(value: cb::TrySendError<PoolAddr>) -> Self {
match value {
cb::TrySendError::Full(_) => Self::Send(GenericSendError::QueueFull(None)),
cb::TrySendError::Disconnected(_) => {
@ -952,6 +952,8 @@ pub mod std_mod {
fn tc_slice_raw(&self) -> &[u8];
fn sender_id(&self) -> Option<ComponentId>;
fn cache_and_convert(
&mut self,
possible_packet: &TcInMemory,
@ -974,6 +976,7 @@ pub mod std_mod {
/// [SharedStaticMemoryPool].
#[derive(Default, Clone)]
pub struct EcssTcInVecConverter {
sender_id: Option<ComponentId>,
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> {
self.pus_tc_raw = None;
match tc_in_memory {
super::TcInMemory::StoreAddr(_) => {
super::TcInMemory::Pool(_packet_in_pool) => {
return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone()));
}
super::TcInMemory::Vec(vec) => {
self.pus_tc_raw = Some(vec.clone());
super::TcInMemory::Vec(packet_with_sender) => {
self.pus_tc_raw = Some(packet_with_sender.packet.clone());
self.sender_id = Some(packet_with_sender.sender_id);
}
};
Ok(())
}
fn sender_id(&self) -> Option<ComponentId> {
self.sender_id
}
fn tc_slice_raw(&self) -> &[u8] {
if self.pus_tc_raw.is_none() {
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
/// are stored as a `Vec<u8>`.
pub struct EcssTcInSharedStoreConverter {
sender_id: Option<ComponentId>,
shared_tc_store: SharedStaticMemoryPool,
pus_buf: Vec<u8>,
}
@ -1011,15 +1020,16 @@ pub mod std_mod {
impl EcssTcInSharedStoreConverter {
pub fn new(shared_tc_store: SharedStaticMemoryPool, max_expected_tc_size: usize) -> Self {
Self {
sender_id: None,
shared_tc_store,
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.
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)?;
if tc_size > self.pus_buf.len() {
@ -1041,8 +1051,9 @@ pub mod std_mod {
impl EcssTcInMemConverter for EcssTcInSharedStoreConverter {
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
match tc_in_memory {
super::TcInMemory::StoreAddr(addr) => {
self.copy_tc_to_buf(*addr)?;
super::TcInMemory::Pool(packet_in_pool) => {
self.copy_tc_to_buf(packet_in_pool.store_addr)?;
self.sender_id = Some(packet_in_pool.sender_id);
}
super::TcInMemory::Vec(_) => {
return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone()));
@ -1054,6 +1065,10 @@ pub mod std_mod {
fn tc_slice_raw(&self) -> &[u8] {
self.pus_buf.as_ref()
}
fn sender_id(&self) -> Option<ComponentId> {
self.sender_id
}
}
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 tc_size = tc.write_to_bytes(mut_buf.as_mut_slice()).unwrap();
let mut tc_pool = self.tc_pool.write().unwrap();
@ -1372,7 +1392,10 @@ pub mod tests {
drop(tc_pool);
// Send accepted TC to test service handler.
self.tc_sender
.send(EcssTcAndToken::new(addr, *token))
.send(EcssTcAndToken::new(
PacketInPool::new(sender_id, addr),
*token,
))
.expect("sending tc failed");
}
@ -1486,11 +1509,19 @@ pub mod tests {
}
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.
self.tc_sender
.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,
))
.expect("sending tc failed");

View File

@ -14,7 +14,7 @@ use spacepackets::{ByteConversionError, CcsdsPacket};
#[cfg(feature = "std")]
use std::error::Error;
use crate::pool::{PoolProvider, StoreError};
use crate::pool::{PoolError, PoolProvider};
#[cfg(feature = "alloc")]
pub use alloc_mod::*;
@ -151,7 +151,7 @@ pub enum ScheduleError {
},
/// Nested time-tagged commands are not allowed.
NestedScheduledTc,
StoreError(StoreError),
StoreError(PoolError),
TcDataEmpty,
TimestampError(TimestampError),
WrongSubservice(u8),
@ -206,8 +206,8 @@ impl From<PusError> for ScheduleError {
}
}
impl From<StoreError> for ScheduleError {
fn from(e: StoreError) -> Self {
impl From<PoolError> for ScheduleError {
fn from(e: PoolError) -> Self {
Self::StoreError(e)
}
}
@ -240,7 +240,7 @@ impl Error for ScheduleError {
pub trait PusSchedulerProvider {
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;
@ -347,7 +347,7 @@ pub mod alloc_mod {
};
use spacepackets::time::cds::{self, DaysLen24Bits};
use crate::pool::StoreAddr;
use crate::pool::PoolAddr;
use super::*;
@ -368,8 +368,8 @@ pub mod alloc_mod {
}
enum DeletionResult {
WithoutStoreDeletion(Option<StoreAddr>),
WithStoreDeletion(Result<bool, StoreError>),
WithoutStoreDeletion(Option<PoolAddr>),
WithStoreDeletion(Result<bool, PoolError>),
}
/// This is the core data structure for scheduling PUS telecommands with [alloc] support.
@ -525,7 +525,7 @@ pub mod alloc_mod {
&mut self,
time_window: TimeWindow<TimeProvider>,
pool: &mut (impl PoolProvider + ?Sized),
) -> Result<u64, (u64, StoreError)> {
) -> Result<u64, (u64, PoolError)> {
let range = self.retrieve_by_time_filter(time_window);
let mut del_packets = 0;
let mut res_if_fails = None;
@ -555,7 +555,7 @@ pub mod alloc_mod {
pub fn delete_all(
&mut self,
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)
}
@ -601,7 +601,7 @@ pub mod alloc_mod {
/// 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
/// 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) =
self.delete_by_request_id_internal_without_store_deletion(req_id)
{
@ -615,7 +615,7 @@ pub mod alloc_mod {
&mut self,
req_id: &RequestId,
pool: &mut (impl PoolProvider + ?Sized),
) -> Result<bool, StoreError> {
) -> Result<bool, PoolError> {
if let DeletionResult::WithStoreDeletion(v) =
self.delete_by_request_id_internal_with_store_deletion(req_id, pool)
{
@ -693,7 +693,7 @@ pub mod alloc_mod {
releaser: R,
tc_store: &mut (impl PoolProvider + ?Sized),
tc_buf: &mut [u8],
) -> Result<u64, (u64, StoreError)> {
) -> Result<u64, (u64, PoolError)> {
self.release_telecommands_internal(releaser, tc_store, Some(tc_buf))
}
@ -707,7 +707,7 @@ pub mod alloc_mod {
&mut self,
releaser: R,
tc_store: &mut (impl PoolProvider + ?Sized),
) -> Result<u64, (u64, StoreError)> {
) -> Result<u64, (u64, PoolError)> {
self.release_telecommands_internal(releaser, tc_store, None)
}
@ -716,7 +716,7 @@ pub mod alloc_mod {
mut releaser: R,
tc_store: &mut (impl PoolProvider + ?Sized),
mut tc_buf: Option<&mut [u8]>,
) -> Result<u64, (u64, StoreError)> {
) -> Result<u64, (u64, PoolError)> {
let tcs_to_release = self.telecommands_to_release();
let mut released_tcs = 0;
let mut store_error = Ok(());
@ -762,7 +762,7 @@ pub mod alloc_mod {
mut releaser: R,
tc_store: &(impl PoolProvider + ?Sized),
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 mut released_tcs = alloc::vec::Vec::new();
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
/// 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.
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;
let mut deletion_ok = Ok(());
for tc_lists in &mut self.tc_map {
@ -851,7 +851,7 @@ pub mod alloc_mod {
mod tests {
use super::*;
use crate::pool::{
PoolProvider, StaticMemoryPool, StaticPoolAddr, StaticPoolConfig, StoreAddr, StoreError,
PoolAddr, PoolError, PoolProvider, StaticMemoryPool, StaticPoolAddr, StaticPoolConfig,
};
use alloc::collections::btree_map::Range;
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
@ -990,7 +990,7 @@ mod tests {
.insert_unwrapped_and_stored_tc(
UnixTime::new_only_secs(100),
TcInfo::new(
StoreAddr::from(StaticPoolAddr {
PoolAddr::from(StaticPoolAddr {
pool_idx: 0,
packet_idx: 1,
}),
@ -1007,7 +1007,7 @@ mod tests {
.insert_unwrapped_and_stored_tc(
UnixTime::new_only_secs(100),
TcInfo::new(
StoreAddr::from(StaticPoolAddr {
PoolAddr::from(StaticPoolAddr {
pool_idx: 0,
packet_idx: 2,
}),
@ -1051,8 +1051,8 @@ mod tests {
fn common_check(
enabled: bool,
store_addr: &StoreAddr,
expected_store_addrs: Vec<StoreAddr>,
store_addr: &PoolAddr,
expected_store_addrs: Vec<PoolAddr>,
counter: &mut usize,
) {
assert!(enabled);
@ -1061,8 +1061,8 @@ mod tests {
}
fn common_check_disabled(
enabled: bool,
store_addr: &StoreAddr,
expected_store_addrs: Vec<StoreAddr>,
store_addr: &PoolAddr,
expected_store_addrs: Vec<PoolAddr>,
counter: &mut usize,
) {
assert!(!enabled);
@ -1516,7 +1516,7 @@ mod tests {
// TC could not even be read..
assert_eq!(err.0, 0);
match err.1 {
StoreError::DataDoesNotExist(addr) => {
PoolError::DataDoesNotExist(addr) => {
assert_eq!(tc_info_0.addr(), addr);
}
_ => panic!("unexpected error {}", err.1),
@ -1539,7 +1539,7 @@ mod tests {
assert!(reset_res.is_err());
let err = reset_res.unwrap_err();
match err {
StoreError::DataDoesNotExist(addr) => {
PoolError::DataDoesNotExist(addr) => {
assert_eq!(addr, tc_info_0.addr());
}
_ => panic!("unexpected error {err}"),
@ -1641,7 +1641,7 @@ mod tests {
let err = insert_res.unwrap_err();
match err {
ScheduleError::StoreError(e) => match e {
StoreError::StoreFull(_) => {}
PoolError::StoreFull(_) => {}
_ => panic!("unexpected store error {e}"),
},
_ => panic!("unexpected error {err}"),

View File

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

View File

@ -203,10 +203,14 @@ mod tests {
.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! {
to self.common {
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_next_verification_tm(
&self,
@ -254,9 +258,13 @@ mod tests {
.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! {
to self.common {
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator);
fn read_next_tm(&mut self) -> PusTmReader<'_>;
fn check_no_tm_available(&self) -> bool;
fn check_next_verification_tm(

View File

@ -10,7 +10,7 @@
#[cfg(feature = "std")]
use crate::queue::GenericSendError;
use crate::{
pool::{PoolProvider, StoreAddr, StoreError},
pool::{PoolAddr, PoolError, PoolProvider},
ComponentId,
};
#[cfg(feature = "std")]
@ -33,14 +33,16 @@ pub use std_mod::*;
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 sender_id: ComponentId,
pub store_addr: StoreAddr,
pub store_addr: PoolAddr,
}
impl PacketInPool {
pub fn new(sender_id: ComponentId, store_addr: StoreAddr) -> Self {
pub fn new(sender_id: ComponentId, store_addr: PoolAddr) -> Self {
Self {
sender_id,
store_addr,
@ -183,27 +185,27 @@ impl SharedPacketPool {
/// Helper trait for any generic (static) store which allows storing raw or CCSDS packets.
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)
}
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.
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.
pub trait PusTmPool {
fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result<StoreAddr, StoreError>;
fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> 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<PoolAddr, PoolError>;
}
impl PusTcPool for SharedPacketPool {
fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result<StoreAddr, StoreError> {
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?;
fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result<PoolAddr, PoolError> {
let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
let addr = pg.free_element(pus_tc.len_packed(), |buf| {
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 {
fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result<StoreAddr, StoreError> {
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?;
fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result<PoolAddr, PoolError> {
let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
let addr = pg.free_element(pus_tm.len_packed(), |buf| {
buf[0..pus_tm.len_packed()].copy_from_slice(pus_tm.raw_data());
})?;
Ok(addr)
}
fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result<StoreAddr, StoreError> {
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?;
fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result<PoolAddr, PoolError> {
let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
let mut result = Ok(0);
let addr = pg.free_element(pus_tm.len_written(), |buf| {
result = pus_tm.write_to_bytes(buf);
@ -232,8 +234,8 @@ impl PusTmPool for SharedPacketPool {
}
impl CcsdsPacketPool for SharedPacketPool {
fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result<StoreAddr, StoreError> {
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?;
fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result<PoolAddr, PoolError> {
let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
let addr = pg.free_element(tc_raw.len(), |buf| {
buf[0..tc_raw.len()].copy_from_slice(tc_raw);
})?;
@ -246,7 +248,7 @@ pub trait PacketInPoolSender: Send {
fn send_packet(
&self,
sender_id: ComponentId,
store_addr: StoreAddr,
store_addr: PoolAddr,
) -> Result<(), GenericSendError>;
}
@ -256,7 +258,9 @@ pub mod alloc_mod {
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 sender_id: ComponentId,
pub packet: Vec<u8>,
@ -305,7 +309,7 @@ pub mod std_mod {
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum StoreAndSendError {
#[error("Store error: {0}")]
Store(#[from] StoreError),
Store(#[from] PoolError),
#[error("Genreric send error: {0}")]
Send(#[from] GenericSendError),
}
@ -316,7 +320,7 @@ pub mod std_mod {
fn send_packet(
&self,
sender_id: ComponentId,
store_addr: StoreAddr,
store_addr: PoolAddr,
) -> Result<(), GenericSendError> {
self.send(PacketInPool::new(sender_id, store_addr))
.map_err(|_| GenericSendError::RxDisconnected)
@ -327,7 +331,7 @@ pub mod std_mod {
fn send_packet(
&self,
sender_id: ComponentId,
store_addr: StoreAddr,
store_addr: PoolAddr,
) -> Result<(), GenericSendError> {
self.try_send(PacketInPool::new(sender_id, store_addr))
.map_err(|e| match e {
@ -342,7 +346,7 @@ pub mod std_mod {
fn send_packet(
&self,
sender_id: ComponentId,
store_addr: StoreAddr,
store_addr: PoolAddr,
) -> Result<(), GenericSendError> {
self.try_send(PacketInPool::new(sender_id, store_addr))
.map_err(|e| match e {
@ -455,7 +459,7 @@ pub mod std_mod {
sender_id: crate::ComponentId,
tm: crate::pus::PusTmVariant,
) -> Result<(), crate::pus::EcssTmtcError> {
let send_addr = |store_addr: StoreAddr| {
let send_addr = |store_addr: PoolAddr| {
self.sender
.send_packet(sender_id, store_addr)
.map_err(EcssTmtcError::Send)
@ -632,7 +636,7 @@ pub(crate) mod tests {
assert!(result.is_err());
matches!(
result.unwrap_err(),
StoreAndSendError::Store(StoreError::StoreFull(..))
StoreAndSendError::Store(PoolError::StoreFull(..))
);
let packet_in_pool = tc_rx.try_recv().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::sync::mpsc;
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 shared_pool = Arc::new(RwLock::new(StaticMemoryPool::new(pool_cfg)));
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 mut dummy = shared_pool.write().unwrap();
let addr = dummy.add(&DUMMY_DATA).expect("Writing data failed");