- IEC 61850 server: added support to configure report buffer at runtime

- IEC 61850 server: new IedServerConfig type and new IedServer constructor
pull/68/head
Michael Zillgith 7 years ago
parent fe4ae3f38f
commit 7cb5ff670a

@ -1,3 +1,9 @@
Changes to version 1.2.2
------------------------
- IEC 61850 server: added support to configure report buffer at runtime
- IEC 61850 server: new IedServerConfig type and new IedServer constructor
Changes to version 1.2.1
------------------------

@ -83,7 +83,17 @@ main(int argc, char** argv)
{
printf("Using libIEC61850 version %s\n", LibIEC61850_getVersionString());
iedServer = IedServer_create(&iedModel);
/* Create new server configuration object */
IedServerConfig config = IedServerConfig_create();
/* Set buffer size for buffered report control blocks to 200000 bytes */
IedServerConfig_setReportBufferSize(config, 200000);
/* Create a new IEC 61850 server instance */
iedServer = IedServer_createWithConfig(&iedModel, NULL, config);
/* configuration object is no longer required */
IedServerConfig_destroy(config);
/* Set the base path for the MMS file services */
MmsServer mmsServer = IedServer_getMmsServer(iedServer);
@ -108,7 +118,7 @@ main(int argc, char** argv)
IedServer_setConnectionIndicationHandler(iedServer, (IedConnectionIndicationHandler) connectionHandler, NULL);
/* MMS server will be instructed to start listening to client connections. */
/* MMS server will be instructed to start listening for client connections. */
IedServer_start(iedServer, 102);
if (!IedServer_isRunning(iedServer)) {

@ -66,6 +66,7 @@ set (lib_common_SRCS
./iec61850/client/ied_connection.c
./iec61850/common/iec61850_common.c
./iec61850/server/impl/ied_server.c
./iec61850/server/impl/ied_server_config.c
./iec61850/server/impl/client_connection.c
./iec61850/server/model/model.c
./iec61850/server/model/dynamic_model.c

@ -15,7 +15,7 @@
#include "platform_endian.h"
#define LIBIEC61850_VERSION "1.2.1"
#define LIBIEC61850_VERSION "1.2.2"
#ifndef CONFIG_DEFAULT_MMS_VENDOR_NAME
#define CONFIG_DEFAULT_MMS_VENDOR_NAME "libiec61850.com"

@ -421,12 +421,11 @@ Timestamp_toMmsValue(Timestamp* self, MmsValue* mmsValue);
/**
* \brief Get the version of the library as string
*
* \return the version of the library (e.g. "0.8.3")
* \return the version of the library (e.g. "1.2.2")
*/
char*
LibIEC61850_getVersionString(void);
/** @} */
/**@}*/

@ -3,7 +3,7 @@
*
* IEC 61850 server API for libiec61850.
*
* Copyright 2013, 2014 Michael Zillgith
* Copyright 2013-2018 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -41,6 +41,49 @@ extern "C" {
#include "hal_filesystem.h"
#include "iec61850_config_file_parser.h"
/**
* \brief Configuration object to configure IEC 61850 stack features
*/
typedef struct sIedServerConfig* IedServerConfig;
struct sIedServerConfig
{
/** size of the report buffer associated with a buffered report control block */
int reportBufferSize;
};
/**
* \brief Create a new configuration object
*
* \return a new configuration object with default configuration values
*/
IedServerConfig
IedServerConfig_create(void);
/**
* \brief Destroy the configuration object
*/
void
IedServerConfig_destroy(IedServerConfig self);
/**
* \brief Set the report buffer size for buffered reporting
*
* \param reportBufferSize the buffer size for each buffered report control block
*/
void
IedServerConfig_setReportBufferSize(IedServerConfig self, int reportBufferSize);
/**
* \brief Gets the report buffer size for buffered reporting
*
* \return the buffer size for each buffered report control block
*/
int
IedServerConfig_getReportBufferSize(IedServerConfig self);
/**
* An opaque handle for an IED server instance
*/
@ -79,6 +122,16 @@ IedServer_create(IedModel* dataModel);
IedServer
IedServer_createWithTlsSupport(IedModel* dataModel, TLSConfiguration tlsConfiguration);
/**
* \brief Create new new IedServer with extended configurations parameters
*
* \param dataModel reference to the IedModel data structure to be used as IEC 61850 data model of the device
* \param tlsConfiguration TLS configuration object, or NULL to not use TLS
* \param serverConfiguration IED server configuration object for advanced server configuration
*/
IedServer
IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguration, IedServerConfig serverConfiguration);
/**
* \brief Destroy an IedServer instance and release all resources (memory, TCP sockets)
*

@ -3,7 +3,7 @@
*
* Library private function definitions for IedServer.
*
* Copyright 2013 Michael Zillgith
* Copyright 2013-2018 Michael Zillgith
*
* This file is part of libIEC61850.
*

@ -1,7 +1,7 @@
/*
* mms_mapping.h
*
* Copyright 2013-2016 Michael Zillgith
* Copyright 2013-2018 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -46,7 +46,7 @@ typedef enum {
typedef struct sMmsMapping MmsMapping;
MmsMapping*
MmsMapping_create(IedModel* model);
MmsMapping_create(IedModel* model, IedServer iedServer);
MmsDevice*
MmsMapping_getMmsDeviceModel(MmsMapping* mapping);
@ -138,9 +138,6 @@ MmsMapping_ObjectReferenceToVariableAccessSpec(char* objectReference);
char*
MmsMapping_varAccessSpecToObjectReference(MmsVariableAccessSpecification* varAccessSpec);
void
MmsMapping_setIedServer(MmsMapping* self, IedServer iedServer);
void
MmsMapping_setConnectionIndicationHandler(MmsMapping* self, IedConnectionIndicationHandler handler, void* parameter);

@ -97,7 +97,7 @@ typedef struct {
} ReportControl;
ReportControl*
ReportControl_create(bool buffered, LogicalNode* parentLN);
ReportControl_create(bool buffered, LogicalNode* parentLN, int reportBufferSize);
void
ReportControl_destroy(ReportControl* self);

@ -391,8 +391,9 @@ updateDataSetsWithCachedValues(IedServer self)
}
}
IedServer
IedServer_createWithTlsSupport(IedModel* dataModel, TLSConfiguration tlsConfiguration)
IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguration, IedServerConfig serverConfiguration)
{
IedServer self = (IedServer) GLOBAL_CALLOC(1, sizeof(struct sIedServer));
@ -407,7 +408,14 @@ IedServer_createWithTlsSupport(IedModel* dataModel, TLSConfiguration tlsConfigur
self->dataModelLock = Semaphore_create(1);
#endif
self->mmsMapping = MmsMapping_create(dataModel);
#if (CONFIG_IEC61850_REPORT_SERVICE == 1)
if (serverConfiguration)
self->reportBufferSize = serverConfiguration->reportBufferSize;
else
self->reportBufferSize = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE;
#endif
self->mmsMapping = MmsMapping_create(dataModel, self);
self->mmsDevice = MmsMapping_getMmsDeviceModel(self->mmsMapping);
@ -417,8 +425,6 @@ IedServer_createWithTlsSupport(IedModel* dataModel, TLSConfiguration tlsConfigur
MmsMapping_installHandlers(self->mmsMapping);
MmsMapping_setIedServer(self->mmsMapping, self);
createMmsServerCache(self);
dataModel->initializer();
@ -447,7 +453,13 @@ IedServer_createWithTlsSupport(IedModel* dataModel, TLSConfiguration tlsConfigur
IedServer
IedServer_create(IedModel* dataModel)
{
return IedServer_createWithTlsSupport(dataModel, NULL);
return IedServer_createWithConfig(dataModel, NULL, NULL);
}
IedServer
IedServer_createWithTlsSupport(IedModel* dataModel, TLSConfiguration tlsConfiguration)
{
return IedServer_createWithConfig(dataModel, tlsConfiguration, NULL);
}
void

@ -0,0 +1,55 @@
/*
* ied_server_config.c
*
* Copyright 2018 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
#include "iec61850_server.h"
#include "libiec61850_platform_includes.h"
IedServerConfig
IedServerConfig_create()
{
IedServerConfig self = (IedServerConfig) GLOBAL_MALLOC(sizeof(struct sIedServerConfig));
if (self) {
self->reportBufferSize = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE;
}
return self;
}
void
IedServerConfig_destroy(IedServerConfig self)
{
GLOBAL_FREEMEM(self);
}
void
IedServerConfig_setReportBufferSize(IedServerConfig self, int reportBufferSize)
{
self->reportBufferSize = reportBufferSize;
}
int
IedServerConfig_getReportBufferSize(IedServerConfig self)
{
return self->reportBufferSize;
}

@ -1272,11 +1272,12 @@ createMmsModelFromIedModel(MmsMapping* self, IedModel* iedModel)
}
MmsMapping*
MmsMapping_create(IedModel* model)
MmsMapping_create(IedModel* model, IedServer iedServer)
{
MmsMapping* self = (MmsMapping*) GLOBAL_CALLOC(1, sizeof(struct sMmsMapping));
self->model = model;
self->iedServer = iedServer;
#if (CONFIG_IEC61850_REPORT_SERVICE == 1)
self->reportControls = LinkedList_create();
@ -2564,12 +2565,6 @@ MmsMapping_installHandlers(MmsMapping* self)
MmsServer_installVariableListChangedHandler(self->mmsServer, variableListChangedHandler, (void*) self);
}
void
MmsMapping_setIedServer(MmsMapping* self, IedServer iedServer)
{
self->iedServer = iedServer;
}
void
MmsMapping_setConnectionIndicationHandler(MmsMapping* self, IedConnectionIndicationHandler handler, void* parameter)
{

@ -35,6 +35,7 @@
#include "mms_value_internal.h"
#include "conversions.h"
#include "reporting.h"
#include "ied_server_private.h"
#include <string.h>
#ifndef DEBUG_IED_SERVER
@ -62,16 +63,25 @@
static ReportBuffer*
ReportBuffer_create(void)
ReportBuffer_create(int bufferSize)
{
ReportBuffer* self = (ReportBuffer*) GLOBAL_MALLOC(sizeof(ReportBuffer));
self->lastEnqueuedReport = NULL;
self->oldestReport = NULL;
self->nextToTransmit = NULL;
self->memoryBlockSize = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE;
self->memoryBlock = (uint8_t*) GLOBAL_MALLOC(self->memoryBlockSize);
self->reportsCount = 0;
self->isOverflow = true;
if (self) {
self->lastEnqueuedReport = NULL;
self->oldestReport = NULL;
self->nextToTransmit = NULL;
self->reportsCount = 0;
self->isOverflow = true;
self->memoryBlockSize = bufferSize;
self->memoryBlock = (uint8_t*) GLOBAL_MALLOC(self->memoryBlockSize);
if (self->memoryBlock == NULL) {
GLOBAL_FREEMEM(self);
self = NULL;
}
}
return self;
}
@ -84,7 +94,7 @@ ReportBuffer_destroy(ReportBuffer* self)
}
ReportControl*
ReportControl_create(bool buffered, LogicalNode* parentLN)
ReportControl_create(bool buffered, LogicalNode* parentLN, int reportBufferSize)
{
ReportControl* self = (ReportControl*) GLOBAL_MALLOC(sizeof(ReportControl));
self->name = NULL;
@ -120,7 +130,7 @@ ReportControl_create(bool buffered, LogicalNode* parentLN)
self->lastEntryId = 0;
if (buffered) {
self->reportBuffer = ReportBuffer_create();
self->reportBuffer = ReportBuffer_create(reportBufferSize);
}
return self;
@ -1156,7 +1166,7 @@ Reporting_createMmsBufferedRCBs(MmsMapping* self, MmsDomain* domain,
int currentReport = 0;
while (currentReport < reportsCount) {
ReportControl* rc = ReportControl_create(true, logicalNode);
ReportControl* rc = ReportControl_create(true, logicalNode, self->iedServer->reportBufferSize);
rc->domain = domain;
@ -1193,7 +1203,7 @@ Reporting_createMmsUnbufferedRCBs(MmsMapping* self, MmsDomain* domain,
int currentReport = 0;
while (currentReport < reportsCount) {
ReportControl* rc = ReportControl_create(false, logicalNode);
ReportControl* rc = ReportControl_create(false, logicalNode, self->iedServer->reportBufferSize);
rc->domain = domain;

@ -580,4 +580,9 @@ EXPORTS
CDC_VSS_create
CDC_VSG_create
Timestamp_createFromByteArray
IedModel_getDeviceByIndex
IedModel_getDeviceByIndex
IedServerConfig_create
IedServerConfig_destroy
IedServerConfig_setReportBufferSize
IedServerConfig_getReportBufferSize
IedServer_createWithConfig

@ -707,4 +707,9 @@ EXPORTS
SVPublisher_ASDU_setQuality
Timestamp_createFromByteArray
IedModel_getDeviceByIndex
SVReceiver_enableDestAddrCheck
SVReceiver_enableDestAddrCheck
IedServerConfig_create
IedServerConfig_destroy
IedServerConfig_setReportBufferSize
IedServerConfig_getReportBufferSize
IedServer_createWithConfig
Loading…
Cancel
Save