From 269324de28f6f8d8d1db4d87c9a186bc2803dcce Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 15 Apr 2024 14:35:06 +0200 Subject: [PATCH] all test fixes --- satrs-example/src/pus/action.rs | 5 +- satrs-example/src/pus/mod.rs | 10 +- satrs/CHANGELOG.md | 2 + satrs/src/action.rs | 4 +- satrs/src/encoding/mod.rs | 5 +- satrs/src/hal/std/tcp_cobs_server.rs | 8 +- satrs/src/hal/std/tcp_spacepackets_server.rs | 5 +- satrs/src/params.rs | 8 +- satrs/src/pool.rs | 168 +++++++++---------- satrs/src/pus/event_man.rs | 2 +- satrs/src/pus/event_srv.rs | 6 +- satrs/src/pus/mod.rs | 105 ++++++++---- satrs/src/pus/scheduler.rs | 54 +++--- satrs/src/pus/scheduler_srv.rs | 8 +- satrs/src/pus/test.rs | 12 +- satrs/src/tmtc/mod.rs | 54 +++--- satrs/tests/pools.rs | 4 +- 17 files changed, 260 insertions(+), 200 deletions(-) diff --git a/satrs-example/src/pus/action.rs b/satrs-example/src/pus/action.rs index ad4764e..dcdb345 100644 --- a/satrs-example/src/pus/action.rs +++ b/satrs-example/src/pus/action.rs @@ -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(); } } diff --git a/satrs-example/src/pus/mod.rs b/satrs-example/src/pus/mod.rs index b7fd506..6e5ec37 100644 --- a/satrs-example/src/pus/mod.rs +++ b/satrs-example/src/pus/mod.rs @@ -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 PusTcDistributor { pub fn handle_tc_generic( &mut self, sender_id: ComponentId, - addr_opt: Option, + addr_opt: Option, raw_tc: &[u8], ) -> Result { let pus_tc_result = PusTcReader::new(raw_tc); @@ -119,10 +119,10 @@ impl PusTcDistributor { .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 { diff --git a/satrs/CHANGELOG.md b/satrs/CHANGELOG.md index 1894aef..c78da56 100644 --- a/satrs/CHANGELOG.md +++ b/satrs/CHANGELOG.md @@ -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. diff --git a/satrs/src/action.rs b/satrs/src/action.rs index 4aea9f1..95f3a41 100644 --- a/satrs/src/action.rs +++ b/satrs/src/action.rs @@ -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), } diff --git a/satrs/src/encoding/mod.rs b/satrs/src/encoding/mod.rs index b3242e5..99ce51d 100644 --- a/satrs/src/encoding/mod.rs +++ b/satrs/src/encoding/mod.rs @@ -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; diff --git a/satrs/src/hal/std/tcp_cobs_server.rs b/satrs/src/hal/std/tcp_cobs_server.rs index 538974f..1f00007 100644 --- a/satrs/src/hal/std/tcp_cobs_server.rs +++ b/satrs/src/hal/std/tcp_cobs_server.rs @@ -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; diff --git a/satrs/src/hal/std/tcp_spacepackets_server.rs b/satrs/src/hal/std/tcp_spacepackets_server.rs index 1baea6b..4a5788a 100644 --- a/satrs/src/hal/std/tcp_spacepackets_server.rs +++ b/satrs/src/hal/std/tcp_spacepackets_server.rs @@ -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; diff --git a/satrs/src/params.rs b/satrs/src/params.rs index 10fb41c..da770eb 100644 --- a/satrs/src/params.rs +++ b/satrs/src/params.rs @@ -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), #[cfg(feature = "alloc")] String(String), } -impl From for Params { - fn from(x: StoreAddr) -> Self { +impl From for Params { + fn from(x: PoolAddr) -> Self { Self::Store(x) } } diff --git a/satrs/src/pool.rs b/satrs/src/pool.rs index 1c3b8a4..3640ce8 100644 --- a/satrs/src/pool.rs +++ b/satrs/src/pool.rs @@ -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 for StoreAddr { +impl From for PoolAddr { fn from(value: StaticPoolAddr) -> Self { ((value.pool_idx as u64) << 16) | value.packet_idx as u64 } } -impl From for StaticPoolAddr { - fn from(value: StoreAddr) -> Self { +impl From 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), + InvalidStoreId(StoreIdError, Option), /// 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 for StoreError { +impl From 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; + fn add(&mut self, data: &[u8]) -> Result; /// 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; + ) -> Result; /// 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( - &mut self, - addr: &StoreAddr, - updater: U, - ) -> Result<(), StoreError>; + fn modify(&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; + fn read(&self, addr: &PoolAddr, buf: &mut [u8]) -> Result; /// Delete data inside the pool given a [StoreAddr]. - fn delete(&mut self, addr: StoreAddr) -> Result<(), StoreError>; - fn has_element_at(&self, addr: &StoreAddr) -> Result; + fn delete(&mut self, addr: PoolAddr) -> Result<(), PoolError>; + fn has_element_at(&self, addr: &PoolAddr) -> Result; /// Retrieve the length of the data at the given store address. - fn len_of_data(&self, addr: &StoreAddr) -> Result; + fn len_of_data(&self, addr: &PoolAddr) -> Result; #[cfg(feature = "alloc")] - fn read_as_vec(&self, addr: &StoreAddr) -> Result, StoreError> { + fn read_as_vec(&self, addr: &PoolAddr) -> Result, 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; + fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard; /// 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; + fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard; } pub struct PoolGuard<'a, MemProvider: PoolProvider + ?Sized> { pool: &'a mut MemProvider, - pub addr: StoreAddr, + pub addr: PoolAddr, no_deletion: bool, - deletion_failed_error: Option, + deletion_failed_error: Option, } /// 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 { + pub fn read(&self, buf: &mut [u8]) -> Result { self.pool.read(&self.addr, buf) } #[cfg(feature = "alloc")] - pub fn read_as_vec(&self) -> Result, StoreError> { + pub fn read_as_vec(&self) -> Result, 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(&mut self, updater: &mut U) -> Result<(), StoreError> { + pub fn update(&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; + pub fn read(&self, buf: &mut [u8]) -> Result; /// 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 { + fn addr_check(&self, addr: &StaticPoolAddr) -> Result { 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 { + fn reserve(&mut self, data_len: usize) -> Result { 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 { + fn find_subpool(&self, req_size: usize, start_at_subpool: u16) -> Result { 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 { @@ -546,10 +543,10 @@ mod alloc_mod { } impl PoolProvider for StaticMemoryPool { - fn add(&mut self, data: &[u8]) -> Result { + fn add(&mut self, data: &[u8]) -> Result { 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 { + ) -> Result { 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( &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 { + fn read(&self, addr: &PoolAddr, buf: &mut [u8]) -> Result { 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 { + fn has_element_at(&self, addr: &PoolAddr) -> Result { 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 { + fn len_of_data(&self, addr: &PoolAddr) -> Result { 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 { + fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard { PoolRwGuard::new(self, addr) } - fn read_with_guard(&mut self, addr: StoreAddr) -> PoolGuard { + fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard { 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"); } diff --git a/satrs/src/pus/event_man.rs b/satrs/src/pus/event_man.rs index a09a1b0..1a03f69 100644 --- a/satrs/src/pus/event_man.rs +++ b/satrs/src/pus/event_man.rs @@ -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 = diff --git a/satrs/src/pus/event_srv.rs b/satrs/src/pus/event_srv.rs index 0bff0bc..c782b3a 100644 --- a/satrs/src/pus/event_srv.rs +++ b/satrs/src/pus/event_srv.rs @@ -213,9 +213,13 @@ mod tests { .expect("acceptance success failure") } + fn send_tc(&self, token: &VerificationToken, tc: &PusTcCreator) { + self.common + .send_tc(self.handler.service_helper.id(), token, tc); + } + delegate! { to self.common { - fn send_tc(&self, token: &VerificationToken, 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); diff --git a/satrs/src/pus/mod.rs b/satrs/src/pus/mod.rs index e10af78..c6a5631 100644 --- a/satrs/src/pus/mod.rs +++ b/satrs/src/pus/mod.rs @@ -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 for PusTmVariant<'_, '_> { - fn from(value: StoreAddr) -> Self { +impl From for PusTmVariant<'_, '_> { + fn from(value: PoolAddr) -> Self { Self::InStore(value) } } @@ -62,10 +63,10 @@ impl<'time, 'src_data> From> 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 for EcssTmtcError { - fn from(value: StoreError) -> Self { +impl From 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` are supported. #[non_exhaustive] #[derive(Debug, Clone, PartialEq, Eq)] pub enum TcInMemory { - StoreAddr(StoreAddr), + Pool(PacketInPool), #[cfg(feature = "alloc")] - Vec(alloc::vec::Vec), + Vec(PacketAsVec), } -impl From for TcInMemory { - fn from(value: StoreAddr) -> Self { - Self::StoreAddr(value) +impl From for TcInMemory { + fn from(value: PacketInPool) -> Self { + Self::Pool(value) } } #[cfg(feature = "alloc")] -impl From> for TcInMemory { - fn from(value: alloc::vec::Vec) -> Self { +impl From for TcInMemory { + fn from(value: PacketAsVec) -> Self { Self::Vec(value) } } @@ -263,8 +263,8 @@ impl From for TryRecvTmtcError { } } -impl From for TryRecvTmtcError { - fn from(value: StoreError) -> Self { +impl From 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> for EcssTmtcError { - fn from(_: mpsc::SendError) -> Self { + impl From> for EcssTmtcError { + fn from(_: mpsc::SendError) -> Self { Self::Send(GenericSendError::RxDisconnected) } } @@ -769,14 +769,14 @@ pub mod std_mod { use super::*; use crossbeam_channel as cb; - impl From> for EcssTmtcError { - fn from(_: cb::SendError) -> Self { + impl From> for EcssTmtcError { + fn from(_: cb::SendError) -> Self { Self::Send(GenericSendError::RxDisconnected) } } - impl From> for EcssTmtcError { - fn from(value: cb::TrySendError) -> Self { + impl From> for EcssTmtcError { + fn from(value: cb::TrySendError) -> 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; + 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, pub pus_tc_raw: Option>, } @@ -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 { + 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`. pub struct EcssTcInSharedStoreConverter { + sender_id: Option, shared_tc_store: SharedStaticMemoryPool, pus_buf: Vec, } @@ -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 { + self.sender_id + } } pub struct PusServiceBase< @@ -1364,7 +1379,12 @@ pub mod tests { ), ) } - pub fn send_tc(&self, token: &VerificationToken, tc: &PusTcCreator) { + pub fn send_tc( + &self, + sender_id: ComponentId, + token: &VerificationToken, + 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, tc: &PusTcCreator) { + pub fn send_tc( + &self, + sender_id: ComponentId, + token: &VerificationToken, + 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"); diff --git a/satrs/src/pus/scheduler.rs b/satrs/src/pus/scheduler.rs index 2d43f78..3ae8b58 100644 --- a/satrs/src/pus/scheduler.rs +++ b/satrs/src/pus/scheduler.rs @@ -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 for ScheduleError { } } -impl From for ScheduleError { - fn from(e: StoreError) -> Self { +impl From 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), - WithStoreDeletion(Result), + WithoutStoreDeletion(Option), + WithStoreDeletion(Result), } /// 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, pool: &mut (impl PoolProvider + ?Sized), - ) -> Result { + ) -> Result { 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 { + ) -> Result { self.delete_by_time_filter(TimeWindow::::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 { + pub fn delete_by_request_id(&mut self, req_id: &RequestId) -> Option { 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 { + ) -> Result { 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 { + ) -> Result { 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 { + ) -> Result { 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 { + ) -> Result { 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, StoreError)> { + ) -> Result, (alloc::vec::Vec, 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, + store_addr: &PoolAddr, + expected_store_addrs: Vec, counter: &mut usize, ) { assert!(enabled); @@ -1061,8 +1061,8 @@ mod tests { } fn common_check_disabled( enabled: bool, - store_addr: &StoreAddr, - expected_store_addrs: Vec, + store_addr: &PoolAddr, + expected_store_addrs: Vec, 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}"), diff --git a/satrs/src/pus/scheduler_srv.rs b/satrs/src/pus/scheduler_srv.rs index b78b8bf..4d538b8 100644 --- a/satrs/src/pus/scheduler_srv.rs +++ b/satrs/src/pus/scheduler_srv.rs @@ -315,9 +315,13 @@ mod tests { .expect("acceptance success failure") } + fn send_tc(&self, token: &VerificationToken, tc: &PusTcCreator) { + self.common + .send_tc(self.handler.service_helper.id(), token, tc); + } + delegate! { to self.common { - fn send_tc(&self, token: &VerificationToken, 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(()) } diff --git a/satrs/src/pus/test.rs b/satrs/src/pus/test.rs index 7400367..a1ca93e 100644 --- a/satrs/src/pus/test.rs +++ b/satrs/src/pus/test.rs @@ -203,10 +203,14 @@ mod tests { .expect("acceptance success failure") } + fn send_tc(&self, token: &VerificationToken, 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, 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, tc: &PusTcCreator) { + self.common + .send_tc(self.handler.service_helper.id(), token, tc); + } + delegate! { to self.common { - fn send_tc(&self, token: &VerificationToken, tc: &PusTcCreator); fn read_next_tm(&mut self) -> PusTmReader<'_>; fn check_no_tm_available(&self) -> bool; fn check_next_verification_tm( diff --git a/satrs/src/tmtc/mod.rs b/satrs/src/tmtc/mod.rs index ce22527..715ec7a 100644 --- a/satrs/src/tmtc/mod.rs +++ b/satrs/src/tmtc/mod.rs @@ -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 { + fn add_ccsds_tc(&mut self, _: &SpHeader, tc_raw: &[u8]) -> Result { self.add_raw_tc(tc_raw) } - fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result; + fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result; } /// 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; + fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result; } /// 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; - fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result; + fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result; + fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result; } impl PusTcPool for SharedPacketPool { - fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result { - let mut pg = self.0.write().map_err(|_| StoreError::LockError)?; + fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result { + 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 { - let mut pg = self.0.write().map_err(|_| StoreError::LockError)?; + fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result { + 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 { - let mut pg = self.0.write().map_err(|_| StoreError::LockError)?; + fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result { + 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 { - let mut pg = self.0.write().map_err(|_| StoreError::LockError)?; + fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result { + 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, @@ -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(); diff --git a/satrs/tests/pools.rs b/satrs/tests/pools.rs index f2baece..9e61097 100644 --- a/satrs/tests/pools.rs +++ b/satrs/tests/pools.rs @@ -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, Receiver) = mpsc::channel(); + let (tx, rx): (Sender, Receiver) = mpsc::channel(); let jh0 = thread::spawn(move || { let mut dummy = shared_pool.write().unwrap(); let addr = dummy.add(&DUMMY_DATA).expect("Writing data failed");