diff --git a/dotnet/IEC61850forCSharp/IedServerConfig.cs b/dotnet/IEC61850forCSharp/IedServerConfig.cs index 586f547bd..13588af45 100644 --- a/dotnet/IEC61850forCSharp/IedServerConfig.cs +++ b/dotnet/IEC61850forCSharp/IedServerConfig.cs @@ -69,6 +69,24 @@ public class IedServerConfig : IDisposable [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] static extern void IedServerConfig_enableDynamicDataSetService(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool enable); + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern void IedServerConfig_setMaxAssociationSpecificDataSets(IntPtr self, int maxDataSets); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern int IedServerConfig_getMaxAssociationSpecificDataSets(IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern void IedServerConfig_setMaxDomainSpecificDataSets(IntPtr self, int maxDataSets); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern int IedServerConfig_getMaxDomainSpecificDataSets(IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern void IedServerConfig_setMaxDataSetEntries(IntPtr self, int maxDataSetEntries); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern int IedServerConfig_getMaxDatasSetEntries(IntPtr self); + internal IntPtr self; public IedServerConfig () @@ -132,6 +150,10 @@ public int MaxMmsConnections } } + /// + /// Enable/Disable dynamic data set service for MMS + /// + /// true if dynamic data set service enabled; otherwise, false. public bool DynamicDataSetServiceEnabled { get { @@ -142,6 +164,48 @@ public bool DynamicDataSetServiceEnabled } } + /// + /// Gets or sets the maximum number of data set entries for dynamic data sets + /// + /// The max. number data set entries. + public int MaxDataSetEntries + { + get { + return IedServerConfig_getMaxDatasSetEntries (self); + } + set { + IedServerConfig_setMaxDataSetEntries (self, value); + } + } + + /// + /// Gets or sets the maximum number of association specific (non-permanent) data sets. + /// + /// The max. number of association specific data sets. + public int MaxAssociationSpecificDataSets + { + get { + return IedServerConfig_getMaxAssociationSpecificDataSets (self); + } + set { + IedServerConfig_setMaxAssociationSpecificDataSets (self, value); + } + } + + /// + /// Gets or sets the maximum number of domain specific (permanent) data sets. + /// + /// The max. numebr of domain specific data sets. + public int MaxDomainSpecificDataSets + { + get { + return IedServerConfig_getMaxDomainSpecificDataSets (self); + } + set { + IedServerConfig_setMaxDomainSpecificDataSets (self, value); + } + } + /// /// Releases all resource used by the object. /// diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h index c0203674a..b0ad9db98 100644 --- a/src/iec61850/inc/iec61850_server.h +++ b/src/iec61850/inc/iec61850_server.h @@ -60,6 +60,12 @@ struct sIedServerConfig /** when true (default) enable dynamic data set services for MMS */ bool enableDynamicDataSetService; + /** the maximum number of allowed association specific data sets */ + int maxAssociationSpecificDataSets; + + /** the maximum number of allowed domain specific data sets */ + int maxDomainSpecificDataSets; + /** maximum number of data set entries of dynamic data sets */ int maxDataSetEntries; @@ -141,6 +147,8 @@ IedServerConfig_getMaxMmsConnections(IedServerConfig self); /** * \brief Set the basepath of the file services * + * NOTE: the basepath specifies the local directory that is served by MMS file services + * * \param basepath new file service base path */ void @@ -168,12 +176,6 @@ IedServerConfig_enableFileService(IedServerConfig self, bool enable); bool IedServerConfig_isFileServiceEnabled(IedServerConfig self); -void -IedServerConfig_enableSetFileService(IedServerConfig self, bool enable); - -bool -IedServerConfig_isSetFileServiceEnabled(IedServerConfig self); - /** * \brief Enable/disable the dynamic data set service for MMS * @@ -190,30 +192,61 @@ IedServerConfig_enableDynamicDataSetService(IedServerConfig self, bool enable); bool IedServerConfig_isDynamicDataSetServiceEnabled(IedServerConfig self); - +/** + * \brief Set the maximum allowed number of association specific (non-permanent) data sets + * + * NOTE: This specifies the maximum number of non-permanent data sets per connection. When + * the connection is closed these data sets are deleted automatically. + * + * \param maxDataSets maximum number of allowed data sets. + */ void IedServerConfig_setMaxAssociationSpecificDataSets(IedServerConfig self, int maxDataSets); +/** + * \brief Get the maximum allowed number of association specific (non-permanent) data sets + * + * \return maximum number of allowed data sets. + */ +int +IedServerConfig_getMaxAssociationSpecificDataSets(IedServerConfig self); + +/** + * \brief Set the maximum allowed number of domain specific (permanent) data sets + * + * \param maxDataSets maximum number of allowed data sets. + */ void IedServerConfig_setMaxDomainSpecificDataSets(IedServerConfig self, int maxDataSets); /** - * \brief Set the maximum number of entries in a dynamic data set + * \brief Get the maximum allowed number of domain specific (permanent) data sets + * + * \return maximum number of allowed data sets. + */ +int +IedServerConfig_getMaxDomainSpecificDataSets(IedServerConfig self); + +/** + * \brief Set the maximum number of entries in dynamic data sets + * + * NOTE: this comprises the base data set entries (can be simple or complex variables). + * When the client tries to create a data set with more member the request will be + * rejected and the data set will not be created. * * \param maxDataSetEntries the maximum number of entries allowed in a data set */ void IedServerConfig_setMaxDataSetEntries(IedServerConfig self, int maxDataSetEntries); +/** + * \brief Get the maximum number of entries in dynamic data sets + * + * \return the maximum number of entries allowed in a data sets + */ int IedServerConfig_getMaxDatasSetEntries(IedServerConfig self); -void -IedServerConfig_enableWriteDataSetService(IedServerConfig self, bool enable); - -bool -IedServerConfig_isWriteDataSetServiceEnabled(IedServerConfig self); - /** * \brief Enable/disable the log service for MMS * diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index 4bcb12f1a..035e33256 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -437,6 +437,8 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio if (serverConfiguration) { MmsServer_enableFileService(self->mmsServer, serverConfiguration->enableFileService); MmsServer_enableDynamicNamedVariableListService(self->mmsServer, serverConfiguration->enableDynamicDataSetService); + MmsServer_setMaxAssociationSpecificDataSets(self->mmsServer, serverConfiguration->maxAssociationSpecificDataSets); + MmsServer_setMaxDomainSpecificDataSets(self->mmsServer, serverConfiguration->maxDomainSpecificDataSets); MmsServer_setMaxDataSetEntries(self->mmsServer, serverConfiguration->maxDataSetEntries); MmsServer_enableJournalService(self->mmsServer, serverConfiguration->enableLogService); MmsServer_setFilestoreBasepath(self->mmsServer, serverConfiguration->fileServiceBasepath); diff --git a/src/iec61850/server/impl/ied_server_config.c b/src/iec61850/server/impl/ied_server_config.c index a03e0975d..b9d1dd037 100644 --- a/src/iec61850/server/impl/ied_server_config.c +++ b/src/iec61850/server/impl/ied_server_config.c @@ -28,6 +28,14 @@ #define CONFIG_MMS_MAX_NUMBER_OF_DATA_SET_MEMBERS 100 #endif +#ifndef CONFIG_MMS_MAX_NUMBER_OF_ASSOCIATION_SPECIFIC_DATA_SETS +#define CONFIG_MMS_MAX_NUMBER_OF_ASSOCIATION_SPECIFIC_DATA_SETS 10 +#endif + +#ifndef CONFIG_MMS_MAX_NUMBER_OF_DOMAIN_SPECIFIC_DATA_SETS +#define CONFIG_MMS_MAX_NUMBER_OF_DOMAIN_SPECIFIC_DATA_SETS 10 +#endif + IedServerConfig IedServerConfig_create() { @@ -38,6 +46,8 @@ IedServerConfig_create() self->fileServiceBasepath = StringUtils_copyString(CONFIG_VIRTUAL_FILESTORE_BASEPATH); self->enableFileService = true; self->enableDynamicDataSetService = true; + self->maxAssociationSpecificDataSets = CONFIG_MMS_MAX_NUMBER_OF_ASSOCIATION_SPECIFIC_DATA_SETS; + self->maxDomainSpecificDataSets = CONFIG_MMS_MAX_NUMBER_OF_DOMAIN_SPECIFIC_DATA_SETS; self->maxDataSetEntries = CONFIG_MMS_MAX_NUMBER_OF_DATA_SET_MEMBERS; self->enableLogService = true; self->edition = IEC_61850_EDITION_2; @@ -119,6 +129,30 @@ IedServerConfig_isDynamicDataSetServiceEnabled(IedServerConfig self) return self->enableDynamicDataSetService; } +void +IedServerConfig_setMaxAssociationSpecificDataSets(IedServerConfig self, int maxDataSets) +{ + self->maxAssociationSpecificDataSets = maxDataSets; +} + +int +IedServerConfig_getMaxAssociationSpecificDataSets(IedServerConfig self) +{ + return self->maxAssociationSpecificDataSets; +} + +void +IedServerConfig_setMaxDomainSpecificDataSets(IedServerConfig self, int maxDataSets) +{ + self->maxDomainSpecificDataSets = maxDataSets; +} + +int +IedServerConfig_getMaxDomainSpecificDataSets(IedServerConfig self) +{ + return self->maxDomainSpecificDataSets; +} + void IedServerConfig_setMaxDataSetEntries(IedServerConfig self, int maxDataSetEntries) { diff --git a/src/mms/inc/mms_server.h b/src/mms/inc/mms_server.h index e4cd063f3..bf06de203 100644 --- a/src/mms/inc/mms_server.h +++ b/src/mms/inc/mms_server.h @@ -255,11 +255,29 @@ MmsServer_enableFileService(MmsServer self, bool enable); void MmsServer_enableDynamicNamedVariableListService(MmsServer self, bool enable); +/** + * \brief Set the maximum number of association specific data sets (per connection) + * + * \param[in] self the MmsServer instance + * \param[in] maxDataSets maximum number association specific data sets + */ +void +MmsServer_setMaxAssociationSpecificDataSets(MmsServer self, int maxDataSets); + +/** + * \brief Set the maximum number of domain specific data sets + * + * \param[in] self the MmsServer instance + * \param[in] maxDataSets maximum number domain specific data sets + */ +void +MmsServer_setMaxDomainSpecificDataSets(MmsServer self, int maxDataSets); + /** * \brief Set the maximum number of data set entries (for dynamic data sets) * * \param[in] self the MmsServer instance - * \param[in] maximum number of dynamic data set entires + * \param[in] maxDataSetEntries maximum number of dynamic data set entries */ void MmsServer_setMaxDataSetEntries(MmsServer self, int maxDataSetEntries); diff --git a/src/mms/inc_private/mms_server_internal.h b/src/mms/inc_private/mms_server_internal.h index bea5994b8..7a9155f43 100644 --- a/src/mms/inc_private/mms_server_internal.h +++ b/src/mms/inc_private/mms_server_internal.h @@ -170,6 +170,8 @@ struct sMmsServer { bool dynamicVariableListServiceEnabled; int maxDataSetEntries; bool journalServiceEnabled; + int maxAssociationSpecificDataSets; + int maxDomainSpecificDataSets; #endif /* (CONFIG_SET_FILESTORE_BASEPATH_AT_RUNTIME == 1) */ }; diff --git a/src/mms/iso_mms/server/mms_named_variable_list_service.c b/src/mms/iso_mms/server/mms_named_variable_list_service.c index 8aee035d1..3a0a78a79 100644 --- a/src/mms/iso_mms/server/mms_named_variable_list_service.c +++ b/src/mms/iso_mms/server/mms_named_variable_list_service.c @@ -453,7 +453,11 @@ mmsServer_handleDefineNamedVariableListRequest( goto exit_free_struct; } +#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) + if (LinkedList_size(domain->namedVariableLists) < connection->server->maxDomainSpecificDataSets) { +#else if (LinkedList_size(domain->namedVariableLists) < CONFIG_MMS_MAX_NUMBER_OF_DOMAIN_SPECIFIC_DATA_SETS) { +#endif char variableListName[65]; if (request->variableListName.choice.domainspecific.itemId.size > 64) { @@ -498,7 +502,11 @@ mmsServer_handleDefineNamedVariableListRequest( } else if (request->variableListName.present == ObjectName_PR_aaspecific) { +#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) + if (LinkedList_size(connection->namedVariableLists) < connection->server->maxAssociationSpecificDataSets) { +#else if (LinkedList_size(connection->namedVariableLists) < CONFIG_MMS_MAX_NUMBER_OF_ASSOCIATION_SPECIFIC_DATA_SETS) { +#endif char variableListName[65]; diff --git a/src/mms/iso_mms/server/mms_server.c b/src/mms/iso_mms/server/mms_server.c index 18ef0a423..7d5048879 100644 --- a/src/mms/iso_mms/server/mms_server.c +++ b/src/mms/iso_mms/server/mms_server.c @@ -72,6 +72,8 @@ MmsServer_create(MmsDevice* device, TLSConfiguration tlsConfiguration) self->dynamicVariableListServiceEnabled = true; self->journalServiceEnabled = true; self->maxDataSetEntries = CONFIG_MMS_MAX_NUMBER_OF_DATA_SET_MEMBERS; + self->maxAssociationSpecificDataSets = CONFIG_MMS_MAX_NUMBER_OF_ASSOCIATION_SPECIFIC_DATA_SETS; + self->maxDomainSpecificDataSets = CONFIG_MMS_MAX_NUMBER_OF_DOMAIN_SPECIFIC_DATA_SETS; #endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */ return self; @@ -138,6 +140,18 @@ MmsServer_enableJournalService(MmsServer self, bool enable) self->journalServiceEnabled = enable; } +void +MmsServer_setMaxAssociationSpecificDataSets(MmsServer self, int maxDataSets) +{ + self->maxAssociationSpecificDataSets = maxDataSets; +} + +void +MmsServer_setMaxDomainSpecificDataSets(MmsServer self, int maxDataSets) +{ + self->maxDomainSpecificDataSets = maxDataSets; +} + #endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */ void diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index 9382c85c6..33d4be39c 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -616,3 +616,8 @@ EXPORTS IedServerConfig_getMaxMmsConnections IedServerConfig_setMaxDataSetEntries IedServerConfig_getMaxDatasSetEntries + IedServerConfig_setMaxAssociationSpecificDataSets + IedServerConfig_getMaxAssociationSpecificDataSets + IedServerConfig_setMaxDomainSpecificDataSets + IedServerConfig_getMaxDomainSpecificDataSets + \ No newline at end of file diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index 79dc10eec..df59cae1c 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -744,3 +744,7 @@ EXPORTS IedServerConfig_getMaxMmsConnections IedServerConfig_setMaxDataSetEntries IedServerConfig_getMaxDatasSetEntries + IedServerConfig_setMaxAssociationSpecificDataSets + IedServerConfig_getMaxAssociationSpecificDataSets + IedServerConfig_setMaxDomainSpecificDataSets + IedServerConfig_getMaxDomainSpecificDataSets