Skip to content

Fix ASDU 6 time format and add the RII to ASDU 20 - #3

Open
boeboe wants to merge 2 commits into
masarray:mainfrom
boeboe:fix/asdu6-cp56-asdu20-rii
Open

boeboe wants to merge 2 commits into
masarray:mainfrom
boeboe:fix/asdu6-cp56-asdu20-rii

Conversation

@boeboe

@boeboe boeboe commented Nov 12, 2026

Copy link
Copy Markdown

Fixes #1
Fixes #2

Two changes to Iec103AsduBuilder, one commit each:

  • ClockSynchronization sends ASDU 6 with a CP56Time2a (7 octets), as in IEC 60870-5-103 clause 7.3.1.6. The new EncodeCp56Time2a writes milliseconds, minute, hour, day of month with day of week (1 = Monday), month and year. ASDU 1 still uses EncodeCp32Time2a.
  • GeneralCommand takes an optional returnInformationIdentifier (default 0) and appends it after the DCO, as in clause 7.3.2.4. Existing callers compile unchanged. AsduDecoder adds the RII to the notes of a type 20 ASDU.

The slave simulator only acknowledges ASDU 6 and ASDU 20 on the link layer and does not read their information elements, so it needs no change.

Tests

Two new cases in tests/ArIEC103.Protocol.Tests check the encoded bytes of both ASDUs and decode them again. Restore, build (ArIEC103.sln, Release) and the protocol smoke tests pass (13/13) with the .NET 8 SDK. Against the old code the ASDU 6 case fails and the ASDU 20 case does not compile.

Interoperability

With these changes ArIEC103 as the control system gets a confirmation of the clock synchronization (ASDU 6, cause 8) and of the general command (ASDU 1, cause 20, SIN = RII, then cause 12) from a station that checks the ASDU lengths; before, both timed out. This was run in the iec60870-5-interop harness against vitusdong/iec103-dotnet and against go-iec60870-5: six cases moved from failing to passing and no other case changed.

Iec103AsduBuilder.ClockSynchronization encoded the time with
EncodeCp32Time2a: four octets of time and one zero octet, five octets
in all. IEC 60870-5-103 clause 7.3.1.6 defines the information element
of ASDU 6 as seven octets of binary time (CP56Time2a, clause 7.2.6.29),
so a station that checks the length ignores the command and sends no
confirmation.

Add EncodeCp56Time2a (milliseconds, minute, hour, day of month with day
of week, month, year) and use it for ASDU 6. ASDU 1 keeps CP32Time2a.
Iec103AsduBuilder.GeneralCommand ended ASDU 20 after the DCO, e.g.
14 81 14 01 A0 63 02. IEC 60870-5-103 clause 7.3.2.4 defines the
information element as DCO followed by the return information
identifier (RII, clause 7.2.6.19), which the protection equipment
returns as SIN of the ASDU 1 that confirms the command (clause 7.4.4).
A station that checks the length drops the short ASDU and sends no
confirmation.

Add an optional returnInformationIdentifier parameter (default 0) and
append it after the DCO. AsduDecoder notes the RII of a type 20 ASDU.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ASDU 20 general command has no return information identifier (RII) ASDU 6 clock synchronization is sent with CP32Time2a instead of CP56Time2a

1 participant