diff --git a/satrs/src/action.rs b/satrs/src/action.rs index 7caeaa6..b35a48d 100644 --- a/satrs/src/action.rs +++ b/satrs/src/action.rs @@ -1,4 +1,8 @@ -use crate::{pool::StoreAddr, TargetId}; +use crate::{ + params::{Params, ParamsHeapless}, + pool::StoreAddr, + TargetId, +}; pub type ActionId = u32; @@ -43,21 +47,29 @@ impl TargetedActionRequest { /// A reply to an action request. #[non_exhaustive] -#[derive(Clone, Eq, PartialEq, Debug)] +#[derive(Clone, Debug)] pub enum ActionReply { - CompletionFailed(ActionId), + CompletionFailed { + id: ActionId, + reason: Params, + }, StepFailed { id: ActionId, step: u32, + reason: Params, }, Completed(ActionId), #[cfg(feature = "alloc")] CompletedStringId(alloc::string::String), #[cfg(feature = "alloc")] - CompletionFailedStringId(alloc::string::String), + CompletionFailedStringId { + id: alloc::string::String, + reason: Params, + }, #[cfg(feature = "alloc")] StepFailedStringId { id: alloc::string::String, step: u32, + reason: Params, }, } diff --git a/satrs/src/params.rs b/satrs/src/params.rs index 1279015..90d7028 100644 --- a/satrs/src/params.rs +++ b/satrs/src/params.rs @@ -618,6 +618,42 @@ impl From<&str> for Params { } } +/// Please note while [WritableToBeBytes] is implemented for [Params], the default implementation +/// will not be able to process store parameters. +impl WritableToBeBytes for Params { + fn raw_len(&self) -> usize { + match self { + Params::Heapless(p) => match p { + ParamsHeapless::Raw(raw) => raw.raw_len(), + ParamsHeapless::EcssEnum(enumeration) => enumeration.raw_len(), + }, + Params::Store(_) => 0, + Params::Vec(vec) => vec.len(), + Params::String(string) => string.len(), + } + } + + fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result { + match self { + Params::Heapless(p) => match p { + ParamsHeapless::Raw(raw) => raw.write_to_be_bytes(buf), + ParamsHeapless::EcssEnum(enumeration) => enumeration.write_to_be_bytes(buf), + }, + Params::Store(_) => Ok(0), + Params::Vec(vec) => { + // TODO: size checks. + buf[0..vec.len()].copy_from_slice(vec); + Ok(vec.len()) + } + Params::String(string) => { + // TODO: size checks + buf[0..string.len()].copy_from_slice(string.as_bytes()); + Ok(string.len()) + } + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/satrs/src/pus/action.rs b/satrs/src/pus/action.rs index 2ee4815..8d43d9c 100644 --- a/satrs/src/pus/action.rs +++ b/satrs/src/pus/action.rs @@ -1,4 +1,7 @@ -use crate::{action::ActionRequest, TargetId}; +use crate::{ + action::{ActionId, ActionReply, ActionRequest}, + TargetId, +}; use super::verification::{TcStateAccepted, VerificationToken}; @@ -61,10 +64,17 @@ pub mod alloc_mod { #[cfg(feature = "std")] #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))] pub mod std_mod { - use crate::pus::{ - get_current_cds_short_timestamp, verification::VerificationReportingProvider, - EcssTcInMemConverter, EcssTcReceiverCore, EcssTmSenderCore, GenericRoutingError, - PusPacketHandlerResult, PusPacketHandlingError, PusRoutingErrorHandler, PusServiceHelper, + use hashbrown::HashMap; + + use crate::{ + params::WritableToBeBytes, + pus::{ + get_current_cds_short_timestamp, + verification::{FailParams, TcStateStarted, VerificationReportingProvider}, + EcssTcInMemConverter, EcssTcReceiverCore, EcssTmSenderCore, GenericRoutingError, + PusPacketHandlerResult, PusPacketHandlingError, PusRoutingErrorHandler, + PusServiceHelper, + }, }; use super::*; @@ -175,6 +185,40 @@ pub mod std_mod { Ok(PusPacketHandlerResult::RequestHandled) } } + pub struct PusService8ReplyHandler { + active_requests: HashMap, + verification_reporter: VerificationReporter, + fail_data_buf: alloc::vec::Vec, + } + + impl + PusService8ReplyHandler + { + pub fn add_routed_request(&mut self, target_id: TargetId, action_id: ActionId) { + self.active_requests.insert(target_id, action_id); + } + pub fn handle_action_reply( + &mut self, + reply: ActionReply, + token: VerificationToken, + time_stamp: &[u8], + ) { + 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), + ); + } + ActionReply::StepFailed { id, step, reason } => {} + ActionReply::Completed(id) => {} + ActionReply::CompletedStringId(id) => {} + ActionReply::CompletionFailedStringId { id, reason } => {} + ActionReply::StepFailedStringId { id, step, reason } => {} + } + } + } } #[cfg(test)]