Skip to content

CCSDS File Delivery Protocol - CfdpManager#5138

Open
Brian-Campuzano wants to merge 245 commits into
nasa:develfrom
FireflySpace:cfdp-merge
Open

CCSDS File Delivery Protocol - CfdpManager#5138
Brian-Campuzano wants to merge 245 commits into
nasa:develfrom
FireflySpace:cfdp-merge

Conversation

@Brian-Campuzano

Copy link
Copy Markdown
Collaborator
Related Issue(s) #2768
Has Unit Tests (y/n) y
Documentation Included (y/n) y
Generative AI was used in this contribution (y/n) y

Change Description

This PR adds the CfdpManager component, an F´ implementation of the CCSDS File Delivery Protocol (CFDP) standard ported from NASA's Core Flight System (cFS) CFDP Application v3.0.0. CfdpManager provides both Class 1 (unacknowledged) and Class 2 (acknowledged) file transfer capabilities, designed to replace the standard FileUplink and FileDownlink components with guaranteed file delivery support.

Attribution and License:

  • Substantial portions ported from: NASA Core Flight System (cFS) CFDP (CF) Application v3.0.0
  • Original License: Apache License 2.0
  • Original Copyright: Copyright (c) 2019 United States Government as represented by the Administrator of the National Aeronautics and Space Administration
  • NASA Docket: GSC-18,447-1

Ported components (retain original NASA copyright):

  • Core CFDP engine and transaction management logic (Engine.cpp, Transaction.hpp, TransactionTx.cpp, TransactionRx.cpp)
  • Protocol state machines for transmit and receive operations
  • Utility functions for file handling and resource management (Utils.cpp, Channel.cpp)
  • Chunk and gap tracking for Class 2 transfers (Chunk.cpp, Clist.cpp)

New F´-specific implementations:

  • CfdpManager component wrapper with F´ ports, commands, events, telemetry, and parameters
  • Object-oriented PDU encoding/decoding classes based on F´ Serializable interface
  • Timer implementation using F´ time primitives
  • FileHandlingCfdp subtopology for integration

See ATTRIBUTION.md for complete file-by-file attribution breakdown.

Summary of changes:

  • Full PDU support: Metadata, FileData, EOF, FIN, ACK, NAK
  • Multi-channel support with configurable throttling and timer parameters
  • Port-based file transfer interface compatible with existing F´ components (e.g., DpCatalog)
  • Comprehensive unit tests covering Class 1/2 transactions, PDU handling, and edge cases
  • Complete SDD documentation with architecture diagrams, sequence diagrams, and usage examples

Rationale

Current F´ file transfer components (FileUplink/FileDownlink) lack reliable delivery guarantees over lossy or intermittent links, automatic retransmission and gap detection, and industry-standard CFDP protocol compliance required for interoperability with ground systems and other spacecraft.

CfdpManager addresses these gaps by implementing the CCSDS CFDP standard, which is specifically designed for space missions with long propagation delays, high error rates, and disruption-tolerant requirements. By porting NASA's proven CF application from cFS, this implementation leverages flight-proven CFDP logic while adapting it to F´'s architecture and component model.

Testing/Review Recommendations

Unit Test Coverage:

  • CfdpManagerTester.cpp: Component-level tests with Class 1/2 TX/RX transactions, NAK handling, timer expiration, and throttling
  • PduTester.cpp: PDU serialization/deserialization tests for all PDU types

Areas to focus on:

  1. Port connections & buffer management: Verify buffer allocation/deallocation patterns in uplink/downlink paths (particularly dataOut/dataReturnIn and bufferAllocate/bufferDeallocate)
  2. Timer logic: Review 1Hz scheduler integration and protocol timer handling (inactivity, ACK, NAK timers)
  3. Multi-channel support: Validate channel isolation and resource limits (transactions per channel)
  4. Configuration parameters: Review default values in CfdpCfg.hpp and CfdpCfg.fpp
  5. File I/O error handling: Verify proper cleanup on file open/read/write failures
  6. CF→F´ port quality: Review adaptations from cFS to F´ (e.g., replacing CFE OS calls with F´ Os abstraction)
  7. Documentation accuracy: Cross-check SDD against implementation

Future Work

  • Add support for offset/partial file transfers in fileIn port
  • Implement additional TLV (Type-Length-Value) options (e.g., flow label, fault handler overrides)
  • Add command-line parameter validation for remote entity IDs
  • Consider performance optimizations for high-throughput scenarios
  • Add integration tests with ComQueue and deframing components

AI Usage (see policy)

Generative AI (Claude Code) was used for:

  • Code generation: Assisted with boilerplate for PDU class implementations, unit test scaffolding, and F´ component port wiring
  • Documentation: Assisted with drafting and formatting the SDD markdown (including sequence diagrams and tables) and generating this PR description
  • Refactoring: Suggested improvements during CF→F´ port (e.g., replacing void* with typed pointers, modernizing C→C++ patterns)
  • Debugging: Assisted in diagnosing unit test failures and identifying edge cases in transaction state machines

Important note: AI was NOT used to generate the core CFDP protocol logic. The core engine, transaction state machines, and protocol logic were ported directly from NASA's CF application v3.0.0 (human-written, flight-proven code). AI assistance was limited to F´-specific integration code, documentation, and port quality improvements.

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

Comment thread Svc/Ccsds/CfdpManager/Channel.cpp Fixed
Comment thread Svc/Ccsds/CfdpManager/Channel.hpp Fixed
Comment thread Svc/Ccsds/CfdpManager/Clist.cpp Fixed
Comment thread Svc/Ccsds/CfdpManager/Clist.cpp Fixed
Comment thread Svc/Ccsds/CfdpManager/Clist.cpp Fixed
Comment thread Svc/Ccsds/CfdpManager/Types/PduBase.hpp Fixed
Comment thread Svc/Ccsds/CfdpManager/Types/PduBase.hpp Fixed
Comment thread Svc/Ccsds/CfdpManager/Types/test/ut/PduTests.cpp Fixed
Comment thread Svc/Ccsds/CfdpManager/Utils.cpp Fixed
Comment thread default/config/CfdpCfg.hpp Fixed

@thomas-bc thomas-bc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few AI finds that seemed relevant, and one big question about how to handle file paths.

Comment thread Svc/Ccsds/CfdpManager/Engine.cpp Outdated
Comment thread Svc/Ccsds/CfdpManager/Types/PduHeader.cpp Outdated

/* store the filenames in transaction - validation already done during deserialization */
txn->m_history->fnames.src_filename = md.getSourceFilename();
txn->m_history->fnames.dst_filename = md.getDestFilename();

@thomas-bc thomas-bc May 12, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One security issue that we've had reported a lot on the F Prime Svc.FileUplink component is that it allows to write files at any location on the filesystem, potentially overwriting critical system files etc.
This is risky for in case of operator oversight (shrug) but also if you receive unauthenticated (potentially malicious) commands.
My understanding is this CfdpManager has the same capability.

Did you find that CFDP makes recommendation on how to deal with that? If not, we should agree on a rationale so that we stop the spam of "hey you have a critical vulnerability here". Maybe the answer is "encrypt/authenticate your comms". But we should agree on something.

cc @bitWarrior , if you have recommendations.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CfdpManager was patterned using the same security model as FileUplink/FileDownlink. Authentication is expected to happen at the physical or network layers, not in the application itself. In out use-cases, CFDP traffic is being sent over authenticated channels such as encrypted radios or Bundle Protocol Security, so CfdpManager assumes the source is already trusted. That matches the assumptions generally made by the CCSDS 727.0-B-5 CFDP standard.

I understand the defense-in-depth argument for adding application-layer path validation. The tradeoff is additional configuration complexity and possible conflicts with legitimate use cases like firmware updates or system file management. It also does not solve the underlying problem if the CFDP traffic itself is unauthenticated.

I added a “Security Considerations” section to the SDD to document the design rationale more clearly.

If there is interest in revisiting the design or discussing path validation for F´ components more broadly, I’d be happy to join that discussion.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with everything you've said. I think this is the correct long-term approach. Leaving this thread open for awareness.

@lestarch-autobot lestarch-autobot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review summary (run 1)

Per-agent results

Agent must fix suggestion could fix future work outstanding Verdict
Security Vulnerabilities 2 2 1 0 5 No-Go
Supply Chain / Runner Safety 0 0 0 0 0 Go
F Prime C/C++ Design 7 6 1 0 14 No-Go
Documentation Currency 1 1 2 0 4 No-Go
Design 2 0 0 0 2 No-Go
Test Quality 5 1 1 0 7 No-Go
CI safety Go
Totals 17 10 5 0 32 No-Go
Supply-chain surfaces
Surface Outstanding
Dependencies clean
Vendored / submodule clean
Build / test infrastructure clean
Workflows / actions / scripts clean
Generator output clean
Prompt-injection clean
Review-system integrity clean
Outstanding must-fix items (17)

Security Vulnerabilities

  • Inverted condition in stopPollDir prevents stopping active poll directories — comment
  • No path traversal validation on filenames received from remote CFDP entity — comment

F Prime C/C++ Design

  • CPP-25/STL: std::function banned in F Prime (Chunk.hpp) — comment
  • CPP-25/STL: std::function banned in F Prime (Clist.hpp) — comment
  • CPP-25/STL: std::function banned in F Prime (Types.hpp) — comment
  • CPP-1: Dynamic new allocation in Engine::init()comment
  • CPP-1: Multiple bare operator new/new[] in Channel constructor — comment
  • CPP-7: Lambda forbidden in F Prime (Channel.cpp) — comment
  • CPP-7: Lambda with capture forbidden (TransactionRx.cpp) — comment

Documentation Currency

  • Missing Events section in SDD — 72 ground-facing events undocumented — comment

Design

  • Human design adjudication required. 73-file new component requires design-owner sign-off — comment
  • FPP–C++ divergence: Telemetry.fppi claims "not yet implemented" but telemetry IS implemented — comment

Test Quality

  • ~8 of 9 new async commands have no sendCmd_*/ASSERT_CMD_RESPONSE coverage — comment
  • ~53 of 55 new events have no ASSERT_EVENTS_* coverage — comment
  • None of 10 new parameters have paramSet_*/paramGet_* coverage — comment
  • dataReturnIn async port has no test invocation — comment
  • SendFile command lacks failure-path coverage — comment

Merge readiness

Merge readiness: No-Go — 5 of 6 reviewers report outstanding must-fix findings (security-review, fprime-code-review, stale-documentation-review, design-review, test-quality-review).

Agents that did not run on this PR

All 6 registered reviewers ran successfully.


Safe satisfying flights begin with thorough reviews — the crew is counting on us. 🚀

Brian-Campuzano and others added 29 commits June 5, 2026 10:27
Add comprehensive SDD for the FileHandlingCfdp subtopology following
the same structure and pattern as the existing FileHandling subtopology
documentation.

The SDD documents:
- Requirements for CFDP file transfer, file management, and parameter management
- Component instances (CfdpManager, FileManager, PrmDb) and their purposes
- Configuration hooks and required connections (rate groups, communication stack)
- Key differences from the FileHandling subtopology (CFDP vs legacy file transfer)
- Example topology integration with CFDP PDU wiring
- Compile-time and runtime CFDP configuration parameters
- Limitations and architectural boundaries

This documentation provides integration engineers with a complete
reference for using the FileHandlingCfdp subtopology in F' CCSDS
deployments with reliable CFDP-based file delivery.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Address three review comments on PR nasa#5138:

1. Add comprehensive Events section documenting all 72 events
   - Organize events into 7 logical categories: Command/Control, PDU
     Serialization errors, RX/TX Transaction events, Transfer Complete,
     Transaction Control, and Miscellaneous/Diagnostic
   - Include event name, severity, and description for each
   - Provide context for ground operators to understand event semantics

2. Add missing ResetCounters command to Commands table
   - Documents the ability to reset telemetry counters per channel
   - Notes that channelId 0xFF resets all channels

3. Add missing telemetry fields to Telemetry section
   - Add recvPdu to Receive Counters table
   - Add sentFileDataBytes and sentPdu to Sent Counters table
   - Ensures SDD matches ChannelTelemetry struct in Types.fpp

Also remove "PROPOSALS" comment from Telemetry.fppi as the telemetry
is now implemented and active in the component.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…emAllocator usage. Needed a new cleanup to avoid duplicate allocator storage
Address CPP-6 and CPP-10 coding standard violations identified in PR review.

Changes:
- Replace all NULL with nullptr throughout codebase (CPP-6 requirement)
- Add justification comments for all const_cast<U8*> usages (CPP-10):
  "Fw::SerialBuffer requires non-const U8* even for deserialization"
- Add justification comment for reinterpret_cast in container_of_cpp (CPP-10):
  "Required for intrusive list node-to-parent pointer arithmetic"

All unit tests pass.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…, CPP-8)

Convert all unscoped enums in CfdpManager to enum class for type safety per F' CPP-26 coding standard:
- FileDirective, ConditionCode, AckTxnStatus, FinDeliveryCode, FinFileStatus, ChecksumType
- TxnState, TxSubState, RxSubState, Direction, TransactionInitType, CfdpTickType, TxnStatus
- PduType, PduDirection, CrcFlag, LargeFileFlag, TlvType

Replace #define CFDP_NUM_TRANSACTIONS_PER_CHANNEL with static constexpr per F' CPP-8 standard.

All enum references updated with qualified names and static_cast where needed for:
- Comparisons with U8/U32 types
- Array subscripts
- Bitwise operations
- FW_ASSERT calls requiring integer types

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Update test code to use qualified enum class names and cast comparisons.
Unit tests still have compilation errors but production code builds successfully.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed all remaining unit test compilation errors after enum class conversion:

1. Removed invalid static_cast<U8> from enum class parameters in initialize() calls
   - FinPdu::initialize() now takes FinDeliveryCode and FinFileStatus directly
   - Array initializations now use enum class types without casts

2. Fixed misplaced closing parentheses in function calls
   - Changed `func(..., arg),` → `func(..., arg,`
   - Changed `func(...))` → `func(...)`

3. Corrected EXPECT_EQ comparisons to compare enum-to-enum
   - Removed unnecessary static_cast<U8>() from getter results
   - Direct enum comparisons: `EXPECT_EQ(EnumClass::VALUE, obj.getEnum())`

4. Added missing enum qualifiers for TLV types
   - TLV_TYPE_MESSAGE_TO_USER → TlvType::TLV_TYPE_MESSAGE_TO_USER
   - TLV_TYPE_FLOW_LABEL → TlvType::TLV_TYPE_FLOW_LABEL

All unit tests now pass:
- CfdpManager main tests: 15/15 passed
- Types PDU tests: all passed

Production code and all unit tests build successfully.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replaced FW_ASSERT with graceful error handling when attempting to
transfer zero-length files. This prevents a DoS vulnerability where an
operator command could crash the component.

Changes:
- TransactionTx.cpp: Replace assert with error event and fault counter
- Events.fppi: Add TxZeroLengthFile warning event
- Add command unit tests verifying both bug fixes:
  * testSendFileZeroLength: Verifies zero-length file handling (no crash)
  * testSendFileNonExistent: Verifies file open error handling
  * testStopPollDirActive: Verifies stopPollDir fix (inverted condition)
  * testStopPollDirNotActive: Verifies inactive directory handling

All tests use ASSERT_EVENTS macros and Os::FileSystem operations.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added defensive check to prevent unsigned integer underflow when
pduDataLength < offsetSize. While the subsequent validation at line 148
already catches malformed PDUs, the intermediate underflow state is
fragile and could introduce vulnerabilities in future code changes.

The fix validates pduDataLength against offsetSize before performing
the subtraction, returning FW_DESERIALIZE_SIZE_MISMATCH for invalid PDUs.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replaced FW_ASSERT calls on sendAck/sendFin return values with proper
error handling. The asserts could fire if PDU serialization fails due
to hardware fault or unexpected internal state.

Changes:
- TransactionRx.cpp: Replace asserts with graceful handling of ERROR status
- When sendAck returns ERROR: clear retry flag to avoid infinite loop
- When sendFin returns ERROR: continue state transition (already logged)
- Serialization errors are already logged by FailPduSerialization event

This prevents component crashes from serialization failures while
maintaining proper error reporting.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…n tests

Changes:
- Added expectExactCounts parameter to sendAndVerifyClass2Tx helper
- Single-transaction tests (testClass2TxNominal, testClass2TxPortBased) now use EXPECT_EQ for exact telemetry counts
- Multi-transaction tests and NAK tests continue to use EXPECT_GE for lower bounds
- Previously used EXPECT_GE(tlm[...].get_recvPdu(), 3u) which would pass even if count was wrong
- With EXPECT_EQ, single-transaction tests will catch regressions that inflate or miscount PDUs

Rationale:
- In isolated single-transaction tests with fresh tester instance, exact counts are known
- EXPECT_EQ catches regressions; EXPECT_GE only validates lower bound
- Distinguishes between tests where exact counts are expected vs cumulative/NAK scenarios

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Better events description

Include sent bytes (not total) in EOF after cancel

Log non-cero EOF condition codes

Fix bug deserializing variable-lenght entity ID

Properly read condition code bits

Only check file size and CRC for non-error EOF

Set txn status on EOF error to prevent completion event

Add telemetry for canceled transactions

For canceled transactions, don't wait for FIN
...fixes issues with CRC errors when uplinking many
times consecutively with packet loss
...to support transfers over links with higher packet drop rates.
Fix Cancel Transaction issues, update events and recycle transaction updates
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants