TPDU Types#

icspacket.proto.cotp.structs.checksum(tpdu_data: Iterable[int], checksum_off: int)[source]#

Compute the checksum for a TPDU according to Annex D.3 of X.224.

Two running accumulators, C0 and C1, are folded over every octet of tpdu_data in order (each octet updates C0, and the updated C0 is then folded into C1). Their final values are combined with the total octet count L and the checksum’s offset n to derive the pair of result octets:

  • X = (-C1 + (L - n) * C0) mod 256

  • Y = (C1 - (L - n + 1) * C0) mod 256

Parameters:
  • tpdu_data (Iterable[int]) – Sequence of TPDU octets.

  • checksum_off (int) – Offset where the two checksum octets reside.

Returns:

Two-byte checksum value (X, Y).

Return type:

bytes

icspacket.proto.cotp.structs.verify_checksum(tpdu_data: bytes, checksum_off: int) bool[source]#

Verify the checksum of a TPDU.

The function temporarily zeroes out the checksum field and recomputes it using checksum(). If the recomputed checksum matches the original octets at the checksum offset, the TPDU is considered valid.

Parameters:
  • tpdu_data (bytes) – The TPDU octets containing a checksum field.

  • checksum_off (int) – Offset to the start of the checksum field.

Returns:

True if checksum matches, False otherwise.

Return type:

bool

class icspacket.proto.cotp.structs.TPDU_Code(*values)[source]#

Per-type identifier occupying the upper nibble of a TPDU’s code octet; selects which TPDU subclass and fixed header layout a decoder should use for the remaining bytes.

ED = 1#
EA = 2#
RJ = 5#
AK = 6#
ER = 7#
DR = 8#
DC = 12#
CC = 13#
CR = 14#
DT = 15#
class icspacket.proto.cotp.structs.TPDU_Class(*values)[source]#

Transport protocol classes (clause 7 of X.224), assigned to the class_id of a TPDU_ClassOption to pick which connection, flow-control, and recovery features a transport connection uses.

CLASS0 = 0#

Class 0 - simple class.

Covers connection establishment (with negotiation), segmented data transfer, and reporting of protocol errors.

CLASS1 = 1#

Class 1 - basic error recovery class.

Provides flow control tied to the underlying network connection’s own flow control, together with error recovery, expedited data transfer, an explicit disconnect procedure, and the ability to run consecutive transport connections over a single network connection.

CLASS2 = 2#

Class 2 - multiplexing class.

Supports transport connections with flow control being optional (used or not, per connection); it offers neither error detection nor error recovery.

CLASS3 = 3#

Class 3 - error recovery and multiplexing class.

Everything class 2 offers, but always with explicit flow control, plus recovery from a failure reported by the Network Layer that is handled internally, without involving the TS-user.

CLASS4 = 4#

Class 4 - error detection and recovery class.

Everything class 3 offers, plus detection and recovery from lost, duplicated, or out-of-sequence TPDUs, again handled internally without involving the TS-user.

class icspacket.proto.cotp.structs.TPDU_DisconnectReason(*values)[source]#

Reason codes carried by a DR-TPDU to explain why the transport connection is being released.

NORMAL = 128#

The session entity requested this disconnect under normal conditions.

REMOTE_CONGEST = 129#

The remote transport entity was congested at the time the connection was requested.

NEGO_FAILED = 130#

Class negotiation failed, i.e. none of the proposed protocol class(es) could be supported.

DUPLICATE_SOURCE = 131#

This source reference was already in use for the same pair of NSAPs.

MISMATCHED_REFERENCES = 132#

The connection’s reference values did not match.

PROTOCOL_ERROR = 133#

A protocol error was detected.

REF_OVERFLOW = 135#

The connection reference has overflowed.

CONN_REFUSED = 136#

The connection request was refused over this network connection.

INVALID_LENGTH = 138#

The header length, or a parameter’s length, was invalid.

UNSPECIFIED = 0#

No specific reason was given.

TSAP_CONGESTION = 1#

The destination TSAP was congested.

ENTITIY_NOT_ATTACHED = 2#

No session entity is attached to that TSAP.

UNKNOWN_ADDRESS = 3#

The destination address was not recognized.

class icspacket.proto.cotp.structs.TPDU_Size(*values)[source]#

Maximum TPDU size (header included, in octets) proposed for use over the requested transport connection. Each value is the base-2 logarithm of the octet count it represents, as carried in the TPDU-SIZE parameter.

SIZE_8192 = 13#
SIZE_4096 = 12#
SIZE_2048 = 11#
SIZE_1024 = 10#
SIZE_512 = 9#
SIZE_256 = 8#
SIZE_128 = 7#
class icspacket.proto.cotp.structs.TPDU_RejectCause(*values)[source]#

Why a connection request was rejected.

UNSPECIFIED = 0#

No cause was given.

INVALID_PARAMETER_CODE = 1#

A parameter code was not recognized.

INVALID_PDU_TYPE = 2#

The PDU type was not recognized.

INVALID_PARAMETER_VALUE = 3#

A parameter carried a value that is not valid.

class icspacket.proto.cotp.structs.TPDU_AdditionalOptions(unused: bool = False, non_blocking: bool = False, use_request_ack: bool = False, use_selective_ack: bool = False, speed_up: bool = False, use_receipt_info: bool = False, use_checksum_16bit: bool = False, use_transport_speed_up: bool = True)[source]#

Bit flags for the ADDITIONAL OPTION SELECTION parameter; irrelevant whenever class 0 is the preferred class.

unused: bool = False#
non_blocking: bool = False#

When set, class 4 uses non-blocking expedited data.

use_request_ack: bool = False#

When set, classes 1, 3 and 4 use the request-acknowledgement option.

use_selective_ack: bool = False#

When set, class 4 uses selective acknowledgement.

speed_up: bool = False#

When set, class 1 makes use of the network service’s expedited delivery.

use_receipt_info: bool = False#

Chooses, for class 1, between receipt confirmation (True) and the explicit AK variant (False).

use_checksum_16bit: bool = False#

When set, class 4 uses the 16-bit checksum defined in clause 6.17.

use_transport_speed_up: bool = True#

When set, the transport-expedited data transfer service is used.

class icspacket.proto.cotp.structs.TPDU_TransitDelay(calling_target_value: int = 0, calling_maximum_acceptable: int = 0, called_target_value: int = 0, called_maximum_acceptable: int = 0)[source]#

TRANSIT DELAY parameter values, one target/maximum pair per direction; unused whenever class 0 is the preferred class.

calling_target_value: int = 0#

Target transit delay from the calling to the called user.

calling_maximum_acceptable: int = 0#

Largest transit delay still acceptable from the calling to the called user.

called_target_value: int = 0#

Target transit delay from the called to the calling user.

called_maximum_acceptable: int = 0#

Largest transit delay still acceptable from the called to the calling user.

class icspacket.proto.cotp.structs.TPDU_ResidualErrorRate(target_value: int = 0, minimum_acceptable: int = 0, tsdu_size_of_interest: int = 0)[source]#

RESIDUAL ERROR RATE parameter values; unused whenever class 0 is the preferred class.

target_value: int = 0#

Target residual error rate, expressed as a power of 10.

minimum_acceptable: int = 0#

Smallest residual error rate still acceptable, expressed as a power of 10.

tsdu_size_of_interest: int = 0#

TSDU size this error rate applies to, expressed as a power of 2.

class icspacket.proto.cotp.structs.Parameter_Code(*values)[source]#

Defines different parameter types used accross TPDUs

CALLING_T_SELECTOR = 193#
CALLED_T_SELECTOR = 194#
TPDU_SIZE = 192#
MAX_TPDU_SIZE = 240#
VERSION = 196#
PROTECTION = 197#
CHECKSUM = 195#
ADDITIONAL_OPTS = 198#
ALTERNATIVE_CLASSES = 199#
ACK_TIME = 133#
THROUGHPUT = 137#
ERROR_RATE = 134#
PRIORITY = 135#
TRANSIT_DELAY = 136#
REASSIGNMENT_TIME = 139#
INACTIVITY = 242#
ADDTITIONAL_INFO = 224#
SUBSEQUENCE_NUM = 138#
FLOW_CONTROL_INFO = 140#
ACK_PARAMS = 143#
class icspacket.proto.cotp.structs.Parameter(type_id: Parameter_Code = 0, value: Any = b'')[source]#

A single TLV-encoded entry from a TPDU’s variable part (X.224, §13.2.3).

Each TPDU subclass that defines a parameters field stores a list of these; the variable part only exists at all when at least one such parameter needs to be carried.

type_id: Parameter_Code = 0#

The parameter code

value: Any = b''#

Parameter payload, length-prefixed by a single length octet.

The concrete type stored here is looked up from TPDU_PARAM_TYPES based on type_id, so this field decodes to whatever representation is appropriate for that parameter code.

class icspacket.proto.cotp.structs.TPDU(li: int = 0, code: int = 0)[source]#

Transport Protocol Data Units (TPDUs)

li: int = 0#

Header length indicator, in octets.

Counts the fixed and variable parts of the header - i.e. everything after this field up to (but not including) the user data - which is the same quantity build() derives from fixed_size plus the packed variable part’s length. The value 255 (1111 1111) is set aside by the standard for a future length-indicator extension.

code: int = 0#

Raw TPDU code octet, combining tpdu_code (upper nibble) and code_arg (lower nibble); together they identify which kind of TPDU this is and how the rest of the header is laid out.

property tpdu_code: TPDU_Code#

Qualified TPDU code

property code_arg: int#

Argument bits of the TPDU code

has_parameters() bool[source]#

Whether the TPDU has parameters

get_parameters() list[Parameter][source]#

Returns the parameters of the TPDU if present

has_checksum() bool[source]#

Checks whether the TPDU has a checksum parameter

property fixed_size: int#

Returns the number of octets that make up the fixed (header) part of this TPDU, excluding the variable part and user data.

This value is normally defined per TPDU type in X.224 and stored as the class attribute TPDU_FIXED_SIZE. If the subclass does not define it, a default of 1 octet is returned.

The fixed size is used when computing the length indicator (LI), and also when locating parameter offsets, such as the position of the checksum parameter.

property first_checksum_octet: int#

Returns the zero-based index (offset) of the first checksum octet within the serialized TPDU, or -1 if no parameters are present.

For ease of computation, the checksum parameter MUST appear in the first position of the variable part when present. This means:

  • Offset starts at fixed_size (end of fixed header)

  • Add 1 byte for the Length Indicator (LI)

  • Add 2 bytes for the TLV header (parameter code and length)

get_checksum() bytes[source]#

Returns the current 2-byte checksum value from the variable part, if a checksum parameter is present. If no checksum parameter is found, returns an empty byte string.

The checksum parameter is identified by its type code Parameter_Code.CHECKSUM and should be the first parameter.

set_checksum(value: bytes)[source]#

Sets the checksum parameter value in the TPDU.

If a checksum parameter already exists, its value is replaced. If it does not exist, it is inserted into the first position of the parameter list. This ensures the checksum field is correctly located for both building and verification.

is_valid() bool[source]#

Verifies the TPDU checksum if present.

  • If no checksum parameter is found, returns True (valid by default).

  • If present, recomputes the checksum over the TPDU using the Annex D.3 algorithm, comparing the calculated value to the stored one.

This method does not rebuild the TPDU using build() to avoid unintentional mutations; it uses the raw packed representation for verification.

build(add_checksum: bool = False) bytes[source]#

Serializes the TPDU into its octet representation.

This method constructs a valid TPDU by encoding its fixed and variable parts, and optionally adds a checksum parameter.

Behavior depends on add_checksum:

  • False (default): The TPDU is serialized normally without any checksum.

  • True:
    1. A placeholder checksum parameter (two zero bytes) is inserted.

    2. The TPDU is packed into octets.

    3. The checksum is recomputed across the entire TPDU (with zeros in the checksum field).

    4. The placeholder checksum is replaced with the computed value and the TPDU is repacked.

Example:

>>> pdu = TPDU_ConnectionRequest()
>>> pdu.build(add_checksum=True)
b'\n\xe0\x00\x00\x00\x00\x00\xc3\x02|\xd5'
>>> parsed = TPDU_ConnectionRequest.from_octets(_)
TPDU_ConnectionRequest(li=10, code=224,...parameters=[Parameter(type_id=<Parameter_Code.CHECKSUM: int1_t95>, value=b'|\xd5')])
Parameters:

add_checksum – Whether to generate and insert a checksum parameter during the build process.

Returns:

Byte string representing the complete TPDU.

classmethod from_octets(octets: bytes)[source]#

Deserialize raw octets into a TPDU (or subclass) instance.

This method unpacks the raw TPDU structure into the corresponding class representation.

Parameters:

octets (bytes) – Encoded TPDU octets.

Returns:

TPDU instance populated from octets.

Return type:

TPDU

class icspacket.proto.cotp.structs.TPDU_ClassOption(class_id: TPDU_Class = TPDU_Class.CLASS0, reserved: int = 0, extended_formats: bool = False, explicit_flow_control: bool = False)[source]#

CLASS OPTION octet, as carried by CR/CC-TPDUs.

Packs the preferred/selected transport protocol class (class_id) for this connection alongside the extended_formats and explicit_flow_control switches, with two reserved bits in between.

class_id: TPDU_Class = 0#
reserved: int = 0#
extended_formats: bool = False#
explicit_flow_control: bool = False#
icspacket.proto.cotp.structs.TPDU_VariablePart = Field('_', arch='x86_64', order='Little Endian', seq=True, struct=Struct(fields=['type_id', 'value']), cond=False, options=False)#

Packing helper for a TPDU’s variable part (X.224, §13.2.3): an open-ended sequence of zero or more Parameter entries, back to back until the bytes run out.

icspacket.proto.cotp.structs.TPDU_UserData = <Bytes>#

Packing helper for a TPDU’s user-data field (X.224, §13.2.4): the remaining bytes are copied through as-is, with no further structure imposed.

class icspacket.proto.cotp.structs.TPDU_ConnectionRequest(li: int = 0, code: int = 0, dst_ref: int = 0, src_ref: int = 0, class_opt: TPDU_ClassOption = None, parameters: list[Parameter] = None, user_data: bytes = None)[source]#

Connection Request (CR) TPDU (X.224, §13.3), sent to open a new transport connection and propose the parameters it should use.

TPDU_FIXED_SIZE = 6#
dst_ref: int = 0#

Destination reference - always zero on a CR-TPDU.

src_ref: int = 0#

Source reference chosen by this (initiating) transport entity to identify the connection being requested.

class_opt: TPDU_ClassOption = None#

First-choice class option for this connection (bits 8-5 of octet 7). Any further class choices the initiator wants to offer as alternatives go into the variable part instead.

parameters: list[Parameter] = None#

Optional parameters that may accompany a CR-TPDU (X.224, §13.3.4).

Transport-Selector, TPDU size, and preferred maximum TPDU size may be present regardless of class. Version number, protection parameters, and alternative protocol class(es) only matter once a class other than 0 is proposed - alternative classes are additionally never used when running over CLNS. Throughput, residual error rate, priority, and transit delay are likewise skipped whenever class 0 is preferred. Checksum and acknowledgement time only make sense when class 4 is the preferred class. Reassignment time is omitted when class 0 or 2 is preferred, but remains available when class 4 is preferred with class 3 offered as an alternate. The inactivity timer applies once class 4 is either preferred or selected.

user_data: bytes = None#

User data accompanying the request; class 0 must leave this empty, while every other class may optionally include some.

class icspacket.proto.cotp.structs.TPDU_ConnectionConfirm(li: int = 0, code: int = 0, dst_ref: int = 0, src_ref: int = 0, class_opt: TPDU_ClassOption = None, parameters: list[Parameter] = None, user_data: bytes = b'')[source]#

Connection Confirm (CC) TPDU (X.224, §13.4), returned in reply to a CR-TPDU to accept the connection and settle on its final parameters.

TPDU_FIXED_SIZE = 6#
dst_ref: int = 0#

Destination reference - identifies, from the remote transport entity’s point of view, which requested connection this CC-TPDU confirms.

src_ref: int = 0#

Source reference chosen by this (responding) transport entity to identify the now-confirmed connection.

class_opt: TPDU_ClassOption = None#

Class and option finally selected, from the CR-TPDU’s offered choices, for this now-accepted connection.

parameters: list[Parameter] = None#

Same as in TPDU_ConnectionRequest

user_data: bytes = b''#

User data returned with the confirmation (X.224, §13.4.5); empty for class 0, optional for every other class.

class icspacket.proto.cotp.structs.TPDU_DisconnectRequest(li: int = 0, code: int = 0, dst_ref: int = 0, src_ref: int = 0, reason: TPDU_DisconnectReason | int = 0, parameters: list[Parameter] = None, user_data: bytes = None)[source]#

Disconnect Request (DR) TPDU (X.224, §13.5): initiates release of a transport connection, optionally carrying parameters and user data explaining why.

TPDU_FIXED_SIZE = 6#
dst_ref: int = 0#

Destination reference - identifies the transport connection to be released.

src_ref: int = 0#

Source reference - identifies the transport connection from the sender’s perspective.

reason: TPDU_DisconnectReason | int = 0#

Reason code for disconnection (See X.224, §13.5.4).

parameters: list[Parameter] = None#

Optional variable-part parameters; only additional information and checksum may appear here.

user_data: bytes = None#

Optional explanatory user data, limited to 64 octets.

class icspacket.proto.cotp.structs.TPDU_DisconnectConfirm(li: int = 0, code: int = 0, dst_ref: int = 0, src_ref: int = 0, parameters: list[Parameter] = None)[source]#

Disconnect Confirm (DC) TPDU (X.224, §13.6): the reply to a DR-TPDU acknowledging that the connection has been released.

TPDU_FIXED_SIZE = 5#
dst_ref: int = 0#

Destination reference - identifies the transport connection being confirmed as disconnected.

src_ref: int = 0#

Source reference - identifies the transport connection from the sender’s perspective.

parameters: list[Parameter] = None#

Only checksum is allowed as a parameter

class icspacket.proto.cotp.structs.TPDU_Number(eot: bool = False, value: int = 0)[source]#
eot: bool = False#

End-of-TSDU marker.

Set to 1 on the final DT-TPDU of a segmented TSDU so the receiver knows the sequence is complete; 0 on every DT-TPDU before it.

value: int = 0#

Send sequence number for this TPDU.

Always zero in class 0, and unconstrained in class 2 when explicit flow control is not used. Packed into bits 7-1 of octet 3 for classes 0 and 1, or bits 7-1 of octet 5 for classes 2, 3 and 4.

class icspacket.proto.cotp.structs.TPDU_Data(li: int = 0, code: int = 0, nr: TPDU_Number = None, user_data: bytes = b'')[source]#

Data (DT) TPDU (X.224, §13.7): the workhorse PDU that carries application data across an established transport connection, plus any parameters needed alongside it.

TPDU_FIXED_SIZE = 2#
nr: TPDU_Number = None#

Sequence number and end-of-TSDU marker for this DT-TPDU.

user_data: bytes = b''#

The actual TSDU payload data being carried by this TPDU.

property tpdu_nr: int#
property is_last: bool#
class icspacket.proto.cotp.structs.TPDU_ExpeditedData(li: int = 0, code: int = 0, dst_ref: int = 0, ed_nr: TPDU_Number = None, parameters: list[Parameter] = None, user_data: bytes = None)[source]#

Expedited Data (ED) TPDU (X.224, §13.8): carries urgent data that should bypass normal flow control on its way across the connection.

TPDU_FIXED_SIZE = 4#
dst_ref: int = 0#

Destination reference - identifies the transport connection to which the expedited data belongs.

ed_nr: TPDU_Number = None#

Sequence number for expedited data (See X.224, §13.8.4).

parameters: list[Parameter] = None#

Only checksum is allowed as a parameter

user_data: bytes = None#

Expedited payload data, bounded by whatever maximum size the expedited service allows.

class icspacket.proto.cotp.structs.TPDU_DataAcknowledgement(li: int = 0, code: int = 0, dst_ref: int = 0, next_nr: TPDU_Number = None, credit: int = 0, parameters: list[Parameter] = None)[source]#

Data Acknowledgement (AK) TPDU (X.224, §13.9): acknowledges data received so far and reports flow-control state back to the sender.

TPDU_FIXED_SIZE = 6#
dst_ref: int = 0#

Destination reference - identifies the transport connection.

next_nr: TPDU_Number = None#

Sequence number of the next DT-TPDU this side expects to receive.

credit: int = 0#

Flow-control credit: how many further TPDUs the sender of this AK-TPDU is currently willing to accept.

parameters: list[Parameter] = None#

Optional parameters an AK-TPDU may carry (X.224, §13.9): a checksum, and, only where class 4 permits it, a subsequence number, flow-control confirmation, and/or selective-acknowledgement parameters.

class icspacket.proto.cotp.structs.TPDU_ExpeditedDataAcknowledgement(li: int = 0, code: int = 0, dst_ref: int = 0, ed_nr: TPDU_Number = None, parameters: list[Parameter] = None)[source]#

Expedited Data Acknowledgement (EA) TPDU (X.224, §13.10): acknowledges receipt of a specific ED-TPDU.

TPDU_FIXED_SIZE = 4#
dst_ref: int = 0#

Destination reference - identifies the transport connection.

ed_nr: TPDU_Number = None#

Sequence number of the ED-TPDU that this acknowledgement confirms.

parameters: list[Parameter] = None#

Only checksum is allowed as a parameter

class icspacket.proto.cotp.structs.TPDU_Reject(li: int = 0, code: int = 0, dst_ref: int = 0, y_nr: int = 0)[source]#

Reject (RJ) TPDU (X.224, §13.11): tells the peer that TPDU(s) it sent were rejected and need to be retransmitted.

TPDU_FIXED_SIZE = 5#
dst_ref: int = 0#

Destination reference - identifies the transport connection.

y_nr: int = 0#

Sequence number of the next TPDU this side still expects, i.e. Y(R).

class icspacket.proto.cotp.structs.ER_RejectCause(*values)[source]#
REASON_NOT_SPECIFIED = 0#
INVALID_PARAMETER_CODE = 1#
INVALID_TPDU_TYPE = 2#
INVALID_PARAMETER_VALUE = 3#
class icspacket.proto.cotp.structs.TPDU_Error(li: int = 0, code: int = 0, dst_ref: int = 0, reject_cause: ER_RejectCause | int = ER_RejectCause.REASON_NOT_SPECIFIED, parameters: list[Parameter] = None)[source]#

TPDU Error (ER) TPDU (X.224, §13.12): reports a protocol error detected in a received TPDU; it never carries user data.

TPDU_FIXED_SIZE = 4#
dst_ref: int = 0#

Destination reference (See §13.4.3).

reject_cause: ER_RejectCause | int = 0#

Reject cause (See §13.12.3).

parameters: list[Parameter] = None#

Optional parameters: an “Invalid TPDU” entry and/or a checksum.

icspacket.proto.cotp.structs.parse_tpdu(octets: bytes) TPDU | TPDU_ConnectionConfirm | TPDU_ConnectionRequest | TPDU_Data | TPDU_DataAcknowledgement | TPDU_DisconnectConfirm | TPDU_DisconnectRequest | TPDU_Error | TPDU_ExpeditedData | TPDU_ExpeditedDataAcknowledgement | TPDU_Reject[source]#

Parse a TPDU (Transport Protocol Data Unit) from raw octets.

First decodes a generic TPDU to extract the TPDU code and uses this to dispatch to the corresponding TPDU subclass implementation defined in TPDU_TYPES.

Example:

>>> tpdu = parse_tpdu(...)
>>> isinstance(tpdu, TPDU_Data)
True
>>> data: bytes = tpdu.user_data
Parameters:

octets (bytes) – Raw TPDU octets to parse.

Raises:

ValueError – If the octet buffer is shorter than two bytes.

Returns:

A parsed TPDU instance corresponding to the TPDU code (e.g., TPDU_ConnectionRequest).

Return type:

_TPDULike