spp

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 2, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Index

Constants

View Source
const (
	PacketTypeTM uint8 = 0 // Telemetry
	PacketTypeTC uint8 = 1 // Telecommand
)

Packet types per CCSDS 133.0-B-2.

View Source
const (
	SeqFlagContinuation uint8 = 0 // Continuation segment
	SeqFlagFirstSegment uint8 = 1 // First segment
	SeqFlagLastSegment  uint8 = 2 // Last segment
	SeqFlagUnsegmented  uint8 = 3 // Unsegmented (standalone)
)

Sequence flags per CCSDS 133.0-B-2.

View Source
const APIDIdle uint16 = 0x7FF

APIDIdle is the idle-packet APID ('all ones') per CCSDS 133.0-B-2 4.1.3.3.4.

View Source
const PrimaryHeaderSize = 6 // CCSDS primary header is always 6 bytes

Variables

View Source
var (
	// ErrInvalidHeader indicates an invalid primary or secondary header.
	ErrInvalidHeader = errors.New("invalid header: header does not conform to CCSDS standards")

	// ErrInvalidVersion indicates the version number is not 0 (CCSDS v1).
	ErrInvalidVersion = errors.New("invalid version: must be 0 for CCSDS v1")

	// ErrInvalidType indicates the packet type is not 0 (TM) or 1 (TC).
	ErrInvalidType = errors.New("invalid packet type: must be 0 (TM) or 1 (TC)")

	// ErrInvalidAPID indicates that the provided APID is out of range.
	ErrInvalidAPID = errors.New("invalid APID: must be in the range 0-2047")

	// ErrInvalidSequenceFlags indicates the sequence flags are out of range.
	ErrInvalidSequenceFlags = errors.New("invalid sequence flags: must be in the range 0-3")

	// ErrInvalidSequenceCount indicates the sequence count is out of range.
	ErrInvalidSequenceCount = errors.New("invalid sequence count: must be in the range 0-16383")

	// ErrEmptyPacket indicates a packet has neither a secondary header nor user data (CCSDS C1/C2).
	ErrEmptyPacket = errors.New("packet must contain a secondary header or user data")

	// ErrNilPacket indicates a nil packet was provided.
	ErrNilPacket = errors.New("packet must not be nil")

	// ErrPacketTooLarge indicates that the packet size exceeds the allowable limit.
	ErrPacketTooLarge = errors.New("packet length must be between 7 and 65542 octets")

	// ErrDataTooShort indicates that the provided data is too short for decoding.
	ErrDataTooShort = errors.New("provided data is too short to decode the packet")

	// ErrPacketLengthMismatch indicates that the packet data field size does not match the packet length.
	ErrPacketLengthMismatch = errors.New("packet data field size does not match packet length")

	// ErrSecondaryHeaderMissing indicates that a required secondary header is missing.
	ErrSecondaryHeaderMissing = errors.New("secondary header flag is set but no secondary header is provided")

	// ErrSecondaryHeaderFlagClear indicates a packet carries a SecondaryHeader
	// while its Secondary Header Flag is '0'. CCSDS 133.0-B-2 4.1.3.3.3.2 makes
	// the flag the sole signal of the header's presence, so the two must agree:
	// encoding such a packet would declare a data field longer than the octets
	// actually written.
	ErrSecondaryHeaderFlagClear = errors.New("secondary header is set but the secondary header flag is 0")

	// ErrSecondaryHeaderTwice indicates a packet was given both a parsed
	// SecondaryHeader and a Secondary Header Indicator saying the octets are
	// already in the user data. Honoring both would count the header twice in
	// the Packet Data Length (4.1.3.5.3) and write it twice on the wire.
	ErrSecondaryHeaderTwice = errors.New("secondary header supplied both as a parsed header and as user data octets")

	// ErrSecondaryHeaderExceedsDataField indicates the configured secondary
	// header decoder wants more octets than the packet data field holds. This
	// is a decoder/packet mismatch, not a truncated buffer.
	ErrSecondaryHeaderExceedsDataField = errors.New("secondary header size exceeds the packet data field")

	// ErrSecondaryHeaderTooSmall indicates the secondary header is less than 1 octet.
	ErrSecondaryHeaderTooSmall = errors.New("secondary header must be at least 1 octet")

	// ErrSecondaryHeaderSizeMismatch indicates SecondaryHeader.Encode() returned
	// a byte count different from SecondaryHeader.Size().
	ErrSecondaryHeaderSizeMismatch = errors.New("secondary header encoded size does not match Size()")

	// ErrIdleWithSecondaryHeader indicates an idle packet (APID 0x7FF) carries a
	// secondary header, which CCSDS 133.0-B-2 4.1.3.3.3.4 forbids.
	ErrIdleWithSecondaryHeader = errors.New("idle packet must not contain a secondary header")

	// ErrCRCValidationFailed indicates that the CRC validation of the packet failed.
	ErrCRCValidationFailed = errors.New("CRC validation failed: data integrity check failed")

	// ErrQoSUnsupported indicates a QoS Requirement was passed to SendPacket
	// but the transport does not implement QoSWriter, so the requested service
	// level cannot be honored. Sending anyway would silently downgrade the
	// packet, which is worse than refusing.
	ErrQoSUnsupported = errors.New("transport does not support QoS: it does not implement QoSWriter")
)

Functions

func DeclaredPacketSize added in v0.3.0

func DeclaredPacketSize(data []byte) int

DeclaredPacketSize returns the total packet length declared by the primary header at the front of data (6 (primary header) + Packet Data Length + 1) or -1 when data is shorter than the 6-octet primary header.

The returned length may be longer than data: it is what the header claims, not what is present. That is exactly what a stream reader needs, since it must learn how many octets to fetch before it has them. Callers holding a fixed buffer should use PacketSizer, which refuses a packet that is not all there.

func IsIdleBytes added in v0.3.0

func IsIdleBytes(data []byte) bool

IsIdleBytes reports whether the encoded packet at the front of data carries the idle APID (0x7FF, CCSDS 133.0-B-2 4.1.3.3.4.4). Idle packets are fill: a receiver discards them instead of delivering them to an application.

It reads only the two APID octets, so it works on a packet that is not yet complete in the buffer.

func PacketSizer

func PacketSizer(data []byte) int

PacketSizer returns the total length in bytes of the complete Space Packet at the front of data, or -1 if data does not hold a complete packet.

It implements the sdl.PacketSizer signature used by the data link packet services to slice packets out of a reassembly buffer. Those callers hold whatever frame data has arrived so far, so a packet that reaches past the end of the buffer is not a packet yet: -1 tells them to pull another frame rather than to read octets that are not there.

Use DeclaredPacketSize when you are reading from a stream and want the length before you have fetched the body.

Types

type APIDConfig added in v0.3.0

type APIDConfig struct {
	// NewSecondaryHeader builds a fresh secondary header for each received
	// packet on this APID whose Secondary Header Flag is set. Nil delivers
	// the header octets at the front of UserData instead.
	NewSecondaryHeader func() SecondaryHeader

	// ErrorControl reports whether packets received on this APID carry a
	// trailing CRC-16 error control field.
	ErrorControl bool
}

APIDConfig is the receive-side handling for one APID, overriding the service-wide ServiceConfig fields of the same names. The zero value means "no secondary header decoder, no error control" for that APID. An entry is a complete replacement, not a partial override.

type DecodeOption

type DecodeOption func(*decodeConfig)

DecodeOption configures optional decoding behavior.

func WithDecodeErrorControl

func WithDecodeErrorControl() DecodeOption

WithDecodeErrorControl indicates the packet contains a trailing 2-byte error control field. The CRC is extracted, verified against the packet contents using CRC-16-CCITT, and stored in the decoded SpacePacket.

func WithDecodeSecondaryHeader

func WithDecodeSecondaryHeader(sh SecondaryHeader) DecodeOption

WithDecodeSecondaryHeader provides a SecondaryHeader implementation for decoding. If the packet's secondary header flag is set, this decoder will be used. Otherwise, secondary header bytes are included in UserData.

type Indication added in v0.3.0

type Indication struct {
	// Data is the Octet String: the Packet Data Field, which is what is left
	// once the Packet Extraction Function removes the Packet Primary Header
	// (4.3.2.2).
	//
	// When the packet carried a Packet Secondary Header its octets lead Data,
	// whether or not a decoder was configured, because 4.3.2.2 defines
	// SecondaryHeaderIndicator as reporting a secondary header "at the start
	// of the Octet String" and the two have to agree. A configured decoder
	// does not remove them from here; it fills SecondaryHeader in as well.
	//
	// The one thing Data omits is the error control field, when the service
	// was configured to expect one. Those two octets are consumed and checked
	// by this layer and are not part of the octet string the user sent.
	Data []byte

	// APID identifies the managed data path the octet string arrived on
	// (3.4.2.2).
	APID uint16

	// SecondaryHeaderIndicator reports whether a Packet Secondary Header leads
	// Data (3.4.2.3, 4.3.2.2). It is a mandatory parameter, read straight from
	// the Secondary Header Flag.
	SecondaryHeaderIndicator bool

	// SecondaryHeader is the parsed secondary header, when the service had a
	// ServiceConfig.NewSecondaryHeader factory and the flag was set. It is nil
	// otherwise. This is a convenience beyond the primitive of 3.4.3.3.2.
	// The octets themselves are always at the front of Data.
	SecondaryHeader SecondaryHeader

	// DataLoss is the Data Loss Indicator (3.4.2.4): true when the Packet
	// Sequence Count for this APID skipped ahead, so packets were lost in
	// transmission. The parameter is optional; the continuity check behind it
	// is mandatory (4.3.2.2).
	DataLoss bool

	// PacketsLost is how many packets the count skipped, modulo 16384. It is
	// zero unless DataLoss is true.
	PacketsLost int
}

Indication carries the parameters the OCTET_STRING.indication primitive delivers to the Octet String Service user (CCSDS 133.0-B-2 3.4.3.3.2).

type PacketIndication added in v0.3.0

type PacketIndication struct {
	// Packet is the Space Packet, delivered intact (3.3.1).
	Packet *SpacePacket

	// APID identifies the managed data path the packet arrived on (3.3.2.2).
	APID uint16

	// PacketLoss is the Packet Loss Indicator (3.3.2.3): true when the Packet
	// Sequence Count for this APID skipped ahead, so packets were lost in
	// transmission.
	PacketLoss bool

	// PacketsLost is how many packets the count skipped, modulo 16384. It is
	// zero unless PacketLoss is true.
	PacketsLost int
}

PacketIndication carries the parameters the PACKET.indication primitive delivers to the Packet Service user (CCSDS 133.0-B-2 3.3.3.3.2): the Space Packet, its APID, and the optional Packet Loss Indicator.

type PacketOption

type PacketOption func(*SpacePacket) error

PacketOption defines a function type for configuring SpacePacket options.

func WithErrorControl

func WithErrorControl() PacketOption

WithErrorControl enables the error control field on the SpacePacket. The CRC-16-CCITT checksum is computed automatically during Encode().

func WithPacketType added in v0.3.0

func WithPacketType(packetType uint8) PacketOption

WithPacketType overrides the Packet Type of the SpacePacket: PacketTypeTM (0) or PacketTypeTC (1) per CCSDS 133.0-B-2 4.1.3.3.2.

NewSpacePacket, NewTMPacket, and NewTCPacket already fix the type, so this option is mainly for NewIdlePacket, which defaults to telemetry.

func WithSecondaryHeader

func WithSecondaryHeader(header SecondaryHeader) PacketOption

WithSecondaryHeader adds a secondary header to the SpacePacket and sets the Secondary Header Flag to '1' (4.1.3.3.3.2).

The header's octets are written ahead of the user data on encode. Use WithSecondaryHeaderIndicator instead when the octets are already at the front of the data you are passing in.

func WithSecondaryHeaderIndicator added in v0.3.0

func WithSecondaryHeaderIndicator(present bool) PacketOption

WithSecondaryHeaderIndicator sets the Secondary Header Flag for a packet whose data field already begins with the Packet Secondary Header octets.

This is the Secondary Header Indicator parameter of 3.4.2.3: the service user signals that a secondary header leads the octets it is handing over, and the Packet Assembly Function translates that signal into the flag (3.4.2.3.3, 4.2.2.3, 4.2.2.4). No SecondaryHeader implementation is needed, because nothing here has to interpret the octets. They are counted in the Packet Data Length as part of the user data and written verbatim.

Passing false is the default and clears the flag.

func WithSequenceCount

func WithSequenceCount(n uint16) PacketOption

WithSequenceCount pins the sequence count on the SpacePacket.

Service.SendPacket honors a pinned count: it sends the packet with that count instead of stamping its own. It then resynchronizes the per-APID counter to one past the pinned value, so later unpinned packets on the same APID carry on from there. CCSDS 133.0-B-2 4.1.3.4.3.4 requires the count to stay continuous modulo 16384; leaving the counter where it was would make the APID emit a jump and then a jump back.

func WithSequenceFlags

func WithSequenceFlags(flags uint8) PacketOption

WithSequenceFlags sets the sequence flags on the SpacePacket.

type PacketSendOption added in v0.3.0

type PacketSendOption func(*packetSendConfig)

PacketSendOption configures optional parameters of a SendPacket call.

func WithQoS added in v0.3.0

func WithQoS(qos QoS) PacketSendOption

WithQoS attaches the QoS Requirement of 3.3.2.4 to a SendPacket call. The transport must implement QoSWriter, or the send fails with ErrQoSUnsupported before anything reaches the wire.

type PrimaryHeader

type PrimaryHeader struct {
	Version             uint8  // Packet version number (3 bits, must be 0 for CCSDS v1)
	Type                uint8  // Packet type: 0 = TM, 1 = TC (1 bit)
	SecondaryHeaderFlag uint8  // Indicates if a secondary header is present (1 bit)
	APID                uint16 // Application Process Identifier (11 bits, 0-2047)
	SequenceFlags       uint8  // Sequence flags (2 bits)
	SequenceCount       uint16 // Packet sequence count (14 bits, 0-16383)
	PacketLength        uint16 // Packet data field length minus 1 (16 bits)
}

PrimaryHeader represents the mandatory 6-byte header of a CCSDS space packet.

func (*PrimaryHeader) Decode

func (ph *PrimaryHeader) Decode(data []byte) error

Decode deserializes a 6-byte array into a PrimaryHeader.

func (*PrimaryHeader) Encode

func (ph *PrimaryHeader) Encode() ([]byte, error)

Encode serializes the PrimaryHeader into a 6-byte array.

func (*PrimaryHeader) Humanize

func (ph *PrimaryHeader) Humanize() string

Humanize generates a human-readable representation of the PrimaryHeader.

func (*PrimaryHeader) Validate

func (ph *PrimaryHeader) Validate() error

Validate checks that all fields conform to CCSDS 133.0-B-2.

type QoS added in v0.3.0

type QoS uint8

QoS is the QoS Requirement parameter of the PACKET.request primitive (CCSDS 133.0-B-2 3.3.2.4). It selects a quality-of-service level when an underlying subnetwork offers more than one, for example Type-A (sequence-controlled) versus Type-B (expedited) service on a Telecommand space data link. What each value means belongs to the transport, since the standard leaves the levels themselves to the underlying subnetworks.

QoS is a Packet Service parameter only: the OCTET_STRING.request primitive of 3.4.3.2.2 does not carry one, so SendBytes takes no QoS option.

type QoSWriter added in v0.3.0

type QoSWriter interface {
	WriteQoS(p []byte, qos QoS) (n int, err error)
}

QoSWriter is implemented by transports whose underlying subnetwork offers multiple quality-of-service levels. SendPacket hands the QoS Requirement of a WithQoS send to WriteQoS; a transport without the method cannot honor the requirement, and such sends are refused with ErrQoSUnsupported rather than silently downgraded.

type SecondaryHeader

type SecondaryHeader interface {
	// Encode serializes the secondary header into bytes.
	Encode() ([]byte, error)
	// Decode deserializes bytes into the secondary header.
	Decode([]byte) error
	// Size returns the fixed size in bytes of the encoded secondary header.
	Size() int
}

SecondaryHeader is implemented by mission-specific secondary headers.

The contents are specified by the source end user and passed to the destination by management (CCSDS 133.0-B-2 4.1.4.2.1.4), and the length is mission-defined, but the layout is not a free-for-all. Per 4.1.4.2.1.5 a Packet Secondary Header consists of either a Time Code Field alone, an Ancillary Data Field alone, or a Time Code Field followed by an Ancillary Data Field (in that order) and 4.1.4.2.1.6 requires the chosen option to stay the same for a managed data path through every mission phase.

This interface cannot check that: it sees only octets, so which of the three shapes an implementation produces, and whether it keeps producing the same one, is the implementation's responsibility. What is checked here is structural: the header must be at least one octet and must fit inside the packet data field.

type SendOption

type SendOption func(*sendConfig)

SendOption configures optional parameters for SendBytes.

func WithSendErrorControl

func WithSendErrorControl() SendOption

WithSendErrorControl enables CRC-16-CCITT error control on the outgoing packet. The checksum is computed automatically during encoding.

func WithSendPacketName added in v0.3.0

func WithSendPacketName(name uint16) SendOption

WithSendPacketName pins the same 14 bits as WithSendSequenceCount under the other name the standard gives them.

For a telecommand packet (Packet Type '1') bits 18-31 of the primary header carry either the Packet Sequence Count or a Packet Name (4.1.3.4.3.2), so the two options do the same thing; this one says which meaning is intended.

func WithSendPacketType added in v0.3.0

func WithSendPacketType(packetType uint8) SendOption

WithSendPacketType overrides the Packet Type of the outgoing packet, which otherwise comes from ServiceConfig.PacketType.

Packet Type is a parameter of the OCTET_STRING.request primitive (3.4.3.2.2), so one service can send both telemetry and telecommand octet strings.

func WithSendSecondaryHeader

func WithSendSecondaryHeader(sh SecondaryHeader) SendOption

WithSendSecondaryHeader builds the outgoing packet's secondary header from a SecondaryHeader implementation, which is encoded ahead of the octet string.

It sets the Secondary Header Indicator of 3.4.2.3 as a side effect. Use WithSendSecondaryHeaderIndicator when the octet string you are passing to SendBytes already begins with the header octets.

func WithSendSecondaryHeaderIndicator added in v0.3.0

func WithSendSecondaryHeaderIndicator(present bool) SendOption

WithSendSecondaryHeaderIndicator is the Secondary Header Indicator parameter of the OCTET_STRING.request primitive (3.4.2.3, 3.4.3.2.2).

Per 3.4.2.3.2 the parameter is a signal, not a header: the service user says whether a Packet Secondary Header is contained at the start of the octet string it is handing over, and the Packet Assembly Function sets the Secondary Header Flag to match (3.4.2.3.3, 4.2.2.3). Nothing in this layer has to interpret the octets, so no SecondaryHeader implementation is needed , which is what lets a user who holds a pre-formatted data field send it.

func WithSendSequenceCount added in v0.3.0

func WithSendSequenceCount(n uint16) SendOption

WithSendSequenceCount pins the Packet Sequence Count of the outgoing packet instead of taking the service's next count for the APID.

It is the Packet Sequence Count parameter of the OCTET_STRING.request primitive (3.4.3.2.2). As with WithSequenceCount, the service then carries on from one past the pinned value so the APID's count stays continuous.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service provides both the Packet Service (CCSDS 3.3) and the Octet String Service (CCSDS 3.4) over a shared transport.

A Service is safe for concurrent use. Sends are serialized against each other and receives against each other, so a sequence count is allocated and its packet written as one step and a packet's header and body are read as one step. Sending and receiving proceed independently, which is what a full-duplex transport wants.

Serializing sends is not a convenience: 4.1.3.4.3.4 requires the Packet Sequence Count to be continuous modulo 16384, and allocating counts under a lock while writing outside it would let two senders put their packets on the wire in the opposite order to the counts they were given.

func NewService

func NewService(rw io.ReadWriter, cfg ServiceConfig) *Service

NewService creates a new SPP service over the given transport.

func (*Service) LastDataLoss added in v0.3.0

func (s *Service) LastDataLoss() int

LastDataLoss returns how many packets were missing before the most recently received packet, across all APIDs. Zero means the count was continuous.

This is the Data Loss Indicator of 3.4.2.4, an optional service parameter; the continuity check that produces it is not optional (4.3.2.2).

The value is service-wide: with concurrent receivers, another packet may land between a ReceivePacket and this call, so the figure read here may belong to that packet instead. Use ReceivePacketIndication (or ReceiveBytes, whose Indication carries the same figures) when the loss must be bound to a specific packet.

func (*Service) ReceiveBytes

func (s *Service) ReceiveBytes() (Indication, error)

ReceiveBytes reads a space packet from the transport and delivers it as an Octet String with the indication parameters of 3.4.3.3.2: the APID, the mandatory Secondary Header Indicator, and the optional Data Loss Indicator.

The Octet String is the Packet Data Field, per the Packet Extraction Function of 4.3.2.2: "extract Octet Strings by removing the Packet Primary Header". Any secondary header octets stay at the front of it, which is what the Secondary Header Indicator is there to announce.

When ServiceConfig.DiscardIdle is set, idle packets are dropped and the next real packet is delivered instead.

func (*Service) ReceivePacket

func (s *Service) ReceivePacket() (*SpacePacket, error)

ReceivePacket reads and decodes a complete space packet from the transport.

It also runs the sequence count continuity check of 4.3.2.2 for the packet's APID; the result is available from LastDataLoss and is carried on the Indication that ReceiveBytes returns.

When ServiceConfig.DiscardIdle is set, idle packets are read and dropped and the next real packet is returned.

func (*Service) ReceivePacketIndication added in v0.3.0

func (s *Service) ReceivePacketIndication() (PacketIndication, error)

ReceivePacketIndication reads a space packet and delivers it with the indication parameters of 3.3.3.3.2, including the Packet Loss Indicator for this packet's APID.

Unlike ReceivePacket followed by LastDataLoss, the loss figure here is bound to the returned packet, so concurrent receivers cannot misattribute one packet's gap to another.

func (*Service) ResetContinuity added in v0.3.0

func (s *Service) ResetContinuity()

ResetContinuity forgets every APID's received count, so the next packet on each is treated as a first packet and reports no loss. Use it after a link outage, where the gap across the break carries no information.

func (*Service) SendBytes

func (s *Service) SendBytes(apid uint16, data []byte, opts ...SendOption) error

SendBytes wraps the given data in a space packet and writes it to the transport. The caller provides raw bytes and service parameters; SPP handles packet construction.

func (*Service) SendPacket

func (s *Service) SendPacket(packet *SpacePacket, opts ...PacketSendOption) error

SendPacket writes a pre-built space packet to the transport. It is the PACKET.request primitive of 3.3.3.2; WithQoS supplies the primitive's optional QoS Requirement parameter.

A packet whose count the caller owns is sent with that count untouched, and the service resynchronizes its own counter for the APID to one past it. 4.1.3.4.3.4 requires the count to be continuous modulo 16384; if the counter kept its old value, an APID that sent one such packet would emit a jump out and a jump back (0, 1, 2, 1234, 3, 4) and a receiver would read that as two losses. Two kinds of packet own their count:

  • one built with WithSequenceCount, where the caller said which count to use;
  • one returned by Decode, which already carries the count the originating application assigned it (4.1.3.4.3.3). 3.3.1 requires Packet Service SDUs to be transferred "without further formatting" and the Packet Transfer Function of 4.2.3 does not renumber, so a relay forwards what it received rather than stamping over it.

Any other packet is stamped with the next count for its APID (4.1.3.4.3), which mutates the caller's packet in place.

type ServiceConfig

type ServiceConfig struct {
	PacketType      uint8 // PacketTypeTM or PacketTypeTC
	MaxPacketLength int   // maximum total packet size in octets; default 65542
	ErrorControl    bool  // if true, received packets are expected to contain a trailing CRC; APIDs entries override this per APID

	// NewSecondaryHeader builds a fresh secondary header for each received
	// packet whose Secondary Header Flag is set. Leave it nil to have the
	// header octets delivered at the front of UserData instead.
	//
	// It is a factory rather than a single value because a decoded header
	// belongs to the packet it came from. One shared instance would be
	// overwritten by every later packet, so every delivered packet would end
	// up showing the newest packet's header. It also has to be a factory
	// rather than a type the service copies for itself: the width of a
	// mission's secondary header usually lives in the value (a PUS header
	// reads it from its mission profile), so only the caller can build one
	// that is configured correctly. APIDs entries override this per APID.
	NewSecondaryHeader func() SecondaryHeader

	// DiscardIdle drops received idle packets (APID 0x7FF) instead of
	// delivering them. They are link fill with no application meaning
	// (4.1.3.3.4.4), so a receiving application normally wants them gone.
	DiscardIdle bool

	// APIDs overrides the receive-side handling per APID. CCSDS 133.0-B-2
	// manages the Packet Secondary Header Contents per APID and managed data
	// path (table 5-1), so two APIDs on the same transport may carry
	// different secondary header formats, and, since the error control
	// field is likewise a per-data-path convention, one APID may carry a
	// trailing CRC while another does not.
	//
	// An entry replaces both service-wide settings for its APID: received
	// packets on that APID use the entry's NewSecondaryHeader and
	// ErrorControl instead of the fields above, including their zero values.
	// APIDs without an entry keep the service-wide behavior.
	APIDs map[uint16]APIDConfig
}

ServiceConfig holds configuration for a Service.

type SpacePacket

type SpacePacket struct {
	PrimaryHeader   PrimaryHeader   // The primary header of the space packet
	SecondaryHeader SecondaryHeader // Optional mission-specific secondary header
	UserData        []byte          // User data contained in the packet
	ErrorControl    *uint16         // Optional error control field (e.g., CRC)
	// contains filtered or unexported fields
}

SpacePacket represents a complete space packet as per CCSDS standards.

func Decode

func Decode(data []byte, opts ...DecodeOption) (*SpacePacket, error)

Decode parses a byte slice into a SpacePacket. The returned packet does not retain the input slice; all fields are copied. Trailing bytes beyond the packet length declared in the primary header are ignored, so a buffer may carry more than one packet; use PacketSizer to find the packet boundary.

func NewIdlePacket added in v0.3.0

func NewIdlePacket(fill []byte, options ...PacketOption) (*SpacePacket, error)

NewIdlePacket creates an idle SpacePacket (APID 0x7FF) carrying the given fill data. Per CCSDS 133.0-B-2 4.1.3.3.3.4 the Secondary Header Flag of an idle packet is '0'; its data field content is mission-defined fill (at least 1 octet).

The packet is a telemetry packet by default. Neither 4.1.3.3.2.3 nor 4.1.3.3.4.4 ties the idle APID to a packet type, so a telecommand idle packet is equally legal; pass WithPacketType(PacketTypeTC) for one.

func NewSpacePacket

func NewSpacePacket(apid uint16, packetType uint8, data []byte, options ...PacketOption) (*SpacePacket, error)

NewSpacePacket creates a new SpacePacket instance. Per CCSDS C1/C2: a packet must contain at least a secondary header or user data. User data may be nil/empty if a secondary header is provided, and vice versa.

func NewTCPacket

func NewTCPacket(apid uint16, data []byte, options ...PacketOption) (*SpacePacket, error)

NewTCPacket creates a new telecommand SpacePacket.

func NewTMPacket

func NewTMPacket(apid uint16, data []byte, options ...PacketOption) (*SpacePacket, error)

NewTMPacket creates a new telemetry SpacePacket.

func (*SpacePacket) Encode

func (sp *SpacePacket) Encode() ([]byte, error)

Encode converts the SpacePacket into a byte slice for transmission. The Packet Data Length field is recomputed from the current secondary header, user data, and error control sizes, so mutating those fields after construction cannot produce an inconsistent length on the wire. The packet is validated before encoding.

The Secondary Header Flag decides everything about the secondary header: whether its octets are written and whether its size counts towards the Packet Data Length (4.1.3.3.3.2 and 4.1.3.5.3). A SecondaryHeader attached while the flag is '0' is rejected rather than silently dropped, because counting it and not writing it would declare a data field longer than the packet carries and make the receiver eat into the next packet.

func (*SpacePacket) Humanize

func (sp *SpacePacket) Humanize() string

Humanize generates a human-readable representation of the SpacePacket.

func (*SpacePacket) IsIdle

func (sp *SpacePacket) IsIdle() bool

IsIdle reports whether the packet is an idle packet (APID 0x7FF).

func (*SpacePacket) Validate

func (sp *SpacePacket) Validate() error

Validate checks the integrity and correctness of the SpacePacket.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL