diff --git a/config/stack_config.h b/config/stack_config.h
index 4cac7cfd..a3c419df 100644
--- a/config/stack_config.h
+++ b/config/stack_config.h
@@ -51,7 +51,7 @@
#define CONFIG_MMS_THREADLESS_STACK 0
/* number of concurrent MMS client connections the server accepts, -1 for no limit */
-#define CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS 5
+#define CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS 100
/* activate TCP keep alive mechanism. 1 -> activate */
#define CONFIG_ACTIVATE_TCP_KEEPALIVE 1
diff --git a/dotnet/IEC61850forCSharp/IedServerConfig.cs b/dotnet/IEC61850forCSharp/IedServerConfig.cs
index 9f1d7bde..586f547b 100644
--- a/dotnet/IEC61850forCSharp/IedServerConfig.cs
+++ b/dotnet/IEC61850forCSharp/IedServerConfig.cs
@@ -56,6 +56,19 @@ namespace IEC61850.Server
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern byte IedServerConfig_getEdition(IntPtr self);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedServerConfig_setMaxMmsConnections(IntPtr self, int maxConnections);
+
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern int IedServerConfig_getMaxMmsConnections(IntPtr self);
+
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
+ static extern bool IedServerConfig_isDynamicDataSetServiceEnabled(IntPtr self);
+
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void IedServerConfig_enableDynamicDataSetService(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool enable);
+
internal IntPtr self;
public IedServerConfig ()
@@ -91,6 +104,10 @@ namespace IEC61850.Server
}
}
+ ///
+ /// Gets or sets the edition of the IEC 61850 standard to use
+ ///
+ /// The IEC 61850 edition to use.
public Iec61850Edition Edition
{
get {
@@ -101,6 +118,30 @@ namespace IEC61850.Server
}
}
+ ///
+ /// Gets or sets maximum number of MMS clients
+ ///
+ /// The max number of MMS client connections.
+ public int MaxMmsConnections
+ {
+ get {
+ return IedServerConfig_getMaxMmsConnections (self);
+ }
+ set {
+ IedServerConfig_setMaxMmsConnections (self, value);
+ }
+ }
+
+ public bool DynamicDataSetServiceEnabled
+ {
+ get {
+ return IedServerConfig_isDynamicDataSetServiceEnabled (self);
+ }
+ set {
+ IedServerConfig_enableDynamicDataSetService (self, value);
+ }
+ }
+
///
/// Releases all resource used by the object.
///
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 55e789ec..1f928531 100644
--- a/examples/server_example_basic_io/server_example_basic_io.c
+++ b/examples/server_example_basic_io/server_example_basic_io.c
@@ -90,6 +90,7 @@ main(int argc, char** argv)
/* Set buffer size for buffered report control blocks to 200000 bytes */
IedServerConfig_setReportBufferSize(config, 200000);
+ /* Set stack compliance to a specific edition of the standard (WARNING: data model has also to be checked for compliance) */
IedServerConfig_setEdition(config, IEC_61850_EDITION_2);
/* Set the base path for the MMS file services */
@@ -103,6 +104,9 @@ main(int argc, char** argv)
IedServerConfig_enableLogService(config, true);
+ /* set maximum number of clients */
+ IedServerConfig_setMaxMmsConnections(config, 2);
+
/* Create a new IEC 61850 server instance */
iedServer = IedServer_createWithConfig(&iedModel, NULL, config);
@@ -132,7 +136,7 @@ main(int argc, char** argv)
IedServer_start(iedServer, 102);
if (!IedServer_isRunning(iedServer)) {
- printf("Starting server failed! Exit.\n");
+ printf("Starting server failed (maybe need root permissions or another server is already using the port)! Exit.\n");
IedServer_destroy(iedServer);
exit(-1);
}
diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h
index 8f6cabce..bffed036 100644
--- a/src/iec61850/inc/iec61850_server.h
+++ b/src/iec61850/inc/iec61850_server.h
@@ -65,6 +65,9 @@ struct sIedServerConfig
/** IEC 61850 edition (0 = edition 1, 1 = edition 2, 2 = edition 2.1, ...) */
uint8_t edition;
+
+ /** maximum number of MMS (TCP) connections */
+ int maxMmsConnections;
};
/**
@@ -113,9 +116,22 @@ IedServerConfig_setReportBufferSize(IedServerConfig self, int reportBufferSize);
int
IedServerConfig_getReportBufferSize(IedServerConfig self);
+/**
+ * \brief Set the maximum number of MMS (TCP) connections the server accepts
+ *
+ * NOTE: Parameter has to be smaller than CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS if
+ * CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1
+ *
+ * \param maxConnection maximum number of TCP connections
+ */
void
IedServerConfig_setMaxMmsConnections(IedServerConfig self, int maxConnections);
+/**
+ * \brief Get the maximum number of MMS (TCP) connections the server accepts
+ *
+ * \return maximum number of TCP connections
+ */
int
IedServerConfig_getMaxMmsConnections(IedServerConfig self);
@@ -150,10 +166,10 @@ bool
IedServerConfig_isFileServiceEnabled(IedServerConfig self);
void
-IedServerConfig_enableFileWriteService(IedServerConfig self, bool enable);
+IedServerConfig_enableSetFileService(IedServerConfig self, bool enable);
bool
-IedServerConfig_isFileWriteServiceEnabled(IedServerConfig self);
+IedServerConfig_isSetFileServiceEnabled(IedServerConfig self);
/**
* \brief Enable/disable the dynamic data set service for MMS
diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c
index d33a1e43..a1a351b6 100644
--- a/src/iec61850/server/impl/ied_server.c
+++ b/src/iec61850/server/impl/ied_server.c
@@ -439,6 +439,7 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio
MmsServer_enableDynamicNamedVariableListService(self->mmsServer, serverConfiguration->enableDynamicDataSetService);
MmsServer_enableJournalService(self->mmsServer, serverConfiguration->enableLogService);
MmsServer_setFilestoreBasepath(self->mmsServer, serverConfiguration->fileServiceBasepath);
+ MmsServer_setMaxConnections(self->mmsServer, serverConfiguration->maxMmsConnections);
}
#endif
diff --git a/src/iec61850/server/impl/ied_server_config.c b/src/iec61850/server/impl/ied_server_config.c
index 6712c0b9..cc01c773 100644
--- a/src/iec61850/server/impl/ied_server_config.c
+++ b/src/iec61850/server/impl/ied_server_config.c
@@ -125,3 +125,15 @@ IedServerConfig_isLogServiceEnabled(IedServerConfig self)
{
return self->enableLogService;
}
+
+void
+IedServerConfig_setMaxMmsConnections(IedServerConfig self, int maxConnections)
+{
+ self->maxMmsConnections = maxConnections;
+}
+
+int
+IedServerConfig_getMaxMmsConnections(IedServerConfig self)
+{
+ return self->maxMmsConnections;
+}
diff --git a/src/mms/inc/iso_server.h b/src/mms/inc/iso_server.h
index a5da6495..849df2cf 100644
--- a/src/mms/inc/iso_server.h
+++ b/src/mms/inc/iso_server.h
@@ -94,6 +94,9 @@ IsoServer_create(TLSConfiguration tlsConfiguration);
void
IsoServer_setTcpPort(IsoServer self, int port);
+void
+IsoServer_setMaxConnections(IsoServer self, int maxConnections);
+
void
IsoServer_setLocalIpAddress(IsoServer self, const char* ipAddress);
diff --git a/src/mms/inc/mms_server.h b/src/mms/inc/mms_server.h
index 5d6cd93b..1780bc39 100644
--- a/src/mms/inc/mms_server.h
+++ b/src/mms/inc/mms_server.h
@@ -225,6 +225,14 @@ MmsServer_installFileAccessHandler(MmsServer self, MmsFileAccessHandler handler,
void
MmsServer_setFilestoreBasepath(MmsServer self, const char* basepath);
+/**
+ * \brief Set the maximum number of TCP client connections
+ *
+ * \param[in] maxConnections the maximum number of TCP client connections to accept
+ */
+void
+MmsServer_setMaxConnections(MmsServer self, int maxConnections);
+
/**
* \brief Enable/disable MMS file services at runtime
*
diff --git a/src/mms/inc_private/mms_server_internal.h b/src/mms/inc_private/mms_server_internal.h
index 37cffb35..62ea4061 100644
--- a/src/mms/inc_private/mms_server_internal.h
+++ b/src/mms/inc_private/mms_server_internal.h
@@ -165,6 +165,7 @@ struct sMmsServer {
#endif
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
+ int maxConnections;
bool fileServiceEnabled;
bool dynamicVariableListServiceEnabled;
bool journalServiceEnabled;
diff --git a/src/mms/iso_mms/server/mms_server.c b/src/mms/iso_mms/server/mms_server.c
index 2352926d..5cf57390 100644
--- a/src/mms/iso_mms/server/mms_server.c
+++ b/src/mms/iso_mms/server/mms_server.c
@@ -107,6 +107,12 @@ MmsServer_setFilestoreBasepath(MmsServer self, const char* basepath)
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
+void
+MmsServer_setMaxConnections(MmsServer self, int maxConnections)
+{
+ IsoServer_setMaxConnections(self->isoServer, maxConnections);
+}
+
void
MmsServer_enableFileService(MmsServer self, bool enable)
{
diff --git a/src/mms/iso_server/iso_server.c b/src/mms/iso_server/iso_server.c
index f36af1dd..fe855496 100644
--- a/src/mms/iso_server/iso_server.c
+++ b/src/mms/iso_server/iso_server.c
@@ -72,10 +72,14 @@ struct sIsoServer {
TLSConfiguration tlsConfiguration;
+#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
+ int maxConnections;
+#endif
+
#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1)
LinkedList openClientConnections;
#else
- IsoConnection* openClientConnections;
+ IsoConnection openClientConnections[CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS];
#endif /* (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) */
#if (CONFIG_MMS_THREADLESS_STACK != 1)
@@ -355,11 +359,6 @@ setupIsoServer(IsoServer self)
setState(self, ISO_SVR_STATE_RUNNING);
-#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1)
- if (DEBUG_ISO_SERVER)
- printf("ISO_SERVER: server is limited to %i client connections.\n", (int) CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS);
-#endif
-
exit_function:
return success;
}
@@ -374,6 +373,17 @@ handleIsoConnections(IsoServer self)
if ((connectionSocket = ServerSocket_accept((ServerSocket) self->serverSocket)) != NULL) {
+#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
+ if (private_IsoServer_getConnectionCounter(self) >= self->maxConnections) {
+ if (DEBUG_ISO_SERVER)
+ printf("ISO_SERVER: maximum number of connections reached -> reject connection attempt.\n");
+
+ Socket_destroy(connectionSocket);
+
+ return;
+ }
+#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
+
#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1)
if (private_IsoServer_getConnectionCounter(self) >= CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS) {
if (DEBUG_ISO_SERVER)
@@ -416,6 +426,17 @@ handleIsoConnectionsThreadless(IsoServer self)
if ((connectionSocket = ServerSocket_accept((ServerSocket) self->serverSocket)) != NULL) {
+#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
+ if (private_IsoServer_getConnectionCounter(self) >= self->maxConnections) {
+ if (DEBUG_ISO_SERVER)
+ printf("ISO_SERVER: maximum number of connections reached -> reject connection attempt.\n");
+
+ Socket_destroy(connectionSocket);
+
+ return;
+ }
+#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
+
#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1)
if (private_IsoServer_getConnectionCounter(self) >= CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS) {
if (DEBUG_ISO_SERVER)
@@ -499,9 +520,6 @@ IsoServer_create(TLSConfiguration tlsConfiguration)
#if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1)
self->openClientConnections = LinkedList_create();
-#else
- self->openClientConnections = (IsoConnection*)
- GLOBAL_CALLOC(CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS, sizeof(IsoConnection));
#endif
#if (CONFIG_MMS_THREADLESS_STACK != 1) && (CONFIG_MMS_SINGLE_THREADED == 0)
@@ -514,6 +532,14 @@ IsoServer_create(TLSConfiguration tlsConfiguration)
return self;
}
+#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
+void
+IsoServer_setMaxConnections(IsoServer self, int maxConnections)
+{
+ self->maxConnections = maxConnections;
+}
+#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
+
void
IsoServer_setTcpPort(IsoServer self, int port)
{
@@ -769,8 +795,6 @@ IsoServer_destroy(IsoServer self)
lockClientConnections(self);
#endif
-#else
- GLOBAL_FREEMEM(self->openClientConnections);
#endif /* (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) */
#if (CONFIG_MMS_THREADLESS_STACK != 1) && (CONFIG_MMS_SINGLE_THREADED == 0)
diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def
index 30d98eb4..27a7b3d6 100644
--- a/src/vs/libiec61850-wo-goose.def
+++ b/src/vs/libiec61850-wo-goose.def
@@ -612,3 +612,5 @@ EXPORTS
IedServerConfig_isLogServiceEnabled
IedServerConfig_setEdition
IedServerConfig_getEdition
+ IedServerConfig_setMaxMmsConnections
+ IedServerConfig_getMaxMmsConnections
diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def
index 039e5ea8..e90c3ff1 100644
--- a/src/vs/libiec61850.def
+++ b/src/vs/libiec61850.def
@@ -740,3 +740,5 @@ EXPORTS
IedServerConfig_isLogServiceEnabled
IedServerConfig_setEdition
IedServerConfig_getEdition
+ IedServerConfig_setMaxMmsConnections
+ IedServerConfig_getMaxMmsConnections