2024-02-20 14:33:21 +01:00
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::sync::mpsc;
|
|
|
|
|
2024-04-04 15:18:53 +02:00
|
|
|
use log::warn;
|
2024-02-20 14:33:21 +01:00
|
|
|
use satrs::action::ActionRequest;
|
2024-02-12 15:51:37 +01:00
|
|
|
use satrs::hk::HkRequest;
|
|
|
|
use satrs::mode::ModeRequest;
|
2024-04-04 15:18:53 +02:00
|
|
|
use satrs::pus::verification::{
|
|
|
|
FailParams, TcStateAccepted, VerificationReportingProvider, VerificationToken,
|
|
|
|
};
|
|
|
|
use satrs::pus::{ActiveRequestProvider, EcssTmSenderCore, GenericRoutingError, PusRequestRouter};
|
2024-02-20 14:33:21 +01:00
|
|
|
use satrs::queue::GenericSendError;
|
2024-04-04 15:18:53 +02:00
|
|
|
use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId};
|
|
|
|
use satrs::spacepackets::ecss::tc::PusTcReader;
|
|
|
|
use satrs::spacepackets::ecss::PusPacket;
|
|
|
|
use satrs::ComponentId;
|
|
|
|
use satrs_example::config::components::PUS_ROUTING_SERVICE;
|
|
|
|
use satrs_example::config::tmtc_err;
|
2023-07-05 21:08:04 +02:00
|
|
|
|
2024-04-04 15:18:53 +02:00
|
|
|
#[derive(Clone, Debug)]
|
2023-02-15 11:19:23 +01:00
|
|
|
#[non_exhaustive]
|
2024-04-04 15:18:53 +02:00
|
|
|
pub enum CompositeRequest {
|
2023-07-05 21:08:04 +02:00
|
|
|
Hk(HkRequest),
|
|
|
|
Action(ActionRequest),
|
2022-12-19 17:03:26 +01:00
|
|
|
}
|
2022-12-21 10:15:41 +01:00
|
|
|
|
2024-04-04 15:18:53 +02:00
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct GenericRequestRouter {
|
|
|
|
pub id: ComponentId,
|
|
|
|
// All messages which do not have a dedicated queue.
|
|
|
|
pub composite_router_map: HashMap<ComponentId, mpsc::Sender<GenericMessage<CompositeRequest>>>,
|
|
|
|
pub mode_router_map: HashMap<ComponentId, mpsc::Sender<GenericMessage<ModeRequest>>>,
|
2023-02-27 13:44:24 +01:00
|
|
|
}
|
|
|
|
|
2024-04-04 15:18:53 +02:00
|
|
|
impl Default for GenericRequestRouter {
|
|
|
|
fn default() -> Self {
|
2023-02-27 13:44:24 +01:00
|
|
|
Self {
|
2024-04-04 15:18:53 +02:00
|
|
|
id: PUS_ROUTING_SERVICE.raw(),
|
|
|
|
composite_router_map: Default::default(),
|
|
|
|
mode_router_map: Default::default(),
|
2023-02-27 13:44:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-04-04 15:18:53 +02:00
|
|
|
impl GenericRequestRouter {
|
|
|
|
pub(crate) fn handle_error_generic(
|
|
|
|
&self,
|
|
|
|
active_request: &impl ActiveRequestProvider,
|
|
|
|
tc: &PusTcReader,
|
|
|
|
error: GenericRoutingError,
|
|
|
|
tm_sender: &(impl EcssTmSenderCore + ?Sized),
|
|
|
|
verif_reporter: &impl VerificationReportingProvider,
|
|
|
|
time_stamp: &[u8],
|
|
|
|
) {
|
|
|
|
warn!(
|
|
|
|
"Routing request for service {} failed: {error:?}",
|
|
|
|
tc.service()
|
|
|
|
);
|
|
|
|
let accepted_token: VerificationToken<TcStateAccepted> = active_request
|
|
|
|
.token()
|
|
|
|
.try_into()
|
|
|
|
.expect("token is not in accepted state");
|
|
|
|
match error {
|
|
|
|
GenericRoutingError::UnknownTargetId(id) => {
|
|
|
|
let apid_target_id = UniqueApidTargetId::from(id);
|
|
|
|
warn!("Target APID for request: {}", apid_target_id.apid);
|
|
|
|
warn!("Target Unique ID for request: {}", apid_target_id.unique_id);
|
|
|
|
let mut fail_data: [u8; 8] = [0; 8];
|
|
|
|
fail_data.copy_from_slice(&id.to_be_bytes());
|
|
|
|
verif_reporter
|
|
|
|
.completion_failure(
|
|
|
|
tm_sender,
|
|
|
|
accepted_token,
|
|
|
|
FailParams::new(time_stamp, &tmtc_err::UNKNOWN_TARGET_ID, &fail_data),
|
|
|
|
)
|
|
|
|
.expect("Sending start failure failed");
|
|
|
|
}
|
|
|
|
GenericRoutingError::Send(_) => {
|
|
|
|
let mut fail_data: [u8; 8] = [0; 8];
|
|
|
|
fail_data.copy_from_slice(&active_request.target_id().to_be_bytes());
|
|
|
|
verif_reporter
|
|
|
|
.completion_failure(
|
|
|
|
tm_sender,
|
|
|
|
accepted_token,
|
|
|
|
FailParams::new(time_stamp, &tmtc_err::ROUTING_ERROR, &fail_data),
|
|
|
|
)
|
|
|
|
.expect("Sending start failure failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl PusRequestRouter<HkRequest> for GenericRequestRouter {
|
2024-02-20 14:33:21 +01:00
|
|
|
type Error = GenericRoutingError;
|
|
|
|
|
|
|
|
fn route(
|
|
|
|
&self,
|
2024-04-04 15:18:53 +02:00
|
|
|
requestor_info: MessageMetadata,
|
|
|
|
target_id: ComponentId,
|
2024-02-20 14:33:21 +01:00
|
|
|
hk_request: HkRequest,
|
|
|
|
) -> Result<(), Self::Error> {
|
2024-04-04 15:18:53 +02:00
|
|
|
if let Some(sender) = self.composite_router_map.get(&target_id) {
|
2024-02-20 14:33:21 +01:00
|
|
|
sender
|
2024-04-04 15:18:53 +02:00
|
|
|
.send(GenericMessage::new(
|
|
|
|
requestor_info,
|
|
|
|
CompositeRequest::Hk(hk_request),
|
2024-02-20 14:33:21 +01:00
|
|
|
))
|
2024-04-04 15:18:53 +02:00
|
|
|
.map_err(|_| GenericRoutingError::Send(GenericSendError::RxDisconnected))?;
|
|
|
|
return Ok(());
|
2024-02-20 14:33:21 +01:00
|
|
|
}
|
2024-04-04 15:18:53 +02:00
|
|
|
Err(GenericRoutingError::UnknownTargetId(target_id))
|
2024-02-20 14:33:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-04 15:18:53 +02:00
|
|
|
impl PusRequestRouter<ActionRequest> for GenericRequestRouter {
|
2024-02-20 14:33:21 +01:00
|
|
|
type Error = GenericRoutingError;
|
|
|
|
|
|
|
|
fn route(
|
|
|
|
&self,
|
2024-04-04 15:18:53 +02:00
|
|
|
requestor_info: MessageMetadata,
|
|
|
|
target_id: ComponentId,
|
2024-02-20 14:33:21 +01:00
|
|
|
action_request: ActionRequest,
|
|
|
|
) -> Result<(), Self::Error> {
|
2024-04-04 15:18:53 +02:00
|
|
|
if let Some(sender) = self.composite_router_map.get(&target_id) {
|
2024-02-20 14:33:21 +01:00
|
|
|
sender
|
2024-04-04 15:18:53 +02:00
|
|
|
.send(GenericMessage::new(
|
|
|
|
requestor_info,
|
|
|
|
CompositeRequest::Action(action_request),
|
2024-02-20 14:33:21 +01:00
|
|
|
))
|
2024-04-04 15:18:53 +02:00
|
|
|
.map_err(|_| GenericRoutingError::Send(GenericSendError::RxDisconnected))?;
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
Err(GenericRoutingError::UnknownTargetId(target_id))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PusRequestRouter<ModeRequest> for GenericRequestRouter {
|
|
|
|
type Error = GenericRoutingError;
|
|
|
|
|
|
|
|
fn route(
|
|
|
|
&self,
|
|
|
|
requestor_info: MessageMetadata,
|
|
|
|
target_id: ComponentId,
|
|
|
|
request: ModeRequest,
|
|
|
|
) -> Result<(), Self::Error> {
|
|
|
|
if let Some(sender) = self.mode_router_map.get(&target_id) {
|
|
|
|
sender
|
|
|
|
.send(GenericMessage::new(requestor_info, request))
|
|
|
|
.map_err(|_| GenericRoutingError::Send(GenericSendError::RxDisconnected))?;
|
|
|
|
return Ok(());
|
2024-02-20 14:33:21 +01:00
|
|
|
}
|
2024-04-04 15:18:53 +02:00
|
|
|
Err(GenericRoutingError::UnknownTargetId(target_id))
|
2024-02-20 14:33:21 +01:00
|
|
|
}
|
|
|
|
}
|