leodos_protocols/transport/cfdp/class2/machine/sender/action.rs
1use heapless::Vec;
2
3use crate::transport::cfdp::CfdpError;
4use crate::transport::cfdp::class2::machine::MAX_ACTIONS_PER_EVENT;
5use crate::transport::cfdp::class2::machine::PromptType;
6use crate::transport::cfdp::class2::machine::TimerType;
7use crate::transport::cfdp::class2::machine::TransactionId;
8use crate::transport::cfdp::filestore::FileId;
9use crate::transport::cfdp::pdu::EntityId;
10use crate::transport::cfdp::pdu::file_directive::ConditionCode;
11use crate::transport::cfdp::pdu::file_directive::ack::AckedDirectiveCode;
12use crate::transport::cfdp::pdu::file_directive::ack::TransactionStatus;
13use crate::transport::cfdp::pdu::file_directive::metadata::ChecksumType;
14use crate::transport::cfdp::pdu::file_directive::nak::NakSegmentsIterator;
15
16/// Represents all possible outputs from the `SenderMachine`.
17///
18/// These are instructions for the `Runner` to execute, such as sending PDUs,
19/// managing timers, or interacting with the filestore.
20#[derive(Debug)]
21pub enum Action<'a> {
22 /// Instructs the `Runner` to serialize and send a Metadata PDU.
23 SendMetadata {
24 /// Identifies the transaction this PDU belongs to.
25 transaction_id: TransactionId,
26 /// The remote entity to send this PDU to.
27 destination_id: EntityId,
28 /// Total size of the file being transferred in bytes.
29 file_size: u64,
30 /// Filestore identifier for the file on the sending side.
31 source_file_name: FileId,
32 /// Filestore identifier for the file on the receiving side.
33 destination_file_name: FileId,
34 /// Algorithm used to verify file integrity.
35 checksum_type: ChecksumType,
36 },
37 /// Instructs the `Runner` to serialize and send a File Data PDU.
38 SendFileData {
39 /// Identifies the transaction this PDU belongs to.
40 transaction_id: TransactionId,
41 /// The remote entity to send this PDU to.
42 destination_id: EntityId,
43 /// Byte offset within the file where this data begins.
44 offset: u64,
45 /// The file data segment payload.
46 data: &'a [u8],
47 },
48 /// Instructs the `Runner` to serialize and send an EOF PDU.
49 SendEof {
50 /// Identifies the transaction this PDU belongs to.
51 transaction_id: TransactionId,
52 /// The remote entity to send this PDU to.
53 destination_id: EntityId,
54 /// Status condition at the time the EOF is sent.
55 condition_code: ConditionCode,
56 /// Total size of the file in bytes.
57 file_size: u64,
58 /// Computed checksum of the complete file data.
59 checksum: u32,
60 },
61 /// Instructs the `Runner` to serialize and send a Finished PDU.
62 SendFinished {
63 /// Identifies the transaction this PDU belongs to.
64 transaction_id: TransactionId,
65 /// The remote entity to send this PDU to.
66 destination_id: EntityId,
67 /// Final status condition of the transaction.
68 condition_code: ConditionCode,
69 },
70 /// Instructs the `Runner` to serialize and send an ACK PDU.
71 SendAck {
72 /// Identifies the transaction this PDU belongs to.
73 transaction_id: TransactionId,
74 /// The remote entity to send this PDU to.
75 destination_id: EntityId,
76 /// The directive code being acknowledged.
77 acked_directive_code: AckedDirectiveCode,
78 /// Status condition associated with the acknowledgment.
79 condition_code: ConditionCode,
80 /// Current status of the transaction being acknowledged.
81 transaction_status: TransactionStatus,
82 },
83 /// Instructs the `Runner` to serialize and send a Prompt PDU.
84 SendPrompt {
85 /// Identifies the transaction this PDU belongs to.
86 transaction_id: TransactionId,
87 /// The remote entity to send this PDU to.
88 destination_id: EntityId,
89 /// Whether to prompt for a NAK or Keep Alive response.
90 prompt_type: PromptType,
91 },
92 /// Instructs the `Runner` to read a segment of data from the filestore.
93 ReadDataSegment {
94 /// Identifies the transaction this read belongs to.
95 transaction_id: TransactionId,
96 /// Byte offset where the segment begins.
97 start_offset: u64,
98 /// Byte offset where the segment ends (exclusive).
99 end_offset: u64,
100 },
101 /// Instructs the `Runner` to read multiple segments of data from the filestore.
102 ReadDataSegmentBatch {
103 /// Identifies the transaction this batch read belongs to.
104 transaction_id: TransactionId,
105 /// Iterator over the missing segments requested by the receiver.
106 segments: NakSegmentsIterator<'a>,
107 },
108 /// Instructs the `Runner` to start a timer for a specific transaction.
109 StartTimer {
110 /// Identifies the transaction this timer belongs to.
111 transaction_id: TransactionId,
112 /// The kind of timer to start (e.g. Ack, Nak, Inactivity).
113 timer_type: TimerType,
114 /// Duration of the timer in seconds.
115 seconds: u16,
116 },
117 /// Instructs the `Runner` to stop a timer for a specific transaction.
118 StopTimer {
119 /// Identifies the transaction this timer belongs to.
120 transaction_id: TransactionId,
121 /// The type of timer to stop. If `None`, stops all timers for the transaction.
122 timer_type: Option<TimerType>,
123 },
124 /// Instructs the `Runner` that a transaction is completed and can be cleaned up.
125 TerminateTransaction {
126 /// Identifies the transaction to terminate.
127 transaction_id: TransactionId,
128 /// Final status condition describing why the transaction ended.
129 condition_code: ConditionCode,
130 },
131 /// Instructs the `Runner` to calculate a checksum for a transaction.
132 CalculateChecksum {
133 /// Identifies the transaction to compute the checksum for.
134 transaction_id: TransactionId,
135 /// Algorithm to use for the checksum calculation.
136 checksum_type: ChecksumType,
137 },
138 /// Instructs the `Runner` to notify the user that a fault has occurred.
139 NotifyFault {
140 /// Identifies the faulted transaction.
141 transaction_id: TransactionId,
142 /// The condition that caused the fault.
143 condition_code: ConditionCode,
144 },
145 /// Instructs the `Runner` to notify the user that a transaction was suspended.
146 NotifySuspended {
147 /// Identifies the suspended transaction.
148 transaction_id: TransactionId,
149 },
150 /// Instructs the `Runner` to notify the user that a transaction was resumed.
151 NotifyResumed {
152 /// Identifies the resumed transaction.
153 transaction_id: TransactionId,
154 /// Number of bytes successfully transferred before suspension.
155 progress: u64,
156 },
157}
158
159/// A bounded collection of actions produced by processing a single event.
160pub struct Actions<'a> {
161 /// The bounded buffer of actions.
162 actions: Vec<Action<'a>, MAX_ACTIONS_PER_EVENT, u8>,
163}
164
165impl<'a> Actions<'a> {
166 /// Creates an empty `Actions` collection.
167 pub fn new() -> Self {
168 Actions {
169 actions: Vec::new(),
170 }
171 }
172
173 /// Adds an action to the collection.
174 pub fn push(&mut self, action: Action<'a>) -> Result<(), CfdpError> {
175 self.actions
176 .push(action)
177 .map_err(|_| CfdpError::ActionBufferFull)
178 }
179
180 /// Returns an iterator over the actions.
181 pub fn iter(&self) -> impl Iterator<Item = &Action<'a>> {
182 self.actions.iter()
183 }
184
185 /// Removes all actions from the collection.
186 pub fn clear(&mut self) {
187 self.actions.clear();
188 }
189}
190
191impl<'a> Iterator for Actions<'a> {
192 type Item = Action<'a>;
193
194 fn next(&mut self) -> Option<Self::Item> {
195 self.actions.pop()
196 }
197}