CCSDS Packets & Frames

Premium

Build and take apart CCSDS space packets, TM transfer frames and SDLS, a field at a time

Open to everyone during the beta. It will need a helio.tools account once premium tools launch.

The octets

Whether the last two octets are a checksum is a managed parameter. Nothing in a TM frame says, so it has to be told, and guessing it by seeing whether a CRC happens to check out would be wrong about one time in 65,536.

Separators, 0x prefixes and brackets are all fine. Paste a dump straight in.

Security association

SDLS puts a header in front of the frame data field and a trailer behind it. Only the security parameter index has a size the standard fixes; every other length here is agreed in the Security Association before anything is transmitted, and nothing in the frame reveals it. That is why this asks rather than guesses.

12 for AES-GCM

Block ciphers only

16 for AES-GCM

Breakdown

Paste some octets above, or load one of the examples.

Totals

Length
First six octets, in bits

The Blue Books are free and they are precise. They are also spread across several documents, which is why so much of this work happens with a PDF open on one screen and a hex dump on the other, counting bits by hand. Everything below is the part people actually get wrong, written down once.

The off-by-one that catches everybody

The Packet Data Length field holds one less than the number of octets in the packet data field. Not the length of the packet, and not the length of the data field. A packet carrying eight octets of data writes 7 into a sixteen-bit field, and the whole packet is 6 + 7 + 1 = 14 octets.

The reason is that a packet data field of zero octets is not allowed, so the encoding gives that impossible value up in exchange for one more octet at the top end. It means the largest data field is 65,536 octets, not 65,535.

It appears a second time in the TM transfer frame secondary header, whose length field is also one less than the truth. Two chances to make the same mistake, in two different places, is worse than one.

The APID is not on its own

An application process is identified by the packet type together with the APID, not by the APID alone. Telemetry APID 100 and telecommand APID 100 are two different application processes, and a routing table that keys on the eleven bits without the type bit will merge them.

APID 2047, all ones, is reserved for idle packets. They exist so a transfer frame can be filled when there is nothing worth sending, and an idle packet must not claim a secondary header.

Virtual channel identifiers are three different widths

This is the one that survives review and fails in integration.

The spacecraft identifier moves too: ten bits in TM and TC, eight in AOS.

The trap in a mission that moves its downlink from TM to AOS is that the channel numbers stay valid. Virtual channel 3 is a legal value in both, so nothing in the configuration complains and nothing looks wrong. What changes is where those bits sit: the identifier moves from bits 12 to 14 to bits 10 to 15, and the spacecraft identifier shrinks underneath it. Anything that parses the header has to change, and nothing will tell you so.

What the first header pointer is really saying

Packets do not respect frame boundaries. A long packet spans several frames, and a frame usually contains the tail of one packet, then some whole ones, then the start of the next. The first header pointer is how a receiver finds its way in: it is the offset, in octets from the start of the data field, of the first packet that begins in this frame.

Two values are not offsets at all:

A frame processor that handles only the ordinary case does not crash. It silently drops every packet that spans a frame boundary, which on a busy virtual channel can be most of them, and the symptom is missing telemetry rather than an error anybody can see.

The pointer is also meaningless when the synchronisation flag is set, because then the data field carries a VCA_SDU rather than packets. So is the segment length identifier. Both have to be checked before they are believed.

Managed parameters, or the things the frame does not tell you

A TM transfer frame does not carry its own length. Frame length is fixed for a mission and agreed in advance, and a receiver that does not already know it cannot find where one frame ends and the next begins. This surprises people coming from TC, where the length is in the header.

Whether a frame error control field is present is also a managed parameter. There is no flag for it. That is why this tool asks rather than guessing: deciding by whether a CRC happens to check out would be wrong about one time in 65,536, and being quietly wrong is the failure worth designing against.

The same applies to the packet secondary header. The flag tells you one is there; nothing tells you what is in it. Its layout is a mission choice, and on European missions it is usually the PUS header from ECSS-E-ST-70-41C.

SDLS, and why this tool asks you a question first

Space Data Link Security wraps the transfer frame data field: a security header in front of it, a security trailer behind it. Turning it on is the single biggest change you can make to a frame's layout, and almost none of that layout is written down in the standard as a number.

The security parameter index is sixteen bits. That is the end of what CCSDS 355.0-B fixes. The initialisation vector, the sequence number, the pad length field and the message authentication code are all lengths agreed in the Security Association, out of band, before anything is transmitted. Nothing in the frame tells you what they are.

So a decoder cannot work out where the data field starts without being told, and one that guesses is confidently wrong on every mission whose parameters differ from the guess. That is why the panel above asks. A diagram with fixed offsets would look far more useful and would be a lie.

The trailer is inside the data field, not at the end of the frame

This is the mistake worth naming. The operational control field and the frame error control field sit outside the security envelope. If you measure the MAC back from the end of the frame rather than from the end of the data field, you are two octets out with a checksum present, six with an operational control field, and eight with both.

The symptom is authentication that fails on every frame, which looks exactly like a key or a keying-material problem, and people go and check the key.

What the three services actually give you

An initialisation vector reused with the same key destroys the confidentiality of both frames it was used on. That is why the sequence number exists, and why a Security Association with no IV in the header has to derive one identically at both ends or repeat a keystream.

One thing this tool deliberately does not do: verify a MAC or decrypt a data field. Both need the key, and a key does not belong in a web page, including this one. It finds the fields and tells you what they are; the cryptography stays where your keys already live.

The first header pointer means nothing until you decrypt

When the data field is ciphertext, the first header pointer in the frame header still refers to the plaintext inside it. Reading it as an offset into the encrypted octets gives you a number that looks plausible and points at nothing.

The CRC has an evil twin

The frame error control field uses the generatorx^16 + x^12 + x^5 + 1 with the shift register preset to all ones and no final inversion. Elsewhere this is catalogued as CRC-16/CCITT-FALSE, and the unflattering name is there for a reason: a great many implementations labelled "CCITT" preset the register to zero instead, and produce a completely different and equally plausible answer for the same octets.

If a frame checks out in every field except this one, suspect the CRC implementation before suspecting the link. Run it over the ASCII string123456789: the right one gives 0x29B1, and the zero-preset one gives 0x31C3. Two lines of code apart, and nothing about either output tells you which you have.

Where the version bits take you

The first two bits of a transfer frame are the version number, and they are how a receiver tells one protocol from another before it knows anything else.00 is a TM transfer frame and 01 is AOS, and the two have different header layouts from the third bit onwards. Decoding an AOS frame with a TM parser gives you a spacecraft identifier that is wrong by a factor of four and a virtual channel that is somebody else's, with no error anywhere.

In a space packet the equivalent field is three bits, and the only defined value is 000. Anything else there almost never means a different protocol version. It means the buffer does not start where you think it does.

Why this runs in your browser

Real telemetry and real commands are commercially sensitive at best, and frequently subject to export control. An engineer with a frame in front of them is often not permitted to paste it into a website, which is a good reason not to have one that would.

Nothing here is uploaded. The decoding happens in JavaScript on the page in front of you, and you can watch the network panel stay silent while you work, or disconnect and carry on.