all test fixes
Some checks failed
Rust/sat-rs/pipeline/pr-main There was a failure building this commit
Some checks failed
Rust/sat-rs/pipeline/pr-main There was a failure building this commit
This commit is contained in:
parent
794094ae9f
commit
269324de28
@ -465,7 +465,10 @@ mod tests {
|
|||||||
.verif_reporter()
|
.verif_reporter()
|
||||||
.check_next_is_acceptance_success(id, accepted_token.request_id());
|
.check_next_is_acceptance_success(id, accepted_token.request_id());
|
||||||
self.pus_packet_tx
|
self.pus_packet_tx
|
||||||
.send(EcssTcAndToken::new(tc.to_vec().unwrap(), accepted_token))
|
.send(EcssTcAndToken::new(
|
||||||
|
PacketAsVec::new(self.service.service_helper.id(), tc.to_vec().unwrap()),
|
||||||
|
accepted_token,
|
||||||
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::requests::GenericRequestRouter;
|
use crate::requests::GenericRequestRouter;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use satrs::pool::StoreAddr;
|
use satrs::pool::PoolAddr;
|
||||||
use satrs::pus::verification::{
|
use satrs::pus::verification::{
|
||||||
self, FailParams, TcStateAccepted, TcStateStarted, VerificationReporter,
|
self, FailParams, TcStateAccepted, TcStateStarted, VerificationReporter,
|
||||||
VerificationReporterCfg, VerificationReportingProvider, VerificationToken,
|
VerificationReporterCfg, VerificationReportingProvider, VerificationToken,
|
||||||
@ -98,7 +98,7 @@ impl<TmSender: EcssTmSender> PusTcDistributor<TmSender> {
|
|||||||
pub fn handle_tc_generic(
|
pub fn handle_tc_generic(
|
||||||
&mut self,
|
&mut self,
|
||||||
sender_id: ComponentId,
|
sender_id: ComponentId,
|
||||||
addr_opt: Option<StoreAddr>,
|
addr_opt: Option<PoolAddr>,
|
||||||
raw_tc: &[u8],
|
raw_tc: &[u8],
|
||||||
) -> Result<PusPacketHandlerResult, GenericSendError> {
|
) -> Result<PusPacketHandlerResult, GenericSendError> {
|
||||||
let pus_tc_result = PusTcReader::new(raw_tc);
|
let pus_tc_result = PusTcReader::new(raw_tc);
|
||||||
@ -119,10 +119,10 @@ impl<TmSender: EcssTmSender> PusTcDistributor<TmSender> {
|
|||||||
.acceptance_success(&self.tm_sender, init_token, self.stamp_helper.stamp())
|
.acceptance_success(&self.tm_sender, init_token, self.stamp_helper.stamp())
|
||||||
.expect("Acceptance success failure");
|
.expect("Acceptance success failure");
|
||||||
let service = PusServiceId::try_from(pus_tc.service());
|
let service = PusServiceId::try_from(pus_tc.service());
|
||||||
let tc_in_memory = if let Some(store_addr) = addr_opt {
|
let tc_in_memory: TcInMemory = if let Some(store_addr) = addr_opt {
|
||||||
TcInMemory::StoreAddr(store_addr)
|
PacketInPool::new(sender_id, store_addr).into()
|
||||||
} else {
|
} else {
|
||||||
TcInMemory::Vec(Vec::from(raw_tc))
|
PacketAsVec::new(sender_id, Vec::from(raw_tc)).into()
|
||||||
};
|
};
|
||||||
match service {
|
match service {
|
||||||
Ok(standard_service) => match standard_service {
|
Ok(standard_service) => match standard_service {
|
||||||
|
@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
a `send_raw_tc` method which is not mutable anymore.
|
a `send_raw_tc` method which is not mutable anymore.
|
||||||
- Renamed `TmPacketSourceCore` to `TmPacketSource`.
|
- Renamed `TmPacketSourceCore` to `TmPacketSource`.
|
||||||
- Renamed `EcssTmSenderCore` to `EcssTmSender`.
|
- Renamed `EcssTmSenderCore` to `EcssTmSender`.
|
||||||
|
- Renamed `StoreAddr` to `PoolAddr`.
|
||||||
|
- Reanmed `StoreError` to `PoolError`.
|
||||||
- TCP server generics order. The error generics come last now.
|
- TCP server generics order. The error generics come last now.
|
||||||
- `encoding::ccsds::PacketIdValidator` renamed to `ValidatorU16Id`, which lives in the crate root.
|
- `encoding::ccsds::PacketIdValidator` renamed to `ValidatorU16Id`, which lives in the crate root.
|
||||||
It can be used for both CCSDS packet ID and CCSDS APID validation.
|
It can be used for both CCSDS packet ID and CCSDS APID validation.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{params::Params, pool::StoreAddr};
|
use crate::{params::Params, pool::PoolAddr};
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub use alloc_mod::*;
|
pub use alloc_mod::*;
|
||||||
@ -21,7 +21,7 @@ impl ActionRequest {
|
|||||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||||
pub enum ActionRequestVariant {
|
pub enum ActionRequestVariant {
|
||||||
NoData,
|
NoData,
|
||||||
StoreData(StoreAddr),
|
StoreData(PoolAddr),
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
VecData(alloc::vec::Vec<u8>),
|
VecData(alloc::vec::Vec<u8>),
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,10 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
use alloc::collections::VecDeque;
|
use alloc::collections::VecDeque;
|
||||||
|
|
||||||
use crate::{tmtc::{PacketAsVec, PacketSenderRaw}, ComponentId};
|
use crate::{
|
||||||
|
tmtc::{PacketAsVec, PacketSenderRaw},
|
||||||
|
ComponentId,
|
||||||
|
};
|
||||||
|
|
||||||
use super::cobs::encode_packet_with_cobs;
|
use super::cobs::encode_packet_with_cobs;
|
||||||
|
|
||||||
|
@ -206,10 +206,14 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
encoding::tests::{INVERTED_PACKET, SIMPLE_PACKET}, hal::std::tcp_server::{
|
encoding::tests::{INVERTED_PACKET, SIMPLE_PACKET},
|
||||||
|
hal::std::tcp_server::{
|
||||||
tests::{ConnectionFinishedHandler, SyncTmSource},
|
tests::{ConnectionFinishedHandler, SyncTmSource},
|
||||||
ConnectionResult, ServerConfig,
|
ConnectionResult, ServerConfig,
|
||||||
}, queue::GenericSendError, tmtc::PacketAsVec, ComponentId
|
},
|
||||||
|
queue::GenericSendError,
|
||||||
|
tmtc::PacketAsVec,
|
||||||
|
ComponentId,
|
||||||
};
|
};
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use cobs::encode;
|
use cobs::encode;
|
||||||
|
@ -204,7 +204,10 @@ mod tests {
|
|||||||
hal::std::tcp_server::{
|
hal::std::tcp_server::{
|
||||||
tests::{ConnectionFinishedHandler, SyncTmSource},
|
tests::{ConnectionFinishedHandler, SyncTmSource},
|
||||||
ConnectionResult, ServerConfig,
|
ConnectionResult, ServerConfig,
|
||||||
}, queue::GenericSendError, tmtc::PacketAsVec, ComponentId
|
},
|
||||||
|
queue::GenericSendError,
|
||||||
|
tmtc::PacketAsVec,
|
||||||
|
ComponentId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::TcpSpacepacketsServer;
|
use super::TcpSpacepacketsServer;
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
//! This includes the [ParamsHeapless] enumeration for contained values which do not require heap
|
//! This includes the [ParamsHeapless] enumeration for contained values which do not require heap
|
||||||
//! allocation, and the [Params] which enumerates [ParamsHeapless] and some additional types which
|
//! allocation, and the [Params] which enumerates [ParamsHeapless] and some additional types which
|
||||||
//! require [alloc] support but allow for more flexbility.
|
//! require [alloc] support but allow for more flexbility.
|
||||||
use crate::pool::StoreAddr;
|
use crate::pool::PoolAddr;
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
@ -588,15 +588,15 @@ from_conversions_for_raw!(
|
|||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum Params {
|
pub enum Params {
|
||||||
Heapless(ParamsHeapless),
|
Heapless(ParamsHeapless),
|
||||||
Store(StoreAddr),
|
Store(PoolAddr),
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
Vec(Vec<u8>),
|
Vec(Vec<u8>),
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
String(String),
|
String(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StoreAddr> for Params {
|
impl From<PoolAddr> for Params {
|
||||||
fn from(x: StoreAddr) -> Self {
|
fn from(x: PoolAddr) -> Self {
|
||||||
Self::Store(x)
|
Self::Store(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ use spacepackets::ByteConversionError;
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
type NumBlocks = u16;
|
type NumBlocks = u16;
|
||||||
pub type StoreAddr = u64;
|
pub type PoolAddr = u64;
|
||||||
|
|
||||||
/// Simple address type used for transactions with the local pool.
|
/// Simple address type used for transactions with the local pool.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
@ -100,14 +100,14 @@ impl StaticPoolAddr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StaticPoolAddr> for StoreAddr {
|
impl From<StaticPoolAddr> for PoolAddr {
|
||||||
fn from(value: StaticPoolAddr) -> Self {
|
fn from(value: StaticPoolAddr) -> Self {
|
||||||
((value.pool_idx as u64) << 16) | value.packet_idx as u64
|
((value.pool_idx as u64) << 16) | value.packet_idx as u64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StoreAddr> for StaticPoolAddr {
|
impl From<PoolAddr> for StaticPoolAddr {
|
||||||
fn from(value: StoreAddr) -> Self {
|
fn from(value: PoolAddr) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pool_idx: ((value >> 16) & 0xff) as u16,
|
pool_idx: ((value >> 16) & 0xff) as u16,
|
||||||
packet_idx: (value & 0xff) as u16,
|
packet_idx: (value & 0xff) as u16,
|
||||||
@ -150,59 +150,59 @@ impl Error for StoreIdError {}
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
pub enum StoreError {
|
pub enum PoolError {
|
||||||
/// Requested data block is too large
|
/// Requested data block is too large
|
||||||
DataTooLarge(usize),
|
DataTooLarge(usize),
|
||||||
/// The store is full. Contains the index of the full subpool
|
/// The store is full. Contains the index of the full subpool
|
||||||
StoreFull(u16),
|
StoreFull(u16),
|
||||||
/// Store ID is invalid. This also includes partial errors where only the subpool is invalid
|
/// Store ID is invalid. This also includes partial errors where only the subpool is invalid
|
||||||
InvalidStoreId(StoreIdError, Option<StoreAddr>),
|
InvalidStoreId(StoreIdError, Option<PoolAddr>),
|
||||||
/// Valid subpool and packet index, but no data is stored at the given address
|
/// Valid subpool and packet index, but no data is stored at the given address
|
||||||
DataDoesNotExist(StoreAddr),
|
DataDoesNotExist(PoolAddr),
|
||||||
ByteConversionError(spacepackets::ByteConversionError),
|
ByteConversionError(spacepackets::ByteConversionError),
|
||||||
LockError,
|
LockError,
|
||||||
/// Internal or configuration errors
|
/// Internal or configuration errors
|
||||||
InternalError(u32),
|
InternalError(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for StoreError {
|
impl Display for PoolError {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
StoreError::DataTooLarge(size) => {
|
PoolError::DataTooLarge(size) => {
|
||||||
write!(f, "data to store with size {size} is too large")
|
write!(f, "data to store with size {size} is too large")
|
||||||
}
|
}
|
||||||
StoreError::StoreFull(u16) => {
|
PoolError::StoreFull(u16) => {
|
||||||
write!(f, "store is too full. index for full subpool: {u16}")
|
write!(f, "store is too full. index for full subpool: {u16}")
|
||||||
}
|
}
|
||||||
StoreError::InvalidStoreId(id_e, addr) => {
|
PoolError::InvalidStoreId(id_e, addr) => {
|
||||||
write!(f, "invalid store ID: {id_e}, address: {addr:?}")
|
write!(f, "invalid store ID: {id_e}, address: {addr:?}")
|
||||||
}
|
}
|
||||||
StoreError::DataDoesNotExist(addr) => {
|
PoolError::DataDoesNotExist(addr) => {
|
||||||
write!(f, "no data exists at address {addr:?}")
|
write!(f, "no data exists at address {addr:?}")
|
||||||
}
|
}
|
||||||
StoreError::InternalError(e) => {
|
PoolError::InternalError(e) => {
|
||||||
write!(f, "internal error: {e}")
|
write!(f, "internal error: {e}")
|
||||||
}
|
}
|
||||||
StoreError::ByteConversionError(e) => {
|
PoolError::ByteConversionError(e) => {
|
||||||
write!(f, "store error: {e}")
|
write!(f, "store error: {e}")
|
||||||
}
|
}
|
||||||
StoreError::LockError => {
|
PoolError::LockError => {
|
||||||
write!(f, "lock error")
|
write!(f, "lock error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ByteConversionError> for StoreError {
|
impl From<ByteConversionError> for PoolError {
|
||||||
fn from(value: ByteConversionError) -> Self {
|
fn from(value: ByteConversionError) -> Self {
|
||||||
Self::ByteConversionError(value)
|
Self::ByteConversionError(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Error for StoreError {
|
impl Error for PoolError {
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
if let StoreError::InvalidStoreId(e, _) = self {
|
if let PoolError::InvalidStoreId(e, _) = self {
|
||||||
return Some(e);
|
return Some(e);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
@ -219,7 +219,7 @@ pub trait PoolProvider {
|
|||||||
/// Add new data to the pool. The provider should attempt to reserve a memory block with the
|
/// Add new data to the pool. The provider should attempt to reserve a memory block with the
|
||||||
/// appropriate size and then copy the given data to the block. Yields a [StoreAddr] which can
|
/// appropriate size and then copy the given data to the block. Yields a [StoreAddr] which can
|
||||||
/// be used to access the data stored in the pool
|
/// be used to access the data stored in the pool
|
||||||
fn add(&mut self, data: &[u8]) -> Result<StoreAddr, StoreError>;
|
fn add(&mut self, data: &[u8]) -> Result<PoolAddr, PoolError>;
|
||||||
|
|
||||||
/// The provider should attempt to reserve a free memory block with the appropriate size first.
|
/// The provider should attempt to reserve a free memory block with the appropriate size first.
|
||||||
/// It then executes a user-provided closure and passes a mutable reference to that memory
|
/// It then executes a user-provided closure and passes a mutable reference to that memory
|
||||||
@ -230,31 +230,28 @@ pub trait PoolProvider {
|
|||||||
&mut self,
|
&mut self,
|
||||||
len: usize,
|
len: usize,
|
||||||
writer: W,
|
writer: W,
|
||||||
) -> Result<StoreAddr, StoreError>;
|
) -> Result<PoolAddr, PoolError>;
|
||||||
|
|
||||||
/// Modify data added previously using a given [StoreAddr]. The provider should use the store
|
/// Modify data added previously using a given [StoreAddr]. The provider should use the store
|
||||||
/// address to determine if a memory block exists for that address. If it does, it should
|
/// address to determine if a memory block exists for that address. If it does, it should
|
||||||
/// call the user-provided closure and pass a mutable reference to the memory block
|
/// call the user-provided closure and pass a mutable reference to the memory block
|
||||||
/// to the closure. This allows the user to modify the memory block.
|
/// to the closure. This allows the user to modify the memory block.
|
||||||
fn modify<U: FnMut(&mut [u8])>(
|
fn modify<U: FnMut(&mut [u8])>(&mut self, addr: &PoolAddr, updater: U)
|
||||||
&mut self,
|
-> Result<(), PoolError>;
|
||||||
addr: &StoreAddr,
|
|
||||||
updater: U,
|
|
||||||
) -> Result<(), StoreError>;
|
|
||||||
|
|
||||||
/// The provider should copy the data from the memory block to the user-provided buffer if
|
/// The provider should copy the data from the memory block to the user-provided buffer if
|
||||||
/// it exists.
|
/// it exists.
|
||||||
fn read(&self, addr: &StoreAddr, buf: &mut [u8]) -> Result<usize, StoreError>;
|
fn read(&self, addr: &PoolAddr, buf: &mut [u8]) -> Result<usize, PoolError>;
|
||||||
|
|
||||||
/// Delete data inside the pool given a [StoreAddr].
|
/// Delete data inside the pool given a [StoreAddr].
|
||||||
fn delete(&mut self, addr: StoreAddr) -> Result<(), StoreError>;
|
fn delete(&mut self, addr: PoolAddr) -> Result<(), PoolError>;
|
||||||
fn has_element_at(&self, addr: &StoreAddr) -> Result<bool, StoreError>;
|
fn has_element_at(&self, addr: &PoolAddr) -> Result<bool, PoolError>;
|
||||||
|
|
||||||
/// Retrieve the length of the data at the given store address.
|
/// Retrieve the length of the data at the given store address.
|
||||||
fn len_of_data(&self, addr: &StoreAddr) -> Result<usize, StoreError>;
|
fn len_of_data(&self, addr: &PoolAddr) -> Result<usize, PoolError>;
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
fn read_as_vec(&self, addr: &StoreAddr) -> Result<alloc::vec::Vec<u8>, StoreError> {
|
fn read_as_vec(&self, addr: &PoolAddr) -> Result<alloc::vec::Vec<u8>, PoolError> {
|
||||||
let mut vec = alloc::vec![0; self.len_of_data(addr)?];
|
let mut vec = alloc::vec![0; self.len_of_data(addr)?];
|
||||||
self.read(addr, &mut vec)?;
|
self.read(addr, &mut vec)?;
|
||||||
Ok(vec)
|
Ok(vec)
|
||||||
@ -271,7 +268,7 @@ pub trait PoolProviderWithGuards: PoolProvider {
|
|||||||
/// This can prevent memory leaks. Users can read the data and release the guard
|
/// This can prevent memory leaks. Users can read the data and release the guard
|
||||||
/// if the data in the store is valid for further processing. If the data is faulty, no
|
/// if the data in the store is valid for further processing. If the data is faulty, no
|
||||||
/// manual deletion is necessary when returning from a processing function prematurely.
|
/// manual deletion is necessary when returning from a processing function prematurely.
|
||||||
fn read_with_guard(&mut self, addr: StoreAddr) -> PoolGuard<Self>;
|
fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard<Self>;
|
||||||
|
|
||||||
/// This function behaves like [PoolProvider::modify], but consumes the provided
|
/// This function behaves like [PoolProvider::modify], but consumes the provided
|
||||||
/// address and returns a RAII conformant guard object.
|
/// address and returns a RAII conformant guard object.
|
||||||
@ -281,20 +278,20 @@ pub trait PoolProviderWithGuards: PoolProvider {
|
|||||||
/// This can prevent memory leaks. Users can read (and modify) the data and release the guard
|
/// This can prevent memory leaks. Users can read (and modify) the data and release the guard
|
||||||
/// if the data in the store is valid for further processing. If the data is faulty, no
|
/// if the data in the store is valid for further processing. If the data is faulty, no
|
||||||
/// manual deletion is necessary when returning from a processing function prematurely.
|
/// manual deletion is necessary when returning from a processing function prematurely.
|
||||||
fn modify_with_guard(&mut self, addr: StoreAddr) -> PoolRwGuard<Self>;
|
fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PoolGuard<'a, MemProvider: PoolProvider + ?Sized> {
|
pub struct PoolGuard<'a, MemProvider: PoolProvider + ?Sized> {
|
||||||
pool: &'a mut MemProvider,
|
pool: &'a mut MemProvider,
|
||||||
pub addr: StoreAddr,
|
pub addr: PoolAddr,
|
||||||
no_deletion: bool,
|
no_deletion: bool,
|
||||||
deletion_failed_error: Option<StoreError>,
|
deletion_failed_error: Option<PoolError>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This helper object can be used to safely access pool data without worrying about memory
|
/// This helper object can be used to safely access pool data without worrying about memory
|
||||||
/// leaks.
|
/// leaks.
|
||||||
impl<'a, MemProvider: PoolProvider> PoolGuard<'a, MemProvider> {
|
impl<'a, MemProvider: PoolProvider> PoolGuard<'a, MemProvider> {
|
||||||
pub fn new(pool: &'a mut MemProvider, addr: StoreAddr) -> Self {
|
pub fn new(pool: &'a mut MemProvider, addr: PoolAddr) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pool,
|
pool,
|
||||||
addr,
|
addr,
|
||||||
@ -303,12 +300,12 @@ impl<'a, MemProvider: PoolProvider> PoolGuard<'a, MemProvider> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&self, buf: &mut [u8]) -> Result<usize, StoreError> {
|
pub fn read(&self, buf: &mut [u8]) -> Result<usize, PoolError> {
|
||||||
self.pool.read(&self.addr, buf)
|
self.pool.read(&self.addr, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub fn read_as_vec(&self) -> Result<alloc::vec::Vec<u8>, StoreError> {
|
pub fn read_as_vec(&self) -> Result<alloc::vec::Vec<u8>, PoolError> {
|
||||||
self.pool.read_as_vec(&self.addr)
|
self.pool.read_as_vec(&self.addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,19 +331,19 @@ pub struct PoolRwGuard<'a, MemProvider: PoolProvider + ?Sized> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, MemProvider: PoolProvider> PoolRwGuard<'a, MemProvider> {
|
impl<'a, MemProvider: PoolProvider> PoolRwGuard<'a, MemProvider> {
|
||||||
pub fn new(pool: &'a mut MemProvider, addr: StoreAddr) -> Self {
|
pub fn new(pool: &'a mut MemProvider, addr: PoolAddr) -> Self {
|
||||||
Self {
|
Self {
|
||||||
guard: PoolGuard::new(pool, addr),
|
guard: PoolGuard::new(pool, addr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update<U: FnMut(&mut [u8])>(&mut self, updater: &mut U) -> Result<(), StoreError> {
|
pub fn update<U: FnMut(&mut [u8])>(&mut self, updater: &mut U) -> Result<(), PoolError> {
|
||||||
self.guard.pool.modify(&self.guard.addr, updater)
|
self.guard.pool.modify(&self.guard.addr, updater)
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate!(
|
delegate!(
|
||||||
to self.guard {
|
to self.guard {
|
||||||
pub fn read(&self, buf: &mut [u8]) -> Result<usize, StoreError>;
|
pub fn read(&self, buf: &mut [u8]) -> Result<usize, PoolError>;
|
||||||
/// Releasing the pool guard will disable the automatic deletion of the data when the guard
|
/// Releasing the pool guard will disable the automatic deletion of the data when the guard
|
||||||
/// is dropped.
|
/// is dropped.
|
||||||
pub fn release(&mut self);
|
pub fn release(&mut self);
|
||||||
@ -357,7 +354,7 @@ impl<'a, MemProvider: PoolProvider> PoolRwGuard<'a, MemProvider> {
|
|||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
mod alloc_mod {
|
mod alloc_mod {
|
||||||
use super::{PoolGuard, PoolProvider, PoolProviderWithGuards, PoolRwGuard, StaticPoolAddr};
|
use super::{PoolGuard, PoolProvider, PoolProviderWithGuards, PoolRwGuard, StaticPoolAddr};
|
||||||
use crate::pool::{NumBlocks, StoreAddr, StoreError, StoreIdError};
|
use crate::pool::{NumBlocks, PoolAddr, PoolError, StoreIdError};
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use spacepackets::ByteConversionError;
|
use spacepackets::ByteConversionError;
|
||||||
@ -452,41 +449,41 @@ mod alloc_mod {
|
|||||||
local_pool
|
local_pool
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addr_check(&self, addr: &StaticPoolAddr) -> Result<usize, StoreError> {
|
fn addr_check(&self, addr: &StaticPoolAddr) -> Result<usize, PoolError> {
|
||||||
self.validate_addr(addr)?;
|
self.validate_addr(addr)?;
|
||||||
let pool_idx = addr.pool_idx as usize;
|
let pool_idx = addr.pool_idx as usize;
|
||||||
let size_list = self.sizes_lists.get(pool_idx).unwrap();
|
let size_list = self.sizes_lists.get(pool_idx).unwrap();
|
||||||
let curr_size = size_list[addr.packet_idx as usize];
|
let curr_size = size_list[addr.packet_idx as usize];
|
||||||
if curr_size == STORE_FREE {
|
if curr_size == STORE_FREE {
|
||||||
return Err(StoreError::DataDoesNotExist(StoreAddr::from(*addr)));
|
return Err(PoolError::DataDoesNotExist(PoolAddr::from(*addr)));
|
||||||
}
|
}
|
||||||
Ok(curr_size)
|
Ok(curr_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_addr(&self, addr: &StaticPoolAddr) -> Result<(), StoreError> {
|
fn validate_addr(&self, addr: &StaticPoolAddr) -> Result<(), PoolError> {
|
||||||
let pool_idx = addr.pool_idx as usize;
|
let pool_idx = addr.pool_idx as usize;
|
||||||
if pool_idx >= self.pool_cfg.cfg.len() {
|
if pool_idx >= self.pool_cfg.cfg.len() {
|
||||||
return Err(StoreError::InvalidStoreId(
|
return Err(PoolError::InvalidStoreId(
|
||||||
StoreIdError::InvalidSubpool(addr.pool_idx),
|
StoreIdError::InvalidSubpool(addr.pool_idx),
|
||||||
Some(StoreAddr::from(*addr)),
|
Some(PoolAddr::from(*addr)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if addr.packet_idx >= self.pool_cfg.cfg[addr.pool_idx as usize].0 {
|
if addr.packet_idx >= self.pool_cfg.cfg[addr.pool_idx as usize].0 {
|
||||||
return Err(StoreError::InvalidStoreId(
|
return Err(PoolError::InvalidStoreId(
|
||||||
StoreIdError::InvalidPacketIdx(addr.packet_idx),
|
StoreIdError::InvalidPacketIdx(addr.packet_idx),
|
||||||
Some(StoreAddr::from(*addr)),
|
Some(PoolAddr::from(*addr)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reserve(&mut self, data_len: usize) -> Result<StaticPoolAddr, StoreError> {
|
fn reserve(&mut self, data_len: usize) -> Result<StaticPoolAddr, PoolError> {
|
||||||
let mut subpool_idx = self.find_subpool(data_len, 0)?;
|
let mut subpool_idx = self.find_subpool(data_len, 0)?;
|
||||||
|
|
||||||
if self.pool_cfg.spill_to_higher_subpools {
|
if self.pool_cfg.spill_to_higher_subpools {
|
||||||
while let Err(StoreError::StoreFull(_)) = self.find_empty(subpool_idx) {
|
while let Err(PoolError::StoreFull(_)) = self.find_empty(subpool_idx) {
|
||||||
if (subpool_idx + 1) as usize == self.sizes_lists.len() {
|
if (subpool_idx + 1) as usize == self.sizes_lists.len() {
|
||||||
return Err(StoreError::StoreFull(subpool_idx));
|
return Err(PoolError::StoreFull(subpool_idx));
|
||||||
}
|
}
|
||||||
subpool_idx += 1;
|
subpool_idx += 1;
|
||||||
}
|
}
|
||||||
@ -500,7 +497,7 @@ mod alloc_mod {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_subpool(&self, req_size: usize, start_at_subpool: u16) -> Result<u16, StoreError> {
|
fn find_subpool(&self, req_size: usize, start_at_subpool: u16) -> Result<u16, PoolError> {
|
||||||
for (i, &(_, elem_size)) in self.pool_cfg.cfg.iter().enumerate() {
|
for (i, &(_, elem_size)) in self.pool_cfg.cfg.iter().enumerate() {
|
||||||
if i < start_at_subpool as usize {
|
if i < start_at_subpool as usize {
|
||||||
continue;
|
continue;
|
||||||
@ -509,21 +506,21 @@ mod alloc_mod {
|
|||||||
return Ok(i as u16);
|
return Ok(i as u16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(StoreError::DataTooLarge(req_size))
|
Err(PoolError::DataTooLarge(req_size))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, addr: &StaticPoolAddr, data: &[u8]) -> Result<(), StoreError> {
|
fn write(&mut self, addr: &StaticPoolAddr, data: &[u8]) -> Result<(), PoolError> {
|
||||||
let packet_pos = self.raw_pos(addr).ok_or(StoreError::InternalError(0))?;
|
let packet_pos = self.raw_pos(addr).ok_or(PoolError::InternalError(0))?;
|
||||||
let subpool = self
|
let subpool = self
|
||||||
.pool
|
.pool
|
||||||
.get_mut(addr.pool_idx as usize)
|
.get_mut(addr.pool_idx as usize)
|
||||||
.ok_or(StoreError::InternalError(1))?;
|
.ok_or(PoolError::InternalError(1))?;
|
||||||
let pool_slice = &mut subpool[packet_pos..packet_pos + data.len()];
|
let pool_slice = &mut subpool[packet_pos..packet_pos + data.len()];
|
||||||
pool_slice.copy_from_slice(data);
|
pool_slice.copy_from_slice(data);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_empty(&mut self, subpool: u16) -> Result<(u16, &mut usize), StoreError> {
|
fn find_empty(&mut self, subpool: u16) -> Result<(u16, &mut usize), PoolError> {
|
||||||
if let Some(size_list) = self.sizes_lists.get_mut(subpool as usize) {
|
if let Some(size_list) = self.sizes_lists.get_mut(subpool as usize) {
|
||||||
for (i, elem_size) in size_list.iter_mut().enumerate() {
|
for (i, elem_size) in size_list.iter_mut().enumerate() {
|
||||||
if *elem_size == STORE_FREE {
|
if *elem_size == STORE_FREE {
|
||||||
@ -531,12 +528,12 @@ mod alloc_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(StoreError::InvalidStoreId(
|
return Err(PoolError::InvalidStoreId(
|
||||||
StoreIdError::InvalidSubpool(subpool),
|
StoreIdError::InvalidSubpool(subpool),
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Err(StoreError::StoreFull(subpool))
|
Err(PoolError::StoreFull(subpool))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn raw_pos(&self, addr: &StaticPoolAddr) -> Option<usize> {
|
fn raw_pos(&self, addr: &StaticPoolAddr) -> Option<usize> {
|
||||||
@ -546,10 +543,10 @@ mod alloc_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PoolProvider for StaticMemoryPool {
|
impl PoolProvider for StaticMemoryPool {
|
||||||
fn add(&mut self, data: &[u8]) -> Result<StoreAddr, StoreError> {
|
fn add(&mut self, data: &[u8]) -> Result<PoolAddr, PoolError> {
|
||||||
let data_len = data.len();
|
let data_len = data.len();
|
||||||
if data_len > POOL_MAX_SIZE {
|
if data_len > POOL_MAX_SIZE {
|
||||||
return Err(StoreError::DataTooLarge(data_len));
|
return Err(PoolError::DataTooLarge(data_len));
|
||||||
}
|
}
|
||||||
let addr = self.reserve(data_len)?;
|
let addr = self.reserve(data_len)?;
|
||||||
self.write(&addr, data)?;
|
self.write(&addr, data)?;
|
||||||
@ -560,9 +557,9 @@ mod alloc_mod {
|
|||||||
&mut self,
|
&mut self,
|
||||||
len: usize,
|
len: usize,
|
||||||
mut writer: W,
|
mut writer: W,
|
||||||
) -> Result<StoreAddr, StoreError> {
|
) -> Result<PoolAddr, PoolError> {
|
||||||
if len > POOL_MAX_SIZE {
|
if len > POOL_MAX_SIZE {
|
||||||
return Err(StoreError::DataTooLarge(len));
|
return Err(PoolError::DataTooLarge(len));
|
||||||
}
|
}
|
||||||
let addr = self.reserve(len)?;
|
let addr = self.reserve(len)?;
|
||||||
let raw_pos = self.raw_pos(&addr).unwrap();
|
let raw_pos = self.raw_pos(&addr).unwrap();
|
||||||
@ -574,9 +571,9 @@ mod alloc_mod {
|
|||||||
|
|
||||||
fn modify<U: FnMut(&mut [u8])>(
|
fn modify<U: FnMut(&mut [u8])>(
|
||||||
&mut self,
|
&mut self,
|
||||||
addr: &StoreAddr,
|
addr: &PoolAddr,
|
||||||
mut updater: U,
|
mut updater: U,
|
||||||
) -> Result<(), StoreError> {
|
) -> Result<(), PoolError> {
|
||||||
let addr = StaticPoolAddr::from(*addr);
|
let addr = StaticPoolAddr::from(*addr);
|
||||||
let curr_size = self.addr_check(&addr)?;
|
let curr_size = self.addr_check(&addr)?;
|
||||||
let raw_pos = self.raw_pos(&addr).unwrap();
|
let raw_pos = self.raw_pos(&addr).unwrap();
|
||||||
@ -586,7 +583,7 @@ mod alloc_mod {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(&self, addr: &StoreAddr, buf: &mut [u8]) -> Result<usize, StoreError> {
|
fn read(&self, addr: &PoolAddr, buf: &mut [u8]) -> Result<usize, PoolError> {
|
||||||
let addr = StaticPoolAddr::from(*addr);
|
let addr = StaticPoolAddr::from(*addr);
|
||||||
let curr_size = self.addr_check(&addr)?;
|
let curr_size = self.addr_check(&addr)?;
|
||||||
if buf.len() < curr_size {
|
if buf.len() < curr_size {
|
||||||
@ -604,7 +601,7 @@ mod alloc_mod {
|
|||||||
Ok(curr_size)
|
Ok(curr_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete(&mut self, addr: StoreAddr) -> Result<(), StoreError> {
|
fn delete(&mut self, addr: PoolAddr) -> Result<(), PoolError> {
|
||||||
let addr = StaticPoolAddr::from(addr);
|
let addr = StaticPoolAddr::from(addr);
|
||||||
self.addr_check(&addr)?;
|
self.addr_check(&addr)?;
|
||||||
let block_size = self.pool_cfg.cfg.get(addr.pool_idx as usize).unwrap().1;
|
let block_size = self.pool_cfg.cfg.get(addr.pool_idx as usize).unwrap().1;
|
||||||
@ -617,7 +614,7 @@ mod alloc_mod {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_element_at(&self, addr: &StoreAddr) -> Result<bool, StoreError> {
|
fn has_element_at(&self, addr: &PoolAddr) -> Result<bool, PoolError> {
|
||||||
let addr = StaticPoolAddr::from(*addr);
|
let addr = StaticPoolAddr::from(*addr);
|
||||||
self.validate_addr(&addr)?;
|
self.validate_addr(&addr)?;
|
||||||
let pool_idx = addr.pool_idx as usize;
|
let pool_idx = addr.pool_idx as usize;
|
||||||
@ -629,7 +626,7 @@ mod alloc_mod {
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len_of_data(&self, addr: &StoreAddr) -> Result<usize, StoreError> {
|
fn len_of_data(&self, addr: &PoolAddr) -> Result<usize, PoolError> {
|
||||||
let addr = StaticPoolAddr::from(*addr);
|
let addr = StaticPoolAddr::from(*addr);
|
||||||
self.validate_addr(&addr)?;
|
self.validate_addr(&addr)?;
|
||||||
let pool_idx = addr.pool_idx as usize;
|
let pool_idx = addr.pool_idx as usize;
|
||||||
@ -643,11 +640,11 @@ mod alloc_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PoolProviderWithGuards for StaticMemoryPool {
|
impl PoolProviderWithGuards for StaticMemoryPool {
|
||||||
fn modify_with_guard(&mut self, addr: StoreAddr) -> PoolRwGuard<Self> {
|
fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard<Self> {
|
||||||
PoolRwGuard::new(self, addr)
|
PoolRwGuard::new(self, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_with_guard(&mut self, addr: StoreAddr) -> PoolGuard<Self> {
|
fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard<Self> {
|
||||||
PoolGuard::new(self, addr)
|
PoolGuard::new(self, addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -656,8 +653,8 @@ mod alloc_mod {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::pool::{
|
use crate::pool::{
|
||||||
PoolGuard, PoolProvider, PoolProviderWithGuards, PoolRwGuard, StaticMemoryPool,
|
PoolError, PoolGuard, PoolProvider, PoolProviderWithGuards, PoolRwGuard, StaticMemoryPool,
|
||||||
StaticPoolAddr, StaticPoolConfig, StoreError, StoreIdError, POOL_MAX_SIZE,
|
StaticPoolAddr, StaticPoolConfig, StoreIdError, POOL_MAX_SIZE,
|
||||||
};
|
};
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
@ -781,7 +778,7 @@ mod tests {
|
|||||||
let res = local_pool.free_element(8, |_| {});
|
let res = local_pool.free_element(8, |_| {});
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
let err = res.unwrap_err();
|
let err = res.unwrap_err();
|
||||||
assert_eq!(err, StoreError::StoreFull(1));
|
assert_eq!(err, PoolError::StoreFull(1));
|
||||||
|
|
||||||
// Verify that the two deletions are successful
|
// Verify that the two deletions are successful
|
||||||
assert!(local_pool.delete(addr0).is_ok());
|
assert!(local_pool.delete(addr0).is_ok());
|
||||||
@ -803,7 +800,7 @@ mod tests {
|
|||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
res.unwrap_err(),
|
res.unwrap_err(),
|
||||||
StoreError::DataDoesNotExist { .. }
|
PoolError::DataDoesNotExist { .. }
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -816,8 +813,8 @@ mod tests {
|
|||||||
let res = local_pool.add(&test_buf);
|
let res = local_pool.add(&test_buf);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
let err = res.unwrap_err();
|
let err = res.unwrap_err();
|
||||||
assert!(matches!(err, StoreError::StoreFull { .. }));
|
assert!(matches!(err, PoolError::StoreFull { .. }));
|
||||||
if let StoreError::StoreFull(subpool) = err {
|
if let PoolError::StoreFull(subpool) = err {
|
||||||
assert_eq!(subpool, 2);
|
assert_eq!(subpool, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -835,7 +832,7 @@ mod tests {
|
|||||||
let err = res.unwrap_err();
|
let err = res.unwrap_err();
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
err,
|
err,
|
||||||
StoreError::InvalidStoreId(StoreIdError::InvalidSubpool(3), Some(_))
|
PoolError::InvalidStoreId(StoreIdError::InvalidSubpool(3), Some(_))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -852,7 +849,7 @@ mod tests {
|
|||||||
let err = res.unwrap_err();
|
let err = res.unwrap_err();
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
err,
|
err,
|
||||||
StoreError::InvalidStoreId(StoreIdError::InvalidPacketIdx(1), Some(_))
|
PoolError::InvalidStoreId(StoreIdError::InvalidPacketIdx(1), Some(_))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -863,7 +860,7 @@ mod tests {
|
|||||||
let res = local_pool.add(&data_too_large);
|
let res = local_pool.add(&data_too_large);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
let err = res.unwrap_err();
|
let err = res.unwrap_err();
|
||||||
assert_eq!(err, StoreError::DataTooLarge(20));
|
assert_eq!(err, PoolError::DataTooLarge(20));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -871,10 +868,7 @@ mod tests {
|
|||||||
let mut local_pool = basic_small_pool();
|
let mut local_pool = basic_small_pool();
|
||||||
let res = local_pool.free_element(POOL_MAX_SIZE + 1, |_| {});
|
let res = local_pool.free_element(POOL_MAX_SIZE + 1, |_| {});
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
assert_eq!(
|
assert_eq!(res.unwrap_err(), PoolError::DataTooLarge(POOL_MAX_SIZE + 1));
|
||||||
res.unwrap_err(),
|
|
||||||
StoreError::DataTooLarge(POOL_MAX_SIZE + 1)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -883,7 +877,7 @@ mod tests {
|
|||||||
// Try to request a slot which is too large
|
// Try to request a slot which is too large
|
||||||
let res = local_pool.free_element(20, |_| {});
|
let res = local_pool.free_element(20, |_| {});
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
assert_eq!(res.unwrap_err(), StoreError::DataTooLarge(20));
|
assert_eq!(res.unwrap_err(), PoolError::DataTooLarge(20));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1003,7 +997,7 @@ mod tests {
|
|||||||
let should_fail = local_pool.free_element(8, |_| {});
|
let should_fail = local_pool.free_element(8, |_| {});
|
||||||
assert!(should_fail.is_err());
|
assert!(should_fail.is_err());
|
||||||
if let Err(err) = should_fail {
|
if let Err(err) = should_fail {
|
||||||
assert_eq!(err, StoreError::StoreFull(1));
|
assert_eq!(err, PoolError::StoreFull(1));
|
||||||
} else {
|
} else {
|
||||||
panic!("unexpected store address");
|
panic!("unexpected store address");
|
||||||
}
|
}
|
||||||
@ -1034,7 +1028,7 @@ mod tests {
|
|||||||
let should_fail = local_pool.free_element(8, |_| {});
|
let should_fail = local_pool.free_element(8, |_| {});
|
||||||
assert!(should_fail.is_err());
|
assert!(should_fail.is_err());
|
||||||
if let Err(err) = should_fail {
|
if let Err(err) = should_fail {
|
||||||
assert_eq!(err, StoreError::StoreFull(2));
|
assert_eq!(err, PoolError::StoreFull(2));
|
||||||
} else {
|
} else {
|
||||||
panic!("unexpected store address");
|
panic!("unexpected store address");
|
||||||
}
|
}
|
||||||
|
@ -257,8 +257,8 @@ pub mod alloc_mod {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{events::SeverityInfo, tmtc::PacketAsVec};
|
|
||||||
use crate::request::UniqueApidTargetId;
|
use crate::request::UniqueApidTargetId;
|
||||||
|
use crate::{events::SeverityInfo, tmtc::PacketAsVec};
|
||||||
use std::sync::mpsc::{self, TryRecvError};
|
use std::sync::mpsc::{self, TryRecvError};
|
||||||
|
|
||||||
const INFO_EVENT: EventU32TypedSev<SeverityInfo> =
|
const INFO_EVENT: EventU32TypedSev<SeverityInfo> =
|
||||||
|
@ -213,9 +213,13 @@ mod tests {
|
|||||||
.expect("acceptance success failure")
|
.expect("acceptance success failure")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) {
|
||||||
|
self.common
|
||||||
|
.send_tc(self.handler.service_helper.id(), token, tc);
|
||||||
|
}
|
||||||
|
|
||||||
delegate! {
|
delegate! {
|
||||||
to self.common {
|
to self.common {
|
||||||
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator);
|
|
||||||
fn read_next_tm(&mut self) -> PusTmReader<'_>;
|
fn read_next_tm(&mut self) -> PusTmReader<'_>;
|
||||||
fn check_no_tm_available(&self) -> bool;
|
fn check_no_tm_available(&self) -> bool;
|
||||||
fn check_next_verification_tm(&self, subservice: u8, expected_request_id: RequestId);
|
fn check_next_verification_tm(&self, subservice: u8, expected_request_id: RequestId);
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
//!
|
//!
|
||||||
//! This module contains structures to make working with the PUS C standard easier.
|
//! This module contains structures to make working with the PUS C standard easier.
|
||||||
//! The satrs-example application contains various usage examples of these components.
|
//! The satrs-example application contains various usage examples of these components.
|
||||||
use crate::pool::{StoreAddr, StoreError};
|
use crate::pool::{PoolAddr, PoolError};
|
||||||
use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken};
|
use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken};
|
||||||
use crate::queue::{GenericReceiveError, GenericSendError};
|
use crate::queue::{GenericReceiveError, GenericSendError};
|
||||||
use crate::request::{GenericMessage, MessageMetadata, RequestId};
|
use crate::request::{GenericMessage, MessageMetadata, RequestId};
|
||||||
|
use crate::tmtc::{PacketAsVec, PacketInPool};
|
||||||
use crate::ComponentId;
|
use crate::ComponentId;
|
||||||
use core::fmt::{Display, Formatter};
|
use core::fmt::{Display, Formatter};
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
@ -44,12 +45,12 @@ use self::verification::VerificationReportingProvider;
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum PusTmVariant<'time, 'src_data> {
|
pub enum PusTmVariant<'time, 'src_data> {
|
||||||
InStore(StoreAddr),
|
InStore(PoolAddr),
|
||||||
Direct(PusTmCreator<'time, 'src_data>),
|
Direct(PusTmCreator<'time, 'src_data>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StoreAddr> for PusTmVariant<'_, '_> {
|
impl From<PoolAddr> for PusTmVariant<'_, '_> {
|
||||||
fn from(value: StoreAddr) -> Self {
|
fn from(value: PoolAddr) -> Self {
|
||||||
Self::InStore(value)
|
Self::InStore(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,10 +63,10 @@ impl<'time, 'src_data> From<PusTmCreator<'time, 'src_data>> for PusTmVariant<'ti
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EcssTmtcError {
|
pub enum EcssTmtcError {
|
||||||
Store(StoreError),
|
Store(PoolError),
|
||||||
ByteConversion(ByteConversionError),
|
ByteConversion(ByteConversionError),
|
||||||
Pus(PusError),
|
Pus(PusError),
|
||||||
CantSendAddr(StoreAddr),
|
CantSendAddr(PoolAddr),
|
||||||
CantSendDirectTm,
|
CantSendDirectTm,
|
||||||
Send(GenericSendError),
|
Send(GenericSendError),
|
||||||
Receive(GenericReceiveError),
|
Receive(GenericReceiveError),
|
||||||
@ -99,8 +100,8 @@ impl Display for EcssTmtcError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StoreError> for EcssTmtcError {
|
impl From<PoolError> for EcssTmtcError {
|
||||||
fn from(value: StoreError) -> Self {
|
fn from(value: PoolError) -> Self {
|
||||||
Self::Store(value)
|
Self::Store(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,27 +176,26 @@ impl EcssTmSender for EcssTmDummySender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Maybe this should wrap PacketInStore and PacketAsVec instead..
|
/// A PUS telecommand packet can be stored in memory and sent using different methods. Right now,
|
||||||
/// A PUS telecommand packet can be stored in memory using different methods. Right now,
|
|
||||||
/// storage inside a pool structure like [crate::pool::StaticMemoryPool], and storage inside a
|
/// storage inside a pool structure like [crate::pool::StaticMemoryPool], and storage inside a
|
||||||
/// `Vec<u8>` are supported.
|
/// `Vec<u8>` are supported.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum TcInMemory {
|
pub enum TcInMemory {
|
||||||
StoreAddr(StoreAddr),
|
Pool(PacketInPool),
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
Vec(alloc::vec::Vec<u8>),
|
Vec(PacketAsVec),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StoreAddr> for TcInMemory {
|
impl From<PacketInPool> for TcInMemory {
|
||||||
fn from(value: StoreAddr) -> Self {
|
fn from(value: PacketInPool) -> Self {
|
||||||
Self::StoreAddr(value)
|
Self::Pool(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
impl From<alloc::vec::Vec<u8>> for TcInMemory {
|
impl From<PacketAsVec> for TcInMemory {
|
||||||
fn from(value: alloc::vec::Vec<u8>) -> Self {
|
fn from(value: PacketAsVec) -> Self {
|
||||||
Self::Vec(value)
|
Self::Vec(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,8 +263,8 @@ impl From<PusError> for TryRecvTmtcError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StoreError> for TryRecvTmtcError {
|
impl From<PoolError> for TryRecvTmtcError {
|
||||||
fn from(value: StoreError) -> Self {
|
fn from(value: PoolError) -> Self {
|
||||||
Self::Tmtc(value.into())
|
Self::Tmtc(value.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -654,7 +654,7 @@ pub mod alloc_mod {
|
|||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||||
pub mod std_mod {
|
pub mod std_mod {
|
||||||
use crate::pool::{
|
use crate::pool::{
|
||||||
PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool, StoreAddr, StoreError,
|
PoolAddr, PoolError, PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool,
|
||||||
};
|
};
|
||||||
use crate::pus::verification::{TcStateAccepted, VerificationToken};
|
use crate::pus::verification::{TcStateAccepted, VerificationToken};
|
||||||
use crate::pus::{
|
use crate::pus::{
|
||||||
@ -681,8 +681,8 @@ pub mod std_mod {
|
|||||||
use super::{AcceptedEcssTcAndToken, ActiveRequestProvider, TcInMemory};
|
use super::{AcceptedEcssTcAndToken, ActiveRequestProvider, TcInMemory};
|
||||||
use crate::tmtc::PacketInPool;
|
use crate::tmtc::PacketInPool;
|
||||||
|
|
||||||
impl From<mpsc::SendError<StoreAddr>> for EcssTmtcError {
|
impl From<mpsc::SendError<PoolAddr>> for EcssTmtcError {
|
||||||
fn from(_: mpsc::SendError<StoreAddr>) -> Self {
|
fn from(_: mpsc::SendError<PoolAddr>) -> Self {
|
||||||
Self::Send(GenericSendError::RxDisconnected)
|
Self::Send(GenericSendError::RxDisconnected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -769,14 +769,14 @@ pub mod std_mod {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crossbeam_channel as cb;
|
use crossbeam_channel as cb;
|
||||||
|
|
||||||
impl From<cb::SendError<StoreAddr>> for EcssTmtcError {
|
impl From<cb::SendError<PoolAddr>> for EcssTmtcError {
|
||||||
fn from(_: cb::SendError<StoreAddr>) -> Self {
|
fn from(_: cb::SendError<PoolAddr>) -> Self {
|
||||||
Self::Send(GenericSendError::RxDisconnected)
|
Self::Send(GenericSendError::RxDisconnected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<cb::TrySendError<StoreAddr>> for EcssTmtcError {
|
impl From<cb::TrySendError<PoolAddr>> for EcssTmtcError {
|
||||||
fn from(value: cb::TrySendError<StoreAddr>) -> Self {
|
fn from(value: cb::TrySendError<PoolAddr>) -> Self {
|
||||||
match value {
|
match value {
|
||||||
cb::TrySendError::Full(_) => Self::Send(GenericSendError::QueueFull(None)),
|
cb::TrySendError::Full(_) => Self::Send(GenericSendError::QueueFull(None)),
|
||||||
cb::TrySendError::Disconnected(_) => {
|
cb::TrySendError::Disconnected(_) => {
|
||||||
@ -952,6 +952,8 @@ pub mod std_mod {
|
|||||||
|
|
||||||
fn tc_slice_raw(&self) -> &[u8];
|
fn tc_slice_raw(&self) -> &[u8];
|
||||||
|
|
||||||
|
fn sender_id(&self) -> Option<ComponentId>;
|
||||||
|
|
||||||
fn cache_and_convert(
|
fn cache_and_convert(
|
||||||
&mut self,
|
&mut self,
|
||||||
possible_packet: &TcInMemory,
|
possible_packet: &TcInMemory,
|
||||||
@ -974,6 +976,7 @@ pub mod std_mod {
|
|||||||
/// [SharedStaticMemoryPool].
|
/// [SharedStaticMemoryPool].
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct EcssTcInVecConverter {
|
pub struct EcssTcInVecConverter {
|
||||||
|
sender_id: Option<ComponentId>,
|
||||||
pub pus_tc_raw: Option<Vec<u8>>,
|
pub pus_tc_raw: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -981,16 +984,21 @@ pub mod std_mod {
|
|||||||
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
|
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
|
||||||
self.pus_tc_raw = None;
|
self.pus_tc_raw = None;
|
||||||
match tc_in_memory {
|
match tc_in_memory {
|
||||||
super::TcInMemory::StoreAddr(_) => {
|
super::TcInMemory::Pool(_packet_in_pool) => {
|
||||||
return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone()));
|
return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone()));
|
||||||
}
|
}
|
||||||
super::TcInMemory::Vec(vec) => {
|
super::TcInMemory::Vec(packet_with_sender) => {
|
||||||
self.pus_tc_raw = Some(vec.clone());
|
self.pus_tc_raw = Some(packet_with_sender.packet.clone());
|
||||||
|
self.sender_id = Some(packet_with_sender.sender_id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sender_id(&self) -> Option<ComponentId> {
|
||||||
|
self.sender_id
|
||||||
|
}
|
||||||
|
|
||||||
fn tc_slice_raw(&self) -> &[u8] {
|
fn tc_slice_raw(&self) -> &[u8] {
|
||||||
if self.pus_tc_raw.is_none() {
|
if self.pus_tc_raw.is_none() {
|
||||||
return &[];
|
return &[];
|
||||||
@ -1004,6 +1012,7 @@ pub mod std_mod {
|
|||||||
/// packets should be avoided. Please note that this structure is not able to convert TCs which
|
/// packets should be avoided. Please note that this structure is not able to convert TCs which
|
||||||
/// are stored as a `Vec<u8>`.
|
/// are stored as a `Vec<u8>`.
|
||||||
pub struct EcssTcInSharedStoreConverter {
|
pub struct EcssTcInSharedStoreConverter {
|
||||||
|
sender_id: Option<ComponentId>,
|
||||||
shared_tc_store: SharedStaticMemoryPool,
|
shared_tc_store: SharedStaticMemoryPool,
|
||||||
pus_buf: Vec<u8>,
|
pus_buf: Vec<u8>,
|
||||||
}
|
}
|
||||||
@ -1011,15 +1020,16 @@ pub mod std_mod {
|
|||||||
impl EcssTcInSharedStoreConverter {
|
impl EcssTcInSharedStoreConverter {
|
||||||
pub fn new(shared_tc_store: SharedStaticMemoryPool, max_expected_tc_size: usize) -> Self {
|
pub fn new(shared_tc_store: SharedStaticMemoryPool, max_expected_tc_size: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
sender_id: None,
|
||||||
shared_tc_store,
|
shared_tc_store,
|
||||||
pus_buf: alloc::vec![0; max_expected_tc_size],
|
pus_buf: alloc::vec![0; max_expected_tc_size],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_tc_to_buf(&mut self, addr: StoreAddr) -> Result<(), PusTcFromMemError> {
|
pub fn copy_tc_to_buf(&mut self, addr: PoolAddr) -> Result<(), PusTcFromMemError> {
|
||||||
// Keep locked section as short as possible.
|
// Keep locked section as short as possible.
|
||||||
let mut tc_pool = self.shared_tc_store.write().map_err(|_| {
|
let mut tc_pool = self.shared_tc_store.write().map_err(|_| {
|
||||||
PusTcFromMemError::EcssTmtc(EcssTmtcError::Store(StoreError::LockError))
|
PusTcFromMemError::EcssTmtc(EcssTmtcError::Store(PoolError::LockError))
|
||||||
})?;
|
})?;
|
||||||
let tc_size = tc_pool.len_of_data(&addr).map_err(EcssTmtcError::Store)?;
|
let tc_size = tc_pool.len_of_data(&addr).map_err(EcssTmtcError::Store)?;
|
||||||
if tc_size > self.pus_buf.len() {
|
if tc_size > self.pus_buf.len() {
|
||||||
@ -1041,8 +1051,9 @@ pub mod std_mod {
|
|||||||
impl EcssTcInMemConverter for EcssTcInSharedStoreConverter {
|
impl EcssTcInMemConverter for EcssTcInSharedStoreConverter {
|
||||||
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
|
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
|
||||||
match tc_in_memory {
|
match tc_in_memory {
|
||||||
super::TcInMemory::StoreAddr(addr) => {
|
super::TcInMemory::Pool(packet_in_pool) => {
|
||||||
self.copy_tc_to_buf(*addr)?;
|
self.copy_tc_to_buf(packet_in_pool.store_addr)?;
|
||||||
|
self.sender_id = Some(packet_in_pool.sender_id);
|
||||||
}
|
}
|
||||||
super::TcInMemory::Vec(_) => {
|
super::TcInMemory::Vec(_) => {
|
||||||
return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone()));
|
return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone()));
|
||||||
@ -1054,6 +1065,10 @@ pub mod std_mod {
|
|||||||
fn tc_slice_raw(&self) -> &[u8] {
|
fn tc_slice_raw(&self) -> &[u8] {
|
||||||
self.pus_buf.as_ref()
|
self.pus_buf.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sender_id(&self) -> Option<ComponentId> {
|
||||||
|
self.sender_id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PusServiceBase<
|
pub struct PusServiceBase<
|
||||||
@ -1364,7 +1379,12 @@ pub mod tests {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
pub fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) {
|
pub fn send_tc(
|
||||||
|
&self,
|
||||||
|
sender_id: ComponentId,
|
||||||
|
token: &VerificationToken<TcStateAccepted>,
|
||||||
|
tc: &PusTcCreator,
|
||||||
|
) {
|
||||||
let mut mut_buf = self.pus_buf.borrow_mut();
|
let mut mut_buf = self.pus_buf.borrow_mut();
|
||||||
let tc_size = tc.write_to_bytes(mut_buf.as_mut_slice()).unwrap();
|
let tc_size = tc.write_to_bytes(mut_buf.as_mut_slice()).unwrap();
|
||||||
let mut tc_pool = self.tc_pool.write().unwrap();
|
let mut tc_pool = self.tc_pool.write().unwrap();
|
||||||
@ -1372,7 +1392,10 @@ pub mod tests {
|
|||||||
drop(tc_pool);
|
drop(tc_pool);
|
||||||
// Send accepted TC to test service handler.
|
// Send accepted TC to test service handler.
|
||||||
self.tc_sender
|
self.tc_sender
|
||||||
.send(EcssTcAndToken::new(addr, *token))
|
.send(EcssTcAndToken::new(
|
||||||
|
PacketInPool::new(sender_id, addr),
|
||||||
|
*token,
|
||||||
|
))
|
||||||
.expect("sending tc failed");
|
.expect("sending tc failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1486,11 +1509,19 @@ pub mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PusServiceHandlerWithVecCommon {
|
impl PusServiceHandlerWithVecCommon {
|
||||||
pub fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) {
|
pub fn send_tc(
|
||||||
|
&self,
|
||||||
|
sender_id: ComponentId,
|
||||||
|
token: &VerificationToken<TcStateAccepted>,
|
||||||
|
tc: &PusTcCreator,
|
||||||
|
) {
|
||||||
// Send accepted TC to test service handler.
|
// Send accepted TC to test service handler.
|
||||||
self.tc_sender
|
self.tc_sender
|
||||||
.send(EcssTcAndToken::new(
|
.send(EcssTcAndToken::new(
|
||||||
TcInMemory::Vec(tc.to_vec().expect("pus tc conversion to vec failed")),
|
TcInMemory::Vec(PacketAsVec::new(
|
||||||
|
sender_id,
|
||||||
|
tc.to_vec().expect("pus tc conversion to vec failed"),
|
||||||
|
)),
|
||||||
*token,
|
*token,
|
||||||
))
|
))
|
||||||
.expect("sending tc failed");
|
.expect("sending tc failed");
|
||||||
|
@ -14,7 +14,7 @@ use spacepackets::{ByteConversionError, CcsdsPacket};
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
use crate::pool::{PoolProvider, StoreError};
|
use crate::pool::{PoolError, PoolProvider};
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub use alloc_mod::*;
|
pub use alloc_mod::*;
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ pub enum ScheduleError {
|
|||||||
},
|
},
|
||||||
/// Nested time-tagged commands are not allowed.
|
/// Nested time-tagged commands are not allowed.
|
||||||
NestedScheduledTc,
|
NestedScheduledTc,
|
||||||
StoreError(StoreError),
|
StoreError(PoolError),
|
||||||
TcDataEmpty,
|
TcDataEmpty,
|
||||||
TimestampError(TimestampError),
|
TimestampError(TimestampError),
|
||||||
WrongSubservice(u8),
|
WrongSubservice(u8),
|
||||||
@ -206,8 +206,8 @@ impl From<PusError> for ScheduleError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StoreError> for ScheduleError {
|
impl From<PoolError> for ScheduleError {
|
||||||
fn from(e: StoreError) -> Self {
|
fn from(e: PoolError) -> Self {
|
||||||
Self::StoreError(e)
|
Self::StoreError(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -240,7 +240,7 @@ impl Error for ScheduleError {
|
|||||||
pub trait PusSchedulerProvider {
|
pub trait PusSchedulerProvider {
|
||||||
type TimeProvider: CcsdsTimeProvider + TimeReader;
|
type TimeProvider: CcsdsTimeProvider + TimeReader;
|
||||||
|
|
||||||
fn reset(&mut self, store: &mut (impl PoolProvider + ?Sized)) -> Result<(), StoreError>;
|
fn reset(&mut self, store: &mut (impl PoolProvider + ?Sized)) -> Result<(), PoolError>;
|
||||||
|
|
||||||
fn is_enabled(&self) -> bool;
|
fn is_enabled(&self) -> bool;
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ pub mod alloc_mod {
|
|||||||
};
|
};
|
||||||
use spacepackets::time::cds::{self, DaysLen24Bits};
|
use spacepackets::time::cds::{self, DaysLen24Bits};
|
||||||
|
|
||||||
use crate::pool::StoreAddr;
|
use crate::pool::PoolAddr;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -368,8 +368,8 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum DeletionResult {
|
enum DeletionResult {
|
||||||
WithoutStoreDeletion(Option<StoreAddr>),
|
WithoutStoreDeletion(Option<PoolAddr>),
|
||||||
WithStoreDeletion(Result<bool, StoreError>),
|
WithStoreDeletion(Result<bool, PoolError>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is the core data structure for scheduling PUS telecommands with [alloc] support.
|
/// This is the core data structure for scheduling PUS telecommands with [alloc] support.
|
||||||
@ -525,7 +525,7 @@ pub mod alloc_mod {
|
|||||||
&mut self,
|
&mut self,
|
||||||
time_window: TimeWindow<TimeProvider>,
|
time_window: TimeWindow<TimeProvider>,
|
||||||
pool: &mut (impl PoolProvider + ?Sized),
|
pool: &mut (impl PoolProvider + ?Sized),
|
||||||
) -> Result<u64, (u64, StoreError)> {
|
) -> Result<u64, (u64, PoolError)> {
|
||||||
let range = self.retrieve_by_time_filter(time_window);
|
let range = self.retrieve_by_time_filter(time_window);
|
||||||
let mut del_packets = 0;
|
let mut del_packets = 0;
|
||||||
let mut res_if_fails = None;
|
let mut res_if_fails = None;
|
||||||
@ -555,7 +555,7 @@ pub mod alloc_mod {
|
|||||||
pub fn delete_all(
|
pub fn delete_all(
|
||||||
&mut self,
|
&mut self,
|
||||||
pool: &mut (impl PoolProvider + ?Sized),
|
pool: &mut (impl PoolProvider + ?Sized),
|
||||||
) -> Result<u64, (u64, StoreError)> {
|
) -> Result<u64, (u64, PoolError)> {
|
||||||
self.delete_by_time_filter(TimeWindow::<cds::CdsTime>::new_select_all(), pool)
|
self.delete_by_time_filter(TimeWindow::<cds::CdsTime>::new_select_all(), pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,7 +601,7 @@ pub mod alloc_mod {
|
|||||||
/// Please note that this function will stop on the first telecommand with a request ID match.
|
/// Please note that this function will stop on the first telecommand with a request ID match.
|
||||||
/// In case of duplicate IDs (which should generally not happen), this function needs to be
|
/// In case of duplicate IDs (which should generally not happen), this function needs to be
|
||||||
/// called repeatedly.
|
/// called repeatedly.
|
||||||
pub fn delete_by_request_id(&mut self, req_id: &RequestId) -> Option<StoreAddr> {
|
pub fn delete_by_request_id(&mut self, req_id: &RequestId) -> Option<PoolAddr> {
|
||||||
if let DeletionResult::WithoutStoreDeletion(v) =
|
if let DeletionResult::WithoutStoreDeletion(v) =
|
||||||
self.delete_by_request_id_internal_without_store_deletion(req_id)
|
self.delete_by_request_id_internal_without_store_deletion(req_id)
|
||||||
{
|
{
|
||||||
@ -615,7 +615,7 @@ pub mod alloc_mod {
|
|||||||
&mut self,
|
&mut self,
|
||||||
req_id: &RequestId,
|
req_id: &RequestId,
|
||||||
pool: &mut (impl PoolProvider + ?Sized),
|
pool: &mut (impl PoolProvider + ?Sized),
|
||||||
) -> Result<bool, StoreError> {
|
) -> Result<bool, PoolError> {
|
||||||
if let DeletionResult::WithStoreDeletion(v) =
|
if let DeletionResult::WithStoreDeletion(v) =
|
||||||
self.delete_by_request_id_internal_with_store_deletion(req_id, pool)
|
self.delete_by_request_id_internal_with_store_deletion(req_id, pool)
|
||||||
{
|
{
|
||||||
@ -693,7 +693,7 @@ pub mod alloc_mod {
|
|||||||
releaser: R,
|
releaser: R,
|
||||||
tc_store: &mut (impl PoolProvider + ?Sized),
|
tc_store: &mut (impl PoolProvider + ?Sized),
|
||||||
tc_buf: &mut [u8],
|
tc_buf: &mut [u8],
|
||||||
) -> Result<u64, (u64, StoreError)> {
|
) -> Result<u64, (u64, PoolError)> {
|
||||||
self.release_telecommands_internal(releaser, tc_store, Some(tc_buf))
|
self.release_telecommands_internal(releaser, tc_store, Some(tc_buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,7 +707,7 @@ pub mod alloc_mod {
|
|||||||
&mut self,
|
&mut self,
|
||||||
releaser: R,
|
releaser: R,
|
||||||
tc_store: &mut (impl PoolProvider + ?Sized),
|
tc_store: &mut (impl PoolProvider + ?Sized),
|
||||||
) -> Result<u64, (u64, StoreError)> {
|
) -> Result<u64, (u64, PoolError)> {
|
||||||
self.release_telecommands_internal(releaser, tc_store, None)
|
self.release_telecommands_internal(releaser, tc_store, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -716,7 +716,7 @@ pub mod alloc_mod {
|
|||||||
mut releaser: R,
|
mut releaser: R,
|
||||||
tc_store: &mut (impl PoolProvider + ?Sized),
|
tc_store: &mut (impl PoolProvider + ?Sized),
|
||||||
mut tc_buf: Option<&mut [u8]>,
|
mut tc_buf: Option<&mut [u8]>,
|
||||||
) -> Result<u64, (u64, StoreError)> {
|
) -> Result<u64, (u64, PoolError)> {
|
||||||
let tcs_to_release = self.telecommands_to_release();
|
let tcs_to_release = self.telecommands_to_release();
|
||||||
let mut released_tcs = 0;
|
let mut released_tcs = 0;
|
||||||
let mut store_error = Ok(());
|
let mut store_error = Ok(());
|
||||||
@ -762,7 +762,7 @@ pub mod alloc_mod {
|
|||||||
mut releaser: R,
|
mut releaser: R,
|
||||||
tc_store: &(impl PoolProvider + ?Sized),
|
tc_store: &(impl PoolProvider + ?Sized),
|
||||||
tc_buf: &mut [u8],
|
tc_buf: &mut [u8],
|
||||||
) -> Result<alloc::vec::Vec<TcInfo>, (alloc::vec::Vec<TcInfo>, StoreError)> {
|
) -> Result<alloc::vec::Vec<TcInfo>, (alloc::vec::Vec<TcInfo>, PoolError)> {
|
||||||
let tcs_to_release = self.telecommands_to_release();
|
let tcs_to_release = self.telecommands_to_release();
|
||||||
let mut released_tcs = alloc::vec::Vec::new();
|
let mut released_tcs = alloc::vec::Vec::new();
|
||||||
for tc in tcs_to_release {
|
for tc in tcs_to_release {
|
||||||
@ -793,7 +793,7 @@ pub mod alloc_mod {
|
|||||||
/// The holding store for the telecommands needs to be passed so all the stored telecommands
|
/// The holding store for the telecommands needs to be passed so all the stored telecommands
|
||||||
/// can be deleted to avoid a memory leak. If at last one deletion operation fails, the error
|
/// can be deleted to avoid a memory leak. If at last one deletion operation fails, the error
|
||||||
/// will be returned but the method will still try to delete all the commands in the schedule.
|
/// will be returned but the method will still try to delete all the commands in the schedule.
|
||||||
fn reset(&mut self, store: &mut (impl PoolProvider + ?Sized)) -> Result<(), StoreError> {
|
fn reset(&mut self, store: &mut (impl PoolProvider + ?Sized)) -> Result<(), PoolError> {
|
||||||
self.enabled = false;
|
self.enabled = false;
|
||||||
let mut deletion_ok = Ok(());
|
let mut deletion_ok = Ok(());
|
||||||
for tc_lists in &mut self.tc_map {
|
for tc_lists in &mut self.tc_map {
|
||||||
@ -851,7 +851,7 @@ pub mod alloc_mod {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::pool::{
|
use crate::pool::{
|
||||||
PoolProvider, StaticMemoryPool, StaticPoolAddr, StaticPoolConfig, StoreAddr, StoreError,
|
PoolAddr, PoolError, PoolProvider, StaticMemoryPool, StaticPoolAddr, StaticPoolConfig,
|
||||||
};
|
};
|
||||||
use alloc::collections::btree_map::Range;
|
use alloc::collections::btree_map::Range;
|
||||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
|
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
|
||||||
@ -990,7 +990,7 @@ mod tests {
|
|||||||
.insert_unwrapped_and_stored_tc(
|
.insert_unwrapped_and_stored_tc(
|
||||||
UnixTime::new_only_secs(100),
|
UnixTime::new_only_secs(100),
|
||||||
TcInfo::new(
|
TcInfo::new(
|
||||||
StoreAddr::from(StaticPoolAddr {
|
PoolAddr::from(StaticPoolAddr {
|
||||||
pool_idx: 0,
|
pool_idx: 0,
|
||||||
packet_idx: 1,
|
packet_idx: 1,
|
||||||
}),
|
}),
|
||||||
@ -1007,7 +1007,7 @@ mod tests {
|
|||||||
.insert_unwrapped_and_stored_tc(
|
.insert_unwrapped_and_stored_tc(
|
||||||
UnixTime::new_only_secs(100),
|
UnixTime::new_only_secs(100),
|
||||||
TcInfo::new(
|
TcInfo::new(
|
||||||
StoreAddr::from(StaticPoolAddr {
|
PoolAddr::from(StaticPoolAddr {
|
||||||
pool_idx: 0,
|
pool_idx: 0,
|
||||||
packet_idx: 2,
|
packet_idx: 2,
|
||||||
}),
|
}),
|
||||||
@ -1051,8 +1051,8 @@ mod tests {
|
|||||||
|
|
||||||
fn common_check(
|
fn common_check(
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
store_addr: &StoreAddr,
|
store_addr: &PoolAddr,
|
||||||
expected_store_addrs: Vec<StoreAddr>,
|
expected_store_addrs: Vec<PoolAddr>,
|
||||||
counter: &mut usize,
|
counter: &mut usize,
|
||||||
) {
|
) {
|
||||||
assert!(enabled);
|
assert!(enabled);
|
||||||
@ -1061,8 +1061,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
fn common_check_disabled(
|
fn common_check_disabled(
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
store_addr: &StoreAddr,
|
store_addr: &PoolAddr,
|
||||||
expected_store_addrs: Vec<StoreAddr>,
|
expected_store_addrs: Vec<PoolAddr>,
|
||||||
counter: &mut usize,
|
counter: &mut usize,
|
||||||
) {
|
) {
|
||||||
assert!(!enabled);
|
assert!(!enabled);
|
||||||
@ -1516,7 +1516,7 @@ mod tests {
|
|||||||
// TC could not even be read..
|
// TC could not even be read..
|
||||||
assert_eq!(err.0, 0);
|
assert_eq!(err.0, 0);
|
||||||
match err.1 {
|
match err.1 {
|
||||||
StoreError::DataDoesNotExist(addr) => {
|
PoolError::DataDoesNotExist(addr) => {
|
||||||
assert_eq!(tc_info_0.addr(), addr);
|
assert_eq!(tc_info_0.addr(), addr);
|
||||||
}
|
}
|
||||||
_ => panic!("unexpected error {}", err.1),
|
_ => panic!("unexpected error {}", err.1),
|
||||||
@ -1539,7 +1539,7 @@ mod tests {
|
|||||||
assert!(reset_res.is_err());
|
assert!(reset_res.is_err());
|
||||||
let err = reset_res.unwrap_err();
|
let err = reset_res.unwrap_err();
|
||||||
match err {
|
match err {
|
||||||
StoreError::DataDoesNotExist(addr) => {
|
PoolError::DataDoesNotExist(addr) => {
|
||||||
assert_eq!(addr, tc_info_0.addr());
|
assert_eq!(addr, tc_info_0.addr());
|
||||||
}
|
}
|
||||||
_ => panic!("unexpected error {err}"),
|
_ => panic!("unexpected error {err}"),
|
||||||
@ -1641,7 +1641,7 @@ mod tests {
|
|||||||
let err = insert_res.unwrap_err();
|
let err = insert_res.unwrap_err();
|
||||||
match err {
|
match err {
|
||||||
ScheduleError::StoreError(e) => match e {
|
ScheduleError::StoreError(e) => match e {
|
||||||
StoreError::StoreFull(_) => {}
|
PoolError::StoreFull(_) => {}
|
||||||
_ => panic!("unexpected store error {e}"),
|
_ => panic!("unexpected store error {e}"),
|
||||||
},
|
},
|
||||||
_ => panic!("unexpected error {err}"),
|
_ => panic!("unexpected error {err}"),
|
||||||
|
@ -315,9 +315,13 @@ mod tests {
|
|||||||
.expect("acceptance success failure")
|
.expect("acceptance success failure")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) {
|
||||||
|
self.common
|
||||||
|
.send_tc(self.handler.service_helper.id(), token, tc);
|
||||||
|
}
|
||||||
|
|
||||||
delegate! {
|
delegate! {
|
||||||
to self.common {
|
to self.common {
|
||||||
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator);
|
|
||||||
fn read_next_tm(&mut self) -> PusTmReader<'_>;
|
fn read_next_tm(&mut self) -> PusTmReader<'_>;
|
||||||
fn check_no_tm_available(&self) -> bool;
|
fn check_no_tm_available(&self) -> bool;
|
||||||
fn check_next_verification_tm(&self, subservice: u8, expected_request_id: RequestId);
|
fn check_next_verification_tm(&self, subservice: u8, expected_request_id: RequestId);
|
||||||
@ -340,7 +344,7 @@ mod tests {
|
|||||||
fn reset(
|
fn reset(
|
||||||
&mut self,
|
&mut self,
|
||||||
_store: &mut (impl crate::pool::PoolProvider + ?Sized),
|
_store: &mut (impl crate::pool::PoolProvider + ?Sized),
|
||||||
) -> Result<(), crate::pool::StoreError> {
|
) -> Result<(), crate::pool::PoolError> {
|
||||||
self.reset_count += 1;
|
self.reset_count += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -203,10 +203,14 @@ mod tests {
|
|||||||
.expect("acceptance success failure")
|
.expect("acceptance success failure")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) {
|
||||||
|
self.common
|
||||||
|
.send_tc(self.handler.service_helper.id(), token, tc);
|
||||||
|
}
|
||||||
|
|
||||||
delegate! {
|
delegate! {
|
||||||
to self.common {
|
to self.common {
|
||||||
fn read_next_tm(&mut self) -> PusTmReader<'_>;
|
fn read_next_tm(&mut self) -> PusTmReader<'_>;
|
||||||
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator);
|
|
||||||
fn check_no_tm_available(&self) -> bool;
|
fn check_no_tm_available(&self) -> bool;
|
||||||
fn check_next_verification_tm(
|
fn check_next_verification_tm(
|
||||||
&self,
|
&self,
|
||||||
@ -254,9 +258,13 @@ mod tests {
|
|||||||
.expect("acceptance success failure")
|
.expect("acceptance success failure")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator) {
|
||||||
|
self.common
|
||||||
|
.send_tc(self.handler.service_helper.id(), token, tc);
|
||||||
|
}
|
||||||
|
|
||||||
delegate! {
|
delegate! {
|
||||||
to self.common {
|
to self.common {
|
||||||
fn send_tc(&self, token: &VerificationToken<TcStateAccepted>, tc: &PusTcCreator);
|
|
||||||
fn read_next_tm(&mut self) -> PusTmReader<'_>;
|
fn read_next_tm(&mut self) -> PusTmReader<'_>;
|
||||||
fn check_no_tm_available(&self) -> bool;
|
fn check_no_tm_available(&self) -> bool;
|
||||||
fn check_next_verification_tm(
|
fn check_next_verification_tm(
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use crate::queue::GenericSendError;
|
use crate::queue::GenericSendError;
|
||||||
use crate::{
|
use crate::{
|
||||||
pool::{PoolProvider, StoreAddr, StoreError},
|
pool::{PoolAddr, PoolError, PoolProvider},
|
||||||
ComponentId,
|
ComponentId,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -33,14 +33,16 @@ pub use std_mod::*;
|
|||||||
|
|
||||||
pub mod tm_helper;
|
pub mod tm_helper;
|
||||||
|
|
||||||
#[derive(Debug)]
|
/// Simple type modelling packet stored inside a pool structure. This structure is intended to
|
||||||
|
/// be used when sending a packet via a message queue, so it also contains the sender ID.
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct PacketInPool {
|
pub struct PacketInPool {
|
||||||
pub sender_id: ComponentId,
|
pub sender_id: ComponentId,
|
||||||
pub store_addr: StoreAddr,
|
pub store_addr: PoolAddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PacketInPool {
|
impl PacketInPool {
|
||||||
pub fn new(sender_id: ComponentId, store_addr: StoreAddr) -> Self {
|
pub fn new(sender_id: ComponentId, store_addr: PoolAddr) -> Self {
|
||||||
Self {
|
Self {
|
||||||
sender_id,
|
sender_id,
|
||||||
store_addr,
|
store_addr,
|
||||||
@ -183,27 +185,27 @@ impl SharedPacketPool {
|
|||||||
|
|
||||||
/// Helper trait for any generic (static) store which allows storing raw or CCSDS packets.
|
/// Helper trait for any generic (static) store which allows storing raw or CCSDS packets.
|
||||||
pub trait CcsdsPacketPool {
|
pub trait CcsdsPacketPool {
|
||||||
fn add_ccsds_tc(&mut self, _: &SpHeader, tc_raw: &[u8]) -> Result<StoreAddr, StoreError> {
|
fn add_ccsds_tc(&mut self, _: &SpHeader, tc_raw: &[u8]) -> Result<PoolAddr, PoolError> {
|
||||||
self.add_raw_tc(tc_raw)
|
self.add_raw_tc(tc_raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result<StoreAddr, StoreError>;
|
fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result<PoolAddr, PoolError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper trait for any generic (static) store which allows storing ECSS PUS Telecommand packets.
|
/// Helper trait for any generic (static) store which allows storing ECSS PUS Telecommand packets.
|
||||||
pub trait PusTcPool {
|
pub trait PusTcPool {
|
||||||
fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result<StoreAddr, StoreError>;
|
fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result<PoolAddr, PoolError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper trait for any generic (static) store which allows storing ECSS PUS Telemetry packets.
|
/// Helper trait for any generic (static) store which allows storing ECSS PUS Telemetry packets.
|
||||||
pub trait PusTmPool {
|
pub trait PusTmPool {
|
||||||
fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result<StoreAddr, StoreError>;
|
fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result<PoolAddr, PoolError>;
|
||||||
fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result<StoreAddr, StoreError>;
|
fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result<PoolAddr, PoolError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PusTcPool for SharedPacketPool {
|
impl PusTcPool for SharedPacketPool {
|
||||||
fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result<StoreAddr, StoreError> {
|
fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result<PoolAddr, PoolError> {
|
||||||
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?;
|
let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
|
||||||
let addr = pg.free_element(pus_tc.len_packed(), |buf| {
|
let addr = pg.free_element(pus_tc.len_packed(), |buf| {
|
||||||
buf[0..pus_tc.len_packed()].copy_from_slice(pus_tc.raw_data());
|
buf[0..pus_tc.len_packed()].copy_from_slice(pus_tc.raw_data());
|
||||||
})?;
|
})?;
|
||||||
@ -212,16 +214,16 @@ impl PusTcPool for SharedPacketPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PusTmPool for SharedPacketPool {
|
impl PusTmPool for SharedPacketPool {
|
||||||
fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result<StoreAddr, StoreError> {
|
fn add_pus_tm_from_reader(&mut self, pus_tm: &PusTmReader) -> Result<PoolAddr, PoolError> {
|
||||||
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?;
|
let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
|
||||||
let addr = pg.free_element(pus_tm.len_packed(), |buf| {
|
let addr = pg.free_element(pus_tm.len_packed(), |buf| {
|
||||||
buf[0..pus_tm.len_packed()].copy_from_slice(pus_tm.raw_data());
|
buf[0..pus_tm.len_packed()].copy_from_slice(pus_tm.raw_data());
|
||||||
})?;
|
})?;
|
||||||
Ok(addr)
|
Ok(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result<StoreAddr, StoreError> {
|
fn add_pus_tm_from_creator(&mut self, pus_tm: &PusTmCreator) -> Result<PoolAddr, PoolError> {
|
||||||
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?;
|
let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
|
||||||
let mut result = Ok(0);
|
let mut result = Ok(0);
|
||||||
let addr = pg.free_element(pus_tm.len_written(), |buf| {
|
let addr = pg.free_element(pus_tm.len_written(), |buf| {
|
||||||
result = pus_tm.write_to_bytes(buf);
|
result = pus_tm.write_to_bytes(buf);
|
||||||
@ -232,8 +234,8 @@ impl PusTmPool for SharedPacketPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CcsdsPacketPool for SharedPacketPool {
|
impl CcsdsPacketPool for SharedPacketPool {
|
||||||
fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result<StoreAddr, StoreError> {
|
fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result<PoolAddr, PoolError> {
|
||||||
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?;
|
let mut pg = self.0.write().map_err(|_| PoolError::LockError)?;
|
||||||
let addr = pg.free_element(tc_raw.len(), |buf| {
|
let addr = pg.free_element(tc_raw.len(), |buf| {
|
||||||
buf[0..tc_raw.len()].copy_from_slice(tc_raw);
|
buf[0..tc_raw.len()].copy_from_slice(tc_raw);
|
||||||
})?;
|
})?;
|
||||||
@ -246,7 +248,7 @@ pub trait PacketInPoolSender: Send {
|
|||||||
fn send_packet(
|
fn send_packet(
|
||||||
&self,
|
&self,
|
||||||
sender_id: ComponentId,
|
sender_id: ComponentId,
|
||||||
store_addr: StoreAddr,
|
store_addr: PoolAddr,
|
||||||
) -> Result<(), GenericSendError>;
|
) -> Result<(), GenericSendError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +258,9 @@ pub mod alloc_mod {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
/// Simple type modelling packet stored in the heap. This structure is intended to
|
||||||
|
/// be used when sending a packet via a message queue, so it also contains the sender ID.
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct PacketAsVec {
|
pub struct PacketAsVec {
|
||||||
pub sender_id: ComponentId,
|
pub sender_id: ComponentId,
|
||||||
pub packet: Vec<u8>,
|
pub packet: Vec<u8>,
|
||||||
@ -305,7 +309,7 @@ pub mod std_mod {
|
|||||||
#[derive(Debug, Clone, PartialEq, Eq, Error)]
|
#[derive(Debug, Clone, PartialEq, Eq, Error)]
|
||||||
pub enum StoreAndSendError {
|
pub enum StoreAndSendError {
|
||||||
#[error("Store error: {0}")]
|
#[error("Store error: {0}")]
|
||||||
Store(#[from] StoreError),
|
Store(#[from] PoolError),
|
||||||
#[error("Genreric send error: {0}")]
|
#[error("Genreric send error: {0}")]
|
||||||
Send(#[from] GenericSendError),
|
Send(#[from] GenericSendError),
|
||||||
}
|
}
|
||||||
@ -316,7 +320,7 @@ pub mod std_mod {
|
|||||||
fn send_packet(
|
fn send_packet(
|
||||||
&self,
|
&self,
|
||||||
sender_id: ComponentId,
|
sender_id: ComponentId,
|
||||||
store_addr: StoreAddr,
|
store_addr: PoolAddr,
|
||||||
) -> Result<(), GenericSendError> {
|
) -> Result<(), GenericSendError> {
|
||||||
self.send(PacketInPool::new(sender_id, store_addr))
|
self.send(PacketInPool::new(sender_id, store_addr))
|
||||||
.map_err(|_| GenericSendError::RxDisconnected)
|
.map_err(|_| GenericSendError::RxDisconnected)
|
||||||
@ -327,7 +331,7 @@ pub mod std_mod {
|
|||||||
fn send_packet(
|
fn send_packet(
|
||||||
&self,
|
&self,
|
||||||
sender_id: ComponentId,
|
sender_id: ComponentId,
|
||||||
store_addr: StoreAddr,
|
store_addr: PoolAddr,
|
||||||
) -> Result<(), GenericSendError> {
|
) -> Result<(), GenericSendError> {
|
||||||
self.try_send(PacketInPool::new(sender_id, store_addr))
|
self.try_send(PacketInPool::new(sender_id, store_addr))
|
||||||
.map_err(|e| match e {
|
.map_err(|e| match e {
|
||||||
@ -342,7 +346,7 @@ pub mod std_mod {
|
|||||||
fn send_packet(
|
fn send_packet(
|
||||||
&self,
|
&self,
|
||||||
sender_id: ComponentId,
|
sender_id: ComponentId,
|
||||||
store_addr: StoreAddr,
|
store_addr: PoolAddr,
|
||||||
) -> Result<(), GenericSendError> {
|
) -> Result<(), GenericSendError> {
|
||||||
self.try_send(PacketInPool::new(sender_id, store_addr))
|
self.try_send(PacketInPool::new(sender_id, store_addr))
|
||||||
.map_err(|e| match e {
|
.map_err(|e| match e {
|
||||||
@ -455,7 +459,7 @@ pub mod std_mod {
|
|||||||
sender_id: crate::ComponentId,
|
sender_id: crate::ComponentId,
|
||||||
tm: crate::pus::PusTmVariant,
|
tm: crate::pus::PusTmVariant,
|
||||||
) -> Result<(), crate::pus::EcssTmtcError> {
|
) -> Result<(), crate::pus::EcssTmtcError> {
|
||||||
let send_addr = |store_addr: StoreAddr| {
|
let send_addr = |store_addr: PoolAddr| {
|
||||||
self.sender
|
self.sender
|
||||||
.send_packet(sender_id, store_addr)
|
.send_packet(sender_id, store_addr)
|
||||||
.map_err(EcssTmtcError::Send)
|
.map_err(EcssTmtcError::Send)
|
||||||
@ -632,7 +636,7 @@ pub(crate) mod tests {
|
|||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
matches!(
|
matches!(
|
||||||
result.unwrap_err(),
|
result.unwrap_err(),
|
||||||
StoreAndSendError::Store(StoreError::StoreFull(..))
|
StoreAndSendError::Store(PoolError::StoreFull(..))
|
||||||
);
|
);
|
||||||
let packet_in_pool = tc_rx.try_recv().unwrap();
|
let packet_in_pool = tc_rx.try_recv().unwrap();
|
||||||
let mut pool = shared_pool.0.write().unwrap();
|
let mut pool = shared_pool.0.write().unwrap();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use satrs::pool::{PoolGuard, PoolProvider, StaticMemoryPool, StaticPoolConfig, StoreAddr};
|
use satrs::pool::{PoolAddr, PoolGuard, PoolProvider, StaticMemoryPool, StaticPoolConfig};
|
||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::mpsc::{Receiver, Sender};
|
use std::sync::mpsc::{Receiver, Sender};
|
||||||
@ -12,7 +12,7 @@ fn threaded_usage() {
|
|||||||
let pool_cfg = StaticPoolConfig::new(vec![(16, 6), (32, 3), (8, 12)], false);
|
let pool_cfg = StaticPoolConfig::new(vec![(16, 6), (32, 3), (8, 12)], false);
|
||||||
let shared_pool = Arc::new(RwLock::new(StaticMemoryPool::new(pool_cfg)));
|
let shared_pool = Arc::new(RwLock::new(StaticMemoryPool::new(pool_cfg)));
|
||||||
let shared_clone = shared_pool.clone();
|
let shared_clone = shared_pool.clone();
|
||||||
let (tx, rx): (Sender<StoreAddr>, Receiver<StoreAddr>) = mpsc::channel();
|
let (tx, rx): (Sender<PoolAddr>, Receiver<PoolAddr>) = mpsc::channel();
|
||||||
let jh0 = thread::spawn(move || {
|
let jh0 = thread::spawn(move || {
|
||||||
let mut dummy = shared_pool.write().unwrap();
|
let mut dummy = shared_pool.write().unwrap();
|
||||||
let addr = dummy.add(&DUMMY_DATA).expect("Writing data failed");
|
let addr = dummy.add(&DUMMY_DATA).expect("Writing data failed");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user