continue the pain

This commit is contained in:
Robin Müller 2024-02-27 14:33:14 +01:00
parent f5acdaeffc
commit 656229a542
5 changed files with 128 additions and 56 deletions

View File

@ -1,8 +1,4 @@
use crate::{
params::{Params, ParamsHeapless},
pool::StoreAddr,
TargetId,
};
use crate::{params::Params, pool::StoreAddr, TargetId};
pub type ActionId = u32;

View File

@ -1,10 +1,14 @@
use crate::{
action::{ActionId, ActionReply, ActionRequest},
action::{ActionId, ActionRequest},
params::Params,
TargetId,
};
use super::verification::{TcStateAccepted, VerificationToken};
use satrs_shared::res_code::ResultU16;
use spacepackets::ecss::EcssEnumU16;
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
pub use std_mod::*;
@ -13,6 +17,24 @@ pub use std_mod::*;
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
pub use alloc_mod::*;
/// A reply to an action request, but tailored to the PUS standard verification process.
#[non_exhaustive]
#[derive(Clone, Debug)]
pub enum ActionReplyPus {
CompletionFailed {
id: ActionId,
error_code: ResultU16,
params: Params,
},
StepFailed {
id: ActionId,
error_code: ResultU16,
step: EcssEnumU16,
params: Params,
},
Completed(ActionId),
}
/// This trait is an abstraction for the routing of PUS service 8 action requests to a dedicated
/// recipient using the generic [TargetId].
pub trait PusActionRequestRouter {
@ -65,15 +87,19 @@ pub mod alloc_mod {
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
pub mod std_mod {
use hashbrown::HashMap;
use spacepackets::ByteConversionError;
use crate::{
params::WritableToBeBytes,
pus::{
get_current_cds_short_timestamp,
verification::{FailParams, TcStateStarted, VerificationReportingProvider},
EcssTcInMemConverter, EcssTcReceiverCore, EcssTmSenderCore, GenericRoutingError,
PusPacketHandlerResult, PusPacketHandlingError, PusRoutingErrorHandler,
PusServiceHelper,
verification::{
FailParams, FailParamsWithStep, RequestId, TcStateStarted,
VerificationReportingProvider,
},
EcssTcInMemConverter, EcssTcReceiverCore, EcssTmSenderCore, EcssTmtcError,
GenericRoutingError, PusPacketHandlerResult, PusPacketHandlingError,
PusRoutingErrorHandler, PusServiceHelper,
},
};
@ -185,8 +211,15 @@ pub mod std_mod {
Ok(PusPacketHandlerResult::RequestHandled)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ActiveRequest {
action_id: ActionId,
target_id: TargetId,
}
pub struct PusService8ReplyHandler<VerificationReporter: VerificationReportingProvider> {
active_requests: HashMap<TargetId, ActionId>,
active_requests: HashMap<RequestId, ActiveRequest>,
verification_reporter: VerificationReporter,
fail_data_buf: alloc::vec::Vec<u8>,
}
@ -194,29 +227,68 @@ pub mod std_mod {
impl<VerificationReporter: VerificationReportingProvider>
PusService8ReplyHandler<VerificationReporter>
{
pub fn add_routed_request(&mut self, target_id: TargetId, action_id: ActionId) {
self.active_requests.insert(target_id, action_id);
pub fn add_routed_request(
&mut self,
request_id: RequestId,
target_id: TargetId,
action_id: ActionId,
) {
self.active_requests.insert(
request_id,
ActiveRequest {
target_id,
action_id,
},
);
}
pub fn handle_action_reply(
&mut self,
reply: ActionReply,
reply: ActionReplyPus,
token: VerificationToken<TcStateStarted>,
time_stamp: &[u8],
) {
) -> Result<(), EcssTmtcError> {
match reply {
ActionReply::CompletionFailed { id, reason } => {
reason.write_to_be_bytes(self.fail_data_buf.as_mut_slice());
self.verification_reporter.completion_failure(
token,
FailParams::new(time_stamp, failure_code, failure_data),
);
ActionReplyPus::CompletionFailed {
id: _,
error_code,
params,
} => {
params.write_to_be_bytes(&mut self.fail_data_buf)?;
self.verification_reporter
.completion_failure(
token,
FailParams::new(time_stamp, &error_code, &self.fail_data_buf),
)
.map_err(|e| e.0)?;
}
ActionReplyPus::StepFailed {
id: _,
error_code,
step,
params,
} => {
params.write_to_be_bytes(&mut self.fail_data_buf)?;
self.verification_reporter
.step_failure(
token,
FailParamsWithStep::new(
time_stamp,
&step,
&error_code,
&self.fail_data_buf,
),
)
.expect("step failure");
}
ActionReplyPus::Completed(id) => {
self.active_requests.remove(&id);
self.verification_reporter
.completion_success(token, time_stamp)
.expect("completion success");
}
ActionReply::StepFailed { id, step, reason } => {}
ActionReply::Completed(id) => {}
ActionReply::CompletedStringId(id) => {}
ActionReply::CompletionFailedStringId { id, reason } => {}
ActionReply::StepFailedStringId { id, step, reason } => {}
}
Ok(())
}
}
}

View File

@ -4,7 +4,7 @@
//! The satrs-example application contains various usage examples of these components.
use crate::pool::{StoreAddr, StoreError};
use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken};
use crate::queue::{GenericRecvError, GenericSendError};
use crate::queue::{GenericReceiveError, GenericSendError};
use crate::ChannelId;
use core::fmt::{Display, Formatter};
#[cfg(feature = "alloc")]
@ -59,26 +59,26 @@ impl<'tm> From<PusTmCreator<'tm>> for PusTmWrapper<'tm> {
#[derive(Debug, Clone)]
pub enum EcssTmtcError {
StoreLock,
Store(StoreError),
ByteConversion(ByteConversionError),
Pus(PusError),
CantSendAddr(StoreAddr),
CantSendDirectTm,
Send(GenericSendError),
Recv(GenericRecvError),
Receive(GenericReceiveError),
}
impl Display for EcssTmtcError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
EcssTmtcError::StoreLock => {
write!(f, "store lock error")
}
EcssTmtcError::Store(store) => {
write!(f, "store error: {store}")
write!(f, "ecss tmtc error: {store}")
}
EcssTmtcError::Pus(pus_e) => {
write!(f, "PUS error: {pus_e}")
EcssTmtcError::ByteConversion(e) => {
write!(f, "ecss tmtc error: {e}")
}
EcssTmtcError::Pus(e) => {
write!(f, "ecss tmtc error: {e}")
}
EcssTmtcError::CantSendAddr(addr) => {
write!(f, "can not send address {addr}")
@ -86,11 +86,11 @@ impl Display for EcssTmtcError {
EcssTmtcError::CantSendDirectTm => {
write!(f, "can not send TM directly")
}
EcssTmtcError::Send(send_e) => {
write!(f, "send error {send_e}")
EcssTmtcError::Send(e) => {
write!(f, "ecss tmtc error: {e}")
}
EcssTmtcError::Recv(recv_e) => {
write!(f, "recv error {recv_e}")
EcssTmtcError::Receive(e) => {
write!(f, "ecss tmtc error {e}")
}
}
}
@ -114,9 +114,9 @@ impl From<GenericSendError> for EcssTmtcError {
}
}
impl From<GenericRecvError> for EcssTmtcError {
fn from(value: GenericRecvError) -> Self {
Self::Recv(value)
impl From<GenericReceiveError> for EcssTmtcError {
fn from(value: GenericReceiveError) -> Self {
Self::Receive(value)
}
}
@ -125,9 +125,10 @@ impl Error for EcssTmtcError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
EcssTmtcError::Store(e) => Some(e),
EcssTmtcError::ByteConversion(e) => Some(e),
EcssTmtcError::Pus(e) => Some(e),
EcssTmtcError::Send(e) => Some(e),
EcssTmtcError::Recv(e) => Some(e),
EcssTmtcError::Receive(e) => Some(e),
_ => None,
}
}
@ -368,11 +369,13 @@ mod alloc_mod {
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
pub mod std_mod {
use crate::pool::{PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool, StoreAddr};
use crate::pool::{
PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool, StoreAddr, StoreError,
};
use crate::pus::verification::{TcStateAccepted, VerificationToken};
use crate::pus::{
EcssChannel, EcssTcAndToken, EcssTcReceiverCore, EcssTmSenderCore, EcssTmtcError,
GenericRecvError, GenericSendError, PusTmWrapper, TryRecvTmtcError,
GenericReceiveError, GenericSendError, PusTmWrapper, TryRecvTmtcError,
};
use crate::tmtc::tm_helper::SharedTmPool;
use crate::{ChannelId, TargetId};
@ -564,7 +567,7 @@ pub mod std_mod {
self.receiver.try_recv().map_err(|e| match e {
TryRecvError::Empty => TryRecvTmtcError::Empty,
TryRecvError::Disconnected => {
TryRecvTmtcError::Tmtc(EcssTmtcError::from(GenericRecvError::TxDisconnected))
TryRecvTmtcError::Tmtc(EcssTmtcError::from(GenericReceiveError::TxDisconnected))
}
})
}
@ -659,7 +662,7 @@ pub mod std_mod {
self.receiver.try_recv().map_err(|e| match e {
cb::TryRecvError::Empty => TryRecvTmtcError::Empty,
cb::TryRecvError::Disconnected => TryRecvTmtcError::Tmtc(EcssTmtcError::from(
GenericRecvError::TxDisconnected,
GenericReceiveError::TxDisconnected,
)),
})
}
@ -805,10 +808,9 @@ pub mod std_mod {
pub fn copy_tc_to_buf(&mut self, addr: StoreAddr) -> Result<(), PusPacketHandlingError> {
// Keep locked section as short as possible.
let mut tc_pool = self
.shared_tc_store
.write()
.map_err(|_| PusPacketHandlingError::EcssTmtc(EcssTmtcError::StoreLock))?;
let mut tc_pool = self.shared_tc_store.write().map_err(|_| {
PusPacketHandlingError::EcssTmtc(EcssTmtcError::Store(StoreError::LockError))
})?;
let tc_size = tc_pool
.len_of_data(&addr)
.map_err(|e| PusPacketHandlingError::EcssTmtc(EcssTmtcError::Store(e)))?;

View File

@ -29,12 +29,12 @@ impl Error for GenericSendError {}
/// Generic error type for sending something via a message queue.
#[derive(Debug, Copy, Clone)]
pub enum GenericRecvError {
pub enum GenericReceiveError {
Empty,
TxDisconnected,
}
impl Display for GenericRecvError {
impl Display for GenericReceiveError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
Self::TxDisconnected => {
@ -48,7 +48,7 @@ impl Display for GenericRecvError {
}
#[cfg(feature = "std")]
impl Error for GenericRecvError {}
impl Error for GenericReceiveError {}
#[cfg(feature = "std")]
impl<T> From<mpsc::SendError<T>> for GenericSendError {

View File

@ -8,7 +8,9 @@ pub use std_mod::*;
#[cfg(feature = "std")]
pub mod std_mod {
use crate::pool::{PoolProvider, SharedStaticMemoryPool, StaticMemoryPool, StoreAddr};
use crate::pool::{
PoolProvider, SharedStaticMemoryPool, StaticMemoryPool, StoreAddr, StoreError,
};
use crate::pus::EcssTmtcError;
use spacepackets::ecss::tm::PusTmCreator;
use spacepackets::ecss::WritablePusPacket;
@ -34,7 +36,7 @@ pub mod std_mod {
}
pub fn add_pus_tm(&self, pus_tm: &PusTmCreator) -> Result<StoreAddr, EcssTmtcError> {
let mut pg = self.0.write().map_err(|_| EcssTmtcError::StoreLock)?;
let mut pg = self.0.write().map_err(|_| StoreError::LockError)?;
let addr = pg.free_element(pus_tm.len_written(), |buf| {
pus_tm
.write_to_bytes(buf)