Documentation
¶
Overview ¶
Package cfdp implements the CCSDS File Delivery Protocol per CCSDS 727.0-B-5 (July 2020).
CFDP moves files over space links. A transaction sends one file from a source entity to a destination entity as a run of Protocol Data Units: a Metadata PDU describing the file, a stream of File Data PDUs carrying its contents, and an EOF PDU closing it out. In acknowledged mode the receiver answers with NAK PDUs naming the gaps it still needs, and the exchange ends with a Finished PDU and its ACK.
CFDP PDUs are ordinary payload bytes. They ride inside Space Packets or Encapsulation Packets, so this package composes with pkg/spp and pkg/epp from the outside and changes neither.
The transaction machines here own no goroutines and no clock. The caller pumps them, the same shape as pkg/cop's FOP-1: hand PDUs in, ask what to send next, drive timeouts from your own scheduler. That keeps the library testable and leaves scheduling policy where it belongs.
Index ¶
- Constants
- Variables
- func DecodeFaultHandlerOverride(t TLV) (ConditionCode, FaultHandler, error)
- type ACKPDU
- type Checksum
- type ConditionCode
- type DeliveryCode
- type Direction
- type DirectiveCode
- type DirectoryListingRequest
- type DirectoryListingResponse
- type EOFPDU
- type EntityID
- type FaultHandler
- type FileDataPDU
- type FileStatus
- type Filestore
- type FilestoreAction
- type FilestoreRequest
- type FilestoreResponse
- type FinishedPDU
- type KeepAlivePDU
- type LV
- type MemoryFilestore
- func (f *MemoryFilestore) Create(name string) error
- func (f *MemoryFilestore) Delete(name string) error
- func (f *MemoryFilestore) Exists(name string) bool
- func (f *MemoryFilestore) Read(name string) ([]byte, error)
- func (f *MemoryFilestore) Rename(from, to string) error
- func (f *MemoryFilestore) Size(name string) (uint64, error)
- func (f *MemoryFilestore) WriteAt(name string, offset uint64, data []byte) error
- type MetadataPDU
- type NAKPDU
- type OSFilestore
- func (f *OSFilestore) Create(name string) error
- func (f *OSFilestore) Delete(name string) error
- func (f *OSFilestore) Exists(name string) bool
- func (f *OSFilestore) Read(name string) ([]byte, error)
- func (f *OSFilestore) Rename(from, to string) error
- func (f *OSFilestore) Size(name string) (uint64, error)
- func (f *OSFilestore) WriteAt(name string, offset uint64, data []byte) error
- type OriginatingTransactionID
- type PDU
- type PDUHeader
- type PromptPDU
- type PromptResponse
- type ProxyClosureRequest
- type ProxyFaultHandlerOverride
- type ProxyFilestoreRequest
- type ProxyFilestoreResponse
- type ProxyFlowLabel
- type ProxyMessageToUser
- type ProxyPutRequest
- type ProxyPutResponse
- type ProxySegmentationControl
- type ProxyTransmissionMode
- type Receiver
- func (r *Receiver) Cancel()
- func (r *Receiver) Complete() bool
- func (r *Receiver) ConditionCode() ConditionCode
- func (r *Receiver) DeclareFault(cond ConditionCode)
- func (r *Receiver) Done() bool
- func (r *Receiver) ExpireCheckLimit()
- func (r *Receiver) FileName() string
- func (r *Receiver) HandlePDU(pdu *PDU) error
- func (r *Receiver) Metadata() *MetadataPDU
- func (r *Receiver) MissingSegments() []SegmentRequest
- func (r *Receiver) NextPDU() (*PDU, bool, error)
- func (r *Receiver) RequestNAK() error
- func (r *Receiver) ResendFinished()
- func (r *Receiver) Resume()
- func (r *Receiver) State() TransactionState
- func (r *Receiver) Suspend()
- func (r *Receiver) Suspended() bool
- type ReceiverConfig
- type RecordContinuationState
- type RemoteResumeRequest
- type RemoteResumeResponse
- type RemoteStatusReportRequest
- type RemoteStatusReportResponse
- type RemoteSuspendRequest
- type RemoteSuspendResponse
- type SegmentRequest
- type Sender
- func (s *Sender) AckFinished() (*PDU, bool, error)
- func (s *Sender) Cancel()
- func (s *Sender) Checksum() uint32
- func (s *Sender) DeclareFault(cond ConditionCode)
- func (s *Sender) Done() bool
- func (s *Sender) Finished() *FinishedPDU
- func (s *Sender) HandlePDU(pdu *PDU) error
- func (s *Sender) NextPDU() (*PDU, bool, error)
- func (s *Sender) ResendEOF()
- func (s *Sender) Resume()
- func (s *Sender) State() TransactionState
- func (s *Sender) Suspend()
- func (s *Sender) Suspended() bool
- type SenderConfig
- type SuspensionResponse
- type TLV
- type TLVType
- type TransactionID
- type TransactionState
- type TransactionStatus
- type UserMessage
- type UserMessageType
Constants ¶
const ( // ChecksumModular is the legacy modular checksum. Clause 4.2.2.3 requires every // implementation to provide it. ChecksumModular uint8 = 0 // ChecksumCRC32C is CRC-32 Castagnoli, registry entry 2. ChecksumCRC32C uint8 = 2 // ChecksumCRC32 is the standard CRC-32, registry entry 3. ChecksumCRC32 uint8 = 3 // ChecksumNull always yields zero. Clause 4.2.2.4 requires it, and warns that it // protects nothing. ChecksumNull uint8 = 15 )
Checksum types from the SANA Checksum Identifiers registry, as referenced by CCSDS 727.0-B-5 clause 4.2.2.2.
const ( // StatusSuccessful is status code 0 for every action. StatusSuccessful uint8 = 0x0 // StatusNotPerformed is status code 15 for every action. StatusNotPerformed uint8 = 0xF )
Status codes shared across actions, per table 5-18. Code 0 is success for every action and 15 means the action was not attempted.
const CRCSize = 2
CRCSize is the width of the optional PDU CRC, in octets (clause 4.1.3).
const DefaultSegmentSize = 1024
DefaultSegmentSize is the file data payload size used when a SenderConfig leaves SegmentSize at zero.
const FixedHeaderSize = 4
FixedHeaderSize is the width of the PDU header before the variable-width entity IDs and transaction sequence number.
const MaxIDWidth = 8
MaxIDWidth is the widest entity ID or sequence number the 3-bit length fields of table 5-1 can describe: the encoded value is the width less one.
const MaxSegmentMetadataSize = 63
MaxSegmentMetadataSize is the widest segment metadata a 6-bit length field can describe (clause 5.3, table 5-14).
const MessageMagicSize = 4
MessageMagicSize is the width of the message identifier in octets.
const Version = 1
Version is the PDU version of CCSDS 727.0-B-5 table 5-1: binary '001', the second version of the protocol.
Variables ¶
var ( // ErrDataTooShort indicates the input ended before a field it must contain. ErrDataTooShort = errors.New("data too short for the PDU field being read") // ErrInvalidVersion indicates a PDU version other than the '001' of // CCSDS 727.0-B-5 table 5-1. ErrInvalidVersion = errors.New("invalid PDU version: this implementation speaks version 1") // ErrInvalidEntityIDWidth indicates an entity ID or transaction sequence // number width outside the 1-to-8 octet range the 3-bit length field allows. ErrInvalidEntityIDWidth = errors.New("invalid entity ID or sequence number width: must be 1 to 8 octets") // ErrEntityIDOverflow indicates a value too large for its declared width. ErrEntityIDOverflow = errors.New("entity ID or sequence number does not fit its declared width") // ErrValueTooLong indicates an LV or TLV value beyond the 255 octets its // 8-bit length field can describe. ErrValueTooLong = errors.New("LV or TLV value exceeds 255 octets") // ErrInvalidDirectiveCode indicates a reserved or unrecognized directive code. ErrInvalidDirectiveCode = errors.New("invalid or reserved file directive code") // ErrWrongDirectiveCode indicates a decode call for one directive was // handed the bytes of another. ErrWrongDirectiveCode = errors.New("directive code does not match the PDU being decoded") // ErrNotFileDirective indicates a file directive operation on a File Data PDU. ErrNotFileDirective = errors.New("PDU is file data, not a file directive") // ErrNotFileData indicates a file data operation on a File Directive PDU. ErrNotFileData = errors.New("PDU is a file directive, not file data") // ErrCRCMismatch indicates the optional PDU CRC failed validation, so the // PDU must be discarded per clause 4.1.2. ErrCRCMismatch = errors.New("PDU CRC mismatch: received CRC does not match computed CRC") // ErrDataLengthMismatch indicates the header's PDU data field length does // not match the bytes supplied. ErrDataLengthMismatch = errors.New("PDU data field length does not match the data supplied") // ErrUnsupportedChecksumType indicates a checksum algorithm this // implementation does not provide. ErrUnsupportedChecksumType = errors.New("unsupported checksum type") // ErrChecksumFailure indicates the received file did not match the // checksum in its EOF PDU. ErrChecksumFailure = errors.New("file checksum failure") // ErrFileSizeError indicates received file data extends beyond the size // declared in the EOF PDU. ErrFileSizeError = errors.New("file size error: data extends past the declared file size") // ErrInvalidTransmissionMode indicates an operation that the transaction's // class does not support. ErrInvalidTransmissionMode = errors.New("invalid transmission mode for this operation") // ErrTransactionFinished indicates the transaction has already completed. ErrTransactionFinished = errors.New("transaction has already finished") // ErrSuspended indicates the transaction is suspended and will emit // nothing until resumed. ErrSuspended = errors.New("transaction is suspended") // ErrFileNotFound indicates the filestore has no such file. ErrFileNotFound = errors.New("file not found in the filestore") // ErrFilestoreRejection indicates the filestore refused the operation. ErrFilestoreRejection = errors.New("filestore rejected the operation") // ErrUnsupportedAction indicates a filestore action code this // implementation does not execute. ErrUnsupportedAction = errors.New("unsupported filestore action") // ErrSegmentTooLarge indicates segment metadata beyond the 63 octets its // 6-bit length field can describe. ErrSegmentTooLarge = errors.New("segment metadata exceeds 63 octets") // ErrInvalidFaultHandler indicates a fault handler override TLV whose // handler code is not one of the four defined by clause 5.4.4. ErrInvalidFaultHandler = errors.New("invalid fault handler code") // ErrNotUserMessage indicates a Message to User TLV that does not open // with the "cfdp" identifier, so it is an application message rather than // a Reserved CFDP Message. It is how a receiver tells the two apart, not // a malformed protocol message. ErrNotUserMessage = errors.New("message to user is not a Reserved CFDP Message") // ErrReservedBitsSet indicates a field the standard requires to be zero // that is not. A sender setting one is using something this issue has not // defined, and reading the rest of the field out from under it would be a // guess. ErrReservedBitsSet = errors.New("a field reserved for future use is not zero") )
Sentinel errors returned by the CFDP protocol machinery.
var MessageMagic = [4]byte{'c', 'f', 'd', 'p'}
MessageMagic is the message identifier every Reserved CFDP Message opens with: the ASCII characters "cfdp" (clause 6.1.2, table 6-1).
It is what distinguishes a protocol message from an application one, since both travel in a Message to User TLV.
Functions ¶
func DecodeFaultHandlerOverride ¶
func DecodeFaultHandlerOverride(t TLV) (ConditionCode, FaultHandler, error)
DecodeFaultHandlerOverride reads a fault handler override TLV (clause 5.4.4).
Types ¶
type ACKPDU ¶
type ACKPDU struct {
// AckedDirective is the directive being acknowledged: EOF or Finished.
AckedDirective DirectiveCode
// DirectiveSubtype is binary '0001' when acknowledging a Finished PDU and
// '0000' for everything else (clause 5.2.4).
DirectiveSubtype uint8
// ConditionCode is the condition code of the acknowledged PDU.
ConditionCode ConditionCode
TransactionStatus TransactionStatus
}
ACKPDU acknowledges an EOF or Finished PDU. Table 5-8 allows no others.
func DecodeACKPDU ¶
DecodeACKPDU parses an ACK PDU data field.
func NewACK ¶
func NewACK(acked DirectiveCode, cond ConditionCode, status TransactionStatus) (*ACKPDU, error)
NewACK builds an ACK for one directive, filling in the subtype table 5-8 requires.
type Checksum ¶
type Checksum interface {
// Update folds a run of file octets at the given file offset into the sum.
Update(offset uint64, data []byte)
// Sum returns the checksum computed so far.
Sum() uint32
// Type returns the SANA registry identifier for this algorithm.
Type() uint8
}
Checksum accumulates a CFDP file checksum. Every checksum is 32 bits (clause 4.2.1.2).
Segments may arrive in any order and at any offset: Update takes the file offset with the data, so an out-of-order stream produces the same result as a sequential one.
func NewChecksum ¶
NewChecksum returns an accumulator for a checksum type, or ErrUnsupportedChecksumType if this package does not implement it.
type ConditionCode ¶
type ConditionCode uint8
ConditionCode reports why a transaction ended as it did, per table 5-5.
const ( CondNoError ConditionCode = 0x0 CondPositiveACKLimitReached ConditionCode = 0x1 CondKeepAliveLimitReached ConditionCode = 0x2 CondInvalidTransmissionMode ConditionCode = 0x3 CondFilestoreRejection ConditionCode = 0x4 CondFileChecksumFailure ConditionCode = 0x5 CondFileSizeError ConditionCode = 0x6 CondNAKLimitReached ConditionCode = 0x7 CondInactivityDetected ConditionCode = 0x8 CondInvalidFileStructure ConditionCode = 0x9 CondCheckLimitReached ConditionCode = 0xA CondUnsupportedChecksumType ConditionCode = 0xB CondSuspendRequestReceived ConditionCode = 0xE CondCancelRequestReceived ConditionCode = 0xF )
type DeliveryCode ¶
type DeliveryCode uint8
DeliveryCode says whether the receiver got everything (clause 5.2.3).
const ( // DeliveryDataComplete means metadata, all file data and EOF arrived and // the checksum verified. DeliveryDataComplete DeliveryCode = 0 // DeliveryDataIncomplete means something is still missing. DeliveryDataIncomplete DeliveryCode = 1 )
func (DeliveryCode) String ¶ added in v0.4.0
func (d DeliveryCode) String() string
String names the delivery code.
type Direction ¶
type Direction uint8
Direction indicates which way a PDU travels, per table 5-1. It exists so intermediate nodes can forward PDUs without parsing them.
type DirectiveCode ¶
type DirectiveCode uint8
DirectiveCode identifies a file directive, per CCSDS 727.0-B-5 table 5-4.
const ( // DirectiveEOF closes out the file data stream (clause 5.2.2). DirectiveEOF DirectiveCode = 0x04 // DirectiveFinished reports delivery at the receiver (clause 5.2.3). DirectiveFinished DirectiveCode = 0x05 // DirectiveACK acknowledges an EOF or Finished PDU (clause 5.2.4). DirectiveACK DirectiveCode = 0x06 // DirectiveMetadata opens a transaction (clause 5.2.5). DirectiveMetadata DirectiveCode = 0x07 // DirectiveNAK names the file segments still missing (clause 5.2.6). DirectiveNAK DirectiveCode = 0x08 // DirectivePrompt asks the far end for a NAK or Keep Alive (clause 5.2.7). DirectivePrompt DirectiveCode = 0x09 // DirectiveKeepAlive reports the receiver's progress (clause 5.2.8). DirectiveKeepAlive DirectiveCode = 0x0C )
func DirectiveCodeOf ¶
func DirectiveCodeOf(data []byte) (DirectiveCode, error)
DirectiveCodeOf returns the directive code of a File Directive PDU data field.
func (DirectiveCode) Valid ¶
func (d DirectiveCode) Valid() bool
Valid reports whether the code is one of the seven defined directives. Table 5-4 reserves 00-03 and 0D-FF, and leaves 0A-0B undefined.
type DirectoryListingRequest ¶ added in v0.4.0
type DirectoryListingRequest struct {
DirectoryName string
// DirectoryFileName is where the responder should put the listing, on the
// filestore local to the requesting user.
DirectoryFileName string
}
DirectoryListingRequest asks a remote user for a directory listing, to be written to a named file on the requester's own filestore (table 6-15).
func DecodeDirectoryListingRequest ¶ added in v0.4.0
func DecodeDirectoryListingRequest(content []byte) (*DirectoryListingRequest, error)
DecodeDirectoryListingRequest reads the message content.
func (DirectoryListingRequest) Encode ¶ added in v0.4.0
func (m DirectoryListingRequest) Encode() (UserMessage, error)
Encode builds the message.
func (*DirectoryListingRequest) Humanize ¶ added in v0.4.0
func (m *DirectoryListingRequest) Humanize() string
Humanize returns a human-readable summary.
type DirectoryListingResponse ¶ added in v0.4.0
type DirectoryListingResponse struct {
// Successful is the listing response code. Table 6-16 encodes success as
// '0'. The opposite polarity from the Remote Status Report Response,
// where table 6-19 encodes success as '1'. The flag here reads the same
// way in both, and each encoder writes what its own table says.
Successful bool
DirectoryName string
DirectoryFileName string
}
DirectoryListingResponse reports whether the listing could be produced (table 6-16).
func DecodeDirectoryListingResponse ¶ added in v0.4.0
func DecodeDirectoryListingResponse(content []byte) (*DirectoryListingResponse, error)
DecodeDirectoryListingResponse reads the message content.
func (DirectoryListingResponse) Encode ¶ added in v0.4.0
func (m DirectoryListingResponse) Encode() (UserMessage, error)
Encode builds the message: the response code, seven spare bits, then the two names.
func (*DirectoryListingResponse) Humanize ¶ added in v0.4.0
func (m *DirectoryListingResponse) Humanize() string
Humanize returns a human-readable summary.
type EOFPDU ¶
type EOFPDU struct {
ConditionCode ConditionCode
FileChecksum uint32
FileSize uint64 // FSS
// FaultLocation is an entity ID TLV, present only when ConditionCode is
// not "no error".
FaultLocation *TLV
}
EOFPDU closes the file data stream and carries the checksum the receiver verifies against.
func DecodeEOFPDU ¶
DecodeEOFPDU parses an EOF PDU data field.
type EntityID ¶
EntityID is a CFDP entity identifier or transaction sequence number: an unsigned integer whose octet width travels in the PDU header (clause 5.1.4).
Width carries semantic weight on the wire but none in comparisons: Clause 5.1.7 note 3 says two IDs of different widths compare by zero-padding the shorter.
func NewEntityID ¶
NewEntityID returns an EntityID just wide enough to hold value.
type FaultHandler ¶
type FaultHandler uint8
FaultHandler is a disposition for a fault condition, per CCSDS 727.0-B-5 Clause 4.8. Table 4-1 assigns every fault condition a default handler; a fault handler override TLV (clause 5.4.4) or per-transaction configuration replaces it.
The numeric values are the handler codes of the fault handler override TLV, so a FaultHandler travels on the wire unchanged.
const ( // FaultHandlerCancel issues a Notice of Cancellation ('0001'): the // transaction closes out with the fault's condition code. FaultHandlerCancel FaultHandler = 0x1 // FaultHandlerSuspend issues a Notice of Suspension ('0010'): the // transaction goes quiet until the caller resumes it. FaultHandlerSuspend FaultHandler = 0x2 // FaultHandlerIgnore ignores the fault ('0011') and lets the transaction // carry on. FaultHandlerIgnore FaultHandler = 0x3 // FaultHandlerAbandon abandons the transaction ('0100') with no further // protocol activity, not even a Finished PDU. FaultHandlerAbandon FaultHandler = 0x4 )
func DefaultFaultHandler ¶
func DefaultFaultHandler(ConditionCode) FaultHandler
DefaultFaultHandler returns table 4-1's default disposition for a fault condition: every condition defaults to a Notice of Cancellation.
func (FaultHandler) Valid ¶
func (h FaultHandler) Valid() bool
Valid reports whether the handler is one of the four defined codes.
type FileDataPDU ¶
type FileDataPDU struct {
// RecordContinuation and SegmentMetadata are present only when the
// header's segment metadata flag is set.
RecordContinuation RecordContinuationState
SegmentMetadata []byte
// Offset is where this data belongs in the file, in octets from the start.
Offset uint64 // FSS
// Data is the file content itself.
Data []byte
}
FileDataPDU carries a run of file octets at a given offset.
func DecodeFileDataPDU ¶
func DecodeFileDataPDU(data []byte, segmentMetadataPresent, largeFile bool) (*FileDataPDU, error)
DecodeFileDataPDU parses a File Data PDU data field. The flags must match the header that carried it.
func (*FileDataPDU) Encode ¶
func (p *FileDataPDU) Encode(segmentMetadataPresent, largeFile bool) ([]byte, error)
Encode serializes the File Data PDU data field.
segmentMetadataPresent and largeFile must match the flags in the PDU header that will carry this data field; the wire format is not self-describing.
func (*FileDataPDU) End ¶
func (p *FileDataPDU) End() uint64
End returns the file offset just past this segment's last octet.
func (*FileDataPDU) Humanize ¶
func (p *FileDataPDU) Humanize() string
Humanize returns a human-readable summary.
type FileStatus ¶
type FileStatus uint8
FileStatus reports what became of the delivered file (clause 5.2.3).
const ( FileDiscardedDeliberately FileStatus = 0 FileDiscardedRejection FileStatus = 1 FileRetainedSuccessfully FileStatus = 2 FileStatusUnreported FileStatus = 3 )
type Filestore ¶
type Filestore interface {
// Read returns the whole contents of name.
Read(name string) ([]byte, error)
// WriteAt writes data at a byte offset, growing the file as needed.
WriteAt(name string, offset uint64, data []byte) error
// Create makes an empty file, replacing any existing one.
Create(name string) error
// Delete removes a file.
Delete(name string) error
// Rename moves a file.
Rename(from, to string) error
// Size returns the current length of a file.
Size(name string) (uint64, error)
// Exists reports whether a file is present.
Exists(name string) bool
}
Filestore is the file system a CFDP entity reads from and writes to.
It is deliberately small: CFDP needs to read a source file, write a destination file at arbitrary offsets, and run the handful of filestore actions of table 5-16. Anything richer belongs to the application.
type FilestoreAction ¶
type FilestoreAction uint8
FilestoreAction is a filestore request action code, per CCSDS 727.0-B-5 table 5-16.
const ( ActionCreateFile FilestoreAction = 0x0 ActionDeleteFile FilestoreAction = 0x1 ActionRenameFile FilestoreAction = 0x2 ActionAppendFile FilestoreAction = 0x3 ActionReplaceFile FilestoreAction = 0x4 ActionCreateDirectory FilestoreAction = 0x5 ActionRemoveDirectory FilestoreAction = 0x6 ActionDenyFile FilestoreAction = 0x7 ActionDenyDirectory FilestoreAction = 0x8 )
func (FilestoreAction) NeedsSecondFileName ¶
func (a FilestoreAction) NeedsSecondFileName() bool
NeedsSecondFileName reports whether this action takes two filenames, per table 5-16.
type FilestoreRequest ¶
type FilestoreRequest struct {
Action FilestoreAction
FirstFileName LV
SecondFileName LV
}
FilestoreRequest is the value of a filestore request TLV (table 5-15).
func DecodeFilestoreRequest ¶
func DecodeFilestoreRequest(t TLV) (*FilestoreRequest, error)
DecodeFilestoreRequest parses a filestore request TLV.
func (FilestoreRequest) Encode ¶
func (r FilestoreRequest) Encode() (TLV, error)
Encode serializes the request as a TLV of type 00.
type FilestoreResponse ¶
type FilestoreResponse struct {
Action FilestoreAction
StatusCode uint8
FirstFileName LV
SecondFileName LV
Message LV
}
FilestoreResponse is the value of a filestore response TLV (table 5-17).
func DecodeFilestoreResponse ¶
func DecodeFilestoreResponse(t TLV) (*FilestoreResponse, error)
DecodeFilestoreResponse parses a filestore response TLV.
func ExecuteFilestoreRequest ¶
func ExecuteFilestoreRequest(fs Filestore, req *FilestoreRequest) FilestoreResponse
ExecuteFilestoreRequest runs one filestore action and returns the response TLV value that belongs in the Finished PDU.
Actions this package does not execute (append, replace, and the directory actions) come back with status "not performed" rather than an error, which is what table 5-18 provides for.
func (FilestoreResponse) Encode ¶
func (r FilestoreResponse) Encode() (TLV, error)
Encode serializes the response as a TLV of type 01.
type FinishedPDU ¶
type FinishedPDU struct {
ConditionCode ConditionCode
DeliveryCode DeliveryCode
FileStatus FileStatus
FilestoreResponses []TLV
FaultLocation *TLV
}
FinishedPDU reports the outcome of a transaction at the receiver.
func DecodeFinishedPDU ¶
func DecodeFinishedPDU(data []byte) (*FinishedPDU, error)
DecodeFinishedPDU parses a Finished PDU data field.
The trailing TLVs are all filestore responses except a final entity ID TLV, which is the fault location. Table 5-7 distinguishes them by type, not by position, so this splits on the type code.
func (*FinishedPDU) Encode ¶
func (p *FinishedPDU) Encode() ([]byte, error)
Encode serializes the Finished PDU data field.
func (*FinishedPDU) Humanize ¶
func (p *FinishedPDU) Humanize() string
Humanize returns a human-readable summary.
type KeepAlivePDU ¶
type KeepAlivePDU struct {
Progress uint64 // FSS, offset from the start of the file
}
KeepAlivePDU reports how much of the file the receiver has.
func DecodeKeepAlivePDU ¶
func DecodeKeepAlivePDU(data []byte, largeFile bool) (*KeepAlivePDU, error)
DecodeKeepAlivePDU parses a Keep Alive PDU data field.
func (*KeepAlivePDU) Encode ¶
func (p *KeepAlivePDU) Encode(largeFile bool) ([]byte, error)
Encode serializes the Keep Alive PDU data field.
func (*KeepAlivePDU) Humanize ¶
func (p *KeepAlivePDU) Humanize() string
Humanize returns a human-readable summary.
type LV ¶
type LV struct {
Value []byte
}
LV is a Length-Value object per CCSDS 727.0-B-5 table 5-2: an 8-bit length followed by that many octets. Used for filenames, whose position in the PDU is fixed even though their length is not.
A zero length means the value is absent, an empty filename, for instance, marks a transaction with no associated file (clause 5.2.5).
type MemoryFilestore ¶
type MemoryFilestore struct {
// contains filtered or unexported fields
}
MemoryFilestore is an in-memory Filestore, useful for tests and for entities that never touch a disk. It is safe for concurrent use.
func NewMemoryFilestore ¶
func NewMemoryFilestore() *MemoryFilestore
NewMemoryFilestore returns an empty in-memory filestore.
func (*MemoryFilestore) Create ¶
func (f *MemoryFilestore) Create(name string) error
Create makes an empty file, discarding any existing contents.
func (*MemoryFilestore) Delete ¶
func (f *MemoryFilestore) Delete(name string) error
Delete removes a file.
func (*MemoryFilestore) Exists ¶
func (f *MemoryFilestore) Exists(name string) bool
Exists reports whether the file is present.
func (*MemoryFilestore) Read ¶
func (f *MemoryFilestore) Read(name string) ([]byte, error)
Read returns a copy of the file's contents.
func (*MemoryFilestore) Rename ¶
func (f *MemoryFilestore) Rename(from, to string) error
Rename moves a file.
type MetadataPDU ¶
type MetadataPDU struct {
// ClosureRequested asks the receiver for a Finished PDU. Table 5-9 says
// set it to '0' and ignore it in acknowledged mode, where a Finished PDU
// is sent regardless.
ClosureRequested bool
// ChecksumType selects the algorithm, per the SANA registry. Zero is the
// legacy modular checksum.
ChecksumType uint8
// FileSize is the file length in octets, or zero for unbounded size.
FileSize uint64 // FSS
// SourceFileName and DestinationFileName are empty when the transaction
// carries no file (metadata-only, as used by proxy operations).
SourceFileName LV
DestinationFileName LV
// Options are filestore requests, messages to user, fault handler
// overrides and flow labels.
Options []TLV
}
MetadataPDU opens a transaction and describes the file being sent.
func DecodeMetadataPDU ¶
func DecodeMetadataPDU(data []byte, largeFile bool) (*MetadataPDU, error)
DecodeMetadataPDU parses a Metadata PDU data field.
func (*MetadataPDU) Encode ¶
func (p *MetadataPDU) Encode(largeFile bool) ([]byte, error)
Encode serializes the Metadata PDU data field.
func (*MetadataPDU) Humanize ¶
func (p *MetadataPDU) Humanize() string
Humanize returns a human-readable summary.
type NAKPDU ¶
type NAKPDU struct {
StartOfScope uint64 // FSS
EndOfScope uint64 // FSS
Requests []SegmentRequest
}
NAKPDU lists the gaps the receiver is still missing.
func DecodeNAKPDU ¶
DecodeNAKPDU parses a NAK PDU data field.
type OSFilestore ¶
type OSFilestore struct {
Root string
}
OSFilestore is a Filestore backed by a directory on disk. Every name is resolved inside Root, and names that would escape it are refused.
func NewOSFilestore ¶
func NewOSFilestore(dir string) *OSFilestore
NewOSFilestore returns a filestore rooted at dir.
func (*OSFilestore) Create ¶
func (f *OSFilestore) Create(name string) error
Create makes an empty file, truncating any existing one.
func (*OSFilestore) Exists ¶
func (f *OSFilestore) Exists(name string) bool
Exists reports whether the file is present.
func (*OSFilestore) Read ¶
func (f *OSFilestore) Read(name string) ([]byte, error)
Read returns the whole contents of the file.
func (*OSFilestore) Rename ¶
func (f *OSFilestore) Rename(from, to string) error
Rename moves a file.
type OriginatingTransactionID ¶ added in v0.4.0
type OriginatingTransactionID struct {
Transaction TransactionID
}
OriginatingTransactionID is the message every User operation carries alongside its own, naming the transaction the operation refers to.
func DecodeOriginatingTransactionID ¶ added in v0.4.0
func DecodeOriginatingTransactionID(content []byte) (*OriginatingTransactionID, error)
DecodeOriginatingTransactionID reads the message content.
func (OriginatingTransactionID) Encode ¶ added in v0.4.0
func (m OriginatingTransactionID) Encode() (UserMessage, error)
Encode builds the message.
func (*OriginatingTransactionID) Humanize ¶ added in v0.4.0
func (m *OriginatingTransactionID) Humanize() string
Humanize returns a human-readable summary.
type PDU ¶
type PDU struct {
Header *PDUHeader
// Data is the PDU data field with any trailing CRC already removed.
Data []byte
}
PDU is one complete Protocol Data Unit: a header plus its data field.
func DecodePDU ¶
DecodePDU parses one complete PDU, verifying the CRC when the header says one is present. A CRC failure returns ErrCRCMismatch and the caller must discard the PDU, per clause 4.1.2.
func (*PDU) Encode ¶
Encode serializes the PDU, setting the data field length and appending the CRC when the header asks for one.
Per clause 4.1.3.2 the CRC occupies the final octets of the data field, its length counts toward the data field length, and it covers everything from the first octet of the header to the last octet before the CRC itself.
type PDUHeader ¶
type PDUHeader struct {
// IsFileData distinguishes a File Data PDU ('1') from a File Directive ('0').
IsFileData bool
// Direction is which way the PDU travels.
Direction Direction
// Acknowledged selects acknowledged mode. Note the wire encoding is
// inverted: table 5-1 gives '0' for acknowledged and '1' for
// unacknowledged, so this field is the logical sense, not the bit.
Acknowledged bool
// CRCFlag marks a PDU carrying a trailing CRC (clause 4.1).
CRCFlag bool
// LargeFile widens every File-Size Sensitive field from 32 to 64 bits
// (clause 5.1.10).
LargeFile bool
// DataLength is the octet length of the PDU data field. When CRCFlag is
// set this includes the two CRC octets (clause 4.1.3.2).
DataLength uint16
// SegmentationControl records whether record boundaries survive
// segmentation. Always '0' and ignored for File Directive PDUs.
SegmentationControl bool
// SegmentMetadataFlag marks a File Data PDU carrying segment metadata.
// Always '0' and ignored for File Directive PDUs.
SegmentMetadataFlag bool
// Source, TransactionSeq and Destination identify the transaction. All
// three entity IDs share one width; the sequence number has its own.
Source EntityID
TransactionSeq EntityID
Destination EntityID
}
PDUHeader is the fixed PDU header of CCSDS 727.0-B-5 table 5-1.
The first octet packs version, PDU type, direction, transmission mode, the CRC flag and the large-file flag. Then comes the 16-bit data field length. The fourth octet packs segmentation control, the entity ID width, the segment metadata flag and the sequence number width. The three variable width fields follow in the order source, sequence number, destination.
func DecodePDUHeader ¶
DecodePDUHeader parses a PDU header from the front of data and returns the header along with the number of octets consumed.
type PromptPDU ¶
type PromptPDU struct {
Response PromptResponse
}
PromptPDU asks the far end for a NAK or a Keep Alive.
func DecodePromptPDU ¶
DecodePromptPDU parses a Prompt PDU data field.
type PromptResponse ¶
type PromptResponse uint8
PromptResponse selects what the far end should send back (clause 5.2.7).
const ( // PromptNAK asks for a NAK PDU. PromptNAK PromptResponse = 0 // PromptKeepAlive asks for a Keep Alive PDU. PromptKeepAlive PromptResponse = 1 )
type ProxyClosureRequest ¶ added in v0.4.0
type ProxyClosureRequest struct {
ClosureRequested bool
}
ProxyClosureRequest asks for transaction closure on the proxied transaction (table 6-11).
func DecodeProxyClosureRequest ¶ added in v0.4.0
func DecodeProxyClosureRequest(content []byte) (*ProxyClosureRequest, error)
DecodeProxyClosureRequest reads the message content.
func (ProxyClosureRequest) Encode ¶ added in v0.4.0
func (m ProxyClosureRequest) Encode() UserMessage
Encode builds the message.
type ProxyFaultHandlerOverride ¶ added in v0.4.0
type ProxyFaultHandlerOverride struct {
Condition ConditionCode
Handler FaultHandler
}
ProxyFaultHandlerOverride changes a fault handler for the proxied transaction (table 6-7).
Its content is one octet holding the same condition code and handler code pairing clause 5.4.4 defines for the fault handler override TLV.
func DecodeProxyFaultHandlerOverride ¶ added in v0.4.0
func DecodeProxyFaultHandlerOverride(content []byte) (*ProxyFaultHandlerOverride, error)
DecodeProxyFaultHandlerOverride reads the message content.
func (ProxyFaultHandlerOverride) Encode ¶ added in v0.4.0
func (m ProxyFaultHandlerOverride) Encode() UserMessage
Encode builds the message.
type ProxyFilestoreRequest ¶ added in v0.4.0
type ProxyFilestoreRequest struct {
Request FilestoreRequest
}
ProxyFilestoreRequest carries one filestore request for the respondent to perform as part of the proxy operation.
Its content is a length octet and then a filestore request TLV's value, not a whole TLV: table 6-6 says the field "is a single CFDP filestore request as defined in table 5-15", and the length octet in front of it does the job the TLV's own length would.
func DecodeProxyFilestoreRequest ¶ added in v0.4.0
func DecodeProxyFilestoreRequest(content []byte) (*ProxyFilestoreRequest, error)
DecodeProxyFilestoreRequest reads the message content.
func (ProxyFilestoreRequest) Encode ¶ added in v0.4.0
func (m ProxyFilestoreRequest) Encode() (UserMessage, error)
Encode builds the message.
func (*ProxyFilestoreRequest) Humanize ¶ added in v0.4.0
func (m *ProxyFilestoreRequest) Humanize() string
Humanize returns a human-readable summary.
type ProxyFilestoreResponse ¶ added in v0.4.0
type ProxyFilestoreResponse struct {
Response FilestoreResponse
}
ProxyFilestoreResponse reports the outcome of one proxy filestore request.
func DecodeProxyFilestoreResponse ¶ added in v0.4.0
func DecodeProxyFilestoreResponse(content []byte) (*ProxyFilestoreResponse, error)
DecodeProxyFilestoreResponse reads the message content.
func (ProxyFilestoreResponse) Encode ¶ added in v0.4.0
func (m ProxyFilestoreResponse) Encode() (UserMessage, error)
Encode builds the message.
func (*ProxyFilestoreResponse) Humanize ¶ added in v0.4.0
func (m *ProxyFilestoreResponse) Humanize() string
Humanize returns a human-readable summary.
type ProxyFlowLabel ¶ added in v0.4.0
type ProxyFlowLabel struct {
Label []byte
}
ProxyFlowLabel carries a mission-defined flow label for the proxied transaction (table 6-9).
func DecodeProxyFlowLabel ¶ added in v0.4.0
func DecodeProxyFlowLabel(content []byte) (*ProxyFlowLabel, error)
DecodeProxyFlowLabel reads the message content.
func (ProxyFlowLabel) Encode ¶ added in v0.4.0
func (m ProxyFlowLabel) Encode() (UserMessage, error)
Encode builds the message.
type ProxyMessageToUser ¶ added in v0.4.0
type ProxyMessageToUser struct {
Text []byte
}
ProxyMessageToUser carries a message for the beneficiary's user, to be placed in the proxied transaction's metadata (table 6-5).
func DecodeProxyMessageToUser ¶ added in v0.4.0
func DecodeProxyMessageToUser(content []byte) (*ProxyMessageToUser, error)
DecodeProxyMessageToUser reads the message content.
func (ProxyMessageToUser) Encode ¶ added in v0.4.0
func (m ProxyMessageToUser) Encode() (UserMessage, error)
Encode builds the message.
type ProxyPutRequest ¶ added in v0.4.0
type ProxyPutRequest struct {
// Destination is the beneficiary's entity ID.
Destination EntityID
// SourceFileName and DestinationFileName are empty when omitted, which
// table 6-4 expresses as a zero-length LV rather than an absent field.
SourceFileName string
DestinationFileName string
}
ProxyPutRequest asks a remote user to send a file to a third entity.
The remote user is the respondent, and the entity named here is the beneficiary. When the beneficiary is the originator the operation works as a Get (clause 6.2, note).
func DecodeProxyPutRequest ¶ added in v0.4.0
func DecodeProxyPutRequest(content []byte) (*ProxyPutRequest, error)
DecodeProxyPutRequest reads the message content.
func (ProxyPutRequest) Encode ¶ added in v0.4.0
func (m ProxyPutRequest) Encode() (UserMessage, error)
Encode builds the message.
func (*ProxyPutRequest) Humanize ¶ added in v0.4.0
func (m *ProxyPutRequest) Humanize() string
Humanize returns a human-readable summary.
type ProxyPutResponse ¶ added in v0.4.0
type ProxyPutResponse struct {
Condition ConditionCode
Delivery DeliveryCode
File FileStatus
}
ProxyPutResponse reports the outcome of a proxy put back to the originator.
func DecodeProxyPutResponse ¶ added in v0.4.0
func DecodeProxyPutResponse(content []byte) (*ProxyPutResponse, error)
DecodeProxyPutResponse reads the message content.
func (ProxyPutResponse) Encode ¶ added in v0.4.0
func (m ProxyPutResponse) Encode() (UserMessage, error)
Encode builds the message.
The layout is condition code (4 bits), one spare bit, delivery code (1 bit), file status (2 bits). The same packing the Finished PDU uses, which is why the codes are the shared types.
func (*ProxyPutResponse) Humanize ¶ added in v0.4.0
func (m *ProxyPutResponse) Humanize() string
Humanize returns a human-readable summary.
type ProxySegmentationControl ¶ added in v0.4.0
type ProxySegmentationControl struct {
// RecordBoundariesRespected is '0' on the wire when true, per table 6-10.
RecordBoundariesRespected bool
}
ProxySegmentationControl says whether record boundaries are respected (table 6-10).
func DecodeProxySegmentationControl ¶ added in v0.4.0
func DecodeProxySegmentationControl(content []byte) (*ProxySegmentationControl, error)
DecodeProxySegmentationControl reads the message content.
func (ProxySegmentationControl) Encode ¶ added in v0.4.0
func (m ProxySegmentationControl) Encode() UserMessage
Encode builds the message.
type ProxyTransmissionMode ¶ added in v0.4.0
type ProxyTransmissionMode struct {
Acknowledged bool
}
ProxyTransmissionMode selects acknowledged or unacknowledged transmission for the proxied transaction (table 6-8).
func DecodeProxyTransmissionMode ¶ added in v0.4.0
func DecodeProxyTransmissionMode(content []byte) (*ProxyTransmissionMode, error)
DecodeProxyTransmissionMode reads the message content.
func (ProxyTransmissionMode) Encode ¶ added in v0.4.0
func (m ProxyTransmissionMode) Encode() UserMessage
Encode builds the message: seven spare bits then the mode.
type Receiver ¶
type Receiver struct {
// contains filtered or unexported fields
}
Receiver drives one incoming CFDP transaction.
Like Sender it owns no goroutines and no clock: the caller feeds it PDUs with HandlePDU and asks NextPDU what to send back.
Usage:
- Create with NewReceiver
- Call HandlePDU for every PDU that arrives
- Call NextPDU and transmit whatever it returns
- Check Done or State to see when the transaction has completed
A Receiver is safe for concurrent use.
func NewReceiver ¶
func NewReceiver(fs Filestore, config ReceiverConfig) *Receiver
NewReceiver prepares a transaction to receive one file.
func (*Receiver) Cancel ¶
func (r *Receiver) Cancel()
Cancel abandons the receive (clause 4.11.1): the partial file is discarded and, when the class calls for one, a Finished PDU with condition code "cancel request received" closes the transaction out.
func (*Receiver) Complete ¶
Complete reports whether every octet of the file has arrived and the EOF PDU has been seen.
func (*Receiver) ConditionCode ¶
func (r *Receiver) ConditionCode() ConditionCode
ConditionCode returns why the transaction ended as it did.
func (*Receiver) DeclareFault ¶
func (r *Receiver) DeclareFault(cond ConditionCode)
DeclareFault raises a fault the caller's own timers detected (a NAK limit, a keep-alive limit, a positive-ACK limit, or inactivity (table 5-5)) and applies the fault handler configured for it, defaulting to the table 4-1 disposition. The library owns no clock, so counting those limits is the caller's job.
func (*Receiver) ExpireCheckLimit ¶
func (r *Receiver) ExpireCheckLimit()
ExpireCheckLimit reports that the caller's transaction check timer has expired for the last time (clause 4.6.3.3). The caller drives this from its own clock, like RequestNAK and ResendEOF. Under the table 4-1 default the transaction cancels with condition code "check limit reached", which forces the Finished PDU a Class 1 closure-requested transaction still owes.
func (*Receiver) Metadata ¶
func (r *Receiver) Metadata() *MetadataPDU
Metadata returns the Metadata PDU that opened the transaction, if it has arrived.
func (*Receiver) MissingSegments ¶
func (r *Receiver) MissingSegments() []SegmentRequest
MissingSegments returns the byte ranges still outstanding.
func (*Receiver) NextPDU ¶
NextPDU returns the next PDU to send back, or ok == false when nothing is pending. A suspended transaction emits nothing.
func (*Receiver) RequestNAK ¶
RequestNAK queues a NAK for whatever is still missing. The caller drives this from its own timer, since this library owns no clock.
func (*Receiver) ResendFinished ¶
func (r *Receiver) ResendFinished()
ResendFinished re-queues the Finished PDU when its ACK does not arrive.
func (*Receiver) Resume ¶
func (r *Receiver) Resume()
Resume lets a suspended transaction emit again.
func (*Receiver) State ¶
func (r *Receiver) State() TransactionState
State returns the current transaction state.
type ReceiverConfig ¶
type ReceiverConfig struct {
// Source, Destination and TransactionSeq identify the transaction. They
// come from the first PDU received. Inbound PDUs whose source entity ID or
// transaction sequence number differ are ignored (clause 5.1), so one Receiver
// never applies a foreign transaction's PDUs.
Source EntityID
Destination EntityID
TransactionSeq EntityID
// Acknowledged selects Class 2 behavior: NAKs, Finished, and its ACK.
Acknowledged bool
// CRCFlag adds a CRC to every outgoing PDU.
CRCFlag bool
// DestinationFileName overrides the name in the Metadata PDU. Leave it
// empty to use what the sender asked for.
DestinationFileName string
// FaultHandlers overrides the default disposition for the given fault
// conditions at this entity. Table 4-1 defaults every condition to a
// Notice of Cancellation; fault handler override TLVs arriving in the
// Metadata PDU take precedence over both (clause 4.8).
FaultHandlers map[ConditionCode]FaultHandler
}
ReceiverConfig describes one incoming transaction.
type RecordContinuationState ¶
type RecordContinuationState uint8
RecordContinuationState says how a File Data PDU's payload sits relative to record boundaries, per CCSDS 727.0-B-5 clause 5.3. It is present only when the header's segment metadata flag is set.
const ( // RecordNeitherStartNorEnd means the payload holds no record boundary. With // segmentation control set it continues a record from an earlier PDU; // otherwise the file simply has no records. RecordNeitherStartNorEnd RecordContinuationState = 0 // RecordStartOnly means the payload starts a record that does not end here. RecordStartOnly RecordContinuationState = 1 // RecordEndOnly means the payload ends a record that began earlier. RecordEndOnly RecordContinuationState = 2 // RecordStartAndEnd means the payload holds one or more whole records. RecordStartAndEnd RecordContinuationState = 3 )
func (RecordContinuationState) String ¶
func (r RecordContinuationState) String() string
String names the continuation state.
type RemoteResumeRequest ¶ added in v0.4.0
type RemoteResumeRequest struct {
Transaction TransactionID
}
RemoteResumeRequest asks a remote user to resume one transaction (table 6-24). Clause 6.6.3.1.2 requires the carrying transaction to be Acknowledged.
func DecodeRemoteResumeRequest ¶ added in v0.4.0
func DecodeRemoteResumeRequest(content []byte) (*RemoteResumeRequest, error)
DecodeRemoteResumeRequest reads the message content.
func (RemoteResumeRequest) Encode ¶ added in v0.4.0
func (m RemoteResumeRequest) Encode() (UserMessage, error)
Encode builds the message.
type RemoteResumeResponse ¶ added in v0.4.0
type RemoteResumeResponse struct {
SuspensionResponse
}
RemoteResumeResponse reports the suspension state after a resume request (table 6-25).
func DecodeRemoteResumeResponse ¶ added in v0.4.0
func DecodeRemoteResumeResponse(content []byte) (*RemoteResumeResponse, error)
DecodeRemoteResumeResponse reads the message content.
func (RemoteResumeResponse) Encode ¶ added in v0.4.0
func (m RemoteResumeResponse) Encode() (UserMessage, error)
Encode builds the message.
type RemoteStatusReportRequest ¶ added in v0.4.0
type RemoteStatusReportRequest struct {
Transaction TransactionID
// ReportFileName is where the responder should put the report.
ReportFileName string
}
RemoteStatusReportRequest asks a remote user for a status report on one transaction, written to a named file on the requester's filestore (table 6-18).
func DecodeRemoteStatusReportRequest ¶ added in v0.4.0
func DecodeRemoteStatusReportRequest(content []byte) (*RemoteStatusReportRequest, error)
DecodeRemoteStatusReportRequest reads the message content.
func (RemoteStatusReportRequest) Encode ¶ added in v0.4.0
func (m RemoteStatusReportRequest) Encode() (UserMessage, error)
Encode builds the message.
func (*RemoteStatusReportRequest) Humanize ¶ added in v0.4.0
func (m *RemoteStatusReportRequest) Humanize() string
Humanize returns a human-readable summary.
type RemoteStatusReportResponse ¶ added in v0.4.0
type RemoteStatusReportResponse struct {
Status TransactionStatus
// Successful is the report response code. Table 6-19 encodes success as
// '1', the opposite of the Directory Listing Response's '0'.
Successful bool
Transaction TransactionID
}
RemoteStatusReportResponse reports whether the status report could be produced (table 6-19).
func DecodeRemoteStatusReportResponse ¶ added in v0.4.0
func DecodeRemoteStatusReportResponse(content []byte) (*RemoteStatusReportResponse, error)
DecodeRemoteStatusReportResponse reads the message content.
func (RemoteStatusReportResponse) Encode ¶ added in v0.4.0
func (m RemoteStatusReportResponse) Encode() (UserMessage, error)
Encode builds the message.
The first octet packs transaction status (2 bits), five spare bits, then the response code in the low bit, an unusual order, with the flag last rather than first as in table 6-16.
func (*RemoteStatusReportResponse) Humanize ¶ added in v0.4.0
func (m *RemoteStatusReportResponse) Humanize() string
Humanize returns a human-readable summary.
type RemoteSuspendRequest ¶ added in v0.4.0
type RemoteSuspendRequest struct {
Transaction TransactionID
}
RemoteSuspendRequest asks a remote user to suspend one transaction (table 6-21).
Clause 6.5.3.1.2 requires the carrying transaction to be Acknowledged.
func DecodeRemoteSuspendRequest ¶ added in v0.4.0
func DecodeRemoteSuspendRequest(content []byte) (*RemoteSuspendRequest, error)
DecodeRemoteSuspendRequest reads the message content.
func (RemoteSuspendRequest) Encode ¶ added in v0.4.0
func (m RemoteSuspendRequest) Encode() (UserMessage, error)
Encode builds the message.
type RemoteSuspendResponse ¶ added in v0.4.0
type RemoteSuspendResponse struct {
SuspensionResponse
}
RemoteSuspendResponse reports the suspension state after a suspend request (table 6-22).
func DecodeRemoteSuspendResponse ¶ added in v0.4.0
func DecodeRemoteSuspendResponse(content []byte) (*RemoteSuspendResponse, error)
DecodeRemoteSuspendResponse reads the message content.
func (RemoteSuspendResponse) Encode ¶ added in v0.4.0
func (m RemoteSuspendResponse) Encode() (UserMessage, error)
Encode builds the message.
type SegmentRequest ¶
type SegmentRequest struct {
StartOffset uint64 // FSS
EndOffset uint64 // FSS, first octet after the requested segment
}
SegmentRequest names one range of file data the receiver still needs. A request of 0..0 asks for the metadata (table 5-11).
func (SegmentRequest) IsMetadataRequest ¶
func (s SegmentRequest) IsMetadataRequest() bool
IsMetadataRequest reports whether this request asks for the Metadata PDU rather than a run of file data.
type Sender ¶
type Sender struct {
// contains filtered or unexported fields
}
Sender drives one outgoing CFDP transaction.
It owns no goroutines and no clock. The caller pumps it: NextPDU returns the next PDU to transmit, HandlePDU feeds inbound PDUs back in, and the caller's own scheduler decides when to retransmit. This is the same contract as pkg/cop's FOP-1.
Usage:
- Create with NewSender
- Call NextPDU repeatedly and transmit what it returns, until it reports that nothing is pending
- Call HandlePDU when a PDU arrives on the return link
- Check Done or State to see when the transaction has completed
A Sender is safe for concurrent use.
func NewSender ¶
func NewSender(fs Filestore, config SenderConfig) (*Sender, error)
NewSender prepares a transaction to send one file. It reads the source file up front and computes its checksum, so the file must be readable now.
A transaction with an empty source filename carries metadata only, which is how proxy operations and pure filestore requests travel (clause 5.2.5).
func (*Sender) AckFinished ¶
AckFinished builds the ACK a Class 2 sender owes for a Finished PDU (clause 5.2.4). Returns ok == false when no Finished PDU has arrived.
func (*Sender) Cancel ¶
func (s *Sender) Cancel()
Cancel cancels the transaction (clause 4.11.1). The next PDU out is an EOF carrying the cancel condition code of table 5-5 and the transaction's progress so far.
func (*Sender) DeclareFault ¶
func (s *Sender) DeclareFault(cond ConditionCode)
DeclareFault raises a fault the caller's own timers detected (the positive ACK limit of clause 4.7, a keep-alive limit, or inactivity (table 5-5)) and applies the fault handler configured for it, defaulting to the table 4-1 disposition (cancel). The library owns no clock, so counting those limits is the caller's job.
func (*Sender) Finished ¶
func (s *Sender) Finished() *FinishedPDU
Finished returns the Finished PDU the receiver sent, if any.
func (*Sender) HandlePDU ¶
HandlePDU feeds a PDU arriving on the return link into the transaction.
The sender expects NAK, ACK of its EOF, Finished, Keep Alive and Prompt. Anything else is ignored rather than treated as an error, since a shared link may carry PDUs for other transactions.
func (*Sender) NextPDU ¶
NextPDU returns the next PDU to transmit, or ok == false when nothing is pending right now. A false does not mean the transaction is over: check Done for that.
The order is metadata, then any segments a NAK asked for again, then fresh file data, then EOF. A suspended transaction emits nothing.
func (*Sender) ResendEOF ¶
func (s *Sender) ResendEOF()
ResendEOF re-queues the EOF PDU. The caller invokes this from its own timer when an EOF ACK does not arrive; clause 4.2 leaves the timing to the implementation and this library owns no clock.
func (*Sender) State ¶
func (s *Sender) State() TransactionState
State returns the current transaction state.
type SenderConfig ¶
type SenderConfig struct {
// Source, Destination and TransactionSeq identify the transaction.
Source EntityID
Destination EntityID
TransactionSeq EntityID
// Acknowledged selects Class 2 (acknowledged) rather than Class 1.
Acknowledged bool
// SegmentSize is the largest file data payload per PDU, in octets.
SegmentSize int
// SourceFileName and DestinationFileName name the file at each end.
SourceFileName string
DestinationFileName string
// ChecksumType selects the file checksum algorithm. Zero is the modular
// checksum every implementation must provide.
ChecksumType uint8
// ClosureRequested asks for a Finished PDU in unacknowledged mode. It is
// ignored in acknowledged mode, where one always comes back.
ClosureRequested bool
// CRCFlag adds a CRC to every outgoing PDU.
CRCFlag bool
// FilestoreRequests travel in the Metadata PDU for the receiver to run.
FilestoreRequests []FilestoreRequest
// MessagesToUser are opaque application messages for the Metadata PDU.
MessagesToUser [][]byte
// FaultHandlers overrides the default disposition for the given fault
// conditions at this entity. Table 4-1 defaults every condition to a
// Notice of Cancellation (clause 4.8).
FaultHandlers map[ConditionCode]FaultHandler
// FaultHandlerOverrides travel as TLVs in the Metadata PDU (clause 5.4.4) and
// change the receiver's disposition for the named conditions.
FaultHandlerOverrides map[ConditionCode]FaultHandler
}
SenderConfig describes one outgoing transaction.
type SuspensionResponse ¶ added in v0.4.0
type SuspensionResponse struct {
Suspended bool
Status TransactionStatus
Transaction TransactionID
}
SuspensionResponse is the body both the suspend and the resume response share: whether the transaction is now suspended, its status, and which transaction it was (tables 6-22 and 6-25).
Clause 6.6.4.2 notes that a successful resume may not change the suspension status at all, because several motivations for suspending can be valid at once, so the indicator reports the state, not the outcome of the request.
func (*SuspensionResponse) Humanize ¶ added in v0.4.0
func (m *SuspensionResponse) Humanize() string
Humanize returns a human-readable summary.
type TLV ¶
TLV is a Type-Length-Value object per table 5-3. Unlike an LV, a TLV can sit anywhere in the PDU, because its type field says what it is.
func DecodeTLV ¶
DecodeTLV reads one TLV object from the front of data, returning it and the number of octets consumed.
func DecodeTLVs ¶
DecodeTLVs reads TLV objects until data runs out. A trailing partial object is an error, not a silent truncation.
func EntityIDTLV ¶
EntityIDTLV builds the entity ID TLV that carries a fault location (clause 5.4.6).
func FaultHandlerOverrideTLV ¶
func FaultHandlerOverrideTLV(cond ConditionCode, handler FaultHandler) (TLV, error)
FaultHandlerOverrideTLV builds the fault handler override TLV of clause 5.4.4: one octet holding the condition code (4 bits) and the handler code (4 bits).
func (TLV) AsEntityID ¶
AsEntityID reads an entity ID out of a TLV of type 06.
type TLVType ¶
type TLVType uint8
TLVType identifies the kind of a TLV object, per clause 5.4.
const ( // TLVFilestoreRequest carries a filestore action to perform (clause 5.4.1). TLVFilestoreRequest TLVType = 0x00 // TLVFilestoreResponse reports the outcome of one request (clause 5.4.2). TLVFilestoreResponse TLVType = 0x01 // TLVMessageToUser carries an opaque application message (clause 5.4.3). TLVMessageToUser TLVType = 0x02 // TLVFaultHandlerOverride changes the handler for one condition (clause 5.4.4). TLVFaultHandlerOverride TLVType = 0x04 // TLVFlowLabel carries a mission-defined flow label (clause 5.4.5). TLVFlowLabel TLVType = 0x05 // TLVEntityID carries an entity ID, used for fault location (clause 5.4.6). TLVEntityID TLVType = 0x06 )
type TransactionID ¶ added in v0.4.0
TransactionID identifies one transaction by the entity that started it and the sequence number that entity gave it.
It appears on its own as the Originating Transaction ID message (table 6-2) and again inside the request and response messages of the remote operations, always in the same encoding: a length nibble pair, then the two values.
func (TransactionID) Encode ¶ added in v0.4.0
func (t TransactionID) Encode() ([]byte, error)
Encode writes the length octet and the two values (table 6-2).
The two 3-bit length fields hold the width less one, so a one-octet value encodes as zero. Each is preceded by a reserved bit that the standard requires to be zero.
func (TransactionID) Humanize ¶ added in v0.4.0
func (t TransactionID) Humanize() string
Humanize returns a human-readable summary.
type TransactionState ¶
type TransactionState int
TransactionState is where a transaction has got to.
const ( // StateIdle means the transaction has not started. StateIdle TransactionState = iota // StateSendingMetadata means the Metadata PDU is next out. StateSendingMetadata // StateSendingData means file data is flowing. StateSendingData // StateSendingEOF means the EOF PDU is next out. StateSendingEOF // StateAwaitingEOFAck means the sender is waiting for the ACK of its EOF. StateAwaitingEOFAck // StateAwaitingFinished means the sender is waiting for a Finished PDU. StateAwaitingFinished // StateFinished means the transaction is complete. StateFinished // StateCancelled means the transaction was abandoned. StateCancelled )
type TransactionStatus ¶
type TransactionStatus uint8
TransactionStatus is the acknowledging entity's view of the transaction (clause 5.2.4).
const ( StatusUndefined TransactionStatus = 0 StatusActive TransactionStatus = 1 StatusTerminated TransactionStatus = 2 StatusUnrecognized TransactionStatus = 3 )
func (TransactionStatus) String ¶
func (s TransactionStatus) String() string
String names the transaction status.
type UserMessage ¶ added in v0.4.0
type UserMessage struct {
Type UserMessageType
// Content is the message body, whose shape the type decides. It is empty
// for Proxy Put Cancel, which clause 6.2.6.2 says has no content.
Content []byte
}
UserMessage is one Reserved CFDP Message: its type and its content, with the "cfdp" identifier already checked off the front.
func DecodeUserMessage ¶ added in v0.4.0
func DecodeUserMessage(data []byte) (*UserMessage, error)
DecodeUserMessage reads a Reserved CFDP Message from a Message to User TLV's value.
A Message to User that does not open with "cfdp" is an application message and not this package's business, so it comes back as ErrNotUserMessage rather than as a malformed protocol message. A receiver walks the metadata TLVs and uses that to tell the two apart.
func ProxyPutCancel ¶ added in v0.4.0
func ProxyPutCancel() UserMessage
ProxyPutCancel asks the respondent to cancel the proxied transaction.
Clause 6.2.6.2: "A Proxy Put Cancel message is mandatory. It has no content."
func UserMessagesFrom ¶ added in v0.4.0
func UserMessagesFrom(tlvs []TLV) []*UserMessage
UserMessagesFrom picks the Reserved CFDP Messages out of a run of metadata TLVs, leaving application messages alone.
func (UserMessage) Encode ¶ added in v0.4.0
func (m UserMessage) Encode() []byte
Encode serializes the message with its identifier and type octet.
func (UserMessage) EncodeTLV ¶ added in v0.4.0
func (m UserMessage) EncodeTLV() TLV
EncodeTLV wraps the message in the Message to User TLV that carries it.
type UserMessageType ¶ added in v0.4.0
type UserMessageType uint8
UserMessageType identifies a Reserved CFDP Message, per the message type tables of section 6.
const ( // Proxy operations, table 6-3. MsgProxyPutRequest UserMessageType = 0x00 MsgProxyMessageToUser UserMessageType = 0x01 MsgProxyFilestoreRequest UserMessageType = 0x02 MsgProxyFaultHandlerOverride UserMessageType = 0x03 MsgProxyTransmissionMode UserMessageType = 0x04 MsgProxyFlowLabel UserMessageType = 0x05 MsgProxySegmentationControl UserMessageType = 0x06 MsgProxyPutResponse UserMessageType = 0x07 MsgProxyFilestoreResponse UserMessageType = 0x08 MsgProxyPutCancel UserMessageType = 0x09 // MsgOriginatingTransactionID is common to all User operations (clause 6.1.5), // which is why it sits inside the proxy range rather than after it. MsgOriginatingTransactionID UserMessageType = 0x0A MsgProxyClosureRequest UserMessageType = 0x0B // Directory operations, table 6-14. MsgDirectoryListingRequest UserMessageType = 0x10 MsgDirectoryListingResponse UserMessageType = 0x11 // Remote status report operations, table 6-17. MsgRemoteStatusReportRequest UserMessageType = 0x20 MsgRemoteStatusReportResponse UserMessageType = 0x21 // Remote suspend operations, table 6-20. MsgRemoteSuspendRequest UserMessageType = 0x30 MsgRemoteSuspendResponse UserMessageType = 0x31 // Remote resume operations, table 6-23. MsgRemoteResumeRequest UserMessageType = 0x38 MsgRemoteResumeResponse UserMessageType = 0x39 )
The message types, from tables 6-3, 6-14, 6-17, 6-20 and 6-23.
The numbering is grouped by operation with gaps between groups, and one gap inside the proxy group: 0x0A is the Originating Transaction ID, which is common to every operation rather than belonging to proxy, so the proxy group runs 0x00 to 0x09 and then resumes at 0x0B.
func (UserMessageType) String ¶ added in v0.4.0
func (t UserMessageType) String() string
String names the message type.
func (UserMessageType) Valid ¶ added in v0.4.0
func (t UserMessageType) Valid() bool
Valid reports whether this is a message type section 6 defines.