From e9df41614573b0548d356bb6e3892ab42e0ce61b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 5 Jun 2024 16:34:21 +0200 Subject: [PATCH] fix dependency issues --- satrs-mib/Cargo.toml | 1 + satrs-mib/codegen/Cargo.toml | 1 + satrs-shared/Cargo.toml | 4 +- satrs/Cargo.toml | 5 +- satrs/src/cfdp/dest.rs | 3 +- satrs/src/cfdp/mod.rs | 3 +- satrs/src/cfdp/request.rs | 308 +++++++++++++++++++++++++++++++++++ 7 files changed, 321 insertions(+), 4 deletions(-) create mode 100644 satrs/src/cfdp/request.rs diff --git a/satrs-mib/Cargo.toml b/satrs-mib/Cargo.toml index 96c7a37..54759bf 100644 --- a/satrs-mib/Cargo.toml +++ b/satrs-mib/Cargo.toml @@ -25,6 +25,7 @@ optional = true [dependencies.satrs-shared] version = ">=0.1.3, <0.2" features = ["serde"] +path = "../satrs-shared" [dependencies.satrs-mib-codegen] path = "codegen" diff --git a/satrs-mib/codegen/Cargo.toml b/satrs-mib/codegen/Cargo.toml index 584a66e..f5a674a 100644 --- a/satrs-mib/codegen/Cargo.toml +++ b/satrs-mib/codegen/Cargo.toml @@ -29,6 +29,7 @@ trybuild = { version = "1", features = ["diff"] } [dev-dependencies.satrs-shared] version = ">=0.1.3, <0.2" +path = "../../satrs-shared" [dev-dependencies.satrs-mib] path = ".." diff --git a/satrs-shared/Cargo.toml b/satrs-shared/Cargo.toml index 175f909..3a2520b 100644 --- a/satrs-shared/Cargo.toml +++ b/satrs-shared/Cargo.toml @@ -22,8 +22,10 @@ version = "0.3" optional = true [dependencies.spacepackets] -version = ">0.9, <=0.11" +version = ">0.9" default-features = false +git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets" +branch = "cfdp-tlv-owned-type" [features] serde = ["dep:serde", "spacepackets/serde"] diff --git a/satrs/Cargo.toml b/satrs/Cargo.toml index ec2b2d0..5c9fd0d 100644 --- a/satrs/Cargo.toml +++ b/satrs/Cargo.toml @@ -21,14 +21,17 @@ crc = "3" [dependencies.satrs-shared] version = ">=0.1.3, <0.2" +path = "../satrs-shared" [dependencies.num_enum] version = ">0.5, <=0.7" default-features = false [dependencies.spacepackets] -version = "0.11" +version = "0.12" default-features = false +git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets" +branch = "cfdp-tlv-owned-type" [dependencies.cobs] git = "https://github.com/robamu/cobs.rs.git" diff --git a/satrs/src/cfdp/dest.rs b/satrs/src/cfdp/dest.rs index b1e12da..c320bb2 100644 --- a/satrs/src/cfdp/dest.rs +++ b/satrs/src/cfdp/dest.rs @@ -20,7 +20,7 @@ use spacepackets::{ metadata::{MetadataGenericParams, MetadataPduReader}, CfdpPdu, CommonPduConfig, FileDirectiveType, PduError, PduHeader, WritablePduPacket, }, - tlv::{msg_to_user::MsgToUserTlv, EntityIdTlv, GenericTlv, TlvType}, + tlv::{msg_to_user::MsgToUserTlv, EntityIdTlv, GenericTlv, ReadableTlv, TlvType}, ChecksumType, ConditionCode, FaultHandlerCode, PduType, TransmissionMode, }, util::{UnsignedByteField, UnsignedEnum}, @@ -94,6 +94,7 @@ struct TransactionParams { file_properties: FileProperties, cksum_buf: [u8; 1024], msgs_to_user_size: usize, + // TODO: Should we make this configurable? msgs_to_user_buf: [u8; 1024], remote_cfg: Option, } diff --git a/satrs/src/cfdp/mod.rs b/satrs/src/cfdp/mod.rs index 51f72e6..514b8ce 100644 --- a/satrs/src/cfdp/mod.rs +++ b/satrs/src/cfdp/mod.rs @@ -21,6 +21,7 @@ use crate::time::CountdownProvider; pub mod dest; #[cfg(feature = "alloc")] pub mod filestore; +pub mod request; #[cfg(feature = "std")] pub mod source; pub mod user; @@ -332,7 +333,7 @@ pub trait UserFaultHookProvider { } #[derive(Debug, PartialEq, Eq, Copy, Clone)] -struct DummyFaultHook {} +pub struct DummyFaultHook {} impl UserFaultHookProvider for DummyFaultHook { fn notice_of_suspension_cb( diff --git a/satrs/src/cfdp/request.rs b/satrs/src/cfdp/request.rs new file mode 100644 index 0000000..ce87c04 --- /dev/null +++ b/satrs/src/cfdp/request.rs @@ -0,0 +1,308 @@ +use spacepackets::{ + cfdp::{ + tlv::{GenericTlv, Tlv, TlvType}, + SegmentationControl, TransmissionMode, + }, + util::UnsignedByteField, +}; + +trait ReadablePutRequest { + fn destination_id(&self) -> UnsignedByteField; + fn source_file(&self) -> Option<&str>; + fn dest_file(&self) -> Option<&str>; + fn trans_mode(&self) -> Option; + fn closure_requested(&self) -> Option; + fn seg_ctrl(&self) -> Option; + fn msgs_to_user(&self, f: impl FnMut(&Tlv)); + fn fault_handler_overrides(&self, f: impl FnMut(&Tlv)); + fn flow_label(&self) -> Option; + fn fs_requests(&self, f: impl FnMut(&Tlv)); +} + +#[derive(Debug, PartialEq, Eq)] +pub struct PutRequest<'src_file, 'dest_file, 'msgs_to_user, 'fh_ovrds, 'flow_label, 'fs_requests> { + pub destination_id: UnsignedByteField, + pub source_file: Option<&'src_file str>, + pub dest_file: Option<&'dest_file str>, + pub trans_mode: Option, + pub closure_requested: Option, + pub seg_ctrl: Option, + pub msgs_to_user: Option<&'msgs_to_user [Tlv<'msgs_to_user>]>, + pub fault_handler_overrides: Option<&'fh_ovrds [Tlv<'fh_ovrds>]>, + pub flow_label: Option>, + pub fs_requests: Option<&'fs_requests [Tlv<'fs_requests>]>, +} + +impl ReadablePutRequest for PutRequest<'_, '_, '_, '_, '_, '_> { + fn destination_id(&self) -> UnsignedByteField { + self.destination_id + } + + fn source_file(&self) -> Option<&str> { + self.source_file + } + + fn dest_file(&self) -> Option<&str> { + self.dest_file + } + + fn trans_mode(&self) -> Option { + self.trans_mode + } + + fn closure_requested(&self) -> Option { + self.closure_requested + } + + fn seg_ctrl(&self) -> Option { + self.seg_ctrl + } + + fn msgs_to_user(&self, mut f: impl FnMut(&Tlv)) { + if let Some(msgs_to_user) = self.msgs_to_user { + for msg_to_user in msgs_to_user { + f(msg_to_user) + } + } + } + + fn fault_handler_overrides(&self, mut f: impl FnMut(&Tlv)) { + if let Some(fh_overrides) = self.fault_handler_overrides { + for fh_override in fh_overrides { + f(fh_override) + } + } + } + + fn flow_label(&self) -> Option { + self.flow_label + } + + fn fs_requests(&self, mut f: impl FnMut(&Tlv)) { + if let Some(fs_requests) = self.fs_requests { + for fs_request in fs_requests { + f(fs_request) + } + } + } +} + +impl<'src_file, 'dest_file> PutRequest<'src_file, 'dest_file, 'static, 'static, 'static, 'static> { + pub fn new_regular_request( + dest_id: UnsignedByteField, + source_file: &'src_file str, + dest_file: &'dest_file str, + trans_mode: Option, + closure_requested: Option, + ) -> Self { + Self { + destination_id: dest_id, + source_file: Some(source_file), + dest_file: Some(dest_file), + trans_mode, + closure_requested, + seg_ctrl: None, + msgs_to_user: None, + fault_handler_overrides: None, + flow_label: None, + fs_requests: None, + } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct TlvWithInvalidType(pub(crate) ()); + +impl<'msgs_to_user> PutRequest<'static, 'static, 'msgs_to_user, 'static, 'static, 'static> { + pub fn new_msgs_to_user_only( + dest_id: UnsignedByteField, + msgs_to_user: &'msgs_to_user [Tlv<'msgs_to_user>], + ) -> Result { + Ok(Self { + destination_id: dest_id, + source_file: None, + dest_file: None, + trans_mode: None, + closure_requested: None, + seg_ctrl: None, + msgs_to_user: Some(msgs_to_user), + fault_handler_overrides: None, + flow_label: None, + fs_requests: None, + }) + } + + /// Uses [generic_tlv_list_type_check] to check the TLV type validity of all TLV fields. + pub fn check_tlv_type_validities(&self) -> bool { + generic_tlv_list_type_check(self.msgs_to_user, TlvType::MsgToUser); + if let Some(msgs_to_user) = self.msgs_to_user { + for msg_to_user in msgs_to_user { + if msg_to_user.tlv_type().is_none() { + return false; + } + if msg_to_user.tlv_type().unwrap() != TlvType::MsgToUser { + return false; + } + } + } + generic_tlv_list_type_check(self.fault_handler_overrides, TlvType::FaultHandler); + generic_tlv_list_type_check(self.fs_requests, TlvType::FilestoreRequest); + true + } +} + +pub fn generic_tlv_list_type_check(opt_tlvs: Option<&[Tlv<'_>]>, tlv_type: TlvType) -> bool { + if let Some(tlvs) = opt_tlvs { + for tlv in tlvs { + if tlv.tlv_type().is_none() { + return false; + } + if tlv.tlv_type().unwrap() != tlv_type { + return false; + } + } + } + true +} + +#[cfg(feature = "alloc")] +pub mod alloc_mod { + use super::*; + use alloc::string::ToString; + use spacepackets::cfdp::tlv::{msg_to_user::MsgToUserTlv, TlvOwned}; + + #[derive(Debug, Clone, PartialEq, Eq)] + #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] + pub struct PutRequestOwned { + pub destination_id: UnsignedByteField, + pub source_file: Option, + pub dest_file: Option, + pub trans_mode: Option, + pub closure_requested: Option, + pub seg_ctrl: Option, + pub msgs_to_user: Option>, + pub fault_handler_overrides: Option>, + pub flow_label: Option, + pub fs_requests: Option>, + } + + impl PutRequestOwned { + pub fn new_regular_request( + dest_id: UnsignedByteField, + source_file: &str, + dest_file: &str, + trans_mode: Option, + closure_requested: Option, + ) -> Self { + Self { + destination_id: dest_id, + source_file: Some(source_file.to_string()), + dest_file: Some(dest_file.to_string()), + trans_mode, + closure_requested, + seg_ctrl: None, + msgs_to_user: None, + fault_handler_overrides: None, + flow_label: None, + fs_requests: None, + } + } + + pub fn new_msgs_to_user_only( + dest_id: UnsignedByteField, + msgs_to_user: &[MsgToUserTlv<'_>], + ) -> Result { + Ok(Self { + destination_id: dest_id, + source_file: None, + dest_file: None, + trans_mode: None, + closure_requested: None, + seg_ctrl: None, + msgs_to_user: Some(msgs_to_user.iter().map(|msg| msg.tlv.to_owned()).collect()), + fault_handler_overrides: None, + flow_label: None, + fs_requests: None, + }) + } + } + + impl From> for PutRequestOwned { + fn from(req: PutRequest<'_, '_, '_, '_, '_, '_>) -> Self { + Self { + destination_id: req.destination_id, + source_file: req.source_file.map(|s| s.into()), + dest_file: req.dest_file.map(|s| s.into()), + trans_mode: req.trans_mode, + closure_requested: req.closure_requested, + seg_ctrl: req.seg_ctrl, + msgs_to_user: req + .msgs_to_user + .map(|msgs_to_user| msgs_to_user.iter().map(|msg| msg.to_owned()).collect()), + fault_handler_overrides: req + .msgs_to_user + .map(|fh_overides| fh_overides.iter().map(|msg| msg.to_owned()).collect()), + flow_label: req + .flow_label + .map(|flow_label_tlv| flow_label_tlv.to_owned()), + fs_requests: req + .fs_requests + .map(|fs_requests| fs_requests.iter().map(|msg| msg.to_owned()).collect()), + } + } + } + + impl ReadablePutRequest for PutRequestOwned { + fn destination_id(&self) -> UnsignedByteField { + self.destination_id + } + + fn source_file(&self) -> Option<&str> { + self.source_file.as_deref() + } + + fn dest_file(&self) -> Option<&str> { + self.dest_file.as_deref() + } + + fn trans_mode(&self) -> Option { + self.trans_mode + } + + fn closure_requested(&self) -> Option { + self.closure_requested + } + + fn seg_ctrl(&self) -> Option { + self.seg_ctrl + } + + fn msgs_to_user(&self, mut f: impl FnMut(&Tlv)) { + if let Some(msgs_to_user) = &self.msgs_to_user { + for msg_to_user in msgs_to_user { + f(&msg_to_user.as_tlv()) + } + } + } + + fn fault_handler_overrides(&self, mut f: impl FnMut(&Tlv)) { + if let Some(fh_overrides) = &self.fault_handler_overrides { + for fh_override in fh_overrides { + f(&fh_override.as_tlv()) + } + } + } + + fn flow_label(&self) -> Option { + self.flow_label.as_ref().map(|tlv| tlv.as_tlv()) + } + + fn fs_requests(&self, mut f: impl FnMut(&Tlv)) { + if let Some(fs_requests) = &self.fs_requests { + for fs_request in fs_requests { + f(&fs_request.as_tlv()) + } + } + } + } +}