APCI - Framing Layer#

Application Protocol Control Information: the I/S/U-format control field, sequence-number bookkeeping, and the fixed APCI frame header shared by every IEC 60870-5-104 message.

APCI - Application Protocol Control Information (IEC 60870-5-104 framing).

(See IEC 60870-5-104, clause 5 - APCI structure)

Every message exchanged over an IEC 60870-5-104 TCP connection is wrapped in an APCI frame: a fixed start byte, an automatically-computed length octet, and a 4-octet control field whose own low bits pick one of three formats -

  • I-format (Information transfer): carries an ASDU and both a send and a receive sequence number.

  • S-format (Numbered supervisory function): a bare acknowledgment, carrying only a receive sequence number.

  • U-format (Unnumbered control function): the STARTDT/STOPDT/ TESTFR connection handshake.

icspacket.proto.iec104.apci.APCI_MAX_ASDU_LENGTH = 249#

Largest ASDU payload (in octets) an I-format APCI frame should carry.

The length octet is a single byte (max 255), of which 4 octets are always spent on the control field; 249 is the conservative, commonly used ceiling for the 104 profile, leaving a small safety margin below the theoretical 255 - 4 = 251.

class icspacket.proto.iec104.apci.ControlField(*, octet1: int = 0, octet2: int = 0, octet3: int = 0, octet4: int = 0)[source]#

Raw 4-octet APCI control field.

(See IEC 60870-5-104, clause 5.2)

property format: APCIFormat#

Which of the three APCI formats this control field follows.

property send_seq: int#

N(S): this frame’s send sequence number (I-format only), a counter modulo 2**15.

property recv_seq: int#

N(R): the last send sequence number acknowledged by the sender of this frame (I-format and S-format), a counter modulo 2**15.

property function: UFormatFunction#

U-format handshake function flags (STARTDT/STOPDT/ TESTFR, U-format only).

static new_i(send_seq: int, recv_seq: int) ControlField[source]#

Builds an I-format control field with the given sequence numbers.

static new_s(recv_seq: int) ControlField[source]#

Builds an S-format control field acknowledging recv_seq.

static new_u(function: UFormatFunction) ControlField[source]#

Builds a U-format control field carrying function.

class icspacket.proto.iec104.apci.APDU_Frame(*, control: ControlField = <factory>, asdu: bytes = b'')[source]#

The variable-length part of an APCI frame: the control field plus, for I-format frames only, the raw encoded ASDU payload.

This struct only exists to be wrapped by APCI’s Prefixed length field - use APCI directly instead of this class.

control: ControlField#

The 4-octet control field, see ControlField.

asdu: bytes = b''#

Raw encoded ASDU bytes. Only meaningful when control.format is I_FORMAT; empty for S-format and U-format frames.

class icspacket.proto.iec104.apci.APCI(*, start: bytes = b'h', frame: APDU_Frame = <factory>)[source]#

Application Protocol Control Information - the top-level TCP frame every IEC 60870-5-104 message is wrapped in.

(See IEC 60870-5-104, clause 5.1)

Because this class inherits StructDefMixin, it can be read straight off a socket with from_bytes(), and an outgoing frame just needs to_bytes() - the length octet is always computed automatically, there is no build() step.

Examples#

>>> APCI.startdt_act().to_bytes()
b'h\x04\x07\x00\x00\x00'
>>> APCI.i_format(send_seq=0, recv_seq=0, asdu=b"...").to_bytes()
start: bytes = b'h'#

Fixed start byte (0x68); not part of the constructor/repr since its value never varies.

frame: APDU_Frame#

The control field and (I-format only) ASDU payload, automatically length-prefixed. See APDU_Frame.

property control: ControlField#

Shortcut for self.frame.control.

property format: APCIFormat#

Shortcut for self.frame.control.format.

property asdu: bytes#

Shortcut for self.frame.asdu.

static i_format(send_seq: int, recv_seq: int, asdu: bytes) APCI[source]#

Builds an I-format APCI frame carrying asdu.

static s_format(recv_seq: int) APCI[source]#

Builds an S-format (bare acknowledgment) APCI frame.

static u_format(function: UFormatFunction) APCI[source]#

Builds a U-format (handshake) APCI frame carrying function.

static startdt_act() APCI[source]#

Builds a STARTDT activation frame (client to server).

static startdt_con() APCI[source]#

Builds a STARTDT confirmation frame (server to client).

static stopdt_act() APCI[source]#

Builds a STOPDT activation frame (client to server).

static stopdt_con() APCI[source]#

Builds a STOPDT confirmation frame (server to client).

static testfr_act() APCI[source]#

Builds a TESTFR activation frame (either direction).

static testfr_con() APCI[source]#

Builds a TESTFR confirmation frame (either direction).