make new abstractions more generic
All checks were successful
Rust/sat-rs/pipeline/pr-main This commit looks good
All checks were successful
Rust/sat-rs/pipeline/pr-main This commit looks good
This commit is contained in:
parent
c6f2dde138
commit
b0d32aff4f
@ -71,19 +71,6 @@ pub struct ActiveActionRequest {
|
|||||||
common: ActiveRequest,
|
common: ActiveRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ActiveRequestMapProvider: Default {
|
|
||||||
fn insert(&mut self, request_id: &RequestId, request: ActiveActionRequest);
|
|
||||||
fn get(&self, request_id: RequestId) -> Option<&ActiveActionRequest>;
|
|
||||||
fn get_mut(&mut self, request_id: RequestId) -> Option<&mut ActiveActionRequest>;
|
|
||||||
fn remove(&mut self, request_id: RequestId) -> bool;
|
|
||||||
|
|
||||||
/// Call a user-supplied closure for each active request.
|
|
||||||
fn for_each<F: FnMut(&RequestId, &ActiveActionRequest)>(&self, f: F);
|
|
||||||
|
|
||||||
/// Call a user-supplied closure for each active request. Mutable variant.
|
|
||||||
fn for_each_mut<F: FnMut(&RequestId, &mut ActiveActionRequest)>(&mut self, f: F);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||||
pub mod alloc_mod {
|
pub mod alloc_mod {
|
||||||
@ -130,9 +117,10 @@ pub mod std_mod {
|
|||||||
verification::{
|
verification::{
|
||||||
self, FailParams, FailParamsWithStep, TcStateStarted, VerificationReportingProvider,
|
self, FailParams, FailParamsWithStep, TcStateStarted, VerificationReportingProvider,
|
||||||
},
|
},
|
||||||
EcssTcInMemConverter, EcssTcReceiverCore, EcssTmSenderCore, EcssTmtcError,
|
ActiveRequestMapProvider, DefaultActiveRequestMap, EcssTcInMemConverter,
|
||||||
GenericRoutingError, PusPacketHandlerResult, PusPacketHandlingError,
|
EcssTcReceiverCore, EcssTmSenderCore, EcssTmtcError, GenericRoutingError,
|
||||||
PusRoutingErrorHandler, PusServiceHelper,
|
PusPacketHandlerResult, PusPacketHandlingError, PusRoutingErrorHandler,
|
||||||
|
PusServiceHelper,
|
||||||
},
|
},
|
||||||
request::RequestId,
|
request::RequestId,
|
||||||
};
|
};
|
||||||
@ -250,38 +238,7 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
pub type DefaultActiveActionRequestMap = DefaultActiveRequestMap<ActiveActionRequest>;
|
||||||
pub struct DefaultActiveRequestMap(HashMap<RequestId, ActiveActionRequest>);
|
|
||||||
|
|
||||||
impl ActiveRequestMapProvider for DefaultActiveRequestMap {
|
|
||||||
fn insert(&mut self, request_id: &RequestId, request: ActiveActionRequest) {
|
|
||||||
self.0.insert(*request_id, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get(&self, request_id: RequestId) -> Option<&ActiveActionRequest> {
|
|
||||||
self.0.get(&request_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_mut(&mut self, request_id: RequestId) -> Option<&mut ActiveActionRequest> {
|
|
||||||
self.0.get_mut(&request_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove(&mut self, request_id: RequestId) -> bool {
|
|
||||||
self.0.remove(&request_id).is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn for_each<F: FnMut(&RequestId, &ActiveActionRequest)>(&self, mut f: F) {
|
|
||||||
for (req_id, active_req) in &self.0 {
|
|
||||||
f(req_id, active_req);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn for_each_mut<F: FnMut(&RequestId, &mut ActiveActionRequest)>(&mut self, mut f: F) {
|
|
||||||
for (req_id, active_req) in &mut self.0 {
|
|
||||||
f(req_id, active_req);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ActionReplyHandlerHook {
|
pub trait ActionReplyHandlerHook {
|
||||||
fn handle_unexpected_reply(&mut self, reply: &ActionReplyPusWithIds);
|
fn handle_unexpected_reply(&mut self, reply: &ActionReplyPusWithIds);
|
||||||
@ -291,10 +248,10 @@ pub mod std_mod {
|
|||||||
|
|
||||||
pub struct PusService8ReplyHandler<
|
pub struct PusService8ReplyHandler<
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
ActiveRequestMap: ActiveRequestMapProvider,
|
ActiveRequestMap: ActiveRequestMapProvider<ActiveActionRequest>,
|
||||||
UserHook: ActionReplyHandlerHook,
|
UserHook: ActionReplyHandlerHook,
|
||||||
> {
|
> {
|
||||||
active_requests: ActiveRequestMap,
|
active_request_map: ActiveRequestMap,
|
||||||
verification_reporter: VerificationReporter,
|
verification_reporter: VerificationReporter,
|
||||||
fail_data_buf: alloc::vec::Vec<u8>,
|
fail_data_buf: alloc::vec::Vec<u8>,
|
||||||
current_time: UnixTimestamp,
|
current_time: UnixTimestamp,
|
||||||
@ -303,20 +260,22 @@ pub mod std_mod {
|
|||||||
|
|
||||||
impl<
|
impl<
|
||||||
VerificationReporter: VerificationReportingProvider,
|
VerificationReporter: VerificationReportingProvider,
|
||||||
ActiveRequestMap: ActiveRequestMapProvider,
|
ActiveRequestMap: ActiveRequestMapProvider<ActiveActionRequest>,
|
||||||
UserHook: ActionReplyHandlerHook,
|
UserHook: ActionReplyHandlerHook,
|
||||||
> PusService8ReplyHandler<VerificationReporter, ActiveRequestMap, UserHook>
|
> PusService8ReplyHandler<VerificationReporter, ActiveRequestMap, UserHook>
|
||||||
{
|
{
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||||
pub fn new_with_init_time_now(
|
pub fn new_from_now(
|
||||||
verification_reporter: VerificationReporter,
|
verification_reporter: VerificationReporter,
|
||||||
|
active_request_map: ActiveRequestMap,
|
||||||
fail_data_buf_size: usize,
|
fail_data_buf_size: usize,
|
||||||
user_hook: UserHook,
|
user_hook: UserHook,
|
||||||
) -> Result<Self, SystemTimeError> {
|
) -> Result<Self, SystemTimeError> {
|
||||||
let current_time = UnixTimestamp::from_now()?;
|
let current_time = UnixTimestamp::from_now()?;
|
||||||
Ok(Self::new(
|
Ok(Self::new(
|
||||||
verification_reporter,
|
verification_reporter,
|
||||||
|
active_request_map,
|
||||||
fail_data_buf_size,
|
fail_data_buf_size,
|
||||||
user_hook,
|
user_hook,
|
||||||
current_time,
|
current_time,
|
||||||
@ -325,18 +284,20 @@ pub mod std_mod {
|
|||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
verification_reporter: VerificationReporter,
|
verification_reporter: VerificationReporter,
|
||||||
|
active_request_map: ActiveRequestMap,
|
||||||
fail_data_buf_size: usize,
|
fail_data_buf_size: usize,
|
||||||
user_hook: UserHook,
|
user_hook: UserHook,
|
||||||
init_time: UnixTimestamp,
|
init_time: UnixTimestamp,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
active_requests: ActiveRequestMap::default(),
|
active_request_map,
|
||||||
verification_reporter,
|
verification_reporter,
|
||||||
fail_data_buf: alloc::vec![0; fail_data_buf_size],
|
fail_data_buf: alloc::vec![0; fail_data_buf_size],
|
||||||
current_time: init_time,
|
current_time: init_time,
|
||||||
user_hook,
|
user_hook,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_routed_request(
|
pub fn add_routed_request(
|
||||||
&mut self,
|
&mut self,
|
||||||
request_id: verification::RequestId,
|
request_id: verification::RequestId,
|
||||||
@ -344,7 +305,7 @@ pub mod std_mod {
|
|||||||
token: VerificationToken<TcStateStarted>,
|
token: VerificationToken<TcStateStarted>,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
) {
|
) {
|
||||||
self.active_requests.insert(
|
self.active_request_map.insert(
|
||||||
&request_id.into(),
|
&request_id.into(),
|
||||||
ActiveActionRequest {
|
ActiveActionRequest {
|
||||||
action_id,
|
action_id,
|
||||||
@ -358,7 +319,7 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn request_active(&self, request_id: RequestId) -> bool {
|
pub fn request_active(&self, request_id: RequestId) -> bool {
|
||||||
self.active_requests.get(request_id).is_some()
|
self.active_request_map.get(request_id).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -373,7 +334,7 @@ pub mod std_mod {
|
|||||||
/// It will call [Self::handle_timeout] for all active requests which have timed out.
|
/// It will call [Self::handle_timeout] for all active requests which have timed out.
|
||||||
pub fn check_for_timeouts(&mut self, time_stamp: &[u8]) -> Result<(), EcssTmtcError> {
|
pub fn check_for_timeouts(&mut self, time_stamp: &[u8]) -> Result<(), EcssTmtcError> {
|
||||||
let mut timed_out_commands = alloc::vec::Vec::new();
|
let mut timed_out_commands = alloc::vec::Vec::new();
|
||||||
self.active_requests.for_each(|request_id, active_req| {
|
self.active_request_map.for_each(|request_id, active_req| {
|
||||||
let diff = self.current_time - active_req.common.start_time;
|
let diff = self.current_time - active_req.common.start_time;
|
||||||
if diff.duration_absolute > active_req.common.timeout {
|
if diff.duration_absolute > active_req.common.timeout {
|
||||||
self.handle_timeout(active_req, time_stamp);
|
self.handle_timeout(active_req, time_stamp);
|
||||||
@ -381,7 +342,7 @@ pub mod std_mod {
|
|||||||
timed_out_commands.push(*request_id);
|
timed_out_commands.push(*request_id);
|
||||||
});
|
});
|
||||||
for timed_out_command in timed_out_commands {
|
for timed_out_command in timed_out_commands {
|
||||||
self.active_requests.remove(timed_out_command);
|
self.active_request_map.remove(timed_out_command);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -412,7 +373,9 @@ pub mod std_mod {
|
|||||||
action_reply_with_ids: ActionReplyPusWithIds,
|
action_reply_with_ids: ActionReplyPusWithIds,
|
||||||
time_stamp: &[u8],
|
time_stamp: &[u8],
|
||||||
) -> Result<(), EcssTmtcError> {
|
) -> Result<(), EcssTmtcError> {
|
||||||
let active_req = self.active_requests.get(action_reply_with_ids.request_id);
|
let active_req = self
|
||||||
|
.active_request_map
|
||||||
|
.get(action_reply_with_ids.request_id);
|
||||||
if active_req.is_none() {
|
if active_req.is_none() {
|
||||||
self.user_hook
|
self.user_hook
|
||||||
.handle_unexpected_reply(&action_reply_with_ids);
|
.handle_unexpected_reply(&action_reply_with_ids);
|
||||||
@ -468,12 +431,47 @@ pub mod std_mod {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if remove_entry {
|
if remove_entry {
|
||||||
self.active_requests
|
self.active_request_map
|
||||||
.remove(action_reply_with_ids.request_id);
|
.remove(action_reply_with_ids.request_id);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<VerificationReporter: VerificationReportingProvider, UserHook: ActionReplyHandlerHook>
|
||||||
|
PusService8ReplyHandler<VerificationReporter, DefaultActiveActionRequestMap, UserHook>
|
||||||
|
{
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||||
|
pub fn new_from_now_with_default_map(
|
||||||
|
verification_reporter: VerificationReporter,
|
||||||
|
fail_data_buf_size: usize,
|
||||||
|
user_hook: UserHook,
|
||||||
|
) -> Result<Self, SystemTimeError> {
|
||||||
|
let current_time = UnixTimestamp::from_now()?;
|
||||||
|
Ok(Self::new_with_default_map(
|
||||||
|
verification_reporter,
|
||||||
|
fail_data_buf_size,
|
||||||
|
user_hook,
|
||||||
|
current_time,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_default_map(
|
||||||
|
verification_reporter: VerificationReporter,
|
||||||
|
fail_data_buf_size: usize,
|
||||||
|
user_hook: UserHook,
|
||||||
|
init_time: UnixTimestamp,
|
||||||
|
) -> Self {
|
||||||
|
Self::new(
|
||||||
|
verification_reporter,
|
||||||
|
DefaultActiveRequestMap::<ActiveActionRequest>(HashMap::default()),
|
||||||
|
fail_data_buf_size,
|
||||||
|
user_hook,
|
||||||
|
init_time,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -670,7 +668,7 @@ mod tests {
|
|||||||
verif_reporter: TestVerificationReporter,
|
verif_reporter: TestVerificationReporter,
|
||||||
handler: PusService8ReplyHandler<
|
handler: PusService8ReplyHandler<
|
||||||
TestVerificationReporter,
|
TestVerificationReporter,
|
||||||
DefaultActiveRequestMap,
|
DefaultActiveActionRequestMap,
|
||||||
TestReplyHandlerHook,
|
TestReplyHandlerHook,
|
||||||
>,
|
>,
|
||||||
}
|
}
|
||||||
@ -680,7 +678,7 @@ mod tests {
|
|||||||
let reply_handler_hook = TestReplyHandlerHook::default();
|
let reply_handler_hook = TestReplyHandlerHook::default();
|
||||||
let shared_verif_map = SharedVerificationMap::default();
|
let shared_verif_map = SharedVerificationMap::default();
|
||||||
let test_verif_reporter = TestVerificationReporter::new(shared_verif_map.clone());
|
let test_verif_reporter = TestVerificationReporter::new(shared_verif_map.clone());
|
||||||
let reply_handler = PusService8ReplyHandler::new_with_init_time_now(
|
let reply_handler = PusService8ReplyHandler::new_from_now_with_default_map(
|
||||||
test_verif_reporter.clone(),
|
test_verif_reporter.clone(),
|
||||||
128,
|
128,
|
||||||
reply_handler_hook,
|
reply_handler_hook,
|
||||||
|
@ -5,12 +5,15 @@
|
|||||||
use crate::pool::{StoreAddr, StoreError};
|
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::RequestId;
|
||||||
use crate::ChannelId;
|
use crate::ChannelId;
|
||||||
use core::fmt::{Display, Formatter};
|
use core::fmt::{Display, Formatter};
|
||||||
|
use core::time::Duration;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use downcast_rs::{impl_downcast, Downcast};
|
use downcast_rs::{impl_downcast, Downcast};
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use dyn_clone::DynClone;
|
use dyn_clone::DynClone;
|
||||||
|
use spacepackets::time::UnixTimestamp;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
@ -39,6 +42,8 @@ pub use alloc_mod::*;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std_mod::*;
|
pub use std_mod::*;
|
||||||
|
|
||||||
|
use self::verification::TcStateStarted;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum PusTmWrapper<'tm> {
|
pub enum PusTmWrapper<'tm> {
|
||||||
InStore(StoreAddr),
|
InStore(StoreAddr),
|
||||||
@ -270,8 +275,30 @@ pub trait ReceivesEcssPusTc {
|
|||||||
fn pass_pus_tc(&mut self, header: &SpHeader, pus_tc: &PusTcReader) -> Result<(), Self::Error>;
|
fn pass_pus_tc(&mut self, header: &SpHeader, pus_tc: &PusTcReader) -> Result<(), Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ActiveRequestMapProvider<V>: Sized {
|
||||||
|
fn insert(&mut self, request_id: &RequestId, request: V);
|
||||||
|
fn get(&self, request_id: RequestId) -> Option<&V>;
|
||||||
|
fn get_mut(&mut self, request_id: RequestId) -> Option<&mut V>;
|
||||||
|
fn remove(&mut self, request_id: RequestId) -> bool;
|
||||||
|
|
||||||
|
/// Call a user-supplied closure for each active request.
|
||||||
|
fn for_each<F: FnMut(&RequestId, &V)>(&self, f: F);
|
||||||
|
|
||||||
|
/// Call a user-supplied closure for each active request. Mutable variant.
|
||||||
|
fn for_each_mut<F: FnMut(&RequestId, &mut V)>(&mut self, f: F);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct ActiveRequest {
|
||||||
|
token: VerificationToken<TcStateStarted>,
|
||||||
|
start_time: UnixTimestamp,
|
||||||
|
timeout: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
mod alloc_mod {
|
mod alloc_mod {
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
use crate::TargetId;
|
use crate::TargetId;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -370,6 +397,39 @@ mod alloc_mod {
|
|||||||
verif_reporter: &impl VerificationReportingProvider,
|
verif_reporter: &impl VerificationReportingProvider,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct DefaultActiveRequestMap<V>(pub HashMap<RequestId, V>);
|
||||||
|
|
||||||
|
impl<V> ActiveRequestMapProvider<V> for DefaultActiveRequestMap<V> {
|
||||||
|
fn insert(&mut self, request_id: &RequestId, request: V) {
|
||||||
|
self.0.insert(*request_id, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self, request_id: RequestId) -> Option<&V> {
|
||||||
|
self.0.get(&request_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mut(&mut self, request_id: RequestId) -> Option<&mut V> {
|
||||||
|
self.0.get_mut(&request_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove(&mut self, request_id: RequestId) -> bool {
|
||||||
|
self.0.remove(&request_id).is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn for_each<F: FnMut(&RequestId, &V)>(&self, mut f: F) {
|
||||||
|
for (req_id, active_req) in &self.0 {
|
||||||
|
f(req_id, active_req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn for_each_mut<F: FnMut(&RequestId, &mut V)>(&mut self, mut f: F) {
|
||||||
|
for (req_id, active_req) in &mut self.0 {
|
||||||
|
f(req_id, active_req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user