Repository navigation
CfdpManager: fail a downlink whose source file shrinks while it is sent - #6364
bitWarrior wants to merge 1 commit into
Conversation
sSubstateSendFileData asks sSendFileData for the bytes between m_foffs and the file size captured when the transfer started. If the source has been truncated below m_foffs, the read returns OP_OK with 0 bytes. The empty File Data PDU was still sent and reported as success with bytes_processed == 0, which fell into the empty else branch: m_foffs never advanced, the downlink never reached EOF, and every cycle sent max_outgoing_pdus_per_cycle empty File Data PDUs and blocked later downlinks on that channel. A Class 2 NAK retransmission over a truncated range stalled the same way, since the chunk was never removed. sSendFileData now treats a successful 0-byte read with bytes still expected as a file error: it emits the new TxFileShortRead event and returns ERROR without sending a PDU. The file data path then fails the transfer with TXN_STATUS_FILESTORE_REJECTION and sends EOF, and the NAK response path fails it with TXN_STATUS_NAK_RESPONSE_ERROR, as for other read errors. Add Class 1 and Class 2 unit tests that truncate the source mid-downlink. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Coverage report — base
|
| Module | Line | Δ | Function | Δ | Branch | Δ |
|---|---|---|---|---|---|---|
Os/Generic/Types |
91.79 | -0.35 | 92.86 | +0.00 | 73.83 | +0.00 |
Os/Posix |
71.03 | -0.25 | 87.50 | +0.00 | 50.89 | -0.45 |
Os/Generic |
90.18 | -0.10 | 89.13 | +0.00 | 75.48 | -0.19 |
Svc/Ccsds/CfdpManager |
90.87 | +0.07 | 96.89 | +0.00 | 78.28 | +0.18 |
Fw/DataStructures |
97.96 | +0.27 | 97.14 | +0.00 | 82.66 | +0.36 |
New modules
| Module | Line | Function | Branch |
|---|---|---|---|
Fw/Prm |
0.00 | 0.00 | 0.00 |
Modules without UTs
CFDP/Checksum/GTest, Drv/LinuxGpioDriver, Drv/LinuxI2cDriver, Drv/LinuxSpiDriver, Drv/Ports/DataTypes, Drv/PosixUartDriver, FppTestProject/FppTest/topology/async, FppTestProject/FppTest/topology/components/Comp, FppTestProject/FppTest/topology/components/Framework, FppTestProject/FppTest/topology/components/Receiver, FppTestProject/FppTest/topology/components/Sender, FppTestProject/FppTest/topology/guarded, FppTestProject/FppTest/topology/sync, FppTestProject/FppTest/topology/top_ports, FppTestProject/FppTest/topology/types, Fw/Com, Fw/Comp, Fw/FilePacket/GTest, Fw/Fpy, Fw/Obj, Fw/Port, Fw/Sm, Fw/Test, Fw/Types/GTest, Os/Models, Svc/Ccsds/Types, Svc/Ccsds/Utils, Svc/FatalHandler, Svc/Subtopologies/CdhCore, Svc/Subtopologies/ComCcsds, Svc/Subtopologies/ComCcsdsSdls, Svc/Subtopologies/ComFprime, Svc/Subtopologies/ComLoggerTee, Svc/Subtopologies/DataProducts, Svc/Subtopologies/DpCompression, Svc/Subtopologies/FileHandling, Svc/Subtopologies/FileHandlingCfdp, Svc/Subtopologies/FileHandlingCfdp/FileHandlingCfdpConfig, TestDeploymentsProject/Ref/DpDemo, TestDeploymentsProject/Ref/PingReceiver, TestDeploymentsProject/Ref/RecvBuffApp, TestDeploymentsProject/Ref/SendBuffApp, TestDeploymentsProject/Ref/Top, TestDeploymentsProject/Ref/TypeDemo, cmake/test/data/TestConfigDeployment, cmake/test/data/TestDeployment/TestBuildAutocoder, cmake/test/data/TestDeployment/TestDuplicateDirective, cmake/test/data/TestDeployment/TestHeaderAutocoder, cmake/test/data/TestDeployment/TestLinkDepends, cmake/test/data/TestDeployment/TestRelative, cmake/test/data/test-fprime-library/TestLibrary/TestComponent, cmake/test/data/test-fprime-library2/TestLibrary2/TestComponent
|
The one failing check here, Integration Tests (teensy41), is not caused by this change. The same job also fails on
It looks like a problem with the teensy41 board or runner (details in #6363 (comment)). |
Summary
If a file's size goes down while CfdpManager is downlinking it, the downlink never finishes.
sSubstateSendFileDataaskssSendFileDatafor the bytes betweenm_foffsand the file size captured when the transfer started. Once the source has been truncated belowm_foffs, the read returnsOP_OKwith 0 bytes. The empty File Data PDU was still sent and reported as success withbytes_processed == 0, which falls into the emptyelsebranch.m_foffsnever advances and the transaction never reaches EOF. Every cycle sendsmax_outgoing_pdus_per_cycleempty File Data PDUs and blocks later downlinks on that channel. A Class 2 NAK retransmission over a truncated range stalls the same way, because the chunk is never removed from the list.This can happen whenever anything onboard rewrites or truncates a file that is queued or being sent.
Changes
sSendFileDatatreats a successful 0-byte read while bytes are still expected as a file error. It emits the newTxFileShortReadevent and returnsERRORwithout sending a PDU. The existing error handling then ends the transfer:TXN_STATUS_FILESTORE_REJECTION, then EOF.TXN_STATUS_NAK_RESPONSE_ERROR.TxFileShortReadevent (warning low) with the file, the offset, and the starting size.Class1TxSourceTruncatedandClass2TxSourceTruncatedstart a 200 KB downlink, truncate the source after the first cycle, and run 10 more cycles. Each expects exactly oneTxFileShortRead, no completion event, and at most 4 PDUs sent after the truncation.TxFileTransferFailed.Testing
CfdpManager UTs: 219/219 pass. With the new check disabled, both new tests fail.
Notes
sTickNakthat hits a truncated range now sends nothing. The transaction then ends through its ACK-limit or inactivity timer instead of sending empty PDUs. Failing it immediately there would mean finishing a transaction while its queue is being traversed, so that part is left as is.🤖 Generated with Claude Code