Documentation
¶
Overview ¶
Package sle implements the foundation of the CCSDS Space Link Extension transfer services: the Internet SLE Protocol One transport, a BER codec for SLE protocol data units, ISP1 credentials, and the association handshake.
SLE is how ground systems move space link data between each other. A mission control centre opens a TCP connection to a ground station and either receives telemetry (frames, channel frames, operational control fields) or sends telecommand transmission units. This library already produces and consumes exactly those payloads: CADUs from pkg/tmsc, CLTUs from pkg/tcsc, CLCWs from pkg/cop. SLE is the wire between ground systems.
The standard numbers ¶
The SLE suite is easy to misattribute, so for the record:
CCSDS 913.1-B-2 ISP1, the transport this package implements CCSDS 911.1-B-5 Return All Frames CCSDS 911.2-B-4 Return Channel Frames CCSDS 911.5-B-4 Return Operational Control Fields CCSDS 912.1-B-5 Forward CLTU
CCSDS 914.0-M-2 is the SLE Application Program Interface, a Recommended Practice rather than a Blue Book, and is not a wire specification.
Three design decisions ¶
First, this package owns no goroutines and no timers. Every codec is pure and the association state machine is caller-pumped, the same contract as pkg/cop's FOP-1: you feed it inbound messages and ask what to send. ISP1 has a heartbeat and a dead factor; this package tells you when a heartbeat is due and when a peer has gone silent, and your scheduler acts on it. Actual TCP I/O is yours.
Second, the BER codec here is a deliberate subset. Go's encoding/asn1 is DER-oriented and cannot round-trip SLE PDUs: it rejects the context-specific CHOICE tagging the SLE modules rely on. Rather than take a dependency, this package carries just enough BER to encode and decode what SLE actually sends, developed against the ASN.1 modules in the service specifications. It emits definite lengths only, and accepts the indefinite form on decode, because real providers emit it.
Third, ISP1 credentials hash with SHA-256, per CCSDS 913.1-B-2 clause 3.1.2.3. SHA-1 belonged to the previous issue of the standard. A 20-octet legacy digest still decodes (no other length but 20 or 32 does) but it cannot be verified, because this package does not implement the superseded scheme: verification requires SHA-256, and only SHA-256 is ever generated.
What is here ¶
The transport and the handshake: TML message framing, the context and heartbeat messages, BER, credentials, and BIND, UNBIND and PEER-ABORT, including the OBJECT IDENTIFIER form of the service instance identifier and the primitive [104] PEER-ABORT encoding. On top of that, the four transfer services themselves: RAF, RCF, ROCF and FCLTU, each as a caller-pumped user machine and a provider. On the provider side, Production runs the transfer buffer and the production status of clause 3.1.9 and annex B, and Complex serves several service instances and routes an inbound BIND between them. GET-PARAMETER decodes and answers cleanly, and the per-service parameter sets are named: all 50 alternatives across the four services, with integer values read and structured ones left as raw BER. See docs/content/conformance/sle.md for the row-by-row conformance picture.
Index ¶
- Constants
- Variables
- func AppendAntennaId(dst []byte, a AntennaId) []byte
- func AppendCltuLastOk(dst []byte, c CltuLastOk) []byte
- func AppendCltuLastProcessed(dst []byte, c CltuLastProcessed) []byte
- func AppendConditionalTime(dst []byte, c ConditionalTime) []byte
- func AppendControlWordType(dst []byte, c ControlWordType) []byte
- func AppendCredentialsChoice(dst []byte, c *Credentials) ([]byte, error)
- func AppendElement(dst []byte, class uint8, constructed bool, tag uint32, content []byte) []byte
- func AppendGVCID(dst []byte, g GVCID) ([]byte, error)
- func AppendInteger(dst []byte, v int64) []byte
- func AppendLength(dst []byte, length int) []byte
- func AppendNull(dst []byte) []byte
- func AppendObjectIdentifier(dst []byte, oid []uint32) ([]byte, error)
- func AppendOctetString(dst []byte, v []byte) []byte
- func AppendPDU(dst []byte, tag uint32, content []byte) []byte
- func AppendSequence(dst []byte, content []byte) []byte
- func AppendTag(dst []byte, class uint8, constructed bool, tag uint32) []byte
- func AppendTaggedInteger(dst []byte, tag uint32, v int64) []byte
- func AppendTimeChoice(dst []byte, t Time) []byte
- func AppendVisibleString(dst []byte, v string) []byte
- func WriteMessage(w io.Writer, m *Message) error
- type Acknowledgement
- type AntennaId
- type ApplicationIdentifier
- type Association
- func (a *Association) Abort(diagnostic PeerAbortDiagnostic, now time.Time) *PeerAbort
- func (a *Association) AbortDiagnostic() *PeerAbortDiagnostic
- func (a *Association) Bind(now time.Time, randomNumber int32, serviceType ApplicationIdentifier, ...) (*BindInvocation, error)
- func (a *Association) Bound() bool
- func (a *Association) CheckPeerCredentials(c *Credentials, now time.Time) error
- func (a *Association) ContextMessage(now time.Time) *Message
- func (a *Association) HandleBindInvocation(b *BindInvocation, now time.Time, randomNumber int32) (*BindReturn, error)
- func (a *Association) HandleBindReturn(b *BindReturn, now time.Time) error
- func (a *Association) HandleContextMessage(body []byte, now time.Time) error
- func (a *Association) HandlePeerAbort(p *PeerAbort, now time.Time)
- func (a *Association) HandleUnbindInvocation(u *UnbindInvocation, now time.Time, randomNumber int32) (*UnbindReturn, error)
- func (a *Association) HandleUnbindReturn(u *UnbindReturn, now time.Time) error
- func (a *Association) HandleUrgentData(octet byte, now time.Time) *PeerAbort
- func (a *Association) HeartbeatDue(now time.Time) bool
- func (a *Association) MakeCredentials(now time.Time, randomNumber int32) (*Credentials, error)
- func (a *Association) NextHeartbeat() time.Time
- func (a *Association) PeerDead(now time.Time) bool
- func (a *Association) RecordReceived(now time.Time)
- func (a *Association) RecordSent(now time.Time)
- func (a *Association) Role() Role
- func (a *Association) ServiceType() ApplicationIdentifier
- func (a *Association) State() AssociationState
- func (a *Association) Unbind(now time.Time, randomNumber int32, reason UnbindReason) (*UnbindInvocation, error)
- func (a *Association) Version() uint16
- type AssociationConfig
- type AssociationState
- type AuthenticationLevel
- type BindDiagnostic
- type BindInvocation
- type BindReturn
- type CltuIdentification
- type CltuLastOk
- type CltuLastProcessed
- type CltuNotificationKind
- type CltuStatus
- type Complex
- func (c *Complex) Abort()
- func (c *Complex) Add(config InstanceConfig) (*Instance, error)
- func (c *Complex) DueInstances(now time.Time) []*Instance
- func (c *Complex) Humanize() string
- func (c *Complex) Instance(name string) (*Instance, error)
- func (c *Complex) Instances() []*Instance
- func (c *Complex) Len() int
- func (c *Complex) NextDeadline() (time.Time, bool)
- func (c *Complex) Route(bind *BindInvocation) (*Instance, BindDiagnostic, error)
- type ConditionalTime
- type ContextMessage
- type ControlWordKind
- type ControlWordType
- type Credentials
- type Decoder
- type DeliveryMode
- func (d DeliveryMode) AllowsDiscard() bool
- func (d DeliveryMode) AllowsPastStartTime() bool
- func (d DeliveryMode) AllowsPeriodicStatusReport() bool
- func (d DeliveryMode) IsForward() bool
- func (d DeliveryMode) IsOnline() bool
- func (d DeliveryMode) IsReturn() bool
- func (d DeliveryMode) RequiresBackpressure() bool
- func (d DeliveryMode) String() string
- func (d DeliveryMode) Valid() bool
- type Diagnostics
- type Element
- func (e *Element) Bool() (bool, error)
- func (e *Element) Copy() []byte
- func (e *Element) Int64() (int64, error)
- func (e *Element) IsContext(tag uint32) bool
- func (e *Element) IsUniversal(tag uint8) bool
- func (e *Element) ObjectIdentifier() ([]uint32, error)
- func (e *Element) String() string
- func (e *Element) Uint64() (uint64, error)
- type EventInvocationId
- type FCLTUAsyncNotifyInvocation
- type FCLTUProductionStatus
- type FCLTUProvider
- func (c FCLTUProvider) Association() *Association
- func (c FCLTUProvider) DeliveryMode() DeliveryMode
- func (p *FCLTUProvider) ExpectedCltuIdentification() (CltuIdentification, bool)
- func (p *FCLTUProvider) HandlePDU(data []byte, now time.Time) (*FCLTUProviderEvent, error)
- func (c FCLTUProvider) HandlePeerAbort(p *PeerAbort, now time.Time)
- func (p *FCLTUProvider) HandleStartInvocation(s *FCLTUStartInvocation, answer *FCLTUStartReturn, now time.Time, ...) error
- func (p *FCLTUProvider) HandleTransferDataInvocation(t *FCLTUTransferDataInvocation, accept bool, ...) error
- func (c FCLTUProvider) Kind() ServiceKind
- func (c FCLTUProvider) NextPDU() ([]byte, bool)
- func (c FCLTUProvider) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
- func (c FCLTUProvider) Pending() int
- func (p *FCLTUProvider) SendAsyncNotify(n *FCLTUAsyncNotifyInvocation, now time.Time) error
- func (c FCLTUProvider) State() ServiceState
- type FCLTUProviderEvent
- type FCLTUStartDiagnostic
- type FCLTUStartInvocation
- type FCLTUStartReturn
- type FCLTUStatusReportInvocation
- type FCLTUThrowEventDiagnostic
- type FCLTUThrowEventInvocation
- type FCLTUThrowEventReturn
- type FCLTUTransferDataDiagnostic
- type FCLTUTransferDataInvocation
- type FCLTUTransferDataReturn
- type FCLTUUser
- func (c FCLTUUser) Association() *Association
- func (c FCLTUUser) DeliveryMode() DeliveryMode
- func (u *FCLTUUser) HandlePDU(data []byte, now time.Time) (*FCLTUUserEvent, error)
- func (c FCLTUUser) HandlePeerAbort(p *PeerAbort, now time.Time)
- func (u *FCLTUUser) HandleStartReturn(r *FCLTUStartReturn) error
- func (u *FCLTUUser) HandleThrowEventReturn(r *FCLTUThrowEventReturn) error
- func (u *FCLTUUser) HandleTransferDataReturn(r *FCLTUTransferDataReturn) error
- func (c FCLTUUser) Kind() ServiceKind
- func (u *FCLTUUser) NextCltuIdentification() (CltuIdentification, bool)
- func (u *FCLTUUser) NextEventInvocationId() EventInvocationId
- func (c FCLTUUser) NextPDU() ([]byte, bool)
- func (c FCLTUUser) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
- func (c FCLTUUser) Pending() int
- func (u *FCLTUUser) Start(now time.Time, randomNumber int32, first CltuIdentification) (InvokeId, error)
- func (c FCLTUUser) State() ServiceState
- func (u *FCLTUUser) ThrowEvent(now time.Time, randomNumber int32, event uint16, qualifier []byte) (InvokeId, EventInvocationId, error)
- func (u *FCLTUUser) TransferData(now time.Time, randomNumber int32, cltu []byte, ...) (InvokeId, CltuIdentification, error)
- type FCLTUUserEvent
- type FrameQuality
- type GVCID
- type GetParameterDiagnostic
- type GetParameterInvocation
- type GetParameterReturn
- type Instance
- type InstanceConfig
- type InvokeId
- type LockStatus
- type LockStatusReport
- type Message
- type MessageType
- type NotificationKind
- type OperationType
- type PDU
- type ParameterName
- type PeerAbort
- type PeerAbortDiagnostic
- type Production
- func (p *Production) Abort()
- func (p *Production) Backpressure(now time.Time) bool
- func (p *Production) Capacity() int
- func (p *Production) Counters() (released, discarded int)
- func (p *Production) Deadline() (time.Time, bool)
- func (p *Production) Due(now time.Time) bool
- func (p *Production) Expired(now time.Time) bool
- func (p *Production) Humanize() string
- func (p *Production) Insert(frame *RAFTransferDataInvocation, now time.Time) (due bool, err error)
- func (p *Production) InsertNotification(notification *SyncNotifyInvocation, now time.Time) (due bool, err error)
- func (p *Production) Pending() int
- func (p *Production) Release() RAFTransferBuffer
- func (p *Production) SetHalted() (*SyncNotifyInvocation, bool)
- func (p *Production) SetInterrupted() (*SyncNotifyInvocation, bool)
- func (p *Production) SetRunning() (*SyncNotifyInvocation, bool)
- func (p *Production) Status() ProductionStatus
- func (p *Production) Stop() RAFTransferBuffer
- type ProductionConfig
- type ProductionStatus
- type RAFProvider
- func (c RAFProvider) Association() *Association
- func (c RAFProvider) DeliveryMode() DeliveryMode
- func (p *RAFProvider) HandlePDU(data []byte, now time.Time) (*RAFProviderEvent, error)
- func (c RAFProvider) HandlePeerAbort(p *PeerAbort, now time.Time)
- func (p *RAFProvider) HandleStartInvocation(s *RAFStartInvocation, answer *RAFStartReturn, now time.Time, ...) error
- func (c RAFProvider) Kind() ServiceKind
- func (c RAFProvider) NextPDU() ([]byte, bool)
- func (c RAFProvider) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
- func (c RAFProvider) Pending() int
- func (p *RAFProvider) SendTransferBuffer(buffer RAFTransferBuffer, now time.Time) error
- func (c RAFProvider) State() ServiceState
- type RAFProviderEvent
- type RAFStartDiagnostic
- type RAFStartInvocation
- type RAFStartReturn
- type RAFStatusReportInvocation
- type RAFTransferBuffer
- type RAFTransferDataInvocation
- type RAFUser
- func (c RAFUser) Association() *Association
- func (c RAFUser) DeliveryMode() DeliveryMode
- func (u *RAFUser) HandlePDU(data []byte, now time.Time) (*RAFUserEvent, error)
- func (c RAFUser) HandlePeerAbort(p *PeerAbort, now time.Time)
- func (u *RAFUser) HandleStartReturn(r *RAFStartReturn) error
- func (c RAFUser) Kind() ServiceKind
- func (c RAFUser) NextPDU() ([]byte, bool)
- func (c RAFUser) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
- func (c RAFUser) Pending() int
- func (u *RAFUser) Start(now time.Time, randomNumber int32, start, stop ConditionalTime, ...) (InvokeId, error)
- func (c RAFUser) State() ServiceState
- type RAFUserEvent
- type RCFProvider
- func (c RCFProvider) Association() *Association
- func (c RCFProvider) DeliveryMode() DeliveryMode
- func (c RCFProvider) HandlePeerAbort(p *PeerAbort, now time.Time)
- func (p *RCFProvider) HandleStartInvocation(s *RCFStartInvocation, answer *RCFStartReturn, now time.Time, ...) error
- func (c RCFProvider) Kind() ServiceKind
- func (c RCFProvider) NextPDU() ([]byte, bool)
- func (c RCFProvider) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
- func (c RCFProvider) Pending() int
- func (p *RCFProvider) SendTransferBuffer(buffer RCFTransferBuffer, now time.Time) error
- func (c RCFProvider) State() ServiceState
- type RCFStartDiagnostic
- type RCFStartInvocation
- type RCFStartReturn
- type RCFStatusReportInvocation
- type RCFTransferBuffer
- type RCFTransferBufferEntry
- type RCFTransferDataInvocation
- type RCFUser
- func (c RCFUser) Association() *Association
- func (c RCFUser) DeliveryMode() DeliveryMode
- func (u *RCFUser) HandlePDU(data []byte, now time.Time) (*RCFUserEvent, error)
- func (c RCFUser) HandlePeerAbort(p *PeerAbort, now time.Time)
- func (u *RCFUser) HandleStartReturn(r *RCFStartReturn) error
- func (c RCFUser) Kind() ServiceKind
- func (c RCFUser) NextPDU() ([]byte, bool)
- func (c RCFUser) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
- func (c RCFUser) Pending() int
- func (u *RCFUser) Start(now time.Time, randomNumber int32, start, stop ConditionalTime, channel GVCID) (InvokeId, error)
- func (c RCFUser) State() ServiceState
- type RCFUserEvent
- type ROCFProvider
- func (c ROCFProvider) Association() *Association
- func (c ROCFProvider) DeliveryMode() DeliveryMode
- func (c ROCFProvider) HandlePeerAbort(p *PeerAbort, now time.Time)
- func (p *ROCFProvider) HandleStartInvocation(s *ROCFStartInvocation, answer *ROCFStartReturn, now time.Time, ...) error
- func (c ROCFProvider) Kind() ServiceKind
- func (c ROCFProvider) NextPDU() ([]byte, bool)
- func (c ROCFProvider) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
- func (c ROCFProvider) Pending() int
- func (p *ROCFProvider) SendTransferBuffer(buffer ROCFTransferBuffer, now time.Time) error
- func (c ROCFProvider) State() ServiceState
- type ROCFStartDiagnostic
- type ROCFStartInvocation
- type ROCFStartReturn
- type ROCFStatusReportInvocation
- type ROCFTransferBuffer
- type ROCFTransferBufferEntry
- type ROCFTransferDataInvocation
- type ROCFUser
- func (c ROCFUser) Association() *Association
- func (c ROCFUser) DeliveryMode() DeliveryMode
- func (u *ROCFUser) HandlePDU(data []byte, now time.Time) (*ROCFUserEvent, error)
- func (c ROCFUser) HandlePeerAbort(p *PeerAbort, now time.Time)
- func (u *ROCFUser) HandleStartReturn(r *ROCFStartReturn) error
- func (c ROCFUser) Kind() ServiceKind
- func (c ROCFUser) NextPDU() ([]byte, bool)
- func (c ROCFUser) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
- func (c ROCFUser) Pending() int
- func (u *ROCFUser) Start(now time.Time, randomNumber int32, start, stop ConditionalTime, channel GVCID, ...) (InvokeId, error)
- func (c ROCFUser) State() ServiceState
- type ROCFUserEvent
- type ReportRequestKind
- type RequestedFrameQuality
- type Role
- type ScheduleStatusReportDiagnostic
- type ScheduleStatusReportInvocation
- type ScheduleStatusReportReturn
- type ServiceConfig
- type ServiceInstanceAttribute
- type ServiceInstanceIdentifier
- type ServiceKind
- type ServiceParameter
- type ServiceProvider
- func (c ServiceProvider) Association() *Association
- func (c ServiceProvider) DeliveryMode() DeliveryMode
- func (p *ServiceProvider) HandleBindInvocation(b *BindInvocation, now time.Time, randomNumber int32) error
- func (p *ServiceProvider) HandleGetParameterInvocation(g *GetParameterInvocation, parameter []byte, now time.Time, randomNumber int32) error
- func (c ServiceProvider) HandlePeerAbort(p *PeerAbort, now time.Time)
- func (p *ServiceProvider) HandleScheduleStatusReportInvocation(s *ScheduleStatusReportInvocation, accept bool, ...) error
- func (p *ServiceProvider) HandleStopInvocation(s *StopInvocation, accept bool, diagnostic Diagnostics, now time.Time, ...) error
- func (p *ServiceProvider) HandleUnbindInvocation(u *UnbindInvocation, now time.Time, randomNumber int32) error
- func (c ServiceProvider) Kind() ServiceKind
- func (c ServiceProvider) NextPDU() ([]byte, bool)
- func (c ServiceProvider) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
- func (c ServiceProvider) Pending() int
- func (p *ServiceProvider) SendStatusReport(report interface{ ... }, now time.Time) error
- func (c ServiceProvider) State() ServiceState
- type ServiceState
- type ServiceUser
- func (c ServiceUser) Association() *Association
- func (u *ServiceUser) Bind(now time.Time, randomNumber int32) error
- func (c ServiceUser) DeliveryMode() DeliveryMode
- func (u *ServiceUser) GetParameter(parameter int, now time.Time, randomNumber int32) (InvokeId, error)
- func (u *ServiceUser) HandleBindReturn(b *BindReturn, now time.Time) error
- func (u *ServiceUser) HandleGetParameterReturn(r *GetParameterReturn) error
- func (c ServiceUser) HandlePeerAbort(p *PeerAbort, now time.Time)
- func (u *ServiceUser) HandleScheduleStatusReportReturn(r *ScheduleStatusReportReturn) error
- func (u *ServiceUser) HandleStopReturn(a *Acknowledgement) error
- func (u *ServiceUser) HandleUnbindReturn(r *UnbindReturn, now time.Time) error
- func (c ServiceUser) Kind() ServiceKind
- func (c ServiceUser) NextPDU() ([]byte, bool)
- func (u *ServiceUser) Outstanding() map[InvokeId]OperationType
- func (c ServiceUser) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
- func (c ServiceUser) Pending() int
- func (u *ServiceUser) ScheduleStatusReport(kind ReportRequestKind, cycle uint16, now time.Time, randomNumber int32) (InvokeId, error)
- func (c ServiceUser) State() ServiceState
- func (u *ServiceUser) Stop(now time.Time, randomNumber int32) (InvokeId, error)
- func (u *ServiceUser) Unbind(now time.Time, randomNumber int32, reason UnbindReason) error
- type SlduStatusNotification
- type StopInvocation
- type SyncNotifyInvocation
- type Time
- type TransferBufferEntry
- type UnbindInvocation
- type UnbindReason
- type UnbindReturn
- type UpdateMode
- type UplinkStatus
Constants ¶
const ( // ClassUniversal is the class of the built-in ASN.1 types. ClassUniversal uint8 = 0x00 // ClassApplication is the application class. ClassApplication uint8 = 0x40 // ClassContext is the context-specific class, which SLE uses for every // CHOICE alternative and every tagged field. ClassContext uint8 = 0x80 // ClassPrivate is the private class. ClassPrivate uint8 = 0xC0 )
Tag classes, per X.690 clause 8.1.2.2.
const ( TagBoolean uint8 = 1 TagInteger uint8 = 2 TagBitString uint8 = 3 TagOctetString uint8 = 4 TagNull uint8 = 5 TagObjectIdentifier uint8 = 6 TagEnumerated uint8 = 10 TagSequence uint8 = 16 TagSet uint8 = 17 TagVisibleString uint8 = 26 )
Universal tag numbers SLE uses.
const ( // FrameVersionTM is a TM Transfer Frame, called Version 1. FrameVersionTM uint8 = 0 // FrameVersionAOS is an AOS Transfer Frame, called Version 2. FrameVersionAOS uint8 = 1 // FrameVersionUSLP is a USLP Transfer Frame, called Version 4. FrameVersionUSLP uint8 = 12 )
Transfer frame version numbers as a GVCID carries them, from the GvcId SEQUENCE of CCSDS 911.2-B-4 annex A.
Note USLP is 12, not 4. The value is the four-bit Transfer Frame Version Number as it appears on the wire ('1100' binary) rather than the "Version 4" the protocol is called.
const ( MinReportingCycle = 2 MaxReportingCycle = 600 )
MinReportingCycle and MaxReportingCycle bound a periodic reporting cycle: ReportingCycle ::= INTEGER (2 .. 600), in seconds.
const ( // DigestSizeSHA256 is what this package generates. DigestSizeSHA256 = 32 // DigestSizeSHA1 is the legacy size, accepted on receive only. DigestSizeSHA1 = 20 )
Digest sizes, per clause 3.2.3 note 2.
const ( TagFCLTUBindInvocation uint32 = 100 TagFCLTUBindReturn uint32 = 101 TagFCLTUUnbindInvocation uint32 = 102 TagFCLTUUnbindReturn uint32 = 103 TagFCLTUPeerAbortInvocation uint32 = 104 TagFCLTUStartInvocation uint32 = 0 TagFCLTUStartReturn uint32 = 1 TagFCLTUStopInvocation uint32 = 2 TagFCLTUStopReturn uint32 = 3 TagFCLTUScheduleStatusReportInvocation uint32 = 4 TagFCLTUScheduleStatusReportReturn uint32 = 5 TagFCLTUGetParameterInvocation uint32 = 6 TagFCLTUGetParameterReturn uint32 = 7 TagFCLTUThrowEventInvocation uint32 = 8 TagFCLTUThrowEventReturn uint32 = 9 TagFCLTUTransferDataInvocation uint32 = 10 TagFCLTUTransferDataReturn uint32 = 11 TagFCLTUAsyncNotifyInvocation uint32 = 12 TagFCLTUStatusReportInvocation uint32 = 13 )
FCLTU PDU tags, from the CltuUserToProviderPdu and CltuProviderToUserPdu CHOICEs of annex A2.4 and A2.5.
These are not the return services' numbers. Tags [8] and [9] are THROW-EVENT here, where RAF uses them for TRANSFER-BUFFER and STATUS-REPORT, and FCLTU's STATUS-REPORT sits up at [13]. Decoding an FCLTU PDU with a return-service table would silently name the wrong operation, which is why DecodePDU takes a ServiceKind.
const ( TagRAFBindInvocation uint32 = 100 TagRAFBindReturn uint32 = 101 TagRAFUnbindInvocation uint32 = 102 TagRAFUnbindReturn uint32 = 103 TagRAFPeerAbortInvocation uint32 = 104 TagRAFStartInvocation uint32 = 0 TagRAFStartReturn uint32 = 1 TagRAFStopInvocation uint32 = 2 TagRAFStopReturn uint32 = 3 TagRAFScheduleStatusReportInvocation uint32 = 4 TagRAFScheduleStatusReportReturn uint32 = 5 TagRAFGetParameterInvocation uint32 = 6 TagRAFGetParameterReturn uint32 = 7 TagRAFTransferBuffer uint32 = 8 TagRAFStatusReportInvocation uint32 = 9 )
RAF PDU tags, from the RafUsertoProviderPdu and RafProviderToUserPdu CHOICEs of annex A2.6 and A2.7.
The BIND family shares tags [100] to [104] across every service; the service-specific operations take the low numbers.
const Constructed uint8 = 0x20
Constructed is the bit marking a constructed rather than primitive encoding (X.690 clause 8.1.2.5).
const ContextBodySize = 12
ContextBodySize is the width of a context message body (clause 3.3.2.2.4).
const DefaultMaxLength = 16 << 20
DefaultMaxLength bounds a decoded BER value when no limit is given: 16 MiB.
A BER length field can name a value far larger than any real SLE PDU. Sizing an allocation from one is a trivial denial of service, so the decoder always works against a ceiling.
const DefaultMaxMessageSize = 16 << 20
DefaultMaxMessageSize bounds a TML message body when no limit is given: 16 MiB. The length field is 32 bits, so without a cap one message could name four gigabytes.
const MaxEventQualifier = 1024
MaxEventQualifier is the largest eventQualifier a THROW-EVENT may carry: OCTET STRING (SIZE (1 .. 1024)).
const MaxRandomNumber = 2147483647
MaxRandomNumber is the upper bound of the randomNumber field, per the HashInput type of figure 3-1: INTEGER (0 .. 2147483647).
const MaxSpaceLinkDataUnit = 65536
MaxSpaceLinkDataUnit is the largest SpaceLinkDataUnit, per the common types module: OCTET STRING (SIZE (1 .. 65536)).
const ProtocolVersion uint8 = 1
ProtocolVersion is the version a context message carries (clause 3.3.2.2.4 c).
const TMLHeaderSize = 8
TMLHeaderSize is the width of a TML message header in octets (clause 3.3.2.2.1).
const TimeCCSDSPicoSize = 10
TimeCCSDSPicoSize is the width of the picosecond-resolution variant.
const TimeCCSDSSize = 8
TimeCCSDSSize is the width of the SLE time field in octets.
Variables ¶
var ( // ErrDataTooShort indicates the input ended before a field it must contain. ErrDataTooShort = errors.New("data too short for the SLE field being read") // ErrInvalidTag indicates a BER tag the decoder did not expect here. ErrInvalidTag = errors.New("unexpected BER tag") // ErrInvalidLength indicates a BER length that is malformed or beyond the // bytes available. ErrInvalidLength = errors.New("invalid BER length") // ErrIndefiniteLength indicates the indefinite-length form on a primitive // encoding, which X.690 clause 8.1.3.2 forbids. Constructed indefinite-length // encodings are accepted. ErrIndefiniteLength = errors.New("indefinite BER length on a primitive encoding") // ErrInvalidObjectIdentifier indicates an OBJECT IDENTIFIER that cannot // be encoded or decoded. ErrInvalidObjectIdentifier = errors.New("invalid object identifier") // ErrLengthTooLarge indicates a BER length beyond the configured maximum. // A length field can name far more than any real PDU contains, so a cap // is what stops one hostile message exhausting memory. ErrLengthTooLarge = errors.New("BER length exceeds the maximum this decoder accepts") // ErrIntegerOverflow indicates a BER INTEGER too large for the Go type // receiving it. ErrIntegerOverflow = errors.New("BER integer does not fit") // ErrInvalidMessageType indicates a TML message type outside the three of // CCSDS 913.1-B-2 table 3-1. ErrInvalidMessageType = errors.New("invalid TML message type") // ErrInvalidProtocolID indicates a TML context message whose protocol // identification is not 'ISP1'. ErrInvalidProtocolID = errors.New("invalid TML protocol identification: expected ISP1") // ErrInvalidProtocolVersion indicates a TML context message with a // protocol version other than 1. ErrInvalidProtocolVersion = errors.New("invalid TML protocol version") // ErrInvalidContextLength indicates a TML context message body that is not // the 12 octets clause 3.3.2.2.4 requires. ErrInvalidContextLength = errors.New("TML context message body must be 12 octets") // ErrInvalidContextParameters indicates a TML context message whose // parameters are out of range: a nonzero heartbeat interval needs a // nonzero dead factor. ErrInvalidContextParameters = errors.New("invalid TML context parameters") // ErrNonEmptyHeartbeat indicates a heartbeat message carrying a body, // contrary to clause 3.3.2.2.5. ErrNonEmptyHeartbeat = errors.New("TML heartbeat message must have an empty body") // ErrMessageTooLarge indicates a TML message body beyond the configured // maximum. ErrMessageTooLarge = errors.New("TML message body exceeds the maximum this reader accepts") // ErrInvalidCredentials indicates credentials that cannot be decoded. ErrInvalidCredentials = errors.New("invalid credentials") // ErrAuthenticationFailed indicates a credential digest that did not match. ErrAuthenticationFailed = errors.New("authentication failed") // ErrCredentialsExpired indicates credentials whose time is further from // now than the acceptable delay, per clause 3.1.2.2.1. ErrCredentialsExpired = errors.New("credentials are outside the acceptable time window") // ErrInvalidIdentifier indicates an authority identifier outside the // 3-to-16 character range, or one containing a space. ErrInvalidIdentifier = errors.New("invalid authority identifier") // ErrInvalidVersionNumber indicates a version number outside 1 to 65535. ErrInvalidVersionNumber = errors.New("invalid version number: must be 1 to 65535") // ErrWrongState indicates an operation the association state does not allow. ErrWrongState = errors.New("operation not allowed in the current association state") // ErrInvalidProductionConfig indicates a transfer buffer size below one // or a negative latency limit. ErrInvalidProductionConfig = errors.New("invalid production configuration") // ErrProductionNotRunning indicates a frame offered while production is // halted or interrupted. A provider in either state has no data to // deliver, and buffering one anyway would deliver it late and out of // sequence when production resumed. ErrProductionNotRunning = errors.New("production is not running") // ErrDuplicateInstance indicates two service instances configured with // one identifier. A BIND naming it would be ambiguous, and the standard // gives no way to disambiguate. ErrDuplicateInstance = errors.New("service instance is already configured") // ErrUnknownInstance indicates a service instance identifier the complex // does not serve. ErrUnknownInstance = errors.New("no such service instance") // ErrInstanceInUse indicates a BIND to an instance that is already bound. ErrInstanceInUse = errors.New("service instance is already in use") // ErrVersionNotSupported indicates a BIND asking for a version the // instance was not configured for. ErrVersionNotSupported = errors.New("service version is not supported by this instance") // ErrNotBound indicates an operation requiring an established association. ErrNotBound = errors.New("association is not bound") // ErrAlreadyBound indicates a BIND on an association that already has one. ErrAlreadyBound = errors.New("association is already bound") // ErrBindRejected indicates the peer refused the BIND. ErrBindRejected = errors.New("peer rejected the bind") // ErrInvalidReportingCycle indicates a reporting cycle outside the 2-to-600 // second range of ReportingCycle. ErrInvalidReportingCycle = errors.New("invalid reporting cycle: must be 2 to 600 seconds") // ErrNotStarted indicates a data-transfer operation attempted before START. ErrNotStarted = errors.New("service instance is not started") // ErrAlreadyStarted indicates a START on an already-active service instance. ErrAlreadyStarted = errors.New("service instance is already started") // ErrUnexpectedPDU indicates a PDU the service state does not allow, which // the state tables answer with a PEER-ABORT for protocol error. ErrUnexpectedPDU = errors.New("PDU not allowed in the current service state") // ErrUnknownInvokeId indicates a return whose invoke identifier matches no // outstanding invocation. ErrUnknownInvokeId = errors.New("return does not match any outstanding invocation") // ErrDuplicateInvokeId indicates an invocation reusing an invoke // identifier already seen on this association. The provider machines // answer it with the 'duplicate invoke ID' diagnostic. ErrDuplicateInvokeId = errors.New("invoke identifier already used on this association") // ErrCltuOutOfSequence indicates a CLTU identification that is not the one // the provider expects next, per CCSDS 912.1-B-5 clause 3.6.2.5. ErrCltuOutOfSequence = errors.New("CLTU identification is out of sequence") )
Sentinel errors returned by the SLE codecs and the association machine.
var CCSDSEpoch = time.Date(1958, 1, 1, 0, 0, 0, 0, time.UTC)
CCSDSEpoch is 1958-01-01 00:00:00 UTC, the epoch the day count runs from.
var ProtocolID = [4]byte{'I', 'S', 'P', '1'}
ProtocolID is the identification field of a context message: the characters 'I' 'S' 'P' '1' (clause 3.3.2.2.4 a).
Functions ¶
func AppendAntennaId ¶
AppendAntennaId writes an AntennaId CHOICE.
func AppendCltuLastOk ¶
func AppendCltuLastOk(dst []byte, c CltuLastOk) []byte
AppendCltuLastOk writes a CltuLastOk CHOICE. As with CltuLastProcessed, the cltuOk alternative's [1] replaces its SEQUENCE tag (implicit tagging), so the fields sit directly under it.
func AppendCltuLastProcessed ¶
func AppendCltuLastProcessed(dst []byte, c CltuLastProcessed) []byte
AppendCltuLastProcessed writes a CltuLastProcessed CHOICE.
The cltuProcessed alternative is [1] IMPLICIT SEQUENCE, and the module is IMPLICIT TAGS: the tag replaces the SEQUENCE's, so the fields sit directly under [1] with no inner SEQUENCE.
func AppendConditionalTime ¶
func AppendConditionalTime(dst []byte, c ConditionalTime) []byte
AppendConditionalTime writes a ConditionalTime CHOICE.
func AppendControlWordType ¶
func AppendControlWordType(dst []byte, c ControlWordType) []byte
AppendControlWordType writes a ControlWordType CHOICE.
func AppendCredentialsChoice ¶
func AppendCredentialsChoice(dst []byte, c *Credentials) ([]byte, error)
AppendCredentialsChoice writes the Credentials CHOICE of the common types module:
Credentials ::= CHOICE
{ unused [0] NULL
, used [1] OCTET STRING (SIZE (8 .. 256))
}
A nil Credentials takes the unused alternative, which is what an unauthenticated association sends.
func AppendElement ¶
AppendElement writes a complete tag-length-value.
func AppendGVCID ¶
AppendGVCID writes a GvcId SEQUENCE.
func AppendInteger ¶
AppendInteger writes a universal INTEGER.
BER integers are two's complement and minimally encoded: a leading zero octet appears only when it is needed to keep a positive value from looking negative (X.690 clause 8.3).
func AppendLength ¶
AppendLength writes a definite-form length, short or long as needed (X.690 clause 8.1.3).
func AppendNull ¶
AppendNull writes a universal NULL, which has no content.
func AppendObjectIdentifier ¶
AppendObjectIdentifier writes a universal OBJECT IDENTIFIER (X.690 clause 8.19).
The first two arcs pack into one subidentifier (first*40 + second), then every subidentifier is base-128 with continuation bits. The service instance identifiers of the SLE BIND use this type for their attribute names.
func AppendOctetString ¶
AppendOctetString writes a universal OCTET STRING.
func AppendSequence ¶
AppendSequence writes a universal SEQUENCE around already-encoded content.
func AppendTag ¶
AppendTag writes a BER identifier octet, or several when the tag number needs the high-tag-number form (X.690 clause 8.1.2.4).
func AppendTaggedInteger ¶
AppendTaggedInteger writes an INTEGER under a context-specific tag.
func AppendTimeChoice ¶
AppendTimeChoice writes an SLE Time CHOICE, taking the [0] ccsdsFormat alternative that the eight-octet form uses.
func AppendVisibleString ¶
AppendVisibleString writes a universal VisibleString.
Types ¶
type Acknowledgement ¶
type Acknowledgement struct {
Credentials *Credentials
InvokeId InvokeId
// Positive reports whether the operation succeeded.
Positive bool
// Diagnostic explains a failure.
Diagnostic Diagnostics
}
Acknowledgement is the SleAcknowledgement of the common PDUs module: the answer to STOP and to other operations that need only success or failure.
func DecodeAcknowledgement ¶
func DecodeAcknowledgement(data []byte) (*Acknowledgement, error)
DecodeAcknowledgement parses an acknowledgement's content.
func (*Acknowledgement) Encode ¶
func (a *Acknowledgement) Encode() ([]byte, error)
Encode serializes the acknowledgement's content.
func (*Acknowledgement) Humanize ¶
func (a *Acknowledgement) Humanize() string
Humanize returns a human-readable summary.
type AntennaId ¶
type AntennaId struct {
// Global holds an object identifier when the global form is used.
Global []byte
// Local holds a local name, 1 to 16 octets, when the local form is used.
Local []byte
}
AntennaId names the antenna a frame arrived on.
AntennaId ::= CHOICE
{ globalForm [0] OBJECT IDENTIFIER
, localForm [1] OCTET STRING (SIZE (1 .. 16))
}
func DecodeAntennaId ¶
DecodeAntennaId reads an AntennaId CHOICE.
type ApplicationIdentifier ¶
type ApplicationIdentifier int
ApplicationIdentifier names the transfer service a BIND is asking for. Values from the ApplicationIdentifier INTEGER of annex A2.2.
const ( AppReturnAllFrames ApplicationIdentifier = 0 AppReturnInsert ApplicationIdentifier = 1 AppReturnChannelFrames ApplicationIdentifier = 2 AppReturnChannelFSH ApplicationIdentifier = 3 AppReturnChannelOCF ApplicationIdentifier = 4 AppReturnBitstream ApplicationIdentifier = 5 AppReturnSpacePacket ApplicationIdentifier = 6 AppForwardAOSSpacePkt ApplicationIdentifier = 7 AppForwardAOSVCA ApplicationIdentifier = 8 AppForwardBitstream ApplicationIdentifier = 9 AppForwardProtoVCDU ApplicationIdentifier = 10 AppForwardInsert ApplicationIdentifier = 11 AppForwardCVCDU ApplicationIdentifier = 12 AppForwardTCSpacePkt ApplicationIdentifier = 13 AppForwardTCVCA ApplicationIdentifier = 14 AppForwardTCFrame ApplicationIdentifier = 15 AppForwardCLTU ApplicationIdentifier = 16 )
func (ApplicationIdentifier) String ¶
func (a ApplicationIdentifier) String() string
String names the service.
type Association ¶
type Association struct {
// contains filtered or unexported fields
}
Association tracks one SLE association.
It is safe for concurrent use, though the caller normally drives it from a single loop.
func NewAssociation ¶
func NewAssociation(config AssociationConfig) (*Association, error)
NewAssociation prepares an association.
func (*Association) Abort ¶
func (a *Association) Abort(diagnostic PeerAbortDiagnostic, now time.Time) *PeerAbort
Abort ends the association abruptly, returning the PEER-ABORT to send.
ISP1 maps PEER-ABORT onto the transport twice over (CCSDS 913.1-B-2 clause 3.4): the diagnostic goes out as one octet of TCP urgent data (take it from PeerAbort.UrgentData and write it with MSG_OOB) and then the connection closes. This package owns no socket, so both are the caller's to do after sending the PDU this returns.
func (*Association) AbortDiagnostic ¶
func (a *Association) AbortDiagnostic() *PeerAbortDiagnostic
AbortDiagnostic returns why the association aborted, or nil if it did not.
func (*Association) Bind ¶
func (a *Association) Bind( now time.Time, randomNumber int32, serviceType ApplicationIdentifier, version uint16, responderPort string, instance ServiceInstanceIdentifier, ) (*BindInvocation, error)
Bind builds a BIND invocation and moves to bind-pending.
Only the service user sends BIND. randomNumber seeds the credentials; the caller supplies it rather than this package choosing a randomness source.
func (*Association) Bound ¶
func (a *Association) Bound() bool
Bound reports whether the association is established.
func (*Association) CheckPeerCredentials ¶
func (a *Association) CheckPeerCredentials(c *Credentials, now time.Time) error
CheckPeerCredentials verifies credentials on an incoming service PDU.
The service machines call it from every HandlePDU path. It returns nil unless the association's authentication level is 'all' and a peer password is on file. The two lower levels leave service PDUs unchecked, per the levels of CCSDS 913.1-B-2 clause 3.1. When it does check, missing credentials are as bad as wrong ones: an association configured for authentication must not accept a PDU that simply left the field out.
func (*Association) ContextMessage ¶
func (a *Association) ContextMessage(now time.Time) *Message
ContextMessage builds the TML context message that opens the connection.
Clause 3.3.2.2 makes this the first message on a connection, before any SLE PDU.
func (*Association) HandleBindInvocation ¶
func (a *Association) HandleBindInvocation(b *BindInvocation, now time.Time, randomNumber int32) (*BindReturn, error)
HandleBindInvocation processes an inbound BIND at the provider, returning the answer to send.
func (*Association) HandleBindReturn ¶
func (a *Association) HandleBindReturn(b *BindReturn, now time.Time) error
HandleBindReturn processes the provider's answer at the user.
func (*Association) HandleContextMessage ¶
func (a *Association) HandleContextMessage(body []byte, now time.Time) error
HandleContextMessage records the peer's context message.
The peer's heartbeat interval and dead factor govern what this end must send and how long it waits, so they replace the configured values.
Clause 3.3.2.2 makes the context message the initiator's (the SLE user sends it, the provider receives it) so a user rejects an inbound one. The parameters are range-checked: a nonzero heartbeat interval with a zero dead factor could never declare the peer dead.
func (*Association) HandlePeerAbort ¶
func (a *Association) HandlePeerAbort(p *PeerAbort, now time.Time)
HandlePeerAbort processes an inbound PEER-ABORT.
func (*Association) HandleUnbindInvocation ¶
func (a *Association) HandleUnbindInvocation(u *UnbindInvocation, now time.Time, randomNumber int32) (*UnbindReturn, error)
HandleUnbindInvocation processes an inbound UNBIND, returning the answer.
An UNBIND cannot be refused: the return type of annex A2.2 has only a positive alternative.
func (*Association) HandleUnbindReturn ¶
func (a *Association) HandleUnbindReturn(u *UnbindReturn, now time.Time) error
HandleUnbindReturn processes the answer to our UNBIND.
func (*Association) HandleUrgentData ¶
func (a *Association) HandleUrgentData(octet byte, now time.Time) *PeerAbort
HandleUrgentData processes a peer abort that arrived as TCP urgent data: the single diagnostic octet of CCSDS 913.1-B-2 clause 3.4. A caller reading its socket out of band hands the octet here and gets the decoded abort back; the association closes just as it does for the in-band PDU.
func (*Association) HeartbeatDue ¶
func (a *Association) HeartbeatDue(now time.Time) bool
HeartbeatDue reports whether a heartbeat should go out now.
This package runs no clock. Call it from your loop with the current time.
func (*Association) MakeCredentials ¶
func (a *Association) MakeCredentials(now time.Time, randomNumber int32) (*Credentials, error)
MakeCredentials builds credentials for an outgoing service PDU, or returns nil when the association is unauthenticated.
The BIND family generates its own credentials inside this file. The service operations in raf.go, rcf.go, rocf.go and fcltu.go are built by the state machines in service.go, which call this so every PDU on an authenticated association carries the same identity the BIND did.
func (*Association) NextHeartbeat ¶
func (a *Association) NextHeartbeat() time.Time
NextHeartbeat returns when the next heartbeat is due, so a caller can size a select timeout rather than poll.
func (*Association) PeerDead ¶
func (a *Association) PeerDead(now time.Time) bool
PeerDead reports whether the peer has been silent for longer than the heartbeat interval times the dead factor.
Clause 3.3.3 makes this the signal to abort the association.
func (*Association) RecordReceived ¶
func (a *Association) RecordReceived(now time.Time)
RecordReceived notes that something arrived, which proves the peer is alive.
func (*Association) RecordSent ¶
func (a *Association) RecordSent(now time.Time)
RecordSent notes that something went out, which resets the heartbeat timer.
Clause 3.3.3: a heartbeat is only needed on an idle connection, so any traffic serves the same purpose.
func (*Association) Role ¶
func (a *Association) Role() Role
Role reports which end of the association this is.
func (*Association) ServiceType ¶
func (a *Association) ServiceType() ApplicationIdentifier
ServiceType returns the service the BIND agreed on.
func (*Association) State ¶
func (a *Association) State() AssociationState
State returns the current state.
func (*Association) Unbind ¶
func (a *Association) Unbind(now time.Time, randomNumber int32, reason UnbindReason) (*UnbindInvocation, error)
Unbind builds an UNBIND invocation and moves to unbind-pending.
func (*Association) Version ¶
func (a *Association) Version() uint16
Version returns the version the BIND agreed on.
type AssociationConfig ¶
type AssociationConfig struct {
// Role is which end this is.
Role Role
// LocalIdentifier is this end's authority identifier, 3 to 16 characters.
LocalIdentifier string
// PeerIdentifier is the far end's, checked on receipt.
PeerIdentifier string
// HeartbeatInterval is how many seconds between heartbeats. Zero disables
// the heartbeat (clause 3.3.3).
HeartbeatInterval uint16
// DeadFactor is how many intervals of silence mean the peer has gone.
DeadFactor uint16
// UserName and Password authenticate this end. Leave Password nil for an
// unauthenticated association.
UserName string
Password []byte
// PeerPassword verifies the far end's credentials.
PeerPassword []byte
// AuthLevel says which inbound PDUs are authenticated: the BIND exchange
// only (the default), nothing, or every PDU. It matters only when
// PeerPassword is set.
AuthLevel AuthenticationLevel
// AcceptableDelay is how far a peer's credential time may be from now
// before it is rejected (clause 3.1.2.2.1). Zero disables the check.
AcceptableDelay time.Duration
}
AssociationConfig describes one association.
type AssociationState ¶
type AssociationState int
AssociationState is where an association has got to.
const ( // StateUnbound means the connection is open but no BIND has succeeded. StateUnbound AssociationState = iota // StateBindPending means a BIND invocation is out and its return has not // come back. StateBindPending // StateBound means the association is established and PDUs may flow. StateBound // StateUnbindPending means an UNBIND invocation is out. StateUnbindPending // StateClosed means the association has ended, by UNBIND or abort. StateClosed )
type AuthenticationLevel ¶
type AuthenticationLevel int
AuthenticationLevel says which inbound PDUs must carry verified credentials. CCSDS 913.1-B-2 clause 3.1 names the three levels a service agreement can pick.
const ( // AuthLevelBind verifies credentials on the BIND exchange only. This is // the default, and the level most service agreements pick. AuthLevelBind AuthenticationLevel = iota // AuthLevelNone verifies nothing, even when a peer password is // configured. AuthLevelNone // AuthLevelAll verifies the credentials on every inbound PDU. The // service machines run the check in their HandlePDU paths through // CheckPeerCredentials. AuthLevelAll )
func (AuthenticationLevel) String ¶
func (l AuthenticationLevel) String() string
String names the level.
type BindDiagnostic ¶
type BindDiagnostic int
BindDiagnostic explains a refused BIND, from the BindDiagnostic INTEGER of annex A2.2.
const ( BindAccessDenied BindDiagnostic = 0 BindServiceTypeNotSupported BindDiagnostic = 1 BindVersionNotSupported BindDiagnostic = 2 BindNoSuchServiceInstance BindDiagnostic = 3 BindAlreadyBound BindDiagnostic = 4 BindNotAccessibleToThisInitiator BindDiagnostic = 5 BindInconsistentServiceType BindDiagnostic = 6 BindInvalidTime BindDiagnostic = 7 BindOutOfService BindDiagnostic = 8 BindOtherReason BindDiagnostic = 127 )
type BindInvocation ¶
type BindInvocation struct {
// Credentials authenticate the initiator, or nil for an unauthenticated
// association.
Credentials *Credentials
// InitiatorIdentifier names the sending entity, 3 to 16 characters.
InitiatorIdentifier string
// ResponderPortIdentifier names the provider's logical port.
ResponderPortIdentifier string
// ServiceType is the transfer service being requested.
ServiceType ApplicationIdentifier
// VersionNumber is the service version, 1 to 65535.
VersionNumber uint16
// ServiceInstanceIdentifier names the service instance.
ServiceInstanceIdentifier ServiceInstanceIdentifier
}
BindInvocation is the SleBindInvocation of annex A2.2. The user sends it to open an association.
func DecodeBindInvocation ¶
func DecodeBindInvocation(data []byte) (*BindInvocation, error)
DecodeBindInvocation parses a BIND invocation's content.
func (*BindInvocation) Encode ¶
func (b *BindInvocation) Encode() ([]byte, error)
Encode serializes the BIND invocation content, without the outer service tag that each service module adds.
func (*BindInvocation) Humanize ¶
func (b *BindInvocation) Humanize() string
Humanize returns a human-readable summary.
func (*BindInvocation) Validate ¶
func (b *BindInvocation) Validate() error
Validate checks the invocation against annex A2.2.
type BindReturn ¶
type BindReturn struct {
Credentials *Credentials
// ResponderIdentifier names the answering entity.
ResponderIdentifier string
// Positive reports whether the bind succeeded.
Positive bool
// VersionNumber is the agreed version, meaningful when Positive.
VersionNumber uint16
// Diagnostic explains a refusal, meaningful when not Positive.
Diagnostic BindDiagnostic
}
BindReturn is the SleBindReturn of annex A2.2: the provider's answer.
func DecodeBindReturn ¶
func DecodeBindReturn(data []byte) (*BindReturn, error)
DecodeBindReturn parses a BIND return's content.
func (*BindReturn) Encode ¶
func (b *BindReturn) Encode() ([]byte, error)
Encode serializes the BIND return's content.
func (*BindReturn) Humanize ¶
func (b *BindReturn) Humanize() string
Humanize returns a human-readable summary.
type CltuIdentification ¶
type CltuIdentification uint32
CltuIdentification numbers a CLTU within a service instance. The user assigns it and must keep it ascending; the provider quotes it back. IntUnsignedLong: INTEGER (0 .. 4294967295).
type CltuLastOk ¶
type CltuLastOk struct {
// Ok reports whether any CLTU has been radiated successfully.
Ok bool
CltuIdentification CltuIdentification
RadiationStopTime Time
}
CltuLastOk says which CLTU was last radiated without trouble.
CltuLastOk ::= CHOICE
{ noCltuOk [0] NULL
, cltuOk [1] SEQUENCE { cltuIdentification, radiationStopTime }
}
Note that radiationStopTime here is a plain Time, not a ConditionalTime: a CLTU that finished radiating has a stop time by definition.
func DecodeCltuLastOk ¶
func DecodeCltuLastOk(e *Element) (CltuLastOk, error)
DecodeCltuLastOk reads a CltuLastOk CHOICE.
type CltuLastProcessed ¶
type CltuLastProcessed struct {
// Processed reports whether any CLTU has been processed yet.
Processed bool
CltuIdentification CltuIdentification
// RadiationStartTime is when radiation began, undefined if it has not.
RadiationStartTime ConditionalTime
Status CltuStatus
}
CltuLastProcessed says what the provider last took off its queue.
CltuLastProcessed ::= CHOICE
{ noCltuProcessed [0] NULL
, cltuProcessed [1] SEQUENCE
{ cltuIdentification, radiationStartTime, cltuStatus }
}
func DecodeCltuLastProcessed ¶
func DecodeCltuLastProcessed(e *Element) (CltuLastProcessed, error)
DecodeCltuLastProcessed reads a CltuLastProcessed CHOICE.
func (CltuLastProcessed) String ¶
func (c CltuLastProcessed) String() string
String renders what was last processed.
type CltuNotificationKind ¶
type CltuNotificationKind int
CltuNotificationKind says which alternative an ASYNC-NOTIFY took, from the CltuNotification CHOICE of the CLTU structures module.
const ( // NotifyCltuRadiated reports one CLTU went out. NotifyCltuRadiated CltuNotificationKind = 0 // NotifySlduExpired reports a CLTU's window passed unused. NotifySlduExpired CltuNotificationKind = 1 // NotifyProductionInterrupted reports radiation stopped unexpectedly. NotifyProductionInterrupted CltuNotificationKind = 2 // NotifyProductionHalted reports the channel ended. NotifyProductionHalted CltuNotificationKind = 3 // NotifyProductionOperational reports the channel started radiating. NotifyProductionOperational CltuNotificationKind = 4 // NotifyBufferEmpty reports the provider has run out of CLTUs to send. NotifyBufferEmpty CltuNotificationKind = 5 // NotifyActionListCompleted reports a thrown event's actions all ran. NotifyActionListCompleted CltuNotificationKind = 6 // NotifyActionListNotCompleted reports they did not. NotifyActionListNotCompleted CltuNotificationKind = 7 // NotifyEventConditionEvFalse reports a thrown event's condition was false. NotifyEventConditionEvFalse CltuNotificationKind = 8 )
func (CltuNotificationKind) CarriesEventId ¶
func (n CltuNotificationKind) CarriesEventId() bool
CarriesEventId reports whether this notification carries an EventInvocationId rather than a NULL. The last three alternatives do.
func (CltuNotificationKind) String ¶
func (n CltuNotificationKind) String() string
String names the notification.
type CltuStatus ¶
type CltuStatus int
CltuStatus says what became of a CLTU, from the CltuStatus subtype of ForwardDuStatus.
The values are ForwardDuStatus's, and FCLTU uses only five of its seven: 3 is "acknowledged" and 6 is "unsupported transmission mode", both of which belong to the Forward Space Packet service. So the numbering has a hole in it, and 3 is not a value this service ever sends.
const ( // CltuRadiated means the CLTU went out. CltuRadiated CltuStatus = 0 // CltuExpired means its transmission window passed before it could. CltuExpired CltuStatus = 1 // CltuInterrupted means radiation began and was cut short. CltuInterrupted CltuStatus = 2 // CltuProductionStarted means radiation started. CltuProductionStarted CltuStatus = 4 // CltuProductionNotStarted means radiation did not start. CltuProductionNotStarted CltuStatus = 5 )
func (CltuStatus) Valid ¶
func (c CltuStatus) Valid() bool
Valid reports whether the status is one FCLTU defines.
type Complex ¶ added in v0.4.0
type Complex struct {
// contains filtered or unexported fields
}
Complex holds the service instances a provider serves and routes inbound BINDs to them.
It is safe for concurrent use: instances are naturally driven by different connections.
func NewComplex ¶ added in v0.4.0
func NewComplex() *Complex
NewComplex prepares a complex with no instances.
func (*Complex) Abort ¶ added in v0.4.0
func (c *Complex) Abort()
Abort clears every instance's transfer buffer, for a complex whose underlying connection has gone.
Clause 3.1.9.1.12 requires an aborted association to clear its buffer. An abort usually takes one association, so a caller with a live complex aborts the instance rather than the whole thing; this is for shutdown.
func (*Complex) Add ¶ added in v0.4.0
func (c *Complex) Add(config InstanceConfig) (*Instance, error)
Add configures one service instance.
The instance identifier is the key, because that is what a BIND names. Two instances cannot share one: a BIND would be ambiguous, and the standard gives no way to disambiguate.
func (*Complex) DueInstances ¶ added in v0.4.0
DueInstances lists the instances whose transfer buffer should be released now, in configuration order.
A station serving several instances polls this rather than each buffer, so one loop drives them all.
func (*Complex) Humanize ¶ added in v0.4.0
Humanize returns a human-readable summary of the complex.
func (*Complex) Instances ¶ added in v0.4.0
Instances lists the configured instances in configuration order.
func (*Complex) NextDeadline ¶ added in v0.4.0
NextDeadline reports the earliest release timer across every instance, and whether any is running.
It is what a single-threaded station waits on: the next moment any buffer needs attention.
func (*Complex) Route ¶ added in v0.4.0
func (c *Complex) Route(bind *BindInvocation) (*Instance, BindDiagnostic, error)
Route finds the instance a BIND invocation names and checks it can be bound.
It is the admission decision, and it returns the diagnostic to answer with when the answer is no, so a caller does not have to work out which of the BIND diagnostics applies. The diagnostics are the ones annex A defines for SleBindReturn:
- an identifier the complex does not know is 'no such service instance'
- one already bound is 'already bound'
- a version the instance was not configured for is 'version not supported'
A caller that wants to refuse for a reason outside the instance set (the initiator not being the one the agreement names, or the request arriving outside a provision period) checks that itself and answers with the diagnostic that fits. Those are service-agreement matters, and the complex does not hold an agreement.
type ConditionalTime ¶
ConditionalTime is the CHOICE of the common types module: a time that may be absent.
ConditionalTime ::= CHOICE
{ undefined [0] NULL
, known [1] Time
}
RAF START uses it for the start and stop of a requested time range, where "undefined" means "from now" or "until further notice".
func DecodeConditionalTime ¶
func DecodeConditionalTime(e *Element) (ConditionalTime, error)
DecodeConditionalTime reads a ConditionalTime CHOICE.
type ContextMessage ¶
type ContextMessage struct {
// HeartbeatInterval is how many seconds pass between heartbeats. Zero
// disables the heartbeat entirely (clause 3.3.3).
HeartbeatInterval uint16
// DeadFactor is how many intervals of silence mean the peer has gone.
DeadFactor uint16
}
ContextMessage is the body of a TML context message (clause 3.3.2.2.4).
It opens a connection, telling the peer how often to expect a heartbeat and how many missed ones mean the link is dead.
func DecodeContextMessage ¶
func DecodeContextMessage(body []byte) (*ContextMessage, error)
DecodeContextMessage parses a context message body.
func (*ContextMessage) Encode ¶
func (c *ContextMessage) Encode() []byte
Encode serializes the context message body: 'ISP1', three reserved zeros, the version, then the two parameters.
func (*ContextMessage) Humanize ¶
func (c *ContextMessage) Humanize() string
Humanize returns a human-readable summary.
func (*ContextMessage) Message ¶
func (c *ContextMessage) Message() *Message
Message wraps the context body in a TML message.
type ControlWordKind ¶
type ControlWordKind int
ControlWordKind selects which control words to deliver, from the ControlWordType CHOICE of the ROCF structures module.
const ( // ControlWordAll delivers every operational control field. ControlWordAll ControlWordKind = 0 // ControlWordCLCW delivers only CLCWs, for one telecommand virtual // channel or for all of them. ControlWordCLCW ControlWordKind = 1 // ControlWordNotCLCW delivers only fields that are not CLCWs. ControlWordNotCLCW ControlWordKind = 2 )
type ControlWordType ¶
type ControlWordType struct {
Kind ControlWordKind
// TCVirtualChannel names one telecommand virtual channel when Kind is
// ControlWordCLCW and HasTCVirtualChannel is set.
TCVirtualChannel uint8
HasTCVirtualChannel bool
}
ControlWordType is the ROCF filter on which control words to deliver.
ControlWordType ::= CHOICE
{ allControlWords [0] NULL
, clcw [1] TcVcid
, notClcw [2] NULL
}
The clcw alternative carries a TcVcid, itself a CHOICE of "no telecommand virtual channel" and a specific one, so a caller can ask for CLCWs from one TC virtual channel, or from any.
func DecodeControlWordType ¶
func DecodeControlWordType(e *Element) (ControlWordType, error)
DecodeControlWordType reads a ControlWordType CHOICE.
type Credentials ¶
type Credentials struct {
Time Time
RandomNumber int32
// Protected is the message digest, 32 octets from SHA-256 or 20 from the
// legacy SHA-1.
Protected []byte
}
Credentials are the ISP1Credentials of figure 3-2: the time and random number that went into a digest, and the digest itself.
func DecodeCredentials ¶
func DecodeCredentials(data []byte) (*Credentials, error)
DecodeCredentials parses an ISP1Credentials SEQUENCE.
func DecodeCredentialsChoice ¶
func DecodeCredentialsChoice(e *Element) (*Credentials, error)
DecodeCredentialsChoice reads a Credentials CHOICE, returning nil for the unused alternative.
func GenerateCredentials ¶
func GenerateCredentials(t time.Time, randomNumber int32, userName string, password []byte) (*Credentials, error)
GenerateCredentials builds credentials for an outgoing PDU, per clause 3.1.2.1.
The caller supplies the random number rather than this package choosing one. A library has no business picking a mission's randomness source, and the value has to be reproducible in tests.
func (*Credentials) Encode ¶
func (c *Credentials) Encode() ([]byte, error)
Encode serializes the ISP1Credentials SEQUENCE of figure 3-2.
func (*Credentials) Humanize ¶
func (c *Credentials) Humanize() string
Humanize returns a human-readable summary. It shows the digest length rather than the digest.
func (*Credentials) Verify ¶
func (c *Credentials) Verify(now time.Time, acceptableDelay time.Duration, userName string, password []byte) error
Verify checks credentials received from a peer, per clause 3.1.2.2.
now is the current time and acceptableDelay is how far the credential time may be from it. userName and password are the peer's, which the receiver already knows.
The digest comparison is constant time. A timing oracle on a MAC comparison is a real attack, and it costs nothing to avoid.
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
Decoder walks a BER-encoded buffer.
It is a value type over a slice, so a Decoder over a SEQUENCE's content is just another Decoder. That is how nesting works here: no reader interface, no allocation per level.
func NewDecoderWithLimit ¶
NewDecoderWithLimit returns a decoder with an explicit value ceiling.
type DeliveryMode ¶
type DeliveryMode int
DeliveryMode says how a service instance delivers data.
const ( DeliveryReturnTimelyOnline DeliveryMode = 0 DeliveryReturnCompleteOnline DeliveryMode = 1 DeliveryReturnOffline DeliveryMode = 2 DeliveryForwardOnline DeliveryMode = 3 DeliveryForwardOffline DeliveryMode = 4 )
func (DeliveryMode) AllowsDiscard ¶
func (d DeliveryMode) AllowsDiscard() bool
AllowsDiscard reports whether the provider may throw data away to keep up. Only timely online may: state table row 14 of CCSDS 911.1-B-5 clause 4.2.2 is the only cell that sends a 'data discarded' sync notification.
func (DeliveryMode) AllowsPastStartTime ¶
func (d DeliveryMode) AllowsPastStartTime() bool
AllowsPastStartTime reports whether START may name a time range that has already happened. Only offline delivery reads from a store, so only offline can be asked for yesterday.
func (DeliveryMode) AllowsPeriodicStatusReport ¶
func (d DeliveryMode) AllowsPeriodicStatusReport() bool
AllowsPeriodicStatusReport reports whether SCHEDULE-STATUS-REPORT may ask for periodic reports. Offline delivery has no live channel to report on, so the answer there is the 'not supported in this delivery mode' diagnostic.
func (DeliveryMode) IsForward ¶
func (d DeliveryMode) IsForward() bool
IsForward reports whether the mode belongs to a forward service.
func (DeliveryMode) IsOnline ¶
func (d DeliveryMode) IsOnline() bool
IsOnline reports whether the mode reads from a live channel rather than a store.
func (DeliveryMode) IsReturn ¶
func (d DeliveryMode) IsReturn() bool
IsReturn reports whether the mode belongs to a return service.
func (DeliveryMode) RequiresBackpressure ¶
func (d DeliveryMode) RequiresBackpressure() bool
RequiresBackpressure reports whether the caller must slow down rather than let data be dropped. Complete online and offline both promise every frame, so a slow caller has to become the brake.
func (DeliveryMode) Valid ¶
func (d DeliveryMode) Valid() bool
Valid reports whether the mode is one of the five the standard defines.
type Diagnostics ¶
type Diagnostics int
Diagnostics is the common diagnostic set every service shares.
const ( // DiagDuplicateInvokeId means the invoke identifier is already in use. DiagDuplicateInvokeId Diagnostics = 100 // DiagOtherReason covers everything else. DiagOtherReason Diagnostics = 127 )
type Element ¶
type Element struct {
// Class is the tag class: universal, application, context or private.
Class uint8
// Constructed reports whether the content is itself a run of elements.
Constructed bool
// Tag is the tag number.
Tag uint32
// Bytes is the content, with the tag and length already stripped.
Bytes []byte
}
Element is one decoded BER tag-length-value.
func (*Element) Bool ¶
Bool reads an element's content as a BOOLEAN. X.690 clause 8.2.2: any non-zero octet is true.
func (*Element) Copy ¶
Copy returns a copy of the element's content, so it does not alias the buffer the decoder was built over.
func (*Element) IsContext ¶
IsContext reports whether this is a context-specific tag with the given number.
func (*Element) IsUniversal ¶
IsUniversal reports whether this is a universal tag with the given number.
func (*Element) ObjectIdentifier ¶
ObjectIdentifier reads an element's content as the arcs of an OBJECT IDENTIFIER (X.690 clause 8.19).
type EventInvocationId ¶
type EventInvocationId uint32
EventInvocationId numbers a THROW-EVENT invocation, also ascending.
type FCLTUAsyncNotifyInvocation ¶
type FCLTUAsyncNotifyInvocation struct {
Credentials *Credentials
// Kind says which notification this is.
Kind CltuNotificationKind
// EventInvocationId is set when Kind.CarriesEventId reports true.
EventInvocationId EventInvocationId
// LastProcessed and LastOk report the queue's position, sent with every
// notification whatever its kind.
LastProcessed CltuLastProcessed
LastOk CltuLastOk
ProductionStatus FCLTUProductionStatus
UplinkStatus UplinkStatus
}
FCLTUAsyncNotifyInvocation is the CltuAsyncNotifyInvocation of annex A2.5: the provider reporting, after the fact, what happened to a CLTU or to the channel.
This is what makes the service asynchronous. TRANSFER-DATA's return only says the CLTU was queued. Whether it actually reached the antenna arrives here, possibly much later.
func DecodeFCLTUAsyncNotifyInvocation ¶
func DecodeFCLTUAsyncNotifyInvocation(data []byte) (*FCLTUAsyncNotifyInvocation, error)
DecodeFCLTUAsyncNotifyInvocation parses an ASYNC-NOTIFY invocation's content.
func (*FCLTUAsyncNotifyInvocation) Encode ¶
func (n *FCLTUAsyncNotifyInvocation) Encode() ([]byte, error)
Encode serializes the ASYNC-NOTIFY invocation's content.
func (*FCLTUAsyncNotifyInvocation) Humanize ¶
func (n *FCLTUAsyncNotifyInvocation) Humanize() string
Humanize returns a human-readable summary.
type FCLTUProductionStatus ¶
type FCLTUProductionStatus int
FCLTUProductionStatus is the state of the forward physical channel, from the ProductionStatus INTEGER of the CLTU structures module.
This is a different type from the return services' ProductionStatus, not a wider spelling of it. FCLTU has four states where the return services have three, and the numbers do not line up: 1 is "configured" here and "halted" there. Sharing one Go type between them would mislabel every status report.
const ( // FCLTUProductionOperational means the channel is configured and radiating. FCLTUProductionOperational FCLTUProductionStatus = 0 // FCLTUProductionConfigured means the channel is ready but not radiating. FCLTUProductionConfigured FCLTUProductionStatus = 1 // FCLTUProductionInterrupted means radiation stopped unexpectedly. FCLTUProductionInterrupted FCLTUProductionStatus = 2 // FCLTUProductionHalted means the channel ended and will not resume. FCLTUProductionHalted FCLTUProductionStatus = 3 )
func (FCLTUProductionStatus) String ¶
func (p FCLTUProductionStatus) String() string
String names the production status.
type FCLTUProvider ¶
type FCLTUProvider struct {
*ServiceProvider
// contains filtered or unexported fields
}
FCLTUProvider is the provider half of an FCLTU instance. Partial.
It does track the expected CLTU number, because that is what makes the out-of-sequence check testable, but it does not radiate anything: the caller decides what happens to a CLTU and reports it back through SendAsyncNotify.
func NewFCLTUProvider ¶
func NewFCLTUProvider(config ServiceConfig) (*FCLTUProvider, error)
NewFCLTUProvider prepares the provider half of an FCLTU instance.
func (FCLTUProvider) Association ¶
func (c FCLTUProvider) Association() *Association
Association returns the association underneath.
func (FCLTUProvider) DeliveryMode ¶
func (c FCLTUProvider) DeliveryMode() DeliveryMode
DeliveryMode returns the configured delivery mode.
func (*FCLTUProvider) ExpectedCltuIdentification ¶
func (p *FCLTUProvider) ExpectedCltuIdentification() (CltuIdentification, bool)
ExpectedCltuIdentification reports the number the next CLTU must carry.
func (*FCLTUProvider) HandlePDU ¶
func (p *FCLTUProvider) HandlePDU(data []byte, now time.Time) (*FCLTUProviderEvent, error)
HandlePDU decodes one PDU from the user.
func (FCLTUProvider) HandlePeerAbort ¶
HandlePeerAbort takes an inbound PEER-ABORT: the association is over.
func (*FCLTUProvider) HandleStartInvocation ¶
func (p *FCLTUProvider) HandleStartInvocation( s *FCLTUStartInvocation, answer *FCLTUStartReturn, now time.Time, randomNumber int32, ) error
HandleStartInvocation answers a START. Accepting moves to state 3 and arms the expected CLTU number from the invocation.
func (*FCLTUProvider) HandleTransferDataInvocation ¶
func (p *FCLTUProvider) HandleTransferDataInvocation( t *FCLTUTransferDataInvocation, accept bool, diagnostic FCLTUTransferDataDiagnostic, bufferAvailable uint32, now time.Time, randomNumber int32, ) error
HandleTransferDataInvocation answers one CLTU.
It applies the sequence rule of clause 3.6.2.5 itself, because that rule is the protocol rather than a policy: a CLTU whose number is not the expected one is refused with 'out of sequence', and the return carries the number the provider still wants. Everything else (whether there is buffer space, whether the time window is sane) is the caller's decision, passed in through accept.
bufferAvailable is the free buffer to report, in octets.
func (FCLTUProvider) Kind ¶
func (c FCLTUProvider) Kind() ServiceKind
Kind returns which service this is.
func (FCLTUProvider) NextPDU ¶
NextPDU takes the next PDU the caller should send, or reports false when there is nothing waiting.
func (FCLTUProvider) PeerAbort ¶
func (c FCLTUProvider) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
PeerAbort ends the association from this end.
func (FCLTUProvider) Pending ¶
func (c FCLTUProvider) Pending() int
Pending reports how many PDUs are waiting to be sent.
func (*FCLTUProvider) SendAsyncNotify ¶
func (p *FCLTUProvider) SendAsyncNotify(n *FCLTUAsyncNotifyInvocation, now time.Time) error
SendAsyncNotify queues a notification about a CLTU or the channel. Valid in states 2 and 3: a production status change is worth reporting whether or not CLTUs are flowing.
func (FCLTUProvider) State ¶
func (c FCLTUProvider) State() ServiceState
State returns the service state.
type FCLTUProviderEvent ¶
type FCLTUProviderEvent struct {
Operation OperationType
BindInvocation *BindInvocation
UnbindInvocation *UnbindInvocation
StartInvocation *FCLTUStartInvocation
StopInvocation *StopInvocation
ScheduleStatusReportInvocation *ScheduleStatusReportInvocation
GetParameterInvocation *GetParameterInvocation
TransferDataInvocation *FCLTUTransferDataInvocation
ThrowEventInvocation *FCLTUThrowEventInvocation
PeerAbort *PeerAbort
}
FCLTUProviderEvent is one decoded PDU arriving at the provider.
type FCLTUStartDiagnostic ¶
type FCLTUStartDiagnostic int
FCLTUStartDiagnostic explains a refused START, from the specific alternative of DiagnosticCltuStart.
const ( FCLTUStartOutOfService FCLTUStartDiagnostic = 0 FCLTUStartUnableToComply FCLTUStartDiagnostic = 1 FCLTUStartProductionTimeExpired FCLTUStartDiagnostic = 2 FCLTUStartInvalidCltuId FCLTUStartDiagnostic = 3 )
func (FCLTUStartDiagnostic) String ¶
func (f FCLTUStartDiagnostic) String() string
String names the diagnostic.
type FCLTUStartInvocation ¶
type FCLTUStartInvocation struct {
Credentials *Credentials
InvokeId InvokeId
// FirstCltuIdentification is the number the user will put on its first
// CLTU. Everything after it must count up from here.
FirstCltuIdentification CltuIdentification
}
FCLTUStartInvocation is the CltuStartInvocation of annex A2.4. It opens the CLTU stream and fixes the number the first CLTU will carry.
func DecodeFCLTUStartInvocation ¶
func DecodeFCLTUStartInvocation(data []byte) (*FCLTUStartInvocation, error)
DecodeFCLTUStartInvocation parses a START invocation's content.
func (*FCLTUStartInvocation) Encode ¶
func (s *FCLTUStartInvocation) Encode() ([]byte, error)
Encode serializes the START invocation's content.
func (*FCLTUStartInvocation) Humanize ¶
func (s *FCLTUStartInvocation) Humanize() string
Humanize returns a human-readable summary.
type FCLTUStartReturn ¶
type FCLTUStartReturn struct {
Credentials *Credentials
InvokeId InvokeId
// Positive reports whether the provider accepted.
Positive bool
// StartRadiationTime is when the provider can begin radiating. Set when
// Positive.
StartRadiationTime Time
// StopRadiationTime bounds the window, or is undefined for "until further
// notice". Set when Positive.
StopRadiationTime ConditionalTime
// CommonDiagnostic is set when a refusal used the common alternative.
CommonDiagnostic Diagnostics
// SpecificDiagnostic is set when it used the FCLTU-specific one.
SpecificDiagnostic FCLTUStartDiagnostic
// UsedCommon says which alternative a refusal took.
UsedCommon bool
}
FCLTUStartReturn is the CltuStartReturn of annex A2.5.
Its positive result is not the empty NULL the return services use: it carries the window the provider has reserved for radiation.
func DecodeFCLTUStartReturn ¶
func DecodeFCLTUStartReturn(data []byte) (*FCLTUStartReturn, error)
DecodeFCLTUStartReturn parses a START return's content.
func (*FCLTUStartReturn) Encode ¶
func (s *FCLTUStartReturn) Encode() ([]byte, error)
Encode serializes the START return's content.
func (*FCLTUStartReturn) Humanize ¶
func (s *FCLTUStartReturn) Humanize() string
Humanize returns a human-readable summary.
type FCLTUStatusReportInvocation ¶
type FCLTUStatusReportInvocation struct {
Credentials *Credentials
LastProcessed CltuLastProcessed
LastOk CltuLastOk
ProductionStatus FCLTUProductionStatus
UplinkStatus UplinkStatus
// NumberOfCltusReceived counts CLTUs the provider accepted.
NumberOfCltusReceived uint32
// NumberOfCltusProcessed counts those it took off the queue.
NumberOfCltusProcessed uint32
// NumberOfCltusRadiated counts those that actually went out. The gap
// between these three is where CLTUs are being dropped.
NumberOfCltusRadiated uint32
// CltuBufferAvailable is the free buffer in octets.
CltuBufferAvailable uint32
}
FCLTUStatusReportInvocation is the CltuStatusReportInvocation of annex A2.5: the periodic summary of the forward channel.
func DecodeFCLTUStatusReportInvocation ¶
func DecodeFCLTUStatusReportInvocation(data []byte) (*FCLTUStatusReportInvocation, error)
DecodeFCLTUStatusReportInvocation parses a STATUS-REPORT invocation's content.
func (*FCLTUStatusReportInvocation) Encode ¶
func (s *FCLTUStatusReportInvocation) Encode() ([]byte, error)
Encode serializes the STATUS-REPORT invocation's content.
func (*FCLTUStatusReportInvocation) Humanize ¶
func (s *FCLTUStatusReportInvocation) Humanize() string
Humanize returns a human-readable summary.
type FCLTUThrowEventDiagnostic ¶
type FCLTUThrowEventDiagnostic int
FCLTUThrowEventDiagnostic explains a refused THROW-EVENT, from the specific alternative of DiagnosticCltuThrowEvent.
const ( FCLTUEventOperationNotSupported FCLTUThrowEventDiagnostic = 0 FCLTUEventIdOutOfSequence FCLTUThrowEventDiagnostic = 1 FCLTUEventNoSuchEvent FCLTUThrowEventDiagnostic = 2 )
func (FCLTUThrowEventDiagnostic) String ¶
func (f FCLTUThrowEventDiagnostic) String() string
String names the diagnostic.
type FCLTUThrowEventInvocation ¶
type FCLTUThrowEventInvocation struct {
Credentials *Credentials
InvokeId InvokeId
// EventInvocationIdentification numbers this invocation, ascending like
// the CLTU numbers.
EventInvocationIdentification EventInvocationId
// EventIdentifier names the event, 1 to 65535, defined by the service
// agreement.
EventIdentifier uint16
// EventQualifier is the event's argument, 1 to 1024 octets, also defined
// by the service agreement.
EventQualifier []byte
}
FCLTUThrowEventInvocation is the CltuThrowEventInvocation of annex A2.4.
THROW-EVENT is the odd operation of this service. It does not carry data to the spacecraft; it asks the provider's own equipment to do something the service agreement defines, switch an antenna, change a modulation setting, start a ranging measurement. The library cannot know what the events mean, so it carries the identifier and qualifier through untouched.
func DecodeFCLTUThrowEventInvocation ¶
func DecodeFCLTUThrowEventInvocation(data []byte) (*FCLTUThrowEventInvocation, error)
DecodeFCLTUThrowEventInvocation parses a THROW-EVENT invocation's content.
func (*FCLTUThrowEventInvocation) Encode ¶
func (e *FCLTUThrowEventInvocation) Encode() ([]byte, error)
Encode serializes the THROW-EVENT invocation's content.
func (*FCLTUThrowEventInvocation) Humanize ¶
func (e *FCLTUThrowEventInvocation) Humanize() string
Humanize returns a human-readable summary.
type FCLTUThrowEventReturn ¶
type FCLTUThrowEventReturn struct {
Credentials *Credentials
InvokeId InvokeId
// EventInvocationIdentification echoes the invocation this answers.
EventInvocationIdentification EventInvocationId
// Positive reports whether the provider accepted the event.
Positive bool
// CommonDiagnostic is set when a refusal used the common alternative.
CommonDiagnostic Diagnostics
// SpecificDiagnostic is set when it used the FCLTU-specific one.
SpecificDiagnostic FCLTUThrowEventDiagnostic
// UsedCommon says which alternative a refusal took.
UsedCommon bool
}
FCLTUThrowEventReturn is the CltuThrowEventReturn of annex A2.5.
func DecodeFCLTUThrowEventReturn ¶
func DecodeFCLTUThrowEventReturn(data []byte) (*FCLTUThrowEventReturn, error)
DecodeFCLTUThrowEventReturn parses a THROW-EVENT return's content.
func (*FCLTUThrowEventReturn) Encode ¶
func (e *FCLTUThrowEventReturn) Encode() ([]byte, error)
Encode serializes the THROW-EVENT return's content.
func (*FCLTUThrowEventReturn) Humanize ¶
func (e *FCLTUThrowEventReturn) Humanize() string
Humanize returns a human-readable summary.
type FCLTUTransferDataDiagnostic ¶
type FCLTUTransferDataDiagnostic int
FCLTUTransferDataDiagnostic explains a refused CLTU, from the specific alternative of DiagnosticCltuTransferData.
const ( FCLTUDataUnableToProcess FCLTUTransferDataDiagnostic = 0 FCLTUDataUnableToStore FCLTUTransferDataDiagnostic = 1 FCLTUDataOutOfSequence FCLTUTransferDataDiagnostic = 2 FCLTUDataInconsistentTimeRange FCLTUTransferDataDiagnostic = 3 FCLTUDataInvalidTime FCLTUTransferDataDiagnostic = 4 FCLTUDataLateSldu FCLTUTransferDataDiagnostic = 5 FCLTUDataInvalidDelayTime FCLTUTransferDataDiagnostic = 6 FCLTUDataCltuError FCLTUTransferDataDiagnostic = 7 )
func (FCLTUTransferDataDiagnostic) String ¶
func (f FCLTUTransferDataDiagnostic) String() string
String names the diagnostic.
type FCLTUTransferDataInvocation ¶
type FCLTUTransferDataInvocation struct {
Credentials *Credentials
InvokeId InvokeId
// CltuIdentification numbers this CLTU. It must be one more than the last.
CltuIdentification CltuIdentification
// EarliestTransmissionTime and LatestTransmissionTime bound when the CLTU
// may be radiated. Either may be undefined, leaving that end open.
EarliestTransmissionTime ConditionalTime
LatestTransmissionTime ConditionalTime
// DelayTime is how long, in microseconds, the provider must wait after the
// previous CLTU before radiating this one.
DelayTime uint32
// RadiationNotification says whether the user wants an ASYNC-NOTIFY when
// this CLTU is dealt with.
RadiationNotification SlduStatusNotification
// Data is the CLTU itself, 1 to 65536 octets: the acquisition sequence,
// start sequence, codeblocks and tail sequence that pkg/tcsc builds.
Data []byte
}
FCLTUTransferDataInvocation is the CltuTransferDataInvocation of annex A2.4: one CLTU handed to the provider for radiation.
func DecodeFCLTUTransferDataInvocation ¶
func DecodeFCLTUTransferDataInvocation(data []byte) (*FCLTUTransferDataInvocation, error)
DecodeFCLTUTransferDataInvocation parses a TRANSFER-DATA invocation's content.
func (*FCLTUTransferDataInvocation) Encode ¶
func (t *FCLTUTransferDataInvocation) Encode() ([]byte, error)
Encode serializes the TRANSFER-DATA invocation's content.
func (*FCLTUTransferDataInvocation) Humanize ¶
func (t *FCLTUTransferDataInvocation) Humanize() string
Humanize returns a human-readable summary.
type FCLTUTransferDataReturn ¶
type FCLTUTransferDataReturn struct {
Credentials *Credentials
InvokeId InvokeId
// CltuIdentification echoes the CLTU this answers. On a refusal it is the
// number the provider expected next, which tells the user where to resume.
CltuIdentification CltuIdentification
// CltuBufferAvailable is the free buffer in octets. This is the service's
// flow control: a user that ignores it will be refused for lack of store.
CltuBufferAvailable uint32
// Positive reports whether the CLTU was accepted.
Positive bool
// CommonDiagnostic is set when a refusal used the common alternative.
CommonDiagnostic Diagnostics
// SpecificDiagnostic is set when it used the FCLTU-specific one.
SpecificDiagnostic FCLTUTransferDataDiagnostic
// UsedCommon says which alternative a refusal took.
UsedCommon bool
}
FCLTUTransferDataReturn is the CltuTransferDataReturn of annex A2.5: the provider saying whether it took the CLTU, and how much room is left.
func DecodeFCLTUTransferDataReturn ¶
func DecodeFCLTUTransferDataReturn(data []byte) (*FCLTUTransferDataReturn, error)
DecodeFCLTUTransferDataReturn parses a TRANSFER-DATA return's content.
func (*FCLTUTransferDataReturn) Encode ¶
func (t *FCLTUTransferDataReturn) Encode() ([]byte, error)
Encode serializes the TRANSFER-DATA return's content.
func (*FCLTUTransferDataReturn) Humanize ¶
func (t *FCLTUTransferDataReturn) Humanize() string
Humanize returns a human-readable summary.
type FCLTUUser ¶
type FCLTUUser struct {
*ServiceUser
// contains filtered or unexported fields
}
FCLTUUser is the user half of a Forward CLTU instance.
It carries one piece of state the return services have no equivalent for: the next CLTU identification. CCSDS 912.1-B-5 clause 3.6.2.5.1 makes the number the user's to keep. It starts at the START invocation's firstCltuIdentification and goes up by one for every CLTU the provider accepts. Get it wrong and the provider answers 'out of sequence' and discards the CLTU, so the machine keeps the count rather than trusting the caller to.
The number advances as each CLTU is sent, not as each return arrives, Clause 3.1.6 expects the user to pipeline CLTUs without waiting for returns, and each one it sends must carry the next number. A refusal is where the count corrects itself: Clause 3.6.2.5.2b makes the provider quote the number it expected, so a user that fell out of step resynchronises from the refusal.
THROW-EVENT identifications work the same way (clause 3.9): the machine numbers each invocation, and a refusal quotes the identification the provider expected, which resynchronises the count.
func NewFCLTUUser ¶
func NewFCLTUUser(config ServiceConfig) (*FCLTUUser, error)
NewFCLTUUser prepares the user half of an FCLTU instance.
func (FCLTUUser) Association ¶
func (c FCLTUUser) Association() *Association
Association returns the association underneath.
func (FCLTUUser) DeliveryMode ¶
func (c FCLTUUser) DeliveryMode() DeliveryMode
DeliveryMode returns the configured delivery mode.
func (*FCLTUUser) HandlePDU ¶
HandlePDU decodes one PDU from the provider and advances the machine.
A refused CLTU comes back as an event with TransferDataReturn set and ErrCltuOutOfSequence as the error: the PDU is valid and worth reading, and the error says the queue is no longer in step.
func (FCLTUUser) HandlePeerAbort ¶
HandlePeerAbort takes an inbound PEER-ABORT: the association is over.
func (*FCLTUUser) HandleStartReturn ¶
func (u *FCLTUUser) HandleStartReturn(r *FCLTUStartReturn) error
HandleStartReturn takes the answer to START. A positive answer moves to state 3 and arms the CLTU counter at the number the START asked for.
func (*FCLTUUser) HandleThrowEventReturn ¶
func (u *FCLTUUser) HandleThrowEventReturn(r *FCLTUThrowEventReturn) error
HandleThrowEventReturn takes the answer to a THROW-EVENT.
A positive answer means the provider accepted the request, not that the event happened: whether the actions ran arrives later, in an ASYNC-NOTIFY carrying actionListCompleted or actionListNotCompleted.
A refusal echoes the event invocation identification the provider expected (clause 3.9.2.5), so the machine resynchronises its counter from it, the same recovery the CLTU numbers get.
func (*FCLTUUser) HandleTransferDataReturn ¶
func (u *FCLTUUser) HandleTransferDataReturn(r *FCLTUTransferDataReturn) error
HandleTransferDataReturn takes the answer to one CLTU.
On acceptance the counter has already moved (it advanced when the CLTU was sent) so the return changes nothing. On refusal the counter is set to the number the provider says it expects, which clause 3.6.2.5.2b guarantees is in the return: a user that lost its place recovers without another START.
func (*FCLTUUser) NextCltuIdentification ¶
func (u *FCLTUUser) NextCltuIdentification() (CltuIdentification, bool)
NextCltuIdentification reports the number the next CLTU will carry, and whether a START has fixed it yet.
func (*FCLTUUser) NextEventInvocationId ¶
func (u *FCLTUUser) NextEventInvocationId() EventInvocationId
NextEventInvocationId reports the identification the next THROW-EVENT will carry.
func (FCLTUUser) NextPDU ¶
NextPDU takes the next PDU the caller should send, or reports false when there is nothing waiting.
func (FCLTUUser) PeerAbort ¶
func (c FCLTUUser) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
PeerAbort ends the association from this end.
func (FCLTUUser) Pending ¶
func (c FCLTUUser) Pending() int
Pending reports how many PDUs are waiting to be sent.
func (*FCLTUUser) Start ¶
func (u *FCLTUUser) Start( now time.Time, randomNumber int32, first CltuIdentification, ) (InvokeId, error)
Start opens the CLTU stream, fixing the first CLTU's number. State 2 only, per clause 3.4.1.4.
func (*FCLTUUser) ThrowEvent ¶
func (u *FCLTUUser) ThrowEvent( now time.Time, randomNumber int32, event uint16, qualifier []byte, ) (InvokeId, EventInvocationId, error)
ThrowEvent asks the provider's equipment to do something the service agreement defines. Valid in states 2 and 3, per clause 3.9.1.
The event invocation identification comes from the machine's counter, not from the caller: Clause 3.9.2.4 makes it a sequence the user must keep, exactly like the CLTU numbers. The identification used is returned, and it advances as the invocation is sent.
func (*FCLTUUser) TransferData ¶
func (u *FCLTUUser) TransferData( now time.Time, randomNumber int32, cltu []byte, earliest, latest ConditionalTime, delay uint32, notification SlduStatusNotification, ) (InvokeId, CltuIdentification, error)
TransferData queues one CLTU for radiation. State 3 only, per clause 3.6.1.
The CLTU's identification is taken from the machine's counter, not from the caller: Clause 3.6.2.5.1 defines it as a sequence the user must keep unbroken. The data is a CLTU as pkg/tcsc.WrapCLTU builds one, acquisition sequence, start sequence, codeblocks and tail sequence.
type FCLTUUserEvent ¶
type FCLTUUserEvent struct {
Operation OperationType
BindReturn *BindReturn
UnbindReturn *UnbindReturn
StartReturn *FCLTUStartReturn
StopReturn *Acknowledgement
ScheduleStatusReportReturn *ScheduleStatusReportReturn
GetParameterReturn *GetParameterReturn
TransferDataReturn *FCLTUTransferDataReturn
ThrowEventReturn *FCLTUThrowEventReturn
AsyncNotify *FCLTUAsyncNotifyInvocation
StatusReport *FCLTUStatusReportInvocation
PeerAbort *PeerAbort
}
FCLTUUserEvent is one decoded PDU arriving at the user.
type FrameQuality ¶
type FrameQuality int
FrameQuality reports what a delivered frame turned out to be, from the FrameQuality INTEGER of the RAF structures module.
const ( // FrameGood passed error control. FrameGood FrameQuality = 0 // FrameErred failed it. FrameErred FrameQuality = 1 // FrameUndetermined could not be assessed. FrameUndetermined FrameQuality = 2 )
type GVCID ¶
type GVCID struct {
// SpacecraftID is the spacecraft identifier.
SpacecraftID uint16
// VersionNumber is the transfer frame version: 0 for TM, 1 for AOS.
VersionNumber uint8
// VirtualChannelID is the virtual channel, or absent for a master channel.
VirtualChannelID uint8
// MasterChannel reports whether this names a master channel rather than a
// virtual one, in which case VirtualChannelID is meaningless.
MasterChannel bool
}
GVCID identifies a global virtual channel: a spacecraft, a transfer frame version, and a virtual channel within it.
RCF and ROCF filter by it. The frame packages in this repository carry the same fields on their headers but have no shared type for the triple, so it lives here.
func DecodeGVCID ¶
DecodeGVCID reads a GvcId SEQUENCE from an element.
type GetParameterDiagnostic ¶
type GetParameterDiagnostic int
GetParameterDiagnostic is the specific alternative of the DiagnosticRafGet / DiagnosticRcfGet / DiagnosticRocfGet / DiagnosticCltuGetParameter CHOICE. All four define the same single value.
const GetParameterUnknown GetParameterDiagnostic = 0
GetParameterUnknown is 'unknownParameter (0)': the provider does not have the named parameter.
func (GetParameterDiagnostic) String ¶
func (g GetParameterDiagnostic) String() string
String names the diagnostic.
type GetParameterInvocation ¶
type GetParameterInvocation struct {
Credentials *Credentials
InvokeId InvokeId
// Parameter is the service's ParameterName value, from annex A of the
// service specification. The names differ per service, so this package
// does not enumerate them.
Parameter int
}
GetParameterInvocation is the GET-PARAMETER invocation every service shares: RafGetParameterInvocation and its three siblings are the same three fields.
func DecodeGetParameterInvocation ¶
func DecodeGetParameterInvocation(data []byte) (*GetParameterInvocation, error)
DecodeGetParameterInvocation parses a GET-PARAMETER invocation's content.
func (*GetParameterInvocation) Encode ¶
func (g *GetParameterInvocation) Encode() ([]byte, error)
Encode serializes the GET-PARAMETER invocation's content.
func (*GetParameterInvocation) Humanize ¶
func (g *GetParameterInvocation) Humanize() string
Humanize returns a human-readable summary.
type GetParameterReturn ¶
type GetParameterReturn struct {
Credentials *Credentials
InvokeId InvokeId
// Positive reports whether the provider had the parameter.
Positive bool
// Parameter is the chosen alternative of the service's parameter CHOICE,
// still encoded: one complete BER element. Set when Positive.
Parameter []byte
// CommonDiagnostic is set when a refusal used the common alternative.
CommonDiagnostic Diagnostics
// SpecificDiagnostic is set when it used the specific one, whose only
// value is 'unknown parameter'.
SpecificDiagnostic GetParameterDiagnostic
// UsedCommon says which alternative a refusal took.
UsedCommon bool
}
GetParameterReturn is the GET-PARAMETER return every service shares in shape:
result CHOICE
{ positiveResult [0] <service>GetParameter
, negativeResult [1] Diagnostic<service>Get
}
The positive alternative's parameter CHOICE is service-specific and large, so it travels here as raw BER rather than a per-parameter Go type.
func DecodeGetParameterReturn ¶
func DecodeGetParameterReturn(data []byte) (*GetParameterReturn, error)
DecodeGetParameterReturn parses a GET-PARAMETER return's content.
func (*GetParameterReturn) DecodeParameter ¶ added in v0.4.0
func (g *GetParameterReturn) DecodeParameter(service ServiceKind) (*ServiceParameter, bool, error)
DecodeParameter decodes this return's positive result against a service's parameter set.
It reports false when the return is negative, a provider answering 'unknown parameter', which the specs define for exactly the case where it does not have the one asked for.
func (*GetParameterReturn) Encode ¶
func (g *GetParameterReturn) Encode() ([]byte, error)
Encode serializes the GET-PARAMETER return's content.
func (*GetParameterReturn) Humanize ¶
func (g *GetParameterReturn) Humanize() string
Humanize returns a human-readable summary.
type Instance ¶ added in v0.4.0
type Instance struct {
// Name is the service instance identifier, rendered the way operators
// write it.
Name string
// Provider answers the operations a user drives.
Provider *ServiceProvider
// Production runs the transfer buffer, or nil for an instance configured
// without one.
Production *Production
// contains filtered or unexported fields
}
Instance is one service instance in the complex: its provider, and its production when it has any.
func (*Instance) Kind ¶ added in v0.4.0
func (i *Instance) Kind() ServiceKind
Kind names the service this instance provides.
type InstanceConfig ¶ added in v0.4.0
type InstanceConfig struct {
// Service is the instance's own configuration, as NewServiceProvider
// takes it.
Service ServiceConfig
// Production configures the transfer buffer and production status. A
// zero value leaves the instance without production, which is what a
// forward service like FCLTU wants: it has no frames to buffer.
Production *ProductionConfig
}
InstanceConfig describes one service instance the complex will serve.
type InvokeId ¶
type InvokeId uint16
InvokeId correlates a confirmed operation's invocation with its return. IntUnsignedShort: INTEGER (0 .. 65535).
type LockStatus ¶
type LockStatus int
LockStatus reports whether one stage of the receive chain is locked, from the RAF structures module.
const ( LockInLock LockStatus = 0 LockOutOfLock LockStatus = 1 LockNotInUse LockStatus = 2 LockUnknown LockStatus = 3 )
type LockStatusReport ¶
type LockStatusReport struct {
Time Time
CarrierLockStatus LockStatus
SubcarrierLockStatus LockStatus
SymbolSyncLockStatus LockStatus
}
LockStatusReport is the lock state of each stage of the receive chain at a moment, carried by a loss-of-frame-sync notification.
type Message ¶
type Message struct {
Type MessageType
// Body is the message body: an encoded SLE PDU, a context body, or empty
// for a heartbeat.
Body []byte
}
Message is one TML message.
func DecodeMessage ¶
DecodeMessage parses one complete TML message from the front of data, returning it and the octets consumed.
func DecodeMessageWithLimit ¶
DecodeMessageWithLimit parses one message, refusing a body beyond maxBody.
func HeartbeatMessage ¶
func HeartbeatMessage() *Message
HeartbeatMessage returns a TML heartbeat: a header with an empty body.
func ReadMessage ¶
ReadMessage reads one TML message from r.
It reads the eight-octet header, then exactly as many body octets as the header promises, and no further. That matters on a stream: reading ahead would swallow the start of the next message.
type MessageType ¶
type MessageType uint8
MessageType is the TML message type identifier of table 3-1.
const ( // MessageSLEPDU carries an encoded SLE protocol data unit. MessageSLEPDU MessageType = 1 // MessageContext carries the TML initialization parameters. It is the // first message on a connection. MessageContext MessageType = 2 // MessageHeartbeat probes an idle connection. Its body is empty. MessageHeartbeat MessageType = 3 )
func (MessageType) Valid ¶
func (m MessageType) Valid() bool
Valid reports whether the type is one of the three of table 3-1.
type NotificationKind ¶
type NotificationKind int
NotificationKind says which alternative a sync notification took, from the Notification CHOICE of CCSDS 911.1-B-5 annex A, which 911.2-B-4 and 911.5-B-4 repeat unchanged.
const ( // NotifyLossFrameSync reports that frame synchronization was lost, and // carries the lock status of each stage. NotifyLossFrameSync NotificationKind = 0 // NotifyProductionStatusChange reports a change in the channel's state. NotifyProductionStatusChange NotificationKind = 1 // NotifyExcessiveDataBacklog reports the provider cannot keep up. NotifyExcessiveDataBacklog NotificationKind = 2 // NotifyEndOfData reports the requested range is exhausted. NotifyEndOfData NotificationKind = 3 )
func (NotificationKind) String ¶
func (n NotificationKind) String() string
String names the notification.
type OperationType ¶
type OperationType int
OperationType names an SLE operation, independent of which service carries it. The wire tags differ per service; this does not.
const ( OpUnknown OperationType = iota OpBindInvocation OpBindReturn OpUnbindInvocation OpUnbindReturn OpPeerAbort OpStartInvocation OpStartReturn OpStopInvocation OpStopReturn OpScheduleStatusReportInvocation OpScheduleStatusReportReturn OpGetParameterInvocation OpGetParameterReturn OpTransferBuffer OpStatusReportInvocation OpTransferDataInvocation OpAsyncNotifyInvocation OpThrowEventInvocation OpThrowEventReturn OpTransferDataReturn )
type PDU ¶
type PDU struct {
Service ServiceKind
Operation OperationType
// Tag is the wire tag it arrived under.
Tag uint32
// Content is the operation's encoded content, ready for the matching
// decoder.
Content []byte
}
PDU is one decoded SLE protocol data unit: which operation it is, and its still-encoded content.
type ParameterName ¶ added in v0.4.0
type ParameterName int32
ParameterName is the schema's ParameterName: the integer that names a configuration parameter.
The values are not contiguous and not ordered (acquisitionSequenceLength is 201 while apidList is 2) because the enumeration grew across issues and each service's additions were given their own range. They are transcribed from the INTEGER definition in CCSDS 911.1-B-5 annex A.
const ( ParamAcquisitionSequenceLength ParameterName = 201 ParamAPIDList ParameterName = 2 ParamBitLockRequired ParameterName = 3 ParamBlockingTimeoutPeriod ParameterName = 0 ParamBlockingUsage ParameterName = 1 ParamBufferSize ParameterName = 4 ParamClcwGlobalVcID ParameterName = 202 ParamClcwPhysicalChannel ParameterName = 203 ParamCopCntrFramesRepetition ParameterName = 300 ParamDeliveryMode ParameterName = 6 ParamDirectiveInvocation ParameterName = 7 ParamDirectiveInvocationOnline ParameterName = 108 ParamExpectedDirectiveIdentification ParameterName = 8 ParamExpectedEventInvocationIdentification ParameterName = 9 ParamExpectedSlduIdentification ParameterName = 10 ParamFopSlidingWindow ParameterName = 11 ParamFopState ParameterName = 12 ParamLatencyLimit ParameterName = 15 ParamMapList ParameterName = 16 ParamMapMuxControl ParameterName = 17 ParamMapMuxScheme ParameterName = 18 ParamMaximumFrameLength ParameterName = 19 ParamMaximumPacketLength ParameterName = 20 ParamMaximumSlduLength ParameterName = 21 ParamMinimumDelayTime ParameterName = 204 ParamMinReportingCycle ParameterName = 301 ParamModulationFrequency ParameterName = 22 ParamModulationIndex ParameterName = 23 ParamNotificationMode ParameterName = 205 ParamPermittedControlWordTypeSet ParameterName = 101 ParamPermittedFrameQuality ParameterName = 302 ParamPermittedGvcidSet ParameterName = 24 ParamPermittedTcVcidSet ParameterName = 102 ParamPermittedTransmissionMode ParameterName = 107 ParamPermittedUpdateModeSet ParameterName = 103 ParamPlop1IdleSequenceLength ParameterName = 206 ParamPlopInEffect ParameterName = 25 ParamProtocolAbortMode ParameterName = 207 ParamReportingCycle ParameterName = 26 ParamRequestedControlWordType ParameterName = 104 ParamRequestedFrameQuality ParameterName = 27 ParamRequestedGvcid ParameterName = 28 ParamRequestedTcVcid ParameterName = 105 ParamRequestedUpdateMode ParameterName = 106 ParamReturnTimeoutPeriod ParameterName = 29 ParamRfAvailable ParameterName = 30 ParamRfAvailableRequired ParameterName = 31 ParamSegmentHeader ParameterName = 32 ParamSequCntrFramesRepetition ParameterName = 303 ParamSubcarrierToBitRateRatio ParameterName = 34 ParamThrowEventOperation ParameterName = 304 ParamTimeoutType ParameterName = 35 ParamTimerInitial ParameterName = 36 ParamTransmissionLimit ParameterName = 37 ParamTransmitterFrameSequenceNumber ParameterName = 38 ParamVcMuxControl ParameterName = 39 ParamVcMuxScheme ParameterName = 40 ParamVirtualChannel ParameterName = 41 )
The parameter names, from CCSDS 911.1-B-5 annex A.
func (ParameterName) String ¶ added in v0.4.0
func (p ParameterName) String() string
String returns the schema's spelling of the name.
type PeerAbort ¶
type PeerAbort struct {
Diagnostic PeerAbortDiagnostic
}
PeerAbort is the SlePeerAbort of annex A2.2: a bare diagnostic, with no credentials and no surrounding sequence.
func DecodePeerAbort ¶
DecodePeerAbort parses a PEER-ABORT's content: the bare diagnostic octets found under the primitive [104] tag.
The legacy shape this package once emitted (a complete INTEGER TLV nested under a constructed [104]) is still recognized, so an old peer's abort is read rather than mistaken for a huge diagnostic.
func (*PeerAbort) Encode ¶
Encode serializes the PEER-ABORT's content: the bare two's complement octets of the diagnostic.
The SLE modules are DEFINITIONS IMPLICIT TAGS, and the PDU CHOICE makes the operation [104] IMPLICIT SlePeerAbort, so [104] replaces the INTEGER tag rather than wrapping it. On the wire the whole PDU is a primitive context-specific element, 9F 68 01 xx, with no nested INTEGER TLV.
func (*PeerAbort) UrgentData ¶
UrgentData returns the diagnostic as the single octet CCSDS 913.1-B-2 clause 3.4 maps onto TCP urgent data. The aborting end sends this octet out of band (MSG_OOB) before closing the connection, so the peer can tell an abort from a failure; this package owns no socket, so sending it is the caller's job.
type PeerAbortDiagnostic ¶
type PeerAbortDiagnostic int
PeerAbortDiagnostic explains an abrupt end to an association, from the PeerAbortDiagnostic INTEGER of annex A2.2. Values 128 to 255 are reserved for the communications technology in use.
const ( AbortAccessDenied PeerAbortDiagnostic = 0 AbortUnexpectedResponderID PeerAbortDiagnostic = 1 AbortOperationalRequirement PeerAbortDiagnostic = 2 AbortProtocolError PeerAbortDiagnostic = 3 AbortCommunicationsFailure PeerAbortDiagnostic = 4 AbortEncodingError PeerAbortDiagnostic = 5 AbortReturnTimeout PeerAbortDiagnostic = 6 AbortEndOfServiceProvisionPeriod PeerAbortDiagnostic = 7 AbortUnsolicitedInvokeID PeerAbortDiagnostic = 8 AbortOtherReason PeerAbortDiagnostic = 127 )
func (PeerAbortDiagnostic) String ¶
func (p PeerAbortDiagnostic) String() string
String names the diagnostic.
type Production ¶ added in v0.4.0
type Production struct {
// contains filtered or unexported fields
}
Production runs the transfer buffer and the production status for one service instance.
It owns no clock. Every method that could involve time takes the time, and the release timer is checked by the caller through Due and Expired, which is the same bargain the rest of this library makes: a library that sleeps is a library you cannot test.
It is safe for concurrent use, because production and the association that drains it are naturally different goroutines.
func NewProduction ¶ added in v0.4.0
func NewProduction(config ProductionConfig) (*Production, error)
NewProduction prepares production for one service instance.
The initial status is halted, per clause B2.3: production is not yet configured for the instance. A caller that has configured it calls SetRunning.
func (*Production) Abort ¶ added in v0.4.0
func (p *Production) Abort()
Abort clears the transfer buffer without delivering it (clause 3.1.9.1.12).
An aborted association has nowhere to deliver to, so the contents go rather than waiting for a connection that is not coming back. The counters are kept: they describe the instance, not the association.
func (*Production) Backpressure ¶ added in v0.4.0
func (p *Production) Backpressure(now time.Time) bool
Backpressure handles the communications service refusing a released buffer (clause 3.1.9.1.9).
The whole buffer is discarded rather than the one record that would not fit, a 'data discarded due to excessive backlog' notification is inserted, and the release timer is restarted. Per clause 3.1.9.1.10 the buffer's size is incremented by one while that notification waits, so a channel configured with a buffer size of one still carries some telemetry rather than nothing but notifications.
It returns whether the buffer is due again, which it is when the size is one: the notification alone then fills it.
func (*Production) Capacity ¶ added in v0.4.0
func (p *Production) Capacity() int
Capacity reports the buffer's current size, including the temporary increment of clause 3.1.9.1.10 when one is in effect.
func (*Production) Counters ¶ added in v0.4.0
func (p *Production) Counters() (released, discarded int)
Counters reports how many buffers have been released and how many discarded for backpressure.
func (*Production) Deadline ¶ added in v0.4.0
func (p *Production) Deadline() (time.Time, bool)
Deadline reports when the release timer expires, and whether one is running.
A caller driving this from a select loop uses it to size its wait rather than polling Due.
func (*Production) Due ¶ added in v0.4.0
func (p *Production) Due(now time.Time) bool
Due reports whether the buffer should be released now: it is full, or the release timer has expired.
func (*Production) Expired ¶ added in v0.4.0
func (p *Production) Expired(now time.Time) bool
Expired reports whether the release timer has run out (clause 3.1.9.1.5).
It is false when no timer is running, which is the case for an empty buffer and for a configuration with no latency limit.
func (*Production) Humanize ¶ added in v0.4.0
func (p *Production) Humanize() string
Humanize returns a human-readable summary.
func (*Production) Insert ¶ added in v0.4.0
func (p *Production) Insert(frame *RAFTransferDataInvocation, now time.Time) (due bool, err error)
Insert puts one annotated frame into the transfer buffer.
It reports whether the buffer is now due for release, which happens when the buffer is full (clause 3.1.9.1.7a). A caller inserting frames checks the return and calls Release when it is true; it also has to check Expired between inserts, because the release timer can fire while nothing is arriving.
Frames are refused unless production is running: a provider that is halted or interrupted has no data to deliver, and buffering one anyway would deliver it late and out of sequence when production resumed.
func (*Production) InsertNotification ¶ added in v0.4.0
func (p *Production) InsertNotification(notification *SyncNotifyInvocation, now time.Time) (due bool, err error)
InsertNotification puts one synchronous notification into the transfer buffer.
Notifications are accepted whatever production is doing, because the notifications are how a user learns production stopped. Clause 3.1.9.1.3 requires a status-change notification to sit in sequence between the frames acquired before the event and those after it, which is only possible if it goes through the same buffer.
An 'end of data' notification releases the buffer at once (clause 3.1.9.1.7c), which is why this reports due as well.
func (*Production) Pending ¶ added in v0.4.0
func (p *Production) Pending() int
Pending reports how many records are waiting in the transfer buffer.
func (*Production) Release ¶ added in v0.4.0
func (p *Production) Release() RAFTransferBuffer
Release takes the buffer's contents to hand to the communications service.
It returns the records in insertion order (clause 3.1.9.1.8) and clears the buffer, stopping the release timer. An empty buffer yields nil, which is not an error: a caller may release on a schedule and find nothing waiting.
The temporary size increment of clause 3.1.9.1.10 is given back here, since the clause ties it to the buffer being passed to the communications service.
func (*Production) SetHalted ¶ added in v0.4.0
func (p *Production) SetHalted() (*SyncNotifyInvocation, bool)
SetHalted moves production to halted, which table B-1 allows from any state: it is direct management action.
func (*Production) SetInterrupted ¶ added in v0.4.0
func (p *Production) SetInterrupted() (*SyncNotifyInvocation, bool)
SetInterrupted moves production to interrupted, which table B-1 allows only from running: it is the provider detecting a production fault.
From halted it is refused. Halted means production is not configured, so there is nothing running to be interrupted, and reporting one would tell a user the channel had failed rather than that it was never started.
func (*Production) SetRunning ¶ added in v0.4.0
func (p *Production) SetRunning() (*SyncNotifyInvocation, bool)
SetRunning moves production to running.
Table B-1 allows it from halted (management has configured production) and from interrupted (the provider has detected the fault is corrected). It returns the notification to deliver, which the caller inserts into the buffer; clause 3.1.9.1.3 puts a status-change notification in sequence with the frames, not out of band.
Calling it when production is already running changes nothing and yields no notification: table B-1 lists notifications against transitions, and a non-transition is not one.
func (*Production) Status ¶ added in v0.4.0
func (p *Production) Status() ProductionStatus
Status reports the current production status.
func (*Production) Stop ¶ added in v0.4.0
func (p *Production) Stop() RAFTransferBuffer
Stop builds the buffer for immediate delivery on an accepted STOP invocation (clause 3.1.9.1.11).
The clause requires the provider to build and pass the buffer at once rather than waiting for the timer, so a user that stops a service gets what production had already recovered.
type ProductionConfig ¶ added in v0.4.0
type ProductionConfig struct {
// BufferSize is transfer-buffer-size: how many transfer-data and
// sync-notify records the buffer holds before it must be released
// (clause 3.1.9.1.6). It must be at least one.
BufferSize int
// LatencyLimit is how long the release timer runs from the moment a
// record enters an empty buffer (clause 3.1.9.1.5). Zero means no timer, which
// is the offline and complete-online case: Clause 3.1.9.1 requires the timer
// only for timely online delivery, though the buffer itself is used in
// every mode.
LatencyLimit time.Duration
}
ProductionConfig is what service management sets for one service instance (clause 3.1.9.1.5 and clause 3.1.9.1.6).
func (ProductionConfig) Validate ¶ added in v0.4.0
func (c ProductionConfig) Validate() error
Validate checks the configuration.
type ProductionStatus ¶
type ProductionStatus int
ProductionStatus is the state of the return physical channel, from the RAF structures module and annex B.
const ( // ProductionRunning means the channel is producing data. ProductionRunning ProductionStatus = 0 // ProductionInterrupted means production stopped unexpectedly and may resume. ProductionInterrupted ProductionStatus = 1 // ProductionHalted means production ended and will not resume. ProductionHalted ProductionStatus = 2 )
func (ProductionStatus) String ¶
func (p ProductionStatus) String() string
String names the production status.
type RAFProvider ¶
type RAFProvider struct {
*ServiceProvider
}
RAFProvider is the provider half of a RAF instance. Pair it with a Production for the transfer buffer that clause 3.1.9.1 requires of a return service.
func NewRAFProvider ¶
func NewRAFProvider(config ServiceConfig) (*RAFProvider, error)
NewRAFProvider prepares the provider half of a RAF instance.
func (RAFProvider) Association ¶
func (c RAFProvider) Association() *Association
Association returns the association underneath.
func (RAFProvider) DeliveryMode ¶
func (c RAFProvider) DeliveryMode() DeliveryMode
DeliveryMode returns the configured delivery mode.
func (*RAFProvider) HandlePDU ¶
func (p *RAFProvider) HandlePDU(data []byte, now time.Time) (*RAFProviderEvent, error)
HandlePDU decodes one PDU from the user. Unlike the user's HandlePDU this only decodes and reports: the answer is the caller's to compose, because only the caller knows whether the provider can comply.
func (RAFProvider) HandlePeerAbort ¶
HandlePeerAbort takes an inbound PEER-ABORT: the association is over.
func (*RAFProvider) HandleStartInvocation ¶
func (p *RAFProvider) HandleStartInvocation( s *RAFStartInvocation, answer *RAFStartReturn, now time.Time, randomNumber int32, ) error
HandleStartInvocation answers a START. Accepting moves to state 3, which is state table row 9's positive branch.
func (RAFProvider) Kind ¶
func (c RAFProvider) Kind() ServiceKind
Kind returns which service this is.
func (RAFProvider) NextPDU ¶
NextPDU takes the next PDU the caller should send, or reports false when there is nothing waiting.
func (RAFProvider) PeerAbort ¶
func (c RAFProvider) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
PeerAbort ends the association from this end.
func (RAFProvider) Pending ¶
func (c RAFProvider) Pending() int
Pending reports how many PDUs are waiting to be sent.
func (*RAFProvider) SendTransferBuffer ¶
func (p *RAFProvider) SendTransferBuffer(buffer RAFTransferBuffer, now time.Time) error
SendTransferBuffer queues a buffer of frames and notifications. State 3 only, per clause 3.6.1.3.
func (RAFProvider) State ¶
func (c RAFProvider) State() ServiceState
State returns the service state.
type RAFProviderEvent ¶
type RAFProviderEvent struct {
Operation OperationType
BindInvocation *BindInvocation
UnbindInvocation *UnbindInvocation
StartInvocation *RAFStartInvocation
StopInvocation *StopInvocation
ScheduleStatusReportInvocation *ScheduleStatusReportInvocation
GetParameterInvocation *GetParameterInvocation
PeerAbort *PeerAbort
}
RAFProviderEvent is one decoded PDU arriving at the provider.
type RAFStartDiagnostic ¶
type RAFStartDiagnostic int
RAFStartDiagnostic explains a refused START, from the DiagnosticRafStart CHOICE of the RAF structures module.
The CHOICE has a common alternative carrying the shared Diagnostics and a specific one carrying these.
const ( RAFStartOutOfService RAFStartDiagnostic = 0 RAFStartUnableToComply RAFStartDiagnostic = 1 RAFStartInvalidStartTime RAFStartDiagnostic = 2 RAFStartInvalidStopTime RAFStartDiagnostic = 3 RAFStartMissingTimeValue RAFStartDiagnostic = 4 )
func (RAFStartDiagnostic) String ¶
func (r RAFStartDiagnostic) String() string
String names the diagnostic.
type RAFStartInvocation ¶
type RAFStartInvocation struct {
Credentials *Credentials
InvokeId InvokeId
// StartTime and StopTime bound the requested range. Either may be
// undefined, meaning "from now" and "until further notice".
StartTime ConditionalTime
StopTime ConditionalTime
// RequestedFrameQuality selects which frames to deliver.
RequestedFrameQuality RequestedFrameQuality
}
RAFStartInvocation is the RafStartInvocation of annex A2.6. It asks the provider to begin delivering frames.
func DecodeRAFStartInvocation ¶
func DecodeRAFStartInvocation(data []byte) (*RAFStartInvocation, error)
DecodeRAFStartInvocation parses a START invocation's content.
func (*RAFStartInvocation) Encode ¶
func (s *RAFStartInvocation) Encode() ([]byte, error)
Encode serializes the START invocation's content.
func (*RAFStartInvocation) Humanize ¶
func (s *RAFStartInvocation) Humanize() string
Humanize returns a human-readable summary.
type RAFStartReturn ¶
type RAFStartReturn struct {
Credentials *Credentials
InvokeId InvokeId
// Positive reports whether the provider accepted.
Positive bool
// CommonDiagnostic is set when the refusal used the common alternative.
CommonDiagnostic Diagnostics
// SpecificDiagnostic is set when it used the RAF-specific one.
SpecificDiagnostic RAFStartDiagnostic
// UsedCommon says which alternative a refusal took.
UsedCommon bool
}
RAFStartReturn is the RafStartReturn of annex A2.7.
func DecodeRAFStartReturn ¶
func DecodeRAFStartReturn(data []byte) (*RAFStartReturn, error)
DecodeRAFStartReturn parses a START return's content.
func (*RAFStartReturn) Encode ¶
func (s *RAFStartReturn) Encode() ([]byte, error)
Encode serializes the START return's content.
func (*RAFStartReturn) Humanize ¶
func (s *RAFStartReturn) Humanize() string
Humanize returns a human-readable summary.
type RAFStatusReportInvocation ¶
type RAFStatusReportInvocation struct {
Credentials *Credentials
// ErrorFreeFrameNumber counts frames delivered that passed error control.
ErrorFreeFrameNumber uint32
// DeliveredFrameNumber counts every frame delivered.
DeliveredFrameNumber uint32
FrameSyncLockStatus LockStatus
SymbolSyncLockStatus LockStatus
SubcarrierLockStatus LockStatus
CarrierLockStatus LockStatus
ProductionStatus ProductionStatus
}
RAFStatusReportInvocation is the RafStatusReportInvocation of annex A2.7: a periodic summary of how the channel is doing.
func DecodeRAFStatusReportInvocation ¶
func DecodeRAFStatusReportInvocation(data []byte) (*RAFStatusReportInvocation, error)
DecodeRAFStatusReportInvocation parses a STATUS-REPORT invocation's content.
func (*RAFStatusReportInvocation) Encode ¶
func (s *RAFStatusReportInvocation) Encode() ([]byte, error)
Encode serializes the STATUS-REPORT invocation's content.
func (*RAFStatusReportInvocation) Humanize ¶
func (s *RAFStatusReportInvocation) Humanize() string
Humanize returns a human-readable summary.
type RAFTransferBuffer ¶
type RAFTransferBuffer []TransferBufferEntry
RAFTransferBuffer is the RafTransferBuffer of annex A2.7: a SEQUENCE OF frames and notifications, delivered together.
Buffering is why RAF scales. A provider recovering frames at line rate does not send one PDU per frame; it fills a buffer and ships it, so the TCP connection carries a few large messages rather than thousands of small ones.
func DecodeRAFTransferBuffer ¶
func DecodeRAFTransferBuffer(data []byte) (RAFTransferBuffer, error)
DecodeRAFTransferBuffer parses a transfer buffer's content.
func (RAFTransferBuffer) Encode ¶
func (b RAFTransferBuffer) Encode() ([]byte, error)
Encode serializes the transfer buffer's content.
func (RAFTransferBuffer) Frames ¶
func (b RAFTransferBuffer) Frames() []*RAFTransferDataInvocation
Frames returns just the frames in the buffer, which is what a user normally wants.
func (RAFTransferBuffer) Humanize ¶
func (b RAFTransferBuffer) Humanize() string
Humanize returns a human-readable summary.
type RAFTransferDataInvocation ¶
type RAFTransferDataInvocation struct {
Credentials *Credentials
// EarthReceiveTime is when the frame reached the ground.
EarthReceiveTime Time
// AntennaId names the antenna that received it.
AntennaId AntennaId
// DataLinkContinuity counts frames lost since the last delivery, or -1
// when the provider cannot tell. INTEGER (-1 .. 16777215).
DataLinkContinuity int32
// DeliveredFrameQuality is what the frame turned out to be.
DeliveredFrameQuality FrameQuality
// PrivateAnnotation is an optional provider-defined field, 1 to 128 octets.
PrivateAnnotation []byte
// Data is the frame itself: a CADU's frame content, as pkg/tmsc.UnwrapCADU
// produces.
Data []byte
}
RAFTransferDataInvocation is the RafTransferDataInvocation of annex A2.7: one telemetry frame with the metadata describing how it arrived.
func DecodeRAFTransferDataInvocation ¶
func DecodeRAFTransferDataInvocation(data []byte) (*RAFTransferDataInvocation, error)
DecodeRAFTransferDataInvocation parses a TRANSFER-DATA invocation's content.
func (*RAFTransferDataInvocation) Encode ¶
func (t *RAFTransferDataInvocation) Encode() ([]byte, error)
Encode serializes the TRANSFER-DATA invocation's content.
func (*RAFTransferDataInvocation) Humanize ¶
func (t *RAFTransferDataInvocation) Humanize() string
Humanize returns a human-readable summary.
type RAFUser ¶
type RAFUser struct {
*ServiceUser
}
RAFUser is the user half of a RAF service instance.
The lifecycle is the one the state table of CCSDS 911.1-B-5 clause 4.2.2 walks: Bind, wait for the return, Start, then pull transfer buffers until you have what you came for, Stop, Unbind. Each call queues a PDU; NextPDU hands it to you to write, and HandlePDU takes what comes back.
func NewRAFUser ¶
func NewRAFUser(config ServiceConfig) (*RAFUser, error)
NewRAFUser prepares the user half of a RAF instance. The configuration's Kind is set for you.
func (RAFUser) Association ¶
func (c RAFUser) Association() *Association
Association returns the association underneath.
func (RAFUser) DeliveryMode ¶
func (c RAFUser) DeliveryMode() DeliveryMode
DeliveryMode returns the configured delivery mode.
func (*RAFUser) HandlePDU ¶
HandlePDU decodes one PDU from the provider, advances the state machine and returns what arrived.
A PDU the state does not allow is answered with a PEER-ABORT for protocol error, queued for sending, and reported as ErrUnexpectedPDU, which is what every 'peer abort protocol error' cell of the state table says to do.
func (RAFUser) HandlePeerAbort ¶
HandlePeerAbort takes an inbound PEER-ABORT: the association is over.
func (*RAFUser) HandleStartReturn ¶
func (u *RAFUser) HandleStartReturn(r *RAFStartReturn) error
HandleStartReturn takes the answer to START. A positive answer moves to state 3.
func (RAFUser) NextPDU ¶
NextPDU takes the next PDU the caller should send, or reports false when there is nothing waiting.
func (RAFUser) PeerAbort ¶
func (c RAFUser) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
PeerAbort ends the association from this end.
func (RAFUser) Pending ¶
func (c RAFUser) Pending() int
Pending reports how many PDUs are waiting to be sent.
func (*RAFUser) Start ¶
func (u *RAFUser) Start( now time.Time, randomNumber int32, start, stop ConditionalTime, quality RequestedFrameQuality, ) (InvokeId, error)
Start asks the provider to begin delivering frames. State 2 only, per Clause 3.4.1.7.
type RAFUserEvent ¶
type RAFUserEvent struct {
Operation OperationType
BindReturn *BindReturn
UnbindReturn *UnbindReturn
StartReturn *RAFStartReturn
StopReturn *Acknowledgement
ScheduleStatusReportReturn *ScheduleStatusReportReturn
GetParameterReturn *GetParameterReturn
TransferBuffer RAFTransferBuffer
StatusReport *RAFStatusReportInvocation
PeerAbort *PeerAbort
}
RAFUserEvent is one decoded PDU arriving at the user. Exactly one field is set, and Operation says which.
type RCFProvider ¶
type RCFProvider struct {
*ServiceProvider
}
RCFProvider is the provider half of an RCF instance. Partial, like the rest.
func NewRCFProvider ¶
func NewRCFProvider(config ServiceConfig) (*RCFProvider, error)
NewRCFProvider prepares the provider half of an RCF instance.
func (RCFProvider) Association ¶
func (c RCFProvider) Association() *Association
Association returns the association underneath.
func (RCFProvider) DeliveryMode ¶
func (c RCFProvider) DeliveryMode() DeliveryMode
DeliveryMode returns the configured delivery mode.
func (RCFProvider) HandlePeerAbort ¶
HandlePeerAbort takes an inbound PEER-ABORT: the association is over.
func (*RCFProvider) HandleStartInvocation ¶
func (p *RCFProvider) HandleStartInvocation( s *RCFStartInvocation, answer *RCFStartReturn, now time.Time, randomNumber int32, ) error
HandleStartInvocation answers a START, moving to state 3 when it accepts.
func (RCFProvider) Kind ¶
func (c RCFProvider) Kind() ServiceKind
Kind returns which service this is.
func (RCFProvider) NextPDU ¶
NextPDU takes the next PDU the caller should send, or reports false when there is nothing waiting.
func (RCFProvider) PeerAbort ¶
func (c RCFProvider) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
PeerAbort ends the association from this end.
func (RCFProvider) Pending ¶
func (c RCFProvider) Pending() int
Pending reports how many PDUs are waiting to be sent.
func (*RCFProvider) SendTransferBuffer ¶
func (p *RCFProvider) SendTransferBuffer(buffer RCFTransferBuffer, now time.Time) error
SendTransferBuffer queues a buffer of frames and notifications. State 3 only.
func (RCFProvider) State ¶
func (c RCFProvider) State() ServiceState
State returns the service state.
type RCFStartDiagnostic ¶
type RCFStartDiagnostic int
RCFStartDiagnostic explains a refused START, from the DiagnosticRcfStart CHOICE of the RCF structures module.
const ( RCFStartOutOfService RCFStartDiagnostic = 0 RCFStartUnableToComply RCFStartDiagnostic = 1 RCFStartInvalidStartTime RCFStartDiagnostic = 2 RCFStartInvalidStopTime RCFStartDiagnostic = 3 RCFStartMissingTimeValue RCFStartDiagnostic = 4 RCFStartInvalidGVCID RCFStartDiagnostic = 5 )
func (RCFStartDiagnostic) String ¶
func (r RCFStartDiagnostic) String() string
String names the diagnostic.
type RCFStartInvocation ¶
type RCFStartInvocation struct {
Credentials *Credentials
InvokeId InvokeId
StartTime ConditionalTime
StopTime ConditionalTime
// RequestedGVCID names the master or virtual channel to deliver.
RequestedGVCID GVCID
}
RCFStartInvocation is the RcfStartInvocation of the RCF incoming PDUs module: like RAF's, but naming a channel rather than a frame quality.
func DecodeRCFStartInvocation ¶
func DecodeRCFStartInvocation(data []byte) (*RCFStartInvocation, error)
DecodeRCFStartInvocation parses a START invocation's content.
func (*RCFStartInvocation) Encode ¶
func (s *RCFStartInvocation) Encode() ([]byte, error)
Encode serializes the START invocation's content.
func (*RCFStartInvocation) Humanize ¶
func (s *RCFStartInvocation) Humanize() string
Humanize returns a human-readable summary.
type RCFStartReturn ¶
type RCFStartReturn struct {
Credentials *Credentials
InvokeId InvokeId
// Positive reports whether the provider accepted.
Positive bool
// CommonDiagnostic is set when a refusal used the common alternative.
CommonDiagnostic Diagnostics
// SpecificDiagnostic is set when it used the RCF-specific one.
SpecificDiagnostic RCFStartDiagnostic
// UsedCommon says which alternative a refusal took.
UsedCommon bool
}
RCFStartReturn is the RcfStartReturn of annex A2.7.
Unlike FCLTU's, its positive result is an empty NULL: there is nothing to tell the user beyond "yes".
func DecodeRCFStartReturn ¶
func DecodeRCFStartReturn(data []byte) (*RCFStartReturn, error)
DecodeRCFStartReturn parses a START return's content.
func (*RCFStartReturn) Encode ¶
func (s *RCFStartReturn) Encode() ([]byte, error)
Encode serializes the START return's content.
func (*RCFStartReturn) Humanize ¶
func (s *RCFStartReturn) Humanize() string
Humanize returns a human-readable summary.
type RCFStatusReportInvocation ¶
type RCFStatusReportInvocation struct {
Credentials *Credentials
// DeliveredFrameNumber counts frames delivered on the requested channel.
DeliveredFrameNumber uint32
FrameSyncLockStatus LockStatus
SymbolSyncLockStatus LockStatus
SubcarrierLockStatus LockStatus
CarrierLockStatus LockStatus
ProductionStatus ProductionStatus
}
RCFStatusReportInvocation is the RcfStatusReportInvocation of annex A2.7.
It is RAF's status report with one field missing. RAF counts frames twice ( delivered, and of those, error free) because RAF can deliver bad frames. RCF only ever delivers good ones, so the error-free count would say nothing and the spec leaves it out.
func DecodeRCFStatusReportInvocation ¶
func DecodeRCFStatusReportInvocation(data []byte) (*RCFStatusReportInvocation, error)
DecodeRCFStatusReportInvocation parses a STATUS-REPORT invocation's content.
func (*RCFStatusReportInvocation) Encode ¶
func (s *RCFStatusReportInvocation) Encode() ([]byte, error)
Encode serializes the STATUS-REPORT invocation's content.
func (*RCFStatusReportInvocation) Humanize ¶
func (s *RCFStatusReportInvocation) Humanize() string
Humanize returns a human-readable summary.
type RCFTransferBuffer ¶
type RCFTransferBuffer []RCFTransferBufferEntry
RCFTransferBuffer is the RcfTransferBuffer of annex A2.7: a SEQUENCE OF frames and notifications, delivered together for the same reason RAF buffers.
func DecodeRCFTransferBuffer ¶
func DecodeRCFTransferBuffer(data []byte) (RCFTransferBuffer, error)
DecodeRCFTransferBuffer parses a transfer buffer's content.
func (RCFTransferBuffer) Encode ¶
func (b RCFTransferBuffer) Encode() ([]byte, error)
Encode serializes the transfer buffer's content.
func (RCFTransferBuffer) Frames ¶
func (b RCFTransferBuffer) Frames() []*RCFTransferDataInvocation
Frames returns just the frames in the buffer.
func (RCFTransferBuffer) Humanize ¶
func (b RCFTransferBuffer) Humanize() string
Humanize returns a human-readable summary.
type RCFTransferBufferEntry ¶
type RCFTransferBufferEntry struct {
Frame *RCFTransferDataInvocation
Notification *SyncNotifyInvocation
}
RCFTransferBufferEntry is one element of an RcfTransferBuffer.
FrameOrNotification ::= CHOICE
{ annotatedFrame [0] RcfTransferDataInvocation
, syncNotification [1] RcfSyncNotifyInvocation
}
type RCFTransferDataInvocation ¶
type RCFTransferDataInvocation struct {
Credentials *Credentials
EarthReceiveTime Time
AntennaId AntennaId
DataLinkContinuity int32
PrivateAnnotation []byte
Data []byte
}
RCFTransferDataInvocation is the RcfTransferDataInvocation of the RCF outgoing PDUs module.
It differs from RAF's by having no delivered-frame-quality field: RCF delivers only frames that passed error control, so there is nothing to report.
func DecodeRCFTransferDataInvocation ¶
func DecodeRCFTransferDataInvocation(data []byte) (*RCFTransferDataInvocation, error)
DecodeRCFTransferDataInvocation parses a TRANSFER-DATA invocation's content.
func (*RCFTransferDataInvocation) Encode ¶
func (t *RCFTransferDataInvocation) Encode() ([]byte, error)
Encode serializes the TRANSFER-DATA invocation's content.
func (*RCFTransferDataInvocation) Humanize ¶
func (t *RCFTransferDataInvocation) Humanize() string
Humanize returns a human-readable summary.
type RCFUser ¶
type RCFUser struct {
*ServiceUser
}
RCFUser is the user half of an RCF service instance.
It is RAF's machine with one difference in START: the user names a channel instead of a frame quality, and gets only that channel's frames.
func NewRCFUser ¶
func NewRCFUser(config ServiceConfig) (*RCFUser, error)
NewRCFUser prepares the user half of an RCF instance.
func (RCFUser) Association ¶
func (c RCFUser) Association() *Association
Association returns the association underneath.
func (RCFUser) DeliveryMode ¶
func (c RCFUser) DeliveryMode() DeliveryMode
DeliveryMode returns the configured delivery mode.
func (RCFUser) HandlePeerAbort ¶
HandlePeerAbort takes an inbound PEER-ABORT: the association is over.
func (*RCFUser) HandleStartReturn ¶
func (u *RCFUser) HandleStartReturn(r *RCFStartReturn) error
HandleStartReturn takes the answer to START, moving to state 3 when positive.
func (RCFUser) NextPDU ¶
NextPDU takes the next PDU the caller should send, or reports false when there is nothing waiting.
func (RCFUser) PeerAbort ¶
func (c RCFUser) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
PeerAbort ends the association from this end.
func (RCFUser) Pending ¶
func (c RCFUser) Pending() int
Pending reports how many PDUs are waiting to be sent.
type RCFUserEvent ¶
type RCFUserEvent struct {
Operation OperationType
BindReturn *BindReturn
UnbindReturn *UnbindReturn
StartReturn *RCFStartReturn
StopReturn *Acknowledgement
ScheduleStatusReportReturn *ScheduleStatusReportReturn
GetParameterReturn *GetParameterReturn
TransferBuffer RCFTransferBuffer
StatusReport *RCFStatusReportInvocation
PeerAbort *PeerAbort
}
RCFUserEvent is one decoded PDU arriving at the user.
type ROCFProvider ¶
type ROCFProvider struct {
*ServiceProvider
}
ROCFProvider is the provider half of an ROCF instance. Partial.
func NewROCFProvider ¶
func NewROCFProvider(config ServiceConfig) (*ROCFProvider, error)
NewROCFProvider prepares the provider half of an ROCF instance.
func (ROCFProvider) Association ¶
func (c ROCFProvider) Association() *Association
Association returns the association underneath.
func (ROCFProvider) DeliveryMode ¶
func (c ROCFProvider) DeliveryMode() DeliveryMode
DeliveryMode returns the configured delivery mode.
func (ROCFProvider) HandlePeerAbort ¶
HandlePeerAbort takes an inbound PEER-ABORT: the association is over.
func (*ROCFProvider) HandleStartInvocation ¶
func (p *ROCFProvider) HandleStartInvocation( s *ROCFStartInvocation, answer *ROCFStartReturn, now time.Time, randomNumber int32, ) error
HandleStartInvocation answers a START, moving to state 3 when it accepts.
func (ROCFProvider) Kind ¶
func (c ROCFProvider) Kind() ServiceKind
Kind returns which service this is.
func (ROCFProvider) NextPDU ¶
NextPDU takes the next PDU the caller should send, or reports false when there is nothing waiting.
func (ROCFProvider) PeerAbort ¶
func (c ROCFProvider) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
PeerAbort ends the association from this end.
func (ROCFProvider) Pending ¶
func (c ROCFProvider) Pending() int
Pending reports how many PDUs are waiting to be sent.
func (*ROCFProvider) SendTransferBuffer ¶
func (p *ROCFProvider) SendTransferBuffer(buffer ROCFTransferBuffer, now time.Time) error
SendTransferBuffer queues a buffer of control fields and notifications. State 3 only.
func (ROCFProvider) State ¶
func (c ROCFProvider) State() ServiceState
State returns the service state.
type ROCFStartDiagnostic ¶
type ROCFStartDiagnostic int
ROCFStartDiagnostic explains a refused START, from the DiagnosticRocfStart CHOICE of the ROCF structures module.
const ( ROCFStartOutOfService ROCFStartDiagnostic = 0 ROCFStartUnableToComply ROCFStartDiagnostic = 1 ROCFStartInvalidStartTime ROCFStartDiagnostic = 2 ROCFStartInvalidStopTime ROCFStartDiagnostic = 3 ROCFStartMissingTimeValue ROCFStartDiagnostic = 4 ROCFStartInvalidGVCID ROCFStartDiagnostic = 5 ROCFStartInvalidControlWordType ROCFStartDiagnostic = 6 ROCFStartInvalidTcVcid ROCFStartDiagnostic = 7 ROCFStartInvalidUpdateMode ROCFStartDiagnostic = 8 )
func (ROCFStartDiagnostic) String ¶
func (r ROCFStartDiagnostic) String() string
String names the diagnostic.
type ROCFStartInvocation ¶
type ROCFStartInvocation struct {
Credentials *Credentials
InvokeId InvokeId
StartTime ConditionalTime
StopTime ConditionalTime
RequestedGVCID GVCID
// ControlWordType filters which control words to deliver.
ControlWordType ControlWordType
// UpdateMode says whether to deliver every one or only changes.
UpdateMode UpdateMode
}
ROCFStartInvocation is the RocfStartInvocation of the ROCF incoming PDUs module.
func DecodeROCFStartInvocation ¶
func DecodeROCFStartInvocation(data []byte) (*ROCFStartInvocation, error)
DecodeROCFStartInvocation parses a START invocation's content.
func (*ROCFStartInvocation) Encode ¶
func (s *ROCFStartInvocation) Encode() ([]byte, error)
Encode serializes the START invocation's content.
func (*ROCFStartInvocation) Humanize ¶
func (s *ROCFStartInvocation) Humanize() string
Humanize returns a human-readable summary.
type ROCFStartReturn ¶
type ROCFStartReturn struct {
Credentials *Credentials
InvokeId InvokeId
// Positive reports whether the provider accepted.
Positive bool
// CommonDiagnostic is set when a refusal used the common alternative.
CommonDiagnostic Diagnostics
// SpecificDiagnostic is set when it used the ROCF-specific one.
SpecificDiagnostic ROCFStartDiagnostic
// UsedCommon says which alternative a refusal took.
UsedCommon bool
}
ROCFStartReturn is the RocfStartReturn of annex A2.7.
func DecodeROCFStartReturn ¶
func DecodeROCFStartReturn(data []byte) (*ROCFStartReturn, error)
DecodeROCFStartReturn parses a START return's content.
func (*ROCFStartReturn) Encode ¶
func (s *ROCFStartReturn) Encode() ([]byte, error)
Encode serializes the START return's content.
func (*ROCFStartReturn) Humanize ¶
func (s *ROCFStartReturn) Humanize() string
Humanize returns a human-readable summary.
type ROCFStatusReportInvocation ¶
type ROCFStatusReportInvocation struct {
Credentials *Credentials
// ProcessedFrameNumber counts frames the provider examined.
ProcessedFrameNumber uint32
// DeliveredOCFsNumber counts control fields actually delivered.
DeliveredOCFsNumber uint32
FrameSyncLockStatus LockStatus
SymbolSyncLockStatus LockStatus
SubcarrierLockStatus LockStatus
CarrierLockStatus LockStatus
ProductionStatus ProductionStatus
}
ROCFStatusReportInvocation is the RocfStatusReportInvocation of annex A2.7.
Its two counters are not the return services' usual pair. ROCF counts the frames it looked at and the OCFs it sent on, and those differ: a frame may carry no operational control field, or carry one the filter rejected. The gap between the two numbers is how much of the channel was not of interest.
func DecodeROCFStatusReportInvocation ¶
func DecodeROCFStatusReportInvocation(data []byte) (*ROCFStatusReportInvocation, error)
DecodeROCFStatusReportInvocation parses a STATUS-REPORT invocation's content.
func (*ROCFStatusReportInvocation) Encode ¶
func (s *ROCFStatusReportInvocation) Encode() ([]byte, error)
Encode serializes the STATUS-REPORT invocation's content.
func (*ROCFStatusReportInvocation) Humanize ¶
func (s *ROCFStatusReportInvocation) Humanize() string
Humanize returns a human-readable summary.
type ROCFTransferBuffer ¶
type ROCFTransferBuffer []ROCFTransferBufferEntry
ROCFTransferBuffer is the RocfTransferBuffer of annex A2.7.
Buffering matters more here than in RAF. An OCF is four octets, so one PDU per control field would spend far more on framing than on data.
func DecodeROCFTransferBuffer ¶
func DecodeROCFTransferBuffer(data []byte) (ROCFTransferBuffer, error)
DecodeROCFTransferBuffer parses a transfer buffer's content.
func (ROCFTransferBuffer) Encode ¶
func (b ROCFTransferBuffer) Encode() ([]byte, error)
Encode serializes the transfer buffer's content.
func (ROCFTransferBuffer) Humanize ¶
func (b ROCFTransferBuffer) Humanize() string
Humanize returns a human-readable summary.
func (ROCFTransferBuffer) OCFs ¶
func (b ROCFTransferBuffer) OCFs() []*ROCFTransferDataInvocation
OCFs returns just the control fields in the buffer.
type ROCFTransferBufferEntry ¶
type ROCFTransferBufferEntry struct {
OCF *ROCFTransferDataInvocation
Notification *SyncNotifyInvocation
}
ROCFTransferBufferEntry is one element of a RocfTransferBuffer.
OcfOrNotification ::= CHOICE
{ annotatedOcf [0] RocfTransferDataInvocation
, syncNotification [1] RocfSyncNotifyInvocation
}
type ROCFTransferDataInvocation ¶
type ROCFTransferDataInvocation struct {
Credentials *Credentials
EarthReceiveTime Time
AntennaId AntennaId
DataLinkContinuity int32
PrivateAnnotation []byte
// Data is the operational control field.
Data []byte
}
ROCFTransferDataInvocation is the RocfTransferDataInvocation of the ROCF outgoing PDUs module.
Its Data is the operational control field itself (four octets, usually a CLCW that pkg/cop can decode) rather than a whole frame.
func DecodeROCFTransferDataInvocation ¶
func DecodeROCFTransferDataInvocation(data []byte) (*ROCFTransferDataInvocation, error)
DecodeROCFTransferDataInvocation parses a TRANSFER-DATA invocation's content.
The layout matches RCF's exactly, so this shares its decoder and relabels the result.
func (*ROCFTransferDataInvocation) Encode ¶
func (t *ROCFTransferDataInvocation) Encode() ([]byte, error)
Encode serializes the TRANSFER-DATA invocation's content.
func (*ROCFTransferDataInvocation) Humanize ¶
func (t *ROCFTransferDataInvocation) Humanize() string
Humanize returns a human-readable summary.
type ROCFUser ¶
type ROCFUser struct {
*ServiceUser
}
ROCFUser is the user half of an ROCF service instance.
ROCF is the narrowest of the return services: four octets per frame, and only from the frames that carry a control field of the requested kind. A mission running FOP-1 on the ground uses it to close the loop, feeding each delivered field to pkg/cop's CLCW decoder.
func NewROCFUser ¶
func NewROCFUser(config ServiceConfig) (*ROCFUser, error)
NewROCFUser prepares the user half of an ROCF instance.
func (ROCFUser) Association ¶
func (c ROCFUser) Association() *Association
Association returns the association underneath.
func (ROCFUser) DeliveryMode ¶
func (c ROCFUser) DeliveryMode() DeliveryMode
DeliveryMode returns the configured delivery mode.
func (ROCFUser) HandlePeerAbort ¶
HandlePeerAbort takes an inbound PEER-ABORT: the association is over.
func (*ROCFUser) HandleStartReturn ¶
func (u *ROCFUser) HandleStartReturn(r *ROCFStartReturn) error
HandleStartReturn takes the answer to START, moving to state 3 when positive.
func (ROCFUser) NextPDU ¶
NextPDU takes the next PDU the caller should send, or reports false when there is nothing waiting.
func (ROCFUser) PeerAbort ¶
func (c ROCFUser) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
PeerAbort ends the association from this end.
func (ROCFUser) Pending ¶
func (c ROCFUser) Pending() int
Pending reports how many PDUs are waiting to be sent.
func (*ROCFUser) Start ¶
func (u *ROCFUser) Start( now time.Time, randomNumber int32, start, stop ConditionalTime, channel GVCID, control ControlWordType, mode UpdateMode, ) (InvokeId, error)
Start asks the provider to begin delivering control fields. State 2 only.
type ROCFUserEvent ¶
type ROCFUserEvent struct {
Operation OperationType
BindReturn *BindReturn
UnbindReturn *UnbindReturn
StartReturn *ROCFStartReturn
StopReturn *Acknowledgement
ScheduleStatusReportReturn *ScheduleStatusReportReturn
GetParameterReturn *GetParameterReturn
TransferBuffer ROCFTransferBuffer
StatusReport *ROCFStatusReportInvocation
PeerAbort *PeerAbort
}
ROCFUserEvent is one decoded PDU arriving at the user.
type ReportRequestKind ¶
type ReportRequestKind int
ReportRequestKind says what a SCHEDULE-STATUS-REPORT is asking for, from the ReportRequestType CHOICE of the common PDUs module.
const ( // ReportImmediately asks for one report now. ReportImmediately ReportRequestKind = 0 // ReportPeriodically asks for a report every so many seconds. ReportPeriodically ReportRequestKind = 1 // ReportStop turns periodic reporting off. ReportStop ReportRequestKind = 2 )
func (ReportRequestKind) String ¶
func (r ReportRequestKind) String() string
String names the request.
type RequestedFrameQuality ¶
type RequestedFrameQuality int
RequestedFrameQuality says which frames a START asks for, from the parReqFrameQuality values of the RAF structures module.
const ( // FrameQualityGoodOnly asks for frames that passed error control. FrameQualityGoodOnly RequestedFrameQuality = 0 // FrameQualityErredOnly asks for frames that failed it. FrameQualityErredOnly RequestedFrameQuality = 1 // FrameQualityAll asks for everything. FrameQualityAll RequestedFrameQuality = 2 )
func (RequestedFrameQuality) String ¶
func (r RequestedFrameQuality) String() string
String names the requested quality.
type ScheduleStatusReportDiagnostic ¶
type ScheduleStatusReportDiagnostic int
ScheduleStatusReportDiagnostic explains a refused SCHEDULE-STATUS-REPORT, from the specific alternative of DiagnosticScheduleStatusReport.
const ( // ScheduleNotSupportedInThisDeliveryMode means the mode has no reports. ScheduleNotSupportedInThisDeliveryMode ScheduleStatusReportDiagnostic = 0 // ScheduleAlreadyStopped answers a stop when nothing was running. ScheduleAlreadyStopped ScheduleStatusReportDiagnostic = 1 // ScheduleInvalidReportingCycle means the cycle was outside 2 to 600. ScheduleInvalidReportingCycle ScheduleStatusReportDiagnostic = 2 )
func (ScheduleStatusReportDiagnostic) String ¶
func (s ScheduleStatusReportDiagnostic) String() string
String names the diagnostic.
type ScheduleStatusReportInvocation ¶
type ScheduleStatusReportInvocation struct {
Credentials *Credentials
InvokeId InvokeId
// Kind says whether to report once, periodically, or to stop.
Kind ReportRequestKind
// ReportingCycle is the period in seconds, used only when Kind is
// ReportPeriodically.
ReportingCycle uint16
}
ScheduleStatusReportInvocation is the SleScheduleStatusReportInvocation of the common PDUs module. All four services use it unchanged.
func DecodeScheduleStatusReportInvocation ¶
func DecodeScheduleStatusReportInvocation(data []byte) (*ScheduleStatusReportInvocation, error)
DecodeScheduleStatusReportInvocation parses the invocation's content.
func (*ScheduleStatusReportInvocation) Encode ¶
func (s *ScheduleStatusReportInvocation) Encode() ([]byte, error)
Encode serializes the SCHEDULE-STATUS-REPORT invocation's content.
func (*ScheduleStatusReportInvocation) Humanize ¶
func (s *ScheduleStatusReportInvocation) Humanize() string
Humanize returns a human-readable summary.
type ScheduleStatusReportReturn ¶
type ScheduleStatusReportReturn struct {
Credentials *Credentials
InvokeId InvokeId
// Positive reports whether the provider accepted.
Positive bool
// CommonDiagnostic is set when a refusal used the common alternative.
CommonDiagnostic Diagnostics
// SpecificDiagnostic is set when it used the specific one.
SpecificDiagnostic ScheduleStatusReportDiagnostic
// UsedCommon says which alternative a refusal took.
UsedCommon bool
}
ScheduleStatusReportReturn is the SleScheduleStatusReportReturn of the common PDUs module.
func DecodeScheduleStatusReportReturn ¶
func DecodeScheduleStatusReportReturn(data []byte) (*ScheduleStatusReportReturn, error)
DecodeScheduleStatusReportReturn parses the return's content.
func (*ScheduleStatusReportReturn) Encode ¶
func (s *ScheduleStatusReportReturn) Encode() ([]byte, error)
Encode serializes the SCHEDULE-STATUS-REPORT return's content.
func (*ScheduleStatusReportReturn) Humanize ¶
func (s *ScheduleStatusReportReturn) Humanize() string
Humanize returns a human-readable summary.
type ServiceConfig ¶
type ServiceConfig struct {
// Association is the bound association this instance runs over. It must
// already exist; this package does not create one for you, because a
// caller normally wants to configure authentication and heartbeats first.
Association *Association
// Kind names the service, which decides the PDU tags.
Kind ServiceKind
// DeliveryMode is the mode the service agreement fixed. See delivery.go
// for what the machine does with it and what it leaves to you.
DeliveryMode DeliveryMode
// Version is the service version to bind at.
Version uint16
// ResponderPort names the provider's port identifier, used by BIND.
ResponderPort string
// Instance identifies the service instance, used by BIND.
Instance ServiceInstanceIdentifier
}
ServiceConfig configures one service instance.
type ServiceInstanceAttribute ¶
type ServiceInstanceAttribute struct {
// Identifier names the attribute. On the wire it is an OBJECT IDENTIFIER
// from the SLE-SERVICE-INSTANCE-ID module; here it is the operator name (
// "sagr", "spack", "rsl-fg", "fsl-fg", "raf", "rcf", "rocf", "cltu" or
// "antenna") or a dotted OID string for an identifier this package does
// not know by name.
Identifier string
// Value is the attribute value.
Value string
// Legacy reports that the identifier arrived as a VisibleString rather
// than the OBJECT IDENTIFIER the module requires. Some older peers, and
// earlier versions of this package, encoded it that way; the decoder
// accepts the form and flags it here. This package always encodes OIDs.
Legacy bool
}
ServiceInstanceAttribute is one name-value pair of a service instance identifier.
type ServiceInstanceIdentifier ¶
type ServiceInstanceIdentifier []ServiceInstanceAttribute
ServiceInstanceIdentifier names a service instance: a sequence of attributes that together identify one configured service at the provider.
func (ServiceInstanceIdentifier) String ¶
func (s ServiceInstanceIdentifier) String() string
String renders the identifier the way SLE operators write it, as name=value pairs.
type ServiceKind ¶
type ServiceKind int
ServiceKind names which transfer service a PDU belongs to. The same tag number means different operations in different services, so decoding needs to know.
const ( // ServiceRAF is Return All Frames, CCSDS 911.1-B-5. ServiceRAF ServiceKind = iota // ServiceRCF is Return Channel Frames, CCSDS 911.2-B-4. ServiceRCF // ServiceROCF is Return Operational Control Fields, CCSDS 911.5-B-4. ServiceROCF // ServiceFCLTU is Forward CLTU, CCSDS 912.1-B-5. ServiceFCLTU )
type ServiceParameter ¶ added in v0.4.0
type ServiceParameter struct {
// Service is the transfer service whose parameter set this was read
// against, because the same tag means different things in each.
Service ServiceKind
// Tag is the CHOICE alternative the provider chose.
Tag uint32
// Name is the parameterName the alternative carried. The schema
// constrains it to match the alternative, and Decode checks that it
// does: a provider that disagrees with itself is reporting something
// this package should not paper over.
Name ParameterName
// Value is the parameter's value when the schema makes it a single
// integer, which most are. Valid only when HasValue is set.
Value int64
HasValue bool
// Raw is the parameterValue element's content when the value is
// structured. A set of GVCIDs, the online/offline CHOICE of a latency
// limit. Decoding it further needs the service's own ASN.1, and this
// package does not model those shapes rather than guess at them.
Raw []byte
}
ServiceParameter is one configuration parameter from a GET-PARAMETER return.
func DecodeServiceParameter ¶ added in v0.4.0
func DecodeServiceParameter(content []byte, service ServiceKind) (*ServiceParameter, error)
DecodeServiceParameter reads the positive result of a GET-PARAMETER return against one service's parameter set.
content is the parameter CHOICE as GetParameterReturn carries it: the alternative's tag and content, which is where getparameter.go stops.
service is required and cannot be inferred. The same context tag names a different parameter in each service, so decoding a RAF PDU against the FCLTU set would report the wrong parameter with a plausible value.
func (*ServiceParameter) Humanize ¶ added in v0.4.0
func (p *ServiceParameter) Humanize() string
Humanize returns a human-readable summary.
type ServiceProvider ¶
type ServiceProvider struct {
// contains filtered or unexported fields
}
ServiceProvider is the provider half: the ground-station side.
It answers the operations a user drives (BIND, START, STOP, UNBIND) and lets the caller push data while active. One of these is one service instance on one association.
The rest of a real provider lives beside it rather than in it. Production and the transfer buffer are in production.go; serving several instances and routing an inbound BIND between them is Complex, in complex.go. What none of them holds is a service agreement: the provision periods, permitted parameter ranges and scheduling that service management hands down are configuration a mission supplies. See docs/content/conformance/sle.md for the row-by-row picture.
func NewServiceProvider ¶
func NewServiceProvider(config ServiceConfig) (*ServiceProvider, error)
NewServiceProvider prepares the provider half of a service instance.
func (ServiceProvider) Association ¶
func (c ServiceProvider) Association() *Association
Association returns the association underneath.
func (ServiceProvider) DeliveryMode ¶
func (c ServiceProvider) DeliveryMode() DeliveryMode
DeliveryMode returns the configured delivery mode.
func (*ServiceProvider) HandleBindInvocation ¶
func (p *ServiceProvider) HandleBindInvocation(b *BindInvocation, now time.Time, randomNumber int32) error
HandleBindInvocation answers a BIND. State table row 5: accept and go to state 2, or refuse and stay at state 1.
func (*ServiceProvider) HandleGetParameterInvocation ¶
func (p *ServiceProvider) HandleGetParameterInvocation( g *GetParameterInvocation, parameter []byte, now time.Time, randomNumber int32, ) error
HandleGetParameterInvocation answers a GET-PARAMETER. Valid in states 2 and 3, per clause 3.10.
parameter is the still-encoded alternative of the service's parameter CHOICE (one complete BER element) or nil, which answers negatively with 'unknown parameter'. This package does not model the per-service parameter CHOICEs; the caller that has a value to report encodes it.
func (ServiceProvider) HandlePeerAbort ¶
HandlePeerAbort takes an inbound PEER-ABORT: the association is over.
func (*ServiceProvider) HandleScheduleStatusReportInvocation ¶
func (p *ServiceProvider) HandleScheduleStatusReportInvocation( s *ScheduleStatusReportInvocation, accept bool, diagnostic ScheduleStatusReportDiagnostic, now time.Time, randomNumber int32, ) error
HandleScheduleStatusReportInvocation answers a report request.
func (*ServiceProvider) HandleStopInvocation ¶
func (p *ServiceProvider) HandleStopInvocation( s *StopInvocation, accept bool, diagnostic Diagnostics, now time.Time, randomNumber int32, ) error
HandleStopInvocation answers a STOP, returning to state 2 when it accepts.
func (*ServiceProvider) HandleUnbindInvocation ¶
func (p *ServiceProvider) HandleUnbindInvocation(u *UnbindInvocation, now time.Time, randomNumber int32) error
HandleUnbindInvocation answers an UNBIND, returning to state 1.
func (ServiceProvider) Kind ¶
func (c ServiceProvider) Kind() ServiceKind
Kind returns which service this is.
func (ServiceProvider) NextPDU ¶
NextPDU takes the next PDU the caller should send, or reports false when there is nothing waiting.
func (ServiceProvider) PeerAbort ¶
func (c ServiceProvider) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
PeerAbort ends the association from this end.
func (ServiceProvider) Pending ¶
func (c ServiceProvider) Pending() int
Pending reports how many PDUs are waiting to be sent.
func (*ServiceProvider) SendStatusReport ¶
func (p *ServiceProvider) SendStatusReport( report interface{ Encode() ([]byte, error) }, now time.Time, ) error
SendStatusReport queues an unconfirmed STATUS-REPORT. Valid in states 2 and 3: the channel has something to report as soon as the instance is bound.
func (ServiceProvider) State ¶
func (c ServiceProvider) State() ServiceState
State returns the service state.
type ServiceState ¶
type ServiceState int
ServiceState is the state of one service instance.
The numbers are the specs' own: state 1, 2 and 3. They start at 1 rather than 0 so that a state printed in a log matches the state named in the table you are reading it against.
const ( // ServiceUnbound is state 1: no association, nothing allocated. ServiceUnbound ServiceState = 1 // ServiceReady is state 2: bound, but not moving data. ServiceReady ServiceState = 2 // ServiceActive is state 3: bound and transferring. ServiceActive ServiceState = 3 )
func (ServiceState) String ¶
func (s ServiceState) String() string
String names the state the way the specs do.
type ServiceUser ¶
type ServiceUser struct {
// contains filtered or unexported fields
}
ServiceUser is the user half of a service instance: the mission-control side, which binds, starts, receives or sends data, stops and unbinds.
It is embedded by RAFUser, RCFUser, ROCFUser and FCLTUUser, which add the operations that differ between services. Use one of those rather than this directly.
func NewServiceUser ¶
func NewServiceUser(config ServiceConfig) (*ServiceUser, error)
NewServiceUser prepares the user half of a service instance.
func (ServiceUser) Association ¶
func (c ServiceUser) Association() *Association
Association returns the association underneath.
func (*ServiceUser) Bind ¶
func (u *ServiceUser) Bind(now time.Time, randomNumber int32) error
Bind opens the association and asks for the service instance. State 1 only, per CCSDS 911.1-B-5 clause 3.2.1.6.
func (ServiceUser) DeliveryMode ¶
func (c ServiceUser) DeliveryMode() DeliveryMode
DeliveryMode returns the configured delivery mode.
func (*ServiceUser) GetParameter ¶
func (u *ServiceUser) GetParameter(parameter int, now time.Time, randomNumber int32) (InvokeId, error)
GetParameter asks the provider for one configuration parameter, named by the service's ParameterName value. Valid in states 2 and 3, per clause 3.10 of each service specification.
func (*ServiceUser) HandleBindReturn ¶
func (u *ServiceUser) HandleBindReturn(b *BindReturn, now time.Time) error
HandleBindReturn takes the provider's answer to BIND. A positive answer moves to state 2.
func (*ServiceUser) HandleGetParameterReturn ¶
func (u *ServiceUser) HandleGetParameterReturn(r *GetParameterReturn) error
HandleGetParameterReturn takes the answer to GET-PARAMETER.
func (ServiceUser) HandlePeerAbort ¶
HandlePeerAbort takes an inbound PEER-ABORT: the association is over.
func (*ServiceUser) HandleScheduleStatusReportReturn ¶
func (u *ServiceUser) HandleScheduleStatusReportReturn(r *ScheduleStatusReportReturn) error
HandleScheduleStatusReportReturn takes the answer to a report request.
func (*ServiceUser) HandleStopReturn ¶
func (u *ServiceUser) HandleStopReturn(a *Acknowledgement) error
HandleStopReturn takes the answer to STOP. A positive answer returns the instance to state 2; a negative one leaves it active, which is the point of state table row 10's ELSE branch.
func (*ServiceUser) HandleUnbindReturn ¶
func (u *ServiceUser) HandleUnbindReturn(r *UnbindReturn, now time.Time) error
HandleUnbindReturn takes the provider's answer to UNBIND, ending the instance at state 1.
func (ServiceUser) Kind ¶
func (c ServiceUser) Kind() ServiceKind
Kind returns which service this is.
func (ServiceUser) NextPDU ¶
NextPDU takes the next PDU the caller should send, or reports false when there is nothing waiting.
func (*ServiceUser) Outstanding ¶
func (u *ServiceUser) Outstanding() map[InvokeId]OperationType
Outstanding returns the invoke identifiers still awaiting a return, so a caller running the spec's return timers knows which to watch.
func (ServiceUser) PeerAbort ¶
func (c ServiceUser) PeerAbort(diagnostic PeerAbortDiagnostic, now time.Time)
PeerAbort ends the association from this end.
func (ServiceUser) Pending ¶
func (c ServiceUser) Pending() int
Pending reports how many PDUs are waiting to be sent.
func (*ServiceUser) ScheduleStatusReport ¶
func (u *ServiceUser) ScheduleStatusReport( kind ReportRequestKind, cycle uint16, now time.Time, randomNumber int32, ) (InvokeId, error)
ScheduleStatusReport asks for status reports, once or periodically, or turns periodic reporting off. Valid in states 2 and 3.
func (ServiceUser) State ¶
func (c ServiceUser) State() ServiceState
State returns the service state.
func (*ServiceUser) Unbind ¶
func (u *ServiceUser) Unbind(now time.Time, randomNumber int32, reason UnbindReason) error
Unbind ends the association. State 2 only, per clause 3.3.1.5. A user must stop before it may unbind.
type SlduStatusNotification ¶
type SlduStatusNotification int
SlduStatusNotification says whether the user wants an ASYNC-NOTIFY once the CLTU has been dealt with.
const ( // ProduceNotification asks for the notification. ProduceNotification SlduStatusNotification = 0 // DoNotProduceNotification declines it. DoNotProduceNotification SlduStatusNotification = 1 )
func (SlduStatusNotification) String ¶
func (s SlduStatusNotification) String() string
String names the choice.
type StopInvocation ¶
type StopInvocation struct {
Credentials *Credentials
InvokeId InvokeId
}
StopInvocation is the SleStopInvocation of the common PDUs module: a confirmed operation ending data transfer.
func DecodeStopInvocation ¶
func DecodeStopInvocation(data []byte) (*StopInvocation, error)
DecodeStopInvocation parses a STOP invocation's content.
func (*StopInvocation) Encode ¶
func (s *StopInvocation) Encode() ([]byte, error)
Encode serializes the STOP invocation's content.
type SyncNotifyInvocation ¶
type SyncNotifyInvocation struct {
Credentials *Credentials
Kind NotificationKind
// LockStatus is set when Kind is NotifyLossFrameSync.
LockStatus *LockStatusReport
// ProductionStatus is set when Kind is NotifyProductionStatusChange.
ProductionStatus ProductionStatus
}
SyncNotifyInvocation is the sync notification a return service sends: the provider telling the user something happened to the channel.
RAF, RCF and ROCF each define this SEQUENCE in their own ASN.1 module ( RafSyncNotifyInvocation, RcfSyncNotifyInvocation, RocfSyncNotifyInvocation) and all three are the same two fields wrapping the same Notification CHOICE. One Go type covers all three.
func DecodeSyncNotifyInvocation ¶
func DecodeSyncNotifyInvocation(data []byte) (*SyncNotifyInvocation, error)
DecodeSyncNotifyInvocation parses a SYNC-NOTIFY invocation's content.
func (*SyncNotifyInvocation) Encode ¶
func (n *SyncNotifyInvocation) Encode() ([]byte, error)
Encode serializes the SYNC-NOTIFY invocation's content.
func (*SyncNotifyInvocation) Humanize ¶
func (n *SyncNotifyInvocation) Humanize() string
Humanize returns a human-readable summary.
type Time ¶
type Time struct {
// Days since the 1958 epoch.
Days uint16
// Milliseconds of the day.
Milliseconds uint32
// Microseconds of the millisecond. Zero when unused.
Microseconds uint16
}
Time is a CCSDS Day Segmented time as SLE encodes it.
func DecodeTime ¶
DecodeTime parses an eight-octet T-field.
func DecodeTimeChoice ¶
DecodeTimeChoice reads an SLE Time CHOICE.
Alternative [0] is the eight-octet form and [1] the ten-octet picosecond one. This package reads both but keeps only microsecond resolution: the extra precision has nowhere to go in a Go time.Time at these magnitudes.
type TransferBufferEntry ¶
type TransferBufferEntry struct {
Frame *RAFTransferDataInvocation
Notification *SyncNotifyInvocation
}
TransferBufferEntry is one element of a RafTransferBuffer: either a frame or a notification.
FrameOrNotification ::= CHOICE
{ annotatedFrame [0] RafTransferDataInvocation
, syncNotification [1] RafSyncNotifyInvocation
}
type UnbindInvocation ¶
type UnbindInvocation struct {
Credentials *Credentials
Reason UnbindReason
}
UnbindInvocation is the SleUnbindInvocation of annex A2.2.
func DecodeUnbindInvocation ¶
func DecodeUnbindInvocation(data []byte) (*UnbindInvocation, error)
DecodeUnbindInvocation parses an UNBIND invocation's content.
func (*UnbindInvocation) Encode ¶
func (u *UnbindInvocation) Encode() ([]byte, error)
Encode serializes the UNBIND invocation's content.
func (*UnbindInvocation) Humanize ¶
func (u *UnbindInvocation) Humanize() string
Humanize returns a human-readable summary.
type UnbindReason ¶
type UnbindReason int
UnbindReason says why an association is ending, from the UnbindReason INTEGER of annex A2.2.
const ( // UnbindEnd means the service provision period has ended. UnbindEnd UnbindReason = 0 // UnbindSuspend means the association is being suspended and may resume. UnbindSuspend UnbindReason = 1 // UnbindVersionNotSupported means the peer cannot speak this version. UnbindVersionNotSupported UnbindReason = 2 // UnbindOther covers everything else. UnbindOther UnbindReason = 127 )
type UnbindReturn ¶
type UnbindReturn struct {
Credentials *Credentials
}
UnbindReturn is the SleUnbindReturn of annex A2.2. Its result CHOICE has only a positive alternative: an UNBIND cannot be refused.
func DecodeUnbindReturn ¶
func DecodeUnbindReturn(data []byte) (*UnbindReturn, error)
DecodeUnbindReturn parses an UNBIND return's content.
func (*UnbindReturn) Encode ¶
func (u *UnbindReturn) Encode() ([]byte, error)
Encode serializes the UNBIND return's content.
type UpdateMode ¶
type UpdateMode int
UpdateMode says whether to deliver every control field or only changes, from the RequestedUpdateMode INTEGER of the ROCF structures module.
const ( // UpdateContinuous delivers every operational control field. UpdateContinuous UpdateMode = 0 // UpdateChangeBased delivers only fields differing from the last one sent. // // A CLCW usually repeats unchanged for many frames, so this cuts the // downlink cost of watching one dramatically. UpdateChangeBased UpdateMode = 1 )
type UplinkStatus ¶
type UplinkStatus int
UplinkStatus reports what the uplink carrier is doing, from the UplinkStatus INTEGER of the CLTU structures module.
const ( UplinkStatusNotAvailable UplinkStatus = 0 UplinkNoRfAvailable UplinkStatus = 1 UplinkNoBitLock UplinkStatus = 2 UplinkNominal UplinkStatus = 3 )