diff --git a/CHANGELOG b/CHANGELOG
index d3390515..d152b05a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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
------------------------
diff --git a/examples/server_example_basic_io/server_example_basic_io.c b/examples/server_example_basic_io/server_example_basic_io.c
index 14c44e32..218a7466 100644
--- a/examples/server_example_basic_io/server_example_basic_io.c
+++ b/examples/server_example_basic_io/server_example_basic_io.c
@@ -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)) {
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 81fbd3cc..03d77fab 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -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
diff --git a/src/common/inc/libiec61850_platform_includes.h b/src/common/inc/libiec61850_platform_includes.h
index 5ca0f523..d25ac59c 100644
--- a/src/common/inc/libiec61850_platform_includes.h
+++ b/src/common/inc/libiec61850_platform_includes.h
@@ -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"
diff --git a/src/iec61850/inc/iec61850_common.h b/src/iec61850/inc/iec61850_common.h
index 5b5a14e4..d8de6a3e 100644
--- a/src/iec61850/inc/iec61850_common.h
+++ b/src/iec61850/inc/iec61850_common.h
@@ -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);
-
/** @} */
/**@}*/
diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h
index eadafaef..30f57201 100644
--- a/src/iec61850/inc/iec61850_server.h
+++ b/src/iec61850/inc/iec61850_server.h
@@ -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)
*
diff --git a/src/iec61850/inc_private/ied_server_private.h b/src/iec61850/inc_private/ied_server_private.h
index a6308267..d78702cc 100644
--- a/src/iec61850/inc_private/ied_server_private.h
+++ b/src/iec61850/inc_private/ied_server_private.h
@@ -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.
*
diff --git a/src/iec61850/inc_private/mms_mapping.h b/src/iec61850/inc_private/mms_mapping.h
index ec6240ad..5c033535 100644
--- a/src/iec61850/inc_private/mms_mapping.h
+++ b/src/iec61850/inc_private/mms_mapping.h
@@ -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);
diff --git a/src/iec61850/inc_private/reporting.h b/src/iec61850/inc_private/reporting.h
index dce535a4..2dddb257 100644
--- a/src/iec61850/inc_private/reporting.h
+++ b/src/iec61850/inc_private/reporting.h
@@ -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);
diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c
index c219b9a0..28081980 100644
--- a/src/iec61850/server/impl/ied_server.c
+++ b/src/iec61850/server/impl/ied_server.c
@@ -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
diff --git a/src/iec61850/server/impl/ied_server_config.c b/src/iec61850/server/impl/ied_server_config.c
new file mode 100644
index 00000000..4f0f5072
--- /dev/null
+++ b/src/iec61850/server/impl/ied_server_config.c
@@ -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 .
+ *
+ * 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;
+}
diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c
index 7cf2225b..957c3429 100644
--- a/src/iec61850/server/mms_mapping/mms_mapping.c
+++ b/src/iec61850/server/mms_mapping/mms_mapping.c
@@ -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)
{
diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c
index 642d06fc..5edf1504 100644
--- a/src/iec61850/server/mms_mapping/reporting.c
+++ b/src/iec61850/server/mms_mapping/reporting.c
@@ -35,6 +35,7 @@
#include "mms_value_internal.h"
#include "conversions.h"
#include "reporting.h"
+#include "ied_server_private.h"
#include
#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;
diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def
index f6c247ea..7c866d42 100644
--- a/src/vs/libiec61850-wo-goose.def
+++ b/src/vs/libiec61850-wo-goose.def
@@ -580,4 +580,9 @@ EXPORTS
CDC_VSS_create
CDC_VSG_create
Timestamp_createFromByteArray
- IedModel_getDeviceByIndex
\ No newline at end of file
+ IedModel_getDeviceByIndex
+ IedServerConfig_create
+ IedServerConfig_destroy
+ IedServerConfig_setReportBufferSize
+ IedServerConfig_getReportBufferSize
+ IedServer_createWithConfig
\ No newline at end of file
diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def
index 6ba5d303..c9190c50 100644
--- a/src/vs/libiec61850.def
+++ b/src/vs/libiec61850.def
@@ -707,4 +707,9 @@ EXPORTS
SVPublisher_ASDU_setQuality
Timestamp_createFromByteArray
IedModel_getDeviceByIndex
- SVReceiver_enableDestAddrCheck
\ No newline at end of file
+ SVReceiver_enableDestAddrCheck
+ IedServerConfig_create
+ IedServerConfig_destroy
+ IedServerConfig_setReportBufferSize
+ IedServerConfig_getReportBufferSize
+ IedServer_createWithConfig
\ No newline at end of file