leodos_protocols/transport/cfdp/class2/machine/receiver/action.rs
1use heapless::Vec;
2
3use crate::transport::cfdp::class2::machine::TimerType;
4use crate::transport::cfdp::class2::machine::TransactionId;
5use crate::transport::cfdp::class2::machine::MAX_ACTIONS_PER_EVENT;
6use crate::transport::cfdp::filestore::FileId;
7use crate::transport::cfdp::pdu::file_directive::ack::TransactionStatus;
8use crate::transport::cfdp::pdu::file_directive::metadata::ChecksumType;
9use crate::transport::cfdp::pdu::file_directive::ConditionCode;
10use crate::transport::cfdp::pdu::file_directive::DirectiveCode;
11use crate::transport::cfdp::pdu::tlv::filestore_request::FilestoreRequest;
12use crate::transport::cfdp::pdu::tlv::filestore_response::FilestoreResponse;
13use crate::transport::cfdp::pdu::EntityId;
14use crate::transport::cfdp::CfdpError;
15
16/// Represents all possible outputs from the `ReceiverMachine`.
17///
18/// These are instructions for the `Runner` to execute.
19#[derive(Debug, PartialEq, Eq)]
20pub enum Action<'a> {
21 /// Instructs the `Runner` to serialize and send an ACK PDU.
22 SendAck {
23 /// The transaction this ACK belongs to.
24 transaction_id: TransactionId,
25 /// The remote entity to send the ACK to.
26 destination_id: EntityId,
27 /// The directive being acknowledged.
28 directive_code: DirectiveCode,
29 /// The condition under which this ACK is sent.
30 condition_code: ConditionCode,
31 /// The current status of the transaction.
32 transaction_status: TransactionStatus,
33 },
34 /// Instructs the `Runner` to serialize and send a Finished PDU.
35 SendFinished {
36 /// Responses from executed filestore requests.
37 filestore_responses: Vec<FilestoreResponse, 4, u8>,
38 /// The transaction this Finished PDU belongs to.
39 transaction_id: TransactionId,
40 /// The remote entity to send the Finished PDU to.
41 destination_id: EntityId,
42 /// The condition under which the transaction finished.
43 condition_code: ConditionCode,
44 },
45 /// Instructs the `Runner` to serialize and send a NAK PDU.
46 SendNak {
47 /// The transaction this NAK belongs to.
48 transaction_id: TransactionId,
49 /// The remote entity to send the NAK to.
50 destination_id: EntityId,
51 /// The beginning of the file scope covered by this NAK.
52 start_of_scope: u64,
53 /// The end of the file scope covered by this NAK.
54 end_of_scope: u64,
55 // segment_requests: Vec<(U64, U64), 32>,
56 },
57 /// Instructs the `Runner` to serialize and send a Keep Alive PDU.
58 SendKeepAlive {
59 /// The transaction this Keep Alive belongs to.
60 transaction_id: TransactionId,
61 /// The remote entity to send the Keep Alive to.
62 destination_id: EntityId,
63 /// The number of file data bytes received so far.
64 progress: u64,
65 },
66 /// Instructs the `Runner` to write a chunk of data to the filestore.
67 WriteFileData {
68 /// The transaction this file data belongs to.
69 transaction_id: TransactionId,
70 /// The raw file data bytes to write.
71 data: &'a [u8],
72 /// The byte offset within the file where the data should be written.
73 offset: u64,
74 },
75 /// Instructs the `Runner` to start a timer for a specific transaction.
76 StartTimer {
77 /// The transaction this timer is associated with.
78 transaction_id: TransactionId,
79 /// The duration of the timer in seconds.
80 seconds: u16,
81 /// The kind of timer to start (e.g. ACK, NAK, inactivity).
82 timer_type: TimerType,
83 },
84 /// Instructs the `Runner` to stop a timer for a specific transaction.
85 StopTimer {
86 /// The transaction whose timer should be stopped.
87 transaction_id: TransactionId,
88 /// The type of timer to stop. If `None`, stops all timers for the transaction.
89 timer_type: Option<TimerType>,
90 },
91 /// Instructs the `Runner` to notify the user that a transaction has finished.
92 TerminateTransaction {
93 /// The transaction being terminated.
94 transaction_id: TransactionId,
95 /// The condition that caused the termination.
96 condition_code: ConditionCode,
97 },
98 /// Instructs the `Runner` to notify the user that a file has been successfully received.
99 NotifyFileReceived {
100 /// The unique ID of the completed transaction.
101 transaction_id: TransactionId,
102 /// The total size of the received file in bytes.
103 file_size: u64,
104 /// The final name of the received file.
105 file_name: FileId,
106 },
107 /// Instructs the `Runner` to verify the checksum of the received file.
108 VerifyChecksum {
109 /// The transaction whose file checksum should be verified.
110 transaction_id: TransactionId,
111 /// The checksum value declared by the sender in the EOF PDU.
112 expected_checksum: u32,
113 /// The algorithm used to compute the checksum.
114 checksum_type: ChecksumType,
115 },
116 /// Instructs the `Runner` to notify the user that a fault has occurred.
117 NotifyFault {
118 /// The transaction in which the fault occurred.
119 transaction_id: TransactionId,
120 /// The condition code describing the fault.
121 condition_code: ConditionCode,
122 },
123 /// Instructs the `Runner` to notify the user that a transaction was suspended.
124 NotifySuspended {
125 /// The transaction that was suspended.
126 transaction_id: TransactionId,
127 },
128 /// Instructs the `Runner` to notify the user that a transaction was resumed.
129 NotifyResumed {
130 /// The transaction that was resumed.
131 transaction_id: TransactionId,
132 /// The number of file data bytes received at the time of resumption.
133 progress: u64,
134 },
135 /// Instructs the Runner to execute filestore requests and report back with the results.
136 ExecuteFilestoreRequests {
137 /// The filestore requests received in the Metadata PDU.
138 requests: Vec<FilestoreRequest, 4, u8>,
139 /// The transaction these requests belong to.
140 transaction_id: TransactionId,
141 },
142}
143
144/// A bounded collection of actions produced by processing a single event.
145pub struct Actions<'a> {
146 /// The bounded buffer of actions.
147 actions: Vec<Action<'a>, MAX_ACTIONS_PER_EVENT, u8>,
148}
149
150impl<'a> Actions<'a> {
151 /// Creates an empty `Actions` collection.
152 pub fn new() -> Self {
153 Actions {
154 actions: Vec::new(),
155 }
156 }
157
158 /// Adds an action to the collection.
159 pub fn push(&mut self, action: Action<'a>) -> Result<(), CfdpError> {
160 self.actions
161 .push(action)
162 .map_err(|_| CfdpError::ActionBufferFull)
163 }
164
165 /// Returns an iterator over the actions.
166 pub fn iter(&self) -> impl Iterator<Item = &Action<'a>> {
167 self.actions.iter()
168 }
169
170 /// Removes all actions from the collection.
171 pub fn clear(&mut self) {
172 self.actions.clear();
173 }
174}
175
176impl<'a> Iterator for Actions<'a> {
177 type Item = Action<'a>;
178
179 fn next(&mut self) -> Option<Self::Item> {
180 self.actions.pop()
181 }
182}