cfdp_simplified/transaction/
mod.rs

1pub mod error;
2pub mod fault_handler;
3pub mod recv;
4pub mod send;
5
6pub use fault_handler::*;
7
8use std::{collections::HashMap, fmt};
9
10use camino::Utf8PathBuf;
11use error::TransactionError;
12use num_derive::FromPrimitive;
13use serde::Serialize;
14
15use crate::{
16    filestore::ChecksumType,
17    pdu::header::{CRCFlag, Condition, FileSizeFlag, SegmentedData, TransmissionMode},
18    pdu::ops::{EntityID, TransactionSeqNum},
19};
20
21#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
22pub struct TransactionID(pub EntityID, pub TransactionSeqNum);
23
24pub type TransactionResult<T> = Result<T, TransactionError>;
25
26impl fmt::Display for TransactionID {
27    // This trait requires `fmt` with this exact signature.
28    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29        write!(f, "{}.{}", self.0.to_u64(), self.1.to_u64())
30    }
31}
32
33impl TransactionID {
34    pub fn from(entity_id: EntityID, seq_num: TransactionSeqNum) -> Self {
35        Self(entity_id, seq_num)
36    }
37}
38
39#[repr(u8)]
40#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, Serialize)]
41pub enum TransactionState {
42    Active,
43    Suspended,
44    Terminated,
45}
46
47#[derive(Debug, Clone, PartialEq)]
48pub struct Metadata {
49    /// Bytes of the source filename, can be null if length is 0.
50    pub source_filename: Utf8PathBuf,
51    /// Bytes of the destination filename, can be null if length is 0.
52    pub destination_filename: Utf8PathBuf,
53    /// The size of the file being transfered in this transaction.
54    pub file_size: u64,
55    /// Flag to track what kind of [Checksum](crate::filestore::ChecksumType) will be used in this transaction.
56    pub checksum_type: ChecksumType,
57}
58
59#[derive(Clone)]
60pub struct TransactionConfig {
61    /// Identification number of the source (this) entity.
62    pub source_entity_id: EntityID,
63    /// Identification number of the destination (remote) entity.
64    pub destination_entity_id: EntityID,
65    /// CFDP [TransmissionMode]
66    pub transmission_mode: TransmissionMode,
67    /// The sequence number in Big Endian Bytes.
68    pub sequence_number: TransactionSeqNum,
69    /// Flag to indicate whether or not the file size fits inside a [u32]
70    pub file_size_flag: FileSizeFlag,
71    /// A Mapping of actions to take when each condition is reached.
72    /// See also [Condition] and [FaultHandlerAction].
73    pub fault_handler_override: HashMap<Condition, FaultHandlerAction>,
74    /// The maximum length a file segment sent to Destination can be.
75    /// u16 will be larger than any possible CCSDS packet size.
76    pub file_size_segment: u16,
77    /// Flag indicating whether or not CRCs will be present on the PDUs
78    pub crc_flag: CRCFlag,
79    /// Flag indicating whether file metadata is included with FileData
80    pub segment_metadata_flag: SegmentedData,
81    /// Maximum count of timeouts on a timer before a fault is generated.
82    pub max_count: u32,
83    /// Maximum amount timeof without activity before the inactivity timer increments its count.
84    pub inactivity_timeout: i64,
85    /// Maximum amount timeof without activity before the NAK timer increments its count.
86    pub nak_timeout: i64,
87    /// Maximum amount time of without activity before the EOF timer increments its count.
88    pub eof_timeout: i64,
89    /// Interval in secs to send a progress report.
90    pub progress_report_interval_secs: i64,
91}
92
93#[cfg(test)]
94mod test {
95    use super::*;
96    use std::collections::HashMap;
97
98    use crate::{
99        pdu::header::{CRCFlag, FileSizeFlag, SegmentedData, TransmissionMode},
100        transaction::TransactionConfig,
101    };
102
103    use rstest::fixture;
104
105    #[fixture]
106    #[once]
107    pub(crate) fn default_config() -> TransactionConfig {
108        TransactionConfig {
109            source_entity_id: EntityID::from(12_u16),
110            destination_entity_id: EntityID::from(15_u16),
111            transmission_mode: TransmissionMode::Acknowledged,
112            sequence_number: TransactionSeqNum::from(3_u32),
113            file_size_flag: FileSizeFlag::Small,
114            fault_handler_override: HashMap::new(),
115            file_size_segment: 16630_u16,
116            crc_flag: CRCFlag::NotPresent,
117            segment_metadata_flag: SegmentedData::NotPresent,
118            max_count: 5_u32,
119            inactivity_timeout: 300_i64,
120            eof_timeout: 300_i64,
121            nak_timeout: 300_i64,
122            progress_report_interval_secs: 300_i64,
123        }
124    }
125
126    #[test]
127    fn id() {
128        let id = TransactionID::from(EntityID::from(13_u16), TransactionSeqNum::from(541_u32));
129        assert_eq!(
130            TransactionID(EntityID::from(13), TransactionSeqNum::from(541)),
131            id,
132        )
133    }
134}