CFDP PDU Subpackage

The Protocol Data Unit (PDU) subpackage contains the CFDP data units which can be used by CFDP entities to exchange file data.

In general, PDUs are divided in File Directive PDUs and File Data PDUs.

Following File Directive PDUs are available in the subpackage

All are based on the spacepackets.cfdp.pdu.file_directive module.

Following File Data PDUs are available in the subpackage

Every PDU type has a common PDU header which can be found inside the spacepackets.cfdp.pdu.header module.

The helper module spacepackets.cfdp.pdu.helper contains components like the spacepackets.cfdp.pdu.helper.PduWrapper class which stores PDUs as a generic base type and allows typed conversion in to the concrete PDU type

PDU Helper Submodule

class spacepackets.cfdp.pdu.helper.PduFactory

Bases: object

Helper class to generate PDUs and retrieve PDU information from a raw bytestream

static from_raw(data: bytes | bytearray) AbstractFileDirectiveBase | AbstractPduBase | None
static from_raw_to_holder(data: bytes | bytearray) PduHolder
static is_file_directive(data: bytes | bytearray) bool
static pdu_directive_type(data: bytes | bytearray) DirectiveType | None

Retrieve the PDU directive type from a raw bytestream.

Raises:

ValueError – Invalid directive type.

Returns:

None, if the PDU in the given bytestream is not a file directive, otherwise the directive.

static pdu_type(data: bytes | bytearray) PduType
class spacepackets.cfdp.pdu.helper.PduHolder(pdu: AbstractFileDirectiveBase | AbstractPduBase | None)

Bases: object

Helper type to store arbitrary PDU types and cast them to a concrete PDU type conveniently

property base: AbstractFileDirectiveBase | AbstractPduBase | None

Deprecated since version 0.19.0: use packet member instead

property is_file_directive: bool
pack() bytearray
property packet_len: int
property pdu_directive_type: DirectiveType | None

If the contained type is not a PDU file directive, returns None. Otherwise, returns the directive type

property pdu_type: PduType
to_ack_pdu() AckPdu
to_eof_pdu() EofPdu
to_file_data_pdu() FileDataPdu
to_finished_pdu() FinishedPdu
to_keep_alive_pdu() KeepAlivePdu
to_metadata_pdu() MetadataPdu
to_nak_pdu() NakPdu
to_prompt_pdu() PromptPdu

File Data Submodule

class spacepackets.cfdp.pdu.file_data.FileDataParams(file_data: 'bytes', offset: 'int', segment_metadata: 'SegmentMetadata | None' = None)

Bases: object

classmethod empty() FileDataParams
file_data: bytes
offset: int
segment_metadata: SegmentMetadata | None = None
class spacepackets.cfdp.pdu.file_data.FileDataPdu(pdu_conf: PduConfig, params: FileDataParams)

Bases: AbstractPduBase

property crc_flag: CrcFlag
property dest_entity_id: UnsignedByteField
property direction: Direction
property file_data: bytes
property file_flag: LargeFileFlag
get_max_file_seg_len_for_max_packet_len(max_packet_len: int) int

This simply calls get_max_file_seg_len_for_max_packet_len_and_pdu_cfg() with the correct arguments derived from the internal fields.

property has_segment_metadata: bool
property header_len: int
property offset: int
pack() bytearray
property packet_len: int
property pdu_data_field_len: int
property pdu_header: PduHeader
property pdu_type: PduType
property record_cont_state: RecordContinuationState | None
property segment_metadata: SegmentMetadata | None
property source_entity_id: UnsignedByteField
property transaction_seq_num: UnsignedByteField
property transmission_mode: TransmissionMode
classmethod unpack(data: bytes | bytearray) FileDataPdu

Generate an object instance from raw data. Care should be taken to check whether the raw bytestream really contains a File Data PDU.

Raises:
  • BytesTooShortError – Raw data too short for expected object.

  • ValueError – Invalid PDU type or data format.

  • InvalidCrc – PDU has a 16 bit CRC and the CRC check failed.

class spacepackets.cfdp.pdu.file_data.RecordContinuationState(value)

Bases: IntEnum

An enumeration.

END_WITHOUT_START = 2
NO_START_NO_END = 0
START_AND_END = 3
START_WITHOUT_END = 1
class spacepackets.cfdp.pdu.file_data.SegmentMetadata(record_cont_state: 'RecordContinuationState', metadata: 'bytes')

Bases: object

metadata: bytes
record_cont_state: RecordContinuationState
spacepackets.cfdp.pdu.file_data.get_max_file_seg_len_for_max_packet_len_and_pdu_cfg(pdu_conf: PduConfig, max_packet_len: int, segment_metadata: SegmentMetadata | None = None) int

This function can be used to calculate the maximum allowed file segment size for a given maximum packet length and the segment metadata if there is any.

File Directive Submodules

ACK PDU Submodule

class spacepackets.cfdp.pdu.ack.AckPdu(pdu_conf: PduConfig, directive_code_of_acked_pdu: DirectiveType, condition_code_of_acked_pdu: ConditionCode, transaction_status: TransactionStatus)

Bases: AbstractFileDirectiveBase

Encapsulates the ACK file directive PDU, see CCSDS 727.0-B-5 p.81

Construct a ACK PDU object

Parameters:
  • directive_code_of_acked_pdu

  • condition_code_of_acked_pdu

  • transaction_status

  • pdu_conf – PDU configuration parameters

Raises:

ValueError – Directive code invalid. Only EOF and Finished PDUs can be acknowledged

property directive_type: DirectiveType
pack() bytearray
property pdu_header: PduHeader
classmethod unpack(data: bytes | bytearray) AckPdu

Generate an object instance from raw data. Care should be taken to check whether the raw bytestream really contains an ACK PDU.

Raises:
class spacepackets.cfdp.pdu.ack.TransactionStatus(value)

Bases: IntEnum

For more detailed information: CCSDS 727.0-B-5 p.81

ACTIVE = 1
TERMINATED = 2
UNDEFINED = 0
UNRECOGNIZED = 3

NAK PDU Submodule

class spacepackets.cfdp.pdu.nak.NakPdu(pdu_conf: PduConfig, start_of_scope: int, end_of_scope: int, segment_requests: list[tuple[int, int]] | None = None)

Bases: AbstractFileDirectiveBase

Encapsulates the NAK file directive PDU, see CCSDS 727.0-B-5 p.84.

Please note that there is a distinction between a NAK PDU, and a NAK sequence which might consist of multiple NAK PDUs. Generally, each NAK sequence will only consist of one NAK PDU, but might consist of multiple ones if one NAK PDU is not sufficient to send all missing segment requests while staying below a maximum allowed packet size for one PDU.

The start of scope of a NAK sequence (not individual PDU!) can be one of the following:

  • 0 if this is the first NAK sequence.

  • 0 if the event which causes an issuance of the NAK PDU is the NAK timer expiry.

  • The end-of-scope of the previous NAK sequence for this file transaction.

The end of scope of a NAK sequence (not individual PDU!) can be one of the following:

  • The whole file size if an EOF (No Error) PDU was already received.

  • The current reception progress at the time of the event that causes issuance of a NAK sequence.

The start of scope for an individual NAK PDU is the start of scope of the NAK sequence for the first NAK PDU inside the sequence. For every other NAK PDU in the sequence, it is the end-of-scope of the previous NAK PDU.

The end of scope for an individual NAK PDU is the end of scope of the NAK sequence for the last NAK PDU inside the sequence. For every other NAK PDU in the sequence, it is the end offset of the NAK PDU’s last segment request.

Examples

Re-request metadata NAK PDU:

>>> nak_pdu = NakPdu(PduConfig.default(), 0, 0, [(0, 0)])
>>> nak_pdu.start_of_scope
0
>>> nak_pdu.end_of_scope
0
>>> nak_pdu.segment_requests
[(0, 0)]

Re-request two file segments NAK PDU:

>>> nak_pdu = NakPdu(PduConfig.default(), 0, 640, [(0, 128), (512, 640)])
>>> nak_pdu.start_of_scope
0
>>> nak_pdu.end_of_scope
640
>>> nak_pdu.segment_requests
[(0, 128), (512, 640)]

Create a NAK PDU object instance.

Parameters:
  • pdu_conf – Common PDU configuration.

  • start_of_scope – The value of this parameter depends on the start of the scope of the whole NAK sequence and on the position of this PDU inside the NAK sequence. See the class documentation for more details.

  • end_of_scope – The value of this parameter depends on the end of the scope of the whole NAK sequence and on the position of this PDU inside the NAK sequence. See the class documentation for more details.

  • segment_requests – A list of segment request pair tuples, where the first entry of list element is the start offset and the second entry is the end offset. If the start and end offset are both 0, the metadata is re-requested.

property directive_type: DirectiveType
property file_flag: LargeFileFlag
get_max_seg_reqs_for_max_packet_size(max_packet_size: int) int

Member method which forwards to get_max_seg_reqs_for_max_packet_size_and_pdu_cfg(), passing the internal PDU configuration field.

pack() bytearray

Pack the NAK PDU.

Raises:

ValueError – File sizes too large for non-large files

property pdu_header: PduHeader
property segment_requests: list[tuple[int, int]]

An optional list of segment request pair tuples, where the first entry of list element is the start offset and the second entry is the end offset. If the start and end offset are both 0, the metadata is re-requested.

classmethod unpack(data: bytes | bytearray) NakPdu

Generate an object instance from raw data. The user should take care to check whether the raw bytestream really contains a NAK PDU.

Raises:
spacepackets.cfdp.pdu.nak.get_max_seg_reqs_for_max_packet_size_and_pdu_cfg(max_packet_size: int, pdu_conf: PduConfig) int

This function can be used to retrieve the maximum amount of segment request given a PDU configuration to stay below a certain maximum packet size. This is useful to calculate how many NAK PDUs are required inside a NAK sequence.

Raises:

ValueError – Invalid large file flag derived from the PDU configuration, or maximum packet size is not even large enough to hold the base packet without any segment requests.

EOF PDU Submodule

class spacepackets.cfdp.pdu.eof.EofPdu(pdu_conf: PduConfig, file_checksum: bytes | bytearray | int, file_size: int, fault_location: EntityIdTlv | None = None, condition_code: ConditionCode = ConditionCode.NO_ERROR)

Bases: AbstractFileDirectiveBase

Encapsulates the EOF file directive PDU, see CCSDS 727.0-B-5 p.79

Constructor for an EOF PDU.

Parameters:
  • pdu_conf – PDU Configuration.

  • file_checksum – 4 byte checksum.

  • file_size – File Size

  • fault_location – Optional fault location TLV.

  • condition_code – Optional Condition Code

Raises:

ValueError – Invalid input, file checksum not 4 bytes long.

property directive_type: DirectiveType
property fault_location: EntityIdTlv | None
pack() bytearray
property packet_len: int

Get length of the packet when packing it :return:

property pdu_header: PduHeader
classmethod unpack(data: bytes | bytearray) EofPdu

Generate an object instance from raw data. Care should be taken to check whether the raw bytestream really contains an EOF PDU.

Raises:

Metadata PDU Submodule

class spacepackets.cfdp.pdu.metadata.MetadataParams(closure_requested: 'bool', checksum_type: 'ChecksumType', file_size: 'int', source_file_name: 'str | None', dest_file_name: 'str | None')

Bases: object

checksum_type: ChecksumType
closure_requested: bool
dest_file_name: str | None
file_size: int
source_file_name: str | None
class spacepackets.cfdp.pdu.metadata.MetadataPdu(pdu_conf: PduConfig, params: MetadataParams, options: list[AbstractTlvBase] | None = None)

Bases: AbstractFileDirectiveBase

Encapsulates the Metadata file directive PDU, see CCSDS 727.0-B-5 p.83

>>> metadata_params = MetadataParams(
...     closure_requested=True,
...     checksum_type=ChecksumType.CRC_32,
...     file_size=0,
...     source_file_name="/tmp/test_source_file.txt",
...     dest_file_name="/tmp/test_dest_file.txt"
... )
>>> metadata_pdu = MetadataPdu(PduConfig.default(), metadata_params)
>>> metadata_pdu.closure_requested
True
>>> metadata_pdu.checksum_type
<ChecksumType.CRC_32: 3>
>>> metadata_pdu.source_file_name
'/tmp/test_source_file.txt'
>>> metadata_pdu.dest_file_name
'/tmp/test_dest_file.txt'
property checksum_type: ChecksumType
property closure_requested: bool
property dest_file_name: str | None

If there is no associated source file, for example for messages used for Proxy Operations, this function will return None

property directive_param_field_len: int
property directive_type: DirectiveType
property file_size: int

A value of 0 means this is an unbounded file, as opposed to no file. To check whether a Metadata PDU has no associated file, check source_file_name() against None

property options: list[AbstractTlvBase] | None
options_as_tlv() list[CfdpTlv] | None

Returns options() converted to a list of concrete CfdpTlv objects.

pack() bytearray
property pdu_header: PduHeader
property source_file_name: str | None

If there is no associated source file, for example for messages used for Proxy Operations, this function will return None

classmethod unpack(data: bytes | bytearray) MetadataPdu

Generate an object instance from raw data. Care should be taken to check whether the raw bytestream really contains a Metadata PDU.

Raises:

Finished PDU Submodule

class spacepackets.cfdp.pdu.finished.FinishedParams(condition_code: 'ConditionCode', delivery_code: 'DeliveryCode', file_status: 'FileStatus', file_store_responses: 'list[FileStoreResponseTlv]' = <factory>, fault_location: 'EntityIdTlv | None' = None)

Bases: object

condition_code: ConditionCode
delivery_code: DeliveryCode
classmethod empty() FinishedParams
fault_location: EntityIdTlv | None = None
file_status: FileStatus
file_store_responses: list[FileStoreResponseTlv]
classmethod success_params() FinishedParams

Generate the finished parameters to generate a full success FinishedPdu PDU.

class spacepackets.cfdp.pdu.finished.FinishedPdu(pdu_conf: PduConfig, params: FinishedParams)

Bases: AbstractFileDirectiveBase

Encapsulates the Finished file directive PDU, see CCSDS 727.0-B-5 p.80.

>>> finished_pdu = FinishedPdu.success_pdu(PduConfig.default())
>>> finished_pdu.condition_code
<ConditionCode.NO_ERROR: 0>
>>> finished_pdu.delivery_code
<DeliveryCode.DATA_COMPLETE: 0>
>>> finished_pdu.file_status
<FileStatus.FILE_RETAINED: 2>
property condition_code: ConditionCode
property delivery_code: DeliveryCode
property directive_type: DirectiveType
property fault_location: EntityIdTlv | None
property fault_location_len: int
property file_status: FileStatus
property file_store_responses: list[FileStoreResponseTlv]
property file_store_responses_len: int
property finished_params: FinishedParams
property might_have_fault_location: bool
pack() bytearray
property packet_len: int

Get length of the packet when packing it :return:

property pdu_header: PduHeader
classmethod success_pdu(pdu_conf: PduConfig) FinishedPdu
classmethod unpack(data: bytes | bytearray) FinishedPdu

Generate an object instance from raw data. Care should be taken to check whether the raw bytestream really contains a Finished PDU.

Raises:

Keep Alive PDU Submodule

class spacepackets.cfdp.pdu.keep_alive.KeepAlivePdu(pdu_conf: PduConfig, progress: int)

Bases: AbstractFileDirectiveBase

Encapsulates the Keep Alive file directive PDU, see CCSDS 727.0-B-5 p.85

property directive_type: DirectiveType
property file_flag: LargeFileFlag
pack() bytearray
property packet_len: int

Get length of the packet when packing it :return:

property pdu_header: PduHeader
classmethod unpack(data: bytes | bytearray) KeepAlivePdu

Generate an object instance from raw data. Care should be taken to check whether the raw bytestream really contains a Keep Alive PDU.

Raises:

Prompt PDU Module

class spacepackets.cfdp.pdu.prompt.PromptPdu(pdu_conf: PduConfig, response_required: ResponseRequired)

Bases: AbstractFileDirectiveBase

Encapsulates the Prompt file directive PDU, see CCSDS 727.0-B-5 p.84

property directive_type: DirectiveType
pack() bytearray
property pdu_header: PduHeader
classmethod unpack(data: bytes | bytearray) PromptPdu

Generate an object instance from raw data. Care should be taken to check whether the raw bytestream really contains a Prompt PDU.

Raises:
  • BytesTooShortError: – Raw data too short for expected object.

  • ValueError: – Invalid directive type or data format.

  • InvalidCrcError: – PDU has a 16 bit CRC and the CRC check failed.

class spacepackets.cfdp.pdu.prompt.ResponseRequired(value)

Bases: IntEnum

An enumeration.

KEEP_ALIVE = 1
NAK = 0

PDU Header Submodule

class spacepackets.cfdp.pdu.header.AbstractPduBase

Bases: ABC

Encapsulate common functions for PDU. PDU or Packet Data Units are the base data unit which are exchanged for CFDP procedures. Each PDU has a common header and this class provides abstract methods to access fields of that common header. For more, information, refer to CCSDS 727.0-B-5 p.75. The default implementation provided in this library for this abstract class is the PduHeader class.

FIXED_LENGTH = 4
VERSION_BITS = 32
abstract property crc_flag: CrcFlag
abstract property dest_entity_id: UnsignedByteField
abstract property direction: Direction
abstract property file_flag: LargeFileFlag
abstract property header_len: int
static header_len_from_raw(data: bytes | bytearray) int
property large_file_flag_set: bool
abstract pack() bytearray
property packet_len: int
abstract property pdu_data_field_len: int
abstract property pdu_header: PduHeader
abstract property pdu_type: PduType
abstract property source_entity_id: UnsignedByteField
abstract property transaction_seq_num: UnsignedByteField
abstract property transmission_mode: TransmissionMode
class spacepackets.cfdp.pdu.header.PduHeader(pdu_type: PduType, segment_metadata_flag: SegmentMetadataFlag, pdu_data_field_len: int, pdu_conf: PduConfig)

Bases: AbstractPduBase

Concrete implementation of the abstract AbstractPduBase class

Constructor for PDU header

Parameters:
  • pdu_type

  • segment_metadata_flag

  • pdu_data_field_len

  • pdu_conf

Raises:

ValueError – If some field are invalid or default values were unset

static check_len_in_bytes(detected_len: int) LenInBytes
property crc_flag: CrcFlag
property dest_entity_id: UnsignedByteField
property direction: Direction
property file_flag: LargeFileFlag
property header_len: int

Get length of PDU header when packing it

pack() bytearray
property pdu_data_field_len: int
property pdu_header: PduHeader
property pdu_type: PduType
property seg_ctrl: SegmentationControl
set_entity_ids(source_entity_id: UnsignedByteField, dest_entity_id: UnsignedByteField) None

Both IDs must be set at once because they must have the same length as well :param source_entity_id: :param dest_entity_id: :return:

property source_entity_id: UnsignedByteField
property transaction_seq_num: UnsignedByteField
property transmission_mode: TransmissionMode
classmethod unpack(data: bytes | bytearray) PduHeader

Unpack a raw bytearray into the PDU header object representation.

Parameters:

data

Raises:
  • BytesTooShortError – Passed bytearray is too short.

  • UnsupportedCfdpVersion – CFDP version not supported. Only version 2 related to CFDP version CCSDS 727.0-B-5 is supported.

Returns:

Unpacked object representation of a PDU header

verify_length_and_checksum(data: bytes | bytearray) int

spacepackets.cfdp.pdu.file_directive module

class spacepackets.cfdp.pdu.file_directive.AbstractFileDirectiveBase

Bases: AbstractPduBase

Encapsulate common functions for classes which are PDU file directives

property crc_flag: CrcFlag
property dest_entity_id: UnsignedByteField
property direction: Direction
abstract property directive_type: DirectiveType
property file_flag: LargeFileFlag
property header_len: int

Returns the length of the PDU header plus the directive code octet length

property packet_len: int

Get length of the packet when packing it :return:

property pdu_data_field_len: int
property pdu_type: PduType
property source_entity_id: UnsignedByteField
property transaction_seq_num: UnsignedByteField
property transmission_mode: TransmissionMode
class spacepackets.cfdp.pdu.file_directive.DirectiveType(value)

Bases: IntEnum

An enumeration.

ACK_PDU = 6
EOF_PDU = 4
FINISHED_PDU = 5
KEEP_ALIVE_PDU = 12
METADATA_PDU = 7
NAK_PDU = 8
NONE = 10
PROMPT_PDU = 9
class spacepackets.cfdp.pdu.file_directive.FileDirectivePduBase(pdu_conf: PduConfig, directive_code: DirectiveType, directive_param_field_len: int)

Bases: AbstractFileDirectiveBase

Base class for file directive PDUs encapsulating all its common components. All other file directive PDU classes implement this class

Generic constructor for a file directive PDU. Most arguments are passed on the to build the generic PDU header.

Parameters:
  • directive_code

  • directive_param_field_len – Length of the directive parameter field. The length of the PDU data field will be this length plus the one octet / byte of the directive code

  • pdu_conf – Generic PDU transfer configuration

FILE_DIRECTIVE_PDU_LEN = 5
property directive_param_field_len: int
property directive_type: DirectiveType
pack() bytearray
parse_fss_field(raw_packet: bytes | bytearray, current_idx: int) tuple[int, int]

Parse the FSS field, which has different size depending on the large file flag being set or not. Returns the current index incremented and the parsed file size.

Raises:

ValueError – Packet not large enough

property pdu_conf: PduConfig
property pdu_header: PduHeader
classmethod unpack(raw_packet: bytes | bytearray) FileDirectivePduBase

Unpack a raw bytearray into the File Directive PDU object representation.

Parameters:

raw_packet – Unpack PDU file directive base

Raises:

BytesTooShortError – Passed bytearray is too short

Returns:

verify_length_and_checksum(data: bytes | bytearray) None