Request and Reply Messaging Abstraction and first Consumers #136
@ -1,7 +1,10 @@
|
|||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
use satrs::action::{ActionRequest, ActionRequestVariant};
|
use satrs::action::{ActionRequest, ActionRequestVariant};
|
||||||
use satrs::pool::{SharedStaticMemoryPool, StoreAddr};
|
use satrs::pool::{SharedStaticMemoryPool, StoreAddr};
|
||||||
use satrs::pus::action::PusService8ActionRequestHandler;
|
use satrs::pus::action::{
|
||||||
|
ActionReplyPusWithActionId, ActiveActionRequest, DefaultActiveActionRequestMap,
|
||||||
|
PusService8ActionRequestHandler, PusService8ReplyHandler,
|
||||||
|
};
|
||||||
use satrs::pus::verification::{
|
use satrs::pus::verification::{
|
||||||
FailParams, TcStateAccepted, VerificationReporterWithSharedPoolMpscBoundedSender,
|
FailParams, TcStateAccepted, VerificationReporterWithSharedPoolMpscBoundedSender,
|
||||||
VerificationReporterWithVecMpscSender, VerificationReportingProvider, VerificationToken,
|
VerificationReporterWithVecMpscSender, VerificationReportingProvider, VerificationToken,
|
||||||
@ -9,8 +12,9 @@ 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, TmAsVecSenderWithId,
|
PusPacketHandlingError, PusServiceHelper, PusTcToRequestConverter, ReplyHandlerHook,
|
||||||
TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
TmAsVecSenderWithId, TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc,
|
||||||
|
TmInSharedPoolSenderWithId,
|
||||||
};
|
};
|
||||||
use satrs::request::TargetAndApidId;
|
use satrs::request::TargetAndApidId;
|
||||||
use satrs::spacepackets::ecss::tc::PusTcReader;
|
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||||
@ -22,8 +26,6 @@ use std::sync::mpsc::{self};
|
|||||||
|
|
||||||
use crate::requests::GenericRequestRouter;
|
use crate::requests::GenericRequestRouter;
|
||||||
|
|
||||||
use super::GenericRoutingErrorHandler;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ExampleActionRequestConverter {}
|
pub struct ExampleActionRequestConverter {}
|
||||||
|
|
||||||
@ -97,19 +99,29 @@ pub fn create_action_service_static(
|
|||||||
"PUS_8_TC_RECV",
|
"PUS_8_TC_RECV",
|
||||||
pus_action_rx,
|
pus_action_rx,
|
||||||
);
|
);
|
||||||
let pus_8_handler = PusService8ActionRequestHandler::new(
|
let action_request_handler = PusService8ActionRequestHandler::new(
|
||||||
PusServiceHelper::new(
|
PusServiceHelper::new(
|
||||||
action_srv_receiver,
|
action_srv_receiver,
|
||||||
action_srv_tm_sender,
|
action_srv_tm_sender.clone(),
|
||||||
PUS_APID,
|
PUS_APID,
|
||||||
verif_reporter.clone(),
|
verif_reporter.clone(),
|
||||||
EcssTcInSharedStoreConverter::new(tc_pool.clone(), 2048),
|
EcssTcInSharedStoreConverter::new(tc_pool.clone(), 2048),
|
||||||
),
|
),
|
||||||
ExampleActionRequestConverter::default(),
|
ExampleActionRequestConverter::default(),
|
||||||
action_router,
|
action_router,
|
||||||
GenericRoutingErrorHandler::<8>::default(),
|
|
||||||
);
|
);
|
||||||
Pus8Wrapper { pus_8_handler }
|
let action_reply_handler = PusService8ReplyHandler::new_from_now(
|
||||||
|
verif_reporter.clone(),
|
||||||
|
DefaultActiveActionRequestMap::default(),
|
||||||
|
1024,
|
||||||
|
PusActionReplyHook::default(),
|
||||||
|
action_srv_tm_sender,
|
||||||
|
)
|
||||||
|
.expect("Failed to create PUS 8 reply handler");
|
||||||
|
Pus8Wrapper {
|
||||||
|
action_request_handler,
|
||||||
|
action_reply_handler,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_action_service_dynamic(
|
pub fn create_action_service_dynamic(
|
||||||
@ -133,35 +145,69 @@ pub fn create_action_service_dynamic(
|
|||||||
"PUS_8_TC_RECV",
|
"PUS_8_TC_RECV",
|
||||||
pus_action_rx,
|
pus_action_rx,
|
||||||
);
|
);
|
||||||
let pus_8_handler = PusService8ActionRequestHandler::new(
|
let action_request_handler = PusService8ActionRequestHandler::new(
|
||||||
PusServiceHelper::new(
|
PusServiceHelper::new(
|
||||||
action_srv_receiver,
|
action_srv_receiver,
|
||||||
action_srv_tm_sender,
|
action_srv_tm_sender.clone(),
|
||||||
PUS_APID,
|
PUS_APID,
|
||||||
verif_reporter.clone(),
|
verif_reporter.clone(),
|
||||||
EcssTcInVecConverter::default(),
|
EcssTcInVecConverter::default(),
|
||||||
),
|
),
|
||||||
ExampleActionRequestConverter::default(),
|
ExampleActionRequestConverter::default(),
|
||||||
action_router,
|
action_router,
|
||||||
GenericRoutingErrorHandler::<8>::default(),
|
|
||||||
);
|
);
|
||||||
Pus8Wrapper { pus_8_handler }
|
let action_reply_handler = PusService8ReplyHandler::new_from_now(
|
||||||
|
verif_reporter.clone(),
|
||||||
|
DefaultActiveActionRequestMap::default(),
|
||||||
|
1024,
|
||||||
|
PusActionReplyHook::default(),
|
||||||
|
action_srv_tm_sender,
|
||||||
|
)
|
||||||
|
.expect("Failed to create PUS 8 reply handler");
|
||||||
|
Pus8Wrapper {
|
||||||
|
action_request_handler,
|
||||||
|
action_reply_handler,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct PusActionReplyHook {}
|
||||||
|
|
||||||
|
impl ReplyHandlerHook<ActiveActionRequest, ActionReplyPusWithActionId> for PusActionReplyHook {
|
||||||
|
fn handle_unexpected_reply(
|
||||||
|
&mut self,
|
||||||
|
reply: &satrs::request::GenericMessage<ActionReplyPusWithActionId>,
|
||||||
|
) {
|
||||||
|
println!("received unexpected action reply {:?}", reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn timeout_callback(&self, active_request: &ActiveActionRequest) {
|
||||||
|
println!("active request {active_request:?} timed out");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn timeout_error_code(&self) -> satrs::res_code::ResultU16 {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
pub struct Pus8Wrapper<
|
pub struct Pus8Wrapper<
|
||||||
TcReceiver: EcssTcReceiverCore,
|
TcReceiver: EcssTcReceiverCore,
|
||||||
TmSender: EcssTmSenderCore,
|
TmSender: EcssTmSenderCore,
|
||||||
TcInMemConverter: EcssTcInMemConverter,
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
> {
|
> {
|
||||||
pub(crate) pus_8_handler: PusService8ActionRequestHandler<
|
pub(crate) action_request_handler: PusService8ActionRequestHandler<
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
TmSender,
|
TmSender,
|
||||||
TcInMemConverter,
|
TcInMemConverter,
|
||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
ExampleActionRequestConverter,
|
ExampleActionRequestConverter,
|
||||||
GenericRequestRouter,
|
GenericRequestRouter,
|
||||||
GenericRoutingErrorHandler<8>,
|
>,
|
||||||
|
pub(crate) action_reply_handler: PusService8ReplyHandler<
|
||||||
|
VerificationReporter,
|
||||||
|
DefaultActiveActionRequestMap,
|
||||||
|
PusActionReplyHook,
|
||||||
|
TmSender,
|
||||||
>,
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +219,7 @@ impl<
|
|||||||
> Pus8Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
> Pus8Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
||||||
{
|
{
|
||||||
pub fn handle_next_packet(&mut self) -> bool {
|
pub fn handle_next_packet(&mut self) -> bool {
|
||||||
match self.pus_8_handler.handle_one_tc() {
|
match self.action_request_handler.handle_one_tc() {
|
||||||
Ok(result) => match result {
|
Ok(result) => match result {
|
||||||
PusPacketHandlerResult::RequestHandled => {}
|
PusPacketHandlerResult::RequestHandled => {}
|
||||||
PusPacketHandlerResult::RequestHandledPartialSuccess(e) => {
|
PusPacketHandlerResult::RequestHandledPartialSuccess(e) => {
|
||||||
@ -193,6 +239,7 @@ impl<
|
|||||||
error!("PUS packet handling error: {error:?}")
|
error!("PUS packet handling error: {error:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// self.action_reply_handler.handle_replies();
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
use satrs::hk::{CollectionIntervalFactor, HkRequest};
|
use satrs::hk::{CollectionIntervalFactor, HkRequest};
|
||||||
use satrs::pool::{SharedStaticMemoryPool, StoreAddr};
|
use satrs::pool::{SharedStaticMemoryPool, StoreAddr};
|
||||||
use satrs::pus::hk::{PusHkToRequestConverter, PusService3HkHandler};
|
use satrs::pus::hk::PusService3HkRequestHandler;
|
||||||
use satrs::pus::verification::std_mod::{
|
|
||||||
VerificationReporterWithSharedPoolMpscBoundedSender, VerificationReporterWithVecMpscSender,
|
|
||||||
};
|
|
||||||
use satrs::pus::verification::{
|
use satrs::pus::verification::{
|
||||||
FailParams, TcStateAccepted, VerificationReportingProvider, VerificationToken,
|
FailParams, TcStateAccepted, VerificationReporterWithSharedPoolMpscBoundedSender,
|
||||||
|
VerificationReporterWithVecMpscSender, VerificationReportingProvider, VerificationToken,
|
||||||
};
|
};
|
||||||
use satrs::pus::{
|
use satrs::pus::{
|
||||||
EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter,
|
EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter,
|
||||||
EcssTcReceiverCore, EcssTmSenderCore, MpscTcReceiver, PusPacketHandlerResult,
|
EcssTcReceiverCore, EcssTmSenderCore, MpscTcReceiver, PusPacketHandlerResult,
|
||||||
PusPacketHandlingError, PusServiceHelper, TmAsVecSenderWithId, TmAsVecSenderWithMpsc,
|
PusPacketHandlingError, PusServiceHelper, PusTcToRequestConverter, TmAsVecSenderWithId,
|
||||||
TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
||||||
};
|
};
|
||||||
use satrs::request::TargetAndApidId;
|
use satrs::request::TargetAndApidId;
|
||||||
use satrs::spacepackets::ecss::tc::PusTcReader;
|
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||||
@ -24,12 +22,10 @@ use std::sync::mpsc::{self};
|
|||||||
|
|
||||||
use crate::requests::GenericRequestRouter;
|
use crate::requests::GenericRequestRouter;
|
||||||
|
|
||||||
use super::GenericRoutingErrorHandler;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ExampleHkRequestConverter {}
|
pub struct ExampleHkRequestConverter {}
|
||||||
|
|
||||||
impl PusHkToRequestConverter for ExampleHkRequestConverter {
|
impl PusTcToRequestConverter<HkRequest> for ExampleHkRequestConverter {
|
||||||
type Error = PusPacketHandlingError;
|
type Error = PusPacketHandlingError;
|
||||||
|
|
||||||
fn convert(
|
fn convert(
|
||||||
@ -165,7 +161,7 @@ pub fn create_hk_service_static(
|
|||||||
);
|
);
|
||||||
let hk_srv_receiver =
|
let hk_srv_receiver =
|
||||||
MpscTcReceiver::new(TcReceiverId::PusHk as ChannelId, "PUS_8_TC_RECV", pus_hk_rx);
|
MpscTcReceiver::new(TcReceiverId::PusHk as ChannelId, "PUS_8_TC_RECV", pus_hk_rx);
|
||||||
let pus_3_handler = PusService3HkHandler::new(
|
let pus_3_handler = PusService3HkRequestHandler::new(
|
||||||
PusServiceHelper::new(
|
PusServiceHelper::new(
|
||||||
hk_srv_receiver,
|
hk_srv_receiver,
|
||||||
hk_srv_tm_sender,
|
hk_srv_tm_sender,
|
||||||
@ -175,7 +171,6 @@ pub fn create_hk_service_static(
|
|||||||
),
|
),
|
||||||
ExampleHkRequestConverter::default(),
|
ExampleHkRequestConverter::default(),
|
||||||
request_router,
|
request_router,
|
||||||
GenericRoutingErrorHandler::default(),
|
|
||||||
);
|
);
|
||||||
Pus3Wrapper { pus_3_handler }
|
Pus3Wrapper { pus_3_handler }
|
||||||
}
|
}
|
||||||
@ -198,7 +193,7 @@ pub fn create_hk_service_dynamic(
|
|||||||
);
|
);
|
||||||
let hk_srv_receiver =
|
let hk_srv_receiver =
|
||||||
MpscTcReceiver::new(TcReceiverId::PusHk as ChannelId, "PUS_8_TC_RECV", pus_hk_rx);
|
MpscTcReceiver::new(TcReceiverId::PusHk as ChannelId, "PUS_8_TC_RECV", pus_hk_rx);
|
||||||
let pus_3_handler = PusService3HkHandler::new(
|
let pus_3_handler = PusService3HkRequestHandler::new(
|
||||||
PusServiceHelper::new(
|
PusServiceHelper::new(
|
||||||
hk_srv_receiver,
|
hk_srv_receiver,
|
||||||
hk_srv_tm_sender,
|
hk_srv_tm_sender,
|
||||||
@ -208,7 +203,6 @@ pub fn create_hk_service_dynamic(
|
|||||||
),
|
),
|
||||||
ExampleHkRequestConverter::default(),
|
ExampleHkRequestConverter::default(),
|
||||||
request_router,
|
request_router,
|
||||||
GenericRoutingErrorHandler::default(),
|
|
||||||
);
|
);
|
||||||
Pus3Wrapper { pus_3_handler }
|
Pus3Wrapper { pus_3_handler }
|
||||||
}
|
}
|
||||||
@ -219,14 +213,13 @@ pub struct Pus3Wrapper<
|
|||||||
TcInMemConverter: EcssTcInMemConverter,
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
> {
|
> {
|
||||||
pub(crate) pus_3_handler: PusService3HkHandler<
|
pub(crate) pus_3_handler: PusService3HkRequestHandler<
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
TmSender,
|
TmSender,
|
||||||
TcInMemConverter,
|
TcInMemConverter,
|
||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
ExampleHkRequestConverter,
|
ExampleHkRequestConverter,
|
||||||
GenericRequestRouter,
|
GenericRequestRouter,
|
||||||
GenericRoutingErrorHandler<3>,
|
|
||||||
>,
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
use crate::tmtc::MpscStoreAndSendError;
|
use crate::tmtc::MpscStoreAndSendError;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use satrs::pus::verification::{FailParams, VerificationReportingProvider};
|
use satrs::pus::verification::{FailParams, VerificationReportingProvider};
|
||||||
use satrs::pus::{
|
use satrs::pus::{EcssTcAndToken, PusPacketHandlerResult, TcInMemory};
|
||||||
EcssTcAndToken, GenericRoutingError, PusPacketHandlerResult, PusRoutingErrorHandler, TcInMemory,
|
|
||||||
};
|
|
||||||
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;
|
||||||
@ -153,56 +151,3 @@ impl<VerificationReporter: VerificationReportingProvider> PusReceiver<Verificati
|
|||||||
Ok(PusPacketHandlerResult::RequestHandled)
|
Ok(PusPacketHandlerResult::RequestHandled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct GenericRoutingErrorHandler<const SERVICE_ID: u8> {}
|
|
||||||
|
|
||||||
impl<const SERVICE_ID: u8> PusRoutingErrorHandler for GenericRoutingErrorHandler<SERVICE_ID> {
|
|
||||||
type Error = satrs::pus::GenericRoutingError;
|
|
||||||
|
|
||||||
fn handle_error(
|
|
||||||
&self,
|
|
||||||
target_id: satrs::TargetId,
|
|
||||||
token: satrs::pus::verification::VerificationToken<
|
|
||||||
satrs::pus::verification::TcStateAccepted,
|
|
||||||
>,
|
|
||||||
_tc: &PusTcReader,
|
|
||||||
error: Self::Error,
|
|
||||||
time_stamp: &[u8],
|
|
||||||
verif_reporter: &impl VerificationReportingProvider,
|
|
||||||
) {
|
|
||||||
warn!("Routing request for service {SERVICE_ID} failed: {error:?}");
|
|
||||||
match error {
|
|
||||||
GenericRoutingError::UnknownTargetId(id) => {
|
|
||||||
let mut fail_data: [u8; 8] = [0; 8];
|
|
||||||
fail_data.copy_from_slice(&id.to_be_bytes());
|
|
||||||
verif_reporter
|
|
||||||
.start_failure(
|
|
||||||
token,
|
|
||||||
FailParams::new(time_stamp, &tmtc_err::UNKNOWN_TARGET_ID, &fail_data),
|
|
||||||
)
|
|
||||||
.expect("Sending start failure failed");
|
|
||||||
}
|
|
||||||
GenericRoutingError::SendError(_) => {
|
|
||||||
let mut fail_data: [u8; 8] = [0; 8];
|
|
||||||
fail_data.copy_from_slice(&target_id.to_be_bytes());
|
|
||||||
verif_reporter
|
|
||||||
.start_failure(
|
|
||||||
token,
|
|
||||||
FailParams::new(time_stamp, &tmtc_err::ROUTING_ERROR, &fail_data),
|
|
||||||
)
|
|
||||||
.expect("Sending start failure failed");
|
|
||||||
}
|
|
||||||
GenericRoutingError::NotEnoughAppData { expected, found } => {
|
|
||||||
let mut context_info = (found as u32).to_be_bytes().to_vec();
|
|
||||||
context_info.extend_from_slice(&(expected as u32).to_be_bytes());
|
|
||||||
verif_reporter
|
|
||||||
.start_failure(
|
|
||||||
token,
|
|
||||||
FailParams::new(time_stamp, &tmtc_err::NOT_ENOUGH_APP_DATA, &context_info),
|
|
||||||
)
|
|
||||||
.expect("Sending start failure failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -2,14 +2,19 @@ use std::collections::HashMap;
|
|||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
|
use log::warn;
|
||||||
use satrs::action::ActionRequest;
|
use satrs::action::ActionRequest;
|
||||||
use satrs::hk::HkRequest;
|
use satrs::hk::HkRequest;
|
||||||
use satrs::mode::ModeRequest;
|
use satrs::mode::ModeRequest;
|
||||||
use satrs::pus::hk::PusHkRequestRouter;
|
use satrs::pus::verification::{
|
||||||
use satrs::pus::verification::{TcStateAccepted, VerificationToken};
|
FailParams, TcStateAccepted, VerificationReportingProvider, VerificationToken,
|
||||||
|
};
|
||||||
use satrs::pus::{GenericRoutingError, PusRequestRouter};
|
use satrs::pus::{GenericRoutingError, PusRequestRouter};
|
||||||
use satrs::queue::GenericSendError;
|
use satrs::queue::GenericSendError;
|
||||||
|
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||||
|
use satrs::spacepackets::ecss::PusPacket;
|
||||||
use satrs::TargetId;
|
use satrs::TargetId;
|
||||||
|
use satrs_example::config::tmtc_err;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||||
@ -48,7 +53,57 @@ impl RequestWithToken {
|
|||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct GenericRequestRouter(pub HashMap<TargetId, mpsc::Sender<RequestWithToken>>);
|
pub struct GenericRequestRouter(pub HashMap<TargetId, mpsc::Sender<RequestWithToken>>);
|
||||||
|
|
||||||
impl PusHkRequestRouter for GenericRequestRouter {
|
impl GenericRequestRouter {
|
||||||
|
fn handle_error_generic(
|
||||||
|
&self,
|
||||||
|
target_id: satrs::TargetId,
|
||||||
|
token: satrs::pus::verification::VerificationToken<
|
||||||
|
satrs::pus::verification::TcStateAccepted,
|
||||||
|
>,
|
||||||
|
tc: &PusTcReader,
|
||||||
|
error: GenericRoutingError,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
verif_reporter: &impl VerificationReportingProvider,
|
||||||
|
) {
|
||||||
|
warn!(
|
||||||
|
"Routing request for service {} failed: {error:?}",
|
||||||
|
tc.service()
|
||||||
|
);
|
||||||
|
match error {
|
||||||
|
GenericRoutingError::UnknownTargetId(id) => {
|
||||||
|
let mut fail_data: [u8; 8] = [0; 8];
|
||||||
|
fail_data.copy_from_slice(&id.to_be_bytes());
|
||||||
|
verif_reporter
|
||||||
|
.start_failure(
|
||||||
|
token,
|
||||||
|
FailParams::new(time_stamp, &tmtc_err::UNKNOWN_TARGET_ID, &fail_data),
|
||||||
|
)
|
||||||
|
.expect("Sending start failure failed");
|
||||||
|
}
|
||||||
|
GenericRoutingError::SendError(_) => {
|
||||||
|
let mut fail_data: [u8; 8] = [0; 8];
|
||||||
|
fail_data.copy_from_slice(&target_id.to_be_bytes());
|
||||||
|
verif_reporter
|
||||||
|
.start_failure(
|
||||||
|
token,
|
||||||
|
FailParams::new(time_stamp, &tmtc_err::ROUTING_ERROR, &fail_data),
|
||||||
|
)
|
||||||
|
.expect("Sending start failure failed");
|
||||||
|
}
|
||||||
|
GenericRoutingError::NotEnoughAppData { expected, found } => {
|
||||||
|
let mut context_info = (found as u32).to_be_bytes().to_vec();
|
||||||
|
context_info.extend_from_slice(&(expected as u32).to_be_bytes());
|
||||||
|
verif_reporter
|
||||||
|
.start_failure(
|
||||||
|
token,
|
||||||
|
FailParams::new(time_stamp, &tmtc_err::NOT_ENOUGH_APP_DATA, &context_info),
|
||||||
|
)
|
||||||
|
.expect("Sending start failure failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PusRequestRouter<HkRequest> for GenericRequestRouter {
|
||||||
type Error = GenericRoutingError;
|
type Error = GenericRoutingError;
|
||||||
|
|
||||||
fn route(
|
fn route(
|
||||||
@ -68,6 +123,19 @@ impl PusHkRequestRouter for GenericRequestRouter {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
fn handle_error(
|
||||||
|
&self,
|
||||||
|
target_id: satrs::TargetId,
|
||||||
|
token: satrs::pus::verification::VerificationToken<
|
||||||
|
satrs::pus::verification::TcStateAccepted,
|
||||||
|
>,
|
||||||
|
tc: &PusTcReader,
|
||||||
|
error: GenericRoutingError,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
verif_reporter: &impl VerificationReportingProvider,
|
||||||
|
) {
|
||||||
|
self.handle_error_generic(target_id, token, tc, error, time_stamp, verif_reporter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PusRequestRouter<ActionRequest> for GenericRequestRouter {
|
impl PusRequestRouter<ActionRequest> for GenericRequestRouter {
|
||||||
@ -90,4 +158,17 @@ impl PusRequestRouter<ActionRequest> for GenericRequestRouter {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
fn handle_error(
|
||||||
|
&self,
|
||||||
|
target_id: satrs::TargetId,
|
||||||
|
token: satrs::pus::verification::VerificationToken<
|
||||||
|
satrs::pus::verification::TcStateAccepted,
|
||||||
|
>,
|
||||||
|
tc: &PusTcReader,
|
||||||
|
error: GenericRoutingError,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
verif_reporter: &impl VerificationReportingProvider,
|
||||||
|
) {
|
||||||
|
self.handle_error_generic(target_id, token, tc, error, time_stamp, verif_reporter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
|
use satrs_shared::res_code::ResultU16;
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use spacepackets::ByteConversionError;
|
use spacepackets::ByteConversionError;
|
||||||
@ -53,7 +54,7 @@ impl ModeAndSubmode {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> {
|
pub fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> {
|
||||||
if buf.len() < Self::RAW_LEN {
|
if buf.len() < Self::RAW_LEN {
|
||||||
return Err(ByteConversionError::ToSliceTooSmall {
|
return Err(ByteConversionError::ToSliceTooSmall {
|
||||||
expected: Self::RAW_LEN,
|
expected: Self::RAW_LEN,
|
||||||
@ -114,6 +115,13 @@ pub enum ModeRequest {
|
|||||||
AnnounceModeRecursive,
|
AnnounceModeRecursive,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub struct TargetedModeRequest {
|
||||||
|
target_id: TargetId,
|
||||||
|
mode_request: ModeRequest,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
pub enum ModeReply {
|
pub enum ModeReply {
|
||||||
@ -121,20 +129,15 @@ pub enum ModeReply {
|
|||||||
ModeInfo(ModeAndSubmode),
|
ModeInfo(ModeAndSubmode),
|
||||||
/// Reply to a mode request to confirm the commanded mode was reached.
|
/// Reply to a mode request to confirm the commanded mode was reached.
|
||||||
ModeReply(ModeAndSubmode),
|
ModeReply(ModeAndSubmode),
|
||||||
// Can not reach the commanded mode. Returns the mode which was reached in the end.
|
// Can not reach the commanded mode. Contains a reason as a [ResultU16].
|
||||||
CantReachMode(ModeAndSubmode),
|
CantReachMode(ResultU16),
|
||||||
WrongMode {
|
WrongMode {
|
||||||
expected: ModeAndSubmode,
|
expected: ModeAndSubmode,
|
||||||
reached: ModeAndSubmode,
|
reached: ModeAndSubmode,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
pub type GenericModeReply = GenericMessage<ModeReply>;
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
||||||
pub struct TargetedModeRequest {
|
|
||||||
target_id: TargetId,
|
|
||||||
mode_request: ModeRequest,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ModeRequestSender {
|
pub trait ModeRequestSender {
|
||||||
fn local_channel_id(&self) -> ChannelId;
|
fn local_channel_id(&self) -> ChannelId;
|
||||||
@ -146,37 +149,12 @@ pub trait ModeRequestSender {
|
|||||||
) -> Result<(), GenericTargetedMessagingError>;
|
) -> Result<(), GenericTargetedMessagingError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ModeReplySender {
|
|
||||||
fn local_channel_id(&self) -> ChannelId;
|
|
||||||
|
|
||||||
fn send_mode_reply(
|
|
||||||
&self,
|
|
||||||
request_id: RequestId,
|
|
||||||
target_id: ChannelId,
|
|
||||||
reply: ModeReply,
|
|
||||||
) -> Result<(), GenericTargetedMessagingError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ModeRequestReceiver {
|
pub trait ModeRequestReceiver {
|
||||||
fn try_recv_mode_request(
|
fn try_recv_mode_request(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Option<GenericMessage<ModeRequest>>, GenericTargetedMessagingError>;
|
) -> Result<Option<GenericMessage<ModeRequest>>, GenericTargetedMessagingError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ModeReplyReceiver {
|
|
||||||
fn try_recv_mode_reply(
|
|
||||||
&self,
|
|
||||||
) -> Result<Option<GenericMessage<ModeReply>>, GenericTargetedMessagingError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: MessageReceiver<ModeReply>> ModeReplyReceiver for MessageReceiverWithId<ModeReply, R> {
|
|
||||||
fn try_recv_mode_reply(
|
|
||||||
&self,
|
|
||||||
) -> Result<Option<GenericMessage<ModeReply>>, GenericTargetedMessagingError> {
|
|
||||||
self.try_recv_message()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: MessageReceiver<ModeRequest>> ModeRequestReceiver
|
impl<R: MessageReceiver<ModeRequest>> ModeRequestReceiver
|
||||||
for MessageReceiverWithId<ModeRequest, R>
|
for MessageReceiverWithId<ModeRequest, R>
|
||||||
{
|
{
|
||||||
@ -214,32 +192,46 @@ pub trait ModeRequestHandler: ModeProvider {
|
|||||||
fn handle_mode_reached(&mut self) -> Result<(), GenericTargetedMessagingError>;
|
fn handle_mode_reached(&mut self) -> Result<(), GenericTargetedMessagingError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ModeReplyReceiver {
|
||||||
|
fn try_recv_mode_reply(
|
||||||
|
&self,
|
||||||
|
) -> Result<Option<GenericMessage<ModeReply>>, GenericTargetedMessagingError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: MessageReceiver<ModeReply>> ModeReplyReceiver for MessageReceiverWithId<ModeReply, R> {
|
||||||
|
fn try_recv_mode_reply(
|
||||||
|
&self,
|
||||||
|
) -> Result<Option<GenericMessage<ModeReply>>, GenericTargetedMessagingError> {
|
||||||
|
self.try_recv_message()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ModeReplySender {
|
||||||
|
fn local_channel_id(&self) -> ChannelId;
|
||||||
|
|
||||||
|
fn send_mode_reply(
|
||||||
|
&self,
|
||||||
|
request_id: RequestId,
|
||||||
|
target_id: ChannelId,
|
||||||
|
reply: ModeReply,
|
||||||
|
) -> Result<(), GenericTargetedMessagingError>;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||||
pub mod alloc_mod {
|
pub mod alloc_mod {
|
||||||
use crate::request::{
|
use crate::{
|
||||||
|
mode::ModeRequest,
|
||||||
|
queue::GenericTargetedMessagingError,
|
||||||
|
request::{
|
||||||
MessageSender, MessageSenderAndReceiver, MessageSenderMap, MessageSenderMapWithId,
|
MessageSender, MessageSenderAndReceiver, MessageSenderMap, MessageSenderMapWithId,
|
||||||
RequestAndReplySenderAndReceiver,
|
RequestAndReplySenderAndReceiver, RequestId,
|
||||||
|
},
|
||||||
|
ChannelId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl<S: MessageSender<ModeRequest>> MessageSenderMap<ModeRequest, S> {
|
|
||||||
pub fn send_mode_request(
|
|
||||||
&self,
|
|
||||||
request_id: RequestId,
|
|
||||||
local_id: ChannelId,
|
|
||||||
target_id: ChannelId,
|
|
||||||
request: ModeRequest,
|
|
||||||
) -> Result<(), GenericTargetedMessagingError> {
|
|
||||||
self.send_message(request_id, local_id, target_id, request)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_request_target(&mut self, target_id: ChannelId, request_sender: S) {
|
|
||||||
self.add_message_target(target_id, request_sender)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: MessageSender<ModeReply>> MessageSenderMap<ModeReply, S> {
|
impl<S: MessageSender<ModeReply>> MessageSenderMap<ModeReply, S> {
|
||||||
pub fn send_mode_reply(
|
pub fn send_mode_reply(
|
||||||
&self,
|
&self,
|
||||||
@ -271,21 +263,6 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: MessageSender<ModeRequest>> ModeRequestSender for MessageSenderMapWithId<ModeRequest, S> {
|
|
||||||
fn local_channel_id(&self) -> ChannelId {
|
|
||||||
self.local_channel_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_mode_request(
|
|
||||||
&self,
|
|
||||||
request_id: RequestId,
|
|
||||||
target_id: ChannelId,
|
|
||||||
request: ModeRequest,
|
|
||||||
) -> Result<(), GenericTargetedMessagingError> {
|
|
||||||
self.send_message(request_id, target_id, request)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<FROM, S: MessageSender<ModeReply>, R: MessageReceiver<FROM>> ModeReplySender
|
impl<FROM, S: MessageSender<ModeReply>, R: MessageReceiver<FROM>> ModeReplySender
|
||||||
for MessageSenderAndReceiver<ModeReply, FROM, S, R>
|
for MessageSenderAndReceiver<ModeReply, FROM, S, R>
|
||||||
{
|
{
|
||||||
@ -317,51 +294,6 @@ pub mod alloc_mod {
|
|||||||
self.message_receiver.try_recv_message()
|
self.message_receiver.try_recv_message()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<TO, S: MessageSender<TO>, R: MessageReceiver<ModeRequest>> ModeRequestReceiver
|
|
||||||
for MessageSenderAndReceiver<TO, ModeRequest, S, R>
|
|
||||||
{
|
|
||||||
fn try_recv_mode_request(
|
|
||||||
&self,
|
|
||||||
) -> Result<Option<GenericMessage<ModeRequest>>, GenericTargetedMessagingError> {
|
|
||||||
self.message_receiver.try_recv_message()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<FROM, S: MessageSender<ModeRequest>, R: MessageReceiver<FROM>> ModeRequestSender
|
|
||||||
for MessageSenderAndReceiver<ModeRequest, FROM, S, R>
|
|
||||||
{
|
|
||||||
fn local_channel_id(&self) -> ChannelId {
|
|
||||||
self.local_channel_id_generic()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_mode_request(
|
|
||||||
&self,
|
|
||||||
request_id: RequestId,
|
|
||||||
target_id: ChannelId,
|
|
||||||
request: ModeRequest,
|
|
||||||
) -> Result<(), GenericTargetedMessagingError> {
|
|
||||||
self.message_sender_map.send_mode_request(
|
|
||||||
request_id,
|
|
||||||
self.local_channel_id(),
|
|
||||||
target_id,
|
|
||||||
request,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
REPLY,
|
|
||||||
S0: MessageSender<ModeRequest>,
|
|
||||||
R0: MessageReceiver<REPLY>,
|
|
||||||
S1: MessageSender<REPLY>,
|
|
||||||
R1: MessageReceiver<ModeRequest>,
|
|
||||||
> RequestAndReplySenderAndReceiver<ModeRequest, REPLY, S0, R0, S1, R1>
|
|
||||||
{
|
|
||||||
pub fn add_request_target(&mut self, target_id: ChannelId, request_sender: S0) {
|
|
||||||
self.request_sender_map
|
|
||||||
.add_message_target(target_id, request_sender)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
REQUEST,
|
REQUEST,
|
||||||
@ -377,34 +309,6 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
|
||||||
REPLY,
|
|
||||||
S0: MessageSender<ModeRequest>,
|
|
||||||
R0: MessageReceiver<REPLY>,
|
|
||||||
S1: MessageSender<REPLY>,
|
|
||||||
R1: MessageReceiver<ModeRequest>,
|
|
||||||
> ModeRequestSender
|
|
||||||
for RequestAndReplySenderAndReceiver<ModeRequest, REPLY, S0, R0, S1, R1>
|
|
||||||
{
|
|
||||||
fn local_channel_id(&self) -> ChannelId {
|
|
||||||
self.local_channel_id_generic()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_mode_request(
|
|
||||||
&self,
|
|
||||||
request_id: RequestId,
|
|
||||||
target_id: ChannelId,
|
|
||||||
request: ModeRequest,
|
|
||||||
) -> Result<(), GenericTargetedMessagingError> {
|
|
||||||
self.request_sender_map.send_mode_request(
|
|
||||||
request_id,
|
|
||||||
self.local_channel_id(),
|
|
||||||
target_id,
|
|
||||||
request,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
REQUEST,
|
REQUEST,
|
||||||
S0: MessageSender<REQUEST>,
|
S0: MessageSender<REQUEST>,
|
||||||
@ -448,22 +352,6 @@ pub mod alloc_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
|
||||||
REPLY,
|
|
||||||
S0: MessageSender<ModeRequest>,
|
|
||||||
R0: MessageReceiver<REPLY>,
|
|
||||||
S1: MessageSender<REPLY>,
|
|
||||||
R1: MessageReceiver<ModeRequest>,
|
|
||||||
> ModeRequestReceiver
|
|
||||||
for RequestAndReplySenderAndReceiver<ModeRequest, REPLY, S0, R0, S1, R1>
|
|
||||||
{
|
|
||||||
fn try_recv_mode_request(
|
|
||||||
&self,
|
|
||||||
) -> Result<Option<GenericMessage<ModeRequest>>, GenericTargetedMessagingError> {
|
|
||||||
self.request_receiver.try_recv_message()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper type definition for a mode handler which can handle mode requests.
|
/// Helper type definition for a mode handler which can handle mode requests.
|
||||||
pub type ModeRequestHandlerInterface<S, R> =
|
pub type ModeRequestHandlerInterface<S, R> =
|
||||||
MessageSenderAndReceiver<ModeReply, ModeRequest, S, R>;
|
MessageSenderAndReceiver<ModeReply, ModeRequest, S, R>;
|
||||||
@ -511,6 +399,127 @@ pub mod alloc_mod {
|
|||||||
/// process mode requests.
|
/// process mode requests.
|
||||||
pub type ModeInterface<S0, R0, S1, R1> =
|
pub type ModeInterface<S0, R0, S1, R1> =
|
||||||
RequestAndReplySenderAndReceiver<ModeRequest, ModeReply, S0, R0, S1, R1>;
|
RequestAndReplySenderAndReceiver<ModeRequest, ModeReply, S0, R0, S1, R1>;
|
||||||
|
|
||||||
|
impl<S: MessageSender<ModeRequest>> MessageSenderMap<ModeRequest, S> {
|
||||||
|
pub fn send_mode_request(
|
||||||
|
&self,
|
||||||
|
request_id: RequestId,
|
||||||
|
local_id: ChannelId,
|
||||||
|
target_id: ChannelId,
|
||||||
|
request: ModeRequest,
|
||||||
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
|
self.send_message(request_id, local_id, target_id, request)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_request_target(&mut self, target_id: ChannelId, request_sender: S) {
|
||||||
|
self.add_message_target(target_id, request_sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: MessageSender<ModeRequest>> ModeRequestSender for MessageSenderMapWithId<ModeRequest, S> {
|
||||||
|
fn local_channel_id(&self) -> ChannelId {
|
||||||
|
self.local_channel_id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_mode_request(
|
||||||
|
&self,
|
||||||
|
request_id: RequestId,
|
||||||
|
target_id: ChannelId,
|
||||||
|
request: ModeRequest,
|
||||||
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
|
self.send_message(request_id, target_id, request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<TO, S: MessageSender<TO>, R: MessageReceiver<ModeRequest>> ModeRequestReceiver
|
||||||
|
for MessageSenderAndReceiver<TO, ModeRequest, S, R>
|
||||||
|
{
|
||||||
|
fn try_recv_mode_request(
|
||||||
|
&self,
|
||||||
|
) -> Result<Option<GenericMessage<ModeRequest>>, GenericTargetedMessagingError> {
|
||||||
|
self.message_receiver.try_recv_message()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<FROM, S: MessageSender<ModeRequest>, R: MessageReceiver<FROM>> ModeRequestSender
|
||||||
|
for MessageSenderAndReceiver<ModeRequest, FROM, S, R>
|
||||||
|
{
|
||||||
|
fn local_channel_id(&self) -> ChannelId {
|
||||||
|
self.local_channel_id_generic()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_mode_request(
|
||||||
|
&self,
|
||||||
|
request_id: RequestId,
|
||||||
|
target_id: ChannelId,
|
||||||
|
request: ModeRequest,
|
||||||
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
|
self.message_sender_map.send_mode_request(
|
||||||
|
request_id,
|
||||||
|
self.local_channel_id(),
|
||||||
|
target_id,
|
||||||
|
request,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
REPLY,
|
||||||
|
S0: MessageSender<ModeRequest>,
|
||||||
|
R0: MessageReceiver<REPLY>,
|
||||||
|
S1: MessageSender<REPLY>,
|
||||||
|
R1: MessageReceiver<ModeRequest>,
|
||||||
|
> RequestAndReplySenderAndReceiver<ModeRequest, REPLY, S0, R0, S1, R1>
|
||||||
|
{
|
||||||
|
pub fn add_request_target(&mut self, target_id: ChannelId, request_sender: S0) {
|
||||||
|
self.request_sender_map
|
||||||
|
.add_message_target(target_id, request_sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
REPLY,
|
||||||
|
S0: MessageSender<ModeRequest>,
|
||||||
|
R0: MessageReceiver<REPLY>,
|
||||||
|
S1: MessageSender<REPLY>,
|
||||||
|
R1: MessageReceiver<ModeRequest>,
|
||||||
|
> ModeRequestSender
|
||||||
|
for RequestAndReplySenderAndReceiver<ModeRequest, REPLY, S0, R0, S1, R1>
|
||||||
|
{
|
||||||
|
fn local_channel_id(&self) -> ChannelId {
|
||||||
|
self.local_channel_id_generic()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_mode_request(
|
||||||
|
&self,
|
||||||
|
request_id: RequestId,
|
||||||
|
target_id: ChannelId,
|
||||||
|
request: ModeRequest,
|
||||||
|
) -> Result<(), GenericTargetedMessagingError> {
|
||||||
|
self.request_sender_map.send_mode_request(
|
||||||
|
request_id,
|
||||||
|
self.local_channel_id(),
|
||||||
|
target_id,
|
||||||
|
request,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
REPLY,
|
||||||
|
S0: MessageSender<ModeRequest>,
|
||||||
|
R0: MessageReceiver<REPLY>,
|
||||||
|
S1: MessageSender<REPLY>,
|
||||||
|
R1: MessageReceiver<ModeRequest>,
|
||||||
|
> ModeRequestReceiver
|
||||||
|
for RequestAndReplySenderAndReceiver<ModeRequest, REPLY, S0, R0, S1, R1>
|
||||||
|
{
|
||||||
|
fn try_recv_mode_request(
|
||||||
|
&self,
|
||||||
|
) -> Result<Option<GenericMessage<ModeRequest>>, GenericTargetedMessagingError> {
|
||||||
|
self.request_receiver.try_recv_message()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -518,6 +527,8 @@ pub mod alloc_mod {
|
|||||||
pub mod std_mod {
|
pub mod std_mod {
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
|
use crate::request::GenericMessage;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub type ModeRequestHandlerMpsc = ModeRequestHandlerInterface<
|
pub type ModeRequestHandlerMpsc = ModeRequestHandlerInterface<
|
||||||
@ -553,115 +564,4 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {}
|
||||||
use std::sync::mpsc;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
mode::{ModeAndSubmode, ModeReply, ModeReplySender, ModeRequestSender},
|
|
||||||
request::GenericMessage,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{ModeRequest, ModeRequestorAndHandlerMpsc, ModeRequestorMpsc};
|
|
||||||
|
|
||||||
const TEST_CHANNEL_ID_0: u32 = 5;
|
|
||||||
const TEST_CHANNEL_ID_1: u32 = 6;
|
|
||||||
const TEST_CHANNEL_ID_2: u32 = 7;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_simple_mode_requestor() {
|
|
||||||
let (reply_sender, reply_receiver) = mpsc::channel();
|
|
||||||
let (request_sender, request_receiver) = mpsc::channel();
|
|
||||||
let mut mode_requestor = ModeRequestorMpsc::new(TEST_CHANNEL_ID_0, reply_receiver);
|
|
||||||
mode_requestor.add_message_target(TEST_CHANNEL_ID_1, request_sender);
|
|
||||||
|
|
||||||
// Send a request and verify it arrives at the receiver.
|
|
||||||
let request_id = 2;
|
|
||||||
let sent_request = ModeRequest::ReadMode;
|
|
||||||
mode_requestor
|
|
||||||
.send_mode_request(request_id, TEST_CHANNEL_ID_1, sent_request)
|
|
||||||
.expect("send failed");
|
|
||||||
let request = request_receiver.recv().expect("recv failed");
|
|
||||||
assert_eq!(request.request_id, 2);
|
|
||||||
assert_eq!(request.sender_id, TEST_CHANNEL_ID_0);
|
|
||||||
assert_eq!(request.message, sent_request);
|
|
||||||
|
|
||||||
// Send a reply and verify it arrives at the requestor.
|
|
||||||
let mode_reply = ModeReply::ModeReply(ModeAndSubmode::new(1, 5));
|
|
||||||
reply_sender
|
|
||||||
.send(GenericMessage::new(
|
|
||||||
request_id,
|
|
||||||
TEST_CHANNEL_ID_1,
|
|
||||||
mode_reply,
|
|
||||||
))
|
|
||||||
.expect("send failed");
|
|
||||||
let reply = mode_requestor.try_recv_mode_reply().expect("recv failed");
|
|
||||||
assert!(reply.is_some());
|
|
||||||
let reply = reply.unwrap();
|
|
||||||
assert_eq!(reply.sender_id, TEST_CHANNEL_ID_1);
|
|
||||||
assert_eq!(reply.request_id, 2);
|
|
||||||
assert_eq!(reply.message, mode_reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_mode_requestor_and_request_handler_request_sending() {
|
|
||||||
let (_reply_sender_to_connector, reply_receiver_of_connector) = mpsc::channel();
|
|
||||||
let (_request_sender_to_connector, request_receiver_of_connector) = mpsc::channel();
|
|
||||||
|
|
||||||
let (request_sender_to_channel_1, request_receiver_channel_1) = mpsc::channel();
|
|
||||||
//let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
|
||||||
let mut mode_connector = ModeRequestorAndHandlerMpsc::new(
|
|
||||||
TEST_CHANNEL_ID_0,
|
|
||||||
request_receiver_of_connector,
|
|
||||||
reply_receiver_of_connector,
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
ModeRequestSender::local_channel_id(&mode_connector),
|
|
||||||
TEST_CHANNEL_ID_0
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
ModeReplySender::local_channel_id(&mode_connector),
|
|
||||||
TEST_CHANNEL_ID_0
|
|
||||||
);
|
|
||||||
assert_eq!(mode_connector.local_channel_id_generic(), TEST_CHANNEL_ID_0);
|
|
||||||
|
|
||||||
mode_connector.add_request_target(TEST_CHANNEL_ID_1, request_sender_to_channel_1);
|
|
||||||
//mode_connector.add_reply_target(TEST_CHANNEL_ID_2, reply_sender_to_channel_2);
|
|
||||||
|
|
||||||
// Send a request and verify it arrives at the receiver.
|
|
||||||
let request_id = 2;
|
|
||||||
let sent_request = ModeRequest::ReadMode;
|
|
||||||
mode_connector
|
|
||||||
.send_mode_request(request_id, TEST_CHANNEL_ID_1, sent_request)
|
|
||||||
.expect("send failed");
|
|
||||||
|
|
||||||
let request = request_receiver_channel_1.recv().expect("recv failed");
|
|
||||||
assert_eq!(request.request_id, 2);
|
|
||||||
assert_eq!(request.sender_id, TEST_CHANNEL_ID_0);
|
|
||||||
assert_eq!(request.message, ModeRequest::ReadMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_mode_requestor_and_request_handler_reply_sending() {
|
|
||||||
let (_reply_sender_to_connector, reply_receiver_of_connector) = mpsc::channel();
|
|
||||||
let (_request_sender_to_connector, request_receiver_of_connector) = mpsc::channel();
|
|
||||||
|
|
||||||
let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
|
||||||
let mut mode_connector = ModeRequestorAndHandlerMpsc::new(
|
|
||||||
TEST_CHANNEL_ID_0,
|
|
||||||
request_receiver_of_connector,
|
|
||||||
reply_receiver_of_connector,
|
|
||||||
);
|
|
||||||
mode_connector.add_reply_target(TEST_CHANNEL_ID_2, reply_sender_to_channel_2);
|
|
||||||
|
|
||||||
// Send a request and verify it arrives at the receiver.
|
|
||||||
let request_id = 2;
|
|
||||||
let sent_reply = ModeReply::ModeInfo(ModeAndSubmode::new(3, 5));
|
|
||||||
mode_connector
|
|
||||||
.send_mode_reply(request_id, TEST_CHANNEL_ID_2, sent_reply)
|
|
||||||
.expect("send failed");
|
|
||||||
let reply = reply_receiver_channel_2.recv().expect("recv failed");
|
|
||||||
assert_eq!(reply.request_id, 2);
|
|
||||||
assert_eq!(reply.sender_id, TEST_CHANNEL_ID_0);
|
|
||||||
assert_eq!(reply.message, sent_reply);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -122,7 +122,6 @@ pub mod std_mod {
|
|||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
RequestConverter,
|
RequestConverter,
|
||||||
RequestRouter,
|
RequestRouter,
|
||||||
RoutingErrorHandler,
|
|
||||||
RoutingError = GenericRoutingError,
|
RoutingError = GenericRoutingError,
|
||||||
> = PusTargetedRequestHandler<
|
> = PusTargetedRequestHandler<
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
@ -131,7 +130,6 @@ pub mod std_mod {
|
|||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
RequestConverter,
|
RequestConverter,
|
||||||
RequestRouter,
|
RequestRouter,
|
||||||
RoutingErrorHandler,
|
|
||||||
ActionRequest,
|
ActionRequest,
|
||||||
RoutingError,
|
RoutingError,
|
||||||
>;
|
>;
|
||||||
@ -326,7 +324,7 @@ mod tests {
|
|||||||
pus::{
|
pus::{
|
||||||
tests::{
|
tests::{
|
||||||
PusServiceHandlerWithVecCommon, PusTestHarness, SimplePusPacketHandler,
|
PusServiceHandlerWithVecCommon, PusTestHarness, SimplePusPacketHandler,
|
||||||
TestConverter, TestRouter, TestRoutingErrorHandler, APP_DATA_TOO_SHORT, TEST_APID,
|
TestConverter, TestRouter, APP_DATA_TOO_SHORT, TEST_APID,
|
||||||
},
|
},
|
||||||
verification::{
|
verification::{
|
||||||
self,
|
self,
|
||||||
@ -356,6 +354,20 @@ mod tests {
|
|||||||
.push_back((target_id, request));
|
.push_back((target_id, request));
|
||||||
self.check_for_injected_error()
|
self.check_for_injected_error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_error(
|
||||||
|
&self,
|
||||||
|
target_id: TargetId,
|
||||||
|
token: VerificationToken<TcStateAccepted>,
|
||||||
|
tc: &PusTcReader,
|
||||||
|
error: Self::Error,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
verif_reporter: &impl VerificationReportingProvider,
|
||||||
|
) {
|
||||||
|
self.routing_errors
|
||||||
|
.borrow_mut()
|
||||||
|
.push_back((target_id, error));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PusTcToRequestConverter<ActionRequest> for TestConverter<8> {
|
impl PusTcToRequestConverter<ActionRequest> for TestConverter<8> {
|
||||||
@ -413,7 +425,6 @@ mod tests {
|
|||||||
TestVerificationReporter,
|
TestVerificationReporter,
|
||||||
TestConverter<8>,
|
TestConverter<8>,
|
||||||
TestRouter<ActionRequest>,
|
TestRouter<ActionRequest>,
|
||||||
TestRoutingErrorHandler,
|
|
||||||
>,
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,7 +438,6 @@ mod tests {
|
|||||||
srv_handler,
|
srv_handler,
|
||||||
TestConverter::default(),
|
TestConverter::default(),
|
||||||
TestRouter::default(),
|
TestRouter::default(),
|
||||||
TestRoutingErrorHandler::default(),
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -443,8 +453,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
delegate! {
|
delegate! {
|
||||||
to self.handler.routing_error_handler {
|
to self.handler.request_router {
|
||||||
pub fn retrieve_next_error(&mut self) -> (TargetId, GenericRoutingError);
|
pub fn retrieve_next_routing_error(&mut self) -> (TargetId, GenericRoutingError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -714,7 +724,7 @@ mod tests {
|
|||||||
assert_eq!(data, &[]);
|
assert_eq!(data, &[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (target_id, found_error) = action_handler.retrieve_next_error();
|
let (target_id, found_error) = action_handler.retrieve_next_routing_error();
|
||||||
assert_eq!(target_id, TEST_APID.into());
|
assert_eq!(target_id, TEST_APID.into());
|
||||||
check_error(found_error);
|
check_error(found_error);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ pub use std_mod::*;
|
|||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||||
|
#[allow(unused_imports)]
|
||||||
pub use alloc_mod::*;
|
pub use alloc_mod::*;
|
||||||
|
|
||||||
use crate::{hk::HkRequest, TargetId};
|
use crate::{hk::HkRequest, TargetId};
|
||||||
@ -26,158 +27,33 @@ pub trait PusHkRequestRouter {
|
|||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||||
pub mod alloc_mod {
|
pub mod alloc_mod {}
|
||||||
use spacepackets::ecss::tc::PusTcReader;
|
|
||||||
|
|
||||||
use crate::pus::verification::VerificationReportingProvider;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
/// This trait is an abstraction for the conversion of a PUS service 8 action telecommand into
|
|
||||||
/// a [HkRequest].
|
|
||||||
///
|
|
||||||
/// Having a dedicated trait for this allows maximum flexiblity and tailoring of the standard.
|
|
||||||
/// The only requirement is that a valid [TargetId] and a [HkRequest] are returned by the
|
|
||||||
/// core conversion function.
|
|
||||||
///
|
|
||||||
/// The user should take care of performing the error handling as well. Some of the following
|
|
||||||
/// aspects might be relevant:
|
|
||||||
///
|
|
||||||
/// - Checking the validity of the APID, service ID, subservice ID.
|
|
||||||
/// - Checking the validity of the user data.
|
|
||||||
///
|
|
||||||
/// A [VerificationReportingProvider] is passed to the user to also allow handling
|
|
||||||
/// of the verification process as part of the PUS standard requirements.
|
|
||||||
pub trait PusHkToRequestConverter {
|
|
||||||
type Error;
|
|
||||||
fn convert(
|
|
||||||
&mut self,
|
|
||||||
token: VerificationToken<TcStateAccepted>,
|
|
||||||
tc: &PusTcReader,
|
|
||||||
time_stamp: &[u8],
|
|
||||||
verif_reporter: &impl VerificationReportingProvider,
|
|
||||||
) -> Result<(TargetId, HkRequest), Self::Error>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||||
pub mod std_mod {
|
pub mod std_mod {
|
||||||
use crate::pus::{
|
use crate::pus::{GenericRoutingError, PusTargetedRequestHandler};
|
||||||
get_current_cds_short_timestamp, verification::VerificationReportingProvider,
|
|
||||||
EcssTcInMemConverter, EcssTcReceiverCore, EcssTmSenderCore, GenericRoutingError,
|
|
||||||
PusPacketHandlerResult, PusPacketHandlingError, PusRoutingErrorHandler, PusServiceHelper,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// This is a generic high-level handler for the PUS service 3 housekeeping service.
|
pub type PusService3HkRequestHandler<
|
||||||
///
|
|
||||||
/// It performs the following handling steps:
|
|
||||||
///
|
|
||||||
/// 1. Retrieve the next TC packet from the [PusServiceHelper]. The [EcssTcInMemConverter]
|
|
||||||
/// allows to configure the used telecommand memory backend.
|
|
||||||
/// 2. Convert the TC to a targeted action request using the provided
|
|
||||||
/// [PusHkToRequestConverter]. The generic error type is constrained to the
|
|
||||||
/// [PusPacketHandlerResult] for the concrete implementation which offers a packet handler.
|
|
||||||
/// 3. Route the action request using the provided [PusHkRequestRouter]. The generic error
|
|
||||||
/// type is constrained to the [GenericRoutingError] for the concrete implementation.
|
|
||||||
/// 4. Handle all routing errors using the provided [PusRoutingErrorHandler]. The generic error
|
|
||||||
/// type is constrained to the [GenericRoutingError] for the concrete implementation.
|
|
||||||
pub struct PusService3HkHandler<
|
|
||||||
TcReceiver: EcssTcReceiverCore,
|
|
||||||
TmSender: EcssTmSenderCore,
|
|
||||||
TcInMemConverter: EcssTcInMemConverter,
|
|
||||||
VerificationReporter: VerificationReportingProvider,
|
|
||||||
RequestConverter: PusHkToRequestConverter,
|
|
||||||
RequestRouter: PusHkRequestRouter<Error = RoutingError>,
|
|
||||||
RoutingErrorHandler: PusRoutingErrorHandler<Error = RoutingError>,
|
|
||||||
RoutingError = GenericRoutingError,
|
|
||||||
> {
|
|
||||||
service_helper:
|
|
||||||
PusServiceHelper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
|
||||||
pub request_converter: RequestConverter,
|
|
||||||
pub request_router: RequestRouter,
|
|
||||||
pub routing_error_handler: RoutingErrorHandler,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
TcReceiver: EcssTcReceiverCore,
|
|
||||||
TmSender: EcssTmSenderCore,
|
|
||||||
TcInMemConverter: EcssTcInMemConverter,
|
|
||||||
VerificationReporter: VerificationReportingProvider,
|
|
||||||
RequestConverter: PusHkToRequestConverter<Error = PusPacketHandlingError>,
|
|
||||||
RequestRouter: PusHkRequestRouter<Error = RoutingError>,
|
|
||||||
RoutingErrorHandler: PusRoutingErrorHandler<Error = RoutingError>,
|
|
||||||
RoutingError: Clone,
|
|
||||||
>
|
|
||||||
PusService3HkHandler<
|
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
TmSender,
|
TmSender,
|
||||||
TcInMemConverter,
|
TcInMemConverter,
|
||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
RequestConverter,
|
RequestConverter,
|
||||||
RequestRouter,
|
RequestRouter,
|
||||||
RoutingErrorHandler,
|
RoutingError = GenericRoutingError,
|
||||||
RoutingError,
|
> = PusTargetedRequestHandler<
|
||||||
>
|
|
||||||
where
|
|
||||||
PusPacketHandlingError: From<RoutingError>,
|
|
||||||
{
|
|
||||||
pub fn new(
|
|
||||||
service_helper: PusServiceHelper<
|
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
TmSender,
|
TmSender,
|
||||||
TcInMemConverter,
|
TcInMemConverter,
|
||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
>,
|
RequestConverter,
|
||||||
request_converter: RequestConverter,
|
RequestRouter,
|
||||||
request_router: RequestRouter,
|
HkRequest,
|
||||||
routing_error_handler: RoutingErrorHandler,
|
RoutingError,
|
||||||
) -> Self {
|
>;
|
||||||
Self {
|
|
||||||
service_helper,
|
|
||||||
request_converter,
|
|
||||||
request_router,
|
|
||||||
routing_error_handler,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
|
||||||
let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?;
|
|
||||||
if possible_packet.is_none() {
|
|
||||||
return Ok(PusPacketHandlerResult::Empty);
|
|
||||||
}
|
|
||||||
let ecss_tc_and_token = possible_packet.unwrap();
|
|
||||||
let tc = self
|
|
||||||
.service_helper
|
|
||||||
.tc_in_mem_converter
|
|
||||||
.convert_ecss_tc_in_memory_to_reader(&ecss_tc_and_token.tc_in_memory)?;
|
|
||||||
let mut partial_error = None;
|
|
||||||
let time_stamp = get_current_cds_short_timestamp(&mut partial_error);
|
|
||||||
let (target_id, hk_request) = self.request_converter.convert(
|
|
||||||
ecss_tc_and_token.token,
|
|
||||||
&tc,
|
|
||||||
&time_stamp,
|
|
||||||
&self.service_helper.common.verification_handler,
|
|
||||||
)?;
|
|
||||||
if let Err(e) =
|
|
||||||
self.request_router
|
|
||||||
.route(target_id, hk_request, ecss_tc_and_token.token)
|
|
||||||
{
|
|
||||||
self.routing_error_handler.handle_error(
|
|
||||||
target_id,
|
|
||||||
ecss_tc_and_token.token,
|
|
||||||
&tc,
|
|
||||||
e.clone(),
|
|
||||||
&time_stamp,
|
|
||||||
&self.service_helper.common.verification_handler,
|
|
||||||
);
|
|
||||||
return Err(e.into());
|
|
||||||
}
|
|
||||||
Ok(PusPacketHandlerResult::RequestHandled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -194,13 +70,13 @@ mod tests {
|
|||||||
CcsdsPacket, SequenceFlags, SpHeader,
|
CcsdsPacket, SequenceFlags, SpHeader,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::pus::{MpscTcReceiver, TmAsVecSenderWithMpsc};
|
use crate::pus::{MpscTcReceiver, PusTcToRequestConverter, TmAsVecSenderWithMpsc};
|
||||||
use crate::{
|
use crate::{
|
||||||
hk::HkRequest,
|
hk::HkRequest,
|
||||||
pus::{
|
pus::{
|
||||||
tests::{
|
tests::{
|
||||||
PusServiceHandlerWithVecCommon, PusTestHarness, SimplePusPacketHandler,
|
PusServiceHandlerWithVecCommon, PusTestHarness, SimplePusPacketHandler,
|
||||||
TestConverter, TestRouter, TestRoutingErrorHandler, APP_DATA_TOO_SHORT, TEST_APID,
|
TestConverter, TestRouter, APP_DATA_TOO_SHORT, TEST_APID,
|
||||||
},
|
},
|
||||||
verification::{
|
verification::{
|
||||||
tests::TestVerificationReporter, FailParams, RequestId, TcStateAccepted,
|
tests::TestVerificationReporter, FailParams, RequestId, TcStateAccepted,
|
||||||
@ -212,7 +88,7 @@ mod tests {
|
|||||||
TargetId,
|
TargetId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{PusHkRequestRouter, PusHkToRequestConverter, PusService3HkHandler};
|
use super::{PusHkRequestRouter, PusService3HkRequestHandler};
|
||||||
|
|
||||||
impl PusHkRequestRouter for TestRouter<HkRequest> {
|
impl PusHkRequestRouter for TestRouter<HkRequest> {
|
||||||
type Error = GenericRoutingError;
|
type Error = GenericRoutingError;
|
||||||
@ -230,7 +106,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PusHkToRequestConverter for TestConverter<3> {
|
impl PusTcToRequestConverter<HkRequest> for TestConverter<3> {
|
||||||
type Error = PusPacketHandlingError;
|
type Error = PusPacketHandlingError;
|
||||||
fn convert(
|
fn convert(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -277,14 +153,13 @@ mod tests {
|
|||||||
|
|
||||||
struct Pus3HandlerWithVecTester {
|
struct Pus3HandlerWithVecTester {
|
||||||
common: PusServiceHandlerWithVecCommon<TestVerificationReporter>,
|
common: PusServiceHandlerWithVecCommon<TestVerificationReporter>,
|
||||||
handler: PusService3HkHandler<
|
handler: PusService3HkRequestHandler<
|
||||||
MpscTcReceiver,
|
MpscTcReceiver,
|
||||||
TmAsVecSenderWithMpsc,
|
TmAsVecSenderWithMpsc,
|
||||||
EcssTcInVecConverter,
|
EcssTcInVecConverter,
|
||||||
TestVerificationReporter,
|
TestVerificationReporter,
|
||||||
TestConverter<3>,
|
TestConverter<3>,
|
||||||
TestRouter<HkRequest>,
|
TestRouter<HkRequest>,
|
||||||
TestRoutingErrorHandler,
|
|
||||||
>,
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,11 +169,10 @@ mod tests {
|
|||||||
PusServiceHandlerWithVecCommon::new_with_test_verif_sender();
|
PusServiceHandlerWithVecCommon::new_with_test_verif_sender();
|
||||||
Self {
|
Self {
|
||||||
common,
|
common,
|
||||||
handler: PusService3HkHandler::new(
|
handler: PusService3HkRequestHandler::new(
|
||||||
srv_handler,
|
srv_handler,
|
||||||
TestConverter::default(),
|
TestConverter::default(),
|
||||||
TestRouter::default(),
|
TestRouter::default(),
|
||||||
TestRoutingErrorHandler::default(),
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,8 +188,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
delegate! {
|
delegate! {
|
||||||
to self.handler.routing_error_handler {
|
to self.handler.request_router {
|
||||||
pub fn retrieve_next_error(&mut self) -> (TargetId, GenericRoutingError);
|
pub fn retrieve_next_routing_error(&mut self) -> (TargetId, GenericRoutingError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -399,7 +273,7 @@ mod tests {
|
|||||||
assert_eq!(unique_id, 1);
|
assert_eq!(unique_id, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (target_id, found_error) = hk_handler.retrieve_next_error();
|
let (target_id, found_error) = hk_handler.retrieve_next_routing_error();
|
||||||
assert_eq!(target_id, TEST_APID.into());
|
assert_eq!(target_id, TEST_APID.into());
|
||||||
check_error(found_error);
|
check_error(found_error);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ pub use alloc_mod::*;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std_mod::*;
|
pub use std_mod::*;
|
||||||
|
|
||||||
use self::verification::{FailParams, TcStateStarted};
|
use self::verification::{FailParams, TcStateStarted, VerificationReportingProvider};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum PusTmWrapper<'tm> {
|
pub enum PusTmWrapper<'tm> {
|
||||||
@ -347,6 +347,15 @@ pub trait PusRequestRouter<Request> {
|
|||||||
hk_request: Request,
|
hk_request: Request,
|
||||||
token: VerificationToken<TcStateAccepted>,
|
token: VerificationToken<TcStateAccepted>,
|
||||||
) -> Result<(), Self::Error>;
|
) -> Result<(), Self::Error>;
|
||||||
|
fn handle_error(
|
||||||
|
&self,
|
||||||
|
target_id: TargetId,
|
||||||
|
token: VerificationToken<TcStateAccepted>,
|
||||||
|
tc: &PusTcReader,
|
||||||
|
error: Self::Error,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
verif_reporter: &impl VerificationReportingProvider,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
@ -465,19 +474,6 @@ pub mod alloc_mod {
|
|||||||
) -> Result<(TargetId, Request), Self::Error>;
|
) -> Result<(TargetId, Request), Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PusRoutingErrorHandler {
|
|
||||||
type Error;
|
|
||||||
fn handle_error(
|
|
||||||
&self,
|
|
||||||
target_id: TargetId,
|
|
||||||
token: VerificationToken<TcStateAccepted>,
|
|
||||||
tc: &PusTcReader,
|
|
||||||
error: Self::Error,
|
|
||||||
time_stamp: &[u8],
|
|
||||||
verif_reporter: &impl VerificationReportingProvider,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DefaultActiveRequestMap<V>(pub HashMap<RequestId, V>);
|
pub struct DefaultActiveRequestMap<V>(pub HashMap<RequestId, V>);
|
||||||
|
|
||||||
@ -704,10 +700,7 @@ pub mod std_mod {
|
|||||||
pub use cb_mod::*;
|
pub use cb_mod::*;
|
||||||
|
|
||||||
use super::verification::VerificationReportingProvider;
|
use super::verification::VerificationReportingProvider;
|
||||||
use super::{
|
use super::{AcceptedEcssTcAndToken, PusRequestRouter, PusTcToRequestConverter, TcInMemory};
|
||||||
AcceptedEcssTcAndToken, PusRequestRouter, PusRoutingErrorHandler, PusTcToRequestConverter,
|
|
||||||
TcInMemory,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl From<mpsc::SendError<StoreAddr>> for EcssTmtcError {
|
impl From<mpsc::SendError<StoreAddr>> for EcssTmtcError {
|
||||||
fn from(_: mpsc::SendError<StoreAddr>) -> Self {
|
fn from(_: mpsc::SendError<StoreAddr>) -> Self {
|
||||||
@ -999,7 +992,6 @@ pub mod std_mod {
|
|||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
RequestConverter: PusTcToRequestConverter<Request>,
|
RequestConverter: PusTcToRequestConverter<Request>,
|
||||||
RequestRouter: PusRequestRouter<Request, Error = RoutingError>,
|
RequestRouter: PusRequestRouter<Request, Error = RoutingError>,
|
||||||
RoutingErrorHandler: PusRoutingErrorHandler<Error = RoutingError>,
|
|
||||||
Request,
|
Request,
|
||||||
RoutingError = GenericRoutingError,
|
RoutingError = GenericRoutingError,
|
||||||
> {
|
> {
|
||||||
@ -1007,7 +999,7 @@ 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,
|
// pub routing_error_handler: RoutingErrorHandler,
|
||||||
phantom: PhantomData<Request>,
|
phantom: PhantomData<Request>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1018,7 +1010,7 @@ 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>,
|
// RoutingErrorHandler: PusRoutingErrorHandler<Error = RoutingError>,
|
||||||
Request,
|
Request,
|
||||||
RoutingError: Clone,
|
RoutingError: Clone,
|
||||||
>
|
>
|
||||||
@ -1029,7 +1021,7 @@ pub mod std_mod {
|
|||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
RequestConverter,
|
RequestConverter,
|
||||||
RequestRouter,
|
RequestRouter,
|
||||||
RoutingErrorHandler,
|
// RoutingErrorHandler,
|
||||||
Request,
|
Request,
|
||||||
RoutingError,
|
RoutingError,
|
||||||
>
|
>
|
||||||
@ -1045,13 +1037,12 @@ pub mod std_mod {
|
|||||||
>,
|
>,
|
||||||
request_converter: RequestConverter,
|
request_converter: RequestConverter,
|
||||||
request_router: RequestRouter,
|
request_router: RequestRouter,
|
||||||
routing_error_handler: RoutingErrorHandler,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
service_helper,
|
service_helper,
|
||||||
request_converter,
|
request_converter,
|
||||||
request_router,
|
request_router,
|
||||||
routing_error_handler,
|
// routing_error_handler,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1079,7 +1070,7 @@ pub mod std_mod {
|
|||||||
self.request_router
|
self.request_router
|
||||||
.route(target_id, action_request, ecss_tc_and_token.token)
|
.route(target_id, action_request, ecss_tc_and_token.token)
|
||||||
{
|
{
|
||||||
self.routing_error_handler.handle_error(
|
self.request_router.handle_error(
|
||||||
target_id,
|
target_id,
|
||||||
ecss_tc_and_token.token,
|
ecss_tc_and_token.token,
|
||||||
&tc,
|
&tc,
|
||||||
@ -1451,8 +1442,8 @@ pub mod tests {
|
|||||||
};
|
};
|
||||||
use super::{
|
use super::{
|
||||||
EcssTcAndToken, EcssTcInSharedStoreConverter, EcssTcInVecConverter, GenericRoutingError,
|
EcssTcAndToken, EcssTcInSharedStoreConverter, EcssTcInVecConverter, GenericRoutingError,
|
||||||
MpscTcReceiver, PusPacketHandlerResult, PusPacketHandlingError, PusRoutingErrorHandler,
|
MpscTcReceiver, PusPacketHandlerResult, PusPacketHandlingError, PusServiceHelper,
|
||||||
PusServiceHelper, TcInMemory, TmAsVecSenderWithId, TmAsVecSenderWithMpsc,
|
TcInMemory, TmAsVecSenderWithId, TmAsVecSenderWithMpsc,
|
||||||
TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1766,44 +1757,9 @@ pub mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct TestRoutingErrorHandler {
|
|
||||||
pub routing_errors: RefCell<VecDeque<(TargetId, GenericRoutingError)>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PusRoutingErrorHandler for TestRoutingErrorHandler {
|
|
||||||
type Error = GenericRoutingError;
|
|
||||||
|
|
||||||
fn handle_error(
|
|
||||||
&self,
|
|
||||||
target_id: TargetId,
|
|
||||||
_token: VerificationToken<TcStateAccepted>,
|
|
||||||
_tc: &PusTcReader,
|
|
||||||
error: Self::Error,
|
|
||||||
_time_stamp: &[u8],
|
|
||||||
_verif_reporter: &impl VerificationReportingProvider,
|
|
||||||
) {
|
|
||||||
self.routing_errors
|
|
||||||
.borrow_mut()
|
|
||||||
.push_back((target_id, error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TestRoutingErrorHandler {
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.routing_errors.borrow().is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn retrieve_next_error(&mut self) -> (TargetId, GenericRoutingError) {
|
|
||||||
if self.routing_errors.borrow().is_empty() {
|
|
||||||
panic!("no routing request available");
|
|
||||||
}
|
|
||||||
self.routing_errors.borrow_mut().pop_front().unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TestRouter<REQUEST> {
|
pub struct TestRouter<REQUEST> {
|
||||||
pub routing_requests: RefCell<VecDeque<(TargetId, REQUEST)>>,
|
pub routing_requests: RefCell<VecDeque<(TargetId, REQUEST)>>,
|
||||||
|
pub routing_errors: RefCell<VecDeque<(TargetId, GenericRoutingError)>>,
|
||||||
pub injected_routing_failure: RefCell<Option<GenericRoutingError>>,
|
pub injected_routing_failure: RefCell<Option<GenericRoutingError>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1811,6 +1767,7 @@ pub mod tests {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
routing_requests: Default::default(),
|
routing_requests: Default::default(),
|
||||||
|
routing_errors: Default::default(),
|
||||||
injected_routing_failure: Default::default(),
|
injected_routing_failure: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1824,6 +1781,31 @@ pub mod tests {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_error(
|
||||||
|
&self,
|
||||||
|
target_id: TargetId,
|
||||||
|
_token: VerificationToken<TcStateAccepted>,
|
||||||
|
_tc: &PusTcReader,
|
||||||
|
error: GenericRoutingError,
|
||||||
|
_time_stamp: &[u8],
|
||||||
|
_verif_reporter: &impl VerificationReportingProvider,
|
||||||
|
) {
|
||||||
|
self.routing_errors
|
||||||
|
.borrow_mut()
|
||||||
|
.push_back((target_id, error));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn no_routing_errors(&self) -> bool {
|
||||||
|
self.routing_errors.borrow().is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn retrieve_next_routing_error(&mut self) -> (TargetId, GenericRoutingError) {
|
||||||
|
if self.routing_errors.borrow().is_empty() {
|
||||||
|
panic!("no routing request available");
|
||||||
|
}
|
||||||
|
self.routing_errors.borrow_mut().pop_front().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn inject_routing_error(&mut self, error: GenericRoutingError) {
|
pub fn inject_routing_error(&mut self, error: GenericRoutingError) {
|
||||||
*self.injected_routing_failure.borrow_mut() = Some(error);
|
*self.injected_routing_failure.borrow_mut() = Some(error);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,14 @@ use num_enum::{IntoPrimitive, TryFromPrimitive};
|
|||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{mode::ModeReply, request::GenericMessage};
|
use crate::mode::ModeReply;
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
pub use alloc_mod::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub use std_mod::*;
|
||||||
|
|
||||||
pub const MODE_SERVICE_ID: u8 = 200;
|
pub const MODE_SERVICE_ID: u8 = 200;
|
||||||
|
|
||||||
@ -19,8 +26,6 @@ pub enum Subservice {
|
|||||||
TmWrongModeReply = 8,
|
TmWrongModeReply = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type GenericModeReplyPus = GenericMessage<ModeReply>;
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||||
pub mod alloc_mod {}
|
pub mod alloc_mod {}
|
||||||
@ -33,11 +38,12 @@ pub mod std_mod {
|
|||||||
use satrs_shared::res_code::ResultU16;
|
use satrs_shared::res_code::ResultU16;
|
||||||
use spacepackets::{
|
use spacepackets::{
|
||||||
ecss::tm::{PusTmCreator, PusTmSecondaryHeader},
|
ecss::tm::{PusTmCreator, PusTmSecondaryHeader},
|
||||||
|
util::UnsignedEnum,
|
||||||
SpHeader,
|
SpHeader,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
mode::{ModeReply, ModeRequest},
|
mode::{GenericModeReply, ModeRequest},
|
||||||
pus::{
|
pus::{
|
||||||
mode::Subservice,
|
mode::Subservice,
|
||||||
verification::{
|
verification::{
|
||||||
@ -55,7 +61,7 @@ pub mod std_mod {
|
|||||||
fn can_not_reach_mode_result_code(&self) -> ResultU16;
|
fn can_not_reach_mode_result_code(&self) -> ResultU16;
|
||||||
}
|
}
|
||||||
|
|
||||||
use super::{GenericModeReplyPus, MODE_SERVICE_ID};
|
use super::{ModeReply, MODE_SERVICE_ID};
|
||||||
|
|
||||||
pub type PusModeServiceRequestHandler<
|
pub type PusModeServiceRequestHandler<
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
@ -64,7 +70,6 @@ pub mod std_mod {
|
|||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
RequestConverter,
|
RequestConverter,
|
||||||
RequestRouter,
|
RequestRouter,
|
||||||
RoutingErrorHandler,
|
|
||||||
RoutingError = GenericRoutingError,
|
RoutingError = GenericRoutingError,
|
||||||
> = PusTargetedRequestHandler<
|
> = PusTargetedRequestHandler<
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
@ -73,7 +78,6 @@ pub mod std_mod {
|
|||||||
VerificationReporter,
|
VerificationReporter,
|
||||||
RequestConverter,
|
RequestConverter,
|
||||||
RequestRouter,
|
RequestRouter,
|
||||||
RoutingErrorHandler,
|
|
||||||
ModeRequest,
|
ModeRequest,
|
||||||
RoutingError,
|
RoutingError,
|
||||||
>;
|
>;
|
||||||
@ -124,7 +128,7 @@ pub mod std_mod {
|
|||||||
/// Main handler function to handle all received action replies.
|
/// Main handler function to handle all received action replies.
|
||||||
pub fn handle_mode_reply(
|
pub fn handle_mode_reply(
|
||||||
&mut self,
|
&mut self,
|
||||||
mode_reply_with_id: &GenericModeReplyPus,
|
mode_reply_with_id: &GenericModeReply,
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
) -> Result<(), EcssTmtcError> {
|
) -> Result<(), EcssTmtcError> {
|
||||||
let active_req = self.active_request_map.get(mode_reply_with_id.request_id);
|
let active_req = self.active_request_map.get(mode_reply_with_id.request_id);
|
||||||
@ -135,6 +139,7 @@ pub mod std_mod {
|
|||||||
let active_req = active_req.unwrap().clone();
|
let active_req = active_req.unwrap().clone();
|
||||||
let remove_entry = match mode_reply_with_id.message {
|
let remove_entry = match mode_reply_with_id.message {
|
||||||
ModeReply::ModeReply(reply) => {
|
ModeReply::ModeReply(reply) => {
|
||||||
|
reply.write_to_be_bytes(&mut self.tm_buf)?;
|
||||||
let req_id = verification::RequestId::from(mode_reply_with_id.request_id);
|
let req_id = verification::RequestId::from(mode_reply_with_id.request_id);
|
||||||
let mut sp_header = SpHeader::tm_unseg(
|
let mut sp_header = SpHeader::tm_unseg(
|
||||||
req_id.packet_id().apid(),
|
req_id.packet_id().apid(),
|
||||||
@ -149,16 +154,15 @@ pub mod std_mod {
|
|||||||
0,
|
0,
|
||||||
Some(time_stamp),
|
Some(time_stamp),
|
||||||
);
|
);
|
||||||
let pus_tm =
|
let pus_tm = PusTmCreator::new(&mut sp_header, sec_header, &self.tm_buf, true);
|
||||||
PusTmCreator::new(&mut sp_header, sec_header, &mut self.tm_buf, true);
|
|
||||||
self.tm_sender.send_tm(PusTmWrapper::Direct(pus_tm))?;
|
self.tm_sender.send_tm(PusTmWrapper::Direct(pus_tm))?;
|
||||||
self.verification_reporter
|
self.verification_reporter
|
||||||
.completion_success(active_req.token, time_stamp)
|
.completion_success(active_req.token, time_stamp)
|
||||||
.map_err(|e| e.0)?;
|
.map_err(|e| e.0)?;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
ModeReply::CantReachMode(reached_mode) => {
|
ModeReply::CantReachMode(reason) => {
|
||||||
let fail_data_len = reached_mode.to_be_bytes(&mut self.tm_buf)?;
|
let fail_data_len = reason.write_to_be_bytes(&mut self.tm_buf)?;
|
||||||
self.verification_reporter
|
self.verification_reporter
|
||||||
.completion_failure(
|
.completion_failure(
|
||||||
active_req.token,
|
active_req.token,
|
||||||
@ -172,9 +176,19 @@ pub mod std_mod {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
ModeReply::WrongMode { expected, reached } => {
|
ModeReply::WrongMode { expected, reached } => {
|
||||||
// TODO: Generate completion failure with appropriate result code and reached
|
let expected_len = expected.write_to_be_bytes(&mut self.tm_buf)?;
|
||||||
// mode as context information.
|
let reached_len =
|
||||||
// self.verification_reporter.completion_success(active_req.token, time_stamp);
|
reached.write_to_be_bytes(&mut self.tm_buf[expected_len..])?;
|
||||||
|
self.verification_reporter
|
||||||
|
.completion_failure(
|
||||||
|
active_req.token,
|
||||||
|
FailParams::new(
|
||||||
|
time_stamp,
|
||||||
|
&self.user_hook.can_not_reach_mode_result_code(),
|
||||||
|
&self.tm_buf[0..expected_len + reached_len],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map_err(|e| e.0)?;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
_ => true,
|
_ => true,
|
||||||
@ -187,3 +201,122 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use std::sync::mpsc;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
mode::{
|
||||||
|
ModeAndSubmode, ModeReplySender, ModeRequest, ModeRequestSender,
|
||||||
|
ModeRequestorAndHandlerMpsc, ModeRequestorMpsc,
|
||||||
|
},
|
||||||
|
pus::mode::ModeReply,
|
||||||
|
request::GenericMessage,
|
||||||
|
};
|
||||||
|
|
||||||
|
const TEST_CHANNEL_ID_0: u32 = 5;
|
||||||
|
const TEST_CHANNEL_ID_1: u32 = 6;
|
||||||
|
const TEST_CHANNEL_ID_2: u32 = 7;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simple_mode_requestor() {
|
||||||
|
let (reply_sender, reply_receiver) = mpsc::channel();
|
||||||
|
let (request_sender, request_receiver) = mpsc::channel();
|
||||||
|
let mut mode_requestor = ModeRequestorMpsc::new(TEST_CHANNEL_ID_0, reply_receiver);
|
||||||
|
mode_requestor.add_message_target(TEST_CHANNEL_ID_1, request_sender);
|
||||||
|
|
||||||
|
// Send a request and verify it arrives at the receiver.
|
||||||
|
let request_id = 2;
|
||||||
|
let sent_request = ModeRequest::ReadMode;
|
||||||
|
mode_requestor
|
||||||
|
.send_mode_request(request_id, TEST_CHANNEL_ID_1, sent_request)
|
||||||
|
.expect("send failed");
|
||||||
|
let request = request_receiver.recv().expect("recv failed");
|
||||||
|
assert_eq!(request.request_id, 2);
|
||||||
|
assert_eq!(request.sender_id, TEST_CHANNEL_ID_0);
|
||||||
|
assert_eq!(request.message, sent_request);
|
||||||
|
|
||||||
|
// Send a reply and verify it arrives at the requestor.
|
||||||
|
let mode_reply = ModeReply::ModeReply(ModeAndSubmode::new(1, 5));
|
||||||
|
reply_sender
|
||||||
|
.send(GenericMessage::new(
|
||||||
|
request_id,
|
||||||
|
TEST_CHANNEL_ID_1,
|
||||||
|
mode_reply,
|
||||||
|
))
|
||||||
|
.expect("send failed");
|
||||||
|
let reply = mode_requestor.try_recv_mode_reply().expect("recv failed");
|
||||||
|
assert!(reply.is_some());
|
||||||
|
let reply = reply.unwrap();
|
||||||
|
assert_eq!(reply.sender_id, TEST_CHANNEL_ID_1);
|
||||||
|
assert_eq!(reply.request_id, 2);
|
||||||
|
assert_eq!(reply.message, mode_reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mode_requestor_and_request_handler_request_sending() {
|
||||||
|
let (_reply_sender_to_connector, reply_receiver_of_connector) = mpsc::channel();
|
||||||
|
let (_request_sender_to_connector, request_receiver_of_connector) = mpsc::channel();
|
||||||
|
|
||||||
|
let (request_sender_to_channel_1, request_receiver_channel_1) = mpsc::channel();
|
||||||
|
//let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
||||||
|
let mut mode_connector = ModeRequestorAndHandlerMpsc::new(
|
||||||
|
TEST_CHANNEL_ID_0,
|
||||||
|
request_receiver_of_connector,
|
||||||
|
reply_receiver_of_connector,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ModeRequestSender::local_channel_id(&mode_connector),
|
||||||
|
TEST_CHANNEL_ID_0
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ModeReplySender::local_channel_id(&mode_connector),
|
||||||
|
TEST_CHANNEL_ID_0
|
||||||
|
);
|
||||||
|
assert_eq!(mode_connector.local_channel_id_generic(), TEST_CHANNEL_ID_0);
|
||||||
|
|
||||||
|
mode_connector.add_request_target(TEST_CHANNEL_ID_1, request_sender_to_channel_1);
|
||||||
|
|
||||||
|
// Send a request and verify it arrives at the receiver.
|
||||||
|
let request_id = 2;
|
||||||
|
let sent_request = ModeRequest::ReadMode;
|
||||||
|
mode_connector
|
||||||
|
.send_mode_request(request_id, TEST_CHANNEL_ID_1, sent_request)
|
||||||
|
.expect("send failed");
|
||||||
|
|
||||||
|
let request = request_receiver_channel_1.recv().expect("recv failed");
|
||||||
|
assert_eq!(request.request_id, 2);
|
||||||
|
assert_eq!(request.sender_id, TEST_CHANNEL_ID_0);
|
||||||
|
assert_eq!(request.message, ModeRequest::ReadMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mode_requestor_and_request_handler_reply_sending() {
|
||||||
|
let (_reply_sender_to_connector, reply_receiver_of_connector) = mpsc::channel();
|
||||||
|
let (_request_sender_to_connector, request_receiver_of_connector) = mpsc::channel();
|
||||||
|
|
||||||
|
let (reply_sender_to_channel_2, reply_receiver_channel_2) = mpsc::channel();
|
||||||
|
let mut mode_connector = ModeRequestorAndHandlerMpsc::new(
|
||||||
|
TEST_CHANNEL_ID_0,
|
||||||
|
request_receiver_of_connector,
|
||||||
|
reply_receiver_of_connector,
|
||||||
|
);
|
||||||
|
mode_connector.add_reply_target(TEST_CHANNEL_ID_2, reply_sender_to_channel_2);
|
||||||
|
|
||||||
|
// Send a request and verify it arrives at the receiver.
|
||||||
|
let request_id = 2;
|
||||||
|
let sent_reply = ModeReply::ModeInfo(ModeAndSubmode::new(3, 5));
|
||||||
|
mode_connector
|
||||||
|
.send_mode_reply(request_id, TEST_CHANNEL_ID_2, sent_reply)
|
||||||
|
.expect("send failed");
|
||||||
|
let reply = reply_receiver_channel_2.recv().expect("recv failed");
|
||||||
|
assert_eq!(reply.request_id, 2);
|
||||||
|
assert_eq!(reply.sender_id, TEST_CHANNEL_ID_0);
|
||||||
|
assert_eq!(reply.message, sent_reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mode_reply_handler() {}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user