From 0bd492038dcb397726ead46f2baefac4c05636da Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 21 Feb 2024 17:47:15 +0100 Subject: [PATCH] lets just push through with one concrete example and work from there --- satrs/src/mode_tree.rs | 171 +++++++++++++++++++++++++++++++++++++---- satrs/src/pus/mod.rs | 14 ++-- satrs/src/queue.rs | 12 +-- 3 files changed, 171 insertions(+), 26 deletions(-) diff --git a/satrs/src/mode_tree.rs b/satrs/src/mode_tree.rs index 4eaecf6..8ec9910 100644 --- a/satrs/src/mode_tree.rs +++ b/satrs/src/mode_tree.rs @@ -5,7 +5,7 @@ use hashbrown::HashMap; use crate::{ mode::{Mode, ModeAndSubmode, ModeReply, ModeRequest, Submode}, - queue::GenericSendError, + queue::{GenericReceiveError, GenericSendError}, ChannelId, }; @@ -51,6 +51,7 @@ pub type ModeTable = HashMap; pub enum ModeMessagingError { TargetDoesNotExist(ChannelId), Send(GenericSendError), + Receive(GenericReceiveError), } impl From for ModeMessagingError { fn from(value: GenericSendError) -> Self { @@ -58,7 +59,13 @@ impl From for ModeMessagingError { } } -pub trait ModeReplyHandler { +impl From for ModeMessagingError { + fn from(value: GenericReceiveError) -> Self { + Self::Receive(value) + } +} + +pub trait ModeReplySendProvider { fn local_channel_id(&self) -> ChannelId; fn send_mode_reply( @@ -68,12 +75,12 @@ pub trait ModeReplyHandler { ) -> Result<(), ModeMessagingError>; } -pub struct StandardModeReplyMap { +pub struct StandardModeReplySender { pub local_id: ChannelId, pub reply_sender_map: HashMap>, } -impl ModeReplyHandler for StandardModeReplyMap { +impl ModeReplySendProvider for StandardModeReplySender { fn send_mode_reply( &mut self, target_channel_id: ChannelId, @@ -95,7 +102,80 @@ impl ModeReplyHandler for StandardModeReplyMap { } } -pub trait ModeRequestSender { +impl StandardModeReplySender { + pub fn new(local_id: ChannelId) -> Self { + Self { + local_id, + reply_sender_map: HashMap::new(), + } + } + + pub fn add_reply_target( + &mut self, + target_id: ChannelId, + reply_sender: mpsc::Sender, + ) { + self.reply_sender_map.insert(target_id, reply_sender); + } +} + +pub struct ModeReplyTuple { + pub sender_id: ChannelId, + pub reply: ModeReply, +} + +pub trait ModeReplyReceiver { + fn try_recv_mode_reply(&self) -> Result, ModeMessagingError>; +} + +pub struct StandardModeReplyReceiver { + pub sender_id: ChannelId, + pub receiver: mpsc::Receiver, +} + +#[derive(Default)] +pub struct StandardModeReplyReceiverList { + pub reply_receiver_vec: Vec, +} + +impl StandardModeReplyReceiverList { + pub fn add_reply_receiver( + &mut self, + sender_id: ChannelId, + receiver: mpsc::Receiver, + ) { + self.reply_receiver_vec.push(StandardModeReplyReceiver { + sender_id, + receiver, + }); + } +} + +impl ModeReplyReceiver for StandardModeReplyReceiverList { + fn try_recv_mode_reply(&self) -> Result, ModeMessagingError> { + for reply_receiver in &self.reply_receiver_vec { + match reply_receiver.receiver.try_recv() { + Ok(reply) => { + return Ok(Some(ModeReplyTuple { + sender_id: reply_receiver.sender_id, + reply, + })) + } + Err(e) => { + if e == mpsc::TryRecvError::Disconnected { + return Err(GenericReceiveError::TxDisconnected(Some( + reply_receiver.sender_id, + )) + .into()); + } + } + } + } + Ok(None) + } +} + +pub trait ModeRequestSendProvider { fn local_channel_id(&self) -> Option; fn send_mode_request( &mut self, @@ -104,12 +184,12 @@ pub trait ModeRequestSender { ) -> Result<(), ModeMessagingError>; } -pub struct StandardModeRequestMap { +pub struct StandardModeRequestSender { pub local_channel_id: ChannelId, pub request_sender_map: HashMap>, } -impl ModeRequestSender for StandardModeRequestMap { +impl ModeRequestSendProvider for StandardModeRequestSender { fn send_mode_request( &mut self, target_id: ChannelId, @@ -134,6 +214,23 @@ impl ModeRequestSender for StandardModeRequestMap { } } +impl StandardModeRequestSender { + pub fn new(local_channel_id: ChannelId) -> Self { + Self { + local_channel_id, + request_sender_map: HashMap::new(), + } + } + + pub fn add_request_target( + &mut self, + target_id: ChannelId, + request_sender: mpsc::Sender, + ) { + self.request_sender_map.insert(target_id, request_sender); + } +} + pub trait ModeProvider { fn mode_and_submode(&self) -> ModeAndSubmode; } @@ -154,22 +251,25 @@ pub trait ModeRequestHandler: ModeProvider { mod tests { use std::{println, sync::mpsc}; + use hashbrown::HashMap; + use crate::{ mode::{ModeAndSubmode, ModeReply, ModeRequest}, - mode_tree::ModeRequestSender, + mode_tree::ModeRequestSendProvider, ChannelId, }; use super::{ - ModeMessagingError, ModeProvider, ModeReplyHandler, ModeRequestHandler, - ModeRequestWithSenderId, StandardModeReplyMap, StandardModeRequestMap, + ModeMessagingError, ModeProvider, ModeReplySendProvider, ModeRequestHandler, + ModeRequestWithSenderId, StandardModeReplyReceiverList, StandardModeReplySender, + StandardModeRequestSender, }; struct TestDevice { /// One receiver handle for all mode requests. pub mode_req_receiver: mpsc::Receiver, /// This structure contains all handles to send mode replies. - pub mode_reply_sender: StandardModeReplyMap, + pub mode_reply_sender: StandardModeReplySender, pub last_mode_sender: Option, pub mode_and_submode: ModeAndSubmode, pub target_mode_and_submode: Option, @@ -179,9 +279,10 @@ mod tests { /// One receiver handle for all mode requests. pub mode_req_receiver: mpsc::Receiver, /// This structure contains all handles to send mode replies. - pub mode_reply_sender: StandardModeReplyMap, + pub mode_reply_sender: StandardModeReplySender, /// This structure contains all handles to send mode requests to its children. - pub mode_children_map: StandardModeRequestMap, + pub mode_children_map: StandardModeRequestSender, + pub mode_reply_receiver_list: StandardModeReplyReceiverList, pub last_mode_sender: Option, pub mode_and_submode: ModeAndSubmode, pub target_mode_and_submode: Option, @@ -194,6 +295,10 @@ mod tests { } impl TestAssembly { + pub fn run(&mut self) { + self.check_mode_requests() + } + pub fn check_mode_requests(&mut self) { match self.mode_req_receiver.try_recv() { Ok(ModeRequestWithSenderId { sender_id, request }) => { @@ -219,6 +324,7 @@ mod tests { }; } } + impl ModeRequestHandler for TestAssembly { fn start_transition( &mut self, @@ -258,4 +364,43 @@ mod tests { Ok(()) } } + + pub enum TestChannelId { + Device1 = 1, + Device2 = 2, + Assembly = 3, + } + #[test] + fn basic_test() { + let (dev1_sender, dev1_receiver) = mpsc::channel(); + let (dev2_sender, dev2_receiver) = mpsc::channel(); + let mut mode_reply_sender_dev1 = + StandardModeReplySender::new(TestChannelId::Device1 as u32); + let mut mode_reply_sender_dev2 = + StandardModeReplySender::new(TestChannelId::Device2 as u32); + let mut mode_request_map_assy = + StandardModeRequestSender::new(TestChannelId::Assembly as u32); + let mut mode_reply_map_assy = StandardModeReplySender::new(TestChannelId::Assembly as u32); + + let (dev1_reply_sender, assy_reply_receiver_dev1) = mpsc::channel(); + let (dev2_reply_sender, assy_reply_receiver_dev2) = mpsc::channel(); + mode_reply_sender_dev1.add_reply_target(TestChannelId::Assembly as u32, dev1_reply_sender); + mode_reply_sender_dev2.add_reply_target(TestChannelId::Assembly as u32, dev2_reply_sender); + //mode_reply_map_assy.add_reply_target(target_id, reply_sender) + + let device1 = TestDevice { + mode_req_receiver: dev1_receiver, + mode_reply_sender: mode_reply_sender_dev1, + last_mode_sender: None, + mode_and_submode: ModeAndSubmode::new(0, 0), + target_mode_and_submode: None, + }; + let device2 = TestDevice { + mode_req_receiver: dev2_receiver, + mode_reply_sender: mode_reply_sender_dev2, + last_mode_sender: None, + mode_and_submode: ModeAndSubmode::new(0, 0), + target_mode_and_submode: None, + }; + } } diff --git a/satrs/src/pus/mod.rs b/satrs/src/pus/mod.rs index 91be068..0d2168c 100644 --- a/satrs/src/pus/mod.rs +++ b/satrs/src/pus/mod.rs @@ -2,7 +2,7 @@ //! //! This module contains structures to make working with the PUS C standard easier. //! The satrs-example application contains various usage examples of these components. -use crate::queue::{GenericRecvError, GenericSendError}; +use crate::queue::{GenericReceiveError, GenericSendError}; use crate::ChannelId; use core::fmt::{Display, Formatter}; #[cfg(feature = "alloc")] @@ -64,7 +64,7 @@ pub enum EcssTmtcError { Pus(PusError), CantSendAddr(StoreAddr), Send(GenericSendError), - Recv(GenericRecvError), + Recv(GenericReceiveError), } impl Display for EcssTmtcError { @@ -110,8 +110,8 @@ impl From for EcssTmtcError { } } -impl From for EcssTmtcError { - fn from(value: GenericRecvError) -> Self { +impl From for EcssTmtcError { + fn from(value: GenericReceiveError) -> Self { Self::Recv(value) } } @@ -367,7 +367,7 @@ pub mod std_mod { use crate::pus::verification::{TcStateAccepted, VerificationToken}; use crate::pus::{ EcssChannel, EcssTcAndToken, EcssTcReceiver, EcssTcReceiverCore, EcssTmSender, - EcssTmSenderCore, EcssTmtcError, GenericRecvError, GenericSendError, PusTmWrapper, + EcssTmSenderCore, EcssTmtcError, GenericReceiveError, GenericSendError, PusTmWrapper, TryRecvTmtcError, }; use crate::tmtc::tm_helper::SharedTmPool; @@ -486,7 +486,7 @@ pub mod std_mod { self.receiver.try_recv().map_err(|e| match e { TryRecvError::Empty => TryRecvTmtcError::Empty, TryRecvError::Disconnected => { - TryRecvTmtcError::Error(EcssTmtcError::from(GenericRecvError::TxDisconnected)) + TryRecvTmtcError::Error(EcssTmtcError::from(GenericReceiveError::TxDisconnected(Some(self.id())))) } }) } @@ -626,7 +626,7 @@ pub mod std_mod { self.receiver.try_recv().map_err(|e| match e { cb::TryRecvError::Empty => TryRecvTmtcError::Empty, cb::TryRecvError::Disconnected => { - TryRecvTmtcError::Error(EcssTmtcError::from(GenericRecvError::TxDisconnected)) + TryRecvTmtcError::Error(EcssTmtcError::from(GenericReceiveError::TxDisconnected(Some(self.id())))) } }) } diff --git a/satrs/src/queue.rs b/satrs/src/queue.rs index 2d344e0..af73890 100644 --- a/satrs/src/queue.rs +++ b/satrs/src/queue.rs @@ -30,16 +30,16 @@ impl Error for GenericSendError {} /// Generic error type for sending something via a message queue. #[derive(Debug, Copy, Clone)] -pub enum GenericRecvError { +pub enum GenericReceiveError { Empty, - TxDisconnected, + TxDisconnected(Option) } -impl Display for GenericRecvError { +impl Display for GenericReceiveError { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self { - Self::TxDisconnected => { - write!(f, "tx side has disconnected") + Self::TxDisconnected(channel_id) => { + write!(f, "tx side with id {channel_id:?} has disconnected") } Self::Empty => { write!(f, "nothing to receive") @@ -49,4 +49,4 @@ impl Display for GenericRecvError { } #[cfg(feature = "std")] -impl Error for GenericRecvError {} +impl Error for GenericReceiveError {}