Documentation
¶
Overview ¶
Package usdl implements the CCSDS Unified Space Data Link Protocol (USLP) per CCSDS 732.1-B-3.
USLP Transfer Frames carry a Transfer Frame Data Field whose layout is declared in-band by the TFDZ Construction Rules of the TFDF Header. Frames are either non-truncated (full primary header with frame length, flags, and an optional Virtual Channel Frame Count of 0-7 octets) or truncated (a fixed 4-octet header for short telecommands, annex D).
Index ¶
- Constants
- Variables
- func IsIdleFrame(frame *TransferFrame) bool
- type ChannelConfig
- type DataFieldHeader
- type FrameCounter
- type FrameGapDetector
- type FrameOption
- func WithBypassSeqCtrl() FrameOption
- func WithConstructionRule(rule uint8) FrameOption
- func WithInsertZone(data []byte) FrameOption
- func WithOCF(ocf []byte) FrameOption
- func WithPointer(p uint16) FrameOption
- func WithProtCtrlCmd() FrameOption
- func WithSourceOrDest(flag uint8) FrameOption
- func WithUPID(upid uint8) FrameOption
- func WithVCFCount(countLen uint8, count uint64) FrameOption
- func WithoutFECF() FrameOption
- type MAPAccessService
- type MAPOctetStreamService
- type MAPPacketService
- type MasterChannel
- func (mc *MasterChannel) AddFrame(frame *TransferFrame) error
- func (mc *MasterChannel) AddVirtualChannel(vc *VirtualChannel, priority int)
- func (mc *MasterChannel) GetNextFrame() (*TransferFrame, error)
- func (mc *MasterChannel) GetNextFrameOrIdle() (*TransferFrame, error)
- func (mc *MasterChannel) HasPendingFrames() bool
- func (mc *MasterChannel) SCID() uint16
- func (mc *MasterChannel) SetOCFSupplier(supplier func() []byte)
- func (mc *MasterChannel) VCFrameGap() int
- type OIDSequence
- type PacketSizer
- type PhysicalChannel
- type PrimaryHeader
- func (h *PrimaryHeader) Decode(data []byte) error
- func (h *PrimaryHeader) Encode() ([]byte, error)
- func (h *PrimaryHeader) GMAPID() uint32
- func (h *PrimaryHeader) GVCID() uint32
- func (h *PrimaryHeader) Humanize() string
- func (h *PrimaryHeader) MCID() uint32
- func (h *PrimaryHeader) Size() int
- func (h *PrimaryHeader) Validate() error
- type Service
- type ServiceType
- type TransferFrame
- func DecodeTransferFrame(data []byte, fecSize int, insertZoneLen int) (*TransferFrame, error)
- func NewIdleFrame(scid uint16, config ChannelConfig, fill *OIDSequence, ocf []byte) (*TransferFrame, error)
- func NewTransferFrame(scid uint16, vcid, mapid uint8, data []byte, opts ...FrameOption) (*TransferFrame, error)
- func NewTruncatedFrame(scid uint16, vcid, mapid uint8, data []byte, opts ...FrameOption) (*TransferFrame, error)
- type USDLServiceManager
- type VirtualChannel
- type VirtualChannelMultiplexer
Constants ¶
const ( // RulePacketsSpanning ('000'): fixed-length TFDZ of concatenated CCSDS // packets that may span frame boundaries; the First Header Pointer is // required. RulePacketsSpanning uint8 = 0b000 // RuleStartOfSDU ('001'): fixed-length TFDZ holding the start of (or a // complete) MAPA_SDU/VCA_SDU; the Last Valid Octet Pointer is required. RuleStartOfSDU uint8 = 0b001 // RuleContinuingSDU ('010'): fixed-length TFDZ continuing a // MAPA_SDU/VCA_SDU started earlier; the Last Valid Octet Pointer is // required. RuleContinuingSDU uint8 = 0b010 // RuleOctetStream ('011'): variable-length TFDZ carrying a continuous // octet-aligned stream. RuleOctetStream uint8 = 0b011 // RuleStartingSegment ('100'): variable-length TFDZ with the starting // segment of a segmented SDU. RuleStartingSegment uint8 = 0b100 // RuleContinuingSegment ('101'): variable-length TFDZ with a continuing // segment. RuleContinuingSegment uint8 = 0b101 // RuleLastSegment ('110'): variable-length TFDZ with the last segment. RuleLastSegment uint8 = 0b110 // RuleNoSegmentation ('111'): variable-length TFDZ holding complete // SDUs or packets, unsegmented. RuleNoSegmentation uint8 = 0b111 )
TFDZ Construction Rules per CCSDS 732.1-B-3 clause 4.1.4.2.2.2.
const ( // FHPNoPacketStart: for rule '000', no packet starts within this TFDZ // ('all ones', clause 4.1.4.2.4.4). FHPNoPacketStart uint16 = 0xFFFF // LVOPIncomplete: for rules '001'/'010', the SDU does not complete // within this TFDZ ('all ones', clause 4.1.4.2.4.6). LVOPIncomplete uint16 = 0xFFFF )
Special pointer values (CCSDS 732.1-B-3 clause 4.1.4.2.4).
const ( UPIDSpacePackets uint8 = 0 // Space Packets or Encapsulation Packets UPIDCOP1Control uint8 = 1 // COP-1 Control Commands UPIDCOPPControl uint8 = 2 // COP-P Control Commands UPIDUserOctetStream uint8 = 4 // User-defined Octet Stream UPIDMissionSpecific1 uint8 = 5 // Mission Specific Information-1 (one MAPA_SDU) UPIDProx1PseudoPacket1 uint8 = 6 // Proximity-1 Pseudo Packet ID 1 UPIDProx1SPDU uint8 = 7 // Proximity-1 SPDUs UPIDProx1PseudoPacket2 uint8 = 8 // Proximity-1 Pseudo Packet ID 2 UPIDIdle uint8 = 31 // Idle Data (OID frames) )
USLP Protocol Identifiers from the SANA UPID registry (https://sanaregistry.org/r/uslp_protocol_id, CCSDS 732.1-B-3 clause 4.1.4.2.3).
const ( // TruncatedPrimaryHeaderSize is the fixed size of the truncated // primary header (annex D1.3: exactly 4 octets). TruncatedPrimaryHeaderSize = 4 // PrimaryHeaderBaseSize is the size of the non-truncated primary // header before the variable Virtual Channel Frame Count. PrimaryHeaderBaseSize = 7 // MaxVCFCountLen is the largest VCF Count field length in octets // (clause 4.1.2.11, table 4-2). MaxVCFCountLen = 7 )
Primary header sizes.
const DefaultIdleFill byte = 0x55
DefaultIdleFill is the idle fill byte used when ChannelConfig.IdlePattern is empty. It fills the unused tail of fixed-length TFDZs behind the Last Valid Octet Pointer and the body of Encapsulation Idle Packets; that idle pattern is project-specified (clause 4.1.4.3 note 1; a random pattern is preferred) and can be overridden via ChannelConfig.IdlePattern. The TFDZ of an OID frame is NOT filled with this pattern: Clause 4.1.4.1.10 mandates the PN sequence generated by OIDSequence.
const FECSize16 = 2
FECSize16 is the size of the 16-bit Frame Error Control Field (clause 4.1.6.2.2: when present, the FECF occupies the last 16 bits of every Transfer Frame, USLP has no other FECF size).
const MaxTruncatedFrameLen = 32
MaxTruncatedFrameLen is the largest total truncated frame length in octets (annex D1.3.2 note 3: the complete frame must fit within one LDPC(512, 256) codeword; annex D1.4.2.4 caps the TFDZ at 27 octets).
const OCFSize = 4
OCFSize is the size of the Operational Control Field in bytes.
const OIDVCID = 63
OIDVCID is the Virtual Channel ID reserved for Only Idle Data frames (CCSDS 732.1-B-3 clause 4.1.4.1.6: 'all ones').
const TFVN = 12 // 0b1100
TFVN is the USLP Transfer Frame Version Number (CCSDS 732.1-B-3 Clause 4.1.2.2.2: '1100').
Variables ¶
var ( // ErrDataTooShort indicates the provided data is too short for decoding. ErrDataTooShort = errors.New("provided data is too short to decode") // ErrInvalidVersion indicates the TFVN is not 12 (0b1100) for USLP. ErrInvalidVersion = errors.New("invalid version: TFVN must be 12 (0b1100) for USLP") // ErrInvalidSpacecraftID indicates the spacecraft ID is out of range. ErrInvalidSpacecraftID = errors.New("invalid spacecraft ID: must be in range 0-65535 (16 bits)") // ErrInvalidVCID indicates the virtual channel ID is out of range. ErrInvalidVCID = errors.New("invalid virtual channel ID: must be in range 0-63 (6 bits)") // ErrInvalidMAPID indicates the MAP ID is out of range. ErrInvalidMAPID = errors.New("invalid MAP ID: must be in range 0-15 (4 bits)") // ErrInvalidFrameLength indicates the frame length field is out of range. ErrInvalidFrameLength = errors.New("invalid frame length: exceeds maximum of 65536 bytes") // ErrFrameLengthMismatch indicates the decoded frame length field does // not match the length of the delivered frame buffer. ErrFrameLengthMismatch = errors.New("frame length field does not match buffer length") // ErrInvalidVCFCountLen indicates the VCF Count length exceeds 7 octets. ErrInvalidVCFCountLen = errors.New("invalid VCF count length: must be in range 0-7 octets") // ErrInvalidVCFCount indicates the VCF Count does not fit its field width. ErrInvalidVCFCount = errors.New("invalid VCF count: exceeds configured field width") // ErrInvalidHeaderSpare indicates the reserved spare bits of the primary // header are not zero. ErrInvalidHeaderSpare = errors.New("invalid primary header: reserved spare bits must be 00") // ErrTruncatedFrameFields indicates a truncated frame carries fields it // cannot have (insert zone, OCF, FECF, or a pointer-carrying rule). ErrTruncatedFrameFields = errors.New("truncated frame cannot carry insert zone, OCF, FECF, or a pointer") // ErrInvalidFECSize indicates the FECF size is not 0 or 2 octets. The // USLP FECF, when present, is always the 16-bit CRC of clause 4.1.6.2.2. ErrInvalidFECSize = errors.New("invalid FECF size: must be 0 or 2 octets (USLP has only the 16-bit FECF)") // ErrTruncatedFrameTooShort indicates a truncated frame with an empty // TFDZ (annex D1.3.2 note 2: minimum 6 octets in total). ErrTruncatedFrameTooShort = errors.New("truncated frame TFDZ must carry at least one octet (minimum frame length 6)") // ErrTruncatedFrameTooLong indicates a truncated frame over 32 octets // (annex D1.3.2 note 3 and D1.4.2.4). ErrTruncatedFrameTooLong = errors.New("truncated frame exceeds the 32-octet maximum length") // ErrNoOCFSupplier indicates the channel is configured with HasOCF but // no OCF supplier is installed; the OCF content must come from the OCF // service user (clause 4.1.5) rather than being fabricated as zeros. ErrNoOCFSupplier = errors.New("channel requires an OCF but no supplier is set: call SetOCFSupplier") // ErrOctetStreamFixedLength indicates an octet stream was sent on a // fixed-length channel (CCSDS 732.1-B-3 clause 4.2.4.1 forbids it). ErrOctetStreamFixedLength = errors.New("octet stream service requires variable-length transfer frames") // ErrInvalidConstructionRule indicates an invalid TFDZ construction rule. ErrInvalidConstructionRule = errors.New("invalid TFDZ construction rule: must be in range 0-7 (3 bits)") // ErrInvalidPointer indicates the FHP/LVOP is out of range for the TFDZ. ErrInvalidPointer = errors.New("invalid pointer: exceeds data zone length") // ErrCRCMismatch indicates the received CRC does not match the computed CRC. ErrCRCMismatch = errors.New("CRC mismatch: received CRC does not match computed CRC") // ErrDataTooLarge indicates the data field exceeds the maximum frame length. ErrDataTooLarge = errors.New("data field exceeds maximum frame length") // ErrEmptyData indicates that the provided data is empty. ErrEmptyData = errors.New("data cannot be empty") // ErrSizeMismatch indicates the data size does not match the expected fixed size. ErrSizeMismatch = errors.New("data size does not match expected fixed size") // ErrInvalidOCFLength indicates the OCF is not exactly 4 bytes. ErrInvalidOCFLength = errors.New("operational control field must be exactly 4 bytes when present") // ErrInvalidInsertZoneLength indicates the insert zone length is invalid. ErrInvalidInsertZoneLength = errors.New("insert zone length exceeds maximum") // ErrNoFramesAvailable aliases sdl.ErrNoFramesAvailable. ErrNoFramesAvailable = sdl.ErrNoFramesAvailable // ErrBufferFull aliases sdl.ErrBufferFull. ErrBufferFull = sdl.ErrBufferFull // ErrSCIDMismatch indicates the frame SCID does not match the master channel SCID. ErrSCIDMismatch = errors.New("frame SCID does not match master channel SCID") // ErrServiceNotFound aliases sdl.ErrServiceNotFound. ErrServiceNotFound = sdl.ErrServiceNotFound // ErrMasterChannelNotFound aliases sdl.ErrMasterChannelNotFound. ErrMasterChannelNotFound = sdl.ErrMasterChannelNotFound // ErrNoVirtualChannels aliases sdl.ErrNoChannels. ErrNoVirtualChannels = sdl.ErrNoChannels // ErrVirtualChannelNotFound indicates no virtual channel exists for the given VCID. ErrVirtualChannelNotFound = errors.New("virtual channel not found for specified VCID") // ErrDataFieldTooSmall indicates the data field capacity is too small for framing. ErrDataFieldTooSmall = errors.New("data field capacity too small") // ErrNoPacketSizer indicates no PacketSizer has been set on the MAP Packet service. ErrNoPacketSizer = errors.New("no PacketSizer configured: call SetPacketSizer before Receive") // ErrNoMasterChannels aliases sdl.ErrNoMasterChannels. ErrNoMasterChannels = sdl.ErrNoMasterChannels )
Functions ¶
func IsIdleFrame ¶
func IsIdleFrame(frame *TransferFrame) bool
IsIdleFrame reports whether the frame is an Only Idle Data frame. Per CCSDS 732.1-B-3 clause 4.1.4.1.6, OID frames use VCID 63.
Types ¶
type ChannelConfig ¶
type ChannelConfig struct {
FrameLength int // Total frame length in octets (fixed per physical channel; 0 = variable)
HasOCF bool // Whether the Operational Control Field (4 bytes) is carried
HasFECF bool // Whether the 16-bit Frame Error Control Field is present
InsertZoneLen int // Insert zone length in bytes (0 if none)
VCFCountLen uint8 // VCF Count field length in octets (0-7; 0 = no count)
IdlePattern []byte // Idle fill pattern (repeating); empty means DefaultIdleFill
}
ChannelConfig defines the managed parameters of a USLP channel.
IdlePattern is the project-specified idle pattern that fills the unused tail of fixed-length TFDZs behind the Last Valid Octet Pointer and the body of Encapsulation Idle Packets (clause 4.1.4.3 note 1). It does not fill OID frames: their TFDZ carries the mandatory PN sequence (clause 4.1.4.1.10).
func (ChannelConfig) DataFieldCapacity ¶
func (c ChannelConfig) DataFieldCapacity(dfhSize int) int
DataFieldCapacity returns the maximum Transfer Frame Data Zone size for fixed-length frames, given the size of the TFDF header in use (1 octet, or 3 when the construction rule carries a pointer). Fixed-length frames use the full (non-truncated) primary header.
type DataFieldHeader ¶
type DataFieldHeader struct {
ConstructionRule uint8 // 3 bits - TFDZ construction rule
UPID uint8 // 5 bits - USLP Protocol Identifier
Pointer uint16 // 16 bits - FHP (rule '000') or LVOP (rules '001'/'010')
}
DataFieldHeader represents the USLP Transfer Frame Data Field Header (TFDF Header, CCSDS 732.1-B-3 clause 4.1.4.2): one mandatory octet holding the TFDZ Construction Rules (3 bits) and the UPID (5 bits), followed by a 16-bit First Header Pointer / Last Valid Octet Pointer only for the construction rules that require one ('000', '001', '010').
func (*DataFieldHeader) Decode ¶
func (h *DataFieldHeader) Decode(data []byte) error
Decode parses a TFDF header from the start of data.
func (*DataFieldHeader) Encode ¶
func (h *DataFieldHeader) Encode() ([]byte, error)
Encode packs the DataFieldHeader into a byte slice.
func (*DataFieldHeader) HasPointer ¶
func (h *DataFieldHeader) HasPointer() bool
HasPointer reports whether the construction rule carries the 16-bit pointer field (clause 4.1.4.2.4.1: rules '000', '001', and '010' only).
func (*DataFieldHeader) Humanize ¶
func (h *DataFieldHeader) Humanize() string
Humanize returns a human-readable representation of the DataFieldHeader.
func (*DataFieldHeader) Size ¶
func (h *DataFieldHeader) Size() int
Size returns the encoded size of the TFDF header in bytes: 1, or 3 when the construction rule carries a pointer.
func (*DataFieldHeader) Validate ¶
func (h *DataFieldHeader) Validate() error
Validate checks the data field header values.
type FrameCounter ¶
type FrameCounter struct {
// contains filtered or unexported fields
}
FrameCounter manages Virtual Channel Frame Counts per CCSDS 732.1-B-3 Clause 4.1.2.12, keyed by VC and quality of service (clause 4.1.2.12.4-12.5: one sequence-controlled and one expedited count per VC). The count is carried in the primary header's VCF Count field, whose width (0-7 octets) is a managed parameter (clause 4.1.2.11).
func NewFrameCounter ¶
func NewFrameCounter() *FrameCounter
NewFrameCounter creates a new FrameCounter.
func (*FrameCounter) Next ¶
func (fc *FrameCounter) Next(vcid uint8, expedited bool) uint64
Next returns the current frame count for the given VCID and quality of service (expedited = Bypass/Sequence Control Flag set), then increments the counter. Callers mask the value to the managed VCF Count field width.
type FrameGapDetector ¶
type FrameGapDetector struct {
// contains filtered or unexported fields
}
FrameGapDetector tracks per-VC Virtual Channel Frame Counts to detect gaps caused by lost frames (CCSDS 732.1-B-3 clause 4.1.2.12). The count width is the managed VCF Count Length of the channel (clause 4.1.2.11). Sequence- controlled and expedited frames keep separate counts per VC (clause 4.1.2.12.4-12.5), so tracking is keyed by both the VCID and the Bypass/Sequence Control Flag.
func NewFrameGapDetector ¶
func NewFrameGapDetector(countLen uint8) *FrameGapDetector
NewFrameGapDetector creates a detector for the given VCF Count field length in octets (0-7). With a length of zero, no count is carried and Track always reports no gap.
func (*FrameGapDetector) Track ¶
func (d *FrameGapDetector) Track(frame *TransferFrame) int
Track examines the frame's VCF Count and records any gap. Returns the VC gap (0 means no gap or first frame).
func (*FrameGapDetector) VCFrameGap ¶
func (d *FrameGapDetector) VCFrameGap() int
VCFrameGap returns the VC gap detected by the last Track call.
type FrameOption ¶
type FrameOption func(*TransferFrame)
FrameOption configures optional fields on a TransferFrame.
func WithBypassSeqCtrl ¶
func WithBypassSeqCtrl() FrameOption
WithBypassSeqCtrl marks the frame as expedited (bypass flag set).
func WithConstructionRule ¶
func WithConstructionRule(rule uint8) FrameOption
WithConstructionRule sets the TFDZ construction rule.
func WithInsertZone ¶
func WithInsertZone(data []byte) FrameOption
WithInsertZone sets the insert zone data.
func WithOCF ¶
func WithOCF(ocf []byte) FrameOption
WithOCF sets the Operational Control Field. Its presence is signaled by the OCF Flag in the primary header.
func WithPointer ¶
func WithPointer(p uint16) FrameOption
WithPointer sets the First Header Pointer / Last Valid Octet Pointer. It is encoded only for construction rules '000', '001', and '010'.
func WithProtCtrlCmd ¶
func WithProtCtrlCmd() FrameOption
WithProtCtrlCmd marks the TFDF as carrying protocol control commands.
func WithSourceOrDest ¶
func WithSourceOrDest(flag uint8) FrameOption
WithSourceOrDest sets the source-or-destination flag.
func WithVCFCount ¶
func WithVCFCount(countLen uint8, count uint64) FrameOption
WithVCFCount sets the Virtual Channel Frame Count and its field length in octets (0-7).
func WithoutFECF ¶
func WithoutFECF() FrameOption
WithoutFECF omits the Frame Error Control Field. Its presence is a managed parameter of the physical channel (clause 4.1.6.2.1).
type MAPAccessService ¶
type MAPAccessService struct {
// contains filtered or unexported fields
}
MAPAccessService implements the MAP Access service (MAPA) for USLP: transfer of fixed-length MAPA_SDUs.
On fixed-length channels an SDU is carried under construction rule '001' (start) and, when it spans frames, rule '010' (continuation), delimited by the Last Valid Octet Pointer. On variable-length channels each SDU rides alone in a rule '111' frame.
func NewMAPAccessService ¶
func NewMAPAccessService(scid uint16, vcid, mapid uint8, sduSize int, vc *VirtualChannel, config ChannelConfig, counter *FrameCounter) *MAPAccessService
NewMAPAccessService creates a new MAPA service instance.
func (*MAPAccessService) Flush ¶
func (s *MAPAccessService) Flush() error
Flush is a no-op for MAPA service.
func (*MAPAccessService) Receive ¶
func (s *MAPAccessService) Receive() ([]byte, error)
Receive returns the next complete MAPA_SDU, reassembling SDUs that span frames via the construction rules and Last Valid Octet Pointer.
func (*MAPAccessService) Send ¶
func (s *MAPAccessService) Send(data []byte) error
Send transfers one MAPA_SDU of the configured constant length.
func (*MAPAccessService) SetOCFSupplier ¶
func (s *MAPAccessService) SetOCFSupplier(supplier func() []byte)
SetOCFSupplier installs a callback that supplies the 4-octet Operational Control Field (typically a CLCW) for every frame emitted on a channel configured with HasOCF. Without a supplier such a channel refuses to emit frames (ErrNoOCFSupplier) rather than fabricating an all-zero Type-1 report (clause 4.1.5).
type MAPOctetStreamService ¶
type MAPOctetStreamService struct {
// contains filtered or unexported fields
}
MAPOctetStreamService implements the MAP Octet Stream service (MAPO) for USLP: a continuous octet-aligned stream under construction rule '011'. Per CCSDS 732.1-B-3 clause 4.2.4.1 an octet stream is carried only in variable-length Transfer Frames.
func NewMAPOctetStreamService ¶
func NewMAPOctetStreamService(scid uint16, vcid, mapid uint8, vc *VirtualChannel, config ChannelConfig, counter *FrameCounter) *MAPOctetStreamService
NewMAPOctetStreamService creates a new MAPO service instance.
func (*MAPOctetStreamService) Flush ¶
func (s *MAPOctetStreamService) Flush() error
Flush is a no-op for MAPO service.
func (*MAPOctetStreamService) Receive ¶
func (s *MAPOctetStreamService) Receive() ([]byte, error)
Receive retrieves the next frame's data field.
func (*MAPOctetStreamService) Send ¶
func (s *MAPOctetStreamService) Send(data []byte) error
Send emits the supplied octets in one rule '011' frame.
func (*MAPOctetStreamService) SetOCFSupplier ¶
func (s *MAPOctetStreamService) SetOCFSupplier(supplier func() []byte)
SetOCFSupplier installs a callback that supplies the 4-octet Operational Control Field (typically a CLCW) for every frame emitted on a channel configured with HasOCF. Without a supplier such a channel refuses to emit frames (ErrNoOCFSupplier) rather than fabricating an all-zero Type-1 report (clause 4.1.5).
type MAPPacketService ¶
type MAPPacketService struct {
// contains filtered or unexported fields
}
MAPPacketService implements the MAP Packet service (MAPP) for USLP.
On fixed-length channels, packets are concatenated into fixed-length TFDZs under construction rule '000' with the First Header Pointer for boundary recovery; a partially filled final TFDZ is completed with an Encapsulation Idle Packet (clause 4.1.4.3.4). On variable-length channels, each Send emits one frame under rule '111' (No Segmentation).
func NewMAPPacketService ¶
func NewMAPPacketService(scid uint16, vcid, mapid uint8, vc *VirtualChannel, config ChannelConfig, counter *FrameCounter) *MAPPacketService
NewMAPPacketService creates a new MAPP service instance.
func (*MAPPacketService) Flush ¶
func (s *MAPPacketService) Flush() error
Flush completes any remaining buffered packet data with an Encapsulation Idle Packet and emits the final frame (clause 4.1.4.3.4).
func (*MAPPacketService) Receive ¶
func (s *MAPPacketService) Receive() ([]byte, error)
Receive extracts the next complete packet from frame data.
Rule '000' fill is exactly delimited: spare TFDZ space carries Encapsulation Idle Packets (clause 4.1.4.3.4), which stripIdleEncap removes. No pattern heuristic is applied to user data, so payloads that happen to look like an idle pattern are delivered intact.
func (*MAPPacketService) Send ¶
func (s *MAPPacketService) Send(data []byte) error
Send accepts one packet. On variable-length channels it emits one frame per packet; on fixed-length channels it buffers and emits full frames, with Flush() emitting the final partial frame.
func (*MAPPacketService) SetOCFSupplier ¶
func (s *MAPPacketService) SetOCFSupplier(supplier func() []byte)
SetOCFSupplier installs a callback that supplies the 4-octet Operational Control Field (typically a CLCW) for every frame emitted on a channel configured with HasOCF. Without a supplier such a channel refuses to emit frames (ErrNoOCFSupplier) rather than fabricating an all-zero Type-1 report (clause 4.1.5).
func (*MAPPacketService) SetPacketSizer ¶
func (s *MAPPacketService) SetPacketSizer(sizer PacketSizer)
SetPacketSizer configures the PacketSizer used by Receive() to detect packet boundaries.
type MasterChannel ¶
type MasterChannel struct {
// contains filtered or unexported fields
}
MasterChannel manages USLP Transfer Frames for a Master Channel identified by SCID.
func NewMasterChannel ¶
func NewMasterChannel(scid uint16, config ChannelConfig) *MasterChannel
NewMasterChannel creates a new Master Channel for the given spacecraft ID.
func (*MasterChannel) AddFrame ¶
func (mc *MasterChannel) AddFrame(frame *TransferFrame) error
AddFrame routes an inbound frame to the appropriate Virtual Channel.
func (*MasterChannel) AddVirtualChannel ¶
func (mc *MasterChannel) AddVirtualChannel(vc *VirtualChannel, priority int)
AddVirtualChannel registers a Virtual Channel with this Master Channel.
func (*MasterChannel) GetNextFrame ¶
func (mc *MasterChannel) GetNextFrame() (*TransferFrame, error)
GetNextFrame retrieves the next frame from the multiplexer.
func (*MasterChannel) GetNextFrameOrIdle ¶
func (mc *MasterChannel) GetNextFrameOrIdle() (*TransferFrame, error)
GetNextFrameOrIdle returns the next frame or an OID idle frame if none is available. OID frames exist only on fixed-length physical channels. Their TFDZ is drawn from the master channel's persistent PN sequence, which is never restarted across frames (clause 4.1.4.1.10).
func (*MasterChannel) HasPendingFrames ¶
func (mc *MasterChannel) HasPendingFrames() bool
HasPendingFrames checks if any Virtual Channel has pending frames.
func (*MasterChannel) SCID ¶
func (mc *MasterChannel) SCID() uint16
SCID returns the Spacecraft Identifier for this Master Channel.
func (*MasterChannel) SetOCFSupplier ¶
func (mc *MasterChannel) SetOCFSupplier(supplier func() []byte)
SetOCFSupplier installs a callback that supplies the 4-octet Operational Control Field (typically a CLCW) for the OID frames GetNextFrameOrIdle generates on a channel configured with HasOCF. Without a supplier such a channel refuses to build idle frames (ErrNoOCFSupplier) rather than fabricating an all-zero Type-1 report.
func (*MasterChannel) VCFrameGap ¶
func (mc *MasterChannel) VCFrameGap() int
VCFrameGap returns the VC gap from the last AddFrame call.
type OIDSequence ¶
type OIDSequence = pn.OIDSequence
OIDSequence generates the mandatory Pseudo Noise (PN) sequence that fills the TFDZ of OID Transfer Frames (CCSDS 732.1-B-3 clause 4.1.4.1.10, annex H): a 32-cell Fibonacci-form Linear Feedback Shift Register with polynomial D0 + D1 + D2 + D22 + D32, initialized to the 'all ones' state at device start-up and never restarted for subsequent frames. The first octets of the stream are FF FF FF FF 6D B6 D8 61 ... (annex H). It is safe for concurrent use.
TM mandates the same generator (CCSDS 132.0-B-3 clause 4.1.4.6.2), so the implementation is shared with pkg/tmdl rather than copied.
func NewOIDSequence ¶
func NewOIDSequence() *OIDSequence
NewOIDSequence returns a PN generator in the 'all ones' start-up state. Keep one generator per physical channel for the life of the device; the sequence must not be restarted across OID frames (clause 4.1.4.1.10.1).
type PacketSizer ¶
type PacketSizer = sdl.PacketSizer
PacketSizer returns the total length in bytes of the packet starting at data[0], or -1 if the data is too short to determine length.
type PhysicalChannel ¶
type PhysicalChannel struct {
Name string
// contains filtered or unexported fields
}
PhysicalChannel represents a single USLP physical communication link.
func NewPhysicalChannel ¶
func NewPhysicalChannel(name string, config ChannelConfig) *PhysicalChannel
NewPhysicalChannel creates a physical channel with the given configuration.
func (*PhysicalChannel) AddFrame ¶
func (pc *PhysicalChannel) AddFrame(frame *TransferFrame) error
AddFrame demultiplexes an inbound frame to the appropriate Master Channel.
func (*PhysicalChannel) AddMasterChannel ¶
func (pc *PhysicalChannel) AddMasterChannel(mc *MasterChannel, priority int)
AddMasterChannel registers a Master Channel with a priority weight.
func (*PhysicalChannel) GetNextFrame ¶
func (pc *PhysicalChannel) GetNextFrame() (*TransferFrame, error)
GetNextFrame selects the next frame for transmission.
func (*PhysicalChannel) HasPendingFrames ¶
func (pc *PhysicalChannel) HasPendingFrames() bool
HasPendingFrames checks if any Master Channel has pending frames.
type PrimaryHeader ¶
type PrimaryHeader struct {
TFVN uint8 // 4 bits - Transfer Frame Version Number (must be 12 = 0b1100)
SCID uint16 // 16 bits - Spacecraft Identifier
SourceOrDest uint8 // 1 bit - 0=SCID is source, 1=SCID is destination
VCID uint8 // 6 bits - Virtual Channel Identifier (0-63)
MAPID uint8 // 4 bits - Multiplexer Access Point Identifier (0-15)
EndOfFPH bool // 1 bit - End of Frame Primary Header flag (truncated header)
FrameLength uint16 // 16 bits - total frame octets minus 1 (non-truncated only)
BypassSeqCtrl bool // 1 bit - Bypass/Sequence Control flag (1 = expedited)
ProtCtrlCmd bool // 1 bit - Protocol Control Command flag (1 = protocol control)
OCFFlag bool // 1 bit - Operational Control Field present
VCFCountLen uint8 // 3 bits - VCF Count field length in octets (0-7)
VCFCount uint64 // 0-56 bits - Virtual Channel Frame Count
}
PrimaryHeader represents the USLP Transfer Frame Primary Header.
Bit layout (CCSDS 732.1-B-3 clause 4.1.2):
Byte 0: TFVN[3:0] | SCID[15:12] Byte 1: SCID[11:4] Byte 2: SCID[3:0] | SourceOrDest | VCID[5:3] Byte 3: VCID[2:0] | MAPID[3:0] | EndOfFPH
EndOfFPH = 1 marks the truncated header, which is exactly these 4 octets (annex D). A non-truncated header (EndOfFPH = 0) continues:
Bytes 4-5: Frame Length (total octets - 1) Byte 6: Bypass/SeqCtrl | ProtCtrlCmd | spares(2) | OCFFlag | VCFCountLen[2:0] Bytes 7+: VCF Count (VCFCountLen octets, big-endian)
func (*PrimaryHeader) Decode ¶
func (h *PrimaryHeader) Decode(data []byte) error
Decode parses a byte slice into the PrimaryHeader.
func (*PrimaryHeader) Encode ¶
func (h *PrimaryHeader) Encode() ([]byte, error)
Encode packs the PrimaryHeader fields into a byte slice.
func (*PrimaryHeader) GMAPID ¶
func (h *PrimaryHeader) GMAPID() uint32
GMAPID returns the Global MAP Identifier (GVCID + MAP ID).
func (*PrimaryHeader) GVCID ¶
func (h *PrimaryHeader) GVCID() uint32
GVCID returns the Global Virtual Channel Identifier (MCID + VCID).
func (*PrimaryHeader) Humanize ¶
func (h *PrimaryHeader) Humanize() string
Humanize returns a human-readable representation of the PrimaryHeader.
func (*PrimaryHeader) MCID ¶
func (h *PrimaryHeader) MCID() uint32
MCID returns the Master Channel Identifier (TFVN + SCID).
func (*PrimaryHeader) Size ¶
func (h *PrimaryHeader) Size() int
Size returns the encoded size of the primary header in bytes.
func (*PrimaryHeader) Validate ¶
func (h *PrimaryHeader) Validate() error
Validate checks that header values are within their bit-field widths.
type ServiceType ¶
type ServiceType int
ServiceType identifies the USLP service carried on a MAP channel.
const ( MAPP ServiceType = iota // MAP Packet Service MAPA // MAP Access Service MAPO // MAP Octet Stream Service )
type TransferFrame ¶
type TransferFrame struct {
Header PrimaryHeader
InsertZone []byte // optional, fixed length per physical channel
DataFieldHeader DataFieldHeader // TFDF header
DataField []byte // Transfer Frame Data Zone (TFDZ)
OCF []byte // 4 bytes when present (signaled by OCFFlag)
FECF []byte // Frame Error Control Field (16-bit CRC)
HasFECF bool // FECF present (managed per physical channel)
}
TransferFrame represents a USLP Transfer Frame per CCSDS 732.1-B-3.
Layout: PrimaryHeader | InsertZone? | TFDF Header | TFDZ | OCF? | FECF?
Truncated frames (annex D) carry only the 4-octet primary header, a 1-octet TFDF header, and the TFDZ: no insert zone, OCF, or FECF.
func DecodeTransferFrame ¶
func DecodeTransferFrame(data []byte, fecSize int, insertZoneLen int) (*TransferFrame, error)
DecodeTransferFrame parses a byte slice into a USLP Transfer Frame.
fecSize is the managed FECF presence for the physical channel: 0 (absent) or FECSize16 (clause 4.1.6.2.2: the FECF, when present, is the last 16 bits of the frame). insertZoneLen is the managed insert zone length (0 if none). OCF presence is signaled in-band by the OCF Flag. Truncated frames (EndOfFPH set) carry no insert zone, OCF, or FECF, regardless of the managed parameters.
func NewIdleFrame ¶
func NewIdleFrame(scid uint16, config ChannelConfig, fill *OIDSequence, ocf []byte) (*TransferFrame, error)
NewIdleFrame creates an OID (Only Idle Data) Transfer Frame per CCSDS 732.1-B-3 clause 4.1.4.1: VCID 63, MAP ID 0, construction rule '001' with the Last Valid Octet Pointer set to the last TFDZ octet, UPID 'Idle Data', and a TFDZ filled from the mandatory PN sequence (clause 4.1.4.1.10). OID frames exist only on fixed-length physical channels.
fill is the channel's persistent PN generator; passing nil starts a fresh sequence for this frame only, which is fine for a single frame but violates the never-restarted rule across frames, long-lived senders must keep one OIDSequence (MasterChannel does). ocf supplies the 4-octet Operational Control Field when config.HasOCF is set; with HasOCF and no OCF the frame is refused rather than fabricating an all-zero report.
func NewTransferFrame ¶
func NewTransferFrame(scid uint16, vcid, mapid uint8, data []byte, opts ...FrameOption) (*TransferFrame, error)
NewTransferFrame creates a new non-truncated USLP Transfer Frame. The frame length field is computed from the frame contents, the OCF flag from OCF presence, and the FECF (present by default) from the encoded frame.
func NewTruncatedFrame ¶
func NewTruncatedFrame(scid uint16, vcid, mapid uint8, data []byte, opts ...FrameOption) (*TransferFrame, error)
NewTruncatedFrame creates a truncated USLP Transfer Frame (annex D): a 4-octet primary header, a 1-octet TFDF header with construction rule '111' (No Segmentation), and the TFDZ. Truncated frames carry no insert zone, OCF, or FECF, and are allowed only on variable-length virtual channels. The TFDZ must hold at least one octet (annex D1.3.2 note 2: minimum total length 6 octets) and at most 27 (annex D1.4.2.4: maximum total length 32 octets).
func (*TransferFrame) Encode ¶
func (f *TransferFrame) Encode() ([]byte, error)
Encode converts the USLP Transfer Frame to a byte slice.
The frame length field and the Frame Error Control Field are refreshed from the frame's current contents on every call, so changes made after construction are always covered. Use EncodeWithoutFECF to build a frame with a deliberately invalid FECF.
func (*TransferFrame) EncodeWithoutFECF ¶
func (f *TransferFrame) EncodeWithoutFECF() ([]byte, error)
EncodeWithoutFECF serializes the frame excluding the Frame Error Control Field. Use it to build frames with a deliberately invalid FECF; Encode always writes a correct one.
func (*TransferFrame) Humanize ¶
func (f *TransferFrame) Humanize() string
Humanize returns a human-readable representation of the TransferFrame.
type USDLServiceManager ¶
type USDLServiceManager = sdl.ServiceManager[ServiceType, *TransferFrame]
USDLServiceManager manages multiple USLP services and Master Channels.
func NewUSDLServiceManager ¶
func NewUSDLServiceManager() *USDLServiceManager
NewUSDLServiceManager creates a new USLP Service Manager.
type VirtualChannel ¶
type VirtualChannel struct {
*sdl.Channel[*TransferFrame]
// contains filtered or unexported fields
}
VirtualChannel is a frame buffer for a single USLP virtual channel. It owns the MAP demultiplexer for the up-to-16 MAP channels it carries (clause 4.3): services pull their own MAP's frames via NextForMAP, and frames for other MAP channels are held for their services rather than lost.
func NewVirtualChannel ¶
func NewVirtualChannel(vcid uint8, bufferSize int) *VirtualChannel
NewVirtualChannel creates a new USLP Virtual Channel with the given VCID and buffer capacity.
func (*VirtualChannel) NextForMAP ¶
func (vc *VirtualChannel) NextForMAP(mapid uint8) (*TransferFrame, error)
NextForMAP returns the next frame for the given MAP channel. Frames of other MAP IDs pulled from the shared VC buffer are queued for their own services instead of being discarded (clause 4.3 MAP demultiplexing); OID frames carry no service data and are dropped.
type VirtualChannelMultiplexer ¶
type VirtualChannelMultiplexer = sdl.Multiplexer[*TransferFrame]
VirtualChannelMultiplexer is a weighted round-robin frame scheduler for USLP Virtual Channels.
func NewMultiplexer ¶
func NewMultiplexer() *VirtualChannelMultiplexer
NewMultiplexer creates a new USLP Virtual Channel multiplexer.