sat-rs/satrs/src/pus/action.rs
Robin Mueller a5e5a1a5a0
Some checks are pending
Rust/sat-rs/pipeline/head Build started...
First PUS handler abstraction with request mapping
This is the first attempt of a generic PUS service abstraction where
the PUS telecommands need to be converted into targetted requests.
2024-02-13 18:19:45 +01:00

116 lines
3.9 KiB
Rust

use spacepackets::ecss::tc::PusTcReader;
use crate::{action::ActionRequest, TargetId};
use super::verification::{TcStateAccepted, VerificationReporterWithSender, VerificationToken};
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
pub use std_mod::*;
pub trait PusActionToRequestConverter {
type Error;
fn convert(
&mut self,
token: VerificationToken<TcStateAccepted>,
tc: &PusTcReader,
time_stamp: &[u8],
verif_reporter: &mut VerificationReporterWithSender,
) -> Result<(TargetId, ActionRequest), Self::Error>;
}
pub trait PusActionRequestRouter {
type Error;
fn route(
&self,
target_id: TargetId,
hk_request: ActionRequest,
token: VerificationToken<TcStateAccepted>,
) -> Result<(), Self::Error>;
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
pub mod std_mod {
use crate::pus::{
EcssTcInMemConverter, GenericRoutingError, PusPacketHandlerResult, PusPacketHandlingError,
PusRoutingErrorHandler, PusServiceBase, PusServiceHelper,
};
use super::*;
pub struct PusService8ActionHandler<
TcInMemConverter: EcssTcInMemConverter,
RequestConverter: PusActionToRequestConverter,
RequestRouter: PusActionRequestRouter,
RoutingErrorHandler: PusRoutingErrorHandler,
> {
service_helper: PusServiceHelper<TcInMemConverter>,
request_converter: RequestConverter,
request_router: RequestRouter,
routing_error_handler: RoutingErrorHandler,
}
impl<
TcInMemConverter: EcssTcInMemConverter,
RequestConverter: PusActionToRequestConverter<Error = PusPacketHandlingError>,
RequestRouter: PusActionRequestRouter<Error = GenericRoutingError>,
RoutingErrorHandler: PusRoutingErrorHandler<Error = GenericRoutingError>,
>
PusService8ActionHandler<
TcInMemConverter,
RequestConverter,
RequestRouter,
RoutingErrorHandler,
>
{
pub fn new(
service_helper: PusServiceHelper<TcInMemConverter>,
request_converter: RequestConverter,
request_router: RequestRouter,
routing_error_handler: RoutingErrorHandler,
) -> Self {
Self {
service_helper,
request_converter,
request_router,
routing_error_handler,
}
}
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 = PusServiceBase::get_current_timestamp(&mut partial_error);
let (target_id, action_request) = self.request_converter.convert(
ecss_tc_and_token.token,
&tc,
&time_stamp,
&mut self.service_helper.common.verification_handler.borrow_mut(),
)?;
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,
&time_stamp,
&mut self.service_helper.common.verification_handler.borrow_mut(),
);
}
Ok(PusPacketHandlerResult::RequestHandled)
}
}
}