feat(kble-c2a): fragment oversized Space Packets across AOS Transfer Frames#178
Open
Kentaro Sugimoto (tarotene) wants to merge 2 commits into
Open
feat(kble-c2a): fragment oversized Space Packets across AOS Transfer Frames#178Kentaro Sugimoto (tarotene) wants to merge 2 commits into
Kentaro Sugimoto (tarotene) wants to merge 2 commits into
Conversation
…Frames
Per CCSDS 732.0-B-4 §4.1.4, a Space Packet (SP) may span multiple AOS
Transfer Frames via the M_PDU First Header Pointer (FHP) mechanism.
The previous implementation rejected any SP larger than the M_PDU Data
Zone (432 bytes) with an error, and also contained a latent
underflow for SP sizes in [426, 432] where the trailing Idle Packet
would become malformed.
This commit rewrites `to_aos_tfs` (renamed from `to_aos_tf`) to emit
one or more 444-byte AOS TFs per input SP:
- Case A (L <= 425): single TF, SP + Idle Packet -- behaviour preserved
byte-for-byte (asserted by a golden test).
- Case B (L > 425, L mod 432 in {0} union [1..=425]): full 432-byte SP
chunks with FHP = 0x07FF (No Header) for continuation frames;
final frame has FHP pointing to the trailing Idle Packet; when SP
ends exactly on a Data Zone boundary, a dedicated Idle-only TF
(FHP = 0) is appended.
- Case C (L mod 432 in [426..=431]): a minimum 7-byte Idle Packet is
prepended to the first frame to shift the SP start by 7 bytes, which
moves the tail remainder back into [1..=6] -- a region where the
trailing Idle Packet satisfies the CCSDS 133.0-B-1 minimum size.
frame_count advances once per emitted AOS TF (not per input SP),
which is the continuous-per-VC behaviour required by CCSDS 732.0-B-4
section 4.1.2.4.
The caller run_sp_to_aos_tf is updated to iterate over the returned
Vec<BytesMut> and send each frame individually.
Fourteen unit tests cover the full size matrix, including pathological
sizes, exact Data Zone multiples, round-trip SP reconstruction, Idle
Packet structural validity, and frame_count wrapping.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
b0caee7 to
a089fca
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
kble-c2a spacepacket to-aos-tfpreviously assumed one Space Packet (SP) fitsentirely in one AOS Transfer Frame. This violates CCSDS 732.0-B-4 §4.1.4, which
defines the M_PDU First Header Pointer (FHP) mechanism to support SP spanning
across multiple frames. The command now implements that mechanism.
An additional latent bug is fixed simultaneously: SP sizes in the range
[426, 432] passed the explicit upper-bound check but then caused a
usizeunderflow when computing the trailing Idle Packet length, producing either a
panic (debug) or a malformed 444-byte frame with
Packet Data Length = 0xFFFF(release).
Behaviour change matrix
Each row shows the total SP length
Lagainstkble-c2a spacepacket to-aos-tf.Lusizeunderflow; release: writes 444 B frame with malformed Idle Packet (Packet Data Length = 0xFFFF, 0 data bytes)Err("Space Packet is too large: 433 bytes")ErrErrErrErrErrErrSupporting observations
frame_countnow increments once per emitted AOS TF (not per input SP), matching the continuous-per-VC requirement of CCSDS 732.0-B-4 §4.1.2.4. Single-frame cases (L ≤ 425) still increment by 1, preserving existing behaviour.L ∈ [426, 431]was a silently broken band: the release build emitted a 444-byte frame with a corrupt Idle Packet. This is repaired without changing the single-frame output forL ≤ 425.L < 7is now explicitly rejected withErr("Space Packet is too short: {L} bytes"). Previously, such input produced a TF with no valid SP content.Fragmentation algorithm
Three cases based on
Landr = L mod 432:L ≤ 425): single TF,[SP | Idle(432−L)], FHP = 0. Output preserved byte-for-byte.L > 425,r ∈ {0} ∪ [1..=425]): emit full 432-byte SP chunks (FHP = 0x07FF for continuation), then a tail frame with[SP_remainder | Idle(432−r)]at FHP =r. Whenr = 0, append a dedicated Idle-only TF (FHP = 0).r ∈ [426..=431]): a naive tail would leave fewer than 7 bytes for the Idle Packet, violating CCSDS 133.0-B-1. A minimum 7-byte Idle Packet is prepended to the first frame, shifting the SP start from offset 0 to offset 7. This moves the effective tail remainder from[426..=431]to[1..=6], restoring CCSDS compliance.Test plan
cargo test -p kble-c2a— 14 new tests pass (all 19 total, including 5 pre-existingtfsynctests)cargo clippy -p kble-c2a -- -D warnings— no warningsL ≤ 425:sp_bit_identical_to_legacyasserts byte-for-byte equality with the output of the previous implementationassert_sp_round_tripPacket Data Lengthfield) verified for all trailing and prepended Idle PacketsReferences
🤖 Generated with Claude Code