Summary
During HIL investigation of a downlink-wedge bug in a downstream project (PROVES flight software, https://github.com/Open-Source-Space-Foundation/proves-core-reference, issues #457/#344), we found that once fileDownlink is wedged waiting for a buffer that will never be returned (in our case, from a downstream fan-out component that never drained one of its output channels), an explicit FileDownlink.Cancel command completes successfully (OpCodeCompleted) but does not actually unstick the component: subsequent SendFile commands continue to fail with EXECUTION_ERROR ("busy") exactly as before the cancel.
This suggests Cancel's effect depends on the same buffer-return callback that's already permanently blocked, rather than being able to force a clean reset of the transfer state independent of that callback.
Impact
Any wedge of this general shape (a buffer never returned to FileDownlink for whatever reason -- misbehaving downstream component, hardware fault, etc.) becomes unrecoverable without a full process/board reset, which is a poor failure mode for a flight system. Cancel should be a reliable escape hatch regardless of what's holding up the outstanding buffer.
Suggested fix direction
Cancel (and/or a timeout path) should force the component back to idle/ready state independent of whether the outstanding buffer ever comes back, freeing it up (even if that specific buffer is now leaked/orphaned from the buffer manager's perspective) rather than waiting on a callback that may never fire.
Reproduction context
Downstream project used a custom BufferRepeater fan-out component between FileDownlink and two communication channels (UART + LoRa); when the LoRa channel's outbound queue never drained (LoRa TX disabled), the repeater never returned the buffer to FileDownlink, wedging it. Cancel was sent and observed to complete but not restore SendFile functionality. Happy to provide more detail/logs if useful, though the core issue (an unrecoverable wedge if a buffer is never returned, Cancel notwithstanding) appears to be inherent to Svc::FileDownlink's state machine rather than specific to our fan-out component.
🤖 Generated with Claude Code
https://claude.ai/code/session_01WpBURCutAx8281i59nj6fo
Summary
During HIL investigation of a downlink-wedge bug in a downstream project (PROVES flight software, https://github.com/Open-Source-Space-Foundation/proves-core-reference, issues #457/#344), we found that once
fileDownlinkis wedged waiting for a buffer that will never be returned (in our case, from a downstream fan-out component that never drained one of its output channels), an explicitFileDownlink.Cancelcommand completes successfully (OpCodeCompleted) but does not actually unstick the component: subsequentSendFilecommands continue to fail withEXECUTION_ERROR("busy") exactly as before the cancel.This suggests
Cancel's effect depends on the same buffer-return callback that's already permanently blocked, rather than being able to force a clean reset of the transfer state independent of that callback.Impact
Any wedge of this general shape (a buffer never returned to
FileDownlinkfor whatever reason -- misbehaving downstream component, hardware fault, etc.) becomes unrecoverable without a full process/board reset, which is a poor failure mode for a flight system.Cancelshould be a reliable escape hatch regardless of what's holding up the outstanding buffer.Suggested fix direction
Cancel(and/or a timeout path) should force the component back to idle/ready state independent of whether the outstanding buffer ever comes back, freeing it up (even if that specific buffer is now leaked/orphaned from the buffer manager's perspective) rather than waiting on a callback that may never fire.Reproduction context
Downstream project used a custom
BufferRepeaterfan-out component betweenFileDownlinkand two communication channels (UART + LoRa); when the LoRa channel's outbound queue never drained (LoRa TX disabled), the repeater never returned the buffer toFileDownlink, wedging it.Cancelwas sent and observed to complete but not restoreSendFilefunctionality. Happy to provide more detail/logs if useful, though the core issue (an unrecoverable wedge if a buffer is never returned,Cancelnotwithstanding) appears to be inherent toSvc::FileDownlink's state machine rather than specific to our fan-out component.🤖 Generated with Claude Code
https://claude.ai/code/session_01WpBURCutAx8281i59nj6fo