made request handler more generic
All checks were successful
Rust/sat-rs/pipeline/pr-main This commit looks good
All checks were successful
Rust/sat-rs/pipeline/pr-main This commit looks good
This commit is contained in:
parent
41e57a7942
commit
8bdc9686fb
@ -1,18 +1,16 @@
|
|||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
use satrs::action::{ActionRequest, ActionRequestVariant};
|
use satrs::action::{ActionRequest, ActionRequestVariant};
|
||||||
use satrs::pool::{SharedStaticMemoryPool, StoreAddr};
|
use satrs::pool::{SharedStaticMemoryPool, StoreAddr};
|
||||||
use satrs::pus::action::{PusActionToRequestConverter, PusService8ActionHandler};
|
use satrs::pus::action::PusService8ActionRequestHandler;
|
||||||
use satrs::pus::verification::std_mod::{
|
|
||||||
VerificationReporterWithSharedPoolMpscBoundedSender, VerificationReporterWithVecMpscSender,
|
|
||||||
};
|
|
||||||
use satrs::pus::verification::{
|
use satrs::pus::verification::{
|
||||||
FailParams, TcStateAccepted, VerificationReportingProvider, VerificationToken,
|
FailParams, TcStateAccepted, VerificationReporterWithSharedPoolMpscBoundedSender,
|
||||||
|
VerificationReporterWithVecMpscSender, VerificationReportingProvider, VerificationToken,
|
||||||
};
|
};
|
||||||
use satrs::pus::{
|
use satrs::pus::{
|
||||||
EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter,
|
EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter,
|
||||||
EcssTcReceiverCore, EcssTmSenderCore, MpscTcReceiver, PusPacketHandlerResult,
|
EcssTcReceiverCore, EcssTmSenderCore, MpscTcReceiver, PusPacketHandlerResult,
|
||||||
PusPacketHandlingError, PusServiceHelper, TmAsVecSenderWithId, TmAsVecSenderWithMpsc,
|
PusPacketHandlingError, PusServiceHelper, PusTcToRequestConverter, TmAsVecSenderWithId,
|
||||||
TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
||||||
};
|
};
|
||||||
use satrs::request::TargetAndApidId;
|
use satrs::request::TargetAndApidId;
|
||||||
use satrs::spacepackets::ecss::tc::PusTcReader;
|
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||||
@ -29,7 +27,7 @@ use super::GenericRoutingErrorHandler;
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ExampleActionRequestConverter {}
|
pub struct ExampleActionRequestConverter {}
|
||||||
|
|
||||||
impl PusActionToRequestConverter for ExampleActionRequestConverter {
|
impl PusTcToRequestConverter<ActionRequest> for ExampleActionRequestConverter {
|
||||||
type Error = PusPacketHandlingError;
|
type Error = PusPacketHandlingError;
|
||||||
|
|
||||||
fn convert(
|
fn convert(
|
||||||
@ -99,7 +97,7 @@ pub fn create_action_service_static(
|
|||||||
"PUS_8_TC_RECV",
|
"PUS_8_TC_RECV",
|
||||||
pus_action_rx,
|
pus_action_rx,
|
||||||
);
|
);
|
||||||
let pus_8_handler = PusService8ActionHandler::new(
|
let pus_8_handler = PusService8ActionRequestHandler::new(
|
||||||
PusServiceHelper::new(
|
PusServiceHelper::new(
|
||||||
action_srv_receiver,
|
action_srv_receiver,
|
||||||
action_srv_tm_sender,
|
action_srv_tm_sender,
|
||||||
@ -135,7 +133,7 @@ pub fn create_action_service_dynamic(
|
|||||||
"PUS_8_TC_RECV",
|
"PUS_8_TC_RECV",
|
||||||
pus_action_rx,
|
pus_action_rx,
|
||||||
);
|
);
|
||||||
let pus_8_handler = PusService8ActionHandler::new(
|
let pus_8_handler = PusService8ActionRequestHandler::new(
|
||||||
PusServiceHelper::new(
|
PusServiceHelper::new(
|
||||||
action_srv_receiver,
|
action_srv_receiver,
|
||||||
action_srv_tm_sender,
|
action_srv_tm_sender,
|
||||||
@ -156,7 +154,7 @@ pub struct Pus8Wrapper<
|
|||||||
TcInMemConverter: EcssTcInMemConverter,
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
> {
|
> {
|
||||||
pub(crate) pus_8_handler: PusService8ActionHandler<
|
pub(crate) pus_8_handler: PusService8ActionRequestHandler<
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
TmSender,
|
TmSender,
|
||||||
TcInMemConverter,
|
TcInMemConverter,
|
||||||
|
@ -5,10 +5,9 @@ use derive_new::new;
|
|||||||
use satrs::action::ActionRequest;
|
use satrs::action::ActionRequest;
|
||||||
use satrs::hk::HkRequest;
|
use satrs::hk::HkRequest;
|
||||||
use satrs::mode::ModeRequest;
|
use satrs::mode::ModeRequest;
|
||||||
use satrs::pus::action::PusActionRequestRouter;
|
|
||||||
use satrs::pus::hk::PusHkRequestRouter;
|
use satrs::pus::hk::PusHkRequestRouter;
|
||||||
use satrs::pus::verification::{TcStateAccepted, VerificationToken};
|
use satrs::pus::verification::{TcStateAccepted, VerificationToken};
|
||||||
use satrs::pus::GenericRoutingError;
|
use satrs::pus::{GenericRoutingError, PusRequestRouter};
|
||||||
use satrs::queue::GenericSendError;
|
use satrs::queue::GenericSendError;
|
||||||
use satrs::TargetId;
|
use satrs::TargetId;
|
||||||
|
|
||||||
@ -71,7 +70,7 @@ impl PusHkRequestRouter for GenericRequestRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PusActionRequestRouter for GenericRequestRouter {
|
impl PusRequestRouter<ActionRequest> for GenericRequestRouter {
|
||||||
type Error = GenericRoutingError;
|
type Error = GenericRoutingError;
|
||||||
|
|
||||||
fn route(
|
fn route(
|
||||||
|
@ -5,10 +5,7 @@ use crate::{
|
|||||||
TargetId,
|
TargetId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{verification::VerificationToken, ActiveRequest, ActiveRequestProvider};
|
||||||
verification::{TcStateAccepted, VerificationToken},
|
|
||||||
ActiveRequest, ActiveRequestProvider,
|
|
||||||
};
|
|
||||||
|
|
||||||
use delegate::delegate;
|
use delegate::delegate;
|
||||||
use satrs_shared::res_code::ResultU16;
|
use satrs_shared::res_code::ResultU16;
|
||||||
@ -20,6 +17,7 @@ pub use std_mod::*;
|
|||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||||
|
#[allow(unused_imports)]
|
||||||
pub use alloc_mod::*;
|
pub use alloc_mod::*;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -54,18 +52,6 @@ pub enum ActionReplyPus {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 {
|
|
||||||
type Error;
|
|
||||||
fn route(
|
|
||||||
&self,
|
|
||||||
target_id: TargetId,
|
|
||||||
hk_request: ActionRequest,
|
|
||||||
token: VerificationToken<TcStateAccepted>,
|
|
||||||
) -> Result<(), Self::Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ActiveActionRequest {
|
pub struct ActiveActionRequest {
|
||||||
pub action_id: ActionId,
|
pub action_id: ActionId,
|
||||||
@ -85,39 +71,7 @@ impl ActiveRequestProvider for ActiveActionRequest {
|
|||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||||
pub mod alloc_mod {
|
pub mod alloc_mod {}
|
||||||
use spacepackets::ecss::tc::PusTcReader;
|
|
||||||
|
|
||||||
use crate::pus::verification::VerificationReportingProvider;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
/// This trait is an abstraction for the conversion of a PUS service 8 action telecommand into
|
|
||||||
/// an [ActionRequest].
|
|
||||||
///
|
|
||||||
/// Having a dedicated trait for this allows maximum flexiblity and tailoring of the standard.
|
|
||||||
/// The only requirement is that a valid [TargetId] and an [ActionRequest] are returned by the
|
|
||||||
/// core conversion function.
|
|
||||||
///
|
|
||||||
/// The user should take care of performing the error handling as well. Some of the following
|
|
||||||
/// aspects might be relevant:
|
|
||||||
///
|
|
||||||
/// - Checking the validity of the APID, service ID, subservice ID.
|
|
||||||
/// - Checking the validity of the user data.
|
|
||||||
///
|
|
||||||
/// A [VerificationReportingProvider] instance is passed to the user to also allow handling
|
|
||||||
/// of the verification process as part of the PUS standard requirements.
|
|
||||||
pub trait PusActionToRequestConverter {
|
|
||||||
type Error;
|
|
||||||
fn convert(
|
|
||||||
&mut self,
|
|
||||||
token: VerificationToken<TcStateAccepted>,
|
|
||||||
tc: &PusTcReader,
|
|
||||||
time_stamp: &[u8],
|
|
||||||
verif_reporter: &impl VerificationReportingProvider,
|
|
||||||
) -> Result<(TargetId, ActionRequest), Self::Error>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||||
@ -125,14 +79,12 @@ pub mod std_mod {
|
|||||||
use crate::{
|
use crate::{
|
||||||
params::WritableToBeBytes,
|
params::WritableToBeBytes,
|
||||||
pus::{
|
pus::{
|
||||||
get_current_cds_short_timestamp,
|
|
||||||
verification::{
|
verification::{
|
||||||
self, FailParams, FailParamsWithStep, TcStateStarted, VerificationReportingProvider,
|
self, FailParams, FailParamsWithStep, TcStateStarted, VerificationReportingProvider,
|
||||||
},
|
},
|
||||||
ActiveRequestMapProvider, DefaultActiveRequestMap, EcssTcInMemConverter,
|
ActiveRequestMapProvider, DefaultActiveRequestMap, EcssTmSenderCore, EcssTmtcError,
|
||||||
EcssTcReceiverCore, EcssTmSenderCore, EcssTmtcError, GenericRoutingError,
|
GenericRoutingError, PusServiceReplyHandler, PusTargetedRequestHandler,
|
||||||
PusPacketHandlerResult, PusPacketHandlingError, PusRoutingErrorHandler,
|
ReplyHandlerHook,
|
||||||
PusServiceHelper, PusServiceReplyHandler, ReplyHandlerHook,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
@ -141,45 +93,7 @@ pub mod std_mod {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// This is a high-level handler for the PUS service 8 action service.
|
pub type PusService8ActionRequestHandler<
|
||||||
///
|
|
||||||
/// It performs the following handling steps:
|
|
||||||
///
|
|
||||||
/// 1. Retrieve the next TC packet from the [PusServiceHelper]. The [EcssTcInMemConverter]
|
|
||||||
/// allows to configure the used telecommand memory backend.
|
|
||||||
/// 2. Convert the TC to a targeted action request using the provided
|
|
||||||
/// [PusActionToRequestConverter]. The generic error type is constrained to the
|
|
||||||
/// [PusPacketHandlingError] for the concrete implementation which offers a packet handler.
|
|
||||||
/// 3. Route the action request using the provided [PusActionRequestRouter].
|
|
||||||
/// 4. Handle all routing errors using the provided [PusRoutingErrorHandler].
|
|
||||||
pub struct PusService8ActionHandler<
|
|
||||||
TcReceiver: EcssTcReceiverCore,
|
|
||||||
TmSender: EcssTmSenderCore,
|
|
||||||
TcInMemConverter: EcssTcInMemConverter,
|
|
||||||
VerificationReporter: VerificationReportingProvider,
|
|
||||||
RequestConverter: PusActionToRequestConverter,
|
|
||||||
RequestRouter: PusActionRequestRouter<Error = RoutingError>,
|
|
||||||
RoutingErrorHandler: PusRoutingErrorHandler<Error = RoutingError>,
|
|
||||||
RoutingError = GenericRoutingError,
|
|
||||||
> {
|
|
||||||
service_helper:
|
|
||||||
PusServiceHelper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
|
||||||
pub request_converter: RequestConverter,
|
|
||||||
pub request_router: RequestRouter,
|
|
||||||
pub routing_error_handler: RoutingErrorHandler,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
TcReceiver: EcssTcReceiverCore,
|
|
||||||
TmSender: EcssTmSenderCore,
|
|
||||||
TcInMemConverter: EcssTcInMemConverter,
|
|
||||||
VerificationReporter: VerificationReportingProvider,
|
|
||||||
RequestConverter: PusActionToRequestConverter<Error = PusPacketHandlingError>,
|
|
||||||
RequestRouter: PusActionRequestRouter<Error = RoutingError>,
|
|
||||||
RoutingErrorHandler: PusRoutingErrorHandler<Error = RoutingError>,
|
|
||||||
RoutingError: Clone,
|
|
||||||
>
|
|
||||||
PusService8ActionHandler<
|
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
TmSender,
|
TmSender,
|
||||||
TcInMemConverter,
|
TcInMemConverter,
|
||||||
@ -187,77 +101,30 @@ pub mod std_mod {
|
|||||||
RequestConverter,
|
RequestConverter,
|
||||||
RequestRouter,
|
RequestRouter,
|
||||||
RoutingErrorHandler,
|
RoutingErrorHandler,
|
||||||
RoutingError,
|
RoutingError = GenericRoutingError,
|
||||||
>
|
> = PusTargetedRequestHandler<
|
||||||
where
|
|
||||||
PusPacketHandlingError: From<RoutingError>,
|
|
||||||
{
|
|
||||||
pub fn new(
|
|
||||||
service_helper: PusServiceHelper<
|
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
TmSender,
|
TmSender,
|
||||||
TcInMemConverter,
|
TcInMemConverter,
|
||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
>,
|
RequestConverter,
|
||||||
request_converter: RequestConverter,
|
RequestRouter,
|
||||||
request_router: RequestRouter,
|
RoutingErrorHandler,
|
||||||
routing_error_handler: RoutingErrorHandler,
|
ActionRequest,
|
||||||
) -> Self {
|
RoutingError,
|
||||||
Self {
|
>;
|
||||||
service_helper,
|
|
||||||
request_converter,
|
|
||||||
request_router,
|
|
||||||
routing_error_handler,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Core function to poll the next TC packet and try to handle it.
|
|
||||||
pub fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
|
||||||
let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?;
|
|
||||||
if possible_packet.is_none() {
|
|
||||||
return Ok(PusPacketHandlerResult::Empty);
|
|
||||||
}
|
|
||||||
let ecss_tc_and_token = possible_packet.unwrap();
|
|
||||||
let tc = self
|
|
||||||
.service_helper
|
|
||||||
.tc_in_mem_converter
|
|
||||||
.convert_ecss_tc_in_memory_to_reader(&ecss_tc_and_token.tc_in_memory)?;
|
|
||||||
let mut partial_error = None;
|
|
||||||
let time_stamp = get_current_cds_short_timestamp(&mut partial_error);
|
|
||||||
let (target_id, action_request) = self.request_converter.convert(
|
|
||||||
ecss_tc_and_token.token,
|
|
||||||
&tc,
|
|
||||||
&time_stamp,
|
|
||||||
&self.service_helper.common.verification_handler,
|
|
||||||
)?;
|
|
||||||
if let Err(e) =
|
|
||||||
self.request_router
|
|
||||||
.route(target_id, action_request, ecss_tc_and_token.token)
|
|
||||||
{
|
|
||||||
self.routing_error_handler.handle_error(
|
|
||||||
target_id,
|
|
||||||
ecss_tc_and_token.token,
|
|
||||||
&tc,
|
|
||||||
e.clone(),
|
|
||||||
&time_stamp,
|
|
||||||
&self.service_helper.common.verification_handler,
|
|
||||||
);
|
|
||||||
return Err(e.into());
|
|
||||||
}
|
|
||||||
Ok(PusPacketHandlerResult::RequestHandled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type DefaultActiveActionRequestMap = DefaultActiveRequestMap<ActiveActionRequest>;
|
pub type DefaultActiveActionRequestMap = DefaultActiveRequestMap<ActiveActionRequest>;
|
||||||
|
|
||||||
/// Type definition for a PUS 8 action service reply handler which constrains the
|
/// Type definition for a PUS 8 action service reply handler which constrains the
|
||||||
/// [PusServiceReplyHandler] active request and reply generics to the [ActiveActionRequest] and
|
/// [PusServiceReplyHandler] active request and reply generics to the [ActiveActionRequest] and
|
||||||
/// [ActionReplyPusWithIds] type.
|
/// [ActionReplyPusWithIds] type.
|
||||||
pub type PusService8ReplyHandler<VerificationReporter, ActiveRequestMap, UserHook> =
|
pub type PusService8ReplyHandler<VerificationReporter, ActiveRequestMap, UserHook, TmSender> =
|
||||||
PusServiceReplyHandler<
|
PusServiceReplyHandler<
|
||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
ActiveRequestMap,
|
ActiveRequestMap,
|
||||||
UserHook,
|
UserHook,
|
||||||
|
TmSender,
|
||||||
ActiveActionRequest,
|
ActiveActionRequest,
|
||||||
ActionReplyPusWithIds,
|
ActionReplyPusWithIds,
|
||||||
>;
|
>;
|
||||||
@ -266,7 +133,8 @@ pub mod std_mod {
|
|||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveActionRequest>,
|
ActiveRequestMap: ActiveRequestMapProvider<ActiveActionRequest>,
|
||||||
UserHook: ReplyHandlerHook<ActiveActionRequest, ActionReplyPusWithIds>,
|
UserHook: ReplyHandlerHook<ActiveActionRequest, ActionReplyPusWithIds>,
|
||||||
> PusService8ReplyHandler<VerificationReporter, ActiveRequestMap, UserHook>
|
TmSender: EcssTmSenderCore,
|
||||||
|
> PusService8ReplyHandler<VerificationReporter, ActiveRequestMap, UserHook, TmSender>
|
||||||
{
|
{
|
||||||
/// Helper method to register a recently routed action request.
|
/// Helper method to register a recently routed action request.
|
||||||
pub fn add_routed_action_request(
|
pub fn add_routed_action_request(
|
||||||
@ -366,7 +234,14 @@ pub mod std_mod {
|
|||||||
impl<
|
impl<
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
UserHook: ReplyHandlerHook<ActiveActionRequest, ActionReplyPusWithIds>,
|
UserHook: ReplyHandlerHook<ActiveActionRequest, ActionReplyPusWithIds>,
|
||||||
> PusService8ReplyHandler<VerificationReporter, DefaultActiveActionRequestMap, UserHook>
|
TmSender: EcssTmSenderCore,
|
||||||
|
>
|
||||||
|
PusService8ReplyHandler<
|
||||||
|
VerificationReporter,
|
||||||
|
DefaultActiveActionRequestMap,
|
||||||
|
UserHook,
|
||||||
|
TmSender,
|
||||||
|
>
|
||||||
{
|
{
|
||||||
/// Create a new PUS Service 8 reply handler with the [ActiveRequestMap] generic
|
/// Create a new PUS Service 8 reply handler with the [ActiveRequestMap] generic
|
||||||
/// constrained to the [DefaultActiveActionRequestMap] object and with the current time
|
/// constrained to the [DefaultActiveActionRequestMap] object and with the current time
|
||||||
@ -377,12 +252,14 @@ pub mod std_mod {
|
|||||||
verification_reporter: VerificationReporter,
|
verification_reporter: VerificationReporter,
|
||||||
fail_data_buf_size: usize,
|
fail_data_buf_size: usize,
|
||||||
user_hook: UserHook,
|
user_hook: UserHook,
|
||||||
|
tm_sender: TmSender,
|
||||||
) -> Result<Self, SystemTimeError> {
|
) -> Result<Self, SystemTimeError> {
|
||||||
let current_time = UnixTimestamp::from_now()?;
|
let current_time = UnixTimestamp::from_now()?;
|
||||||
Ok(Self::new_with_default_map(
|
Ok(Self::new_with_default_map(
|
||||||
verification_reporter,
|
verification_reporter,
|
||||||
fail_data_buf_size,
|
fail_data_buf_size,
|
||||||
user_hook,
|
user_hook,
|
||||||
|
tm_sender,
|
||||||
current_time,
|
current_time,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -393,6 +270,7 @@ pub mod std_mod {
|
|||||||
verification_reporter: VerificationReporter,
|
verification_reporter: VerificationReporter,
|
||||||
fail_data_buf_size: usize,
|
fail_data_buf_size: usize,
|
||||||
user_hook: UserHook,
|
user_hook: UserHook,
|
||||||
|
tm_sender: TmSender,
|
||||||
init_time: UnixTimestamp,
|
init_time: UnixTimestamp,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
@ -400,6 +278,7 @@ pub mod std_mod {
|
|||||||
DefaultActiveActionRequestMap::default(),
|
DefaultActiveActionRequestMap::default(),
|
||||||
fail_data_buf_size,
|
fail_data_buf_size,
|
||||||
user_hook,
|
user_hook,
|
||||||
|
tm_sender,
|
||||||
init_time,
|
init_time,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -409,9 +288,9 @@ pub mod std_mod {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{cell::RefCell, time::Duration};
|
use core::{cell::RefCell, time::Duration};
|
||||||
use std::time::SystemTimeError;
|
use std::{sync::mpsc, time::SystemTimeError};
|
||||||
|
|
||||||
use alloc::collections::VecDeque;
|
use alloc::{collections::VecDeque, vec::Vec};
|
||||||
use delegate::delegate;
|
use delegate::delegate;
|
||||||
|
|
||||||
use spacepackets::{
|
use spacepackets::{
|
||||||
@ -434,33 +313,34 @@ mod tests {
|
|||||||
verification::{
|
verification::{
|
||||||
self,
|
self,
|
||||||
tests::{SharedVerificationMap, TestVerificationReporter, VerificationStatus},
|
tests::{SharedVerificationMap, TestVerificationReporter, VerificationStatus},
|
||||||
FailParams, TcStateNone, TcStateStarted, VerificationReportingProvider,
|
FailParams, TcStateAccepted, TcStateNone, TcStateStarted,
|
||||||
|
VerificationReportingProvider,
|
||||||
},
|
},
|
||||||
EcssTcInVecConverter, EcssTmtcError, GenericRoutingError, MpscTcReceiver,
|
EcssTcInVecConverter, EcssTmtcError, GenericRoutingError, MpscTcReceiver,
|
||||||
PusPacketHandlerResult, PusPacketHandlingError, ReplyHandlerHook,
|
PusPacketHandlerResult, PusPacketHandlingError, PusRequestRouter,
|
||||||
TmAsVecSenderWithMpsc,
|
PusTcToRequestConverter, ReplyHandlerHook, TmAsVecSenderWithMpsc,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl PusActionRequestRouter for TestRouter<ActionRequest> {
|
impl<Request> PusRequestRouter<Request> for TestRouter<Request> {
|
||||||
type Error = GenericRoutingError;
|
type Error = GenericRoutingError;
|
||||||
|
|
||||||
fn route(
|
fn route(
|
||||||
&self,
|
&self,
|
||||||
target_id: TargetId,
|
target_id: TargetId,
|
||||||
action_request: ActionRequest,
|
request: Request,
|
||||||
_token: VerificationToken<TcStateAccepted>,
|
_token: VerificationToken<TcStateAccepted>,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
self.routing_requests
|
self.routing_requests
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.push_back((target_id, action_request));
|
.push_back((target_id, request));
|
||||||
self.check_for_injected_error()
|
self.check_for_injected_error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PusActionToRequestConverter for TestConverter<8> {
|
impl PusTcToRequestConverter<ActionRequest> for TestConverter<8> {
|
||||||
type Error = PusPacketHandlingError;
|
type Error = PusPacketHandlingError;
|
||||||
fn convert(
|
fn convert(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -508,7 +388,7 @@ mod tests {
|
|||||||
|
|
||||||
struct Pus8RequestTestbenchWithVec {
|
struct Pus8RequestTestbenchWithVec {
|
||||||
common: PusServiceHandlerWithVecCommon<TestVerificationReporter>,
|
common: PusServiceHandlerWithVecCommon<TestVerificationReporter>,
|
||||||
handler: PusService8ActionHandler<
|
handler: PusService8ActionRequestHandler<
|
||||||
MpscTcReceiver,
|
MpscTcReceiver,
|
||||||
TmAsVecSenderWithMpsc,
|
TmAsVecSenderWithMpsc,
|
||||||
EcssTcInVecConverter,
|
EcssTcInVecConverter,
|
||||||
@ -525,7 +405,7 @@ mod tests {
|
|||||||
PusServiceHandlerWithVecCommon::new_with_test_verif_sender();
|
PusServiceHandlerWithVecCommon::new_with_test_verif_sender();
|
||||||
Self {
|
Self {
|
||||||
common,
|
common,
|
||||||
handler: PusService8ActionHandler::new(
|
handler: PusService8ActionRequestHandler::new(
|
||||||
srv_handler,
|
srv_handler,
|
||||||
TestConverter::default(),
|
TestConverter::default(),
|
||||||
TestRouter::default(),
|
TestRouter::default(),
|
||||||
@ -599,10 +479,13 @@ mod tests {
|
|||||||
|
|
||||||
pub struct Pus8ReplyTestbench {
|
pub struct Pus8ReplyTestbench {
|
||||||
verif_reporter: TestVerificationReporter,
|
verif_reporter: TestVerificationReporter,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
ecss_tm_receiver: mpsc::Receiver<Vec<u8>>,
|
||||||
handler: PusService8ReplyHandler<
|
handler: PusService8ReplyHandler<
|
||||||
TestVerificationReporter,
|
TestVerificationReporter,
|
||||||
DefaultActiveActionRequestMap,
|
DefaultActiveActionRequestMap,
|
||||||
TestReplyHandlerHook,
|
TestReplyHandlerHook,
|
||||||
|
mpsc::Sender<Vec<u8>>,
|
||||||
>,
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,11 +494,13 @@ mod tests {
|
|||||||
let reply_handler_hook = TestReplyHandlerHook::default();
|
let reply_handler_hook = TestReplyHandlerHook::default();
|
||||||
let shared_verif_map = SharedVerificationMap::default();
|
let shared_verif_map = SharedVerificationMap::default();
|
||||||
let test_verif_reporter = TestVerificationReporter::new(shared_verif_map.clone());
|
let test_verif_reporter = TestVerificationReporter::new(shared_verif_map.clone());
|
||||||
|
let (ecss_tm_sender, ecss_tm_receiver) = mpsc::channel();
|
||||||
let reply_handler = if normal_ctor {
|
let reply_handler = if normal_ctor {
|
||||||
PusService8ReplyHandler::new_from_now_with_default_map(
|
PusService8ReplyHandler::new_from_now_with_default_map(
|
||||||
test_verif_reporter.clone(),
|
test_verif_reporter.clone(),
|
||||||
128,
|
128,
|
||||||
reply_handler_hook,
|
reply_handler_hook,
|
||||||
|
ecss_tm_sender,
|
||||||
)
|
)
|
||||||
.expect("creating reply handler failed")
|
.expect("creating reply handler failed")
|
||||||
} else {
|
} else {
|
||||||
@ -624,11 +509,13 @@ mod tests {
|
|||||||
DefaultActiveActionRequestMap::default(),
|
DefaultActiveActionRequestMap::default(),
|
||||||
128,
|
128,
|
||||||
reply_handler_hook,
|
reply_handler_hook,
|
||||||
|
ecss_tm_sender,
|
||||||
)
|
)
|
||||||
.expect("creating reply handler failed")
|
.expect("creating reply handler failed")
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
verif_reporter: test_verif_reporter,
|
verif_reporter: test_verif_reporter,
|
||||||
|
ecss_tm_receiver,
|
||||||
handler: reply_handler,
|
handler: reply_handler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,6 +337,18 @@ pub trait ReplyHandlerHook<ActiveRequestType, ReplyType> {
|
|||||||
fn timeout_error_code(&self) -> ResultU16;
|
fn timeout_error_code(&self) -> ResultU16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This trait is an abstraction for the routing of PUS request to a dedicated
|
||||||
|
/// recipient using the generic [TargetId].
|
||||||
|
pub trait PusRequestRouter<Request> {
|
||||||
|
type Error;
|
||||||
|
fn route(
|
||||||
|
&self,
|
||||||
|
target_id: TargetId,
|
||||||
|
hk_request: Request,
|
||||||
|
token: VerificationToken<TcStateAccepted>,
|
||||||
|
) -> Result<(), Self::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub mod alloc_mod {
|
pub mod alloc_mod {
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
@ -427,6 +439,32 @@ pub mod alloc_mod {
|
|||||||
|
|
||||||
impl_downcast!(EcssTcReceiver);
|
impl_downcast!(EcssTcReceiver);
|
||||||
|
|
||||||
|
/// This trait is an abstraction for the conversion of a PUS telecommand into a generic request
|
||||||
|
/// type.
|
||||||
|
///
|
||||||
|
/// Having a dedicated trait for this allows maximum flexiblity and tailoring of the standard.
|
||||||
|
/// The only requirement is that a valid [TargetId] and a request instance are returned by the
|
||||||
|
/// core conversion function.
|
||||||
|
///
|
||||||
|
/// The user should take care of performing the error handling as well. Some of the following
|
||||||
|
/// aspects might be relevant:
|
||||||
|
///
|
||||||
|
/// - Checking the validity of the APID, service ID, subservice ID.
|
||||||
|
/// - Checking the validity of the user data.
|
||||||
|
///
|
||||||
|
/// A [VerificationReportingProvider] instance is passed to the user to also allow handling
|
||||||
|
/// of the verification process as part of the PUS standard requirements.
|
||||||
|
pub trait PusTcToRequestConverter<Request> {
|
||||||
|
type Error;
|
||||||
|
fn convert(
|
||||||
|
&mut self,
|
||||||
|
token: VerificationToken<TcStateAccepted>,
|
||||||
|
tc: &PusTcReader,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
verif_reporter: &impl VerificationReportingProvider,
|
||||||
|
) -> Result<(TargetId, Request), Self::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
pub trait PusRoutingErrorHandler {
|
pub trait PusRoutingErrorHandler {
|
||||||
type Error;
|
type Error;
|
||||||
fn handle_error(
|
fn handle_error(
|
||||||
@ -500,6 +538,7 @@ pub mod alloc_mod {
|
|||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestType>,
|
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestType>,
|
||||||
UserHook: ReplyHandlerHook<ActiveRequestType, ReplyType>,
|
UserHook: ReplyHandlerHook<ActiveRequestType, ReplyType>,
|
||||||
|
TmSender: EcssTmSenderCore,
|
||||||
ActiveRequestType: ActiveRequestProvider,
|
ActiveRequestType: ActiveRequestProvider,
|
||||||
ReplyType,
|
ReplyType,
|
||||||
> {
|
> {
|
||||||
@ -508,6 +547,7 @@ pub mod alloc_mod {
|
|||||||
pub fail_data_buf: alloc::vec::Vec<u8>,
|
pub fail_data_buf: alloc::vec::Vec<u8>,
|
||||||
pub current_time: UnixTimestamp,
|
pub current_time: UnixTimestamp,
|
||||||
pub user_hook: UserHook,
|
pub user_hook: UserHook,
|
||||||
|
pub tm_sender: TmSender,
|
||||||
phantom: PhantomData<(ActiveRequestType, ReplyType)>,
|
phantom: PhantomData<(ActiveRequestType, ReplyType)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,6 +555,7 @@ pub mod alloc_mod {
|
|||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestType>,
|
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestType>,
|
||||||
UserHook: ReplyHandlerHook<ActiveRequestType, ReplyType>,
|
UserHook: ReplyHandlerHook<ActiveRequestType, ReplyType>,
|
||||||
|
TmSender: EcssTmSenderCore,
|
||||||
ActiveRequestType: ActiveRequestProvider,
|
ActiveRequestType: ActiveRequestProvider,
|
||||||
ReplyType,
|
ReplyType,
|
||||||
>
|
>
|
||||||
@ -522,6 +563,7 @@ pub mod alloc_mod {
|
|||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
ActiveRequestMap,
|
ActiveRequestMap,
|
||||||
UserHook,
|
UserHook,
|
||||||
|
TmSender,
|
||||||
ActiveRequestType,
|
ActiveRequestType,
|
||||||
ReplyType,
|
ReplyType,
|
||||||
>
|
>
|
||||||
@ -533,6 +575,7 @@ pub mod alloc_mod {
|
|||||||
active_request_map: ActiveRequestMap,
|
active_request_map: ActiveRequestMap,
|
||||||
fail_data_buf_size: usize,
|
fail_data_buf_size: usize,
|
||||||
user_hook: UserHook,
|
user_hook: UserHook,
|
||||||
|
tm_sender: TmSender,
|
||||||
) -> Result<Self, std::time::SystemTimeError> {
|
) -> Result<Self, std::time::SystemTimeError> {
|
||||||
let current_time = UnixTimestamp::from_now()?;
|
let current_time = UnixTimestamp::from_now()?;
|
||||||
Ok(Self::new(
|
Ok(Self::new(
|
||||||
@ -540,6 +583,7 @@ pub mod alloc_mod {
|
|||||||
active_request_map,
|
active_request_map,
|
||||||
fail_data_buf_size,
|
fail_data_buf_size,
|
||||||
user_hook,
|
user_hook,
|
||||||
|
tm_sender,
|
||||||
current_time,
|
current_time,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -549,6 +593,7 @@ pub mod alloc_mod {
|
|||||||
active_request_map: ActiveRequestMap,
|
active_request_map: ActiveRequestMap,
|
||||||
fail_data_buf_size: usize,
|
fail_data_buf_size: usize,
|
||||||
user_hook: UserHook,
|
user_hook: UserHook,
|
||||||
|
tm_sender: TmSender,
|
||||||
init_time: UnixTimestamp,
|
init_time: UnixTimestamp,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -557,6 +602,7 @@ pub mod alloc_mod {
|
|||||||
fail_data_buf: alloc::vec![0; fail_data_buf_size],
|
fail_data_buf: alloc::vec![0; fail_data_buf_size],
|
||||||
current_time: init_time,
|
current_time: init_time,
|
||||||
user_hook,
|
user_hook,
|
||||||
|
tm_sender,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -642,6 +688,7 @@ pub mod std_mod {
|
|||||||
use crate::tmtc::tm_helper::SharedTmPool;
|
use crate::tmtc::tm_helper::SharedTmPool;
|
||||||
use crate::{ChannelId, TargetId};
|
use crate::{ChannelId, TargetId};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
use core::marker::PhantomData;
|
||||||
use spacepackets::ecss::tc::PusTcReader;
|
use spacepackets::ecss::tc::PusTcReader;
|
||||||
use spacepackets::ecss::tm::PusTmCreator;
|
use spacepackets::ecss::tm::PusTmCreator;
|
||||||
use spacepackets::ecss::{PusError, WritablePusPacket};
|
use spacepackets::ecss::{PusError, WritablePusPacket};
|
||||||
@ -657,7 +704,10 @@ pub mod std_mod {
|
|||||||
pub use cb_mod::*;
|
pub use cb_mod::*;
|
||||||
|
|
||||||
use super::verification::VerificationReportingProvider;
|
use super::verification::VerificationReportingProvider;
|
||||||
use super::{AcceptedEcssTcAndToken, TcInMemory};
|
use super::{
|
||||||
|
AcceptedEcssTcAndToken, PusRequestRouter, PusRoutingErrorHandler, PusTcToRequestConverter,
|
||||||
|
TcInMemory,
|
||||||
|
};
|
||||||
|
|
||||||
impl From<mpsc::SendError<StoreAddr>> for EcssTmtcError {
|
impl From<mpsc::SendError<StoreAddr>> for EcssTmtcError {
|
||||||
fn from(_: mpsc::SendError<StoreAddr>) -> Self {
|
fn from(_: mpsc::SendError<StoreAddr>) -> Self {
|
||||||
@ -931,6 +981,118 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This is a high-level handler for the PUS service 8 action service.
|
||||||
|
///
|
||||||
|
/// It performs the following handling steps:
|
||||||
|
///
|
||||||
|
/// 1. Retrieve the next TC packet from the [PusServiceHelper]. The [EcssTcInMemConverter]
|
||||||
|
/// allows to configure the used telecommand memory backend.
|
||||||
|
/// 2. Convert the TC to a targeted action request using the provided
|
||||||
|
/// [PusActionToRequestConverter]. The generic error type is constrained to the
|
||||||
|
/// [PusPacketHandlingError] for the concrete implementation which offers a packet handler.
|
||||||
|
/// 3. Route the action request using the provided [PusActionRequestRouter].
|
||||||
|
/// 4. Handle all routing errors using the provided [PusRoutingErrorHandler].
|
||||||
|
pub struct PusTargetedRequestHandler<
|
||||||
|
TcReceiver: EcssTcReceiverCore,
|
||||||
|
TmSender: EcssTmSenderCore,
|
||||||
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
|
VerificationReporter: VerificationReportingProvider,
|
||||||
|
RequestConverter: PusTcToRequestConverter<Request>,
|
||||||
|
RequestRouter: PusRequestRouter<Request, Error = RoutingError>,
|
||||||
|
RoutingErrorHandler: PusRoutingErrorHandler<Error = RoutingError>,
|
||||||
|
Request,
|
||||||
|
RoutingError = GenericRoutingError,
|
||||||
|
> {
|
||||||
|
service_helper:
|
||||||
|
PusServiceHelper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
||||||
|
pub request_converter: RequestConverter,
|
||||||
|
pub request_router: RequestRouter,
|
||||||
|
pub routing_error_handler: RoutingErrorHandler,
|
||||||
|
phantom: PhantomData<Request>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
TcReceiver: EcssTcReceiverCore,
|
||||||
|
TmSender: EcssTmSenderCore,
|
||||||
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
|
VerificationReporter: VerificationReportingProvider,
|
||||||
|
RequestConverter: PusTcToRequestConverter<Request, Error = PusPacketHandlingError>,
|
||||||
|
RequestRouter: PusRequestRouter<Request, Error = RoutingError>,
|
||||||
|
RoutingErrorHandler: PusRoutingErrorHandler<Error = RoutingError>,
|
||||||
|
Request,
|
||||||
|
RoutingError: Clone,
|
||||||
|
>
|
||||||
|
PusTargetedRequestHandler<
|
||||||
|
TcReceiver,
|
||||||
|
TmSender,
|
||||||
|
TcInMemConverter,
|
||||||
|
VerificationReporter,
|
||||||
|
RequestConverter,
|
||||||
|
RequestRouter,
|
||||||
|
RoutingErrorHandler,
|
||||||
|
Request,
|
||||||
|
RoutingError,
|
||||||
|
>
|
||||||
|
where
|
||||||
|
PusPacketHandlingError: From<RoutingError>,
|
||||||
|
{
|
||||||
|
pub fn new(
|
||||||
|
service_helper: PusServiceHelper<
|
||||||
|
TcReceiver,
|
||||||
|
TmSender,
|
||||||
|
TcInMemConverter,
|
||||||
|
VerificationReporter,
|
||||||
|
>,
|
||||||
|
request_converter: RequestConverter,
|
||||||
|
request_router: RequestRouter,
|
||||||
|
routing_error_handler: RoutingErrorHandler,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
service_helper,
|
||||||
|
request_converter,
|
||||||
|
request_router,
|
||||||
|
routing_error_handler,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Core function to poll the next TC packet and try to handle it.
|
||||||
|
pub fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
||||||
|
let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?;
|
||||||
|
if possible_packet.is_none() {
|
||||||
|
return Ok(PusPacketHandlerResult::Empty);
|
||||||
|
}
|
||||||
|
let ecss_tc_and_token = possible_packet.unwrap();
|
||||||
|
let tc = self
|
||||||
|
.service_helper
|
||||||
|
.tc_in_mem_converter
|
||||||
|
.convert_ecss_tc_in_memory_to_reader(&ecss_tc_and_token.tc_in_memory)?;
|
||||||
|
let mut partial_error = None;
|
||||||
|
let time_stamp = get_current_cds_short_timestamp(&mut partial_error);
|
||||||
|
let (target_id, action_request) = self.request_converter.convert(
|
||||||
|
ecss_tc_and_token.token,
|
||||||
|
&tc,
|
||||||
|
&time_stamp,
|
||||||
|
&self.service_helper.common.verification_handler,
|
||||||
|
)?;
|
||||||
|
if let Err(e) =
|
||||||
|
self.request_router
|
||||||
|
.route(target_id, action_request, ecss_tc_and_token.token)
|
||||||
|
{
|
||||||
|
self.routing_error_handler.handle_error(
|
||||||
|
target_id,
|
||||||
|
ecss_tc_and_token.token,
|
||||||
|
&tc,
|
||||||
|
e.clone(),
|
||||||
|
&time_stamp,
|
||||||
|
&self.service_helper.common.verification_handler,
|
||||||
|
);
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
|
Ok(PusPacketHandlerResult::RequestHandled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: All these types could probably be no_std if we implemented error handling ourselves..
|
// TODO: All these types could probably be no_std if we implemented error handling ourselves..
|
||||||
// but thiserror is really nice, so keep it like this for simplicity for now. Maybe thiserror
|
// but thiserror is really nice, so keep it like this for simplicity for now. Maybe thiserror
|
||||||
// will be no_std soon, see https://github.com/rust-lang/rust/issues/103765 .
|
// will be no_std soon, see https://github.com/rust-lang/rust/issues/103765 .
|
||||||
|
@ -2,6 +2,10 @@ use num_enum::{IntoPrimitive, TryFromPrimitive};
|
|||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{mode::ModeRequest, TargetId};
|
||||||
|
|
||||||
|
use super::verification::{TcStateAccepted, VerificationToken};
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
|
#[derive(Debug, Eq, PartialEq, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
@ -14,3 +18,51 @@ pub enum Subservice {
|
|||||||
TmCantReachMode = 7,
|
TmCantReachMode = 7,
|
||||||
TmWrongModeReply = 8,
|
TmWrongModeReply = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This trait is an abstraction for the routing of PUS service 8 action requests to a dedicated
|
||||||
|
/// recipient using the generic [TargetId].
|
||||||
|
pub trait PusModeRequestRouter {
|
||||||
|
type Error;
|
||||||
|
fn route(
|
||||||
|
&self,
|
||||||
|
target_id: TargetId,
|
||||||
|
mode_request: ModeRequest,
|
||||||
|
token: VerificationToken<TcStateAccepted>,
|
||||||
|
) -> Result<(), Self::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||||
|
pub mod alloc_mod {
|
||||||
|
use spacepackets::ecss::tc::PusTcReader;
|
||||||
|
|
||||||
|
use crate::pus::verification::VerificationReportingProvider;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// This trait is an abstraction for the conversion of a PUS mode service telecommand into
|
||||||
|
/// an [ModeRequest].
|
||||||
|
///
|
||||||
|
/// Having a dedicated trait for this allows maximum flexiblity and tailoring of the standard.
|
||||||
|
/// The only requirement is that a valid [TargetId] and an [ActionRequest] are returned by the
|
||||||
|
/// core conversion function.
|
||||||
|
///
|
||||||
|
/// The user should take care of performing the error handling as well. Some of the following
|
||||||
|
/// aspects might be relevant:
|
||||||
|
///
|
||||||
|
/// - Checking the validity of the APID, service ID, subservice ID.
|
||||||
|
/// - Checking the validity of the user data.
|
||||||
|
///
|
||||||
|
/// A [VerificationReportingProvider] instance is passed to the user to also allow handling
|
||||||
|
/// of the verification process as part of the PUS standard requirements.
|
||||||
|
pub trait PusModeToRequestConverter {
|
||||||
|
type Error;
|
||||||
|
fn convert(
|
||||||
|
&mut self,
|
||||||
|
token: VerificationToken<TcStateAccepted>,
|
||||||
|
tc: &PusTcReader,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
verif_reporter: &impl VerificationReportingProvider,
|
||||||
|
) -> Result<(TargetId, ModeRequest), Self::Error>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -48,6 +48,10 @@ struct TestDevice {
|
|||||||
pub mode_requestor_info: Option<(RequestId, ChannelId)>,
|
pub mode_requestor_info: Option<(RequestId, ChannelId)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ModeLeafDeviceHelper {
|
||||||
|
// pub
|
||||||
|
}
|
||||||
|
|
||||||
impl TestDevice {
|
impl TestDevice {
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
self.check_mode_requests().expect("mode messaging error");
|
self.check_mode_requests().expect("mode messaging error");
|
||||||
|
Loading…
Reference in New Issue
Block a user