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 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 PDU
- type PDUHeader
- type PromptPDU
- type PromptResponse
- 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 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 TLV
- type TLVType
- type TransactionState
- type TransactionStatus
Constants ¶
const ( // ChecksumModular is the legacy modular checksum. §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. §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 §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 (§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 (§5.3, table 5-14).
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 §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 §5.4.4. ErrInvalidFaultHandler = errors.New("invalid fault handler code") )
Sentinel errors returned by the CFDP protocol machinery.
Functions ¶
func DecodeFaultHandlerOverride ¶
func DecodeFaultHandlerOverride(t TLV) (ConditionCode, FaultHandler, error)
DecodeFaultHandlerOverride reads a fault handler override TLV (§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 (§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 (§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 (§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 )
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 (§5.2.2). DirectiveEOF DirectiveCode = 0x04 // DirectiveFinished reports delivery at the receiver (§5.2.3). DirectiveFinished DirectiveCode = 0x05 // DirectiveACK acknowledges an EOF or Finished PDU (§5.2.4). DirectiveACK DirectiveCode = 0x06 // DirectiveMetadata opens a transaction (§5.2.5). DirectiveMetadata DirectiveCode = 0x07 // DirectiveNAK names the file segments still missing (§5.2.6). DirectiveNAK DirectiveCode = 0x08 // DirectivePrompt asks the far end for a NAK or Keep Alive (§5.2.7). DirectivePrompt DirectiveCode = 0x09 // DirectiveKeepAlive reports the receiver's progress (§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 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 (§5.1.4).
Width carries semantic weight on the wire but none in comparisons: §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 §4.8. Table 4-1 assigns every fault condition a default handler; a fault handler override TLV (§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 (§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 (§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 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 §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 §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 (§4.1).
CRCFlag bool
// LargeFile widens every File-Size Sensitive field from 32 to 64 bits
// (§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 (§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 (§5.2.7).
const ( // PromptNAK asks for a NAK PDU. PromptNAK PromptResponse = 0 // PromptKeepAlive asks for a Keep Alive PDU. PromptKeepAlive PromptResponse = 1 )
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 (§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 (§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 (§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 (§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 §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 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 (§5.2.5).
func (*Sender) AckFinished ¶
AckFinished builds the ACK a Class 2 sender owes for a Finished PDU (§5.2.4). Returns ok == false when no Finished PDU has arrived.
func (*Sender) Cancel ¶
func (s *Sender) Cancel()
Cancel cancels the transaction (§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 §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; §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 (§4.8).
FaultHandlers map[ConditionCode]FaultHandler
// FaultHandlerOverrides travel as TLVs in the Metadata PDU (§5.4.4) and
// change the receiver's disposition for the named conditions.
FaultHandlerOverrides map[ConditionCode]FaultHandler
}
SenderConfig describes one outgoing transaction.
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 (§5.4.6).
func FaultHandlerOverrideTLV ¶
func FaultHandlerOverrideTLV(cond ConditionCode, handler FaultHandler) (TLV, error)
FaultHandlerOverrideTLV builds the fault handler override TLV of §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 §5.4.
const ( // TLVFilestoreRequest carries a filestore action to perform (§5.4.1). TLVFilestoreRequest TLVType = 0x00 // TLVFilestoreResponse reports the outcome of one request (§5.4.2). TLVFilestoreResponse TLVType = 0x01 // TLVMessageToUser carries an opaque application message (§5.4.3). TLVMessageToUser TLVType = 0x02 // TLVFaultHandlerOverride changes the handler for one condition (§5.4.4). TLVFaultHandlerOverride TLVType = 0x04 // TLVFlowLabel carries a mission-defined flow label (§5.4.5). TLVFlowLabel TLVType = 0x05 // TLVEntityID carries an entity ID, used for fault location (§5.4.6). TLVEntityID TLVType = 0x06 )
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 (§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.