Minimal, embedded-optimized implementation of the CCSDS Space Packet Protocol
primary header in C99, targeting small-scale academic missions.
Standards Alignment
CCSDS 133.0-B-2 — Space Packet Protocol (Blue Book, June 2020)
CCSDS 130.3-G-1 — Space Packet Protocols Informational Report (Green Book, April 2023)
The library implements the 6-byte Primary Header exactly as specified. The Packet
Data Field (everything that follows the primary header) is treated as an opaque,
application-owned byte sequence. Its internal layout — secondary header, user data,
any integrity check — is mission-specific and outside the library’s scope, consistent
with CCSDS §4.1.4.2 (“contents of the Packet Secondary Header shall be specified by
the source end user”).
Sequence Flags — wire values match the standard (UNSEGMENTED = 0b11 = 3)
Version enforcement — always serializes Packet Version Number as 000 and rejects any other value on parse (§4.1.3.2)
Zero allocation — no dynamic memory inside the library; caller supplies all buffers
Minimal footprint — single header + single source file, no external dependencies
Pure C99 — no OS primitives, suitable for bare-metal targets
Protocol Notes
Primary header (6 bytes):
Bits
Field
Notes
0–2
Packet Version Number
Always 000 (§4.1.3.2)
3
Packet Type
0 = TM (telemetry), 1 = TC (telecommand)
4
Secondary Header Flag
1 if Packet Data Field starts with a secondary header
5–15
APID
11-bit application process identifier
16–17
Sequence Flags
See table below
18–31
Packet Sequence Count
Modulo-16384 per APID (§4.1.3.4.3)
32–47
Packet Data Length
(Packet Data Field octets) − 1 (§4.1.3.5)
Sequence Flags wire values (§4.1.3.4.2):
Value
Meaning
00 = 0
Continuation segment
01 = 1
First segment
10 = 2
Last segment
11 = 3
Unsegmented (standalone packet)
Packet Data Field:
Follows the primary header immediately. Contains an optional secondary header and
user data (§4.1.4). Structure is entirely mission-defined. The library copies it
verbatim on serialization and exposes a pointer into the wire buffer on parsing.
CRC / integrity:
CCSDS SPP defines no checksum at the Space Packet level. If a mission requires data
integrity checking (e.g. CRC-16-CCITT), it should be computed by the application and
appended to the Packet Data Field before calling sp_packet_serialize. See
examples/main.c for a complete example.
Project Structure
EmbeddedSpacePacket/
├── .github/
│ └── workflows/
│ └── ci.yml # CI: unit tests, coverage gate, sanitizers
├── include/
│ └── space_packet.h # Public API and types
├── src/
│ └── space_packet.c # Serializer, parser, helpers
├── examples/
│ └── main.c # Example: build and parse a packet with app-level CRC
├── tests/
│ ├── cunit.h # Minimal unit test framework
│ ├── test_runners.h # Suite runner declarations
│ ├── test_space_packet.c # Space Packet test suite
│ └── unit_tests.c # Test entry point
├── tools/
│ └── coverage_html.sh # gcovr HTML coverage report
├── build/ # Build artifacts (git-ignored)
├── Makefile
└── README.md
Building
make # library + example + tests
make lib # static library only → build/libspacepacket.a
make example # example binary → build/examples/spacepacket_example
make test # build and run tests
Warnings are treated as errors (-Werror). The build is checked with both gcc and
clang; select the compiler with make CC=clang.
Coverage (requires gcovr)
sudo apt install gcovr
make coverage-html # → build/coverage/index.html
Sanitizers (ASan + UBSan)
make sanitize # rebuild with ASan + UBSan, run tests and example, then clean up
EmbeddedSpacePacket
Minimal, embedded-optimized implementation of the CCSDS Space Packet Protocol primary header in C99, targeting small-scale academic missions.
Standards Alignment
The library implements the 6-byte Primary Header exactly as specified. The Packet Data Field (everything that follows the primary header) is treated as an opaque, application-owned byte sequence. Its internal layout — secondary header, user data, any integrity check — is mission-specific and outside the library’s scope, consistent with CCSDS §4.1.4.2 (“contents of the Packet Secondary Header shall be specified by the source end user”).
Features
UNSEGMENTED = 0b11 = 3)000and rejects any other value on parse (§4.1.3.2)Protocol Notes
Primary header (6 bytes):
000(§4.1.3.2)0= TM (telemetry),1= TC (telecommand)1if Packet Data Field starts with a secondary headerSequence Flags wire values (§4.1.3.4.2):
00= 001= 110= 211= 3Packet Data Field: Follows the primary header immediately. Contains an optional secondary header and user data (§4.1.4). Structure is entirely mission-defined. The library copies it verbatim on serialization and exposes a pointer into the wire buffer on parsing.
CRC / integrity: CCSDS SPP defines no checksum at the Space Packet level. If a mission requires data integrity checking (e.g. CRC-16-CCITT), it should be computed by the application and appended to the Packet Data Field before calling
sp_packet_serialize. Seeexamples/main.cfor a complete example.Project Structure
Building
Warnings are treated as errors (
-Werror). The build is checked with bothgccandclang; select the compiler withmake CC=clang.Coverage (requires
gcovr)Sanitizers (ASan + UBSan)
Clean
Continuous Integration
Every push to
mainand every pull request runs three jobs (.github/workflows/ci.yml):makewithgccand withclang, then the example binarymake coverage-html, then requires 100% line and branch coveragemake sanitizeQuick Start
Minimal encode / decode round trip, condensed from examples/main.c:
The full example in examples/main.c additionally shows a mission-defined secondary header and an application-level CRC-16-CCITT (
make example).Memory Footprint (estimated, 64-bit host)
sp_packet_tstructdata_lenbytesLimitations
References
License
See LICENSE file.