Svc/Ccsds/CfdpManager/docs/sdd.md
The CCSDS File Delivery Protocol (CFDP) is a space communication standard designed for reliable, autonomous file transfer in space missions. CFDP provides a robust mechanism for transferring files between ground systems and spacecraft even in environments with long propagation delays, intermittent connectivity, or high error rates.
CFDP is particularly well-suited for:
The protocol supports two operational modes:
CFDP uses Protocol Data Units (PDUs) - structured messages with a common header and type-specific payloads:
For complete protocol details, refer to the CCSDS 727.0-B-5 - CCSDS File Delivery Protocol (CFDP) Blue Book specification.
The CfdpManager component provides an F' implementation of the CFDP protocol and is designed to replace the standard F' FileUplink and FileDownlink components with the addition of guaranteed file delivery. CfdpManager implements both CFDP Class 1 and Class 2 protocols, providing options for both unacknowledged and acknowledged transfers with retransmissions, gap detection, and reliable file delivery even over lossy or intermittent communication links.
Substantial portions of this implementation were ported from NASA's CF (CFDP) Application in the Core Flight System (cFS) version 3.0.0. The ported code includes:
The F' implementation adds new components built specifically for the F' ecosystem:
Serializable interface for consistent serializationFor detailed attribution, licensing information, and a breakdown of ported vs. new code, see ATTRIBUTION.md.
The CfdpManager component diagram shows the port organization by functional grouping:
Ports are organized as follows:
run1Hz, pingIn, pingOutdataIn, dataInReturndataOut, dataReturnIn, bufferAllocate, bufferDeallocatefileIn, fileDoneOut| Name | Type | Port Type | Description |
|---|---|---|---|
| run1Hz | async input | Svc.Sched | Scheduler port that must be invoked at 1 Hz to drive CFDP protocol timer logic, transaction processing, and state machine execution |
| pingIn | async input | Svc.Ping | Health check input port for liveness monitoring |
| pingOut | output | Svc.Ping | Health check output port for responding to pings |
| Name | Type | Port Type | Description |
|---|---|---|---|
| dataOut | output array[N] | Fw.BufferSend | Send encoded CFDP PDU data buffers to downstream components. One port (N) per CFDP channel. |
| dataReturnIn | async input array[N] | Fw.BufferSend | Receive buffers previously sent via dataOut after downstream processing is complete. One port per CFDP channel. |
| bufferAllocate | output array[N] | Fw.BufferGet | Request allocation of buffers for constructing outgoing CFDP PDUs. One port (N) per CFDP channel. |
| bufferDeallocate | output array[N] | Fw.BufferSend | Return/deallocate buffers that were allocated but not sent (e.g., due to errors). One port (N) per CFDP channel. |
| Name | Type | Port Type | Description |
|---|---|---|---|
| dataIn | async input array[N] | Fw.BufferSend | Receive incoming CFDP PDU data buffers from upstream components (e.g., deframing, radio). One port (N) per CFDP channel. |
| dataInReturn | output array[N] | Fw.BufferSend | Return buffers received via dataIn after PDU processing is complete. One port (N) per CFDP channel. |
| Name | Type | Port Type | Description |
|---|---|---|---|
| fileIn | guarded input | Svc.SendFileRequest | Programmatic file send request interface. Allows other components to initiate CFDP file transfers without using commands. The handler runs on the caller's thread and only validates the request and copies it into an internal queue; the transfer is initiated later on the component's active thread when run1Hz drains the queue, so all engine state is mutated on a single thread. The synchronous response therefore reports only acceptance: STATUS_OK if the request was queued, STATUS_BUSY if the queue (depth set by the fileQueueDepth argument to configure()) is full, or STATUS_INVALID if offset/length are non-zero (unsupported, must be 0) or the filenames do not fit. The final transfer result is delivered later via fileDoneOut. Transaction arguments are populated from component parameters: FileInDefaultChannel, FileInDefaultDestEntityId, FileInDefaultClass, FileInDefaultKeep, and FileInDefaultPriority. |
| fileDoneOut | output | Svc.SendFileComplete | Asynchronous notification of file transfer completion for transfers initiated via fileIn port. Provides final transfer status. Only invoked for port-initiated transactions (not command-initiated). |
The following diagram shows typical CfdpManager port connections with other F' components:
This example demonstrates:
dataIndataOut for transmissionfileIn port and receives completion notifications via fileDoneOutThe design of CfdpManager assumes the following:
File transfers occur by exchanging CFDP Protocol Data Units (PDUs) as defined in CCSDS 727.0-B-5.
PDUs are transported in buffers provided by downstream components via the bufferAllocate port for transmission and received via the dataIn port from upstream components.
Multiple file transfers can occur simultaneously, managed across configurable channels with independent transaction pools.
Files are stored on non-volatile storage accessible via standard file I/O operations.
The run1Hz port is invoked periodically at 1 Hz to drive protocol timers and state machine execution.
For Class 2 transfers, the remote entity implements the CFDP protocol correctly and responds to PDUs according to the specification.
Received files are written to a temporary directory (ChannelConfig.tmp_dir per-channel parameter) during transfer and moved to their final destination upon successful completion.
Port-initiated file transfers (via fileIn) use default configuration parameters (FileInDefaultChannel, FileInDefaultDestEntityId, FileInDefaultClass, FileInDefaultKeep, and FileInDefaultPriority).
CfdpManager follows a layered security architecture where authentication and authorization are enforced at lower network protocol layers rather than at the application layer:
CfdpManager accepts destination file paths as specified in incoming CFDP Metadata PDUs without application-layer path validation. This approach is consistent with the CCSDS 727.0-B-5 CFDP standard, which assumes operation over authenticated communication channels.
For mission deployments, ensure radio links employ hardware encryption or cryptographic authentication, ground systems implement proper authentication and authorization controls, and operational procedures include verification of file paths before commanding transfers.
Because CfdpManager processes PDUs received from an external link, it must remain available even when the received bytes are malformed, degenerate, or hostile. The receive path treats structural properties of an incoming PDU as untrusted input and rejects or safely ignores them rather than relying on an FW_ASSERT, which would raise a FATAL and remove the deployment from service. Assertions in the CFDP code are reserved for internal invariants that cannot be influenced by received data.
A specific case handled here is a syntactically valid FileData PDU that declares a file offset but carries zero file-data octets (its PDU payload length equals the encoded offset length). Such an empty segment conveys no data: the receive handler treats it as a successful no-op — no file write and no gap-tracking update — so it can never produce a zero-length interval in the chunk tracker. This closes the denial-of-service reported in GHSA-mh5x-2m6h-8267, where a single zero-length Class 2 FileData PDU could reach a gap-tracking assertion and terminate the process. Note that this is an availability hardening measure; it does not by itself remove the need for the authenticated lower layers described above.
CfdpManager (CfdpManager.hpp)
Engine (Engine.hpp)
Channel (Channel.hpp)
Transaction (Transaction.hpp)
PduBase (Types/PduBase.hpp)
Fw::Serializable for consistent encoding/decodingPduHeader with transaction identificationConcrete PDU types (all in Types/ directory):
Classes:
Structs (defined in Types.hpp):
Utilities:
Transmission throttling governs how many outgoing PDUs can be sent in a single execution cycle of the component. This mechanism prevents the CFDP engine from overwhelming downstream components (such as communication queues or radio interfaces) with excessive PDU traffic in a single scheduler invocation.
Configuration:
Transmission throttling is controlled by the ChannelConfig.max_outgoing_pdus_per_cycle parameter, which specifies the maximum number of outgoing PDUs that can be transmitted per channel per execution cycle. This limit applies to all outgoing PDU types including Metadata, File Data, EOF, ACK, NAK, and FIN PDUs.
Implementation:
The transmission throttling mechanism is implemented through a per-channel outgoing PDU counter that is reset at the beginning of each execution cycle. When a transaction requests a buffer to send a PDU, the implementation checks if the counter has reached the configured limit. If under the limit, the buffer is allocated and the counter is incremented. If the limit is reached, buffer allocation is denied and the transaction is deferred to the next cycle, with processing resuming from where it left off.
Buffer Management:
The transmission throttling mechanism works in conjunction with buffer allocation from downstream components. Two failure modes can occur: throttling limit reached (the max_outgoing_pdus_per_cycle limit is reached and no buffer allocation is attempted) or buffer exhaustion (the downstream buffer pool is exhausted and buffer allocation fails even when under the throttling limit). In both cases, the transaction defers PDU transmission until the next cycle by returning to a pending state and resuming processing in the next execution cycle. For Class 2 transactions, protocol timers (ACK, NAK, inactivity) continue running and will eventually trigger retransmissions or transaction abandonment if PDUs cannot be sent.
Unlike transmit operations that are driven by the periodic run1Hz scheduler port, receive operations in CfdpManager are driven by the dataIn async input port. Incoming CFDP PDUs arrive via this port and are processed immediately by the component's thread when the port handler is invoked, without per-cycle limits. Receive throttling was implemented in NASA's CF (CFDP) application because CF processes received PDUs during scheduled execution cycles. In contrast, CfdpManager processes incoming PDUs asynchronously as they arrive, so there is no architectural reason to throttle incoming PDUs.
CfdpManager supports two related mechanisms for transferring the contents of a directory:
PlaybackDirectory command): a one-shot operation that sends every file currently in the source directory as individual CFDP transactions and completes when the directory has been fully processed.PollDirectory command): a recurring operation that re-checks the source directory on a fixed interval and automatically sends any new files found. Each channel supports up to MaxPollingDirPerChan independent polling slots, identified by a poll index. The file is deleted from the directory after a successful transfer.Poll cycle behavior:
Each polling slot owns an interval timer that is evaluated once per run1Hz cycle:
PollDirectory command with a non-zero interval (in seconds). A zero interval is rejected at command validation with an InvalidPollInterval event.playbackDirInitiate emits its own event on failure, and re-arming ensures the poll retries on the next interval rather than stalling.Polling continues until stopped with the StopPollDirectory command. Stopping is only honored for a slot that is currently enabled; stopping an inactive slot produces a PollDirNotActive event.
The following sequence diagrams illustrate the external protocol exchanges between spacecraft and ground systems during CFDP transactions. These diagrams focus on the PDU-level interactions and do not depict the internal state machine transitions or detailed transaction processing logic within the CfdpManager component.
This diagram shows a Class 1 file transmission from spacecraft to ground. Class 1 is unacknowledged and provides no retransmission or delivery guarantees.
sequenceDiagram
participant Ground
participant Spacecraft
Ground->>Spacecraft: SendFile command
(source file, destination file)
Note over Spacecraft: Initialize transaction
Spacecraft->>Ground: Metadata PDU
(filename, size)
loop File Data Transfer
Spacecraft->>Ground: File Data PDU
(offset, data segment)
end
Spacecraft->>Ground: EOF PDU
(checksum, file size)
Note over Spacecraft: Transaction complete
(no acknowledgment)
Note over Ground: Verify checksum
Keep or discard file
Key characteristics:
This diagram shows a Class 2 file transmission from spacecraft to ground with gap detection and retransmission. The scenario includes a missing File Data PDU that is detected and retransmitted via NAK.
sequenceDiagram
participant G_ACK as Ground
ACK Timer
participant G_NACK as Ground
NACK Timer
participant Ground
participant Spacecraft
participant S_ACK as Spacecraft
ACK Timer
Ground->>Spacecraft: SendFile command
(source file, destination file)
Note over Spacecraft: Initialize transaction
Spacecraft->>Ground: Metadata PDU
(filename, size)
Spacecraft->>Ground: File Data PDU (1)
Spacecraft--xGround: File Data PDU (2) [LOST]
Spacecraft->>Ground: File Data PDU (3)
Spacecraft->>Ground: EOF PDU
(checksum, file size)
activate S_ACK
Note over S_ACK: Armed on
EOF send
Ground->>Spacecraft: ACK(EOF)
deactivate S_ACK
Note over S_ACK: Cancelled on
ACK(EOF) received
Note over Ground: Gap detected
(missing PDU (2))
Ground->>Spacecraft: NAK
(request PDU (2))
activate G_NACK
Note over G_NACK: Armed on
NAK send
Spacecraft->>Ground: File Data PDU (2) [RETRANSMIT]
deactivate G_NACK
Note over G_NACK: Cancelled on
gap fill
Note over Ground: All data received
Verify checksum
Ground->>Spacecraft: FIN PDU
(delivery complete, file retained)
Note over Ground: File saved and
ready for use
activate G_ACK
Note over G_ACK: Armed on
FIN send
Spacecraft->>Ground: ACK(FIN)
Note over Spacecraft: Transaction complete
deactivate G_ACK
Note over G_ACK: Cancelled on
ACK(FIN) received
Note over Ground: Transaction complete
Key characteristics:
ChannelConfig.ack_timer, cancelled when ACK(EOF) or FIN is received. If the timer expires before receiving acknowledgment, the spacecraft retransmits EOF and rearms the timer. After ChannelConfig.ack_limit retries without acknowledgment, the transaction is abandoned with status ACK_LIMIT_NO_EOFThis diagram shows a Class 2 file reception at the spacecraft from ground with gap detection and retransmission. The scenario includes a missing File Data PDU that is detected and retransmitted via NAK.
sequenceDiagram
participant G_ACK as Ground
ACK Timer
participant Ground
participant Spacecraft
participant S_NAK as Spacecraft
NAK Timer
participant S_ACK as Spacecraft
ACK Timer
Note over Ground: Initialize transaction
Ground->>Spacecraft: Metadata PDU
(filename, size)
Ground--xSpacecraft: File Data PDU (1) [LOST]
Ground->>Spacecraft: File Data PDU (2)
Ground--xSpacecraft: File Data PDU (3) [LOST]
Ground->>Spacecraft: File Data PDU (4)
Ground->>Spacecraft: EOF PDU
(checksum, file size)
activate G_ACK
Note over G_ACK: Armed on
EOF send
Spacecraft->>Ground: ACK(EOF)
deactivate G_ACK
Note over G_ACK: Cancelled on
ACK(EOF) received
Note over Spacecraft: Gaps detected
(missing PDUs (1) and (3))
Spacecraft->>Ground: NAK
(request PDUs (1) and (3))
activate S_NAK
Note over S_NAK: Armed on
NAK send
Ground->>Spacecraft: File Data PDU (1) [RETRANSMIT]
Ground->>Spacecraft: File Data PDU (3) [RETRANSMIT]
deactivate S_NAK
Note over S_NAK: Cancelled on
gaps filled
Note over Spacecraft: All data received
Verify checksum
Spacecraft->>Ground: FIN PDU
(delivery complete, file retained)
Note over Spacecraft: File saved and
ready for use
activate S_ACK
Note over S_ACK: Armed on
FIN send
Ground->>Spacecraft: ACK(FIN)
Note over Ground: Transaction complete
deactivate S_ACK
Note over S_ACK: Cancelled on
ACK(FIN) received
Note over Spacecraft: Transaction complete
Key characteristics:
ChannelConfig.ack_timer, cancelled when all requested data is received. If the timer expires before receiving retransmitted data, the spacecraft sends another NAK and rearms the timer. After ChannelConfig.nack_limit retries without data, the transaction is abandoned with status NAK_LIMIT_REACHEDChannelConfig.ack_timer, cancelled when ACK(FIN) is received. If the timer expires, the spacecraft retransmits FIN and rearms the timer. After ChannelConfig.ack_limit retries without ACK(FIN), the transaction is abandonedCfdpManager uses compile-time configuration defined in two files:
These constants are defined in the Svc.Ccsds.Cfdp module and must be configured at compile time:
| Constant | Purpose |
|---|---|
NumChannels | Number of CFDP channels to instantiate. Determines the size of channel-specific port arrays and the number of independent CFDP channel instances. Each channel has its own transaction pool, configuration, and state. |
MaxFilePathSize | Maximum length for file path strings. Used to size string parameters (ChannelConfig.tmp_dir, ChannelConfig.fail_dir, ChannelConfig.move_dir) and internal file path buffers. |
MaxPduSize | Maximum PDU size in bytes. Limits the maximum possible TX PDU size. Must respect any CCSDS packet size limits on the system. |
These types define the size of CFDP protocol fields:
| Type | Purpose |
|---|---|
EntityId | Entity ID size. Maximum size of entity IDs in CFDP packets. The protocol supports variable-size entity IDs at runtime, but this establishes the maximum. Must be one of: U8, U16, U32, U64. |
TransactionSeq | Transaction sequence number size. Maximum size of transaction sequence numbers in CFDP packets. The protocol supports variable sizes at runtime, but this establishes the maximum. Must be one of: U8, U16, U32, U64. |
FileSize | File size and offset type. Used for file sizes and offsets in CFDP operations. The protocol permits 64-bit values, but the current implementation uses 32-bit. Must be one of: U8, U16, U32, U64. |
| Constant | Purpose |
|---|---|
NakMaxSegments | Maximum NAK segments supported in a NAK PDU. When sending or receiving NAK PDUs, this is the maximum number of segment requests supported. Should match ground CFDP engine configuration. |
MaxTlv | Maximum TLVs (Type-Length-Value) per PDU. Limits the number of TLV metadata fields in EOF and FIN PDUs for diagnostic information (entity IDs, fault handler overrides, messages). |
R2CrcChunkSize | Class 2 CRC calculation chunk size. Buffer size for CRC calculation upon file completion. Larger values use more stack but complete faster. Total bytes per scheduler cycle controlled by RxCrcCalcBytesPerCycle parameter. |
CFDP_CHANNEL_NUM_RX_CHUNKS_PER_TRANSACTION | RX chunks per transaction per channel (array). For Class 2 receive transactions, each chunk tracks a contiguous received file segment. Used for gap detection and NAK generation. Array size must match NumChannels. |
CFDP_CHANNEL_NUM_TX_CHUNKS_PER_TRANSACTION | TX chunks per transaction per channel (array). For Class 2 transmit transactions, each chunk tracks a gap requested via NAK that needs retransmission. Array size must match NumChannels. |
| Constant | Purpose |
|---|---|
MaxSimultaneousRx | Maximum simultaneous file receives. Each channel can support this many active/concurrent receive transactions. Contributes to total transaction pool size. |
MaxCommandedPlaybackFilesPerChan | Maximum commanded playback files per channel. Maximum number of outstanding ground-commanded file transmits per channel. |
MaxCommandedPlaybackDirectoriesPerChan | Maximum commanded playback directories per channel. Each channel can support this many ground-commanded directory playbacks. |
MaxPollingDirPerChan | Maximum polling directories per channel. Determines the size of the per-channel polling directory array. |
NumTransactionsPerPlayback | Number of transactions per playback directory. Each playback/polling directory operation can have this many active transfers pending or active at once. |
NumHistoriesPerChannel | Number of history entries per channel. Each channel maintains a circular buffer of completed transaction records for debugging and reference. Maximum value is 65536. |
The CFDP Manager provides comprehensive event reporting covering all aspects of file transfer operations, organized by functional category. Most events are warning-level to alert operators of potential issues, while activity-high events mark significant milestones like transfer start/completion and transaction control operations.
| Event Name | Severity | Description |
|---|---|---|
| TxFileQueued | activity low | TX file queued for source file (transaction sequence number) |
| SendFileInitiateFail | warning low | Failed to initiate file send transfer for source file |
| UnsupportedSendFileArguments | warning low | Invalid send file port request with offset and length |
| InvalidChannel | warning low | Invalid channel ID, maximum channel ID is specified |
| PlaybackInitiated | activity low | Successfully initiated directory playback for source directory |
| PollDirInitiated | activity low | Successfully initiated directory poll for source directory (identified by channel poll index) |
| PollDirStopped | activity low | Successfully stopped directory poll for channel and poll index |
| PollDirBusy | warning low | Cannot start directory poll - channel poll already in use |
| PollDirNotActive | warning low | Cannot stop directory poll - channel poll is not active |
| InvalidChannelPoll | warning low | Invalid poll ID, maximum poll ID is specified |
| InvalidPollInterval | warning low | Invalid poll interval requested (must be non-zero) |
| SetFlowState | activity low | Set channel to specified flow state |
| ResetCounters | activity high | Reset telemetry counters for channel (0xFF indicates all channels) |
| Event Name | Severity | Description |
|---|---|---|
| FailPduHeaderDeserialization | warning low | Failed to deserialize PDU header on channel |
| FailPduSerialization | warning low | Failed to serialize PDU type on channel |
| FailMetadataPduDeserialization | warning low | Failed to deserialize Metadata PDU on channel |
| FailFileDataPduDeserialization | warning low | Failed to deserialize File Data PDU on channel |
| FailEofPduDeserialization | warning low | Failed to deserialize EOF PDU on channel |
| FailAckPduDeserialization | warning low | Failed to deserialize ACK PDU on channel |
| FailFinPduDeserialization | warning low | Failed to deserialize FIN PDU on channel |
| FailNakPduDeserialization | warning low | Failed to deserialize NAK PDU on channel |
| Event Name | Severity | Description |
|---|---|---|
| RxAckLimitReached | warning low | RX ACK limit reached for transaction, no fin-ack sent |
| RxTempFileCreated | activity low | RX transaction creating temp file without metadata |
| RxFileCreateFailed | warning low | RX transaction failed to create file |
| RxCrcMismatch | warning low | RX transaction CRC mismatch: expected vs actual |
| RxNakLimitReached | warning low | RX transaction NAK limit reached |
| RxSeekFailed | warning low | RX transaction failed to seek to offset |
| RxWriteFailed | warning low | RX transaction write failed: expected bytes vs actual bytes |
| RxFileSizeMismatch | warning low | RX transaction EOF file size mismatch: expected vs actual |
| RxEofCancelReceived | activity high | RX transaction cancelled by sender |
| RxEofWithError | warning low | RX transaction received EOF with error condition code |
| RxSeekCrcFailed | warning low | RX transaction failed to seek during CRC calculation |
| RxReadCrcFailed | warning low | RX transaction failed to read during CRC calculation |
| RxEofMdSizeMismatch | warning low | RX transaction EOF/metadata size mismatch |
| RxFileRenameFailed | warning low | RX transaction failed to rename temp file to final file |
| RxFileReopenFailed | warning low | RX transaction failed to reopen file after rename |
| RxInactivityTimeout | warning low | RX transaction inactivity timer expired |
| RxInvalidDirectiveCode | warning low | RX transaction received invalid directive code for substate |
| RxTransactionLimitReached | warning low | Dropping packet due to max RX transactions reached |
| Event Name | Severity | Description |
|---|---|---|
| TxAckLimitReached | warning low | TX transaction ACK limit reached, no eof-ack received |
| TxInactivityTimeout | warning low | TX transaction inactivity timer expired |
| TxZeroLengthFile | warning low | TX transaction cannot transfer zero-length file |
| TxFileOpenFailed | warning low | TX transaction failed to open file |
| TxFileSeekFailed | warning low | TX transaction failed to seek to beginning of file |
| TxSendMetadataFailed | warning low | TX transaction failed to send metadata PDU |
| TxEarlyFinReceived | warning low | TX transaction received early FIN, cancelling transfer |
| TxInvalidNakPdu | warning low | TX transaction received invalid NAK PDU |
| TxInvalidSegmentRequests | warning low | TX transaction received invalid NAK segment requests |
| TxNonFileDirectivePduReceived | warning low | TX transaction received non-file-directive PDU |
| TxInvalidDirectiveCode | warning low | TX transaction received invalid directive code for substate |
| TxLateFinAcked | diagnostic | Retransmitted FIN acknowledged statelessly for an already-completed/recycled TX transaction (source EID, transaction sequence number) |
| Event Name | Severity | Description |
|---|---|---|
| TxFileTransferStarted | activity high | TX starting file transfer: source file -> dest file |
| TxFileTransferCompleted | activity high | TX completed file transfer: source file -> dest file |
| TxFileTransferFailed | warning low | TX transaction FAILED: source file -> dest file, error code |
| RxFileTransferCompleted | activity high | RX completed file transfer: source file -> dest file |
| RxFileTransferFailed | warning low | RX transaction FAILED: source file -> dest file, error code |
| MetadataReceived | activity low | Metadata received for source and destination files |
| Event Name | Severity | Description |
|---|---|---|
| TransactionSuspended | activity low | Transaction suspended |
| TransactionResumed | activity low | Transaction resumed |
| TransactionCanceled | activity high | Transaction canceled |
| TransactionAbandoned | activity high | Transaction abandoned |
| TransactionNotFound | warning low | Transaction not found |
| Event Name | Severity | Description |
|---|---|---|
| BuffersExhausted | warning low | Unable to allocate a PDU buffer |
| FailKeepFileMove | warning low | Failed to move source file to move directory |
| FailPollFileMove | warning low | Failed to move source file to fail directory |
| FileDataSegmentMetadata | warning low | File data PDU with unsupported segment metadata received |
| ChunklistUnavailable | warning low | Cannot get chunklist, abandoning transaction |
| UnhandledPduInIdleState | warning low | Unhandled PDU type received in idle state |
| InvalidDestinationEid | warning low | Dropping packet for invalid destination entity ID |
| MaxTxTransactionsReached | warning low | Maximum number of commanded TX files reached |
| PlaybackDirOpenFailed | warning low | Failed to open playback directory |
| PlaybackDirSlotUnavailable | warning low | No playback directory slot available |
| DanglingFileHandleClosed | warning low | Closed dangling file handle for channel and transaction |
| PlaybackDirReadFailed | warning low | Failed to read from playback directory |
| ResetFreedTransaction | diagnostic | Attempt to reset a transaction that has already been freed |
| FileRemoveFailed | warning low | Failed to remove file |
| Name | Description |
|---|---|
| SendFile | Initiates a CFDP file transaction to send a file to a remote entity. Specifies channel, destination entity ID, CFDP class (1 or 2), file retention policy, priority, source filename, and destination filename. |
| PlaybackDirectory | Starts a directory playback operation to send all files from a source directory to a destination directory on a remote entity. Files are sent sequentially as individual CFDP transactions. Completes when all files in the directory have been processed. |
| PollDirectory | Establishes a recurring directory poll that periodically checks a source directory for new files and automatically sends them to a destination directory on a remote entity. Poll interval is configurable in seconds and must be non-zero (a zero interval is rejected with a VALIDATION_ERROR response and an InvalidPollInterval event). |
| StopPollDirectory | Stops an active directory poll operation identified by channel ID and poll ID. |
| SetChannelFlow | Sets the flow control state for a specific CFDP channel. Can freeze (pause) or resume PDU transmission on the channel. |
| SuspendResumeTransaction | Suspend or resume a transaction. When suspended, the transaction remains in memory but stops making progress (no PDUs sent or processed, no timers tick). Useful during critical spacecraft operations. Takes an action parameter (SUSPEND or RESUME). Transactions are identified by channel ID, transaction sequence number, and entity ID. |
| CancelTransaction | Gracefully cancel a transaction with protocol close-out. Sends FIN/ACK PDUs as appropriate for the transaction type and state. Transaction is removed from memory. Transactions are identified by channel ID, transaction sequence number, and entity ID. |
| AbandonTransaction | Immediately terminate a transaction without protocol close-out. No FIN/ACK sent. Transaction is immediately removed from memory. Used for stuck or unresponsive transactions. Transactions are identified by channel ID, transaction sequence number, and entity ID. |
| ResetCounters | Resets telemetry counters for the specified CFDP channel. Pass channelId 0xFF to reset all channels. |
| Name | Description |
|---|---|
| LocalEid | Local CFDP entity ID used in PDU headers to identify this node in the CFDP network |
| OutgoingFileChunkSize | Maximum number of bytes to include in each File Data PDU. Limits PDU size for transmission |
| RxCrcCalcBytesPerCycle | Maximum number of received file bytes to process for CRC calculation in a single scheduler cycle. Prevents blocking during large file verification |
| FileInDefaultChannel | CFDP channel ID used for file transfers initiated via the fileIn port interface (not commands) |
| FileInDefaultDestEntityId | Destination entity ID used for file transfers initiated via the fileIn port interface |
| FileInDefaultClass | CFDP class (CLASS_1 or CLASS_2) for file transfers initiated via the fileIn port interface |
| FileInDefaultKeep | File retention policy (KEEP or DELETE) for file transfers initiated via the fileIn port interface |
| FileInDefaultPriority | Priority (0-255, where 0 is highest) for file transfers initiated via the fileIn port interface |
| ChannelConfig.ack_limit | Maximum number of ACK retransmission attempts before abandoning a transaction. Applies when waiting for ACK(EOF) or ACK(FIN) acknowledgments |
| ChannelConfig.nack_limit | Maximum number of NAK retransmission attempts before abandoning a transaction. Applies when waiting for retransmitted file data after sending NAK |
| ChannelConfig.ack_timer | ACK timeout duration in seconds. Determines how long to wait for ACK(EOF) or ACK(FIN) before retransmitting |
| ChannelConfig.inactivity_timer | Inactivity timeout duration in seconds. Transaction is abandoned if no PDUs are received within this period |
| ChannelConfig.dequeue_enabled | Enable or disable transaction dequeuing and processing for this channel. Can be used to pause channel activity |
| ChannelConfig.move_dir | Directory path to move source files after successful TX (transmit) transactions when keep is set to DELETE. If set, provides an archive mechanism to preserve files instead of deleting them. If empty or if the move fails, source files are deleted from the filesystem. Only applies to sending files, not receiving |
| ChannelConfig.max_outgoing_pdus_per_cycle | Maximum number of outgoing PDUs to transmit per execution cycle. Throttles transmission rate to prevent overwhelming downstream components |
| ChannelConfig.tmp_dir | Directory path for storing temporary files during receive (RX) transactions. Files are written here during transfer and moved to their final destination upon successful completion |
| ChannelConfig.fail_dir | Directory path for storing files from polling operations that failed to transfer successfully. If empty or if the move fails, files are deleted from the filesystem |
The timer parameters (ack_timer, inactivity_timer, ack_limit, nack_limit) must be configured appropriately for the communication delay environment:
Critical Relationship: The ack_timer must be longer than the round-trip light time to avoid premature retransmissions. The inactivity_timer should be several times larger than ack_timer to account for file segmentation and processing delays.
CfdpManager's per-channel parameter architecture supports multiple mission profiles simultaneously. Different channels can be configured for near-Earth, lunar, and deep space operations, allowing the system to communicate with multiple destinations concurrently.
Telemetry is emitted as the ChannelTelemetry array, one ChannelTelemetry struct per CFDP channel. Each struct contains the following fields:
| Field | Type | Description |
|---|---|---|
| recvErrors | U32 | Number of PDU receive errors. Incremented when malformed or invalid PDUs are received |
| recvDropped | U32 | Number of PDUs dropped due to lack of resources (buffers, transactions) |
| recvSpurious | U32 | Number of spurious PDUs received (PDUs for nonexistent or completed transactions) |
| recvFileDataBytes | U64 | Total file data bytes received across all transactions |
| recvNakSegmentRequests | U32 | Number of NAK segment requests received from peer entity |
| recvPdu | U32 | Number of PDUs received with valid headers |
| recvEofCanceled | U32 | Number of EOF PDUs received with cancellation condition code |
| Field | Type | Description |
|---|---|---|
| sentNakSegmentRequests | U32 | Number of NAK segment requests sent to peer entity |
| sentFileDataBytes | U64 | Total file data bytes sent across all transactions |
| sentPdu | U32 | Number of PDUs sent with valid headers |
| sentEofCanceled | U32 | Number of EOF PDUs sent with cancellation condition code |
| Field | Type | Description |
|---|---|---|
| faultAckLimit | U32 | Number of transactions abandoned due to ACK limit exceeded (no ACK(EOF) or ACK(FIN) received) |
| faultNakLimit | U32 | Number of transactions abandoned due to NAK limit exceeded (retransmitted data not received) |
| faultInactivityTimer | U32 | Number of transactions abandoned due to inactivity timeout |
| faultCrcMismatch | U32 | Number of CRC mismatches detected in received files |
| faultFileSizeMismatch | U32 | Number of file size mismatches detected (EOF size vs actual received size) |
| faultFileOpen | U32 | Number of file open failures |
| faultFileRead | U32 | Number of file read failures |
| faultFileWrite | U32 | Number of file write failures |
| faultFileSeek | U32 | Number of file seek failures |
| faultFileRename | U32 | Number of file rename failures |
| faultDirectoryRead | U32 | Number of directory read failures during playback/poll operations |
| faultRxEofError | U32 | Number of EOF PDUs received with error condition code (other than cancel) |
| faultTxEofError | U32 | Number of EOF PDUs sent with error condition code (other than cancel) |
| Field | Type | Description |
|---|---|---|
| queueFree | U16 | Number of transactions in FREE queue (available for allocation) |
| queueTxActive | U16 | Number of transactions in active transmit queue (TXA) |
| queueTxWaiting | U16 | Number of transactions in waiting transmit queue (TXW) |
| queueRx | U16 | Number of transactions in receive queue (RX) |
| queueHistory | U16 | Number of completed transactions in history queue |
| Field | Type | Description |
|---|---|---|
| playbackCounter | U8 | Number of active directory playback operations |
| pollCounter | U8 | Number of active directory poll operations |
| Requirement | Description | Rationale | Verification Method |
|---|---|---|---|
| CFDP-001 | CfdpManager shall support CFDP Class 1 (unacknowledged) file transfers | Provides unreliable but low-overhead file transfer for non-critical data where speed is prioritized over guaranteed delivery | Unit Test, System Test |
| CFDP-002 | CfdpManager shall support CFDP Class 2 (acknowledged) file transfers with automatic retransmission | Ensures reliable file delivery with guaranteed completion even over lossy communication links | Unit Test, System Test |
| CFDP-003 | CfdpManager shall detect missing file segments using gap tracking and request retransmission via NAK PDUs | Provides the mechanism to recover from lost file data PDUs in Class 2 transfers | Unit Test |
| CFDP-004 | CfdpManager shall verify file integrity using CRC checksums and reject files with checksum mismatches | Ensures data corruption is detected and prevents accepting corrupted files | Unit Test |
| CFDP-005 | CfdpManager shall support multiple simultaneous file transfers across configurable channels | Allows concurrent file operations to maximize throughput and operational flexibility | Unit Test, System Test |
| CFDP-006 | CfdpManager shall support directory playback operations to transfer all files from a specified directory | Provides batch file transfer capability for operational efficiency | Unit Test |
| CFDP-007 | CfdpManager shall support directory polling operations to automatically detect and transfer new files at configurable intervals | Enables autonomous file downlink without ground intervention | Unit Test |
| CFDP-008 | CfdpManager shall enforce configurable ACK and NAK retry limits and abandon transactions that exceed these limits | Prevents infinite retry loops and ensures forward progress when peer becomes unresponsive | Unit Test |
| CFDP-009 | CfdpManager shall detect transaction inactivity using configurable timeout values and abandon inactive transactions | Reclaims resources from stalled transactions and prevents resource exhaustion | Unit Test |
| CFDP-010 | CfdpManager shall support configurable file archiving to move completed files instead of deletion | Preserves files for audit trails and operational analysis while managing storage | Unit Test |
| CFDP-011 | CfdpManager shall support both command-initiated and port-initiated file transfers | Allows both ground operators and onboard components to initiate file transfers | Unit Test, System Test |
| CFDP-012 | CfdpManager shall support flow control to freeze and resume channel operations | Provides mechanism to temporarily halt file transfers during critical spacecraft operations | Unit Test |
| CFDP-013 | CfdpManager shall process malformed or degenerate received PDUs, including zero-length FileData segments, without raising a FATAL assertion | Preserves deployment availability against untrusted link input and prevents a single crafted PDU from terminating the process (GHSA-mh5x-2m6h-8267) | Unit Test |