Ccsds::CfdpManager
CFDP Introduction
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: - Spacecraft-to-ground file transfers: Downlinking F' event logs, telemetry data files, science data products, and diagnostic files - Ground-to-spacecraft file transfers: Uplinking F' flight software updates, parameter files, and command sequences - Delay-tolerant and disruption-tolerant delivery: Automatic retry and recovery mechanisms for challenging communication links
The protocol supports two operational modes: - Class 1 (Unacknowledged): Unreliable transfer with no acknowledgments, suitable for real-time or non-critical data where speed is prioritized - Class 2 (Acknowledged): Reliable transfer with acknowledgments, retransmissions, and gap detection, ensuring complete and verified file delivery
Protocol Data Units (PDUs)
CFDP uses Protocol Data Units (PDUs) - structured messages with a common header and type-specific payloads:
- Metadata: Initiates transfer with filenames, file size, and options
- File Data: Carries file content segments with offset information
- EOF: Signals completion of file transmission with checksum
- FIN: Reports final delivery status (Class 2 only)
- ACK: Confirms receipt of EOF or FIN (Class 2 only)
- NAK: Requests retransmission of missing segments (Class 2 only)
For complete protocol details, refer to the CCSDS 727.0-B-5 - CCSDS File Delivery Protocol (CFDP) Blue Book specification.
CFDP as an F' Component
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: - Core CFDP engine and transaction management logic - Protocol state machines for transmit and receive operations - Utility functions for file handling and resource management - Chunk and gap tracking for Class 2 transfers
The F' implementation adds new components built specifically for the F' ecosystem:
- CfdpManager component wrapper: Integrates CFDP into F' architecture with standard port interfaces, commands, events, telemetry, and parameters
- Object-oriented PDU encoding/decoding: Type-safe PDU classes based on F' Serializable interface for consistent serialization
- F' timer implementation: Uses F' time primitives for protocol timers
For detailed attribution, licensing information, and a breakdown of ported vs. new code, see ATTRIBUTION.md.
Class Diagram
The CfdpManager component diagram shows the port organization by functional grouping:

Ports are organized as follows:
- Top (System Ports): Scheduling and system health - run1Hz, pingIn, pingOut
- Left (Uplink Ports): Receive CFDP PDUs from remote entities - dataIn, dataInReturn
- Right (Downlink Ports): Send CFDP PDUs to remote entities - dataOut, dataReturnIn, bufferAllocate, bufferDeallocate
- Bottom (File Transfer Ports): Port-based file send interface - fileIn, fileDoneOut
Port Descriptions
System Ports
| 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 |
Downlink Ports
| 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. |
Uplink Ports
| 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. |
File Transfer Ports
| 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). |
Usage Examples
The following diagram shows typical CfdpManager port connections with other F' components:

This example demonstrates:
- Uplink data flow: FprimeRouter deframes incoming CFDP PDUs and sends them to CfdpManager via dataIn
- Downlink data flow: CfdpManager sends outgoing CFDP PDUs to ComQueue via dataOut for transmission
- Port-based file transfers: DpCatalog initiates file transfers via CfdpManager's fileIn port and receives completion notifications via fileDoneOut
Component Design
Assumptions
The 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
bufferAllocateport for transmission and received via thedataInport 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
run1Hzport 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_dirper-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, andFileInDefaultPriority).
Security Considerations
CfdpManager follows a layered security architecture where authentication and authorization are enforced at lower network protocol layers rather than at the application layer:
- Physical/Network Layer Security: Hardware encryption at the radio level, or network-layer protocols like Bundle Protocol Security or IPsec
- Application Layer: CfdpManager assumes CFDP traffic originates from authenticated sources validated at lower layers
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.
Main Class Hierarchy
CfdpManager (CfdpManager.hpp) - Top-level F' component that integrates CFDP into the F' framework - Provides F' port handlers for commands, data input/output, and periodic execution - Owns a single Engine instance and delegates all protocol operations to it - Manages component parameters and provides events/telemetry to the F' system
Engine (Engine.hpp) - Core protocol engine that manages CFDP lifecycle and operations - Owns multiple Channel instances (one per configured CFDP channel) - Handles PDU routing and dispatching to appropriate transactions - Manages transaction creation, initialization, and cleanup - Implements top-level protocol state machine coordination
Channel (Channel.hpp) - Encapsulates channel-specific operations and configuration - Owns a pool of Transaction instances for that channel - Manages playback directories and polling directories - Handles transaction queuing with priority-based scheduling - Controls flow state (normal/frozen) and PDU throttling
Transaction (Transaction.hpp) - Represents individual file transfer operations - Implements both TX (transmit) and RX (receive) state machines - Handles Class 1 (unacknowledged) and Class 2 (acknowledged) protocol states - Implementation split across TransactionTx.cpp and TransactionRx.cpp - Manages file I/O, checksums, timers, and retry logic for each transaction
PDU Type Hierarchy
PduBase (Types/PduBase.hpp)
- Abstract base class for all CFDP Protocol Data Units
- Inherits from F' Fw::Serializable for consistent encoding/decoding
- Contains common PduHeader with transaction identification
Concrete PDU types (all in Types/ directory): - MetadataPdu (MetadataPdu.hpp): Initiates file transfer with filename, size, and options - FileDataPdu (FileDataPdu.hpp): Carries file data segments with offset information - EofPdu (EofPdu.hpp): Signals end of file transmission with checksum and final size - FinPdu (FinPdu.hpp): Indicates transaction completion with delivery status (Class 2 only) - AckPdu (AckPdu.hpp): Acknowledges receipt of EOF or FIN directives (Class 2 only) - NakPdu (NakPdu.hpp): Requests retransmission of missing file segments (Class 2 only)
Supporting Types and Utilities
Classes: - Timer (Timer.hpp): CFDP timer implementation using F' time primitives for ACK timeouts and inactivity detection - CfdpChunkList (Chunk.hpp): Gap tracking for Class 2 transfers; tracks received file segments and identifies missing data for NAK generation - Clist (Clist.hpp): Intrusive circular linked list for efficient transaction queue management
Structs (defined in Types.hpp): - History: Transaction history records for completed transfers; stores filenames, direction, status, and entity IDs - Playback: Playback request state for directory playback and polling operations; manages directory iteration and transaction parameters - CfdpChunkWrapper: Wrapper around CfdpChunkList for pooling and reuse across transactions
Utilities: - Utils (Utils.hpp): Utility functions for transaction traversal, status conversion, and protocol helpers
Transmission and Receive Throttling
Transmission Throttling
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.
Receive Throttling
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.
Sequence Diagrams
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.
Class 1 TX Transaction (Unacknowledged)
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<br/>(source file, destination file)
Note over Spacecraft: Initialize transaction
Spacecraft->>Ground: Metadata PDU<br/>(filename, size)
loop File Data Transfer
Spacecraft->>Ground: File Data PDU<br/>(offset, data segment)
end
Spacecraft->>Ground: EOF PDU<br/>(checksum, file size)
Note over Spacecraft: Transaction complete<br/>(no acknowledgment)
Note over Ground: Verify checksum<br/>Keep or discard file
Key characteristics: - No acknowledgments (ACK, NAK, or FIN PDUs) - No retransmissions or gap detection - Sender completes immediately after sending EOF - Receiver validates checksum and keeps/discards file independently
Class 2 TX Transaction (Acknowledged)
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<br/>ACK Timer
participant G_NACK as Ground<br/>NACK Timer
participant Ground
participant Spacecraft
participant S_ACK as Spacecraft<br/>ACK Timer
Ground->>Spacecraft: SendFile command<br/>(source file, destination file)
Note over Spacecraft: Initialize transaction
Spacecraft->>Ground: Metadata PDU<br/>(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<br/>(checksum, file size)
activate S_ACK
Note over S_ACK: Armed on<br/>EOF send
Ground->>Spacecraft: ACK(EOF)
deactivate S_ACK
Note over S_ACK: Cancelled on<br/>ACK(EOF) received
Note over Ground: Gap detected<br/>(missing PDU (2))
Ground->>Spacecraft: NAK<br/>(request PDU (2))
activate G_NACK
Note over G_NACK: Armed on<br/>NAK send
Spacecraft->>Ground: File Data PDU (2) [RETRANSMIT]
deactivate G_NACK
Note over G_NACK: Cancelled on<br/>gap fill
Note over Ground: All data received<br/>Verify checksum
Ground->>Spacecraft: FIN PDU<br/>(delivery complete, file retained)
Note over Ground: File saved and<br>ready for use
activate G_ACK
Note over G_ACK: Armed on<br/>FIN send
Spacecraft->>Ground: ACK(FIN)
Note over Spacecraft: Transaction complete
deactivate G_ACK
Note over G_ACK: Cancelled on<br/>ACK(FIN) received
Note over Ground: Transaction complete
Key characteristics:
- Full acknowledgment and retransmission support
- EOF is acknowledged to confirm reception
- Ground detects missing data and sends NAK with gap information
- Spacecraft retransmits requested segments
- NAK processing during file data transmission:
- NAKs received during file data transmission (before EOF is sent) are processed immediately
- Requested gap segments are queued and retransmitted with priority over new file data
- This allows gaps to be filled immediately upon detection, rather than waiting for EOF acknowledgment
- FIN PDU from receiver confirms final delivery status
- Timers ensure protocol progress and detect failures
- Spacecraft ACK timer: Armed when EOF is sent with duration 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_EOF
- Transaction completes only after FIN/ACK exchange
Class 2 RX Transaction (Acknowledged)
This 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<br/>ACK Timer
participant Ground
participant Spacecraft
participant S_NAK as Spacecraft<br/>NAK Timer
participant S_ACK as Spacecraft<br/>ACK Timer
Note over Ground: Initialize transaction
Ground->>Spacecraft: Metadata PDU<br/>(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<br/>(checksum, file size)
activate G_ACK
Note over G_ACK: Armed on<br/>EOF send
Spacecraft->>Ground: ACK(EOF)
deactivate G_ACK
Note over G_ACK: Cancelled on<br/>ACK(EOF) received
Note over Spacecraft: Gaps detected<br/>(missing PDUs (1) and (3))
Spacecraft->>Ground: NAK<br/>(request PDUs (1) and (3))
activate S_NAK
Note over S_NAK: Armed on<br/>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<br/>gaps filled
Note over Spacecraft: All data received<br/>Verify checksum
Spacecraft->>Ground: FIN PDU<br/>(delivery complete, file retained)
Note over Spacecraft: File saved and<br>ready for use
activate S_ACK
Note over S_ACK: Armed on<br/>FIN send
Ground->>Spacecraft: ACK(FIN)
Note over Ground: Transaction complete
deactivate S_ACK
Note over S_ACK: Cancelled on<br/>ACK(FIN) received
Note over Spacecraft: Transaction complete
Key characteristics:
- Full acknowledgment and retransmission support
- EOF is acknowledged to confirm reception
- Spacecraft detects missing data and sends NAK with gap information
- Ground retransmits requested segments
- FIN PDU from receiver confirms final delivery status
- Timers ensure protocol progress and detect failures
- Spacecraft NAK timer: Armed when NAK is sent with duration 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_REACHED
- Spacecraft ACK timer: Armed when FIN is sent with duration ChannelConfig.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 abandoned
- Transaction completes only after FIN/ACK exchange
Configuration
CfdpManager uses compile-time configuration defined in two files:
- CfdpCfg.fpp: FPP constants and types visible to both FPP and C++ code
- CfdpCfg.hpp: C++ preprocessor definitions for implementation details
FPP Constants (CfdpCfg.fpp)
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. |
FPP Types (CfdpCfg.fpp)
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. |
C++ Configuration Constants (CfdpCfg.hpp)
Protocol Configuration
| 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. |
Resource Pool Configuration
| 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. |
Events
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.
Command/Control Events
| 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 |
| 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 |
| SetFlowState | activity low | Set channel to specified flow state |
| ResetCounters | activity high | Reset telemetry counters for channel (0xFF indicates all channels) |
PDU Serialization/Deserialization Errors
| 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 |
RX Transaction Events
| 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 |
TX Transaction Events
| 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) |
File Transfer Complete Events
| 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 |
Transaction Control Events
| 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 |
Miscellaneous/Diagnostic Events
| 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 |
Commands
| 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. |
| 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. |
Parameters
| 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 |
Deep Space Timer Configuration
The timer parameters (ack_timer, inactivity_timer, ack_limit, nack_limit) must be configured appropriately for the communication delay environment:
- Near-Earth Operations: Default values (ack_timer=3s, inactivity_timer=30s) are appropriate for round-trip light times of 1-2 seconds
- Lunar Operations: Modest increases recommended (ack_timer=5-10s, inactivity_timer=60-120s) for ~2.5 second round-trip light times
- Deep Space Operations: Significant increases required (ack_timer and inactivity_timer scaled to mission-specific round-trip light times, which can range from minutes to hours)
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
Telemetry is emitted as the ChannelTelemetry array, one ChannelTelemetry struct per CFDP channel. Each struct contains the following fields:
Receive Counters
| 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 |
Sent Counters
| 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 |
Fault Counters
| 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) |
Queue Depths
| 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 |
Activity Counters
| Field | Type | Description |
|---|---|---|
| playbackCounter | U8 | Number of active directory playback operations |
| pollCounter | U8 | Number of active directory poll operations |
Requirements
| 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 |