IEC 60870-5-104 Server Driver

The ESF IEC 60870-5-104 Server Driver implements an IEC 60870 server integrated with ESF Driver and Wires/Asset models.


  • The driver manages a local cache whose entries represent IEC 60870-5 information objects, either in monitoring or control direction.
  • Support for spontaneous messages.
  • Support for a defined subset of IEC 60870-5 information object types.
  • Support for interrogations, counter interrogations and clock synchronization.
  • Supports interrogation groups.
  • Watchdog integration.

Driver cache

The drive cache can be represented as a key -> value map.

The keys are are (IEC 60870 type identifier, information object address) pairs.
The values are are information object representations.

The most straightforward way for populating the cache is to define Assets whose channels represent the entries.
More precisely, entries are created by calling the Driver.prepareRead() and/or Driver.registerChannelListener() Java APIs. If the entries are defined through the Web UI by creating Assets, ESF will take care of calling the APIs above.

  • Current cache entry values can be retrieved using READ operations/channels.
  • Cache entry values can be updated using WRITE operations/channels.
  • Cache update events can be notified to applications by registering channel listeners. In terms of Assets, this corresponds to enabling the listen channel parameter.

Monitoring direction cache entries

The entries that represent data sent in monitor direction can be retrieved and/or updated locally using all the interfaces that leverage ESF Driver APIs, for example by performing a read or write on an Asset channel.

After the value of a monitoring direction entry is updated by a framework component, its value will be visible by IEC 104 clients through interrogations.
Updating a monitoring direction entry value can optionally also trigger sending a spontaneous message to the client.

Entries that refer to time-tagged information objects (e.g. M_SP_TB_1) will report the timestamp of the entry update instant in server time (see the clock synchronization section).

Control direction cache entries

Cache entries in control direction can be retrieved locally in the same way as monitoring direction entries, but should be considered read only from the gateway perspective.

These entries can be modified by IEC 104 client through commands. When a command is received, the new value will be written in the cache and retained indefinitely until another command for the same entry is received.

The effect of commands on cache entries depend on the cause of transmission:

  • ACTIVATION: The driver will update the cache entry with the received value.

  • DEACTIVATION: The driver will reset the cache entry bringing it back to the uninitialized state (see below).

The driver can emit events to framework components just after a command is received. Events can be received on a Wire Graph by ticking the listen flag in Wire Asset configuration or by using the Driver.registerChannelListener() Java APIs.

Since commands only cause modifications of cache entries, commands will likely always succeed (the driver will respond with a positive ACTIVATION CONFRMATION ASDU). Any side effects of the command need to be managed by external components in an appropriate way for the specific application.

Uninitialized entries

All cache entries are created in an uninitialized state until a value is written to them either by an ESF component for monitoring direction or by a IEC client command for control direction.

The behavior of an uninitialized entry is the following:

  • If the value is read by a framework component, an error will be generated.

  • If the value is returned to an IEC client as result of an interrogation command, it will report a default value and the invalid quality bit will be set.

Interaction between cache entries

The driver itself does not introduce any interaction between different entries.

Since the entries are identified by a (type id, ioa) pair, it is possible to define cache entries having the same information object address, these entries are completely unrelated. (for example sending a C_SC_NA_1 with ioa 1 will not affect the entry of type M_SP_NA_1 and ioa 1 by default).

Interactions between entries of the same (or different) information object address can be established by other framework components (for example by a Wire Graph).

Entry lifecycle

As previously said, entries are created by calling the Driver.prepareRead() and/or Driver.registerChannelListener() Java APIs, which is done automatically by the framework if the user creates Asset channels using the web UI.

Every entry is reference counted, calls to Driver.prepareRead() or Driver.registerChannelListener() related to the same (type id, ioa) entry key will increase the reference count and calls to PreparedRead.close() and Driver.unregisterChannelListener() will decrease it.

When the reference count reaches 0, the entry will be deleted.

In term of Assets, all channels referring to the same (type id, ioa) will refer to the same entry and increase the reference count. If and when all channels referring to the same (type id, ioa) are deleted the entry will be removed.

Asset channel configuration contains other parameters besides (type id, ioa), (for example interrogation group, spontaneous messages enabled flag). If multiple channels referencing the same entry are defined, it is important that the other parameters are set to same value, otherwise the driver will use one of the provided values for each parameter, which one is undefined.

Cache persistence

Cache entries reside in device RAM only and are not persisted in any way. An ESF restart or gateway reboot will cause all entries to return to the uninitialized state.

Global configuration parameters

Driver global configuration allow to configure the device listening address, port and other link layer parameters.
Changing the Common Address configuration parameter currently requires a restart of the driver. The driver will use the old common address until the restart.

The driver can be restarted by rebooting the device, restarting ESF, or with the following procedure:

  1. Open the Device -> Bundles section of the web ui
  2. Click on the com.eurotech.framework.iec60870.slave.driver entry
  3. Click on the Stop bundle button
  4. Select the com.eurotech.framework.iec60870.slave.driver entry again
  5. Click on the Start bundle button

Channel configuration parameters

Currently the channel configuration is composed of the following parameters:

  • Resource: The resource type addressed by the channel, usually an information object type id.

  • Object Address: The address of the information object.

  • Spont messages enabled: If set to true, the driver will send spontaneous messages to the server if the cache entry value is updated by some framework component.

    This parameter is ignored for control direction types.

  • Interrogation group: The interrogation or counter interrogation group (for M_IT_NA_1 type) to be assigned to the entry.
    The allowed values depend on the type id:

    • M_SP_NA_1: From 1 to 16
    • M_DP_NA_1: From 1 to 16
    • M_BO_NA_1: From 1 to 16
    • M_ME_NA_1: From 1 to 16
    • M_ME_NB_1: From 1 to 16
    • M_ME_NC_1: From 1 to 16
    • M_IT_NA_1: From 1 to 4

    If this parameter is not set, the value of the entry will be returned only in general interrogations. If set the value will be assigned to the corresponding group, in this case the value will be also returned in general interrogations.

    This parameter is ignored for time-tagged information object types and for control direction types.

Supported types

The driver currently supports the following information object types.

Monitoring direction

Non time-tagged information objects:

  • M_SP_NA_1 (1)
  • M_DP_NA_1 (3)
  • M_BO_NA_1 (7)
  • M_ME_NA_1 (9)
  • M_ME_NB_1 (11)
  • M_ME_NC_1 (13)
  • M_IT_NA_1 (15)

Time-tagged information objects:

  • M_SP_TB_1 (30)
  • M_DP_TB_1 (31)
  • M_BO_TB_1 (33)
  • M_ME_TD_1 (34)
  • M_ME_TE_1 (35)
  • M_ME_TF_1 (36)
  • M_IT_TB_1 (37)

Control direction

  • C_SC_NA_1 (45)
  • C_DC_NA_1 (46)
  • C_SE_NA_1 (48)
  • C_SE_NB_1 (49)
  • C_SE_NC_1 (50)

The driver also supports the C_CS_NA_1 command for clock synchronization, this type is only used internally cannot be used in channel configuration.

Non time-tagged information objects can be sent by the server in spontaneous messages and/or retrieved by the client using interrogations and counter interrogations.

Time-tagged information objects can only be sent in spontaneous messages by the server when a cache entry value is updated by a framework component.

Mapping with IEC 60870 types and Driver/Wires types

The Driver, Wires and Asset models support the following types, that refer to the corresponding Java types.

  • LONG

These types are used in interactions between the Driver and the other ESF components, like the Wire Graph.

  • The numeric types allow to encode the "main" value of the information objects.

  • The STRING type allows to produce a Json representation of the information objects, containing all of its fields (e.g. value, timestamp, quality bits, qualifier etc).
    The current version of the driver only supports this type for reads from the cache and events sent to the framework, currently it is not possible to use it for updating a cache entry.

    This driver uses the same JSON format as ESF IEC 60870-5 master driver, please refer to master driver documentation for more details.

  • The BYTE_ARRAY type is not currently supported by the Driver.

The applicable types for each information object type are described below:

M_SP_NA_1, M_SP_TB_1, C_SC_NA_1
  • BOOLEAN: Encodes the value of the SPI or SCS fields

  • STRING: JSON representation

M_DP_NA_1, M_DP_TB_1, C_DC_NA_1
  • INTEGER, LONG, DOUBLE, FLOAT: Encode the value of the DPI or DCS field, the allowed values are 0, 1, 2 and 3.

  • STRING: JSON representation

M_BO_NA_1, M_BO_TB_1
  • INTEGER, LONG, DOUBLE, FLOAT: Encode the value of the BSI field encoded as an unsigned integer. In order to be able to represent all possible values is recommended to use the LONG type.

  • STRING: JSON representation

M_ME_NA_1, M_ME_TD_1, C_SE_NA_1
  • FLOAT, DOUBLE: Encode the value of the NVA field expressed as a real number in the [-1; 1] range.

  • STRING: JSON representation

M_ME_NB_1, M_ME_TE_1, C_SE_NB_1
  • INTEGER, LONG, DOUBLE, FLOAT: Encode the value of the SVA field.

  • STRING: JSON representation

M_ME_NC_1, M_ME_TF_1, C_SE_NC_1
  • INTEGER, LONG, DOUBLE, FLOAT: Encode the floating point value, if an integer type is specified, a truncation will be performed.

  • STRING: JSON representation

M_IT_NA_1, M_IT_TB_1
  • INTEGER, LONG, DOUBLE, FLOAT: Encode the counter value of the BCR field.

  • STRING: JSON representation

Clock synchronization

The driver supports the clock synchronization command that can be used to adjust the timestamps contained in time-tagged information objects.

Timestamps in time-tagged information objects are obtained from server clock.

Server clock behavior is the following:

  • It is initialized from system time when the driver starts.
  • It is based on a monotonic clock provided by the java.lang.System.nanoTime() Java function.
    • A clock synchronization command does not affect device system time but only server time, unless the set.system.clock global parameter is set.

Setting system time on clock sync

The driver supports setting system time from clock synchronization. This feature can be enabled by setting the set.system.clock global parameter to true. If this feature is enabled, it is important to disable other system level clock synchronization providers (e.g. ESF ClockService, systemd-tymesyncd), in this case the master is responsible of keeping device clock synchronized.

If this feature is enabled, the timestamp received during clock sync must be in UTC, all timestamp flags (validity, DST etc) will be ignored.

SERVER_TIME resource

The SERVER_TIME resource type allows to create channels that provide current server time in milliseconds since EPOCH as read result. SERVER_TIME channels in listen mode will generate an event on clock synchronization reporting the received timestamp.

Interrogation support

The driver supports the C_IC_NA_1 and C_CI_NA_1 commands, the only parts of the command qualifier that are interpreted by the driver are the ones related to the interrogation groups, other fields will be currently ignored.

WatchdogService integration

The Driver exposes a global configuration parameter that allow to enable the integration with ESF WatchdogService.
If enabled it allows to trigger a device reboot if the driver main loop thread hangs for more than 60 seconds.