Commit Graph
6431 Commits
Author SHA1 Message Date
Tobias BaumgartlandClaude Opus 5 6faea2b0f0 cfdp: report a metadata only transaction as a complete delivery
A metadata only transaction - a proxy put request, for instance - carries no
file data and completes the moment its metadata arrives. handleTransferCompletion
took the branch for a null checksum, which sets the condition code and touches
neither delivery field, so both were reported at their reset defaults: a
transaction that succeeded announced itself as

  Finish Condition: No Error (0)
  File delivery code: Data Incomplete (1)
  File delivery status: Discard deliberately (0)

which contradicts itself, and goes out in the Finished PDU to the sender, not
only into the OBSW log. It was noticed on the flatsat, where every CFDP
downlink begins with exactly this kind of transaction carrying the proxy put
request, and each one reported a failed delivery on the console.

Nothing was expected of it and nothing is missing, so the delivery code is
DATA_COMPLETE; there is no file whose status could be reported, so the status
is FILE_STATUS_UNREPORTED.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4eBFnanCACYWdKCzhHMcC
2026-09-16 16:40:12 +02:00
Tobias BaumgartlandClaude Opus 5 844faf850f Stop arrayprinter from sizing its stack buffer from the input
printHex and printDec built a variable length array of (size + 1) * 7 + 1 and
size * 4 + 1 + lines bytes respectively, on the stack, from the caller's
buffer size. Nothing bounded that against the stack it ran on.

This reset an iOBC on the flatsat. A CFDP uplink driven without inter packet
spacing filled the USLP receive buffer with about 12 KB in one 300 ms cycle,
a frame parse error asked for the serial stream to be dumped, and printHex
tried to place an 84 KB array on an 8 KB task stack. FreeRTOS caught it as
STACK OVERFLOW DETECTED in USLP_RX and restarted the OBC.

The trigger needs a parse error, so it hid for as long as the link stayed
clean: USLP_RX sat at 800 bytes of its 8 KB, and the first corrupted frame
with a full receive buffer behind it was fatal.

Emit the output in fixed 128 byte chunks instead, flushing as it is built.
The rendered text is unchanged - verified byte for byte against the previous
implementation for sizes 0 to 4096 and several line widths, including the
line break boundaries.

printBin was already safe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4eBFnanCACYWdKCzhHMcC
2026-09-16 12:02:57 +02:00
Tobias BaumgartlandClaude Opus 5 e256fa4b92 cfdp: parse and act on a Cancel EOF at the destination
handleEofPdu built its EofInfo with a null fault location TLV pointer.
EofPduReader refuses to parse any EOF whose condition code is not NO_ERROR
unless it has somewhere to put that TLV, so every Cancel EOF a sender emits
was rejected with "Ca not deserialize fault location" and dropped before the
handler saw it.

The consequences were invisible from the ground until now: the sender's
cancellation was never acknowledged, so it retransmitted the EOF to its
positive ACK limit and declared a fault, while this handler kept the
transaction open until its own check limit expired. A flatsat uplink hit
exactly that, twice ten seconds apart, which is the sender's retransmission
interval.

Give both EOF parse sites a real EntityIdTlv, held by the handler so no
allocation happens per PDU, and adopt a non-NO_ERROR condition code into the
transaction. Without the second part the cancellation would parse but then
fall through to transfer completion, which would run a checksum pass over a
file the sender has already abandoned and report a checksum failure instead of
the cancellation.

The new test fails without the fix in the same way the flatsat did: no ACK is
emitted at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4eBFnanCACYWdKCzhHMcC
2026-09-16 11:54:34 +02:00
Tobias BaumgartlandClaude Opus 5 9d609b6d2d cfdp: exclude the PDU CRC from variable length PDU tails
FileDataReader takes the two CRC bytes out of the parsed range before it
reads its payload. The three readers with a variable length tail did not,
and each of them walks that tail until the range is exhausted:
MetadataPduReader over its option TLVs, NakPduReader over its segment
requests, FinishPduReader over its filestore and fault location TLVs.

With crcOnTransmission set at the sender, the CRC is therefore parsed as
one more TLV or segment request and the PDU is rejected, metadata and
Finished with INVALID_TLV_TYPE. Reception of CRC bearing PDUs only ever
worked for the PDUs which have no tail at all, which is why it went
unnoticed: a plain file uplink's metadata carries no options. A proxy put
request always carries one, and in acknowledged mode so do the NAK and
Finished PDUs a ground source sends, so this broke the OBSW as a
destination for any request carrying a message to user, and as a source
for every acknowledged downlink.

MetadataPduReader had a partial guard for this - an early return when the
CRC was the only thing left - which covered the no-options case and hid
the defect for the case that has them. It is replaced by the same up front
subtraction the other two now do.

The tests build CRC bearing PDUs by hand through the new PduCrcHelper,
because the creators cannot produce one: they append the CRC without
counting it in the directive data field length, which is a separate defect
left alone here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4eBFnanCACYWdKCzhHMcC
2026-09-16 10:38:08 +02:00
Tobias BaumgartlandClaude Opus 5 892fdff164 cfdp: apply clang-format to the class 2 handler changes
origin/main is clang-format clean, this branch was not: the class 2 work left
six violations across four files. Purely mechanical reflowing, no behaviour
change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZpKfWUzvTkBMXEv9NEoTM
2026-09-15 01:08:30 +02:00
Tobias BaumgartlandClaude Opus 5 30965ed058 cfdp: fix acknowledged mode error handling and PDU transaction filtering
Review of the class 2 implementation turned up seven defects, all in the paths
that only run when something has already gone wrong on the link.

Send failures were still being treated as successful sends in two places the
earlier fix missed. SourceHandler::servicePendingRetransmissions() advanced its
cursor past a segment whose sendFileDataPdu() failed and cleared
metadataPending before the metadata PDU had gone out, so a NAK answered while
the TM store was full dropped exactly the data the peer asked for. Both now
only advance on success, matching the forward-only path.

A NAK carrying more segment requests than the reader's array can hold was a
complete no-op rather than a partial one: NakPduReader::parseData() returns
NAK_CANT_PARSE_OPTIONS without ever calling setSegmentRequestLen(), so the
length stayed at the 0 set before the loop and handleNakPdu() acted on nothing.
Every early return in that loop now reports the number of complete requests
parsed. handleNakPdu() also resets its retransmit state before parsing, because
the reader writes straight into the segment array and a hard parse error used
to leave the previous NAK's indices pointing into a half overwritten one.

handleFinishedPdu() marked the transaction finished and copied the delivery
result before checking whether the PDU had parsed at all, so a Finished PDU
truncated before its condition code byte completed the transfer and reported
the default constructed DATA_COMPLETE - a fabricated success. Only a failure
inside the optional TLVs is tolerated now.

Neither handler checked which transaction an incoming ACK or Finished PDU
belonged to, and CfdpHandler routes on direction and directive alone. A late
ACK from a previous transaction therefore drove whichever one was running now,
up to and including finishing it. Both handlers now compare the PDU's source
entity ID and sequence number against the running transaction, by value rather
than with operator==, which also compares the encoded width.

The Finished PDU send is now retried on failure instead of being assumed sent,
in both transmission modes, bounded by maxFinishedPduSendAttempts. Class 1 used
to finish() regardless, so the peer never heard that a transfer which actually
succeeded had completed and had no way to ask again. Bounding it is the point:
a busy destination handler discards incoming metadata PDUs, so retrying
forever would mean no later uplink could start. Exhausting the budget releases
the transaction without declaring a fault - the file is complete on disk and
the local user already got its indication, only the notification is lost.

Finally, DestHandler's NAK segment scratch buffer is sized to hold at least one
request, so a maxSegmentRequestsPerNakPdu of 0 is a clamped configuration
rather than an out of bounds write.

Eleven new test sections cover all of it. PduSenderMock gains failSendAtIdx and
failSendsFromIdx alongside failNextSend, for the cases where the call under
test emits several PDUs or where the downstream stays broken.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZpKfWUzvTkBMXEv9NEoTM
2026-09-15 00:46:37 +02:00
Tobias BaumgartlandClaude Sonnet 5 fa7ecca728 cfdp: stop swallowing PduSenderIF::sendPdu() failures
SourceHandler::sendGenericPdu() and DestHandler::sendFinishedPdu() discarded
sendPdu()'s return value, so a downstream send failure (e.g. a full TM store)
was invisible to the state machine: transactionParams.progress advanced past
file data that was never actually enqueued for downlink, and a retransmit hit
the same swallowed-error path. Both now propagate the result so a failed send
retries the same segment instead of being silently treated as sent.

Adds a failure-injection knob to PduSenderMock and a SourceHandler test
covering the retry.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZpKfWUzvTkBMXEv9NEoTM
2026-09-14 23:27:09 +02:00
Tobias Baumgartl 0224523cc5 cfdp: implement acknowledged mode (class 2) in both handlers
Class 1 has no retransmission at all: on a lossy uplink a single lost PDU
corrupts a transfer and a lost metadata PDU strands it completely. The PDU
layer for class 2 was already complete and unit tested, but neither handler
implemented the procedures on top of it - the destination handler had a
warning stub for BUSY_CLASS_2_ACKED and a SENDING_ACK_PDU step no branch
serviced, and the source handler discarded every incoming PDU and parked
permanently in BUSY_CLASS_2_ACKED.

RemoteEntityCfg gains the positive ACK, NAK and check timer parameters. The
names mirror cfdppy.mib.RemoteEntityConfig field for field so both ends of a
link can be configured from the same numbers. The defaults are inert for
class 1.

Destination handler:
- tracks received segments in the lostSegmentsContainer that was already
  plumbed through but never read, so completion is "no gaps and EOF seen"
  rather than the class 1 "progress reached the file size"
- emits the ACK for the EOF PDU before the transfer completion step, because
  the checksum pass reads the whole file back from the SD card and would
  otherwise run inside the sender's positive ACK timer
- runs the deferred lost segment procedure: one NAK sequence when the EOF
  arrives, re-issued on NAK timer expiry, NAK_LIMIT_REACHED on the limit.
  Segment requests are batched per PDU and the remainder carried over
- retains the transaction until its Finished PDU is acknowledged, retransmits
  it on positive ACK timeout, POSITIVE_ACK_LIMIT_REACHED on the limit
- can start a transaction from a file data PDU when the metadata was lost and
  request the metadata with a NAK of scope 0 to 0
- acknowledges an EOF PDU for an inactive transaction, otherwise the sender
  declares a fault at the end of an otherwise successful transfer
- runs the check timer after EOF so an incomplete file is cancelled instead
  of pinning the handler forever

Source handler:
- consumes incoming PDUs instead of dropping them on the floor
- waits for the ACK of its EOF PDU and retransmits on timeout
- answers NAK PDUs by retransmitting the requested segments, one PDU per
  state machine call, and the metadata PDU for a scope 0 to 0 request. The
  read and send path is split from the forward-only progress cursor for this
- implements WAIT_FOR_FINISH properly: parses the Finished PDU, acknowledges
  it and reports the received condition and delivery codes instead of a
  hardcoded NO_ERROR / DATA_COMPLETE. This also fixes class 1 with closure,
  which reported success for a transfer the receiver had rejected. The wait
  is bounded so a lost Finished PDU cannot pin the handler

AckPduCreator and NakPduCreator get the `using FileDirectiveCreator::serialize`
that FinishedPduCreator already had, so the convenience overloads are usable.

crcOnTransmission stays unusable and unused: the CRC sizing bug in the PDU
creators is a separate, self-contained fix.
2026-09-11 16:06:53 +02:00
tbaumgartl 42ecc7caf1 Merge pull request 'fix MessageQueueBase ignore fault' (#72) from baumgartl/fix-mqb-ignore-fault into main
Reviewed-on: #72
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2026-09-06 17:53:14 +02:00
muellerr 17926777a1 Merge pull request 'fix: ensure proper mutex unlocking in destructor to prevent system halts' (#71) from baumgartl/fix-mutexguard into main
Reviewed-on: #71
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2026-09-05 10:33:50 +02:00
Tobias Baumgartl 5761c1e187 fix: allow configurable fault handling in sendMessage function 2026-09-05 07:22:32 +02:00
Tobias Baumgartl 427f5a99b9 fix: ensure proper mutex unlocking in destructor to prevent system halts 2026-09-05 06:49:20 +02:00
tbaumgartl b1d2a4726f Merge pull request 'Add COBS encoding support (encoding and decoding)' (#70) from blochm/fsfw:bloch/cobs into main
Reviewed-on: #70
2026-08-27 07:24:55 +02:00
tbaumgartl 4a47eced59 Merge pull request 'Exclude host sources from non-host targets' (#69) from blochm/fsfw:bloch/smol-fix into main
Reviewed-on: #69
2026-08-27 07:18:55 +02:00
blochm b123b3f260 feat: cobs 2026-08-15 12:02:57 +02:00
blochm 428ff3f373 fix: kick out host stuff from device build 2026-08-15 10:11:34 +02:00
muellerr 9890a2c52e Merge pull request 'Better printer task & Bug fix' (#68) from blochm/fsfw:bloch/improve-printout into main
Reviewed-on: #68
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2026-08-06 10:40:08 +02:00
blochm b65854eaa0 fix(DeviceHandlerBase): SerialBufferAdapter was missing <uint32_t>
Previously it simply defaulted to size_t because of the length parameter
type. This is bad, since network serialization is then platform
dependant
2026-07-14 19:20:14 +02:00
blochm 23500c8364 feat(ServiceInterfacePrinter): ringbuffer printer
Previously the printer used a 2d array mechanism to queue up messages,
by selecting a free slot with help of a etl::bitset for tracking. A
message is then sent to the callback what slot is filled up and the
callback then drains the entire queue and prints out the messages.

This was prone to deadline issues, since the entire queue was always
flushed and often I noticed a deadline missed messages when developing
other stuff. Also memory is inefficiently used with the 2d array.

This new version fixes the above using a ring buffer datastructure. We
use a flat array and 2 integer pointers for storing and tracking the
bytes to print. So now there isn't any wasted space between messages.
Also with the design of the ring buffer messages can be written in and
read out at the same time, so we have minimal mutex use (just for
updating the integer pointers). To address the deadline issue, the
callback also only prints out a limited number of bytes per cycle.

(Also the printer code in general has been optimized a bit, since it was
quite needlessly big)
2026-07-14 19:20:14 +02:00
muellerr 91c5b05723 Merge pull request 'add keep alive PDU serializer' (#67) from add-keep-alive-pdu-serializer into main
Reviewed-on: #67
2026-04-14 10:10:45 +02:00
Robin Mueller a8bcb9c8cd add keep alive PDU serializer 2026-04-14 10:09:16 +02:00
muellerr 1d278d6f5c Merge pull request 'Fix stray import' (#66) from ritzmannc/fsfw:ritzmann/fix-stray-import into main
Reviewed-on: #66
2026-03-04 10:10:27 +01:00
ritzmannc b1bc699009 Fix stray import 2026-03-03 20:31:55 +01:00
muellerr 3668e61d5c Merge pull request 'Asynchronous ServiceInterfacePrinter' (#65) from ritzmannc/fsfw:ritzmann/sif-async-print into main
Reviewed-on: #65
2026-03-03 19:28:49 +01:00
ritzmannc 45150c8ce3 Fix of by one errors and set the position after the last char to a null byte. 2026-02-19 00:34:34 +01:00
ritzmannc 7692e598d6 Add FSFW_PRINT_BUFFER_AMOUNT to FSFW template config 2026-02-17 16:40:24 +01:00
ritzmannc 52129e0c84 Remove legacy code 2026-02-13 16:35:11 +01:00
ritzmannc acf60e55e8 Fix Host TaskFactory::printMissedDeadline warning 2026-01-23 12:49:10 +01:00
ritzmannc a625a06b7d Add async printing functionality 2026-01-23 12:48:09 +01:00
muellerr c0a665ffe6 Merge pull request 'PUS: Implement serialization for TC[8, 128] (Direct Command)' (#62) from bertschs/fsfw:bertsch/packet-apis into main
Reviewed-on: #62
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2026-01-12 09:40:12 +01:00
muellerr cceef62cb6 Merge pull request 'Expose health table mutex publically' (#64) from baumgartl/expose-healthtable-mutex into main
Reviewed-on: #64
2026-01-09 13:34:09 +01:00
Tobias Baumgartl 4c3c93c106 Expose health table mutex publically 2026-01-08 19:42:53 +01:00
tbaumgartl d28e2b5f07 Merge pull request 'Increasing the maximum number of allowed mode tables for subsystems' (#63) from spahr/maxNumberOfModeTables into main
Reviewed-on: #63
2026-01-04 20:28:20 +01:00
spahr@ksat-stuttgart.de 6ebe3123ff Increasing the maximum number of allowed mode tables
changelog
2026-01-04 20:27:11 +01:00
bertschs 70b9ba68bf PUS: Implement serialization for TC[8, 128] (Direct Command)
This allows creating and serializing direct
command PUS packets. This functionality is needed
in SOURCE, where OBC prepares TC[8, 128] packets
for Payload Computer (PLOC).

Additionally, expose some setters and
datastructures to facilitate this use case.
2025-11-26 22:13:02 +01:00
muellerr 59706365f6 Merge pull request 'typo' (#59) from mdemke/typo-fix into main
Reviewed-on: #59
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2025-11-06 16:25:07 +01:00
muellerr 0c70ff1822 Merge branch 'main' into mdemke/typo-fix 2025-11-06 16:24:52 +01:00
muellerr 76dd1d1562 Merge pull request 'PUS Routing Configuration' (#60) from meier/pus-routing into main
Reviewed-on: #60
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2025-11-06 16:24:32 +01:00
muellerr f2b72db481 Merge branch 'main' into meier/pus-routing 2025-11-06 16:24:25 +01:00
muellerr fa4af546fa Merge pull request 'Changing the function definition to a virtual function to allow overrides for some custom applications' (#61) from spahr/costumCommandTableExecution into main
Reviewed-on: #61
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2025-11-06 16:24:13 +01:00
spahr@ksat-stuttgart.de 5745d7f01c Changing the function definition to a virtual to allow overrides for custom applications 2025-10-22 23:23:26 +02:00
Jakob Meier d7c1d05599 changelog update 2025-08-03 16:36:19 +02:00
Jakob Meier 86b83810c3 run auto formatter 2025-08-03 16:29:53 +02:00
Jakob Meier d0904fdaa2 added function to set verification reporter of CommandingServiceBase 2025-08-01 08:57:08 +02:00
Jakob Meier f824c066d1 PusServiceBase public functions to change the verifcation reporter and the pus distributor 2025-07-31 16:41:14 +02:00
Jakob Meier d000365b99 PusDistributor public function to change the verifcation reporter 2025-07-31 16:40:34 +02:00
Michael Demke d99f6fd356 typo 2025-06-25 15:22:18 +02:00
muellerr 49eaeae42b Merge pull request 'Adaptions to make shared power lines possible' (#57) from spahr/shared into main
Reviewed-on: #57
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2025-04-28 13:50:31 +02:00
muellerr 7bfc536cf6 Merge branch 'main' into spahr/shared 2025-04-28 13:50:23 +02:00
phoffmann 1da7f7f122 Merge pull request 'Added STOP_DOWNLINK_STORE_CONTENT for Service [15,17]' (#58) from hoffmann/TmStoreMessage into main
Reviewed-on: #58
2025-04-21 19:21:40 +02:00