need to re-work all of this..
Some checks failed
Rust/sat-rs/pipeline/pr-main There was a failure building this commit
Some checks failed
Rust/sat-rs/pipeline/pr-main There was a failure building this commit
This commit is contained in:
parent
d2c4cd7428
commit
0f2a700ef1
@ -53,6 +53,8 @@ pub mod tmtc_err {
|
|||||||
pub const UNKNOWN_TARGET_ID: ResultU16 = ResultU16::new(GroupId::Tmtc as u8, 4);
|
pub const UNKNOWN_TARGET_ID: ResultU16 = ResultU16::new(GroupId::Tmtc as u8, 4);
|
||||||
#[resultcode]
|
#[resultcode]
|
||||||
pub const ROUTING_ERROR: ResultU16 = ResultU16::new(GroupId::Tmtc as u8, 5);
|
pub const ROUTING_ERROR: ResultU16 = ResultU16::new(GroupId::Tmtc as u8, 5);
|
||||||
|
#[resultcode(info = "Request timeout for targeted PUS request. P1: Request ID. P2: Target ID")]
|
||||||
|
pub const REQUEST_TIMEOUT: ResultU16 = ResultU16::new(GroupId::Tmtc as u8, 6);
|
||||||
|
|
||||||
#[resultcode(
|
#[resultcode(
|
||||||
info = "Not enough data inside the TC application data field. Optionally includes: \
|
info = "Not enough data inside the TC application data field. Optionally includes: \
|
||||||
|
@ -2,8 +2,8 @@ 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::{
|
use satrs::pus::action::{
|
||||||
ActionReplyPusWithActionId, ActiveActionRequest, DefaultActiveActionRequestMap,
|
ActionReplyPus, ActionReplyPusWithActionId, ActiveActionRequest, DefaultActiveActionRequestMap,
|
||||||
PusService8ActionRequestHandler, PusService8ReplyHandler,
|
PusService8ReplyHandler,
|
||||||
};
|
};
|
||||||
use satrs::pus::verification::{
|
use satrs::pus::verification::{
|
||||||
FailParams, TcStateAccepted, VerificationReporterWithSharedPoolMpscBoundedSender,
|
FailParams, TcStateAccepted, VerificationReporterWithSharedPoolMpscBoundedSender,
|
||||||
@ -12,20 +12,56 @@ use satrs::pus::verification::{
|
|||||||
use satrs::pus::{
|
use satrs::pus::{
|
||||||
EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter,
|
EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter,
|
||||||
EcssTcReceiverCore, EcssTmSenderCore, MpscTcReceiver, PusPacketHandlerResult,
|
EcssTcReceiverCore, EcssTmSenderCore, MpscTcReceiver, PusPacketHandlerResult,
|
||||||
PusPacketHandlingError, PusServiceHelper, PusTcToRequestConverter, ReplyHandlerHook,
|
PusPacketHandlingError, PusReplyHandler, PusServiceHelper, PusTcToRequestConverter,
|
||||||
TmAsVecSenderWithId, TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc,
|
ReplyHandlerHook, TmAsVecSenderWithId, TmAsVecSenderWithMpsc,
|
||||||
TmInSharedPoolSenderWithId,
|
TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
||||||
};
|
};
|
||||||
use satrs::request::TargetAndApidId;
|
use satrs::request::TargetAndApidId;
|
||||||
use satrs::spacepackets::ecss::tc::PusTcReader;
|
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||||
use satrs::spacepackets::ecss::PusPacket;
|
use satrs::spacepackets::ecss::PusPacket;
|
||||||
use satrs::tmtc::tm_helper::SharedTmPool;
|
use satrs::tmtc::tm_helper::SharedTmPool;
|
||||||
use satrs::{ChannelId, TargetId};
|
use satrs::{ChannelId, TargetId};
|
||||||
|
use satrs_example::config::tmtc_err::REQUEST_TIMEOUT;
|
||||||
use satrs_example::config::{tmtc_err, TcReceiverId, TmSenderId, PUS_APID};
|
use satrs_example::config::{tmtc_err, TcReceiverId, TmSenderId, PUS_APID};
|
||||||
use std::sync::mpsc::{self};
|
use std::sync::mpsc::{self};
|
||||||
|
|
||||||
use crate::requests::GenericRequestRouter;
|
use crate::requests::GenericRequestRouter;
|
||||||
|
|
||||||
|
use super::PusTargetedRequestService;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ActionReplyHandler {}
|
||||||
|
|
||||||
|
impl PusReplyHandler<ActiveActionRequest, ActionReplyPusWithActionId> for ActionReplyHandler {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn handle_unexpected_reply(
|
||||||
|
&mut self,
|
||||||
|
reply: &satrs::request::GenericMessage<ActionReplyPusWithActionId>,
|
||||||
|
) {
|
||||||
|
log::warn!("received unexpected reply for service {SERVICE}: {reply}");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_reply(
|
||||||
|
&mut self,
|
||||||
|
reply: &satrs::request::GenericMessage<ActionReplyPusWithActionId>,
|
||||||
|
verification_handler: &impl VerificationReportingProvider,
|
||||||
|
tm_sender: &impl EcssTmSenderCore,
|
||||||
|
) -> Result<bool, Self::Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
fn timeout_callback(&self, active_request: &ActiveRequestType) {
|
||||||
|
log::warn!("timeout for active request {active_request} on service {SERVICE}");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn timeout_error_code(&self) -> satrs::res_code::ResultU16 {
|
||||||
|
REQUEST_TIMEOUT
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ExampleActionRequestConverter {}
|
pub struct ExampleActionRequestConverter {}
|
||||||
|
|
||||||
@ -99,7 +135,7 @@ pub fn create_action_service_static(
|
|||||||
"PUS_8_TC_RECV",
|
"PUS_8_TC_RECV",
|
||||||
pus_action_rx,
|
pus_action_rx,
|
||||||
);
|
);
|
||||||
let action_request_handler = PusService8ActionRequestHandler::new(
|
let action_request_handler = PusTargetedRequestService::new(
|
||||||
PusServiceHelper::new(
|
PusServiceHelper::new(
|
||||||
action_srv_receiver,
|
action_srv_receiver,
|
||||||
action_srv_tm_sender.clone(),
|
action_srv_tm_sender.clone(),
|
||||||
@ -109,18 +145,13 @@ pub fn create_action_service_static(
|
|||||||
),
|
),
|
||||||
ExampleActionRequestConverter::default(),
|
ExampleActionRequestConverter::default(),
|
||||||
action_router,
|
action_router,
|
||||||
);
|
// TODO: Implementation which does not use run-time allocation? Maybe something like
|
||||||
let action_reply_handler = PusService8ReplyHandler::new_from_now(
|
// a bounded wrapper which pre-allocates using [HashMap::with_capacity]..
|
||||||
verif_reporter.clone(),
|
|
||||||
DefaultActiveActionRequestMap::default(),
|
DefaultActiveActionRequestMap::default(),
|
||||||
1024,
|
ActionReplyHandler::<8>::default(),
|
||||||
PusActionReplyHook::default(),
|
);
|
||||||
action_srv_tm_sender,
|
|
||||||
)
|
|
||||||
.expect("Failed to create PUS 8 reply handler");
|
|
||||||
Pus8Wrapper {
|
Pus8Wrapper {
|
||||||
action_request_handler,
|
action_request_handler,
|
||||||
action_reply_handler,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +176,7 @@ pub fn create_action_service_dynamic(
|
|||||||
"PUS_8_TC_RECV",
|
"PUS_8_TC_RECV",
|
||||||
pus_action_rx,
|
pus_action_rx,
|
||||||
);
|
);
|
||||||
let action_request_handler = PusService8ActionRequestHandler::new(
|
let action_request_handler = PusTargetedRequestService::new(
|
||||||
PusServiceHelper::new(
|
PusServiceHelper::new(
|
||||||
action_srv_receiver,
|
action_srv_receiver,
|
||||||
action_srv_tm_sender.clone(),
|
action_srv_tm_sender.clone(),
|
||||||
@ -155,18 +186,11 @@ pub fn create_action_service_dynamic(
|
|||||||
),
|
),
|
||||||
ExampleActionRequestConverter::default(),
|
ExampleActionRequestConverter::default(),
|
||||||
action_router,
|
action_router,
|
||||||
);
|
|
||||||
let action_reply_handler = PusService8ReplyHandler::new_from_now(
|
|
||||||
verif_reporter.clone(),
|
|
||||||
DefaultActiveActionRequestMap::default(),
|
DefaultActiveActionRequestMap::default(),
|
||||||
1024,
|
ActionReplyHandler::<8>::default(),
|
||||||
PusActionReplyHook::default(),
|
);
|
||||||
action_srv_tm_sender,
|
|
||||||
)
|
|
||||||
.expect("Failed to create PUS 8 reply handler");
|
|
||||||
Pus8Wrapper {
|
Pus8Wrapper {
|
||||||
action_request_handler,
|
action_request_handler,
|
||||||
action_reply_handler,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,19 +219,13 @@ pub struct Pus8Wrapper<
|
|||||||
TcInMemConverter: EcssTcInMemConverter,
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
> {
|
> {
|
||||||
pub(crate) action_request_handler: PusService8ActionRequestHandler<
|
pub(crate) action_request_handler: PusTargetedRequestService<
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
TmSender,
|
TmSender,
|
||||||
TcInMemConverter,
|
TcInMemConverter,
|
||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
ExampleActionRequestConverter,
|
ExampleActionRequestConverter,
|
||||||
GenericRequestRouter,
|
ActionRequest,
|
||||||
>,
|
|
||||||
pub(crate) action_reply_handler: PusService8ReplyHandler<
|
|
||||||
VerificationReporter,
|
|
||||||
DefaultActiveActionRequestMap,
|
|
||||||
PusActionReplyHook,
|
|
||||||
TmSender,
|
|
||||||
>,
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +257,6 @@ impl<
|
|||||||
error!("PUS packet handling error: {error:?}")
|
error!("PUS packet handling error: {error:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// self.action_reply_handler.handle_replies();
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,8 +106,8 @@ impl<
|
|||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
> Pus5Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
> Pus5Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
||||||
{
|
{
|
||||||
pub fn handle_next_packet(&mut self) -> bool {
|
pub fn handle_next_packet(&mut self, time_stamp: &[u8]) -> bool {
|
||||||
match self.pus_5_handler.handle_one_tc() {
|
match self.pus_5_handler.handle_one_tc(time_stamp) {
|
||||||
Ok(result) => match result {
|
Ok(result) => match result {
|
||||||
PusPacketHandlerResult::RequestHandled => {}
|
PusPacketHandlerResult::RequestHandled => {}
|
||||||
PusPacketHandlerResult::RequestHandledPartialSuccess(e) => {
|
PusPacketHandlerResult::RequestHandledPartialSuccess(e) => {
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
|
use crate::requests::GenericRequestRouter;
|
||||||
use crate::tmtc::MpscStoreAndSendError;
|
use crate::tmtc::MpscStoreAndSendError;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use satrs::pus::verification::{FailParams, VerificationReportingProvider};
|
use satrs::pus::verification::{
|
||||||
use satrs::pus::{EcssTcAndToken, PusPacketHandlerResult, TcInMemory};
|
self, FailParams, VerificationReporter, VerificationReporterWithSharedPoolMpscBoundedSender,
|
||||||
|
VerificationReporterWithVecMpscSender, VerificationReportingProvider,
|
||||||
|
};
|
||||||
|
use satrs::pus::{
|
||||||
|
ActiveRequestMapProvider, ActiveRequestProvider, DefaultActiveRequestMap, EcssTcAndToken,
|
||||||
|
EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTcReceiverCore,
|
||||||
|
EcssTmSenderCore, GenericRoutingError, MpscTcReceiver, PusPacketHandlerResult, PusReplyHandler,
|
||||||
|
PusServiceHelper, PusServiceReplyHandler, PusTcToRequestConverter, ReplyHandlerHook,
|
||||||
|
TcInMemory, TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc,
|
||||||
|
};
|
||||||
|
use satrs::request::GenericMessage;
|
||||||
use satrs::spacepackets::ecss::tc::PusTcReader;
|
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||||
use satrs::spacepackets::ecss::PusServiceId;
|
use satrs::spacepackets::ecss::PusServiceId;
|
||||||
use satrs::spacepackets::time::cds::TimeProvider;
|
use satrs::spacepackets::time::cds::TimeProvider;
|
||||||
@ -36,13 +47,6 @@ struct TimeStampHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TimeStampHelper {
|
impl TimeStampHelper {
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
stamper: TimeProvider::new_with_u16_days(0, 0),
|
|
||||||
time_stamp: [0; 7],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stamp(&self) -> &[u8] {
|
pub fn stamp(&self) -> &[u8] {
|
||||||
&self.time_stamp
|
&self.time_stamp
|
||||||
}
|
}
|
||||||
@ -57,16 +61,137 @@ impl TimeStampHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for TimeStampHelper {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
stamper: TimeProvider::from_now_with_u16_days().expect("creating time stamper failed"),
|
||||||
|
time_stamp: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<VerificationReporter: VerificationReportingProvider> PusReceiver<VerificationReporter> {
|
impl<VerificationReporter: VerificationReportingProvider> PusReceiver<VerificationReporter> {
|
||||||
pub fn new(verif_reporter: VerificationReporter, pus_router: PusTcMpscRouter) -> Self {
|
pub fn new(verif_reporter: VerificationReporter, pus_router: PusTcMpscRouter) -> Self {
|
||||||
Self {
|
Self {
|
||||||
verif_reporter,
|
verif_reporter,
|
||||||
pus_router,
|
pus_router,
|
||||||
stamp_helper: TimeStampHelper::new(),
|
stamp_helper: TimeStampHelper::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct PusTargetedRequestService<
|
||||||
|
TcReceiver: EcssTcReceiverCore,
|
||||||
|
TmSender: EcssTmSenderCore,
|
||||||
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
|
VerificationReporter: VerificationReportingProvider,
|
||||||
|
RequestConverter: PusTcToRequestConverter<RequestType>,
|
||||||
|
ReplyHook: ReplyHandlerHook<RequestType, ReplyType>,
|
||||||
|
ActiveRequestMap: ActiveRequestMapProvider<RequestType>,
|
||||||
|
ActiveRequestType: ActiveRequestProvider,
|
||||||
|
RequestType,
|
||||||
|
ReplyType,
|
||||||
|
> {
|
||||||
|
pub service_helper:
|
||||||
|
PusServiceHelper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
||||||
|
pub request_router: GenericRequestRouter,
|
||||||
|
pub request_converter: RequestConverter,
|
||||||
|
pub active_request_map: ActiveRequestMap,
|
||||||
|
pub reply_hook: ReplyHook,
|
||||||
|
phantom: std::marker::PhantomData<RequestType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
TcReceiver: EcssTcReceiverCore,
|
||||||
|
TmSender: EcssTmSenderCore,
|
||||||
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
|
VerificationReporter: VerificationReportingProvider,
|
||||||
|
RequestConverter: PusTcToRequestConverter<RequestType>,
|
||||||
|
ReplyHandler: PusReplyHandler<ActiveRequestType, ReplyType>,
|
||||||
|
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestType>,
|
||||||
|
ActiveRequestType: ActiveRequestProvider,
|
||||||
|
RequestType,
|
||||||
|
ReplyType,
|
||||||
|
>
|
||||||
|
PusTargetedRequestService<
|
||||||
|
TcReceiver,
|
||||||
|
TmSender,
|
||||||
|
TcInMemConverter,
|
||||||
|
VerificationReporter,
|
||||||
|
RequestConverter,
|
||||||
|
ReplyHandler,
|
||||||
|
ActiveRequestMap,
|
||||||
|
ActiveRequestType,
|
||||||
|
RequestType,
|
||||||
|
ReplyType,
|
||||||
|
>
|
||||||
|
{
|
||||||
|
pub fn new(
|
||||||
|
service_helper: PusServiceHelper<
|
||||||
|
TcReceiver,
|
||||||
|
TmSender,
|
||||||
|
TcInMemConverter,
|
||||||
|
VerificationReporter,
|
||||||
|
>,
|
||||||
|
request_converter: RequestConverter,
|
||||||
|
request_router: GenericRequestRouter,
|
||||||
|
active_request_map: ActiveRequestMap,
|
||||||
|
reply_hook: ReplyHandler,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
service_helper,
|
||||||
|
request_router,
|
||||||
|
request_converter,
|
||||||
|
active_request_map,
|
||||||
|
reply_hook,
|
||||||
|
phantom: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_one_tc(&mut self) {
|
||||||
|
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 (active_request, 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(
|
||||||
|
active_request.target_id(),
|
||||||
|
action_request,
|
||||||
|
ecss_tc_and_token.token,
|
||||||
|
) {
|
||||||
|
let verif_request_id = verification::RequestId::new(&tc);
|
||||||
|
self.active_request_map
|
||||||
|
.insert(verif_request_id.into(), active_request);
|
||||||
|
self.request_router.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 fn insert_reply(&mut self, reply: &GenericMessage<ReplyType>) {
|
||||||
|
// self.reply_hook.insert_reply(reply, &self.active_request_map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<VerificationReporter: VerificationReportingProvider> PusReceiver<VerificationReporter> {
|
impl<VerificationReporter: VerificationReportingProvider> PusReceiver<VerificationReporter> {
|
||||||
pub fn handle_tc_packet(
|
pub fn handle_tc_packet(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -103,8 +103,11 @@ impl<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_next_packet(&mut self) -> bool {
|
pub fn handle_next_packet(&mut self, time_stamp: &[u8]) -> bool {
|
||||||
match self.pus_11_handler.handle_one_tc(&mut self.sched_tc_pool) {
|
match self
|
||||||
|
.pus_11_handler
|
||||||
|
.handle_one_tc(time_stamp, &mut self.sched_tc_pool)
|
||||||
|
{
|
||||||
Ok(result) => match result {
|
Ok(result) => match result {
|
||||||
PusPacketHandlerResult::RequestHandled => {}
|
PusPacketHandlerResult::RequestHandled => {}
|
||||||
PusPacketHandlerResult::RequestHandledPartialSuccess(e) => {
|
PusPacketHandlerResult::RequestHandledPartialSuccess(e) => {
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use satrs::pus::{
|
use satrs::{
|
||||||
verification::VerificationReportingProvider, EcssTcInMemConverter, EcssTcReceiverCore,
|
pus::{
|
||||||
EcssTmSenderCore,
|
verification::VerificationReportingProvider, EcssTcInMemConverter, EcssTcReceiverCore,
|
||||||
|
EcssTmSenderCore,
|
||||||
|
},
|
||||||
|
spacepackets::time::{cds, TimeWriter},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -51,6 +54,10 @@ impl<
|
|||||||
|
|
||||||
pub fn periodic_operation(&mut self) {
|
pub fn periodic_operation(&mut self) {
|
||||||
self.schedule_srv.release_tcs();
|
self.schedule_srv.release_tcs();
|
||||||
|
let time_stamp = cds::TimeProvider::from_now_with_u16_days()
|
||||||
|
.expect("time stamp generation error")
|
||||||
|
.to_vec()
|
||||||
|
.unwrap();
|
||||||
loop {
|
loop {
|
||||||
let mut all_queues_empty = true;
|
let mut all_queues_empty = true;
|
||||||
let mut is_srv_finished = |srv_handler_finished: bool| {
|
let mut is_srv_finished = |srv_handler_finished: bool| {
|
||||||
@ -58,9 +65,9 @@ impl<
|
|||||||
all_queues_empty = false;
|
all_queues_empty = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
is_srv_finished(self.test_srv.handle_next_packet());
|
is_srv_finished(self.test_srv.handle_next_packet(&time_stamp));
|
||||||
is_srv_finished(self.schedule_srv.handle_next_packet());
|
is_srv_finished(self.schedule_srv.handle_next_packet(&time_stamp));
|
||||||
is_srv_finished(self.event_srv.handle_next_packet());
|
is_srv_finished(self.event_srv.handle_next_packet(&time_stamp));
|
||||||
is_srv_finished(self.action_srv.handle_next_packet());
|
is_srv_finished(self.action_srv.handle_next_packet());
|
||||||
is_srv_finished(self.hk_srv.handle_next_packet());
|
is_srv_finished(self.hk_srv.handle_next_packet());
|
||||||
if all_queues_empty {
|
if all_queues_empty {
|
||||||
|
@ -111,8 +111,8 @@ impl<
|
|||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
> Service17CustomWrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
> Service17CustomWrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
||||||
{
|
{
|
||||||
pub fn handle_next_packet(&mut self) -> bool {
|
pub fn handle_next_packet(&mut self, time_stamp: &[u8]) -> bool {
|
||||||
let res = self.pus17_handler.handle_one_tc();
|
let res = self.pus17_handler.handle_one_tc(time_stamp);
|
||||||
if res.is_err() {
|
if res.is_err() {
|
||||||
warn!("PUS17 handler failed with error {:?}", res.unwrap_err());
|
warn!("PUS17 handler failed with error {:?}", res.unwrap_err());
|
||||||
return true;
|
return true;
|
||||||
|
@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use super::{
|
use super::{
|
||||||
filestore::{FilestoreError, VirtualFilestore},
|
filestore::{FilestoreError, VirtualFilestore},
|
||||||
user::{CfdpUser, FileSegmentRecvdParams, MetadataReceivedParams},
|
user::{CfdpUser, FileSegmentRecvdParams, MetadataReceivedParams},
|
||||||
CheckTimer, CheckTimerCreator, EntityType, LocalEntityConfig, PacketInfo, PacketTarget,
|
CheckTimerCreator, CountdownProvider, EntityType, LocalEntityConfig, PacketInfo, PacketTarget,
|
||||||
RemoteEntityConfig, RemoteEntityConfigProvider, State, TimerContext, TransactionId,
|
RemoteEntityConfig, RemoteEntityConfigProvider, State, TimerContext, TransactionId,
|
||||||
TransactionStep,
|
TransactionStep,
|
||||||
};
|
};
|
||||||
@ -54,7 +54,7 @@ struct TransferState {
|
|||||||
completion_disposition: CompletionDisposition,
|
completion_disposition: CompletionDisposition,
|
||||||
checksum: u32,
|
checksum: u32,
|
||||||
current_check_count: u32,
|
current_check_count: u32,
|
||||||
current_check_timer: Option<Box<dyn CheckTimer>>,
|
current_check_timer: Option<Box<dyn CountdownProvider>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TransferState {
|
impl Default for TransferState {
|
||||||
@ -799,9 +799,9 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::cfdp::{
|
use crate::cfdp::{
|
||||||
filestore::NativeFilestore, user::OwnedMetadataRecvdParams, CheckTimer, CheckTimerCreator,
|
filestore::NativeFilestore, user::OwnedMetadataRecvdParams, CheckTimerCreator,
|
||||||
DefaultFaultHandler, IndicationConfig, RemoteEntityConfig, StdRemoteEntityConfigProvider,
|
CountdownProvider, DefaultFaultHandler, IndicationConfig, RemoteEntityConfig,
|
||||||
UserFaultHandler, CRC_32,
|
StdRemoteEntityConfigProvider, UserFaultHandler, CRC_32,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -1057,7 +1057,7 @@ mod tests {
|
|||||||
expired: Arc<AtomicBool>,
|
expired: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CheckTimer for TestCheckTimer {
|
impl CountdownProvider for TestCheckTimer {
|
||||||
fn has_expired(&self) -> bool {
|
fn has_expired(&self) -> bool {
|
||||||
self.expired.load(core::sync::atomic::Ordering::Relaxed)
|
self.expired.load(core::sync::atomic::Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
@ -1088,7 +1088,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CheckTimerCreator for TestCheckTimerCreator {
|
impl CheckTimerCreator for TestCheckTimerCreator {
|
||||||
fn get_check_timer_provider(&self, timer_context: TimerContext) -> Box<dyn CheckTimer> {
|
fn get_check_timer_provider(
|
||||||
|
&self,
|
||||||
|
timer_context: TimerContext,
|
||||||
|
) -> Box<dyn CountdownProvider> {
|
||||||
match timer_context {
|
match timer_context {
|
||||||
TimerContext::CheckLimit { .. } => {
|
TimerContext::CheckLimit { .. } => {
|
||||||
Box::new(TestCheckTimer::new(self.check_limit_expired_flag.clone()))
|
Box::new(TestCheckTimer::new(self.check_limit_expired_flag.clone()))
|
||||||
|
@ -17,6 +17,8 @@ use alloc::boxed::Box;
|
|||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::time::CountdownProvider;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub mod dest;
|
pub mod dest;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
@ -45,7 +47,15 @@ pub enum TimerContext {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic abstraction for a check timer which is used by 3 mechanisms of the CFDP protocol.
|
/// A generic trait which allows CFDP entities to create check timers which are required to
|
||||||
|
/// implement special procedures in unacknowledged transmission mode, as specified in 4.6.3.2
|
||||||
|
/// and 4.6.3.3.
|
||||||
|
///
|
||||||
|
/// This trait also allows the creation of different check timers depending on context and purpose
|
||||||
|
/// of the timer, the runtime environment (e.g. standard clock timer vs. timer using a RTC) or
|
||||||
|
/// other factors.
|
||||||
|
///
|
||||||
|
/// The countdown timer is used by 3 mechanisms of the CFDP protocol.
|
||||||
///
|
///
|
||||||
/// ## 1. Check limit handling
|
/// ## 1. Check limit handling
|
||||||
///
|
///
|
||||||
@ -74,22 +84,9 @@ pub enum TimerContext {
|
|||||||
/// The timer will be used to perform the Positive Acknowledgement Procedures as specified in
|
/// The timer will be used to perform the Positive Acknowledgement Procedures as specified in
|
||||||
/// 4.7. 1of the CFDP standard. The expiration period will be provided by the Positive ACK timer
|
/// 4.7. 1of the CFDP standard. The expiration period will be provided by the Positive ACK timer
|
||||||
/// interval of the remote entity configuration.
|
/// interval of the remote entity configuration.
|
||||||
pub trait CheckTimer: Debug {
|
|
||||||
fn has_expired(&self) -> bool;
|
|
||||||
fn reset(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A generic trait which allows CFDP entities to create check timers which are required to
|
|
||||||
/// implement special procedures in unacknowledged transmission mode, as specified in 4.6.3.2
|
|
||||||
/// and 4.6.3.3. The [CheckTimer] documentation provides more information about the purpose of the
|
|
||||||
/// check timer in the context of CFDP.
|
|
||||||
///
|
|
||||||
/// This trait also allows the creation of different check timers depending on context and purpose
|
|
||||||
/// of the timer, the runtime environment (e.g. standard clock timer vs. timer using a RTC) or
|
|
||||||
/// other factors.
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub trait CheckTimerCreator {
|
pub trait CheckTimerCreator {
|
||||||
fn get_check_timer_provider(&self, timer_context: TimerContext) -> Box<dyn CheckTimer>;
|
fn get_check_timer_provider(&self, timer_context: TimerContext) -> Box<dyn CountdownProvider>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Simple implementation of the [CheckTimerCreator] trait assuming a standard runtime.
|
/// Simple implementation of the [CheckTimerCreator] trait assuming a standard runtime.
|
||||||
@ -112,7 +109,7 @@ impl StdCheckTimer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl CheckTimer for StdCheckTimer {
|
impl CountdownProvider for StdCheckTimer {
|
||||||
fn has_expired(&self) -> bool {
|
fn has_expired(&self) -> bool {
|
||||||
let elapsed_time = self.start_time.elapsed();
|
let elapsed_time = self.start_time.elapsed();
|
||||||
if elapsed_time.as_secs() > self.expiry_time_seconds {
|
if elapsed_time.as_secs() > self.expiry_time_seconds {
|
||||||
|
@ -43,6 +43,7 @@ pub mod queue;
|
|||||||
pub mod request;
|
pub mod request;
|
||||||
pub mod res_code;
|
pub mod res_code;
|
||||||
pub mod seq_count;
|
pub mod seq_count;
|
||||||
|
pub mod time;
|
||||||
pub mod tmtc;
|
pub mod tmtc;
|
||||||
|
|
||||||
pub mod action;
|
pub mod action;
|
||||||
|
@ -105,7 +105,6 @@ pub mod std_mod {
|
|||||||
self, FailParams, FailParamsWithStep, TcStateStarted, VerificationReportingProvider,
|
self, FailParams, FailParamsWithStep, TcStateStarted, VerificationReportingProvider,
|
||||||
},
|
},
|
||||||
ActiveRequestMapProvider, DefaultActiveRequestMap, EcssTmSenderCore, EcssTmtcError,
|
ActiveRequestMapProvider, DefaultActiveRequestMap, EcssTmSenderCore, EcssTmtcError,
|
||||||
GenericRoutingError, PusServiceReplyHandler, PusTargetedRequestHandler,
|
|
||||||
ReplyHandlerHook,
|
ReplyHandlerHook,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -115,27 +114,9 @@ pub mod std_mod {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub type PusService8ActionRequestHandler<
|
|
||||||
TcReceiver,
|
|
||||||
TmSender,
|
|
||||||
TcInMemConverter,
|
|
||||||
VerificationReporter,
|
|
||||||
RequestConverter,
|
|
||||||
RequestRouter,
|
|
||||||
RoutingError = GenericRoutingError,
|
|
||||||
> = PusTargetedRequestHandler<
|
|
||||||
TcReceiver,
|
|
||||||
TmSender,
|
|
||||||
TcInMemConverter,
|
|
||||||
VerificationReporter,
|
|
||||||
RequestConverter,
|
|
||||||
RequestRouter,
|
|
||||||
ActionRequest,
|
|
||||||
RoutingError,
|
|
||||||
>;
|
|
||||||
|
|
||||||
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.
|
||||||
@ -299,6 +280,7 @@ pub mod std_mod {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -311,11 +293,12 @@ mod tests {
|
|||||||
|
|
||||||
use spacepackets::{
|
use spacepackets::{
|
||||||
ecss::{
|
ecss::{
|
||||||
tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader},
|
tc::{PusTcCreator, PusTcReader},
|
||||||
tm::PusTmReader,
|
tm::PusTmReader,
|
||||||
PusPacket,
|
PusPacket,
|
||||||
},
|
},
|
||||||
CcsdsPacket, SequenceFlags, SpHeader,
|
time::{cds, TimeWriter},
|
||||||
|
CcsdsPacket,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -324,7 +307,7 @@ mod tests {
|
|||||||
pus::{
|
pus::{
|
||||||
tests::{
|
tests::{
|
||||||
PusServiceHandlerWithVecCommon, PusTestHarness, SimplePusPacketHandler,
|
PusServiceHandlerWithVecCommon, PusTestHarness, SimplePusPacketHandler,
|
||||||
TestConverter, TestRouter, APP_DATA_TOO_SHORT, TEST_APID,
|
TestConverter, TestRouter, APP_DATA_TOO_SHORT,
|
||||||
},
|
},
|
||||||
verification::{
|
verification::{
|
||||||
self,
|
self,
|
||||||
@ -332,9 +315,9 @@ mod tests {
|
|||||||
FailParams, TcStateAccepted, TcStateNone, TcStateStarted,
|
FailParams, TcStateAccepted, TcStateNone, TcStateStarted,
|
||||||
VerificationReportingProvider,
|
VerificationReportingProvider,
|
||||||
},
|
},
|
||||||
EcssTcInVecConverter, EcssTmtcError, GenericRoutingError, MpscTcReceiver,
|
EcssTcInMemConverter, EcssTcInVecConverter, EcssTmtcError, GenericRoutingError,
|
||||||
PusPacketHandlerResult, PusPacketHandlingError, PusRequestRouter,
|
MpscTcReceiver, PusPacketHandlerResult, PusPacketHandlingError, PusRequestRouter,
|
||||||
PusTcToRequestConverter, ReplyHandlerHook, TmAsVecSenderWithMpsc,
|
PusServiceHelper, PusTcToRequestConverter, ReplyHandlerHook, TmAsVecSenderWithMpsc,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -416,29 +399,32 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Pus8RequestTestbenchWithVec {
|
pub struct PusDynRequestHandler<const SERVICE: u8, Request> {
|
||||||
common: PusServiceHandlerWithVecCommon<TestVerificationReporter>,
|
srv_helper: PusServiceHelper<
|
||||||
handler: PusService8ActionRequestHandler<
|
|
||||||
MpscTcReceiver,
|
MpscTcReceiver,
|
||||||
TmAsVecSenderWithMpsc,
|
TmAsVecSenderWithMpsc,
|
||||||
EcssTcInVecConverter,
|
EcssTcInVecConverter,
|
||||||
TestVerificationReporter,
|
TestVerificationReporter,
|
||||||
TestConverter<8>,
|
|
||||||
TestRouter<ActionRequest>,
|
|
||||||
>,
|
>,
|
||||||
|
request_converter: TestConverter<SERVICE>,
|
||||||
|
request_router: TestRouter<Request>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Pus8RequestTestbenchWithVec {
|
||||||
|
common: PusServiceHandlerWithVecCommon<TestVerificationReporter>,
|
||||||
|
handler: PusDynRequestHandler<8, ActionRequest>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pus8RequestTestbenchWithVec {
|
impl Pus8RequestTestbenchWithVec {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let (common, srv_handler) =
|
let (common, srv_helper) = PusServiceHandlerWithVecCommon::new_with_test_verif_sender();
|
||||||
PusServiceHandlerWithVecCommon::new_with_test_verif_sender();
|
|
||||||
Self {
|
Self {
|
||||||
common,
|
common,
|
||||||
handler: PusService8ActionRequestHandler::new(
|
handler: PusDynRequestHandler {
|
||||||
srv_handler,
|
srv_helper,
|
||||||
TestConverter::default(),
|
request_converter: TestConverter::default(),
|
||||||
TestRouter::default(),
|
request_router: TestRouter::default(),
|
||||||
),
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,10 +460,43 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl SimplePusPacketHandler for Pus8RequestTestbenchWithVec {
|
impl SimplePusPacketHandler for Pus8RequestTestbenchWithVec {
|
||||||
delegate! {
|
fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
||||||
to self.handler {
|
let possible_packet = self.handler.srv_helper.retrieve_and_accept_next_packet()?;
|
||||||
fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError>;
|
if possible_packet.is_none() {
|
||||||
|
return Ok(PusPacketHandlerResult::Empty);
|
||||||
}
|
}
|
||||||
|
let ecss_tc_and_token = possible_packet.unwrap();
|
||||||
|
let tc = self
|
||||||
|
.handler
|
||||||
|
.srv_helper
|
||||||
|
.tc_in_mem_converter
|
||||||
|
.convert_ecss_tc_in_memory_to_reader(&ecss_tc_and_token.tc_in_memory)?;
|
||||||
|
let time_stamp = cds::TimeProvider::from_now_with_u16_days()
|
||||||
|
.expect("timestamp generation failed")
|
||||||
|
.to_vec()
|
||||||
|
.unwrap();
|
||||||
|
let (target_id, action_request) = self.handler.request_converter.convert(
|
||||||
|
ecss_tc_and_token.token,
|
||||||
|
&tc,
|
||||||
|
&time_stamp,
|
||||||
|
&self.handler.srv_helper.common.verification_handler,
|
||||||
|
)?;
|
||||||
|
if let Err(e) = self.handler.request_router.route(
|
||||||
|
target_id,
|
||||||
|
action_request,
|
||||||
|
ecss_tc_and_token.token,
|
||||||
|
) {
|
||||||
|
self.handler.request_router.handle_error(
|
||||||
|
target_id,
|
||||||
|
ecss_tc_and_token.token,
|
||||||
|
&tc,
|
||||||
|
e.clone(),
|
||||||
|
&time_stamp,
|
||||||
|
&self.handler.srv_helper.common.verification_handler,
|
||||||
|
);
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
|
Ok(PusPacketHandlerResult::RequestHandled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,68 +686,6 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn basic_test() {
|
|
||||||
let mut action_handler = Pus8RequestTestbenchWithVec::new();
|
|
||||||
let mut sp_header = SpHeader::tc(TEST_APID, SequenceFlags::Unsegmented, 0, 0).unwrap();
|
|
||||||
let sec_header = PusTcSecondaryHeader::new_simple(8, 1);
|
|
||||||
let action_id: u32 = 1;
|
|
||||||
let action_id_raw = action_id.to_be_bytes();
|
|
||||||
let tc = PusTcCreator::new(&mut sp_header, sec_header, action_id_raw.as_ref(), true);
|
|
||||||
action_handler.send_tc(&tc);
|
|
||||||
let result = action_handler.handle_one_tc();
|
|
||||||
assert!(result.is_ok());
|
|
||||||
action_handler.check_next_conversion(&tc);
|
|
||||||
let (target_id, action_req) = action_handler.retrieve_next_request();
|
|
||||||
assert_eq!(target_id, TEST_APID.into());
|
|
||||||
assert_eq!(action_req.action_id, 1);
|
|
||||||
if let ActionRequestVariant::VecData(data) = action_req.variant {
|
|
||||||
assert_eq!(data, &[]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_routing_error() {
|
|
||||||
let mut action_handler = Pus8RequestTestbenchWithVec::new();
|
|
||||||
let mut sp_header = SpHeader::tc(TEST_APID, SequenceFlags::Unsegmented, 0, 0).unwrap();
|
|
||||||
let sec_header = PusTcSecondaryHeader::new_simple(8, 1);
|
|
||||||
let action_id: u32 = 1;
|
|
||||||
let action_id_raw = action_id.to_be_bytes();
|
|
||||||
let tc = PusTcCreator::new(&mut sp_header, sec_header, action_id_raw.as_ref(), true);
|
|
||||||
let error = GenericRoutingError::UnknownTargetId(25);
|
|
||||||
action_handler
|
|
||||||
.handler
|
|
||||||
.request_router
|
|
||||||
.inject_routing_error(error);
|
|
||||||
action_handler.send_tc(&tc);
|
|
||||||
let result = action_handler.handle_one_tc();
|
|
||||||
assert!(result.is_err());
|
|
||||||
let check_error = |routing_error: GenericRoutingError| {
|
|
||||||
if let GenericRoutingError::UnknownTargetId(id) = routing_error {
|
|
||||||
assert_eq!(id, 25);
|
|
||||||
} else {
|
|
||||||
panic!("unexpected error type");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let PusPacketHandlingError::RequestRoutingError(routing_error) = result.unwrap_err() {
|
|
||||||
check_error(routing_error);
|
|
||||||
} else {
|
|
||||||
panic!("unexpected error type");
|
|
||||||
}
|
|
||||||
|
|
||||||
action_handler.check_next_conversion(&tc);
|
|
||||||
let (target_id, action_req) = action_handler.retrieve_next_request();
|
|
||||||
assert_eq!(target_id, TEST_APID.into());
|
|
||||||
assert_eq!(action_req.action_id, 1);
|
|
||||||
if let ActionRequestVariant::VecData(data) = action_req.variant {
|
|
||||||
assert_eq!(data, &[]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let (target_id, found_error) = action_handler.retrieve_next_routing_error();
|
|
||||||
assert_eq!(target_id, TEST_APID.into());
|
|
||||||
check_error(found_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_reply_handler_completion_success() {
|
fn test_reply_handler_completion_success() {
|
||||||
let mut reply_testbench = Pus8ReplyTestbench::new(true);
|
let mut reply_testbench = Pus8ReplyTestbench::new(true);
|
||||||
|
@ -7,10 +7,7 @@ use spacepackets::ecss::PusPacket;
|
|||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
|
|
||||||
use super::verification::VerificationReportingProvider;
|
use super::verification::VerificationReportingProvider;
|
||||||
use super::{
|
use super::{EcssTcInMemConverter, EcssTcReceiverCore, EcssTmSenderCore, PusServiceHelper};
|
||||||
get_current_cds_short_timestamp, EcssTcInMemConverter, EcssTcReceiverCore, EcssTmSenderCore,
|
|
||||||
PusServiceHelper,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct PusService5EventHandler<
|
pub struct PusService5EventHandler<
|
||||||
TcReceiver: EcssTcReceiverCore,
|
TcReceiver: EcssTcReceiverCore,
|
||||||
@ -45,7 +42,10 @@ impl<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
pub fn handle_one_tc(
|
||||||
|
&mut self,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
||||||
let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?;
|
let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?;
|
||||||
if possible_packet.is_none() {
|
if possible_packet.is_none() {
|
||||||
return Ok(PusPacketHandlerResult::Empty);
|
return Ok(PusPacketHandlerResult::Empty);
|
||||||
@ -63,7 +63,7 @@ impl<
|
|||||||
ecss_tc_and_token.token,
|
ecss_tc_and_token.token,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let handle_enable_disable_request = |enable: bool, stamp: [u8; 7]| {
|
let handle_enable_disable_request = |enable: bool| {
|
||||||
if tc.user_data().len() < 4 {
|
if tc.user_data().len() < 4 {
|
||||||
return Err(PusPacketHandlingError::NotEnoughAppData {
|
return Err(PusPacketHandlingError::NotEnoughAppData {
|
||||||
expected: 4,
|
expected: 4,
|
||||||
@ -76,7 +76,7 @@ impl<
|
|||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verification_handler
|
||||||
.start_success(ecss_tc_and_token.token, &stamp)
|
.start_success(ecss_tc_and_token.token, time_stamp)
|
||||||
.map_err(|_| PartialPusHandlingError::Verification);
|
.map_err(|_| PartialPusHandlingError::Verification);
|
||||||
let partial_error = start_token.clone().err();
|
let partial_error = start_token.clone().err();
|
||||||
let mut token: TcStateToken = ecss_tc_and_token.token.into();
|
let mut token: TcStateToken = ecss_tc_and_token.token.into();
|
||||||
@ -106,8 +106,6 @@ impl<
|
|||||||
}
|
}
|
||||||
Ok(PusPacketHandlerResult::RequestHandled)
|
Ok(PusPacketHandlerResult::RequestHandled)
|
||||||
};
|
};
|
||||||
let mut partial_error = None;
|
|
||||||
let time_stamp = get_current_cds_short_timestamp(&mut partial_error);
|
|
||||||
match srv.unwrap() {
|
match srv.unwrap() {
|
||||||
Subservice::TmInfoReport
|
Subservice::TmInfoReport
|
||||||
| Subservice::TmLowSeverityReport
|
| Subservice::TmLowSeverityReport
|
||||||
@ -116,10 +114,10 @@ impl<
|
|||||||
return Err(PusPacketHandlingError::InvalidSubservice(tc.subservice()))
|
return Err(PusPacketHandlingError::InvalidSubservice(tc.subservice()))
|
||||||
}
|
}
|
||||||
Subservice::TcEnableEventGeneration => {
|
Subservice::TcEnableEventGeneration => {
|
||||||
handle_enable_disable_request(true, time_stamp)?;
|
handle_enable_disable_request(true)?;
|
||||||
}
|
}
|
||||||
Subservice::TcDisableEventGeneration => {
|
Subservice::TcDisableEventGeneration => {
|
||||||
handle_enable_disable_request(false, time_stamp)?;
|
handle_enable_disable_request(false)?;
|
||||||
}
|
}
|
||||||
Subservice::TcReportDisabledList | Subservice::TmDisabledEventsReport => {
|
Subservice::TcReportDisabledList | Subservice::TmDisabledEventsReport => {
|
||||||
return Ok(PusPacketHandlerResult::SubserviceNotImplemented(
|
return Ok(PusPacketHandlerResult::SubserviceNotImplemented(
|
||||||
@ -137,6 +135,7 @@ impl<
|
|||||||
mod tests {
|
mod tests {
|
||||||
use delegate::delegate;
|
use delegate::delegate;
|
||||||
use spacepackets::ecss::event::Subservice;
|
use spacepackets::ecss::event::Subservice;
|
||||||
|
use spacepackets::time::{cds, TimeWriter};
|
||||||
use spacepackets::util::UnsignedEnum;
|
use spacepackets::util::UnsignedEnum;
|
||||||
use spacepackets::{
|
use spacepackets::{
|
||||||
ecss::{
|
ecss::{
|
||||||
@ -200,10 +199,9 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SimplePusPacketHandler for Pus5HandlerWithStoreTester {
|
impl SimplePusPacketHandler for Pus5HandlerWithStoreTester {
|
||||||
delegate! {
|
fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
||||||
to self.handler {
|
let time_stamp = cds::TimeProvider::new_with_u16_days(0, 0).to_vec().unwrap();
|
||||||
fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError>;
|
self.handler.handle_one_tc(&time_stamp)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,280 +0,0 @@
|
|||||||
pub use spacepackets::ecss::hk::*;
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
|
||||||
pub use std_mod::*;
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
pub use alloc_mod::*;
|
|
||||||
|
|
||||||
use crate::{hk::HkRequest, TargetId};
|
|
||||||
|
|
||||||
use super::verification::{TcStateAccepted, VerificationToken};
|
|
||||||
|
|
||||||
/// This trait is an abstraction for the routing of PUS service 3 housekeeping requests to a
|
|
||||||
/// dedicated recipient using the generic [TargetId].
|
|
||||||
pub trait PusHkRequestRouter {
|
|
||||||
type Error;
|
|
||||||
fn route(
|
|
||||||
&self,
|
|
||||||
target_id: TargetId,
|
|
||||||
hk_request: HkRequest,
|
|
||||||
token: VerificationToken<TcStateAccepted>,
|
|
||||||
) -> Result<(), Self::Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
|
||||||
pub mod alloc_mod {}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
|
||||||
pub mod std_mod {
|
|
||||||
use crate::pus::{GenericRoutingError, PusTargetedRequestHandler};
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub type PusService3HkRequestHandler<
|
|
||||||
TcReceiver,
|
|
||||||
TmSender,
|
|
||||||
TcInMemConverter,
|
|
||||||
VerificationReporter,
|
|
||||||
RequestConverter,
|
|
||||||
RequestRouter,
|
|
||||||
RoutingError = GenericRoutingError,
|
|
||||||
> = PusTargetedRequestHandler<
|
|
||||||
TcReceiver,
|
|
||||||
TmSender,
|
|
||||||
TcInMemConverter,
|
|
||||||
VerificationReporter,
|
|
||||||
RequestConverter,
|
|
||||||
RequestRouter,
|
|
||||||
HkRequest,
|
|
||||||
RoutingError,
|
|
||||||
>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use delegate::delegate;
|
|
||||||
use spacepackets::ecss::hk::Subservice;
|
|
||||||
|
|
||||||
use spacepackets::{
|
|
||||||
ecss::{
|
|
||||||
tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader},
|
|
||||||
tm::PusTmReader,
|
|
||||||
PusPacket,
|
|
||||||
},
|
|
||||||
CcsdsPacket, SequenceFlags, SpHeader,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::pus::{MpscTcReceiver, PusTcToRequestConverter, TmAsVecSenderWithMpsc};
|
|
||||||
use crate::{
|
|
||||||
hk::HkRequest,
|
|
||||||
pus::{
|
|
||||||
tests::{
|
|
||||||
PusServiceHandlerWithVecCommon, PusTestHarness, SimplePusPacketHandler,
|
|
||||||
TestConverter, TestRouter, APP_DATA_TOO_SHORT, TEST_APID,
|
|
||||||
},
|
|
||||||
verification::{
|
|
||||||
tests::TestVerificationReporter, FailParams, RequestId, TcStateAccepted,
|
|
||||||
VerificationReportingProvider, VerificationToken,
|
|
||||||
},
|
|
||||||
EcssTcInVecConverter, GenericRoutingError, PusPacketHandlerResult,
|
|
||||||
PusPacketHandlingError,
|
|
||||||
},
|
|
||||||
TargetId,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{PusHkRequestRouter, PusService3HkRequestHandler};
|
|
||||||
|
|
||||||
impl PusHkRequestRouter for TestRouter<HkRequest> {
|
|
||||||
type Error = GenericRoutingError;
|
|
||||||
|
|
||||||
fn route(
|
|
||||||
&self,
|
|
||||||
target_id: TargetId,
|
|
||||||
hk_request: HkRequest,
|
|
||||||
_token: VerificationToken<TcStateAccepted>,
|
|
||||||
) -> Result<(), Self::Error> {
|
|
||||||
self.routing_requests
|
|
||||||
.borrow_mut()
|
|
||||||
.push_back((target_id, hk_request));
|
|
||||||
self.check_for_injected_error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PusTcToRequestConverter<HkRequest> for TestConverter<3> {
|
|
||||||
type Error = PusPacketHandlingError;
|
|
||||||
fn convert(
|
|
||||||
&mut self,
|
|
||||||
token: VerificationToken<TcStateAccepted>,
|
|
||||||
tc: &PusTcReader,
|
|
||||||
time_stamp: &[u8],
|
|
||||||
verif_reporter: &impl VerificationReportingProvider,
|
|
||||||
) -> Result<(TargetId, HkRequest), Self::Error> {
|
|
||||||
self.conversion_request.push_back(tc.raw_data().to_vec());
|
|
||||||
self.check_service(tc)?;
|
|
||||||
let target_id = tc.apid();
|
|
||||||
if tc.user_data().len() < 4 {
|
|
||||||
verif_reporter
|
|
||||||
.start_failure(
|
|
||||||
token,
|
|
||||||
FailParams::new(
|
|
||||||
time_stamp,
|
|
||||||
&APP_DATA_TOO_SHORT,
|
|
||||||
(tc.user_data().len() as u32).to_be_bytes().as_ref(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.expect("start success failure");
|
|
||||||
return Err(PusPacketHandlingError::NotEnoughAppData {
|
|
||||||
expected: 4,
|
|
||||||
found: tc.user_data().len(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if tc.subservice() == Subservice::TcGenerateOneShotHk as u8 {
|
|
||||||
verif_reporter
|
|
||||||
.start_success(token, time_stamp)
|
|
||||||
.expect("start success failure");
|
|
||||||
return Ok((
|
|
||||||
target_id.into(),
|
|
||||||
HkRequest::OneShot(u32::from_be_bytes(
|
|
||||||
tc.user_data()[0..4].try_into().unwrap(),
|
|
||||||
)),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Err(PusPacketHandlingError::InvalidAppData(
|
|
||||||
"unexpected app data".into(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Pus3HandlerWithVecTester {
|
|
||||||
common: PusServiceHandlerWithVecCommon<TestVerificationReporter>,
|
|
||||||
handler: PusService3HkRequestHandler<
|
|
||||||
MpscTcReceiver,
|
|
||||||
TmAsVecSenderWithMpsc,
|
|
||||||
EcssTcInVecConverter,
|
|
||||||
TestVerificationReporter,
|
|
||||||
TestConverter<3>,
|
|
||||||
TestRouter<HkRequest>,
|
|
||||||
>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Pus3HandlerWithVecTester {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let (common, srv_handler) =
|
|
||||||
PusServiceHandlerWithVecCommon::new_with_test_verif_sender();
|
|
||||||
Self {
|
|
||||||
common,
|
|
||||||
handler: PusService3HkRequestHandler::new(
|
|
||||||
srv_handler,
|
|
||||||
TestConverter::default(),
|
|
||||||
TestRouter::default(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate! {
|
|
||||||
to self.handler.request_converter {
|
|
||||||
pub fn check_next_conversion(&mut self, tc: &PusTcCreator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delegate! {
|
|
||||||
to self.handler.request_router {
|
|
||||||
pub fn retrieve_next_request(&mut self) -> (TargetId, HkRequest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delegate! {
|
|
||||||
to self.handler.request_router {
|
|
||||||
pub fn retrieve_next_routing_error(&mut self) -> (TargetId, GenericRoutingError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PusTestHarness for Pus3HandlerWithVecTester {
|
|
||||||
delegate! {
|
|
||||||
to self.common {
|
|
||||||
fn send_tc(&mut self, tc: &PusTcCreator) -> VerificationToken<TcStateAccepted>;
|
|
||||||
fn read_next_tm(&mut self) -> PusTmReader<'_>;
|
|
||||||
fn check_no_tm_available(&self) -> bool;
|
|
||||||
fn check_next_verification_tm(
|
|
||||||
&self,
|
|
||||||
subservice: u8,
|
|
||||||
expected_request_id: RequestId,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl SimplePusPacketHandler for Pus3HandlerWithVecTester {
|
|
||||||
delegate! {
|
|
||||||
to self.handler {
|
|
||||||
fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn basic_test() {
|
|
||||||
let mut hk_handler = Pus3HandlerWithVecTester::new();
|
|
||||||
let mut sp_header = SpHeader::tc(TEST_APID, SequenceFlags::Unsegmented, 0, 0).unwrap();
|
|
||||||
let sec_header = PusTcSecondaryHeader::new_simple(3, Subservice::TcGenerateOneShotHk as u8);
|
|
||||||
let unique_id: u32 = 1;
|
|
||||||
let unique_id_raw = unique_id.to_be_bytes();
|
|
||||||
let tc = PusTcCreator::new(&mut sp_header, sec_header, unique_id_raw.as_ref(), true);
|
|
||||||
hk_handler.send_tc(&tc);
|
|
||||||
let result = hk_handler.handle_one_tc();
|
|
||||||
assert!(result.is_ok());
|
|
||||||
hk_handler.check_next_conversion(&tc);
|
|
||||||
let (target_id, hk_request) = hk_handler.retrieve_next_request();
|
|
||||||
assert_eq!(target_id, TEST_APID.into());
|
|
||||||
if let HkRequest::OneShot(id) = hk_request {
|
|
||||||
assert_eq!(id, unique_id);
|
|
||||||
} else {
|
|
||||||
panic!("unexpected request");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_routing_error() {
|
|
||||||
let mut hk_handler = Pus3HandlerWithVecTester::new();
|
|
||||||
let mut sp_header = SpHeader::tc(TEST_APID, SequenceFlags::Unsegmented, 0, 0).unwrap();
|
|
||||||
let sec_header = PusTcSecondaryHeader::new_simple(3, Subservice::TcGenerateOneShotHk as u8);
|
|
||||||
let unique_id: u32 = 1;
|
|
||||||
let unique_id_raw = unique_id.to_be_bytes();
|
|
||||||
let tc = PusTcCreator::new(&mut sp_header, sec_header, unique_id_raw.as_ref(), true);
|
|
||||||
let error = GenericRoutingError::UnknownTargetId(25);
|
|
||||||
hk_handler
|
|
||||||
.handler
|
|
||||||
.request_router
|
|
||||||
.inject_routing_error(error);
|
|
||||||
hk_handler.send_tc(&tc);
|
|
||||||
let result = hk_handler.handle_one_tc();
|
|
||||||
assert!(result.is_err());
|
|
||||||
let check_error = |routing_error: GenericRoutingError| {
|
|
||||||
if let GenericRoutingError::UnknownTargetId(id) = routing_error {
|
|
||||||
assert_eq!(id, 25);
|
|
||||||
} else {
|
|
||||||
panic!("unexpected error type");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let PusPacketHandlingError::RequestRoutingError(routing_error) = result.unwrap_err() {
|
|
||||||
check_error(routing_error);
|
|
||||||
} else {
|
|
||||||
panic!("unexpected error type");
|
|
||||||
}
|
|
||||||
|
|
||||||
hk_handler.check_next_conversion(&tc);
|
|
||||||
let (target_id, hk_req) = hk_handler.retrieve_next_request();
|
|
||||||
assert_eq!(target_id, TEST_APID.into());
|
|
||||||
if let HkRequest::OneShot(unique_id) = hk_req {
|
|
||||||
assert_eq!(unique_id, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let (target_id, found_error) = hk_handler.retrieve_next_routing_error();
|
|
||||||
assert_eq!(target_id, TEST_APID.into());
|
|
||||||
check_error(found_error);
|
|
||||||
}
|
|
||||||
}
|
|
@ -29,7 +29,6 @@ pub mod event;
|
|||||||
pub mod event_man;
|
pub mod event_man;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub mod event_srv;
|
pub mod event_srv;
|
||||||
pub mod hk;
|
|
||||||
pub mod mode;
|
pub mod mode;
|
||||||
pub mod scheduler;
|
pub mod scheduler;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -44,7 +43,7 @@ pub use alloc_mod::*;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std_mod::*;
|
pub use std_mod::*;
|
||||||
|
|
||||||
use self::verification::{FailParams, TcStateStarted, VerificationReportingProvider};
|
use self::verification::{TcStateStarted, VerificationReportingProvider};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum PusTmWrapper<'tm> {
|
pub enum PusTmWrapper<'tm> {
|
||||||
@ -298,14 +297,14 @@ pub trait ActiveRequestProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ActiveRequest {
|
pub struct ActivePusRequest {
|
||||||
target_id: TargetId,
|
target_id: TargetId,
|
||||||
token: VerificationToken<TcStateStarted>,
|
token: VerificationToken<TcStateStarted>,
|
||||||
start_time: UnixTimestamp,
|
start_time: UnixTimestamp,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActiveRequestProvider for ActiveRequest {
|
impl ActiveRequestProvider for ActivePusRequest {
|
||||||
fn target_id(&self) -> TargetId {
|
fn target_id(&self) -> TargetId {
|
||||||
self.target_id
|
self.target_id
|
||||||
}
|
}
|
||||||
@ -323,30 +322,18 @@ impl ActiveRequestProvider for ActiveRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic user hook method.
|
|
||||||
///
|
|
||||||
/// This hook method currently serves the following tasks:
|
|
||||||
///
|
|
||||||
/// 1. Pass specific information to the reply handlers which can not be kept inside the
|
|
||||||
/// framework. This includes information like the error codes used for packet verification.
|
|
||||||
/// 2. It exposes callback methods which can be useful to perform custom user operations like
|
|
||||||
/// logging.
|
|
||||||
pub trait ReplyHandlerHook<ActiveRequestType, ReplyType> {
|
|
||||||
fn handle_unexpected_reply(&mut self, reply: &GenericMessage<ReplyType>);
|
|
||||||
fn timeout_callback(&self, active_request: &ActiveRequestType);
|
|
||||||
fn timeout_error_code(&self) -> ResultU16;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This trait is an abstraction for the routing of PUS request to a dedicated
|
/// This trait is an abstraction for the routing of PUS request to a dedicated
|
||||||
/// recipient using the generic [TargetId].
|
/// recipient using the generic [TargetId].
|
||||||
pub trait PusRequestRouter<Request> {
|
pub trait PusRequestRouter<Request> {
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
fn route(
|
fn route(
|
||||||
&self,
|
&self,
|
||||||
target_id: TargetId,
|
target_id: TargetId,
|
||||||
hk_request: Request,
|
hk_request: Request,
|
||||||
token: VerificationToken<TcStateAccepted>,
|
token: VerificationToken<TcStateAccepted>,
|
||||||
) -> Result<(), Self::Error>;
|
) -> Result<(), Self::Error>;
|
||||||
|
|
||||||
fn handle_error(
|
fn handle_error(
|
||||||
&self,
|
&self,
|
||||||
target_id: TargetId,
|
target_id: TargetId,
|
||||||
@ -358,6 +345,23 @@ pub trait PusRequestRouter<Request> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait PusReplyHandler<ActiveRequestInfo: ActiveRequestProvider, ReplyType> {
|
||||||
|
type Error;
|
||||||
|
|
||||||
|
fn handle_reply(
|
||||||
|
&mut self,
|
||||||
|
reply: &GenericMessage<ReplyType>,
|
||||||
|
verification_handler: &impl VerificationReportingProvider,
|
||||||
|
tm_sender: &impl EcssTmSenderCore,
|
||||||
|
) -> Result<bool, Self::Error>;
|
||||||
|
|
||||||
|
fn handle_unexpected_reply(
|
||||||
|
&mut self,
|
||||||
|
reply: &GenericMessage<ReplyType>,
|
||||||
|
tm_sender: &impl EcssTmSenderCore,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub mod alloc_mod {
|
pub mod alloc_mod {
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
@ -463,7 +467,7 @@ pub mod alloc_mod {
|
|||||||
///
|
///
|
||||||
/// A [VerificationReportingProvider] instance is passed to the user to also allow handling
|
/// A [VerificationReportingProvider] instance is passed to the user to also allow handling
|
||||||
/// of the verification process as part of the PUS standard requirements.
|
/// of the verification process as part of the PUS standard requirements.
|
||||||
pub trait PusTcToRequestConverter<Request> {
|
pub trait PusTcToRequestConverter<ActiveRequestInfo, Request> {
|
||||||
type Error;
|
type Error;
|
||||||
fn convert(
|
fn convert(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -471,7 +475,7 @@ pub mod alloc_mod {
|
|||||||
tc: &PusTcReader,
|
tc: &PusTcReader,
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
verif_reporter: &impl VerificationReportingProvider,
|
verif_reporter: &impl VerificationReportingProvider,
|
||||||
) -> Result<(TargetId, Request), Self::Error>;
|
) -> Result<(ActiveRequestInfo, Request), Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -513,7 +517,9 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic reply handler structure which can be used to handle replies for a specific PUS service.
|
/*
|
||||||
|
/// Generic reply handler structure which can be used to handle replies for a specific PUS
|
||||||
|
/// service.
|
||||||
///
|
///
|
||||||
/// This is done by keeping track of active requests using an internal map structure. An API
|
/// This is done by keeping track of active requests using an internal map structure. An API
|
||||||
/// to register new active requests is exposed as well.
|
/// to register new active requests is exposed as well.
|
||||||
@ -524,42 +530,35 @@ pub mod alloc_mod {
|
|||||||
/// PUS reply handlers. Concrete PUS handlers should constrain the [ActiveRequestProvider] and
|
/// PUS reply handlers. Concrete PUS handlers should constrain the [ActiveRequestProvider] and
|
||||||
/// the `ReplyType` generics to specific types tailored towards PUS services in addition to
|
/// the `ReplyType` generics to specific types tailored towards PUS services in addition to
|
||||||
/// providing an API which can process received replies and convert them into verification
|
/// providing an API which can process received replies and convert them into verification
|
||||||
/// completions or other operation like user hook calls. The framework also provides some concrete
|
/// completions or other operation like user hook calls. The framework also provides some
|
||||||
/// PUS handlers for common PUS services like the mode, action and housekeeping service.
|
/// concrete PUS handlers for common PUS services like the mode, action and housekeeping
|
||||||
|
/// service.
|
||||||
///
|
///
|
||||||
/// This object does not automatically update its internal time information used to check for
|
/// This object does not automatically update its internal time information used to check for
|
||||||
/// timeouts. The user should call the [Self::update_time] and [Self::update_time_from_now] methods
|
/// timeouts. The user should call the [Self::update_time] and [Self::update_time_from_now]
|
||||||
/// to do this.
|
/// methods to do this.
|
||||||
pub struct PusServiceReplyHandler<
|
pub struct PusServiceReplyHandler<
|
||||||
VerificationReporter: VerificationReportingProvider,
|
|
||||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestType>,
|
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestType>,
|
||||||
UserHook: ReplyHandlerHook<ActiveRequestType, ReplyType>,
|
ReplyHook: ReplyHandlerHook<ActiveRequestType, ReplyType>,
|
||||||
TmSender: EcssTmSenderCore,
|
|
||||||
ActiveRequestType: ActiveRequestProvider,
|
ActiveRequestType: ActiveRequestProvider,
|
||||||
ReplyType,
|
ReplyType,
|
||||||
> {
|
> {
|
||||||
pub active_request_map: ActiveRequestMap,
|
pub active_request_map: ActiveRequestMap,
|
||||||
pub verification_reporter: VerificationReporter,
|
|
||||||
pub tm_buf: alloc::vec::Vec<u8>,
|
pub tm_buf: alloc::vec::Vec<u8>,
|
||||||
pub current_time: UnixTimestamp,
|
pub current_time: UnixTimestamp,
|
||||||
pub user_hook: UserHook,
|
pub user_hook: ReplyHook,
|
||||||
pub tm_sender: TmSender,
|
|
||||||
phantom: PhantomData<(ActiveRequestType, ReplyType)>,
|
phantom: PhantomData<(ActiveRequestType, ReplyType)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
VerificationReporter: VerificationReportingProvider,
|
|
||||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestType>,
|
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestType>,
|
||||||
UserHook: ReplyHandlerHook<ActiveRequestType, ReplyType>,
|
ReplyHook: ReplyHandlerHook<ActiveRequestType, ReplyType>,
|
||||||
TmSender: EcssTmSenderCore,
|
|
||||||
ActiveRequestType: ActiveRequestProvider,
|
ActiveRequestType: ActiveRequestProvider,
|
||||||
ReplyType,
|
ReplyType,
|
||||||
>
|
>
|
||||||
PusServiceReplyHandler<
|
PusServiceReplyHandler<
|
||||||
VerificationReporter,
|
|
||||||
ActiveRequestMap,
|
ActiveRequestMap,
|
||||||
UserHook,
|
ReplyHook,
|
||||||
TmSender,
|
|
||||||
ActiveRequestType,
|
ActiveRequestType,
|
||||||
ReplyType,
|
ReplyType,
|
||||||
>
|
>
|
||||||
@ -567,15 +566,12 @@ pub mod alloc_mod {
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||||
pub fn new_from_now(
|
pub fn new_from_now(
|
||||||
verification_reporter: VerificationReporter,
|
|
||||||
active_request_map: ActiveRequestMap,
|
active_request_map: ActiveRequestMap,
|
||||||
fail_data_buf_size: usize,
|
fail_data_buf_size: usize,
|
||||||
user_hook: UserHook,
|
user_hook: ReplyHook,
|
||||||
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(
|
||||||
verification_reporter,
|
|
||||||
active_request_map,
|
active_request_map,
|
||||||
fail_data_buf_size,
|
fail_data_buf_size,
|
||||||
user_hook,
|
user_hook,
|
||||||
@ -585,16 +581,14 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
verification_reporter: VerificationReporter,
|
|
||||||
active_request_map: ActiveRequestMap,
|
active_request_map: ActiveRequestMap,
|
||||||
fail_data_buf_size: usize,
|
fail_data_buf_size: usize,
|
||||||
user_hook: UserHook,
|
user_hook: ReplyHook,
|
||||||
tm_sender: TmSender,
|
tm_sender: TmSender,
|
||||||
init_time: UnixTimestamp,
|
init_time: UnixTimestamp,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
active_request_map,
|
active_request_map,
|
||||||
verification_reporter,
|
|
||||||
tm_buf: alloc::vec![0; fail_data_buf_size],
|
tm_buf: alloc::vec![0; fail_data_buf_size],
|
||||||
current_time: init_time,
|
current_time: init_time,
|
||||||
user_hook,
|
user_hook,
|
||||||
@ -668,6 +662,7 @@ pub mod alloc_mod {
|
|||||||
self.current_time = time;
|
self.current_time = time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -684,13 +679,10 @@ 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};
|
||||||
use spacepackets::time::cds::TimeProvider;
|
|
||||||
use spacepackets::time::StdTimestampError;
|
use spacepackets::time::StdTimestampError;
|
||||||
use spacepackets::time::TimeWriter;
|
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::mpsc::TryRecvError;
|
use std::sync::mpsc::TryRecvError;
|
||||||
@ -700,7 +692,7 @@ pub mod std_mod {
|
|||||||
pub use cb_mod::*;
|
pub use cb_mod::*;
|
||||||
|
|
||||||
use super::verification::VerificationReportingProvider;
|
use super::verification::VerificationReportingProvider;
|
||||||
use super::{AcceptedEcssTcAndToken, PusRequestRouter, PusTcToRequestConverter, TcInMemory};
|
use super::{AcceptedEcssTcAndToken, 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 {
|
||||||
@ -974,17 +966,18 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a high-level handler for the PUS service 8 action service.
|
/// This is a high-level handler for the generic PUS services which need to convert PUS
|
||||||
|
/// commands into a request/reply pattern.
|
||||||
///
|
///
|
||||||
/// It performs the following handling steps:
|
/// It performs the following handling steps:
|
||||||
///
|
///
|
||||||
/// 1. Retrieve the next TC packet from the [PusServiceHelper]. The [EcssTcInMemConverter]
|
/// 1. Retrieve the next TC packet from the [PusServiceHelper]. The [EcssTcInMemConverter]
|
||||||
/// allows to configure the used telecommand memory backend.
|
/// allows to configure the used telecommand memory backend.
|
||||||
/// 2. Convert the TC to a targeted action request using the provided
|
/// 2. Convert the TC to a targeted action request using the provided
|
||||||
/// [PusActionToRequestConverter]. The generic error type is constrained to the
|
/// [PusTcToRequestConverter]. The generic error type is constrained to the
|
||||||
/// [PusPacketHandlingError] for the concrete implementation which offers a packet handler.
|
/// [PusPacketHandlingError] for the concrete implementation which offers a packet handler.
|
||||||
/// 3. Route the action request using the provided [PusActionRequestRouter].
|
/// 3. Route the action request using the provided [PusRequestRouter].
|
||||||
/// 4. Handle all routing errors using the provided [PusRoutingErrorHandler].
|
/*
|
||||||
pub struct PusTargetedRequestHandler<
|
pub struct PusTargetedRequestHandler<
|
||||||
TcReceiver: EcssTcReceiverCore,
|
TcReceiver: EcssTcReceiverCore,
|
||||||
TmSender: EcssTmSenderCore,
|
TmSender: EcssTmSenderCore,
|
||||||
@ -999,10 +992,12 @@ pub mod std_mod {
|
|||||||
PusServiceHelper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
PusServiceHelper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
||||||
pub request_converter: RequestConverter,
|
pub request_converter: RequestConverter,
|
||||||
pub request_router: RequestRouter,
|
pub request_router: RequestRouter,
|
||||||
// pub routing_error_handler: RoutingErrorHandler,
|
|
||||||
phantom: PhantomData<Request>,
|
phantom: PhantomData<Request>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pub trait PusReplyHandlerProvider {
|
||||||
|
// fn add_routed_request(&mut self, request_id: RequestId, active_request: ActiveRequest);
|
||||||
|
// }
|
||||||
impl<
|
impl<
|
||||||
TcReceiver: EcssTcReceiverCore,
|
TcReceiver: EcssTcReceiverCore,
|
||||||
TmSender: EcssTmSenderCore,
|
TmSender: EcssTmSenderCore,
|
||||||
@ -1010,7 +1005,6 @@ pub mod std_mod {
|
|||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
RequestConverter: PusTcToRequestConverter<Request, Error = PusPacketHandlingError>,
|
RequestConverter: PusTcToRequestConverter<Request, Error = PusPacketHandlingError>,
|
||||||
RequestRouter: PusRequestRouter<Request, Error = RoutingError>,
|
RequestRouter: PusRequestRouter<Request, Error = RoutingError>,
|
||||||
// RoutingErrorHandler: PusRoutingErrorHandler<Error = RoutingError>,
|
|
||||||
Request,
|
Request,
|
||||||
RoutingError: Clone,
|
RoutingError: Clone,
|
||||||
>
|
>
|
||||||
@ -1021,7 +1015,6 @@ pub mod std_mod {
|
|||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
RequestConverter,
|
RequestConverter,
|
||||||
RequestRouter,
|
RequestRouter,
|
||||||
// RoutingErrorHandler,
|
|
||||||
Request,
|
Request,
|
||||||
RoutingError,
|
RoutingError,
|
||||||
>
|
>
|
||||||
@ -1042,7 +1035,6 @@ pub mod std_mod {
|
|||||||
service_helper,
|
service_helper,
|
||||||
request_converter,
|
request_converter,
|
||||||
request_router,
|
request_router,
|
||||||
// routing_error_handler,
|
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1083,7 +1075,7 @@ pub mod std_mod {
|
|||||||
Ok(PusPacketHandlerResult::RequestHandled)
|
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 .
|
||||||
@ -1272,26 +1264,6 @@ pub mod std_mod {
|
|||||||
pub tm_apid: u16,
|
pub tm_apid: u16,
|
||||||
pub verification_handler: VerificationReporter,
|
pub verification_handler: VerificationReporter,
|
||||||
}
|
}
|
||||||
#[cfg(feature = "std")]
|
|
||||||
pub fn get_current_cds_short_timestamp(
|
|
||||||
partial_error: &mut Option<PartialPusHandlingError>,
|
|
||||||
) -> [u8; 7] {
|
|
||||||
let mut time_stamp: [u8; 7] = [0; 7];
|
|
||||||
let time_provider =
|
|
||||||
TimeProvider::from_now_with_u16_days().map_err(PartialPusHandlingError::Time);
|
|
||||||
if let Ok(time_provider) = time_provider {
|
|
||||||
// Can't fail, we have a buffer with the exact required size.
|
|
||||||
time_provider.write_to_bytes(&mut time_stamp).unwrap();
|
|
||||||
} else {
|
|
||||||
*partial_error = Some(time_provider.unwrap_err());
|
|
||||||
}
|
|
||||||
time_stamp
|
|
||||||
}
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
pub fn get_current_timestamp_ignore_error() -> [u8; 7] {
|
|
||||||
let mut dummy = None;
|
|
||||||
get_current_cds_short_timestamp(&mut dummy)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is a high-level PUS packet handler helper.
|
/// This is a high-level PUS packet handler helper.
|
||||||
///
|
///
|
||||||
|
@ -43,45 +43,25 @@ pub mod std_mod {
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
mode::{GenericModeReply, ModeRequest},
|
mode::GenericModeReply,
|
||||||
pus::{
|
pus::{
|
||||||
mode::Subservice,
|
mode::Subservice,
|
||||||
verification::{
|
verification::{
|
||||||
self, FailParams, TcStateStarted, VerificationReportingProvider, VerificationToken,
|
self, FailParams, TcStateStarted, VerificationReportingProvider, VerificationToken,
|
||||||
},
|
},
|
||||||
ActiveRequest, ActiveRequestMapProvider, EcssTmSenderCore, EcssTmtcError,
|
ActivePusRequest, ActiveRequestMapProvider, EcssTmSenderCore, EcssTmtcError,
|
||||||
GenericRoutingError, PusServiceReplyHandler, PusTargetedRequestHandler, PusTmWrapper,
|
PusServiceReplyHandler, PusTmWrapper, ReplyHandlerHook,
|
||||||
ReplyHandlerHook,
|
|
||||||
},
|
},
|
||||||
TargetId,
|
TargetId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait ModeReplyHook: ReplyHandlerHook<ActiveRequest, ModeReply> {
|
pub trait ModeReplyHook: ReplyHandlerHook<ActivePusRequest, ModeReply> {
|
||||||
fn wrong_mode_result_code(&self) -> ResultU16;
|
fn wrong_mode_result_code(&self) -> ResultU16;
|
||||||
fn can_not_reach_mode_result_code(&self) -> ResultU16;
|
fn can_not_reach_mode_result_code(&self) -> ResultU16;
|
||||||
}
|
}
|
||||||
|
|
||||||
use super::{ModeReply, MODE_SERVICE_ID};
|
use super::{ModeReply, MODE_SERVICE_ID};
|
||||||
|
|
||||||
pub type PusModeServiceRequestHandler<
|
|
||||||
TcReceiver,
|
|
||||||
TmSender,
|
|
||||||
TcInMemConverter,
|
|
||||||
VerificationReporter,
|
|
||||||
RequestConverter,
|
|
||||||
RequestRouter,
|
|
||||||
RoutingError = GenericRoutingError,
|
|
||||||
> = PusTargetedRequestHandler<
|
|
||||||
TcReceiver,
|
|
||||||
TmSender,
|
|
||||||
TcInMemConverter,
|
|
||||||
VerificationReporter,
|
|
||||||
RequestConverter,
|
|
||||||
RequestRouter,
|
|
||||||
ModeRequest,
|
|
||||||
RoutingError,
|
|
||||||
>;
|
|
||||||
|
|
||||||
/// Type definition for a PUS mode servicd reply handler which constrains the
|
/// Type definition for a PUS mode servicd 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.
|
||||||
@ -95,13 +75,13 @@ pub mod std_mod {
|
|||||||
ActiveRequestMap,
|
ActiveRequestMap,
|
||||||
UserHook,
|
UserHook,
|
||||||
TmSender,
|
TmSender,
|
||||||
ActiveRequest,
|
ActivePusRequest,
|
||||||
ModeReply,
|
ModeReply,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequest>,
|
ActiveRequestMap: ActiveRequestMapProvider<ActivePusRequest>,
|
||||||
UserHook: ModeReplyHook,
|
UserHook: ModeReplyHook,
|
||||||
TmSender: EcssTmSenderCore,
|
TmSender: EcssTmSenderCore,
|
||||||
> PusModeServiceReplyHandler<VerificationReporter, ActiveRequestMap, UserHook, TmSender>
|
> PusModeServiceReplyHandler<VerificationReporter, ActiveRequestMap, UserHook, TmSender>
|
||||||
@ -116,7 +96,7 @@ pub mod std_mod {
|
|||||||
) {
|
) {
|
||||||
self.active_request_map.insert(
|
self.active_request_map.insert(
|
||||||
&request_id.into(),
|
&request_id.into(),
|
||||||
ActiveRequest {
|
ActivePusRequest {
|
||||||
target_id,
|
target_id,
|
||||||
token,
|
token,
|
||||||
start_time: self.current_time,
|
start_time: self.current_time,
|
||||||
|
@ -5,10 +5,9 @@ use super::verification::{
|
|||||||
VerificationReporterWithVecMpscSender, VerificationReportingProvider,
|
VerificationReporterWithVecMpscSender, VerificationReportingProvider,
|
||||||
};
|
};
|
||||||
use super::{
|
use super::{
|
||||||
get_current_cds_short_timestamp, EcssTcInMemConverter, EcssTcInSharedStoreConverter,
|
EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTcReceiverCore,
|
||||||
EcssTcInVecConverter, EcssTcReceiverCore, EcssTmSenderCore, MpscTcReceiver, PusServiceHelper,
|
EcssTmSenderCore, MpscTcReceiver, PusServiceHelper, TmAsVecSenderWithBoundedMpsc,
|
||||||
TmAsVecSenderWithBoundedMpsc, TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc,
|
TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithMpsc,
|
||||||
TmInSharedPoolSenderWithMpsc,
|
|
||||||
};
|
};
|
||||||
use crate::pool::PoolProvider;
|
use crate::pool::PoolProvider;
|
||||||
use crate::pus::{PusPacketHandlerResult, PusPacketHandlingError};
|
use crate::pus::{PusPacketHandlerResult, PusPacketHandlingError};
|
||||||
@ -76,6 +75,7 @@ impl<
|
|||||||
|
|
||||||
pub fn handle_one_tc(
|
pub fn handle_one_tc(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
time_stamp: &[u8],
|
||||||
sched_tc_pool: &mut (impl PoolProvider + ?Sized),
|
sched_tc_pool: &mut (impl PoolProvider + ?Sized),
|
||||||
) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
||||||
let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?;
|
let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?;
|
||||||
@ -95,15 +95,14 @@ impl<
|
|||||||
ecss_tc_and_token.token,
|
ecss_tc_and_token.token,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let mut partial_error = None;
|
let partial_error = None;
|
||||||
let time_stamp = get_current_cds_short_timestamp(&mut partial_error);
|
|
||||||
match standard_subservice.unwrap() {
|
match standard_subservice.unwrap() {
|
||||||
scheduling::Subservice::TcEnableScheduling => {
|
scheduling::Subservice::TcEnableScheduling => {
|
||||||
let start_token = self
|
let start_token = self
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verification_handler
|
||||||
.start_success(ecss_tc_and_token.token, &time_stamp)
|
.start_success(ecss_tc_and_token.token, time_stamp)
|
||||||
.expect("Error sending start success");
|
.expect("Error sending start success");
|
||||||
|
|
||||||
self.scheduler.enable();
|
self.scheduler.enable();
|
||||||
@ -111,7 +110,7 @@ impl<
|
|||||||
self.service_helper
|
self.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verification_handler
|
||||||
.completion_success(start_token, &time_stamp)
|
.completion_success(start_token, time_stamp)
|
||||||
.expect("Error sending completion success");
|
.expect("Error sending completion success");
|
||||||
} else {
|
} else {
|
||||||
return Err(PusPacketHandlingError::Other(
|
return Err(PusPacketHandlingError::Other(
|
||||||
@ -124,7 +123,7 @@ impl<
|
|||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verification_handler
|
||||||
.start_success(ecss_tc_and_token.token, &time_stamp)
|
.start_success(ecss_tc_and_token.token, time_stamp)
|
||||||
.expect("Error sending start success");
|
.expect("Error sending start success");
|
||||||
|
|
||||||
self.scheduler.disable();
|
self.scheduler.disable();
|
||||||
@ -132,7 +131,7 @@ impl<
|
|||||||
self.service_helper
|
self.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verification_handler
|
||||||
.completion_success(start_token, &time_stamp)
|
.completion_success(start_token, time_stamp)
|
||||||
.expect("Error sending completion success");
|
.expect("Error sending completion success");
|
||||||
} else {
|
} else {
|
||||||
return Err(PusPacketHandlingError::Other(
|
return Err(PusPacketHandlingError::Other(
|
||||||
@ -145,7 +144,7 @@ impl<
|
|||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verification_handler
|
||||||
.start_success(ecss_tc_and_token.token, &time_stamp)
|
.start_success(ecss_tc_and_token.token, time_stamp)
|
||||||
.expect("Error sending start success");
|
.expect("Error sending start success");
|
||||||
|
|
||||||
self.scheduler
|
self.scheduler
|
||||||
@ -155,7 +154,7 @@ impl<
|
|||||||
self.service_helper
|
self.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verification_handler
|
||||||
.completion_success(start_token, &time_stamp)
|
.completion_success(start_token, time_stamp)
|
||||||
.expect("Error sending completion success");
|
.expect("Error sending completion success");
|
||||||
}
|
}
|
||||||
scheduling::Subservice::TcInsertActivity => {
|
scheduling::Subservice::TcInsertActivity => {
|
||||||
@ -163,7 +162,7 @@ impl<
|
|||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verification_handler
|
||||||
.start_success(ecss_tc_and_token.token, &time_stamp)
|
.start_success(ecss_tc_and_token.token, time_stamp)
|
||||||
.expect("error sending start success");
|
.expect("error sending start success");
|
||||||
|
|
||||||
// let mut pool = self.sched_tc_pool.write().expect("locking pool failed");
|
// let mut pool = self.sched_tc_pool.write().expect("locking pool failed");
|
||||||
@ -174,7 +173,7 @@ impl<
|
|||||||
self.service_helper
|
self.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verification_handler
|
||||||
.completion_success(start_token, &time_stamp)
|
.completion_success(start_token, time_stamp)
|
||||||
.expect("sending completion success failed");
|
.expect("sending completion success failed");
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@ -241,7 +240,10 @@ mod tests {
|
|||||||
verification::{RequestId, TcStateAccepted, VerificationToken},
|
verification::{RequestId, TcStateAccepted, VerificationToken},
|
||||||
EcssTcInSharedStoreConverter,
|
EcssTcInSharedStoreConverter,
|
||||||
};
|
};
|
||||||
use crate::pus::{MpscTcReceiver, TmInSharedPoolSenderWithBoundedMpsc};
|
use crate::pus::{
|
||||||
|
MpscTcReceiver, PusPacketHandlerResult, PusPacketHandlingError,
|
||||||
|
TmInSharedPoolSenderWithBoundedMpsc,
|
||||||
|
};
|
||||||
use alloc::collections::VecDeque;
|
use alloc::collections::VecDeque;
|
||||||
use delegate::delegate;
|
use delegate::delegate;
|
||||||
use spacepackets::ecss::scheduling::Subservice;
|
use spacepackets::ecss::scheduling::Subservice;
|
||||||
@ -280,6 +282,12 @@ mod tests {
|
|||||||
sched_tc_pool,
|
sched_tc_pool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
||||||
|
let time_stamp = cds::TimeProvider::new_with_u16_days(0, 0).to_vec().unwrap();
|
||||||
|
self.handler
|
||||||
|
.handle_one_tc(&time_stamp, &mut self.sched_tc_pool)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PusTestHarness for Pus11HandlerWithStoreTester {
|
impl PusTestHarness for Pus11HandlerWithStoreTester {
|
||||||
@ -347,9 +355,10 @@ mod tests {
|
|||||||
let token = test_harness.send_tc(&enable_scheduling);
|
let token = test_harness.send_tc(&enable_scheduling);
|
||||||
|
|
||||||
let request_id = token.req_id();
|
let request_id = token.req_id();
|
||||||
|
let time_stamp = cds::TimeProvider::new_with_u16_days(0, 0).to_vec().unwrap();
|
||||||
test_harness
|
test_harness
|
||||||
.handler
|
.handler
|
||||||
.handle_one_tc(&mut test_harness.sched_tc_pool)
|
.handle_one_tc(&time_stamp, &mut test_harness.sched_tc_pool)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
test_harness.check_next_verification_tm(1, request_id);
|
test_harness.check_next_verification_tm(1, request_id);
|
||||||
test_harness.check_next_verification_tm(3, request_id);
|
test_harness.check_next_verification_tm(3, request_id);
|
||||||
@ -407,10 +416,7 @@ mod tests {
|
|||||||
let token = test_harness.send_tc(&enable_scheduling);
|
let token = test_harness.send_tc(&enable_scheduling);
|
||||||
|
|
||||||
let request_id = token.req_id();
|
let request_id = token.req_id();
|
||||||
test_harness
|
test_harness.handle_one_tc().unwrap();
|
||||||
.handler
|
|
||||||
.handle_one_tc(&mut test_harness.sched_tc_pool)
|
|
||||||
.unwrap();
|
|
||||||
test_harness.check_next_verification_tm(1, request_id);
|
test_harness.check_next_verification_tm(1, request_id);
|
||||||
test_harness.check_next_verification_tm(3, request_id);
|
test_harness.check_next_verification_tm(3, request_id);
|
||||||
test_harness.check_next_verification_tm(7, request_id);
|
test_harness.check_next_verification_tm(7, request_id);
|
||||||
|
@ -11,10 +11,9 @@ use super::verification::{
|
|||||||
VerificationReporterWithVecMpscSender, VerificationReportingProvider,
|
VerificationReporterWithVecMpscSender, VerificationReportingProvider,
|
||||||
};
|
};
|
||||||
use super::{
|
use super::{
|
||||||
get_current_cds_short_timestamp, EcssTcInMemConverter, EcssTcInSharedStoreConverter,
|
EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTcReceiverCore,
|
||||||
EcssTcInVecConverter, EcssTcReceiverCore, EcssTmSenderCore, MpscTcReceiver, PusServiceHelper,
|
EcssTmSenderCore, MpscTcReceiver, PusServiceHelper, TmAsVecSenderWithBoundedMpsc,
|
||||||
TmAsVecSenderWithBoundedMpsc, TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc,
|
TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithMpsc,
|
||||||
TmInSharedPoolSenderWithMpsc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This is a helper class for [std] environments to handle generic PUS 17 (test service) packets.
|
/// This is a helper class for [std] environments to handle generic PUS 17 (test service) packets.
|
||||||
@ -47,7 +46,10 @@ impl<
|
|||||||
Self { service_helper }
|
Self { service_helper }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
pub fn handle_one_tc(
|
||||||
|
&mut self,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
||||||
let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?;
|
let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?;
|
||||||
if possible_packet.is_none() {
|
if possible_packet.is_none() {
|
||||||
return Ok(PusPacketHandlerResult::Empty);
|
return Ok(PusPacketHandlerResult::Empty);
|
||||||
@ -62,12 +64,11 @@ impl<
|
|||||||
}
|
}
|
||||||
if tc.subservice() == 1 {
|
if tc.subservice() == 1 {
|
||||||
let mut partial_error = None;
|
let mut partial_error = None;
|
||||||
let time_stamp = get_current_cds_short_timestamp(&mut partial_error);
|
|
||||||
let result = self
|
let result = self
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verification_handler
|
||||||
.start_success(ecss_tc_and_token.token, &time_stamp)
|
.start_success(ecss_tc_and_token.token, time_stamp)
|
||||||
.map_err(|_| PartialPusHandlingError::Verification);
|
.map_err(|_| PartialPusHandlingError::Verification);
|
||||||
let start_token = if let Ok(result) = result {
|
let start_token = if let Ok(result) = result {
|
||||||
Some(result)
|
Some(result)
|
||||||
@ -78,7 +79,7 @@ impl<
|
|||||||
// Sequence count will be handled centrally in TM funnel.
|
// Sequence count will be handled centrally in TM funnel.
|
||||||
let mut reply_header =
|
let mut reply_header =
|
||||||
SpHeader::tm_unseg(self.service_helper.common.tm_apid, 0, 0).unwrap();
|
SpHeader::tm_unseg(self.service_helper.common.tm_apid, 0, 0).unwrap();
|
||||||
let tc_header = PusTmSecondaryHeader::new_simple(17, 2, &time_stamp);
|
let tc_header = PusTmSecondaryHeader::new_simple(17, 2, time_stamp);
|
||||||
let ping_reply = PusTmCreator::new(&mut reply_header, tc_header, &[], true);
|
let ping_reply = PusTmCreator::new(&mut reply_header, tc_header, &[], true);
|
||||||
let result = self
|
let result = self
|
||||||
.service_helper
|
.service_helper
|
||||||
@ -95,7 +96,7 @@ impl<
|
|||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verification_handler
|
||||||
.completion_success(start_token, &time_stamp)
|
.completion_success(start_token, time_stamp)
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
partial_error = Some(PartialPusHandlingError::Verification)
|
partial_error = Some(PartialPusHandlingError::Verification)
|
||||||
@ -168,6 +169,7 @@ mod tests {
|
|||||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader};
|
use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader};
|
||||||
use spacepackets::ecss::tm::PusTmReader;
|
use spacepackets::ecss::tm::PusTmReader;
|
||||||
use spacepackets::ecss::PusPacket;
|
use spacepackets::ecss::PusPacket;
|
||||||
|
use spacepackets::time::{cds, TimeWriter};
|
||||||
use spacepackets::{SequenceFlags, SpHeader};
|
use spacepackets::{SequenceFlags, SpHeader};
|
||||||
|
|
||||||
use super::PusService17TestHandler;
|
use super::PusService17TestHandler;
|
||||||
@ -208,10 +210,9 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl SimplePusPacketHandler for Pus17HandlerWithStoreTester {
|
impl SimplePusPacketHandler for Pus17HandlerWithStoreTester {
|
||||||
delegate! {
|
fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
||||||
to self.handler {
|
let time_stamp = cds::TimeProvider::new_with_u16_days(0, 0).to_vec().unwrap();
|
||||||
fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError>;
|
self.handler.handle_one_tc(&time_stamp)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,10 +252,9 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl SimplePusPacketHandler for Pus17HandlerWithVecTester {
|
impl SimplePusPacketHandler for Pus17HandlerWithVecTester {
|
||||||
delegate! {
|
fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
||||||
to self.handler {
|
let time_stamp = cds::TimeProvider::new_with_u16_days(0, 0).to_vec().unwrap();
|
||||||
fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError>;
|
self.handler.handle_one_tc(&time_stamp)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
satrs/src/time.rs
Normal file
7
satrs/src/time.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
use core::fmt::Debug;
|
||||||
|
|
||||||
|
/// Generic abstraction for a check/countdown timer.
|
||||||
|
pub trait CountdownProvider: Debug {
|
||||||
|
fn has_expired(&self) -> bool;
|
||||||
|
fn reset(&mut self);
|
||||||
|
}
|
148
satrs/tests/pus_targeted_request.rs
Normal file
148
satrs/tests/pus_targeted_request.rs
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
use std::sync::mpsc;
|
||||||
|
|
||||||
|
use satrs::{
|
||||||
|
pus::{
|
||||||
|
verification::{
|
||||||
|
TcStateAccepted, VerificationReporterCfg, VerificationReporterWithVecMpscSender,
|
||||||
|
VerificationReportingProvider, VerificationToken,
|
||||||
|
},
|
||||||
|
ActivePusRequest, DefaultActiveRequestMap, EcssTcInVecConverter, PusRequestRouter,
|
||||||
|
PusServiceReplyHandler, PusTargetedRequestHandler, PusTcToRequestConverter,
|
||||||
|
ReplyHandlerHook, TmAsVecSenderWithId,
|
||||||
|
},
|
||||||
|
TargetId,
|
||||||
|
};
|
||||||
|
use spacepackets::{
|
||||||
|
ecss::{tc::PusTcReader, PusPacket},
|
||||||
|
CcsdsPacket,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
|
pub enum DummyRequest {
|
||||||
|
Ping,
|
||||||
|
WithParam(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
|
pub enum DummyReply {
|
||||||
|
Pong,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DummyRequestConverter {}
|
||||||
|
|
||||||
|
impl PusTcToRequestConverter<DummyRequest> for DummyRequestRouter {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn convert(
|
||||||
|
&mut self,
|
||||||
|
token: VerificationToken<TcStateAccepted>,
|
||||||
|
tc: &PusTcReader,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
verif_reporter: &impl VerificationReportingProvider,
|
||||||
|
) -> Result<(TargetId, DummyRequest), Self::Error> {
|
||||||
|
if tc.service() == 205 && tc.subservice() == 1 {
|
||||||
|
return Ok((tc.apid().into(), DummyRequest::Ping));
|
||||||
|
}
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DummyRequestRouter {
|
||||||
|
dummy_1_sender: mpsc::Sender<DummyRequest>,
|
||||||
|
dummy_2_sender: mpsc::Sender<DummyRequest>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PusRequestRouter<DummyRequest> for DummyRequestRouter {
|
||||||
|
type Error = ();
|
||||||
|
fn route(
|
||||||
|
&self,
|
||||||
|
target_id: TargetId,
|
||||||
|
request: DummyRequest,
|
||||||
|
token: VerificationToken<TcStateAccepted>,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
if target_id == DummyTargetId::Object1 as u64 {
|
||||||
|
self.dummy_1_sender.send(request).ok();
|
||||||
|
} else {
|
||||||
|
self.dummy_2_sender.send(request).ok();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_error(
|
||||||
|
&self,
|
||||||
|
target_id: TargetId,
|
||||||
|
token: VerificationToken<TcStateAccepted>,
|
||||||
|
tc: &PusTcReader,
|
||||||
|
error: Self::Error,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
verif_reporter: &impl VerificationReportingProvider,
|
||||||
|
) {
|
||||||
|
panic!("routing error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct DummyReplyUserHook {}
|
||||||
|
|
||||||
|
impl ReplyHandlerHook<ActivePusRequest, DummyReply> for DummyReplyUserHook {
|
||||||
|
fn handle_unexpected_reply(&mut self, reply: &satrs::request::GenericMessage<DummyReply>) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn timeout_callback(&self, active_request: &ActivePusRequest) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn timeout_error_code(&self) -> satrs_shared::res_code::ResultU16 {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type PusDummyRequestHandler = PusTargetedRequestHandler<
|
||||||
|
mpsc::Sender<Vec<u8>>,
|
||||||
|
mpsc::Sender<Vec<u8>>,
|
||||||
|
EcssTcInVecConverter,
|
||||||
|
VerificationReporterWithVecMpscSender,
|
||||||
|
DummyRequestConverter,
|
||||||
|
DummyRequestRouter,
|
||||||
|
DummyRequest,
|
||||||
|
>;
|
||||||
|
pub type PusDummyReplyHandler = PusServiceReplyHandler<
|
||||||
|
VerificationReporterWithVecMpscSender,
|
||||||
|
DefaultActiveRequestMap<ActivePusRequest>,
|
||||||
|
DummyReplyUserHook,
|
||||||
|
mpsc::Sender<Vec<u8>>,
|
||||||
|
ActivePusRequest,
|
||||||
|
DummyReply,
|
||||||
|
>;
|
||||||
|
const TEST_APID: u16 = 5;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
|
pub enum DummyTargetId {
|
||||||
|
Object1 = 1,
|
||||||
|
Object2 = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum DummyChannelId {
|
||||||
|
Router = 1,
|
||||||
|
Object1 = 2,
|
||||||
|
Object2 = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let reporter_cfg = VerificationReporterCfg::new(TEST_APID, 2, 2, 256).unwrap();
|
||||||
|
let (tm_sender, tm_receiver) = mpsc::channel();
|
||||||
|
let tm_sender_with_wrapper =
|
||||||
|
TmAsVecSenderWithId::new(DummyChannelId::Router as u32, "ROUTER", tm_sender.clone());
|
||||||
|
let verification_handler =
|
||||||
|
VerificationReporterWithVecMpscSender::new(&reporter_cfg, tm_sender_with_wrapper);
|
||||||
|
|
||||||
|
// let dummy_request_handler = PusDummyRequestHandler::new()
|
||||||
|
let dummy_reply_handler = PusDummyReplyHandler::new_from_now(
|
||||||
|
verification_handler,
|
||||||
|
DefaultActiveRequestMap::default(),
|
||||||
|
256,
|
||||||
|
DummyReplyUserHook::default(),
|
||||||
|
tm_sender.clone(),
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user