Introduction

lib60870-CS103 is a feature rich and field proven implementation of the IEC 60870-5-103 protocol for client (master station) and server (slave or controlled station). The library implements all data types of the IEC 60870-5-103 specifications. lib60870-CS103 is implemented in standard C and is compatible with the C99 standard. It is designed to be as easy to use as possible.

The client/server API is strictly asynchronous. You send the requests with non-blocking functions and will have to handle the responses and other events in callback functions.

Here is a list of supported features:

  • CS 103 (IEC 60870-5-103) unbalanced serial modes.

  • Master/Client supports sending system commands, process commands, parameter commands, and data messages in reverse direction.

  • Slave/Server supports sending data messages in monitoring direction and commands in reverse direction.

  • The list of supported ASDU types can be found at the end of the page under Supported message types.

NOTE: CS stands for "companion standard" and specifies variants of the communication protocols and services defined in the IEC 60870-5 standard series.

The library uses an "object-oriented" programming style. It is based on abstract data types (ADT) and functions that operate on these data types. In general the actual implementations of the data types (the data structures that hold the data) is hidden from the API user. In almost all cases it is not required (and also not recommended) that the API user accesses these data structures directly.

Application layer messages

This programming style will be explained by the example of the CS103_ASDU ADT that is a central part of the library API. This data type represents an application layer message of the CS103 protocol. The abbreviation ASDU stands for "Application Service Data Unit". To create a new ASDU object the CS103_ASDU_create function has to be used as a constructor of the object.

This function has various parameters to reflect the different properties of an ASDU. Here is the signature of the CS103_ASDU_create function:

CS103_ASDU
CS103_ASDU_create(bool isSequence, CS103_CauseOfTransmission cot, int ca);

Example:

CS103_ASDU newAsdu = CS103_ASDU_create(false, CS103_COT_SPONTANEOUS, 2);

The first parameter isSequence indicates that the ASDU contains a sequence of consecutive information objects (if true) or one or more independent information objects (if false). A sequence of consecutive information objects means that the ASDU only contains a single information object address (IOA). The consecutive information objects then have addresses IOA, IOA + 1, IOA + 2, …​

The second parameter indicates the cause of transmission (COT). It is to tell the other side the reason for sending the messages. Possible values could be CS103_COT_SPONTANEOUS for spontaneous messages, CS103_COT_REMOTE_OPERATION for remote operation.

the last parameter is ca for the common address of the ASDU.

With the handle of the new ASDU object (in our case newAsdu) we can call one of the various functions to get or set data of the ASDU. For example you can get or set type ID with the CS103_ASDU_getTypeID or CS103_ASDU_setTypeID functions. The first parameter of these functions is always the handle of the ASDU object.

uint8_t typeId = CS103_ASDU_getTypeID(newAsdu);
An important function to create usable ASDU objects is the _CS103_ASDU_addInformationObject_ function. With this function you can add information object instances to the ASDU.
CS103_InformationObject io = (CS103_InformationObject)CS103_TimeTaggedMessage_create(NULL, 255, 1, CS103_DoublePoint_OFF, &timeTag, 1);

CS103_ASDU_addInformationObject(newAsdu, io);

This function can be called multiple times to add more information objects to the ASDU object. It has a boolean return values that indicates if the information object has been added successfully (return value true). Adding an information object can fail when the ASDU payload is already full. In this case the function will return false.

You can also implement customized ASDUs that are out of the standard range using standart information element.

Example:

CS103_ASDU asdu = CS103_ASDU_create(false, CS103_COT_SPONTANEOUS, 2);
CS103_CustomIO io = CS103_CustomIO_create(NULL, 33, 255, 1);

We’re creating the customized information object with an ASDU of type 33 which is out of the standard range.

InformationElement ie = (InformationElement)CS103_StatusOfFault_create(NULL, true, true, false, false);
CS103_CustomIO_addInformationElement(io, ie);
CS103_InformationElement_destroy(ie);

We’re creating the information element of type STATUS_OF_FAULT, assignint its values, and then we add it to the information object.

When the IE is created and it is no longer needed, it has to be released with the CS103_InformationElement_destroy function.

Finally, when the application created an ASDU object and it is no longer needed it has to be released with with the CS103_ASDU_destroy function.

CS103_ASDU_destroy(newAsdu);

Master (client) side programming

For master side programming the following abstract data types and APIs can be used:

  • CS103_Master for unbalanced mode serial connections.

Preparing a CS 103 connection to one or more slaves

CS 103 provides one link layer mode for master/slave connections.

Unbalanced mode supports communication between a single master and multiple slaves on a serial bus. Each slave is addressed by its unique link layer address. Slaves are not allowed to send messages spontaneously. They only respond following a request from the master. The master can address multiple slaves at once by using a broadcast address.

Configuring the serial port

For both modes first the serial port has to be configured and initialized. The following code shows an example how to prepare the serial port for usage with the library:

  SerialPort port = SerialPort_create("/dev/ttsS0", 9600, 8, 'E', 1);

Create and use a new unbalanced master instances

For unbalanced communication mode the CS103_Master type has to be used.

The following code creates a new unbalanced master instance using the serial port defined above. The CS103_Master_setASDUReceivedHandler function provides a callback handler for received ASDUs. The CS103_Master_addSlave function will create a new slave specific state machine to handle all communication with the slave with link layer address 1.

CS103_Master master = CS103_Master_create(port);

CS103_Master_setASDUReceivedHandler(master, asduReceivedHandler, NULL);

CS103_Master_AddSlave(master, 1);

Before sending any command or other request to a specific slave the slave address has to be set with the CS103_Master_useSlaveAddress function.

CS103_Master_useSlaveAddress(master, 1);

Sending requests and receiving responses from the slave

In general an application is concerned with sending application layer messages (ASDUs) to the slave. The master side API supports generic and specialized functions to send messages to the slave. When sending system commands or process commands it is recommended to use the specialized functions because they help to create ASDUs that comply to the standards. These specialized functions are explained in the following sections. They exist generally in two variants for CS103.

For the general case it is possible to send arbitrary ASDUs by using the CS103_Master_sendASDU or function.

For receiving application layer messages the application has to implement the CS103_ASDUReceivedHandler callback.

Example for processing received ASDUs in the CS103_ASDUReceivedHandler
static bool
ASDUReceivedHandler (void* parameter, int address, CS103_ASDU asdu)
{
printf("RECVD ASDU type: %s, COT:%s, CA:%i\n", CS103_TypeID_toString(CS103_ASDU_getTypeID(asdu)), CS103_CauseOfTransmission_toString(CS103_ASDU_getCOT(asdu)),
    CS103_ASDU_getCA(asdu));


if (CS103_ASDU_getTypeID(asdu) == CS103_ASDU_TIME_TAGGED)
{
    CS103_InformationObject io = CS103_ASDU_getElement(asdu, 0);
    TEST_ASSERT_EQUAL_UINT8(1, CS103_InformationObject_getInformationNumber(io));
    TEST_ASSERT_EQUAL_UINT8(255, CS103_InformationObject_getFunctionType(io));

    CS103_TimeTaggedMessage timeTagMessage = (CS103_TimeTaggedMessage)io;

    printf("FUN: %i, INF: %i,SIN:%i, DPI: %s, Time: %ih:%imn:%is\n", CS103_InformationObject_getInformationNumber(io), CS103_InformationObject_getFunctionType(io), CS103_TimeTaggedMessage_getSIN(timeTagMessage), CS103_DoublePoint_toString(CS103_TimeTaggedMessage_getDPI(timeTagMessage)),
        CP32Time2a_getHour(CS103_TimeTaggedMessage_getTimeTag(timeTagMessage)), CP32Time2a_getMinute(CS103_TimeTaggedMessage_getTimeTag(timeTagMessage)), CP32Time2a_getSecond(CS103_TimeTaggedMessage_getTimeTag(timeTagMessage)));

    TEST_ASSERT_EQUAL_UINT8(1, CS103_TimeTaggedMessage_getSIN(timeTagMessage));
    TEST_ASSERT_EQUAL_UINT8(CS103_DoublePoint_OFF, CS103_TimeTaggedMessage_getDPI(timeTagMessage));



}

else if (CS103_ASDU_getTypeID(asdu) == CS103_ASDU_TIME_TAGGED_REL_TIME) {

    CS103_InformationObject io = CS103_ASDU_getElement(asdu, 0);
    TEST_ASSERT_EQUAL_UINT8(1, CS103_InformationObject_getInformationNumber(io));
    TEST_ASSERT_EQUAL_UINT8(255, CS103_InformationObject_getFunctionType(io));

    CS103_TimeTaggedMessageWithRelativeTime TaggedMessageRelTime = (CS103_TimeTaggedMessageWithRelativeTime)io;

    printf("Double Command: %s, RET: %i, FAN: %i, Time: %ih:%imn:%is, SIN: %i\n", CS103_DoublePoint_toString(CS103_TimeTaggedMessageWithRelativeTime_getDPI(TaggedMessageRelTime)),
        CS103_TimeTaggedMessageWithRelativeTime_getRET(TaggedMessageRelTime), CS103_TimeTaggedMessageWithRelativeTime_getFAN(TaggedMessageRelTime), CP32Time2a_getHour(CS103_TimeTaggedMessageWithRelativeTime_getTimeTag(TaggedMessageRelTime)), CP32Time2a_getMinute(CS103_TimeTaggedMessageWithRelativeTime_getTimeTag(TaggedMessageRelTime)),
        CP32Time2a_getSecond(CS103_TimeTaggedMessageWithRelativeTime_getTimeTag(TaggedMessageRelTime)), CS103_TimeTaggedMessageWithRelativeTime_getSIN(TaggedMessageRelTime));


    TEST_ASSERT_EQUAL_UINT8(5, CS103_TimeTaggedMessageWithRelativeTime_getSIN(TaggedMessageRelTime));
    TEST_ASSERT_EQUAL_UINT8(CS103_DoublePoint_ON, CS103_TimeTaggedMessageWithRelativeTime_getDPI(TaggedMessageRelTime));
    TEST_ASSERT_EQUAL_UINT16(1, CS103_TimeTaggedMessageWithRelativeTime_getFAN(TaggedMessageRelTime));

    }
return true;
}

This callback handler has to be installed with the CS103_Master_setASDUReceivedHandler function. CS103_Master_setASDUReceivedHandler(master, asduReceivedHandler, NULL);

All callback handler have a generic reference parameter with the name "parameter" in its function signatures. This parameter can be used by the user to provide application specific context information to the callback handler. This parameter will be set with the install function of the callback handler (like CS103_Master_setASDUReceivedHandler in the example above). If not used this parameter can be set to NULL.

Table 1. Master side callback handler types
callback type event CS 103 CS103_ASDUReceivedHandler

ASDU received but not handled by one of the other callback handlers

+

+

IEC60870_LinkLayerStateChangedHandler

System function in monitoring direction

1- End of general interrogation

It has as parameters: ca as Common address of the slave/server, and scn as scan number. And defined as bellow:

CS103_ASDU CS103_ASDU_create_EndOfGeneralInterrogation(CS103_ASDU asdu, int ca, uint8_t scn);

2- Time synchronization

It has as parameters: ca as Common address of the slave/server, and timeStamp. And defined as bellow:

CS103_ASDU CS103_ASDU_create_TimeSynchronization(CS103_ASDU asdu, int ca, CP56Time2a time);

3- Reset FCB

It has as parameters: ca as Common address of the slave/server, and fun as Function Type. And defined as bellow:

CS103_ASDU CS103_ASDU_create_ResetFCB(CS103_ASDU asdu, int ca, int fun);

4- Reset CU

It has as parameters: ca as Common address of the slave/server, and fun as Function Type. And defined as bellow:

CS103_ASDU CS103_ASDU_create_ResetCU(CS103_ASDU asdu, int ca, int fun);

5- Start/Restart

It has as parameters: ca as Common address of the slave/server, and fun as Function Type. And defined as bellow:

CS103_ASDU CS103_ASDU_create_StartRestart(CS103_ASDU asdu, int ca, int fun);

6- Power On

It has as parameters: ca as Common address of the slave/server, and fun as Function Type. And defined as bellow:

CS103_ASDU CS103_ASDU_create_PowerOn(CS103_ASDU asdu, int ca, int fun);

Status indications in monitor direction

1- Auto-recloser active

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11,12,20,21), and fun as Function type (t(z), I>>, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_AutoRecloserActive(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

2- Teleprotection Active

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11,12,20,21), and fun as Function type (t(z), I>>), And defined as bellow:

CS103_ASDU CS103_ASDU_create_TeleprotectionActive(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

3- Protection Active

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11,12,20,21), and fun as Function type (t(z), I>>,%IT, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_ProtectionActive(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

4- LED reset

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11,12,20,21), and fun as Function type (t(z), I>>,%IT, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_LEDReset(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

5- Monitor Direction Blocked

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (9,11), and fun as Function type (t(z), I>>,%IT, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_MonitorDirectionBlocked(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

6- Test mode

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (9,11), and fun as Function type (t(z), I>>,%IT, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_TestMode(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

7- Local parameter setting

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (9,11), and fun as Function type (t(z), I>>,%IT, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_LocalParameterSetting(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

8- Characteristic 1

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11,12,20,21), and fun as Function type (t(z)), And defined as bellow:

CS103_ASDU CS103_ASDU_create_Characteristic1(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

9- Characteristic 2

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11,12,20,21), and fun as Function type (t(z)), And defined as bellow:

CS103_ASDU CS103_ASDU_create_Characteristic2(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

10- Characteristic 1

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11,12,20,21), and fun as Function type (t(z)), And defined as bellow:

CS103_ASDU CS103_ASDU_create_Characteristic1(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

11-Characteristic 1

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11,12,20,21), and fun as Function type (t(z)), And defined as bellow:

CS103_ASDU CS103_ASDU_create_Characteristic1(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

Supervision indications in monitor direction

1- Auxiliary input 1

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11), and fun as Function type (t(z), I>>,%IT, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_AuxiliaryInput1(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

2- Auxiliary input 2

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11), and fun as Function type (t(z), I>>,%IT, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_AuxiliaryInput1(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

3- Auxiliary input 3

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11), and fun as Function type (t(z), I>>,%IT, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_AuxiliaryInput1(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

4- Auxiliary input 4

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9,11), and fun as Function type (t(z), I>>,%IT, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_AuxiliaryInput1(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

5- Measurand supervision 1

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9), and fun as Function type (t(z), I>>), And defined as bellow:

CS103_ASDU CS103_ASDU_create_MeasurandSupervisionI(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

6- Measurand supervision V

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9), and fun as Function type (t(z), I>>), And defined as bellow:

CS103_ASDU CS103_ASDU_create_MeasurandSupervisionV(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

7- Phase sequence supervision

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9), and fun as Function type (t(z), I>>), And defined as bellow:

CS103_ASDU CS103_ASDU_create_PhaseSequenceSupervision(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

8- Trip circuit supervision

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9), and fun as Function type (t(z), I>>, %IT, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_TripCircuitSupervision(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

9- Back-up operation (overcurrent protection back-up operation)

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9), and fun as Function type (t(z)), And defined as bellow:

CS103_ASDU CS103_ASDU_create_OvercurrentProtectionBackupOperation(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

10- VT fuse failure (VT := voltage transformer)

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9), and fun as Function type (t(z)), And defined as bellow:

CS103_ASDU CS103_ASDU_create_VTFuseFailure(CS103_ASDU asdu, int ca, int cot,int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

11- Teleprotection disturbed

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9), and fun as Function type (t(z), I>>, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_TeleprotectionDisturbed(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

12- Group warning

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9), and fun as Function type (t(z), I>>, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_GroupWarning(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

13- Group alarm

It has as parameters: ca as Common address of the slave/server, cot as Cause of Transmission type (1,7,9), and fun as Function type (t(z), I>>, %IL), And defined as bellow:

CS103_ASDU CS103_ASDU_create_GroupAlarm(CS103_ASDU asdu, int ca, int cot, int fun, CS103_DoublePoint dp, int sin, CP32Time2a timeTag);

Semantics of Function Type (FUN)

128 = Distance Protection t(z)
160 = Overcurrent Protection I>>
176 = Transformer Differential Protection %IT
192 = Line Differential Protection %IL
254 = Generic Function Type GEN
255 = Global Function Type GLB

Cause of Transmission (COT)

1 = CS103_COT_SPONTANEOUS
2 = CS103_COT_CYCLIC
3 = CS103_COT_RESET_FCB
4 = CS103_COT_RESET_CU
5 = CS103_COT_START_RESTART
6 = CS103_COT_POWER_ON
7 = CS103_COT_TEST_MODE
8 = CS103_COT_TIME_SYNC
9 = CS103_COT_INITIATION_OF_GI
10 = CS103_COT_TERMINATION_OF_GI
11 = CS103_COT_LOCAL_OPERATION
12 = CS103_COT_REMOTE_OPERATION
20 = CS103_COT_POS_ACK_COMMAND
21 = CS103_COT_NEG_ACK_COMMAND
31 = CS103_COT_TRANSMISSION_OF_DISTURBANCE_DATA
40 = CS103_COT_POS_ACK_GENERIC_WRITE
41 = CS103_COT_NEG_ACK_GENERIC_WRITE
42 = CS103_COT_VALID_DATA_FOR_GENERIC_READ
43 = CS103_COT_INVALID_DATA_FOR_GENERIC_READ
44 = CS103_COT_GENERIC_WRITE_CONFIRM

Information Elements Types (IE)

1 = CS103_ACTUAL_CHANNEL_INFORMATION 2 = CS103_DOUBLE_POINT_INFORMATION 3 = CS103_DOUBLE_COMMAND 4 = CS103_STATUS_OF_FAULT 5 = CS103_MEASURAND_WITH_QUALITY 6 = CS103_ASCII_CHARACTER 7 = CS103_COMPATIBILITY_LEVEL 8 = CS103_FAULT_NUMBER 9 = CS103_INTERVAL_INFORMATION_ELEMENTS 10 = CS103_NUMBER_FIRST_ELEMENT 11 = CS103_NUMBER_OF_CHANNELS 12 = CS103_NUMBER_OF_INFO_ELEMENTS 13 = CS103_NUMBER_GRID_FAULTS 14 = CS103_NUMBER_OF_TAGS 15 = CS103_NUMBER_DIST_VALUES 17 = CS103_RELATIVE_TIME 18 = CS103_REFERENCE_FACTOR 19 = CS103_RATED_PRIMARY_VALUE 20 = CS103_RATED_SECONDARY_VALUE 21 = CS103_RETURN_INFORMATION_IDENTIFIER 22 = CS103_SHORT_CIRCUIT_LOCATION 23 = CS103_SCAN_NUMBER 24 = CS103_SUPPLEMENTARY_INFORMATION 25 = CS103_TAG_POSITION 26 = CS103_TYPE_OF_ORDER 27 = CS103_TYPE_OF_DISTURBANCE_VALUES 28 = CS103_NUMBER_OF_GENERIC_DATA_SETS 29 = CS103_GENERIC_IDENTIFICATION_NUMBER 30 = CS103_GENERIC_DATA_DESCRIPTION 31 = CS103_KIND_OF_DESCRIPTION 32 = CS103_NUMBER_OF_DESCRIPTIVE_ELEMENTS 33 = CS103_GENERIC_REPLY_CODE 34 = CS103_NUMBER_OF_GENERIC_IDENTIFICATIONS 35 = CS103_SINGLE_DISTURBANCE_VALUES

CS103 (serial) slave configuration and setup

Similar to the master side the CS103 slave side can also be configured for one link layer mode (unbalanced). A CS103 slave is represented by a CS103_SLave object.

Before a CS103_Slave object can be created a SerialPort object is required. The SerialPort object represents the serial interface and its configuration.

SerialPort port = SerialPort_create(serialPort, 9600, 8, 'E', 1);
The created _SerialPort_ object is required for the _CS103_Slave_create_ function:
CS103_Slave slave = CS103_Slave_create(port);

This function has the following signature:

CS103_Slave
CS103_Slave_create(SerialPort serialPort)

For the serial slave it is also required to set a link layer address:

CS103_Slave_setLinkLayerAddress(slave, 1);
Setting some callback functions for the CS103 slave
/* set the callback handler */
CS103_Slave_setCallbacks(CS103_Slave self, CS103_IApplicationCallbacks callbacks, void* callbacksParameter);

/* set the callback handler for the identification info */
CS103_Slave_setIdentificationInfo(CS103_Slave self, uint8_t col, const char* asc, const uint8_t* internalId);

/* set the callback handler for the ASDU Received Handler */
callbacks.ASDUReceiveHandler = ASDUReceiveHandler;

/* set the callback handler for time synchronization */
callbacks.TimeSyncHandler = TimeSyncHandler;

/* set the callback handler for General Interogation Initiation */
callbacks.StartedGI = StartedGI;

/* set the callback handler for next general interrogation data */
callbacks.GetNextGIData = GetNextGIData;

Spontaneous transmission of messages

For spontaneous message transmission on the server/slave side the API user has to allocate a CS103_ASDU object that represents a single ASDU, add Information Objects to the ASDU, and finally put the ASDU into the transmission queue. The transmission queue is a FIFO (first in first out) list. If the queue is full the oldest message will be deleted and replaced by the newly added message. Messages will only be sent if the there is an active client connection or working link layer connection. Otherwise the messages will remain in the queue until a connection is activated.

The following steps have to be done to send spontaneous message:

  1. Step: Create a new CS103_ASDU instance (use CS103_COT_SPONTANEOUS for spontaneous data)

    CS103_ASDU newAsdu = CS103_ASDU_create(false, CS103_COT_SPONTANEOUS cot, 1);
  2. Step: Create a new information object instance containing the data to send

    CS103_InformationObject io = (CS103_InformationObject)CS103_IdentificationMessage_create(NULL, 255, 1);
  3. Step: Add the new information object to the ASDU

    CS103_ASDU_addInformationObject(newAsdu, io);
  4. Step: Release the information object memory

    CS103_InformationObject_destroy(io);
  5. Step: Release the ASDU memory

    CS103_ASDU_destroy(newAsdu);

lib60870-C specific topics

Big endian platforms

The library contains a C header file to determine the platform byte order (src/inc/internal/platform_endian.h) when using the GCC compiler. This depends on defines that are provided by the C compiler. On some older big endian platforms like PowerPC or Coldfire depending on the compiler this may fail. You may have to define

PLATFORM_IS_BIGENDIAN 1

when compiling the library code.

E.g. put

-DPLATFORM_IS_BIGENDIAN=1

on the GCC command line when the platform byte order is big endian.

Configuration options at library compile time

Some configuration options are fixed at compile time of the library code. These options can be found in the file lib60870_config.h.

Reference information

Supported message types

The library supports the following ASDU (application service data unit) types.

Table 2. IEC 60870-5-103 message types
Message type Description C C#

CS103_ASDU_TIME_TAGGED

TYPE IDENTIFICATION 1: Time-tagged message

+

-

CS103_ASDU_TIME_TAGGED_REL_TIME

TYPE IDENTIFICATION 2: Time-tagged message with relative time

+

-

CS103_ASDU_MEASURANDS_1

TYPE IDENTIFICATION 3: Measurands I

+

-

CS103_ASDU_TIME_TAGGED_MEASURANDS_REL_TIME

TYPE IDENTIFICATION 4: Time-tagged measurands with relative time

+

-

CS103_ASDU_IDENTIFICATION

TYPE IDENTIFICATION 5: Identification message

+

-

CS103_ASDU_TIME_SYNC

TYPE IDENTIFICATION 6: Time synchronization

+

-

CS103_ASDU_INIT_GI

TYPE IDENTIFICATION 7: Initiation of general interrogation

+

-

CS103_ASDU_INIT_TERMINATION

TYPE IDENTIFICATION 8: Termination of general interrogation

+

-

CS103_ASDU_MEASURANDS_2

TYPE IDENTIFICATION 9: Measurands II

+

-

CS103_ASDU_LIST_OF_RECORDED_DISTURBANCES

TYPE IDENTIFICATION 23: List of recorded disturbances

+

-

CS103_ASDU_DISTURBANCE_DATA_READY

TYPE IDENTIFICATION 26: Ready for transmission of disturbance data

+

-

CS103_ASDU_CHANNEL_TRANSMISSION_READY

TYPE IDENTIFICATION 27: Ready for transmission of a channel

+

-

CS103_ASDU_TAGS_READY

TYPE IDENTIFICATION 28: Ready for transmission of tags

+

-

CS103_ASDU_TRANSMISSION_OF_TAGS

TYPE IDENTIFICATION 29: Transmission of tags

+

-

CS103_ASDU_TRANSMISSION_OF_DIST_VALUES

TYPE IDENTIFICATION 30: Transmission of disturbance values

+

-

CS103_ASDU_END_OF_TRANSMISSION

TYPE IDENTIFICATION 31: End of transmission

+

-

CS103_ASDU_ORDER_FOR_DIST_DATA_TRANSMISSION

TYPE IDENTIFICATION 24: Order for disturbance data transmission

+

-

CS103_ASDU_ACK_FOR_DIST_DATA_TRANSMISSION

TYPE IDENTIFICATION 25: Acknowledgement for disturbance data transmission

+

-

CS103_ASDU_GENERAL_COMMAND

TYPE IDENTIFICATION 20: General command

+

-