Server tutorial

Warning: the server tutorial is out-dated and will be replaced soon! Accurate examples can be found in the source distribution.

This tutorial introduces in writing your own IEC 61850/MMS server appications with libIEC61850. It will start with a very simple example and will grow to more complex examples introducing the features of the server API.

Example 1 – A simple server example

This example will show you how to create the most simple MMS application. The complete source-code of this example can be found in the examples folder of the source-code distribution.

IedServer iedServer = IedServer_create(&staticIedModel);

IedServer_setAllModelDefaultValues(iedServer);

IedServer_start(iedServer);

while (running) {
    Thread_sleep(1);
}

IedServer_stop(iedServer);

IedServer_destroy(iedServer);

The first code line creates a new IedServer object. This object is responsible for managing the complete MMS protocol stack and the IEC data model. The parameter contains the IEC model description.

Line 3 initializes the MMS server value cache with default values for the complete IEC data model. After this initialization the MMS server is able to handle client connections without invoking any user provided callback functions.

The libIEC61850 user API is designed in an object-oriented fashion. IedServer and most of the other API data types can be seen as classes that are known from other programming languages like C++ or Java. The methods to operate on the data types all start with the name of the data type followed by an underscore and the methods name (e.g. IedServer_start). The first parameter is always the reference to the data type instance to operate on.

Line 5 start the protocol stack. After invoking the IedServer_start function the server starts listening to client connections. The IedServer_start functions starts a new thread that listens for client connections. For every new client connection a dedicated thread is started to handle this connection.

Lines 7 until 9 is the main loop of the application. Here you can feed process values to the MMS server or react on client activities.

Line 11 stops the MMS server. A call to the IedServer_stop function also closes all client connections.

Line 13 does the cleanup. It frees all resources allocated by the IedServer instance.

Example 2 – Feeding process values

The following example builds upon the previous one. It will show you how to provide process values of your application to the MMS server. Values of MMS variables are represented by MmsValue objects in libIEC61850. A MmsValue instance can hold values of all MMS data types the MMS server provides.

This example is build upon the assumption that the IedServer instance handles the MmsValue by itself. In this case the values provided when a client requests them are stored internally by a data structure I call the MMS server cache. You can get access to this values by the getValue-method of IedServer.

MmsValue* totW_mag_f = IedServer_getValue(iedServer, sampleDevice,
                           "MMXU2$MX$TotW$mag$f");
MmsValue* totW_t = IedServer_getValue(iedServer, sampleDevice,
                           "MMXU2$MX$TotW$t");

while (running) {
    /* Update measurement values */
    MmsValue_setFloat(totW_mag_f, totW);
    MmsValue_setUtcTime(totW_t, time(NULL));
    MmsValue_setInt32(stVal, stVal_value);
    totW += 0.1f;
    stVal_value += 1;

    Thread_sleep(1000);
}

Example 3 – Client authentication

libIEC61850 provides support for basic client authentication. The only supported method now is password authentication. To use authentication you need to dig a bit deeper into the MMS stack. MMS uses the ACSE (Association Control Service Element) of the ISO protocol stack to initiate a new client session. ACSE is responsible for client authentication.

In libIEC61850 the complete ISO protocol stack up to the MMS layer is handled internally by an IsoServer object. To feed the ACSE layer with the required authentication parameters you first need access to the IsoServer object that is associated to the IedServer instance. This has to be done with the getIsoServer-method of IedServer. Then you can call the setAuthenticationParameter-method of IsoServer to provide the authentication information. The authentication information is provided by an AcseAuthenticationParameter data structure.

IedServer iedServer = IedServer_create(&staticIedModel);

/* Activate authentication */
AcseAuthenticationParameter auth =
    calloc(1, sizeof(struct sAcseAuthenticationParameter));
auth->mechanism = AUTH_PASSWORD;
auth->value.password.string = "testpw";

IsoServer isoServer = IedServer_getIsoServer(iedServer);
IsoServer_setAuthenticationParameter(isoServer, auth);

IedServer_start(iedServer);

In line 1 of the source-code example an instance of IedServer is created as usual.

Lines 4 to 7 allocates memory for the AcseAuthenticationParameter data structure and initializes this structure with the authentication method and the authentication value which is a string that is used as the password.

In line 9 and 10 you get access to the IsoServer instance and feed ít with the authentication parameters. This has to be done before calling the start-method of IedServer.

Example 4 – Create a data set

You can create statically configured data sets by adding a data set description to a Logical Node description in the ICD file.

Example 5 – Using callback functions

TBD …