Some checks are pending
Rust/sat-rs/pipeline/head Build started...
This is the first attempt of a generic PUS service abstraction where the PUS telecommands need to be converted into targetted requests.
116 lines
3.9 KiB
Rust
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)
|
|
}
|
|
}
|
|
}
|