Skip to main content

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}