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, 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, ) -> 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, request_converter: RequestConverter, request_router: RequestRouter, routing_error_handler: RoutingErrorHandler, } impl< TcInMemConverter: EcssTcInMemConverter, RequestConverter: PusActionToRequestConverter, RequestRouter: PusActionRequestRouter, RoutingErrorHandler: PusRoutingErrorHandler, > PusService8ActionHandler< TcInMemConverter, RequestConverter, RequestRouter, RoutingErrorHandler, > { pub fn new( service_helper: PusServiceHelper, 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 { 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) } } }