Documentation
¶
Overview ¶
Package tcsc implements the TC Synchronization and Channel Coding sublayer per CCSDS 231.0-B-4 (TC Synchronization and Channel Coding).
This sublayer sits between the TC Data Link Protocol (CCSDS 232.0-B-4) and the physical layer, providing:
- Command Link Transmission Unit (CLTU) wrapping and unwrapping
- BCH(63,56) forward error correction per codeblock
- CCSDS pseudo-randomization for bit transition density assurance
Index ¶
- Constants
- Variables
- func AcquisitionSequence(octets int) []byte
- func BCHDecode(cb [CodeblockBytes]byte) ([]byte, int, error)
- func BCHDecodeWithMode(cb [CodeblockBytes]byte, mode DecodeMode) ([]byte, int, error)
- func BCHEncode(info []byte) ([CodeblockBytes]byte, error)
- func DefaultStartSequence() []byte
- func DefaultTailSequence() []byte
- func GeneratePNSequence(length int) []byte
- func IdleSequence(octets int) []byte
- func Randomize(data []byte) []byte
- func UnwrapCLTU(cltu, startSeq, tailSeq []byte, randomize bool) ([]byte, int, error)
- func UnwrapCLTUWithMode(cltu, startSeq, tailSeq []byte, randomize bool, mode DecodeMode) ([]byte, int, error)
- func UplinkSequence(plop PLOP, cltus [][]byte, acqOctets, idleOctets int) ([]byte, error)
- func WrapCLTU(frameData, startSeq, tailSeq []byte, randomize bool) ([]byte, error)
- type DecodeMode
- type PLOP
Constants ¶
const ( // InfoBytes is the number of information bytes per codeblock. InfoBytes = 7 // CodeblockBytes is the total number of bytes per codeblock // (7 info + 1 parity/filler). CodeblockBytes = 8 )
const ( // DefaultAcquisitionOctets is the recommended minimum acquisition // sequence length (128 bits) per CCSDS 231.0-B-4 clause 7.2.2. DefaultAcquisitionOctets = 16 // DefaultIdleOctets is a practical default idle sequence length // between consecutive CLTUs under PLOP-2, chosen by this library and // not by the standard. // // Clause 7.2.4 constrains nothing here: the idle sequence is "an // unconstrained number of bits", and the PLOP-2 figure shows it as // optional, so zero octets is conformant too. The length a mission // actually uses is a managed parameter (section 8). DefaultIdleOctets = 8 )
Variables ¶
var ( // ErrDataTooShort indicates the provided CLTU is too short to contain // the start sequence, at least one codeblock, and tail sequence. ErrDataTooShort = errors.New("provided data is too short to unwrap") // ErrStartSequenceMismatch indicates the CLTU does not start with the // expected start sequence. ErrStartSequenceMismatch = errors.New("CLTU start sequence mismatch") // ErrTailSequenceMismatch indicates the CLTU does not end with the // expected tail sequence. // // Deprecated: UnwrapCLTU now terminates on the tail sequence or on the // first codeblock that fails to decode, per CCSDS 231.0-B-4, so an // exact tail match is no longer required and this error is not returned. ErrTailSequenceMismatch = errors.New("CLTU tail sequence mismatch") // ErrInvalidCLTULength indicates the CLTU body length (excluding start // and tail sequences) is not a multiple of the codeblock size (8 bytes). // // Deprecated: UnwrapCLTU now tolerates trailing octets after the last // decodable codeblock, per CCSDS 231.0-B-4, and no longer returns this // error. ErrInvalidCLTULength = errors.New("CLTU body length is not a multiple of codeblock size") // ErrUncorrectable indicates that a codeblock contains more errors // than the BCH code can correct (more than 1 bit error). ErrUncorrectable = errors.New("uncorrectable error in codeblock: exceeds BCH correction capability") // ErrEmptyData indicates that empty data was provided for encoding. ErrEmptyData = errors.New("empty data provided") // ErrInvalidInfoLength indicates that BCHEncode was called with a slice // that is not exactly 7 bytes (InfoBytes). ErrInvalidInfoLength = errors.New("BCH info must be exactly 7 bytes") // ErrInvalidPLOP indicates an unknown Physical Layer Operations // Procedure was requested (only PLOP-1 and PLOP-2 exist). ErrInvalidPLOP = errors.New("invalid PLOP: must be PLOP1 or PLOP2") )
Functions ¶
func AcquisitionSequence ¶
AcquisitionSequence returns an acquisition sequence of the given length in octets (alternating bit pattern 0x55). If octets is not positive, DefaultAcquisitionOctets is used.
func BCHDecode ¶
func BCHDecode(cb [CodeblockBytes]byte) ([]byte, int, error)
BCHDecode extracts 7 information bytes from an 8-byte codeblock in SEC mode, correcting up to 1 bit error. Returns the corrected information bytes, the number of corrected bit errors, and any error. Returns ErrUncorrectable if the codeblock has more than 1 bit error.
func BCHDecodeWithMode ¶
func BCHDecodeWithMode(cb [CodeblockBytes]byte, mode DecodeMode) ([]byte, int, error)
BCHDecodeWithMode extracts 7 information bytes from an 8-byte codeblock using the given decoding mode.
In ModeSEC, up to 1 bit error is corrected; more errors return ErrUncorrectable. In ModeTED, no correction is attempted and any non-zero syndrome returns ErrUncorrectable (guaranteed detection of up to 3 bit errors).
func BCHEncode ¶
func BCHEncode(info []byte) ([CodeblockBytes]byte, error)
BCHEncode computes the 7-bit BCH parity for 7 information bytes (56 bits) and returns an 8-byte codeblock. Per CCSDS 231.0-B-4 3.3, the transmitted parity bits are the COMPLEMENT of the LFSR remainder; they occupy the high 7 bits of the 8th byte. The filler bit (LSB) is always '0' per 3.3.2. Returns ErrInvalidInfoLength if info is not exactly 7 bytes.
func DefaultStartSequence ¶
func DefaultStartSequence() []byte
DefaultStartSequence returns the standard CCSDS CLTU start sequence (0xEB90) used to identify the beginning of each CLTU in the bitstream. A fresh copy is returned each call to prevent accidental mutation.
func DefaultTailSequence ¶
func DefaultTailSequence() []byte
DefaultTailSequence returns the standard CCSDS CLTU tail sequence (0xC5C5C5C5C5C5C579) used to mark the end of a CLTU. A fresh copy is returned each call to prevent accidental mutation.
func GeneratePNSequence ¶
GeneratePNSequence produces the CCSDS 231.0-B-4 clause 6.2 pseudo-random sequence using an 8-bit LFSR with polynomial
h(x) = x^8 + x^6 + x^4 + x^3 + x^2 + x + 1
initialized to all 1s. Its first 40 digits are FF 39 9E 5A 68.
The generator lives in internal/pn next to the TM one. The two standards do NOT specify the same randomizer: CCSDS 131.0-B-5 clause 10.4.2 uses a different polynomial and a sequence that opens FF 48 0E C0 9A. Calling the TM generator here would put unintelligible octets on the uplink, so the internal names are qualified by standard and this package uses only the TC pair.
func IdleSequence ¶
IdleSequence returns an idle sequence of the given length in octets (alternating bit pattern 0x55). If octets is not positive, DefaultIdleOctets is used.
func Randomize ¶
Randomize applies CCSDS pseudo-randomization by XOR-ing data with the TC PN (pseudo-noise) sequence. The same operation is used for both randomization and de-randomization since XOR is self-inverse. Returns a new slice; the input is not modified.
That self-inverse property is also why a wrap/unwrap round trip proves nothing here: every sequence round-trips, including a wrong one. What pins this to the standard is TestPNSequenceMatchesTheCCSDSVector.
func UnwrapCLTU ¶
UnwrapCLTU extracts and error-corrects TC Transfer Frame data from a CLTU using SEC decoding. See UnwrapCLTUWithMode.
func UnwrapCLTUWithMode ¶
func UnwrapCLTUWithMode(cltu, startSeq, tailSeq []byte, randomize bool, mode DecodeMode) ([]byte, int, error)
UnwrapCLTUWithMode extracts and error-corrects TC Transfer Frame data from a CLTU. It:
- Validates and strips the start sequence
- Decodes 8-byte codeblocks with BCH(63,56) in the given mode
- Terminates on the tail sequence, or on the first codeblock that fails to decode (per CCSDS 231.0-B-4 the receiver stops at the first rejected codeblock, so bit errors in the tail are tolerated)
- Concatenates the 7-byte info portions
- Optionally de-randomizes the result (fill octets included)
Returns the recovered frame data, total number of corrected bit errors, and any error. If startSeq or tailSeq is nil, CCSDS defaults are used.
Note: The caller must know the original data length to strip any padding added during WrapCLTU, as the padding is not self-describing.
func UplinkSequence ¶
UplinkSequence assembles the symbol stream that a PLOP session places on the physical channel for the given CLTUs.
- PLOP-1: acquisition + CLTU, repeated for each CLTU (the carrier is dropped between CLTUs, so each needs a new acquisition sequence).
- PLOP-2: acquisition + CLTU + idle + CLTU + ... (a single session; idle sequence keeps the channel modulated between CLTUs).
acqOctets and idleOctets select the sequence lengths; values that are not positive fall back to the defaults. Returns ErrEmptyData when no CLTUs are given.
func WrapCLTU ¶
WrapCLTU produces a Command Link Transmission Unit from TC Transfer Frame data. It:
- Pads the data to a multiple of 7 bytes (InfoBytes per codeblock) with 0x55 fill octets
- Optionally applies CCSDS pseudo-randomization to the padded buffer (fill octets included, per CCSDS 231.0-B-4: randomization covers everything between the start and tail sequences)
- Encodes each 7-byte block with BCH(63,56) to produce 8-byte codeblocks
- Prepends the start sequence and appends the tail sequence
If startSeq or tailSeq is nil, the CCSDS defaults are used.
Types ¶
type DecodeMode ¶
type DecodeMode int
DecodeMode selects the BCH decoding mode per CCSDS 231.0-B-4 section 3.
const ( // ModeSEC is Single Error Correction: corrects up to 1 bit error per // codeblock. A 3-bit error pattern can silently miscorrect in this mode. ModeSEC DecodeMode = iota // ModeTED is Triple Error Detection: no correction is attempted, and // any detectable error pattern (up to 3 bit errors guaranteed) is // reported as ErrUncorrectable. ModeTED )
type PLOP ¶
type PLOP int
PLOP identifies a Physical Layer Operations Procedure.
const ( // PLOP1 is PLOP-1 (clause 7.4): the session ends after each CLTU, so each // CLTU is preceded by its own acquisition sequence. PLOP1 PLOP = 1 // PLOP2 is PLOP-2 (clause 7.5): one session carries many CLTUs, separated by // idle sequence. This is the CCSDS-recommended procedure. PLOP2 PLOP = 2 )