cop

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: 3 Imported by: 0

Documentation

Overview

Package cop implements the Communications Operation Procedure-1 (COP-1) per CCSDS 232.1-B-2.

COP-1 provides reliable TC frame delivery over the space link using:

  • FOP-1 (Flight Operations Procedure) on the ground side
  • FARM-1 (Frame Acceptance and Reporting Mechanism) on the spacecraft side
  • CLCW (Communications Link Control Word) for return-link status reporting

Index

Constants

View Source
const (
	// TT0 raises an Alert when T1 expires with the transmission limit
	// reached.
	TT0 = 0
	// TT1 suspends the AD service when T1 expires with the transmission
	// limit reached, allowing a later Resume.
	TT1 = 1
)

Timeout types for the T1 timer expiry with the transmission limit reached (CCSDS 232.1-B-2 5.2.6).

Variables

View Source
var (
	// ErrDataTooShort indicates the provided data is too short for CLCW decoding.
	ErrDataTooShort = errors.New("provided data is too short to decode CLCW")

	// ErrInvalidCLCWType indicates the control word type is not 0.
	ErrInvalidCLCWType = errors.New("invalid CLCW: control word type must be 0")

	// ErrInvalidCLCWVersion indicates the CLCW version is not 0.
	ErrInvalidCLCWVersion = errors.New("invalid CLCW: version must be 00")

	// ErrFOPLockout indicates FOP-1 received a CLCW with the Lockout flag set.
	ErrFOPLockout = errors.New("FOP-1: lockout detected, ground must issue unlock")

	// ErrFOPWindowFull indicates the FOP-1 send window is full.
	ErrFOPWindowFull = errors.New("FOP-1: send window full, waiting for acknowledgment")

	// ErrFARMReject indicates FARM-1 rejected a frame (out of window).
	ErrFARMReject = errors.New("FARM-1: frame rejected, sequence number outside window")

	// ErrFARMLockout indicates FARM-1 is in lockout state.
	ErrFARMLockout = errors.New("FARM-1: lockout state, requires unlock command")

	// ErrFARMWait indicates FARM-1 discarded an in-sequence frame because
	// no frame buffer is available (Wait state).
	ErrFARMWait = errors.New("FARM-1: wait state, no frame buffer available")

	// ErrInvalidFrameType indicates a frame with Bypass=0 and Control
	// Command=1, an invalid type per CCSDS 232.0-B-4 4.1.2.3.
	ErrInvalidFrameType = errors.New("invalid frame type: Bypass=0 with Control Command=1")

	// ErrInvalidControlCommand indicates a Type-BC frame whose data field
	// is neither Unlock (0x00) nor Set V(R) (0x82 0x00 <V(R)>).
	ErrInvalidControlCommand = errors.New("invalid control command: expected Unlock (0x00) or Set V(R) (0x82 0x00 vr)")

	// ErrFOPNotActive indicates the AD service is not active (S1-S3).
	ErrFOPNotActive = errors.New("FOP-1: AD service not active")

	// ErrFOPNotInitial indicates a directive that is only valid in the
	// Initial state (S6) was issued elsewhere.
	ErrFOPNotInitial = errors.New("FOP-1: directive only valid in the Initial state")

	// ErrFOPNotSuspended indicates Resume was issued with no suspended
	// AD service.
	ErrFOPNotSuspended = errors.New("FOP-1: AD service is not suspended")

	// ErrFOPInvalidNR indicates a CLCW whose N(R) is outside
	// NN(R)..V(S). The ground and spacecraft have lost synchronization.
	ErrFOPInvalidNR = errors.New("FOP-1: invalid N(R) in CLCW (alert NNR)")

	// ErrFOPSynch indicates a CLCW inconsistent with the FOP state
	// (retransmit requested with nothing outstanding).
	ErrFOPSynch = errors.New("FOP-1: CLCW inconsistent with FOP state (alert SYNCH)")

	// ErrFOPInvalidCLCW indicates an invalid CLCW flag combination
	// (Wait without Retransmit).
	ErrFOPInvalidCLCW = errors.New("FOP-1: invalid CLCW flag combination (alert CLCW)")

	// ErrFOPLimit indicates the transmission limit was reached
	// without progress (alert LIMIT).
	ErrFOPLimit = errors.New("FOP-1: transmission limit reached (alert LIMIT)")

	// ErrFOPTimeout indicates T1 expired during initialisation
	// (alert T1).
	ErrFOPTimeout = errors.New("FOP-1: T1 timer expired (alert T1)")

	// ErrFOPSuspended indicates T1 expired with timeout type TT1 and the
	// AD service was suspended; ResumeAD can continue it.
	ErrFOPSuspended = errors.New("FOP-1: AD service suspended (timeout type 1)")

	// ErrFOPInvalidWindow indicates an invalid FOP sliding window width
	// (valid: 1..255).
	ErrFOPInvalidWindow = errors.New("FOP-1: invalid sliding window width (valid 1-255)")

	// ErrFOPInvalidLimit indicates an invalid transmission limit
	// (valid: 1..255).
	ErrFOPInvalidLimit = errors.New("FOP-1: invalid transmission limit (valid 1-255)")

	// ErrFOPInvalidT1 indicates a negative T1 initial value.
	ErrFOPInvalidT1 = errors.New("FOP-1: invalid T1 initial value")

	// ErrFOPInvalidTimeoutType indicates a timeout type other than TT0
	// or TT1.
	ErrFOPInvalidTimeoutType = errors.New("FOP-1: invalid timeout type (valid 0 or 1)")
)

Functions

This section is empty.

Types

type AlertReason added in v0.3.0

type AlertReason int

AlertReason identifies why FOP-1 raised an Alert and went to Initial.

const (
	AlertNone      AlertReason = iota
	AlertLimit                 // transmission limit reached
	AlertLockout               // CLCW Lockout flag seen
	AlertSynch                 // CLCW inconsistent with FOP state
	AlertNNR                   // invalid N(R) in CLCW
	AlertCLCW                  // invalid CLCW flag combination
	AlertT1                    // T1 timeout with no retransmission allowed
	AlertTerminate             // Terminate AD Service directive
)

func (AlertReason) String added in v0.4.0

func (r AlertReason) String() string

String says why the Alert was raised.

The reasons are the ones CCSDS 232.1-B-2 clause 5.2 names when FOP-1 leaves the Active state for Initial. AlertNone reads as "none" rather than as an empty string, so a log line saying which alert is pending never looks like a missing field.

type CLCW

type CLCW struct {
	ControlWordType   uint8 // 1 bit  - always 0 for CLCW
	Version           uint8 // 2 bits - always 00
	StatusField       uint8 // 3 bits - mission-specific status
	COPInEffect       uint8 // 2 bits - 01=COP-1
	VirtualChannelID  uint8 // 6 bits - VC this CLCW reports on
	Reserved          uint8 // 2 bits - spare
	NoRFAvailableFlag bool  // 1 bit
	NoBitLockFlag     bool  // 1 bit
	LockoutFlag       bool  // 1 bit  - FARM-1 lockout state
	WaitFlag          bool  // 1 bit  - FARM-1 wait state
	RetransmitFlag    bool  // 1 bit  - FARM-1 retransmit request
	FARMBCounter      uint8 // 2 bits - Type-B frame counter (0-3)
	ReportValue       uint8 // 8 bits - V(R): next expected frame sequence number
}

CLCW represents the Communications Link Control Word (4 bytes / 32 bits). Per CCSDS 232.1-B-2 Section 4.2.

The CLCW is generated by FARM-1 on the spacecraft and transported back to the ground via the TM Operational Control Field (OCF).

Bit layout:

Byte 0: [CWType:1][Version:2][Status:3][COP:2]
Byte 1: [VCID:6][Reserved:2]
Byte 2: [NoRF:1][NoBitLock:1][Lockout:1][Wait:1][Retransmit:1][FARMB:2][spare:1]
Byte 3: [ReportValue:8]

func (*CLCW) Decode

func (c *CLCW) Decode(data []byte) error

Decode parses a 4-byte slice into the CLCW.

func (*CLCW) Encode

func (c *CLCW) Encode() ([]byte, error)

Encode packs the CLCW into a 4-byte slice.

func (*CLCW) Humanize

func (c *CLCW) Humanize() string

Humanize returns a human-readable representation of the CLCW.

func (*CLCW) Validate

func (c *CLCW) Validate() error

Validate checks the CLCW fields.

type FARM

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

FARM implements the Frame Acceptance and Reporting Mechanism (FARM-1) per CCSDS 232.1-B-2 Section 6.

FARM-1 runs on the spacecraft side. It validates incoming TC frame sequence numbers and generates CLCW status reports for the return link.

The sliding window W is split into a positive half PW and a negative half NW (PW = NW = W/2, W even, per CCSDS 232.1-B-2 6.1.5):

  • N(S) == V(R): frame accepted, V(R) incremented (E1), unless no buffer is available, in which case the frame is discarded and the Wait and Retransmit flags are set (E2).
  • V(R) < N(S) <= V(R)+PW-1: inside the positive window but out of sequence, discarded, Retransmit flag set (E3).
  • V(R)-NW <= N(S) < V(R): inside the negative window, a duplicate of an already-accepted frame. Discarded silently, no flags change (E4).
  • Otherwise: outside both windows, Lockout is entered (E5). The Retransmit flag is left untouched.

func NewFARM

func NewFARM(vcid uint8, windowWidth uint8) *FARM

NewFARM creates a new FARM-1 instance for the given VCID.

windowWidth is the sliding window W. Per CCSDS 232.1-B-2 it must be an even value in 2..254 (PW = NW = W/2); out-of-range values are clamped and odd values rounded down. By default buffer accounting is disabled (the Wait state is never entered); use SetBuffers to enable it.

func (*FARM) GenerateCLCW

func (f *FARM) GenerateCLCW() *CLCW

GenerateCLCW returns a CLCW reflecting the current FARM-1 state.

func (*FARM) ProcessFrame

func (f *FARM) ProcessFrame(bypassFlag, controlCommandFlag uint8, frameSeqNum uint8, dataField []byte) (bool, error)

ProcessFrame validates an incoming TC frame per FARM-1 rules. Returns whether the frame was accepted.

Frame types per CCSDS 232.0-B-4 4.1.2.3:

  • Type-AD (bypass=0, cc=0): sequence-controlled data, checked against V(R) and the sliding window.
  • Type-BD (bypass=1, cc=0): expedited data, always accepted; increments the FARM-B counter (E6).
  • Type-BC (bypass=1, cc=1): control command. dataField must contain Unlock (0x00) or Set V(R) (0x82 0x00 <V(R)>). Both increment the FARM-B counter. Unlock clears the Lockout, Wait, and Retransmit flags and leaves V(R) untouched (E7). Set V(R) sets V(R) from the directive payload and clears Wait and Retransmit; in Lockout it is accepted but changes nothing except FARM-B (E8).
  • bypass=0, cc=1 is an invalid type and is discarded.

bypassFlag: 0=Type-A, 1=Type-B controlCommandFlag: 0=data, 1=control command frameSeqNum: N(S) from the frame header (ignored for Type-B frames) dataField: the frame data field (used only for Type-BC frames)

func (*FARM) ReleaseBuffer added in v0.3.0

func (f *FARM) ReleaseBuffer()

ReleaseBuffer signals that the higher layer has consumed one accepted frame, freeing its buffer. Leaving the buffer-exhausted condition clears the Wait flag (E10: "buffer release" signal from the higher procedures).

func (*FARM) SetBuffers added in v0.3.0

func (f *FARM) SetBuffers(n int)

SetBuffers configures the number of free frame buffers. When a Type-A frame is accepted, one buffer is consumed; when none are free, the FARM enters the Wait state (E2) and discards in-sequence frames until ReleaseBuffer is called. A negative n disables buffer accounting.

func (*FARM) State

func (f *FARM) State() FARMState

State returns the current FARM-1 state.

func (*FARM) VR

func (f *FARM) VR() uint8

VR returns the current V(R) value.

type FARMState

type FARMState int

FARMState represents the FARM-1 state machine state.

const (
	FARMOpen    FARMState = iota // S1: accepting frames in window
	FARMWait                     // S2: wait state (no buffer available)
	FARMLockout                  // S3: lockout (requires Unlock BC frame)
)

func (FARMState) String added in v0.4.0

func (s FARMState) String() string

String names the state.

Lockout is the one worth reading in a log: a FARM-1 in lockout accepts nothing until an Unlock BC frame arrives, and setting V(R) will not clear it (CCSDS 232.1-B-2 clause 6.1).

type FOP

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

FOP implements the Flight Operations Procedure (FOP-1) per CCSDS 232.1-B-2 Section 5.

FOP-1 runs on the ground side. It manages Type-A (sequence-controlled) frame transmission with sliding window acknowledgment via CLCW, plus the BC (control command) and BD (expedited) transmit paths.

The T1 timer is caller-driven: the FOP holds no wall clock. Configure the timer with SetT1Initial (in whatever unit the caller ticks in) and advance it with Tick. A T1 initial of 0 (the default) disables the timer.

Usage:

  1. Create with NewFOP
  2. Start the AD service with Initialize() or one of the Initiate directives
  3. Call TransmitFrame() to queue Type-A frames
  4. Call GetNextFrame() to get the next frame to send, with its N(S)
  5. Call ProcessCLCW() when a CLCW arrives on the TM return link
  6. Call Tick() as time passes to drive the T1 timer

func NewFOP

func NewFOP(scid uint16, vcid uint8, windowWidth uint8) *FOP

NewFOP creates a new FOP-1 instance in the Initial state (S6).

windowWidth is the FOP sliding window (1..255; 0 is clamped to 1). The transmission limit defaults to 255, the timeout type to TT0, and the T1 timer starts disabled (initial value 0).

func (*FOP) GetNextFrame

func (f *FOP) GetNextFrame() ([]byte, uint8, bool)

GetNextFrame returns the next frame to transmit along with the sequence number N(S) assigned to it (0 for BC and BD frames). Priority order: the pending BC frame, then BD frames, then AD frames in queue order. The third return value is false when nothing is pending.

func (*FOP) Initialize

func (f *FOP) Initialize(initialVS uint8)

Initialize starts the AD service without CLCW check, setting V(S) to the given value first. It is the "Set V(S)" plus "Initiate AD Service (without CLCW check)" directive pair.

func (*FOP) InitiateADWithCLCWCheck added in v0.3.0

func (f *FOP) InitiateADWithCLCWCheck() error

InitiateADWithCLCWCheck starts the AD service once a clean CLCW (Lockout=0, Wait=0, Retransmit=0) arrives (E24). V(S) and NN(R) are then taken from the CLCW report value. Starts T1. Only valid in the Initial state.

func (*FOP) InitiateADWithSetVR added in v0.3.0

func (f *FOP) InitiateADWithSetVR(vr uint8, bcFrame []byte) error

InitiateADWithSetVR starts the AD service by transmitting the given encoded BC Set V(R) frame (E27). vr must match the V(R) value carried by the frame; V(S) and NN(R) are set to it once a CLCW with Lockout=0 and Report Value == vr confirms the directive. Only valid in the Initial state.

func (*FOP) InitiateADWithUnlock added in v0.3.0

func (f *FOP) InitiateADWithUnlock(bcFrame []byte) error

InitiateADWithUnlock starts the AD service by transmitting the given encoded BC Unlock frame (E25). The frame is served by GetNextFrame and retransmitted on T1 expiry until a CLCW with Lockout=0 confirms it. Only valid in the Initial state.

func (*FOP) InitiateADWithoutCLCW added in v0.3.0

func (f *FOP) InitiateADWithoutCLCW() error

InitiateADWithoutCLCW starts the AD service immediately (E23). Only valid in the Initial state.

func (*FOP) LastAlert added in v0.3.0

func (f *FOP) LastAlert() AlertReason

LastAlert returns the reason of the most recent Alert.

func (*FOP) PendingCount

func (f *FOP) PendingCount() int

PendingCount returns the number of unacknowledged AD frames.

func (*FOP) ProcessCLCW

func (f *FOP) ProcessCLCW(clcw *CLCW) error

ProcessCLCW processes a CLCW received on the TM return link. Acknowledges frames, checks N(R) validity, handles the Lockout, Wait, and Retransmit flags, and completes any initiate-in-progress.

func (*FOP) ResumeAD added in v0.3.0

func (f *FOP) ResumeAD() error

ResumeAD resumes a suspended AD service (E30-E33), restoring the state the machine was suspended from and restarting T1. Returns ErrFOPNotSuspended when the service is not suspended.

func (*FOP) SetSlidingWindow added in v0.3.0

func (f *FOP) SetSlidingWindow(w uint8) error

SetSlidingWindow sets the FOP sliding window width K (E36). Valid values are 1..255.

func (*FOP) SetT1Initial added in v0.3.0

func (f *FOP) SetT1Initial(ticks int) error

SetT1Initial sets the T1 timer initial value in caller tick units (E37). A value of 0 disables the timer.

func (*FOP) SetTimeoutType added in v0.3.0

func (f *FOP) SetTimeoutType(tt int) error

SetTimeoutType sets the timeout type (E39): TT0 alerts on T1 expiry with the transmission limit reached; TT1 suspends the AD service.

func (*FOP) SetTransmissionLimit added in v0.3.0

func (f *FOP) SetTransmissionLimit(n uint8) error

SetTransmissionLimit sets the transmission limit (E38). Valid values are 1..255.

func (*FOP) SetVS added in v0.3.0

func (f *FOP) SetVS(vs uint8) error

SetVS sets V(S) (and NN(R)) to the given value (E35). Only valid in the Initial state with no suspended service.

func (*FOP) State

func (f *FOP) State() FOPState

State returns the current FOP-1 state.

func (*FOP) SuspendState added in v0.3.0

func (f *FOP) SuspendState() int

SuspendState returns the suspend state SS (0 = not suspended, 1..4 = suspended from S1..S4).

func (*FOP) TerminateAD added in v0.3.0

func (f *FOP) TerminateAD()

TerminateAD terminates the AD service (E29): all queues are purged and the machine returns to Initial. Any suspend state is cleared.

func (*FOP) Tick added in v0.3.0

func (f *FOP) Tick(n int) error

Tick advances the caller-driven clock by n units. When the T1 timer is running and reaches zero, the timer-expiry events fire (E16-E18 and E104): retransmission while the transmission limit allows it, then either an Alert(T1) (timeout type TT0) or a suspension of the AD service (timeout type TT1). Returns the error corresponding to a raised alert, or nil.

func (*FOP) TimerRunning added in v0.3.0

func (f *FOP) TimerRunning() bool

TimerRunning reports whether the T1 timer is currently running.

func (*FOP) TransmitBDFrame added in v0.3.0

func (f *FOP) TransmitBDFrame(encodedFrame []byte) error

TransmitBDFrame queues an encoded Type-BD (expedited) frame. BD frames bypass sequence control and are served by GetNextFrame ahead of AD frames. Allowed in any state.

func (*FOP) TransmitFrame

func (f *FOP) TransmitFrame(encodedFrame []byte) error

TransmitFrame queues an encoded Type-AD frame for transmission. The frame is assigned the next sequence number V(S). Returns ErrFOPWindowFull if the sliding window is exhausted and ErrFOPNotActive when the AD service is not active (S1-S3).

func (*FOP) VS

func (f *FOP) VS() uint8

VS returns the current V(S) value.

type FOPState

type FOPState int

FOPState represents the FOP-1 state machine state per CCSDS 232.1-B-2 Section 5.1 (table 5-1).

const (
	FOPActive                FOPState = iota // S1: Active
	FOPRetransmitWithoutWait                 // S2: Retransmit without Wait
	FOPRetransmitWithWait                    // S3: Retransmit with Wait
	FOPInitialisingWithoutBC                 // S4: Initialising without BC Frame
	FOPInitialisingWithBC                    // S5: Initialising with BC Frame
	FOPInitial                               // S6: Initial
)

func (FOPState) String added in v0.4.0

func (s FOPState) String() string

String names the state, using the names of table 5-1.

type SentFrame

type SentFrame struct {
	SequenceNum uint8
	Data        []byte // encoded frame bytes for retransmission
}

SentFrame tracks a transmitted Type-A frame awaiting acknowledgment.

Jump to

Keyboard shortcuts

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