this might finally work..
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
6873a8f2a7
commit
309d0101a0
@ -88,12 +88,8 @@ impl<VerificationReporter: VerificationReportingProvider> AcsTask<VerificationRe
|
|||||||
warn!("action request handling not implemented yet")
|
warn!("action request handling not implemented yet")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let started_token = self
|
|
||||||
.verif_reporter
|
|
||||||
.start_success(request.token, &self.timestamp)
|
|
||||||
.expect("Sending start success failed");
|
|
||||||
self.verif_reporter
|
self.verif_reporter
|
||||||
.completion_success(started_token, &self.timestamp)
|
.completion_success(request.token, &self.timestamp)
|
||||||
.expect("Sending completion success failed");
|
.expect("Sending completion success failed");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ fn static_tmtc_pool_main() {
|
|||||||
shared_tc_pool.pool.clone(),
|
shared_tc_pool.pool.clone(),
|
||||||
pus_hk_rx,
|
pus_hk_rx,
|
||||||
request_map,
|
request_map,
|
||||||
pus_hk_reply_rx
|
pus_hk_reply_rx,
|
||||||
);
|
);
|
||||||
let mut pus_stack = PusStack::new(
|
let mut pus_stack = PusStack::new(
|
||||||
pus_hk_service,
|
pus_hk_service,
|
||||||
@ -390,7 +390,7 @@ fn dyn_tmtc_pool_main() {
|
|||||||
verif_reporter.clone(),
|
verif_reporter.clone(),
|
||||||
pus_hk_rx,
|
pus_hk_rx,
|
||||||
request_map,
|
request_map,
|
||||||
pus_hk_reply_rx
|
pus_hk_reply_rx,
|
||||||
);
|
);
|
||||||
let mut pus_stack = PusStack::new(
|
let mut pus_stack = PusStack::new(
|
||||||
pus_hk_service,
|
pus_hk_service,
|
||||||
|
@ -13,9 +13,9 @@ use satrs::pus::verification::{
|
|||||||
};
|
};
|
||||||
use satrs::pus::{
|
use satrs::pus::{
|
||||||
ActiveRequestProvider, EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter,
|
ActiveRequestProvider, EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter,
|
||||||
EcssTcInVecConverter, EcssTcReceiverCore, EcssTmSenderCore, EcssTmtcError, MpscTcReceiver,
|
EcssTcInVecConverter, EcssTcReceiverCore, EcssTmSenderCore, EcssTmtcError,
|
||||||
PusPacketHandlerResult, PusPacketHandlingError, PusReplyHandler, PusServiceHelper,
|
GenericConversionError, MpscTcReceiver, PusPacketHandlerResult, PusReplyHandler,
|
||||||
PusTcToRequestConverter, TmAsVecSenderWithId, TmAsVecSenderWithMpsc,
|
PusServiceHelper, PusTcToRequestConverter, TmAsVecSenderWithId, TmAsVecSenderWithMpsc,
|
||||||
TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
||||||
};
|
};
|
||||||
use satrs::request::{GenericMessage, TargetAndApidId};
|
use satrs::request::{GenericMessage, TargetAndApidId};
|
||||||
@ -138,7 +138,7 @@ pub struct ExampleActionRequestConverter {}
|
|||||||
impl PusTcToRequestConverter<ActivePusActionRequestStd, ActionRequestWithId>
|
impl PusTcToRequestConverter<ActivePusActionRequestStd, ActionRequestWithId>
|
||||||
for ExampleActionRequestConverter
|
for ExampleActionRequestConverter
|
||||||
{
|
{
|
||||||
type Error = PusPacketHandlingError;
|
type Error = GenericConversionError;
|
||||||
|
|
||||||
fn convert(
|
fn convert(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -156,7 +156,7 @@ impl PusTcToRequestConverter<ActivePusActionRequestStd, ActionRequestWithId>
|
|||||||
FailParams::new_no_fail_data(time_stamp, &tmtc_err::NOT_ENOUGH_APP_DATA),
|
FailParams::new_no_fail_data(time_stamp, &tmtc_err::NOT_ENOUGH_APP_DATA),
|
||||||
)
|
)
|
||||||
.expect("Sending start failure failed");
|
.expect("Sending start failure failed");
|
||||||
return Err(PusPacketHandlingError::NotEnoughAppData {
|
return Err(GenericConversionError::NotEnoughAppData {
|
||||||
expected: 8,
|
expected: 8,
|
||||||
found: user_data.len(),
|
found: user_data.len(),
|
||||||
});
|
});
|
||||||
@ -166,7 +166,7 @@ impl PusTcToRequestConverter<ActivePusActionRequestStd, ActionRequestWithId>
|
|||||||
if subservice == 128 {
|
if subservice == 128 {
|
||||||
let token = verif_reporter
|
let token = verif_reporter
|
||||||
.start_success(token, time_stamp)
|
.start_success(token, time_stamp)
|
||||||
.map_err(|e| e.0)?;
|
.expect("sending start success verification failed");
|
||||||
Ok((
|
Ok((
|
||||||
ActivePusActionRequestStd::new(
|
ActivePusActionRequestStd::new(
|
||||||
action_id,
|
action_id,
|
||||||
@ -189,7 +189,7 @@ impl PusTcToRequestConverter<ActivePusActionRequestStd, ActionRequestWithId>
|
|||||||
FailParams::new_no_fail_data(time_stamp, &tmtc_err::INVALID_PUS_SUBSERVICE),
|
FailParams::new_no_fail_data(time_stamp, &tmtc_err::INVALID_PUS_SUBSERVICE),
|
||||||
)
|
)
|
||||||
.expect("Sending start failure failed");
|
.expect("Sending start failure failed");
|
||||||
Err(PusPacketHandlingError::InvalidSubservice(subservice))
|
Err(GenericConversionError::InvalidSubservice(subservice))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,7 +236,7 @@ pub fn create_action_service_static(
|
|||||||
reply_receiver,
|
reply_receiver,
|
||||||
);
|
);
|
||||||
Pus8Wrapper {
|
Pus8Wrapper {
|
||||||
action_request_handler,
|
service: action_request_handler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ pub fn create_action_service_dynamic(
|
|||||||
reply_receiver,
|
reply_receiver,
|
||||||
);
|
);
|
||||||
Pus8Wrapper {
|
Pus8Wrapper {
|
||||||
action_request_handler,
|
service: action_request_handler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ pub struct Pus8Wrapper<
|
|||||||
TcInMemConverter: EcssTcInMemConverter,
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
> {
|
> {
|
||||||
pub(crate) action_request_handler: PusTargetedRequestService<
|
pub(crate) service: PusTargetedRequestService<
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
TmSender,
|
TmSender,
|
||||||
TcInMemConverter,
|
TcInMemConverter,
|
||||||
@ -308,8 +308,8 @@ impl<
|
|||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
> Pus8Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
> Pus8Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
||||||
{
|
{
|
||||||
pub fn handle_next_packet(&mut self, time_stamp: &[u8]) -> bool {
|
pub fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> bool {
|
||||||
match self.action_request_handler.handle_one_tc(time_stamp) {
|
match self.service.poll_and_handle_next_tc(time_stamp) {
|
||||||
Ok(result) => match result {
|
Ok(result) => match result {
|
||||||
PusPacketHandlerResult::RequestHandled => {}
|
PusPacketHandlerResult::RequestHandled => {}
|
||||||
PusPacketHandlerResult::RequestHandledPartialSuccess(e) => {
|
PusPacketHandlerResult::RequestHandledPartialSuccess(e) => {
|
||||||
@ -331,4 +331,14 @@ impl<
|
|||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn poll_and_handle_next_reply(&mut self, time_stamp: &[u8]) -> bool {
|
||||||
|
match self.service.poll_and_check_next_reply(time_stamp) {
|
||||||
|
Ok(packet_handled) => packet_handled,
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("PUS 8: Handling reply failed with error {e:?}");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,12 @@ use satrs::pus::verification::{
|
|||||||
use satrs::pus::{
|
use satrs::pus::{
|
||||||
ActivePusRequestStd, ActiveRequestProvider, DefaultActiveRequestMap, EcssTcAndToken,
|
ActivePusRequestStd, ActiveRequestProvider, DefaultActiveRequestMap, EcssTcAndToken,
|
||||||
EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTcReceiverCore,
|
EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTcReceiverCore,
|
||||||
EcssTmSenderCore, EcssTmtcError, MpscTcReceiver, PusPacketHandlerResult,
|
EcssTmSenderCore, EcssTmtcError, GenericConversionError, MpscTcReceiver,
|
||||||
PusPacketHandlingError, PusReplyHandler, PusServiceHelper, PusTcToRequestConverter,
|
PusPacketHandlerResult, PusReplyHandler, PusServiceHelper, PusTcToRequestConverter,
|
||||||
TmAsVecSenderWithId, TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc,
|
TmAsVecSenderWithId, TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc,
|
||||||
TmInSharedPoolSenderWithId,
|
TmInSharedPoolSenderWithId,
|
||||||
};
|
};
|
||||||
use satrs::request::{TargetAndApidId, GenericMessage};
|
use satrs::request::{GenericMessage, TargetAndApidId};
|
||||||
use satrs::spacepackets::ecss::tc::PusTcReader;
|
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||||
use satrs::spacepackets::ecss::{hk, PusPacket};
|
use satrs::spacepackets::ecss::{hk, PusPacket};
|
||||||
use satrs::tmtc::tm_helper::SharedTmPool;
|
use satrs::tmtc::tm_helper::SharedTmPool;
|
||||||
@ -59,7 +59,7 @@ impl PusReplyHandler<ActivePusRequestStd, HkReply> for HkReplyHandler {
|
|||||||
HkReply::Ack => {
|
HkReply::Ack => {
|
||||||
verification_handler
|
verification_handler
|
||||||
.completion_success(active_request.token(), time_stamp)
|
.completion_success(active_request.token(), time_stamp)
|
||||||
.expect("Sending end success TM failed");
|
.expect("sending completio success verification failed");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(true)
|
Ok(true)
|
||||||
@ -72,7 +72,13 @@ impl PusReplyHandler<ActivePusRequestStd, HkReply> for HkReplyHandler {
|
|||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
_tm_sender: &impl EcssTmSenderCore,
|
_tm_sender: &impl EcssTmSenderCore,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
generic_pus_request_timeout_handler(active_request, verification_handler, time_stamp, "HK")
|
generic_pus_request_timeout_handler(
|
||||||
|
active_request,
|
||||||
|
verification_handler,
|
||||||
|
time_stamp,
|
||||||
|
"HK",
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +95,7 @@ impl Default for ExampleHkRequestConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PusTcToRequestConverter<ActivePusRequestStd, HkRequest> for ExampleHkRequestConverter {
|
impl PusTcToRequestConverter<ActivePusRequestStd, HkRequest> for ExampleHkRequestConverter {
|
||||||
type Error = PusPacketHandlingError;
|
type Error = GenericConversionError;
|
||||||
|
|
||||||
fn convert(
|
fn convert(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -112,7 +118,7 @@ impl PusTcToRequestConverter<ActivePusRequestStd, HkRequest> for ExampleHkReques
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.expect("Sending start failure TM failed");
|
.expect("Sending start failure TM failed");
|
||||||
return Err(PusPacketHandlingError::NotEnoughAppData {
|
return Err(GenericConversionError::NotEnoughAppData {
|
||||||
expected: 4,
|
expected: 4,
|
||||||
found: 0,
|
found: 0,
|
||||||
});
|
});
|
||||||
@ -128,7 +134,7 @@ impl PusTcToRequestConverter<ActivePusRequestStd, HkRequest> for ExampleHkReques
|
|||||||
verif_reporter
|
verif_reporter
|
||||||
.start_failure(token, FailParams::new(time_stamp, err, &user_data_len_raw))
|
.start_failure(token, FailParams::new(time_stamp, err, &user_data_len_raw))
|
||||||
.expect("Sending start failure TM failed");
|
.expect("Sending start failure TM failed");
|
||||||
return Err(PusPacketHandlingError::NotEnoughAppData {
|
return Err(GenericConversionError::NotEnoughAppData {
|
||||||
expected: 8,
|
expected: 8,
|
||||||
found: 4,
|
found: 4,
|
||||||
});
|
});
|
||||||
@ -145,7 +151,7 @@ impl PusTcToRequestConverter<ActivePusRequestStd, HkRequest> for ExampleHkReques
|
|||||||
FailParams::new(time_stamp, &tmtc_err::INVALID_PUS_SUBSERVICE, &[subservice]),
|
FailParams::new(time_stamp, &tmtc_err::INVALID_PUS_SUBSERVICE, &[subservice]),
|
||||||
)
|
)
|
||||||
.expect("Sending start failure TM failed");
|
.expect("Sending start failure TM failed");
|
||||||
return Err(PusPacketHandlingError::InvalidSubservice(subservice));
|
return Err(GenericConversionError::InvalidSubservice(subservice));
|
||||||
}
|
}
|
||||||
let request = match standard_subservice.unwrap() {
|
let request = match standard_subservice.unwrap() {
|
||||||
hk::Subservice::TcEnableHkGeneration | hk::Subservice::TcEnableDiagGeneration => {
|
hk::Subservice::TcEnableHkGeneration | hk::Subservice::TcEnableDiagGeneration => {
|
||||||
@ -171,7 +177,7 @@ impl PusTcToRequestConverter<ActivePusRequestStd, HkRequest> for ExampleHkReques
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.expect("Sending start failure TM failed");
|
.expect("Sending start failure TM failed");
|
||||||
return Err(PusPacketHandlingError::NotEnoughAppData {
|
return Err(GenericConversionError::NotEnoughAppData {
|
||||||
expected: 12,
|
expected: 12,
|
||||||
found: user_data.len(),
|
found: user_data.len(),
|
||||||
});
|
});
|
||||||
@ -192,12 +198,13 @@ impl PusTcToRequestConverter<ActivePusRequestStd, HkRequest> for ExampleHkReques
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.expect("Sending start failure TM failed");
|
.expect("Sending start failure TM failed");
|
||||||
return Err(PusPacketHandlingError::InvalidSubservice(subservice));
|
return Err(GenericConversionError::InvalidSubservice(subservice));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let token = verif_reporter
|
let token = verif_reporter
|
||||||
.start_success(token, time_stamp)
|
.start_success(token, time_stamp)
|
||||||
.map_err(|e| e.0)?;
|
.expect("Sending start success verification failed");
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
ActivePusRequestStd::new(target_id_and_apid.into(), token, self.timeout),
|
ActivePusRequestStd::new(target_id_and_apid.into(), token, self.timeout),
|
||||||
request,
|
request,
|
||||||
@ -239,9 +246,11 @@ pub fn create_hk_service_static(
|
|||||||
DefaultActiveRequestMap::default(),
|
DefaultActiveRequestMap::default(),
|
||||||
HkReplyHandler::default(),
|
HkReplyHandler::default(),
|
||||||
request_router,
|
request_router,
|
||||||
reply_receiver
|
reply_receiver,
|
||||||
);
|
);
|
||||||
Pus3Wrapper { pus_3_handler }
|
Pus3Wrapper {
|
||||||
|
service: pus_3_handler,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_hk_service_dynamic(
|
pub fn create_hk_service_dynamic(
|
||||||
@ -275,9 +284,11 @@ pub fn create_hk_service_dynamic(
|
|||||||
DefaultActiveRequestMap::default(),
|
DefaultActiveRequestMap::default(),
|
||||||
HkReplyHandler::default(),
|
HkReplyHandler::default(),
|
||||||
request_router,
|
request_router,
|
||||||
reply_receiver
|
reply_receiver,
|
||||||
);
|
);
|
||||||
Pus3Wrapper { pus_3_handler }
|
Pus3Wrapper {
|
||||||
|
service: pus_3_handler,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Pus3Wrapper<
|
pub struct Pus3Wrapper<
|
||||||
@ -286,7 +297,7 @@ pub struct Pus3Wrapper<
|
|||||||
TcInMemConverter: EcssTcInMemConverter,
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
> {
|
> {
|
||||||
pub(crate) pus_3_handler: PusTargetedRequestService<
|
pub(crate) service: PusTargetedRequestService<
|
||||||
TcReceiver,
|
TcReceiver,
|
||||||
TmSender,
|
TmSender,
|
||||||
TcInMemConverter,
|
TcInMemConverter,
|
||||||
@ -307,8 +318,8 @@ impl<
|
|||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
> Pus3Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
> Pus3Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
||||||
{
|
{
|
||||||
pub fn handle_next_packet(&mut self, time_stamp: &[u8]) -> bool {
|
pub fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> bool {
|
||||||
match self.pus_3_handler.handle_one_tc(time_stamp) {
|
match self.service.poll_and_handle_next_tc(time_stamp) {
|
||||||
Ok(result) => match result {
|
Ok(result) => match result {
|
||||||
PusPacketHandlerResult::RequestHandled => {}
|
PusPacketHandlerResult::RequestHandled => {}
|
||||||
PusPacketHandlerResult::RequestHandledPartialSuccess(e) => {
|
PusPacketHandlerResult::RequestHandledPartialSuccess(e) => {
|
||||||
@ -330,4 +341,14 @@ impl<
|
|||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn poll_and_handle_next_reply(&mut self, time_stamp: &[u8]) -> bool {
|
||||||
|
match self.service.poll_and_check_next_reply(time_stamp) {
|
||||||
|
Ok(packet_handled) => packet_handled,
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("PUS 3: Handling reply failed with error {e:?}");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
use crate::requests::GenericRequestRouter;
|
use crate::requests::GenericRequestRouter;
|
||||||
use crate::tmtc::MpscStoreAndSendError;
|
use crate::tmtc::MpscStoreAndSendError;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use satrs::pus::action::ActivePusActionRequestStd;
|
use satrs::pus::verification::{
|
||||||
use satrs::pus::verification::{self, FailParams, VerificationReportingProvider};
|
self, FailParams, TcStateAccepted, VerificationReportingProvider, VerificationToken,
|
||||||
|
};
|
||||||
use satrs::pus::{
|
use satrs::pus::{
|
||||||
ActiveRequestMapProvider, ActiveRequestProvider, EcssTcAndToken, EcssTcInMemConverter,
|
ActiveRequestMapProvider, ActiveRequestProvider, EcssTcAndToken, EcssTcInMemConverter,
|
||||||
EcssTcReceiverCore, EcssTmSenderCore, EcssTmtcError, GenericRoutingError,
|
EcssTcReceiverCore, EcssTmSenderCore, EcssTmtcError, GenericConversionError,
|
||||||
PusPacketHandlerResult, PusPacketHandlingError, PusReplyHandler, PusRequestRouter,
|
GenericRoutingError, PusPacketHandlerResult, PusPacketHandlingError, PusReplyHandler,
|
||||||
PusServiceHelper, PusTcToRequestConverter, TcInMemory,
|
PusRequestRouter, PusServiceHelper, PusTcToRequestConverter, TcInMemory,
|
||||||
};
|
};
|
||||||
use satrs::queue::GenericReceiveError;
|
use satrs::queue::GenericReceiveError;
|
||||||
use satrs::request::{GenericMessage, MessageReceiver, MessageSender, MessageSenderAndReceiver};
|
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;
|
||||||
@ -79,12 +80,32 @@ impl<VerificationReporter: VerificationReportingProvider> PusReceiver<Verificati
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This is a generic handler class for all PUS services where a PUS telecommand is converted
|
||||||
|
/// to a targeted request.
|
||||||
|
///
|
||||||
|
/// The generic steps for this process are the following
|
||||||
|
///
|
||||||
|
/// 1. Poll for TC packets
|
||||||
|
/// 2. Convert the raw packets to a [PusTcReader].
|
||||||
|
/// 3. Convert the PUS TC to a typed request using the [PusTcToRequestConverter].
|
||||||
|
/// 4. Route the requests using the [GenericRequestRouter].
|
||||||
|
/// 5. Add the request to the active request map using the [ActiveRequestMapProvider] abstraction.
|
||||||
|
/// 6. Check for replies which complete the forwarded request. The handler takes care of
|
||||||
|
/// the verification process.
|
||||||
|
/// 7. Check for timeouts of active requests. Generally, the timeout on the service level should
|
||||||
|
/// be highest expected timeout for the given target.
|
||||||
|
///
|
||||||
|
/// The handler exposes the following API:
|
||||||
|
///
|
||||||
|
/// 1. [Self::handle_one_tc] which tries to poll and handle one TC packet, covering steps 1-5.
|
||||||
|
/// 2. [Self::check_one_reply] which tries to poll and handle one reply, covering step 6.
|
||||||
|
/// 3. [Self::check_for_request_timeouts] which checks for request timeouts, covering step 7.
|
||||||
pub struct PusTargetedRequestService<
|
pub struct PusTargetedRequestService<
|
||||||
TcReceiver: EcssTcReceiverCore,
|
TcReceiver: EcssTcReceiverCore,
|
||||||
TmSender: EcssTmSenderCore,
|
TmSender: EcssTmSenderCore,
|
||||||
TcInMemConverter: EcssTcInMemConverter,
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = PusPacketHandlingError>,
|
RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = GenericConversionError>,
|
||||||
ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>,
|
ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>,
|
||||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestInfo>,
|
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestInfo>,
|
||||||
ActiveRequestInfo: ActiveRequestProvider,
|
ActiveRequestInfo: ActiveRequestProvider,
|
||||||
@ -106,7 +127,7 @@ impl<
|
|||||||
TmSender: EcssTmSenderCore,
|
TmSender: EcssTmSenderCore,
|
||||||
TcInMemConverter: EcssTcInMemConverter,
|
TcInMemConverter: EcssTcInMemConverter,
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = PusPacketHandlingError>,
|
RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = GenericConversionError>,
|
||||||
ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>,
|
ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>,
|
||||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestInfo>,
|
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestInfo>,
|
||||||
ActiveRequestInfo: ActiveRequestProvider,
|
ActiveRequestInfo: ActiveRequestProvider,
|
||||||
@ -152,7 +173,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_one_tc(
|
pub fn poll_and_handle_next_tc(
|
||||||
&mut self,
|
&mut self,
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
||||||
@ -161,52 +182,103 @@ where
|
|||||||
return Ok(PusPacketHandlerResult::Empty);
|
return Ok(PusPacketHandlerResult::Empty);
|
||||||
}
|
}
|
||||||
let ecss_tc_and_token = possible_packet.unwrap();
|
let ecss_tc_and_token = possible_packet.unwrap();
|
||||||
let tc = self
|
self.service_helper
|
||||||
.service_helper
|
.tc_in_mem_converter_mut()
|
||||||
.tc_in_mem_converter
|
.cache(&ecss_tc_and_token.tc_in_memory)?;
|
||||||
.convert_ecss_tc_in_memory_to_reader(&ecss_tc_and_token.tc_in_memory)?;
|
let tc = self.service_helper.tc_in_mem_converter().convert()?;
|
||||||
let (request_info, request) = self.request_converter.convert(
|
let (request_info, request) = match self.request_converter.convert(
|
||||||
ecss_tc_and_token.token,
|
ecss_tc_and_token.token,
|
||||||
&tc,
|
&tc,
|
||||||
time_stamp,
|
time_stamp,
|
||||||
&self.service_helper.common.verification_handler,
|
&self.service_helper.common.verif_reporter,
|
||||||
)?;
|
) {
|
||||||
|
Ok((info, req)) => (info, req),
|
||||||
|
Err(e) => {
|
||||||
|
self.handle_conversion_to_request_error(&e, ecss_tc_and_token.token, time_stamp);
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
|
};
|
||||||
let verif_request_id = verification::RequestId::new(&tc);
|
let verif_request_id = verification::RequestId::new(&tc);
|
||||||
if let Err(e) =
|
//if let Err(e) =
|
||||||
self.request_router
|
match self
|
||||||
|
.request_router
|
||||||
.route(request_info.target_id(), request, request_info.token())
|
.route(request_info.target_id(), request, request_info.token())
|
||||||
{
|
{
|
||||||
let target_id = request_info.target_id();
|
Ok(()) => {
|
||||||
self.active_request_map
|
self.active_request_map
|
||||||
.insert(&verif_request_id.into(), request_info);
|
.insert(&verif_request_id.into(), request_info);
|
||||||
self.request_router.handle_error(
|
}
|
||||||
target_id,
|
Err(e) => {
|
||||||
request_info.token(),
|
self.request_router.handle_error_generic(
|
||||||
|
&request_info,
|
||||||
&tc,
|
&tc,
|
||||||
e.clone(),
|
e,
|
||||||
time_stamp,
|
time_stamp,
|
||||||
&self.service_helper.common.verification_handler,
|
self.service_helper.verif_reporter(),
|
||||||
);
|
);
|
||||||
return Err(e.into());
|
}
|
||||||
}
|
}
|
||||||
Ok(PusPacketHandlerResult::RequestHandled)
|
Ok(PusPacketHandlerResult::RequestHandled)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_one_reply(&mut self, time_stamp: &[u8]) -> Result<bool, EcssTmtcError> {
|
fn handle_conversion_to_request_error(
|
||||||
|
&mut self,
|
||||||
|
error: &GenericConversionError,
|
||||||
|
token: VerificationToken<TcStateAccepted>,
|
||||||
|
time_stamp: &[u8],
|
||||||
|
) {
|
||||||
|
match error {
|
||||||
|
GenericConversionError::WrongService(service) => {
|
||||||
|
let service_slice: [u8; 1] = [*service];
|
||||||
|
self.service_helper
|
||||||
|
.verif_reporter()
|
||||||
|
.completion_failure(
|
||||||
|
token,
|
||||||
|
FailParams::new(time_stamp, &tmtc_err::INVALID_PUS_SERVICE, &service_slice),
|
||||||
|
)
|
||||||
|
.expect("Sending completion failure failed");
|
||||||
|
}
|
||||||
|
GenericConversionError::InvalidSubservice(subservice) => {
|
||||||
|
let subservice_slice: [u8; 1] = [*subservice];
|
||||||
|
self.service_helper
|
||||||
|
.verif_reporter()
|
||||||
|
.completion_failure(
|
||||||
|
token,
|
||||||
|
FailParams::new(
|
||||||
|
time_stamp,
|
||||||
|
&tmtc_err::INVALID_PUS_SUBSERVICE,
|
||||||
|
&subservice_slice,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.expect("Sending completion failure failed");
|
||||||
|
}
|
||||||
|
GenericConversionError::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());
|
||||||
|
self.service_helper
|
||||||
|
.verif_reporter()
|
||||||
|
.completion_failure(
|
||||||
|
token,
|
||||||
|
FailParams::new(time_stamp, &tmtc_err::NOT_ENOUGH_APP_DATA, &context_info),
|
||||||
|
)
|
||||||
|
.expect("Sending completion failure failed");
|
||||||
|
}
|
||||||
|
// Do nothing.. this is service-level and can not be handled generically here.
|
||||||
|
GenericConversionError::InvalidAppData(_) => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn poll_and_check_next_reply(&mut self, time_stamp: &[u8]) -> Result<bool, EcssTmtcError> {
|
||||||
match self.reply_receiver.try_recv() {
|
match self.reply_receiver.try_recv() {
|
||||||
Ok(reply) => {
|
Ok(reply) => {
|
||||||
self.handle_reply(&reply, time_stamp)?;
|
self.handle_reply(&reply, time_stamp)?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
mpsc::TryRecvError::Empty => {
|
mpsc::TryRecvError::Empty => Ok(false),
|
||||||
return Ok(false);
|
mpsc::TryRecvError::Disconnected => Err(EcssTmtcError::Receive(
|
||||||
}
|
GenericReceiveError::TxDisconnected(None),
|
||||||
mpsc::TryRecvError::Disconnected => {
|
)),
|
||||||
return Err(EcssTmtcError::Receive(GenericReceiveError::TxDisconnected(
|
|
||||||
None,
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,6 +292,7 @@ where
|
|||||||
if active_req_opt.is_none() {
|
if active_req_opt.is_none() {
|
||||||
self.reply_handler
|
self.reply_handler
|
||||||
.handle_unexpected_reply(reply, &self.service_helper.common.tm_sender)?;
|
.handle_unexpected_reply(reply, &self.service_helper.common.tm_sender)?;
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
let active_request = active_req_opt.unwrap();
|
let active_request = active_req_opt.unwrap();
|
||||||
let request_finished = self
|
let request_finished = self
|
||||||
@ -227,7 +300,7 @@ where
|
|||||||
.handle_reply(
|
.handle_reply(
|
||||||
reply,
|
reply,
|
||||||
active_request,
|
active_request,
|
||||||
&self.service_helper.common.verification_handler,
|
&self.service_helper.common.verif_reporter,
|
||||||
time_stamp,
|
time_stamp,
|
||||||
&self.service_helper.common.tm_sender,
|
&self.service_helper.common.tm_sender,
|
||||||
)
|
)
|
||||||
@ -270,7 +343,8 @@ pub fn generic_pus_request_timeout_handler(
|
|||||||
&[],
|
&[],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.map_err(|e| e.0)
|
.map_err(|e| e.0)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<VerificationReporter: VerificationReportingProvider> PusReceiver<VerificationReporter> {
|
impl<VerificationReporter: VerificationReportingProvider> PusReceiver<VerificationReporter> {
|
||||||
|
@ -18,8 +18,8 @@ pub struct PusStack<
|
|||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
> {
|
> {
|
||||||
event_srv: Pus5Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
event_srv: Pus5Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
||||||
hk_srv: Pus3Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
hk_srv_wrapper: Pus3Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
||||||
action_srv: Pus8Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
action_srv_wrapper: Pus8Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
||||||
schedule_srv: Pus11Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
schedule_srv: Pus11Wrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
||||||
test_srv: Service17CustomWrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
test_srv: Service17CustomWrapper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
||||||
}
|
}
|
||||||
@ -45,10 +45,10 @@ impl<
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
event_srv,
|
event_srv,
|
||||||
action_srv,
|
action_srv_wrapper: action_srv,
|
||||||
schedule_srv,
|
schedule_srv,
|
||||||
test_srv,
|
test_srv,
|
||||||
hk_srv,
|
hk_srv_wrapper: hk_srv,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,18 +59,33 @@ impl<
|
|||||||
.to_vec()
|
.to_vec()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
loop {
|
loop {
|
||||||
let mut all_queues_empty = true;
|
let mut nothing_to_do = true;
|
||||||
let mut is_srv_finished = |srv_handler_finished: bool| {
|
let mut is_srv_finished =
|
||||||
if !srv_handler_finished {
|
|tc_handling_done: bool, reply_handling_done: Option<bool>| {
|
||||||
all_queues_empty = false;
|
if !tc_handling_done
|
||||||
|
|| (reply_handling_done.is_some() && !reply_handling_done.unwrap())
|
||||||
|
{
|
||||||
|
nothing_to_do = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
is_srv_finished(self.test_srv.handle_next_packet(&time_stamp));
|
is_srv_finished(self.test_srv.handle_next_packet(&time_stamp), None);
|
||||||
is_srv_finished(self.schedule_srv.handle_next_packet(&time_stamp));
|
is_srv_finished(self.schedule_srv.handle_next_packet(&time_stamp), None);
|
||||||
is_srv_finished(self.event_srv.handle_next_packet(&time_stamp));
|
is_srv_finished(self.event_srv.handle_next_packet(&time_stamp), None);
|
||||||
is_srv_finished(self.action_srv.handle_next_packet(&time_stamp));
|
is_srv_finished(
|
||||||
is_srv_finished(self.hk_srv.handle_next_packet(&time_stamp));
|
self.action_srv_wrapper.poll_and_handle_next_tc(&time_stamp),
|
||||||
if all_queues_empty {
|
Some(
|
||||||
|
self.action_srv_wrapper
|
||||||
|
.poll_and_handle_next_reply(&time_stamp),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
is_srv_finished(
|
||||||
|
self.hk_srv_wrapper.poll_and_handle_next_tc(&time_stamp),
|
||||||
|
Some(self.hk_srv_wrapper.poll_and_handle_next_reply(&time_stamp)),
|
||||||
|
);
|
||||||
|
if nothing_to_do {
|
||||||
|
// Timeout checking is only done once.
|
||||||
|
self.action_srv_wrapper.service.check_for_request_timeouts();
|
||||||
|
self.hk_srv_wrapper.service.check_for_request_timeouts();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,22 +150,19 @@ impl<
|
|||||||
let start_token = self
|
let start_token = self
|
||||||
.pus17_handler
|
.pus17_handler
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.verification_handler
|
|
||||||
.start_success(token, &stamp_buf)
|
.start_success(token, &stamp_buf)
|
||||||
.expect("Error sending start success");
|
.expect("Error sending start success");
|
||||||
self.pus17_handler
|
self.pus17_handler
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.verification_handler
|
|
||||||
.completion_success(start_token, &stamp_buf)
|
.completion_success(start_token, &stamp_buf)
|
||||||
.expect("Error sending completion success");
|
.expect("Error sending completion success");
|
||||||
} else {
|
} else {
|
||||||
let fail_data = [tc.subservice()];
|
let fail_data = [tc.subservice()];
|
||||||
self.pus17_handler
|
self.pus17_handler
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.verification_handler
|
|
||||||
.start_failure(
|
.start_failure(
|
||||||
token,
|
token,
|
||||||
FailParams::new(
|
FailParams::new(
|
||||||
|
@ -7,13 +7,13 @@ use satrs::hk::HkRequest;
|
|||||||
use satrs::mode::ModeRequest;
|
use satrs::mode::ModeRequest;
|
||||||
use satrs::pus::action::ActionRequestWithId;
|
use satrs::pus::action::ActionRequestWithId;
|
||||||
use satrs::pus::verification::{
|
use satrs::pus::verification::{
|
||||||
FailParams, TcStateAccepted, VerificationReportingProvider, VerificationToken,
|
FailParams, TcStateStarted, VerificationReportingProvider, VerificationToken,
|
||||||
};
|
};
|
||||||
use satrs::pus::{GenericRoutingError, PusRequestRouter};
|
use satrs::pus::{ActiveRequestProvider, GenericRoutingError, PusRequestRouter};
|
||||||
use satrs::queue::GenericSendError;
|
use satrs::queue::GenericSendError;
|
||||||
use satrs::spacepackets::ecss::tc::PusTcReader;
|
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||||
use satrs::spacepackets::ecss::PusPacket;
|
use satrs::spacepackets::ecss::PusPacket;
|
||||||
use satrs::TargetId;
|
use satrs::ComponentId;
|
||||||
use satrs_example::config::tmtc_err;
|
use satrs_example::config::tmtc_err;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -27,21 +27,21 @@ pub enum Request {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, new)]
|
#[derive(Clone, Debug, new)]
|
||||||
pub struct TargetedRequest {
|
pub struct TargetedRequest {
|
||||||
pub(crate) target_id: TargetId,
|
pub(crate) target_id: ComponentId,
|
||||||
pub(crate) request: Request,
|
pub(crate) request: Request,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RequestWithToken {
|
pub struct RequestWithToken {
|
||||||
pub(crate) targeted_request: TargetedRequest,
|
pub(crate) targeted_request: TargetedRequest,
|
||||||
pub(crate) token: VerificationToken<TcStateAccepted>,
|
pub(crate) token: VerificationToken<TcStateStarted>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RequestWithToken {
|
impl RequestWithToken {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
target_id: TargetId,
|
target_id: ComponentId,
|
||||||
request: Request,
|
request: Request,
|
||||||
token: VerificationToken<TcStateAccepted>,
|
token: VerificationToken<TcStateStarted>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
targeted_request: TargetedRequest::new(target_id, request),
|
targeted_request: TargetedRequest::new(target_id, request),
|
||||||
@ -51,15 +51,12 @@ impl RequestWithToken {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct GenericRequestRouter(pub HashMap<TargetId, mpsc::Sender<RequestWithToken>>);
|
pub struct GenericRequestRouter(pub HashMap<ComponentId, mpsc::Sender<RequestWithToken>>);
|
||||||
|
|
||||||
impl GenericRequestRouter {
|
impl GenericRequestRouter {
|
||||||
fn handle_error_generic(
|
pub(crate) fn handle_error_generic(
|
||||||
&self,
|
&self,
|
||||||
target_id: satrs::TargetId,
|
active_request: &impl ActiveRequestProvider,
|
||||||
token: satrs::pus::verification::VerificationToken<
|
|
||||||
satrs::pus::verification::TcStateAccepted,
|
|
||||||
>,
|
|
||||||
tc: &PusTcReader,
|
tc: &PusTcReader,
|
||||||
error: GenericRoutingError,
|
error: GenericRoutingError,
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
@ -74,32 +71,22 @@ impl GenericRequestRouter {
|
|||||||
let mut fail_data: [u8; 8] = [0; 8];
|
let mut fail_data: [u8; 8] = [0; 8];
|
||||||
fail_data.copy_from_slice(&id.to_be_bytes());
|
fail_data.copy_from_slice(&id.to_be_bytes());
|
||||||
verif_reporter
|
verif_reporter
|
||||||
.start_failure(
|
.completion_failure(
|
||||||
token,
|
active_request.token(),
|
||||||
FailParams::new(time_stamp, &tmtc_err::UNKNOWN_TARGET_ID, &fail_data),
|
FailParams::new(time_stamp, &tmtc_err::UNKNOWN_TARGET_ID, &fail_data),
|
||||||
)
|
)
|
||||||
.expect("Sending start failure failed");
|
.expect("Sending start failure failed");
|
||||||
}
|
}
|
||||||
GenericRoutingError::SendError(_) => {
|
GenericRoutingError::Send(_) => {
|
||||||
let mut fail_data: [u8; 8] = [0; 8];
|
let mut fail_data: [u8; 8] = [0; 8];
|
||||||
fail_data.copy_from_slice(&target_id.to_be_bytes());
|
fail_data.copy_from_slice(&active_request.target_id().to_be_bytes());
|
||||||
verif_reporter
|
verif_reporter
|
||||||
.start_failure(
|
.completion_failure(
|
||||||
token,
|
active_request.token(),
|
||||||
FailParams::new(time_stamp, &tmtc_err::ROUTING_ERROR, &fail_data),
|
FailParams::new(time_stamp, &tmtc_err::ROUTING_ERROR, &fail_data),
|
||||||
)
|
)
|
||||||
.expect("Sending start failure failed");
|
.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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,9 +95,9 @@ impl PusRequestRouter<HkRequest> for GenericRequestRouter {
|
|||||||
|
|
||||||
fn route(
|
fn route(
|
||||||
&self,
|
&self,
|
||||||
target_id: TargetId,
|
target_id: ComponentId,
|
||||||
hk_request: HkRequest,
|
hk_request: HkRequest,
|
||||||
token: VerificationToken<TcStateAccepted>,
|
token: VerificationToken<TcStateStarted>,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
if let Some(sender) = self.0.get(&target_id) {
|
if let Some(sender) = self.0.get(&target_id) {
|
||||||
sender
|
sender
|
||||||
@ -119,23 +106,10 @@ impl PusRequestRouter<HkRequest> for GenericRequestRouter {
|
|||||||
Request::Hk(hk_request),
|
Request::Hk(hk_request),
|
||||||
token,
|
token,
|
||||||
))
|
))
|
||||||
.map_err(|_| GenericRoutingError::SendError(GenericSendError::RxDisconnected))?;
|
.map_err(|_| GenericRoutingError::Send(GenericSendError::RxDisconnected))?;
|
||||||
}
|
}
|
||||||
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<ActionRequestWithId> for GenericRequestRouter {
|
impl PusRequestRouter<ActionRequestWithId> for GenericRequestRouter {
|
||||||
@ -143,9 +117,9 @@ impl PusRequestRouter<ActionRequestWithId> for GenericRequestRouter {
|
|||||||
|
|
||||||
fn route(
|
fn route(
|
||||||
&self,
|
&self,
|
||||||
target_id: TargetId,
|
target_id: ComponentId,
|
||||||
action_request: ActionRequestWithId,
|
action_request: ActionRequestWithId,
|
||||||
token: VerificationToken<TcStateAccepted>,
|
token: VerificationToken<TcStateStarted>,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
if let Some(sender) = self.0.get(&target_id) {
|
if let Some(sender) = self.0.get(&target_id) {
|
||||||
sender
|
sender
|
||||||
@ -154,21 +128,8 @@ impl PusRequestRouter<ActionRequestWithId> for GenericRequestRouter {
|
|||||||
Request::Action(action_request),
|
Request::Action(action_request),
|
||||||
token,
|
token,
|
||||||
))
|
))
|
||||||
.map_err(|_| GenericRoutingError::SendError(GenericSendError::RxDisconnected))?;
|
.map_err(|_| GenericRoutingError::Send(GenericSendError::RxDisconnected))?;
|
||||||
}
|
}
|
||||||
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,7 +1,4 @@
|
|||||||
use crate::{
|
use crate::ComponentId;
|
||||||
pus::verification::{TcStateAccepted, VerificationToken},
|
|
||||||
TargetId,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub type CollectionIntervalFactor = u32;
|
pub type CollectionIntervalFactor = u32;
|
||||||
pub type UniqueId = u32;
|
pub type UniqueId = u32;
|
||||||
@ -16,25 +13,15 @@ pub enum HkRequest {
|
|||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct TargetedHkRequest {
|
pub struct TargetedHkRequest {
|
||||||
pub target_id: TargetId,
|
pub target_id: ComponentId,
|
||||||
pub hk_request: HkRequest,
|
pub hk_request: HkRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TargetedHkRequest {
|
impl TargetedHkRequest {
|
||||||
pub fn new(target_id: TargetId, hk_request: HkRequest) -> Self {
|
pub fn new(target_id: ComponentId, hk_request: HkRequest) -> Self {
|
||||||
Self {
|
Self {
|
||||||
target_id,
|
target_id,
|
||||||
hk_request,
|
hk_request,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PusHkRequestRouter {
|
|
||||||
type Error;
|
|
||||||
fn route(
|
|
||||||
&self,
|
|
||||||
target_id: TargetId,
|
|
||||||
hk_request: HkRequest,
|
|
||||||
token: VerificationToken<TcStateAccepted>,
|
|
||||||
) -> Result<(), Self::Error>;
|
|
||||||
}
|
|
||||||
|
@ -35,7 +35,6 @@ pub mod hal;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||||
pub mod mode_tree;
|
pub mod mode_tree;
|
||||||
pub mod objects;
|
|
||||||
pub mod pool;
|
pub mod pool;
|
||||||
pub mod power;
|
pub mod power;
|
||||||
pub mod pus;
|
pub mod pus;
|
||||||
@ -55,5 +54,5 @@ pub use spacepackets;
|
|||||||
|
|
||||||
pub use queue::ChannelId;
|
pub use queue::ChannelId;
|
||||||
|
|
||||||
/// Generic target ID type.
|
/// Generic component ID type.
|
||||||
pub type TargetId = u64;
|
pub type ComponentId = u64;
|
||||||
|
@ -13,7 +13,7 @@ pub use std_mod::*;
|
|||||||
use crate::{
|
use crate::{
|
||||||
queue::GenericTargetedMessagingError,
|
queue::GenericTargetedMessagingError,
|
||||||
request::{GenericMessage, MessageReceiver, MessageReceiverWithId, RequestId},
|
request::{GenericMessage, MessageReceiver, MessageReceiverWithId, RequestId},
|
||||||
ChannelId, TargetId,
|
ChannelId, ComponentId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type Mode = u32;
|
pub type Mode = u32;
|
||||||
@ -77,19 +77,19 @@ impl ModeAndSubmode {
|
|||||||
#[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 struct TargetedModeCommand {
|
pub struct TargetedModeCommand {
|
||||||
pub address: TargetId,
|
pub address: ComponentId,
|
||||||
pub mode_submode: ModeAndSubmode,
|
pub mode_submode: ModeAndSubmode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TargetedModeCommand {
|
impl TargetedModeCommand {
|
||||||
pub const fn new(address: TargetId, mode_submode: ModeAndSubmode) -> Self {
|
pub const fn new(address: ComponentId, mode_submode: ModeAndSubmode) -> Self {
|
||||||
Self {
|
Self {
|
||||||
address,
|
address,
|
||||||
mode_submode,
|
mode_submode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn address(&self) -> TargetId {
|
pub fn address(&self) -> ComponentId {
|
||||||
self.address
|
self.address
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ pub enum 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 struct TargetedModeRequest {
|
pub struct TargetedModeRequest {
|
||||||
target_id: TargetId,
|
target_id: ComponentId,
|
||||||
mode_request: ModeRequest,
|
mode_request: ModeRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,308 +0,0 @@
|
|||||||
//! # Module providing addressable object support and a manager for them
|
|
||||||
//!
|
|
||||||
//! Each addressable object can be identified using an [object ID][ObjectId].
|
|
||||||
//! The [system object][ManagedSystemObject] trait also allows storing these objects into the
|
|
||||||
//! [object manager][ObjectManager]. They can then be retrieved and casted back to a known type
|
|
||||||
//! using the object ID.
|
|
||||||
//!
|
|
||||||
//! # Examples
|
|
||||||
//!
|
|
||||||
//! ```rust
|
|
||||||
//! use std::any::Any;
|
|
||||||
//! use std::error::Error;
|
|
||||||
//! use satrs::objects::{ManagedSystemObject, ObjectId, ObjectManager, SystemObject};
|
|
||||||
//!
|
|
||||||
//! struct ExampleSysObj {
|
|
||||||
//! id: ObjectId,
|
|
||||||
//! dummy: u32,
|
|
||||||
//! was_initialized: bool,
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl ExampleSysObj {
|
|
||||||
//! fn new(id: ObjectId, dummy: u32) -> ExampleSysObj {
|
|
||||||
//! ExampleSysObj {
|
|
||||||
//! id,
|
|
||||||
//! dummy,
|
|
||||||
//! was_initialized: false,
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl SystemObject for ExampleSysObj {
|
|
||||||
//! type Error = ();
|
|
||||||
//! fn get_object_id(&self) -> &ObjectId {
|
|
||||||
//! &self.id
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! fn initialize(&mut self) -> Result<(), Self::Error> {
|
|
||||||
//! self.was_initialized = true;
|
|
||||||
//! Ok(())
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl ManagedSystemObject for ExampleSysObj {}
|
|
||||||
//!
|
|
||||||
//! let mut obj_manager = ObjectManager::default();
|
|
||||||
//! let obj_id = ObjectId { id: 0, name: "Example 0"};
|
|
||||||
//! let example_obj = ExampleSysObj::new(obj_id, 42);
|
|
||||||
//! obj_manager.insert(Box::new(example_obj));
|
|
||||||
//! let obj_back_casted: Option<&ExampleSysObj> = obj_manager.get_ref(&obj_id);
|
|
||||||
//! let example_obj = obj_back_casted.unwrap();
|
|
||||||
//! assert_eq!(example_obj.id, obj_id);
|
|
||||||
//! assert_eq!(example_obj.dummy, 42);
|
|
||||||
//! ```
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
use alloc::boxed::Box;
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
pub use alloc_mod::*;
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
use downcast_rs::Downcast;
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
use hashbrown::HashMap;
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use std::error::Error;
|
|
||||||
|
|
||||||
use crate::TargetId;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
|
||||||
pub struct ObjectId {
|
|
||||||
pub id: TargetId,
|
|
||||||
pub name: &'static str,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
pub mod alloc_mod {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
/// Each object which is stored inside the [object manager][ObjectManager] needs to implemented
|
|
||||||
/// this trait
|
|
||||||
pub trait SystemObject: Downcast {
|
|
||||||
type Error;
|
|
||||||
fn get_object_id(&self) -> &ObjectId;
|
|
||||||
fn initialize(&mut self) -> Result<(), Self::Error>;
|
|
||||||
}
|
|
||||||
downcast_rs::impl_downcast!(SystemObject assoc Error);
|
|
||||||
|
|
||||||
pub trait ManagedSystemObject: SystemObject + Send {}
|
|
||||||
downcast_rs::impl_downcast!(ManagedSystemObject assoc Error);
|
|
||||||
|
|
||||||
/// Helper module to manage multiple [ManagedSystemObjects][ManagedSystemObject] by mapping them
|
|
||||||
/// using an [object ID][ObjectId]
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
pub struct ObjectManager<E> {
|
|
||||||
obj_map: HashMap<ObjectId, Box<dyn ManagedSystemObject<Error = E>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
impl<E: 'static> Default for ObjectManager<E> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
impl<E: 'static> ObjectManager<E> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
ObjectManager {
|
|
||||||
obj_map: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn insert(&mut self, sys_obj: Box<dyn ManagedSystemObject<Error = E>>) -> bool {
|
|
||||||
let obj_id = sys_obj.get_object_id();
|
|
||||||
if self.obj_map.contains_key(obj_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
self.obj_map.insert(*obj_id, sys_obj).is_none()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initializes all System Objects in the hash map and returns the number of successful
|
|
||||||
/// initializations
|
|
||||||
pub fn initialize(&mut self) -> Result<u32, Box<dyn Error>> {
|
|
||||||
let mut init_success = 0;
|
|
||||||
for val in self.obj_map.values_mut() {
|
|
||||||
if val.initialize().is_ok() {
|
|
||||||
init_success += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(init_success)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieve a reference to an object stored inside the manager. The type to retrieve needs to
|
|
||||||
/// be explicitly passed as a generic parameter or specified on the left hand side of the
|
|
||||||
/// expression.
|
|
||||||
pub fn get_ref<T: ManagedSystemObject<Error = E>>(&self, key: &ObjectId) -> Option<&T> {
|
|
||||||
self.obj_map.get(key).and_then(|o| o.downcast_ref::<T>())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieve a mutable reference to an object stored inside the manager. The type to retrieve
|
|
||||||
/// needs to be explicitly passed as a generic parameter or specified on the left hand side
|
|
||||||
/// of the expression.
|
|
||||||
pub fn get_mut<T: ManagedSystemObject<Error = E>>(
|
|
||||||
&mut self,
|
|
||||||
key: &ObjectId,
|
|
||||||
) -> Option<&mut T> {
|
|
||||||
self.obj_map
|
|
||||||
.get_mut(key)
|
|
||||||
.and_then(|o| o.downcast_mut::<T>())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::objects::{ManagedSystemObject, ObjectId, ObjectManager, SystemObject};
|
|
||||||
use std::boxed::Box;
|
|
||||||
use std::string::String;
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
struct ExampleSysObj {
|
|
||||||
id: ObjectId,
|
|
||||||
dummy: u32,
|
|
||||||
was_initialized: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExampleSysObj {
|
|
||||||
fn new(id: ObjectId, dummy: u32) -> ExampleSysObj {
|
|
||||||
ExampleSysObj {
|
|
||||||
id,
|
|
||||||
dummy,
|
|
||||||
was_initialized: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SystemObject for ExampleSysObj {
|
|
||||||
type Error = ();
|
|
||||||
fn get_object_id(&self) -> &ObjectId {
|
|
||||||
&self.id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn initialize(&mut self) -> Result<(), Self::Error> {
|
|
||||||
self.was_initialized = true;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ManagedSystemObject for ExampleSysObj {}
|
|
||||||
|
|
||||||
struct OtherExampleObject {
|
|
||||||
id: ObjectId,
|
|
||||||
string: String,
|
|
||||||
was_initialized: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SystemObject for OtherExampleObject {
|
|
||||||
type Error = ();
|
|
||||||
fn get_object_id(&self) -> &ObjectId {
|
|
||||||
&self.id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn initialize(&mut self) -> Result<(), Self::Error> {
|
|
||||||
self.was_initialized = true;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ManagedSystemObject for OtherExampleObject {}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_obj_manager_simple() {
|
|
||||||
let mut obj_manager = ObjectManager::default();
|
|
||||||
let expl_obj_id = ObjectId {
|
|
||||||
id: 0,
|
|
||||||
name: "Example 0",
|
|
||||||
};
|
|
||||||
let example_obj = ExampleSysObj::new(expl_obj_id, 42);
|
|
||||||
assert!(obj_manager.insert(Box::new(example_obj)));
|
|
||||||
let res = obj_manager.initialize();
|
|
||||||
assert!(res.is_ok());
|
|
||||||
assert_eq!(res.unwrap(), 1);
|
|
||||||
let obj_back_casted: Option<&ExampleSysObj> = obj_manager.get_ref(&expl_obj_id);
|
|
||||||
assert!(obj_back_casted.is_some());
|
|
||||||
let expl_obj_back_casted = obj_back_casted.unwrap();
|
|
||||||
assert_eq!(expl_obj_back_casted.dummy, 42);
|
|
||||||
assert!(expl_obj_back_casted.was_initialized);
|
|
||||||
|
|
||||||
let second_obj_id = ObjectId {
|
|
||||||
id: 12,
|
|
||||||
name: "Example 1",
|
|
||||||
};
|
|
||||||
let second_example_obj = OtherExampleObject {
|
|
||||||
id: second_obj_id,
|
|
||||||
string: String::from("Hello Test"),
|
|
||||||
was_initialized: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(obj_manager.insert(Box::new(second_example_obj)));
|
|
||||||
let res = obj_manager.initialize();
|
|
||||||
assert!(res.is_ok());
|
|
||||||
assert_eq!(res.unwrap(), 2);
|
|
||||||
let obj_back_casted: Option<&OtherExampleObject> = obj_manager.get_ref(&second_obj_id);
|
|
||||||
assert!(obj_back_casted.is_some());
|
|
||||||
let expl_obj_back_casted = obj_back_casted.unwrap();
|
|
||||||
assert_eq!(expl_obj_back_casted.string, String::from("Hello Test"));
|
|
||||||
assert!(expl_obj_back_casted.was_initialized);
|
|
||||||
|
|
||||||
let existing_obj_id = ObjectId {
|
|
||||||
id: 12,
|
|
||||||
name: "Example 1",
|
|
||||||
};
|
|
||||||
let invalid_obj = OtherExampleObject {
|
|
||||||
id: existing_obj_id,
|
|
||||||
string: String::from("Hello Test"),
|
|
||||||
was_initialized: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(!obj_manager.insert(Box::new(invalid_obj)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn object_man_threaded() {
|
|
||||||
let obj_manager = Arc::new(Mutex::new(ObjectManager::new()));
|
|
||||||
let expl_obj_id = ObjectId {
|
|
||||||
id: 0,
|
|
||||||
name: "Example 0",
|
|
||||||
};
|
|
||||||
let example_obj = ExampleSysObj::new(expl_obj_id, 42);
|
|
||||||
let second_obj_id = ObjectId {
|
|
||||||
id: 12,
|
|
||||||
name: "Example 1",
|
|
||||||
};
|
|
||||||
let second_example_obj = OtherExampleObject {
|
|
||||||
id: second_obj_id,
|
|
||||||
string: String::from("Hello Test"),
|
|
||||||
was_initialized: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut obj_man_handle = obj_manager.lock().expect("Mutex lock failed");
|
|
||||||
assert!(obj_man_handle.insert(Box::new(example_obj)));
|
|
||||||
assert!(obj_man_handle.insert(Box::new(second_example_obj)));
|
|
||||||
let res = obj_man_handle.initialize();
|
|
||||||
std::mem::drop(obj_man_handle);
|
|
||||||
assert!(res.is_ok());
|
|
||||||
assert_eq!(res.unwrap(), 2);
|
|
||||||
let obj_man_0 = obj_manager.clone();
|
|
||||||
let jh0 = thread::spawn(move || {
|
|
||||||
let locked_man = obj_man_0.lock().expect("Mutex lock failed");
|
|
||||||
let obj_back_casted: Option<&ExampleSysObj> = locked_man.get_ref(&expl_obj_id);
|
|
||||||
assert!(obj_back_casted.is_some());
|
|
||||||
let expl_obj_back_casted = obj_back_casted.unwrap();
|
|
||||||
assert_eq!(expl_obj_back_casted.dummy, 42);
|
|
||||||
assert!(expl_obj_back_casted.was_initialized);
|
|
||||||
std::mem::drop(locked_man)
|
|
||||||
});
|
|
||||||
|
|
||||||
let jh1 = thread::spawn(move || {
|
|
||||||
let locked_man = obj_manager.lock().expect("Mutex lock failed");
|
|
||||||
let obj_back_casted: Option<&OtherExampleObject> = locked_man.get_ref(&second_obj_id);
|
|
||||||
assert!(obj_back_casted.is_some());
|
|
||||||
let expl_obj_back_casted = obj_back_casted.unwrap();
|
|
||||||
assert_eq!(expl_obj_back_casted.string, String::from("Hello Test"));
|
|
||||||
assert!(expl_obj_back_casted.was_initialized);
|
|
||||||
std::mem::drop(locked_man)
|
|
||||||
});
|
|
||||||
jh0.join().expect("Joining thread 0 failed");
|
|
||||||
jh1.join().expect("Joining thread 1 failed");
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,7 @@ use crate::{
|
|||||||
action::{ActionId, ActionRequest},
|
action::{ActionId, ActionRequest},
|
||||||
params::Params,
|
params::Params,
|
||||||
request::{GenericMessage, RequestId},
|
request::{GenericMessage, RequestId},
|
||||||
ChannelId, TargetId,
|
ChannelId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{verification::VerificationToken, ActivePusRequestStd, ActiveRequestProvider};
|
use super::{verification::VerificationToken, ActivePusRequestStd, ActiveRequestProvider};
|
||||||
@ -141,7 +141,10 @@ pub mod alloc_mod {
|
|||||||
pub mod std_mod {
|
pub mod std_mod {
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
use crate::pus::{verification, DefaultActiveRequestMap};
|
use crate::{
|
||||||
|
pus::{verification, DefaultActiveRequestMap},
|
||||||
|
ComponentId,
|
||||||
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -154,7 +157,7 @@ pub mod std_mod {
|
|||||||
impl ActiveRequestProvider for ActivePusActionRequestStd {
|
impl ActiveRequestProvider for ActivePusActionRequestStd {
|
||||||
delegate! {
|
delegate! {
|
||||||
to self.common {
|
to self.common {
|
||||||
fn target_id(&self) -> TargetId;
|
fn target_id(&self) -> ComponentId;
|
||||||
fn token(&self) -> VerificationToken<verification::TcStateStarted>;
|
fn token(&self) -> VerificationToken<verification::TcStateStarted>;
|
||||||
fn has_timed_out(&self) -> bool;
|
fn has_timed_out(&self) -> bool;
|
||||||
fn timeout(&self) -> core::time::Duration;
|
fn timeout(&self) -> core::time::Duration;
|
||||||
@ -165,7 +168,7 @@ pub mod std_mod {
|
|||||||
impl ActivePusActionRequestStd {
|
impl ActivePusActionRequestStd {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
action_id: ActionId,
|
action_id: ActionId,
|
||||||
target_id: TargetId,
|
target_id: ComponentId,
|
||||||
token: VerificationToken<verification::TcStateStarted>,
|
token: VerificationToken<verification::TcStateStarted>,
|
||||||
timeout: core::time::Duration,
|
timeout: core::time::Duration,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -2,12 +2,16 @@ use crate::events::EventU32;
|
|||||||
use crate::pus::event_man::{EventRequest, EventRequestWithToken};
|
use crate::pus::event_man::{EventRequest, EventRequestWithToken};
|
||||||
use crate::pus::verification::TcStateToken;
|
use crate::pus::verification::TcStateToken;
|
||||||
use crate::pus::{PartialPusHandlingError, PusPacketHandlerResult, PusPacketHandlingError};
|
use crate::pus::{PartialPusHandlingError, PusPacketHandlerResult, PusPacketHandlingError};
|
||||||
|
use crate::queue::GenericSendError;
|
||||||
use spacepackets::ecss::event::Subservice;
|
use spacepackets::ecss::event::Subservice;
|
||||||
use spacepackets::ecss::PusPacket;
|
use spacepackets::ecss::PusPacket;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
|
|
||||||
use super::verification::VerificationReportingProvider;
|
use super::verification::VerificationReportingProvider;
|
||||||
use super::{EcssTcInMemConverter, EcssTcReceiverCore, EcssTmSenderCore, PusServiceHelper};
|
use super::{
|
||||||
|
EcssTcInMemConverter, EcssTcReceiverCore, EcssTmSenderCore, GenericConversionError,
|
||||||
|
GenericRoutingError, PusServiceHelper,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct PusService5EventHandler<
|
pub struct PusService5EventHandler<
|
||||||
TcReceiver: EcssTcReceiverCore,
|
TcReceiver: EcssTcReceiverCore,
|
||||||
@ -51,10 +55,10 @@ impl<
|
|||||||
return Ok(PusPacketHandlerResult::Empty);
|
return Ok(PusPacketHandlerResult::Empty);
|
||||||
}
|
}
|
||||||
let ecss_tc_and_token = possible_packet.unwrap();
|
let ecss_tc_and_token = possible_packet.unwrap();
|
||||||
let tc = self
|
self.service_helper
|
||||||
.service_helper
|
.tc_in_mem_converter_mut()
|
||||||
.tc_in_mem_converter
|
.cache(&ecss_tc_and_token.tc_in_memory)?;
|
||||||
.convert_ecss_tc_in_memory_to_reader(&ecss_tc_and_token.tc_in_memory)?;
|
let tc = self.service_helper.tc_in_mem_converter().convert()?;
|
||||||
let subservice = tc.subservice();
|
let subservice = tc.subservice();
|
||||||
let srv = Subservice::try_from(subservice);
|
let srv = Subservice::try_from(subservice);
|
||||||
if srv.is_err() {
|
if srv.is_err() {
|
||||||
@ -63,19 +67,22 @@ impl<
|
|||||||
ecss_tc_and_token.token,
|
ecss_tc_and_token.token,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let handle_enable_disable_request = |enable: bool| {
|
let handle_enable_disable_request =
|
||||||
|
|enable: bool| -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
||||||
if tc.user_data().len() < 4 {
|
if tc.user_data().len() < 4 {
|
||||||
return Err(PusPacketHandlingError::NotEnoughAppData {
|
return Err(GenericConversionError::NotEnoughAppData {
|
||||||
expected: 4,
|
expected: 4,
|
||||||
found: tc.user_data().len(),
|
found: tc.user_data().len(),
|
||||||
});
|
}
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
let user_data = tc.user_data();
|
let user_data = tc.user_data();
|
||||||
let event_u32 = EventU32::from(u32::from_be_bytes(user_data[0..4].try_into().unwrap()));
|
let event_u32 =
|
||||||
|
EventU32::from(u32::from_be_bytes(user_data[0..4].try_into().unwrap()));
|
||||||
let start_token = self
|
let start_token = self
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verif_reporter
|
||||||
.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 partial_error = start_token.clone().err();
|
let partial_error = start_token.clone().err();
|
||||||
@ -97,7 +104,9 @@ impl<
|
|||||||
self.event_request_tx
|
self.event_request_tx
|
||||||
.send(event_req_with_token)
|
.send(event_req_with_token)
|
||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
PusPacketHandlingError::Other("Forwarding event request failed".into())
|
PusPacketHandlingError::RequestRouting(GenericRoutingError::Send(
|
||||||
|
GenericSendError::RxDisconnected,
|
||||||
|
))
|
||||||
})?;
|
})?;
|
||||||
if let Some(partial_error) = partial_error {
|
if let Some(partial_error) = partial_error {
|
||||||
return Ok(PusPacketHandlerResult::RequestHandledPartialSuccess(
|
return Ok(PusPacketHandlerResult::RequestHandledPartialSuccess(
|
||||||
@ -106,12 +115,15 @@ impl<
|
|||||||
}
|
}
|
||||||
Ok(PusPacketHandlerResult::RequestHandled)
|
Ok(PusPacketHandlerResult::RequestHandled)
|
||||||
};
|
};
|
||||||
|
|
||||||
match srv.unwrap() {
|
match srv.unwrap() {
|
||||||
Subservice::TmInfoReport
|
Subservice::TmInfoReport
|
||||||
| Subservice::TmLowSeverityReport
|
| Subservice::TmLowSeverityReport
|
||||||
| Subservice::TmMediumSeverityReport
|
| Subservice::TmMediumSeverityReport
|
||||||
| Subservice::TmHighSeverityReport => {
|
| Subservice::TmHighSeverityReport => {
|
||||||
return Err(PusPacketHandlingError::InvalidSubservice(tc.subservice()))
|
return Err(PusPacketHandlingError::RequestConversion(
|
||||||
|
GenericConversionError::WrongService(tc.subservice()),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
Subservice::TcEnableEventGeneration => {
|
Subservice::TcEnableEventGeneration => {
|
||||||
handle_enable_disable_request(true)?;
|
handle_enable_disable_request(true)?;
|
||||||
@ -151,7 +163,7 @@ mod tests {
|
|||||||
use crate::pus::verification::{
|
use crate::pus::verification::{
|
||||||
RequestId, VerificationReporterWithSharedPoolMpscBoundedSender,
|
RequestId, VerificationReporterWithSharedPoolMpscBoundedSender,
|
||||||
};
|
};
|
||||||
use crate::pus::{MpscTcReceiver, TmInSharedPoolSenderWithBoundedMpsc};
|
use crate::pus::{GenericConversionError, MpscTcReceiver, TmInSharedPoolSenderWithBoundedMpsc};
|
||||||
use crate::{
|
use crate::{
|
||||||
events::EventU32,
|
events::EventU32,
|
||||||
pus::{
|
pus::{
|
||||||
@ -298,7 +310,10 @@ mod tests {
|
|||||||
let result = test_harness.handle_one_tc();
|
let result = test_harness.handle_one_tc();
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
let result = result.unwrap_err();
|
let result = result.unwrap_err();
|
||||||
if let PusPacketHandlingError::NotEnoughAppData { expected, found } = result {
|
if let PusPacketHandlingError::RequestConversion(
|
||||||
|
GenericConversionError::NotEnoughAppData { expected, found },
|
||||||
|
) = result
|
||||||
|
{
|
||||||
assert_eq!(expected, 4);
|
assert_eq!(expected, 4);
|
||||||
assert_eq!(found, 3);
|
assert_eq!(found, 3);
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,7 +6,7 @@ use crate::pool::{StoreAddr, StoreError};
|
|||||||
use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken};
|
use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken};
|
||||||
use crate::queue::{GenericReceiveError, GenericSendError};
|
use crate::queue::{GenericReceiveError, GenericSendError};
|
||||||
use crate::request::{GenericMessage, RequestId};
|
use crate::request::{GenericMessage, RequestId};
|
||||||
use crate::{ChannelId, TargetId};
|
use crate::{ChannelId, ComponentId};
|
||||||
use core::fmt::{Display, Formatter};
|
use core::fmt::{Display, Formatter};
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
@ -287,7 +287,7 @@ pub trait ActiveRequestMapProvider<V>: Sized {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait ActiveRequestProvider {
|
pub trait ActiveRequestProvider {
|
||||||
fn target_id(&self) -> TargetId;
|
fn target_id(&self) -> ComponentId;
|
||||||
fn token(&self) -> VerificationToken<TcStateStarted>;
|
fn token(&self) -> VerificationToken<TcStateStarted>;
|
||||||
fn has_timed_out(&self) -> bool;
|
fn has_timed_out(&self) -> bool;
|
||||||
fn timeout(&self) -> Duration;
|
fn timeout(&self) -> Duration;
|
||||||
@ -300,25 +300,17 @@ pub trait PusRequestRouter<Request> {
|
|||||||
|
|
||||||
fn route(
|
fn route(
|
||||||
&self,
|
&self,
|
||||||
target_id: TargetId,
|
target_id: ComponentId,
|
||||||
request: Request,
|
request: Request,
|
||||||
token: VerificationToken<TcStateAccepted>,
|
token: VerificationToken<TcStateStarted>,
|
||||||
) -> 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,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PusReplyHandler<ActiveRequestInfo: ActiveRequestProvider, ReplyType> {
|
pub trait PusReplyHandler<ActiveRequestInfo: ActiveRequestProvider, ReplyType> {
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
|
/// This function handles a reply for a given PUS request and returns whether that request
|
||||||
|
/// is finished. A finished PUS request will be removed from the active request map.
|
||||||
fn handle_reply(
|
fn handle_reply(
|
||||||
&mut self,
|
&mut self,
|
||||||
reply: &GenericMessage<ReplyType>,
|
reply: &GenericMessage<ReplyType>,
|
||||||
@ -334,6 +326,7 @@ pub trait PusReplyHandler<ActiveRequestInfo: ActiveRequestProvider, ReplyType> {
|
|||||||
tm_sender: &impl EcssTmSenderCore,
|
tm_sender: &impl EcssTmSenderCore,
|
||||||
) -> Result<(), Self::Error>;
|
) -> Result<(), Self::Error>;
|
||||||
|
|
||||||
|
/// Handle the timeout of an active request.
|
||||||
fn handle_request_timeout(
|
fn handle_request_timeout(
|
||||||
&mut self,
|
&mut self,
|
||||||
active_request: &ActiveRequestInfo,
|
active_request: &ActiveRequestInfo,
|
||||||
@ -656,13 +649,14 @@ pub mod std_mod {
|
|||||||
GenericReceiveError, GenericSendError, PusTmWrapper, TryRecvTmtcError,
|
GenericReceiveError, GenericSendError, PusTmWrapper, TryRecvTmtcError,
|
||||||
};
|
};
|
||||||
use crate::tmtc::tm_helper::SharedTmPool;
|
use crate::tmtc::tm_helper::SharedTmPool;
|
||||||
use crate::{ChannelId, TargetId};
|
use crate::{ChannelId, ComponentId};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
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::WritablePusPacket;
|
||||||
use spacepackets::time::StdTimestampError;
|
use spacepackets::time::StdTimestampError;
|
||||||
|
use spacepackets::ByteConversionError;
|
||||||
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;
|
||||||
@ -1059,7 +1053,7 @@ pub mod std_mod {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ActivePusRequestStd {
|
pub struct ActivePusRequestStd {
|
||||||
target_id: TargetId,
|
target_id: ComponentId,
|
||||||
token: VerificationToken<TcStateStarted>,
|
token: VerificationToken<TcStateStarted>,
|
||||||
start_time: std::time::Instant,
|
start_time: std::time::Instant,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
@ -1067,7 +1061,7 @@ pub mod std_mod {
|
|||||||
|
|
||||||
impl ActivePusRequestStd {
|
impl ActivePusRequestStd {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
target_id: TargetId,
|
target_id: ComponentId,
|
||||||
token: VerificationToken<TcStateStarted>,
|
token: VerificationToken<TcStateStarted>,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -1081,7 +1075,7 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ActiveRequestProvider for ActivePusRequestStd {
|
impl ActiveRequestProvider for ActivePusRequestStd {
|
||||||
fn target_id(&self) -> TargetId {
|
fn target_id(&self) -> ComponentId {
|
||||||
self.target_id
|
self.target_id
|
||||||
}
|
}
|
||||||
fn token(&self) -> VerificationToken<TcStateStarted> {
|
fn token(&self) -> VerificationToken<TcStateStarted> {
|
||||||
@ -1102,37 +1096,52 @@ pub mod std_mod {
|
|||||||
// 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 .
|
||||||
|
|
||||||
#[derive(Debug, Clone, Error)]
|
#[derive(Debug, Clone, Error)]
|
||||||
pub enum GenericRoutingError {
|
pub enum PusTcFromMemError {
|
||||||
#[error("not enough application data, expected at least {expected}, found {found}")]
|
#[error("generic PUS error: {0}")]
|
||||||
NotEnoughAppData { expected: usize, found: usize },
|
EcssTmtc(#[from] EcssTmtcError),
|
||||||
#[error("Unknown target ID {0}")]
|
#[error("invalid format of TC in memory: {0:?}")]
|
||||||
UnknownTargetId(TargetId),
|
InvalidFormat(TcInMemory),
|
||||||
#[error("Sending action request failed: {0}")]
|
|
||||||
SendError(GenericSendError),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Error)]
|
#[derive(Debug, Clone, Error)]
|
||||||
pub enum PusPacketHandlingError {
|
pub enum GenericRoutingError {
|
||||||
#[error("generic PUS error: {0}")]
|
// #[error("not enough application data, expected at least {expected}, found {found}")]
|
||||||
Pus(#[from] PusError),
|
// NotEnoughAppData { expected: usize, found: usize },
|
||||||
|
#[error("Unknown target ID {0}")]
|
||||||
|
UnknownTargetId(ComponentId),
|
||||||
|
#[error("Sending action request failed: {0}")]
|
||||||
|
Send(GenericSendError),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This error can be used for generic conversions from PUS Telecommands to request types.
|
||||||
|
///
|
||||||
|
/// Please note that this error can also be used if no request is generated and the PUS
|
||||||
|
/// service, subservice and application data is used directly to perform some request.
|
||||||
|
#[derive(Debug, Clone, Error)]
|
||||||
|
pub enum GenericConversionError {
|
||||||
#[error("wrong service number {0} for packet handler")]
|
#[error("wrong service number {0} for packet handler")]
|
||||||
WrongService(u8),
|
WrongService(u8),
|
||||||
#[error("invalid subservice {0}")]
|
#[error("invalid subservice {0}")]
|
||||||
InvalidSubservice(u8),
|
InvalidSubservice(u8),
|
||||||
#[error("not enough application data, expected at least {expected}, found {found}")]
|
#[error("not enough application data, expected at least {expected}, found {found}")]
|
||||||
NotEnoughAppData { expected: usize, found: usize },
|
NotEnoughAppData { expected: usize, found: usize },
|
||||||
#[error("PUS packet too large, does not fit in buffer: {0}")]
|
|
||||||
PusPacketTooLarge(usize),
|
|
||||||
#[error("invalid application data")]
|
#[error("invalid application data")]
|
||||||
InvalidAppData(String),
|
InvalidAppData(String),
|
||||||
#[error("invalid format of TC in memory: {0:?}")]
|
}
|
||||||
InvalidTcInMemoryFormat(TcInMemory),
|
|
||||||
#[error("generic ECSS tmtc error: {0}")]
|
/// Wrapper type which tries to encapsulate all possible errors when handling PUS packets.
|
||||||
EcssTmtc(#[from] EcssTmtcError),
|
#[derive(Debug, Clone, Error)]
|
||||||
|
pub enum PusPacketHandlingError {
|
||||||
|
#[error("error polling PUS TC packet: {0}")]
|
||||||
|
TcPolling(#[from] EcssTmtcError),
|
||||||
|
#[error("error generating PUS reader from memory: {0}")]
|
||||||
|
TcFromMem(#[from] PusTcFromMemError),
|
||||||
|
#[error("generic request conversion error: {0}")]
|
||||||
|
RequestConversion(#[from] GenericConversionError),
|
||||||
|
#[error("request routing error: {0}")]
|
||||||
|
RequestRouting(#[from] GenericRoutingError),
|
||||||
#[error("invalid verification token")]
|
#[error("invalid verification token")]
|
||||||
InvalidVerificationToken,
|
InvalidVerificationToken,
|
||||||
#[error("request routing error: {0}")]
|
|
||||||
RequestRoutingError(#[from] GenericRoutingError),
|
|
||||||
#[error("other error {0}")]
|
#[error("other error {0}")]
|
||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
@ -1166,19 +1175,24 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait EcssTcInMemConverter {
|
pub trait EcssTcInMemConverter {
|
||||||
fn cache_ecss_tc_in_memory(
|
fn cache(&mut self, possible_packet: &TcInMemory) -> Result<(), PusTcFromMemError>;
|
||||||
&mut self,
|
|
||||||
possible_packet: &TcInMemory,
|
|
||||||
) -> Result<(), PusPacketHandlingError>;
|
|
||||||
|
|
||||||
fn tc_slice_raw(&self) -> &[u8];
|
fn tc_slice_raw(&self) -> &[u8];
|
||||||
|
|
||||||
fn convert_ecss_tc_in_memory_to_reader(
|
fn cache_and_convert(
|
||||||
&mut self,
|
&mut self,
|
||||||
possible_packet: &TcInMemory,
|
possible_packet: &TcInMemory,
|
||||||
) -> Result<PusTcReader<'_>, PusPacketHandlingError> {
|
) -> Result<PusTcReader<'_>, PusTcFromMemError> {
|
||||||
self.cache_ecss_tc_in_memory(possible_packet)?;
|
self.cache(possible_packet)?;
|
||||||
Ok(PusTcReader::new(self.tc_slice_raw())?.0)
|
Ok(PusTcReader::new(self.tc_slice_raw())
|
||||||
|
.map_err(EcssTmtcError::Pus)?
|
||||||
|
.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert(&self) -> Result<PusTcReader<'_>, PusTcFromMemError> {
|
||||||
|
Ok(PusTcReader::new(self.tc_slice_raw())
|
||||||
|
.map_err(EcssTmtcError::Pus)?
|
||||||
|
.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1191,16 +1205,11 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EcssTcInMemConverter for EcssTcInVecConverter {
|
impl EcssTcInMemConverter for EcssTcInVecConverter {
|
||||||
fn cache_ecss_tc_in_memory(
|
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
|
||||||
&mut self,
|
|
||||||
tc_in_memory: &TcInMemory,
|
|
||||||
) -> Result<(), PusPacketHandlingError> {
|
|
||||||
self.pus_tc_raw = None;
|
self.pus_tc_raw = None;
|
||||||
match tc_in_memory {
|
match tc_in_memory {
|
||||||
super::TcInMemory::StoreAddr(_) => {
|
super::TcInMemory::StoreAddr(_) => {
|
||||||
return Err(PusPacketHandlingError::InvalidTcInMemoryFormat(
|
return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone()));
|
||||||
tc_in_memory.clone(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
super::TcInMemory::Vec(vec) => {
|
super::TcInMemory::Vec(vec) => {
|
||||||
self.pus_tc_raw = Some(vec.clone());
|
self.pus_tc_raw = Some(vec.clone());
|
||||||
@ -1234,16 +1243,20 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_tc_to_buf(&mut self, addr: StoreAddr) -> Result<(), PusPacketHandlingError> {
|
pub fn copy_tc_to_buf(&mut self, addr: StoreAddr) -> Result<(), PusTcFromMemError> {
|
||||||
// Keep locked section as short as possible.
|
// Keep locked section as short as possible.
|
||||||
let mut tc_pool = self.shared_tc_store.write().map_err(|_| {
|
let mut tc_pool = self.shared_tc_store.write().map_err(|_| {
|
||||||
PusPacketHandlingError::EcssTmtc(EcssTmtcError::Store(StoreError::LockError))
|
PusTcFromMemError::EcssTmtc(EcssTmtcError::Store(StoreError::LockError))
|
||||||
})?;
|
})?;
|
||||||
let tc_size = tc_pool
|
let tc_size = tc_pool.len_of_data(&addr).map_err(EcssTmtcError::Store)?;
|
||||||
.len_of_data(&addr)
|
|
||||||
.map_err(|e| PusPacketHandlingError::EcssTmtc(EcssTmtcError::Store(e)))?;
|
|
||||||
if tc_size > self.pus_buf.len() {
|
if tc_size > self.pus_buf.len() {
|
||||||
return Err(PusPacketHandlingError::PusPacketTooLarge(tc_size));
|
return Err(
|
||||||
|
EcssTmtcError::ByteConversion(ByteConversionError::ToSliceTooSmall {
|
||||||
|
found: self.pus_buf.len(),
|
||||||
|
expected: tc_size,
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let tc_guard = tc_pool.read_with_guard(addr);
|
let tc_guard = tc_pool.read_with_guard(addr);
|
||||||
// TODO: Proper error handling.
|
// TODO: Proper error handling.
|
||||||
@ -1253,18 +1266,13 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EcssTcInMemConverter for EcssTcInSharedStoreConverter {
|
impl EcssTcInMemConverter for EcssTcInSharedStoreConverter {
|
||||||
fn cache_ecss_tc_in_memory(
|
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
|
||||||
&mut self,
|
|
||||||
tc_in_memory: &TcInMemory,
|
|
||||||
) -> Result<(), PusPacketHandlingError> {
|
|
||||||
match tc_in_memory {
|
match tc_in_memory {
|
||||||
super::TcInMemory::StoreAddr(addr) => {
|
super::TcInMemory::StoreAddr(addr) => {
|
||||||
self.copy_tc_to_buf(*addr)?;
|
self.copy_tc_to_buf(*addr)?;
|
||||||
}
|
}
|
||||||
super::TcInMemory::Vec(_) => {
|
super::TcInMemory::Vec(_) => {
|
||||||
return Err(PusPacketHandlingError::InvalidTcInMemoryFormat(
|
return Err(PusTcFromMemError::InvalidFormat(tc_in_memory.clone()));
|
||||||
tc_in_memory.clone(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1283,7 +1291,7 @@ pub mod std_mod {
|
|||||||
pub tc_receiver: TcReceiver,
|
pub tc_receiver: TcReceiver,
|
||||||
pub tm_sender: TmSender,
|
pub tm_sender: TmSender,
|
||||||
pub tm_apid: u16,
|
pub tm_apid: u16,
|
||||||
pub verification_handler: VerificationReporter,
|
pub verif_reporter: VerificationReporter,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a high-level PUS packet handler helper.
|
/// This is a high-level PUS packet handler helper.
|
||||||
@ -1324,7 +1332,7 @@ pub mod std_mod {
|
|||||||
tc_receiver,
|
tc_receiver,
|
||||||
tm_sender,
|
tm_sender,
|
||||||
tm_apid,
|
tm_apid,
|
||||||
verification_handler,
|
verif_reporter: verification_handler,
|
||||||
},
|
},
|
||||||
tc_in_mem_converter,
|
tc_in_mem_converter,
|
||||||
}
|
}
|
||||||
@ -1355,11 +1363,23 @@ pub mod std_mod {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
TryRecvTmtcError::Tmtc(e) => Err(PusPacketHandlingError::EcssTmtc(e)),
|
TryRecvTmtcError::Tmtc(e) => Err(PusPacketHandlingError::TcPolling(e)),
|
||||||
TryRecvTmtcError::Empty => Ok(None),
|
TryRecvTmtcError::Empty => Ok(None),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn verif_reporter(&self) -> &VerificationReporter {
|
||||||
|
&self.common.verif_reporter
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tc_in_mem_converter(&self) -> &TcInMemConverter {
|
||||||
|
&self.tc_in_mem_converter
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tc_in_mem_converter_mut(&mut self) -> &mut TcInMemConverter {
|
||||||
|
&mut self.tc_in_mem_converter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PusServiceHelperDynWithMpsc<TcInMemConverter, VerificationReporter> = PusServiceHelper<
|
pub type PusServiceHelperDynWithMpsc<TcInMemConverter, VerificationReporter> = PusServiceHelper<
|
||||||
@ -1423,7 +1443,7 @@ pub mod tests {
|
|||||||
};
|
};
|
||||||
use crate::pus::verification::RequestId;
|
use crate::pus::verification::RequestId;
|
||||||
use crate::tmtc::tm_helper::SharedTmPool;
|
use crate::tmtc::tm_helper::SharedTmPool;
|
||||||
use crate::TargetId;
|
use crate::ComponentId;
|
||||||
|
|
||||||
use super::verification::std_mod::{
|
use super::verification::std_mod::{
|
||||||
VerificationReporterWithSharedPoolMpscBoundedSender, VerificationReporterWithVecMpscSender,
|
VerificationReporterWithSharedPoolMpscBoundedSender, VerificationReporterWithVecMpscSender,
|
||||||
@ -1434,9 +1454,9 @@ pub mod tests {
|
|||||||
VerificationReportingProvider, VerificationToken,
|
VerificationReportingProvider, VerificationToken,
|
||||||
};
|
};
|
||||||
use super::{
|
use super::{
|
||||||
EcssTcAndToken, EcssTcInSharedStoreConverter, EcssTcInVecConverter, GenericRoutingError,
|
EcssTcAndToken, EcssTcInSharedStoreConverter, EcssTcInVecConverter, GenericConversionError,
|
||||||
MpscTcReceiver, PusPacketHandlerResult, PusPacketHandlingError, PusServiceHelper,
|
GenericRoutingError, MpscTcReceiver, PusPacketHandlerResult, PusPacketHandlingError,
|
||||||
TcInMemory, TmAsVecSenderWithId, TmAsVecSenderWithMpsc,
|
PusServiceHelper, TcInMemory, TmAsVecSenderWithId, TmAsVecSenderWithMpsc,
|
||||||
TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithId,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1732,7 +1752,9 @@ pub mod tests {
|
|||||||
impl<const SERVICE: u8> TestConverter<SERVICE> {
|
impl<const SERVICE: u8> TestConverter<SERVICE> {
|
||||||
pub fn check_service(&self, tc: &PusTcReader) -> Result<(), PusPacketHandlingError> {
|
pub fn check_service(&self, tc: &PusTcReader) -> Result<(), PusPacketHandlingError> {
|
||||||
if tc.service() != SERVICE {
|
if tc.service() != SERVICE {
|
||||||
return Err(PusPacketHandlingError::WrongService(tc.service()));
|
return Err(PusPacketHandlingError::RequestConversion(
|
||||||
|
GenericConversionError::WrongService(tc.service()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1751,8 +1773,8 @@ pub mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct TestRouter<REQUEST> {
|
pub struct TestRouter<REQUEST> {
|
||||||
pub routing_requests: RefCell<VecDeque<(TargetId, REQUEST)>>,
|
pub routing_requests: RefCell<VecDeque<(ComponentId, REQUEST)>>,
|
||||||
pub routing_errors: RefCell<VecDeque<(TargetId, GenericRoutingError)>>,
|
pub routing_errors: RefCell<VecDeque<(ComponentId, GenericRoutingError)>>,
|
||||||
pub injected_routing_failure: RefCell<Option<GenericRoutingError>>,
|
pub injected_routing_failure: RefCell<Option<GenericRoutingError>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1776,7 +1798,7 @@ pub mod tests {
|
|||||||
|
|
||||||
pub fn handle_error(
|
pub fn handle_error(
|
||||||
&self,
|
&self,
|
||||||
target_id: TargetId,
|
target_id: ComponentId,
|
||||||
_token: VerificationToken<TcStateAccepted>,
|
_token: VerificationToken<TcStateAccepted>,
|
||||||
_tc: &PusTcReader,
|
_tc: &PusTcReader,
|
||||||
error: GenericRoutingError,
|
error: GenericRoutingError,
|
||||||
@ -1792,7 +1814,7 @@ pub mod tests {
|
|||||||
self.routing_errors.borrow().is_empty()
|
self.routing_errors.borrow().is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn retrieve_next_routing_error(&mut self) -> (TargetId, GenericRoutingError) {
|
pub fn retrieve_next_routing_error(&mut self) -> (ComponentId, GenericRoutingError) {
|
||||||
if self.routing_errors.borrow().is_empty() {
|
if self.routing_errors.borrow().is_empty() {
|
||||||
panic!("no routing request available");
|
panic!("no routing request available");
|
||||||
}
|
}
|
||||||
@ -1807,7 +1829,7 @@ pub mod tests {
|
|||||||
self.routing_requests.borrow().is_empty()
|
self.routing_requests.borrow().is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn retrieve_next_request(&mut self) -> (TargetId, REQUEST) {
|
pub fn retrieve_next_request(&mut self) -> (ComponentId, REQUEST) {
|
||||||
if self.routing_requests.borrow().is_empty() {
|
if self.routing_requests.borrow().is_empty() {
|
||||||
panic!("no routing request available");
|
panic!("no routing request available");
|
||||||
}
|
}
|
||||||
|
@ -83,10 +83,10 @@ impl<
|
|||||||
return Ok(PusPacketHandlerResult::Empty);
|
return Ok(PusPacketHandlerResult::Empty);
|
||||||
}
|
}
|
||||||
let ecss_tc_and_token = possible_packet.unwrap();
|
let ecss_tc_and_token = possible_packet.unwrap();
|
||||||
let tc = self
|
self.service_helper
|
||||||
.service_helper
|
.tc_in_mem_converter_mut()
|
||||||
.tc_in_mem_converter
|
.cache(&ecss_tc_and_token.tc_in_memory)?;
|
||||||
.convert_ecss_tc_in_memory_to_reader(&ecss_tc_and_token.tc_in_memory)?;
|
let tc = self.service_helper.tc_in_mem_converter().convert()?;
|
||||||
let subservice = PusPacket::subservice(&tc);
|
let subservice = PusPacket::subservice(&tc);
|
||||||
let standard_subservice = scheduling::Subservice::try_from(subservice);
|
let standard_subservice = scheduling::Subservice::try_from(subservice);
|
||||||
if standard_subservice.is_err() {
|
if standard_subservice.is_err() {
|
||||||
@ -100,16 +100,14 @@ impl<
|
|||||||
scheduling::Subservice::TcEnableScheduling => {
|
scheduling::Subservice::TcEnableScheduling => {
|
||||||
let start_token = self
|
let start_token = self
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.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();
|
||||||
if self.scheduler.is_enabled() {
|
if self.scheduler.is_enabled() {
|
||||||
self.service_helper
|
self.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.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 {
|
||||||
@ -121,16 +119,14 @@ impl<
|
|||||||
scheduling::Subservice::TcDisableScheduling => {
|
scheduling::Subservice::TcDisableScheduling => {
|
||||||
let start_token = self
|
let start_token = self
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.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();
|
||||||
if !self.scheduler.is_enabled() {
|
if !self.scheduler.is_enabled() {
|
||||||
self.service_helper
|
self.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.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 {
|
||||||
@ -142,8 +138,7 @@ impl<
|
|||||||
scheduling::Subservice::TcResetScheduling => {
|
scheduling::Subservice::TcResetScheduling => {
|
||||||
let start_token = self
|
let start_token = self
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.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");
|
||||||
|
|
||||||
@ -152,8 +147,7 @@ impl<
|
|||||||
.expect("Error resetting TC Pool");
|
.expect("Error resetting TC Pool");
|
||||||
|
|
||||||
self.service_helper
|
self.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.verification_handler
|
|
||||||
.completion_success(start_token, time_stamp)
|
.completion_success(start_token, time_stamp)
|
||||||
.expect("Error sending completion success");
|
.expect("Error sending completion success");
|
||||||
}
|
}
|
||||||
@ -161,7 +155,7 @@ impl<
|
|||||||
let start_token = self
|
let start_token = self
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.common
|
||||||
.verification_handler
|
.verif_reporter
|
||||||
.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");
|
||||||
|
|
||||||
@ -171,8 +165,7 @@ impl<
|
|||||||
.expect("insertion of activity into pool failed");
|
.expect("insertion of activity into pool failed");
|
||||||
|
|
||||||
self.service_helper
|
self.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.verification_handler
|
|
||||||
.completion_success(start_token, time_stamp)
|
.completion_success(start_token, time_stamp)
|
||||||
.expect("sending completion success failed");
|
.expect("sending completion success failed");
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,9 @@ use super::verification::{
|
|||||||
};
|
};
|
||||||
use super::{
|
use super::{
|
||||||
EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTcReceiverCore,
|
EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTcReceiverCore,
|
||||||
EcssTmSenderCore, MpscTcReceiver, PusServiceHelper, TmAsVecSenderWithBoundedMpsc,
|
EcssTmSenderCore, GenericConversionError, MpscTcReceiver, PusServiceHelper,
|
||||||
TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc, TmInSharedPoolSenderWithMpsc,
|
TmAsVecSenderWithBoundedMpsc, TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc,
|
||||||
|
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.
|
||||||
@ -55,19 +56,18 @@ impl<
|
|||||||
return Ok(PusPacketHandlerResult::Empty);
|
return Ok(PusPacketHandlerResult::Empty);
|
||||||
}
|
}
|
||||||
let ecss_tc_and_token = possible_packet.unwrap();
|
let ecss_tc_and_token = possible_packet.unwrap();
|
||||||
let tc = self
|
self.service_helper
|
||||||
.service_helper
|
.tc_in_mem_converter_mut()
|
||||||
.tc_in_mem_converter
|
.cache(&ecss_tc_and_token.tc_in_memory)?;
|
||||||
.convert_ecss_tc_in_memory_to_reader(&ecss_tc_and_token.tc_in_memory)?;
|
let tc = self.service_helper.tc_in_mem_converter().convert()?;
|
||||||
if tc.service() != 17 {
|
if tc.service() != 17 {
|
||||||
return Err(PusPacketHandlingError::WrongService(tc.service()));
|
return Err(GenericConversionError::WrongService(tc.service()).into());
|
||||||
}
|
}
|
||||||
if tc.subservice() == 1 {
|
if tc.subservice() == 1 {
|
||||||
let mut partial_error = None;
|
let mut partial_error = None;
|
||||||
let result = self
|
let result = self
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.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 {
|
||||||
@ -94,8 +94,7 @@ impl<
|
|||||||
if let Some(start_token) = start_token {
|
if let Some(start_token) = start_token {
|
||||||
if self
|
if self
|
||||||
.service_helper
|
.service_helper
|
||||||
.common
|
.verif_reporter()
|
||||||
.verification_handler
|
|
||||||
.completion_success(start_token, time_stamp)
|
.completion_success(start_token, time_stamp)
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
@ -162,8 +161,9 @@ mod tests {
|
|||||||
use crate::pus::verification::RequestId;
|
use crate::pus::verification::RequestId;
|
||||||
use crate::pus::verification::{TcStateAccepted, VerificationToken};
|
use crate::pus::verification::{TcStateAccepted, VerificationToken};
|
||||||
use crate::pus::{
|
use crate::pus::{
|
||||||
EcssTcInSharedStoreConverter, EcssTcInVecConverter, MpscTcReceiver, PusPacketHandlerResult,
|
EcssTcInSharedStoreConverter, EcssTcInVecConverter, GenericConversionError, MpscTcReceiver,
|
||||||
PusPacketHandlingError, TmAsVecSenderWithMpsc, TmInSharedPoolSenderWithBoundedMpsc,
|
PusPacketHandlerResult, PusPacketHandlingError, TmAsVecSenderWithMpsc,
|
||||||
|
TmInSharedPoolSenderWithBoundedMpsc,
|
||||||
};
|
};
|
||||||
use delegate::delegate;
|
use delegate::delegate;
|
||||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader};
|
use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader};
|
||||||
@ -320,7 +320,10 @@ mod tests {
|
|||||||
let result = test_harness.handle_one_tc();
|
let result = test_harness.handle_one_tc();
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
let error = result.unwrap_err();
|
let error = result.unwrap_err();
|
||||||
if let PusPacketHandlingError::WrongService(num) = error {
|
if let PusPacketHandlingError::RequestConversion(GenericConversionError::WrongService(
|
||||||
|
num,
|
||||||
|
)) = error
|
||||||
|
{
|
||||||
assert_eq!(num, 3);
|
assert_eq!(num, 3);
|
||||||
} else {
|
} else {
|
||||||
panic!("unexpected error type {error}")
|
panic!("unexpected error type {error}")
|
||||||
|
@ -15,7 +15,7 @@ use spacepackets::{
|
|||||||
ByteConversionError, CcsdsPacket,
|
ByteConversionError, CcsdsPacket,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{queue::GenericTargetedMessagingError, ChannelId, TargetId};
|
use crate::{queue::GenericTargetedMessagingError, ChannelId, ComponentId};
|
||||||
|
|
||||||
/// Generic request ID type. Requests can be associated with an ID to have a unique identifier
|
/// Generic request ID type. Requests can be associated with an ID to have a unique identifier
|
||||||
/// for them. This can be useful for tasks like tracking their progress.
|
/// for them. This can be useful for tasks like tracking their progress.
|
||||||
@ -35,11 +35,11 @@ impl TargetAndApidId {
|
|||||||
Self { apid, target }
|
Self { apid, target }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raw(&self) -> TargetId {
|
pub fn raw(&self) -> ComponentId {
|
||||||
((self.apid as u64) << 32) | (self.target as u64)
|
((self.apid as u64) << 32) | (self.target as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn full_target_id(&self) -> TargetId {
|
pub fn full_target_id(&self) -> ComponentId {
|
||||||
self.raw()
|
self.raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use core::cell::Cell;
|
use core::cell::Cell;
|
||||||
use std::{println, sync::mpsc};
|
use std::{println, sync::mpsc};
|
||||||
|
|
||||||
|
use satrs::action::ActionRequest;
|
||||||
use satrs::mode::{
|
use satrs::mode::{
|
||||||
ModeError, ModeProvider, ModeReplyReceiver, ModeReplySender, ModeRequestHandler,
|
ModeError, ModeProvider, ModeReplyReceiver, ModeReplySender, ModeRequestHandler,
|
||||||
ModeRequestHandlerMpscBounded, ModeRequestReceiver, ModeRequestorAndHandlerMpscBounded,
|
ModeRequestHandlerMpscBounded, ModeRequestReceiver, ModeRequestorAndHandlerMpscBounded,
|
||||||
ModeRequestorBoundedMpsc,
|
ModeRequestorBoundedMpsc,
|
||||||
};
|
};
|
||||||
|
use satrs::pus::action::ActionRequestWithId;
|
||||||
use satrs::request::RequestId;
|
use satrs::request::RequestId;
|
||||||
use satrs::{
|
use satrs::{
|
||||||
mode::{ModeAndSubmode, ModeReply, ModeRequest},
|
mode::{ModeAndSubmode, ModeReply, ModeRequest},
|
||||||
@ -46,11 +48,10 @@ struct TestDevice {
|
|||||||
pub mode_node: ModeRequestHandlerMpscBounded,
|
pub mode_node: ModeRequestHandlerMpscBounded,
|
||||||
pub mode_and_submode: ModeAndSubmode,
|
pub mode_and_submode: ModeAndSubmode,
|
||||||
pub mode_requestor_info: Option<(RequestId, ChannelId)>,
|
pub mode_requestor_info: Option<(RequestId, ChannelId)>,
|
||||||
|
pub action_queue: mpsc::Receiver<GenericMessage<ActionRequest>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ModeLeafDeviceHelper {
|
pub struct ModeLeafDeviceHelper {}
|
||||||
// pub
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TestDevice {
|
impl TestDevice {
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user