ASDU - Application Layer#

The Application Service Data Unit: the common data unit identifier (type ID, cause of transmission, common address) that wraps every information object exchanged over IEC 60870-5-104.

ASDU - Application Service Data Unit (IEC 60870-5-104 application layer).

(See IEC 60870-5-101, clause 7.2 - Application Service Data Unit)

class icspacket.proto.iec104.asdu.ASDU(*, header: ASDU_Header = <factory>, objects: bytes = b'')[source]#

Application Service Data Unit (ASDU).

(See IEC 60870-5-101, clause 7.2)

Carries a ASDU_Header plus the raw, not-yet-decoded information-object bytes; use build()/decode_objects() to go from/to a InformationObject list.

header: ASDU_Header#

The fixed 6-octet header, see ASDU_Header.

objects: bytes = b''#

Raw, undecoded information-object bytes. Populated/consumed via build()/decode_objects().

build(objects: list[InformationObject], sq: bool = False) bytes[source]#

Encode objects and serialize the whole ASDU.

Keeps ASDU_Header.vsq’s number/sq fields in sync with objects/sq before packing, recomputing these derived header fields immediately before packing.

Parameters:
  • objects – The information objects to encode, in wire order.

  • sq – Whether to use the sequential-address form: see VariableStructureQualifier.sq.

Raises:

ValueError – If len(objects) does not fit in the VSQ’s 7-bit number field (i.e. more than 127 objects).

Returns:

The fully encoded ASDU bytes.

decode_objects() list[InformationObject][source]#

Decode objects according to the header’s Type-ID/VSQ.

Raises:

ValueError – If the header’s Type-ID has no registered information-element struct (see asdu_type()).

Returns:

The decoded information objects.

class icspacket.proto.iec104.asdu.ASDU_Header(*, type_id: TypeID | int = TypeID.M_SP_NA_1, vsq: VariableStructureQualifier = <factory>, cot: CauseOfTransmissionField = <factory>, originator_address: int = 0, common_address: int = 0)[source]#

Fixed 6-octet ASDU header.

(See IEC 60870-5-101, clause 7.2 and clause 7.2.4 - Common address of ASDU)

The 104 profile always uses the 2-octet forms of both the Cause Of Transmission’s originator address and the Common Address of ASDU (unlike 101, where 1-octet forms are also legal) - this struct only implements the 104 forms, matching this module’s TCP-only scope.

type_id: TypeID | int = 1#

Identifies the structure and semantics of the objects that follow, see TypeID.

vsq: VariableStructureQualifier#

Variable Structure Qualifier, see VariableStructureQualifier.

cot: CauseOfTransmissionField#

Cause Of Transmission, see CauseOfTransmissionField.

originator_address: int = 0#

Identifies the originating controlling station in multi-master setups; 0 when only one master is used.

common_address: int = 0#

Station (sector) address this ASDU concerns; 0xFFFF addresses all stations (global/broadcast, only valid for select ASDU types).

class icspacket.proto.iec104.asdu.CauseOfTransmissionField(test: bool = False, negative: bool = False, cause: int = 0)[source]#

Cause Of Transmission (COT) octet.

Wraps a CauseOfTransmission value together with the test and negative-confirmation flags. (See IEC 60870-5-101, clause 7.2.3)

test: bool = False#

Marks the ASDU as a test frame - the outstation processes it normally but the master should not act on the result.

negative: bool = False#

P/N: True marks a negative confirmation (the requested activation/command could not be performed).

cause: int = 0#

The reason this ASDU was sent; interpret with CauseOfTransmission.

class icspacket.proto.iec104.asdu.InformationObject(ioa: int, element: Any)[source]#

A single decoded information object: its address plus payload.

element holds whatever struct instance is registered for the owning ASDU’s Type-ID (e.g. an SIQ for M_SP_NA_1).

ioa: int#

Information Object Address (0 - 16777215).

element: Any#

The decoded information element, or None/opaque bytes for unregistered Type-IDs.

class icspacket.proto.iec104.asdu.VariableStructureQualifier(sq: bool = False, number: int = 0)[source]#

Variable Structure Qualifier (VSQ).

Tells a decoder how many information objects follow the ASDU header and whether they share one implicit, incrementing address or each carry their own. (See IEC 60870-5-101, clause 7.2.2)

sq: bool = False#

SQ bit. When True, only the first information object carries an explicit Information Object Address; the rest are implicitly addressed ioa + 1, ioa + 2, etc. (“sequence” of same-kind objects, e.g. a contiguous block of measured values). When False, every object carries its own address.

number: int = 0#

Number of information objects (or, when sq is set, elements within the single addressed sequence) following the header.