Did you know ... Search Documentation:
Pack logtalk -- logtalk-3.97.1/library/ccsds/NOTES.md

This file is part of Logtalk https://logtalk.org/ SPDX-FileCopyrightText: 2025 Paulo Moura <pmoura@logtalk.org> SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

ccsds

The ccsds library implements predicates for parsing and generating CCSDS (Consultative Committee for Space Data Systems) Space Packets following the CCSDS 133.0-B-2 standard (Space Packet Protocol).

Reference documentation:

Packet Structure

A CCSDS Space Packet consists of:

  1. Primary Header (6 bytes):
    • Version Number (3 bits) - Always 000 for Space Packets
    • Packet Type (1 bit) - 0=Telemetry, 1=Telecommand
    • Secondary Header Flag (1 bit) - 0=absent, 1=present
    • Application Process ID (APID) (11 bits) - 0-2047
    • Sequence Flags (2 bits) - 00=continuation, 01=first, 10=last, 11=standalone
    • Packet Sequence Count (14 bits) - 0-16383
    • Packet Data Length (16 bits) - Number of octets in data field minus 1
  2. User Data Field - Variable length payload

Representation

Packets are represented using the compound term:

ccsds_packet(Version, Type, SecHeaderFlag, APID, SeqFlags, SeqCount, SecHeader, UserData)

Where:

  • Version is an integer (0-7, typically 0)
  • Type is an integer (0=telemetry, 1=telecommand)
  • SecHeaderFlag is an integer (0 or 1)
  • APID is an integer (0-2047)
  • SeqFlags is an integer (0-3)
  • SeqCount is an integer (0-16383)
  • SecHeader is either none or secondary_header(Bytes) where Bytes is a list of bytes
  • UserData is a list of bytes Note that the DataLength field from the wire format is not stored in the term representation as it can be computed from SecHeader and UserData. The data_length/2 accessor predicate computes and returns this value when needed.

Parsing

The parse/2 predicate accepts a source term as its first argument. The source can be file(File), stream(Stream), or bytes(Bytes). All source types return a list of packets for uniformity.

To parse packets from a list of bytes:

| ?- ccsds::parse(bytes([0x08, 0x01, 0xC0, 0x00, 0x00, 0x03, 0xDE, 0xAD, 0xBE, 0xEF]), Packets). Packets = [ccsds_packet(0, 0, 1, 1, 3, 0, none, [222, 173, 190, 239])] yes

To parse packets from a binary file:

| ?- ccsds::parse(file('telemetry.bin'), Packets).

To parse packets from a binary stream:

| ?- ccsds::parse(stream(Stream), Packets).

When the packets include a secondary header, the secondary header length must be known. In this case, use the ccsds(SecondaryHeaderLength) object instead of the ccsds object. For example, to parse packets with a secondary header of 6 bytes:

| ?- ccsds(6)::parse(bytes([0x08, 0x01, 0xC0, 0x00, 0x00, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xAA, 0xBB]), Packets).

Generating

The generate/2 predicate accepts a sink term as its first argument and a list of packet terms as the second argument. The sink can be file(File), stream(Stream), or bytes(Bytes).

To generate bytes from a list of packet terms:

| ?- ccsds::generate(bytes(Bytes), [ccsds_packet(0, 0, 1, 1, 3, 0, none, [0xDE, 0xAD, 0xBE, 0xEF])]). Bytes = [8, 1, 192, 0, 0, 3, 222, 173, 190, 239] yes

To write the bytes generated from a list of packet terms to a binary file:

| ?- ccsds::generate(file('output.bin'), Packets).

To write the bytes generated from a list of packet terms to a binary stream:

| ?- ccsds::generate(stream(Stream), Packets).

Accessor Predicates

The library provides convenient accessor predicates for extracting packet fields:

| ?- ccsds::apid(Packet, APID).

% Returns telemetry or telecommand | ?- ccsds::type(Packet, Type).

% Returns continuation, first, last, or standalone | ?- ccsds::sequence_flags(Packet, Flags).

% Returns the secondary header as a list of bytes or none | ?- ccsds::secondary_header(Packet, SecHeader).

% Returns the secondary header time as a cuc_time(Coarse, Fine) term or fails if no time is available | ?- ccsds::secondary_header_time(Packet, Time).

| ?- ccsds::user_data(Packet, Data).

% Returns the packet data length (computed from secondary header and user data) | ?- ccsds::data_length(Packet, Length).

Types and arbitrary generators

The library includes a ccsds_types category that provides ccsds_packet and ccsds_packet(SecondaryHeaderLength) types and arbitrary generators for CCSDS packets. For example:

| ?- type::check(ccsds_packet, Bytes).

| ?- type::arbitrary(ccsds_packet(42), Bytes).

It also provides a ccsds_packets(N) and ccsds_packets(SecondaryHeaderLength, N) types for generating a list with N packets. For example:

| ?- type::arbitrary(ccsds_packets(10), Bytes).

| ?- type::check(ccsds_packets(42, 10), Bytes).

For a term representation of a packet, use the ccsds_packet_term and ccsds_packet_term(SecondaryHeaderLength) types and arbitrary generators. For example:

| ?- type::check(ccsds_packet_term, Packet).

| ?- type::arbitrary(ccsds_packet_term(42), Packet).

API documentation

Open the [../../apis/library_index.html#ccsds](../../apis/library_index.html#ccsds) link in a web browser.

Loading

To load all entities in this library, load the loader.lgt file:

| ?- logtalk_load(ccsds(loader)).

Testing

To test this library predicates, load the tester.lgt file:

| ?- logtalk_load(ccsds(tester)).

To test the performance of the library parsing predicates, load the tester_performance.lgt file:

| ?- logtalk_load(ccsds(tester_performance)).