diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index c55c115c..b1dcdd17 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -250,6 +250,7 @@ installDefaultValuesForDataAttribute(IedServer self, DataAttribute* dataAttribut char domainName[65]; strncpy(domainName, self->model->name, 64); + domainName[64] = 0; MmsMapping_getMmsDomainFromObjectReference(objectReference, domainName + strlen(domainName)); @@ -451,7 +452,6 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio IedServer self = (IedServer) GLOBAL_CALLOC(1, sizeof(struct sIedServer)); if (self) { - self->model = dataModel; self->running = false; @@ -510,56 +510,63 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio self->mmsMapping = MmsMapping_create(dataModel, self); - self->mmsDevice = MmsMapping_getMmsDeviceModel(self->mmsMapping); + if (self->mmsMapping) { + + self->mmsDevice = MmsMapping_getMmsDeviceModel(self->mmsMapping); - self->mmsServer = MmsServer_create(self->mmsDevice, tlsConfiguration); + self->mmsServer = MmsServer_create(self->mmsDevice, tlsConfiguration); #if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) - 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); - MmsServer_setMaxConnections(self->mmsServer, serverConfiguration->maxMmsConnections); - } + 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); + MmsServer_setMaxConnections(self->mmsServer, serverConfiguration->maxMmsConnections); + } #endif - MmsMapping_setMmsServer(self->mmsMapping, self->mmsServer); + MmsMapping_setMmsServer(self->mmsMapping, self->mmsServer); - MmsMapping_installHandlers(self->mmsMapping); + MmsMapping_installHandlers(self->mmsMapping); - createMmsServerCache(self); + createMmsServerCache(self); - dataModel->initializer(); + dataModel->initializer(); - installDefaultValuesInCache(self); /* This will also connect cached MmsValues to DataAttributes */ + installDefaultValuesInCache(self); /* This will also connect cached MmsValues to DataAttributes */ - updateDataSetsWithCachedValues(self); + updateDataSetsWithCachedValues(self); - self->clientConnections = LinkedList_create(); + self->clientConnections = LinkedList_create(); - /* default write access policy allows access to SP, SE and SV FCDAs but denies access to DC and CF FCDAs */ - self->writeAccessPolicies = ALLOW_WRITE_ACCESS_SP | ALLOW_WRITE_ACCESS_SV | ALLOW_WRITE_ACCESS_SE; + /* default write access policy allows access to SP, SE and SV FCDAs but denies access to DC and CF FCDAs */ + self->writeAccessPolicies = ALLOW_WRITE_ACCESS_SP | ALLOW_WRITE_ACCESS_SV | ALLOW_WRITE_ACCESS_SE; - MmsMapping_initializeControlObjects(self->mmsMapping); + MmsMapping_initializeControlObjects(self->mmsMapping); #if (CONFIG_IEC61850_REPORT_SERVICE == 1) - Reporting_activateBufferedReports(self->mmsMapping); + Reporting_activateBufferedReports(self->mmsMapping); #endif #if (CONFIG_IEC61850_SETTING_GROUPS == 1) - MmsMapping_configureSettingGroups(self->mmsMapping); + MmsMapping_configureSettingGroups(self->mmsMapping); #endif #if (CONFIG_INCLUDE_GOOSE_SUPPORT) - if (serverConfiguration) { - MmsMapping_useIntegratedGoosePublisher(self->mmsMapping, serverConfiguration->useIntegratedGoosePublisher); - } - + if (serverConfiguration) { + MmsMapping_useIntegratedGoosePublisher(self->mmsMapping, serverConfiguration->useIntegratedGoosePublisher); + } #endif + + } + else { + IedServer_destroy(self); + self = NULL; + } } return self; @@ -602,7 +609,8 @@ IedServer_destroy(IedServer self) if (self->localIpAddress != NULL) GLOBAL_FREEMEM(self->localIpAddress); - MmsMapping_destroy(self->mmsMapping); + if (self->mmsMapping) + MmsMapping_destroy(self->mmsMapping); LinkedList_destroyDeep(self->clientConnections, (LinkedListValueDeleteFunction) private_ClientConnection_destroy); diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index b89898fc..384b8616 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -1712,8 +1712,6 @@ createNamedVariableFromLogicalNode(MmsMapping* self, MmsDomain* domain, } #endif /* (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) */ - - if (LogicalNode_hasFCData(logicalNode, IEC61850_FC_SV)) { namedVariable->typeSpec.structure.elements[currentComponent] = createFCNamedVariable(logicalNode, IEC61850_FC_SV); @@ -1765,7 +1763,6 @@ createNamedVariableFromLogicalNode(MmsMapping* self, MmsDomain* domain, #endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */ - currentComponent++; } @@ -1793,12 +1790,19 @@ createMmsDomainFromIedDevice(MmsMapping* self, LogicalDevice* logicalDevice) char domainName[65]; int modelNameLength = strlen(self->model->name); + int ldInstName = strlen(logicalDevice->name); + + if ((modelNameLength + ldInstName) > 64) { + + if (DEBUG_IED_SERVER) + printf("IED_SERVER: Resulting domain name (IEDName+LDInst) too long (%i)\n", modelNameLength + ldInstName); - if (modelNameLength > 64) goto exit_function; + } strncpy(domainName, self->model->name, 64); strncat(domainName, logicalDevice->name, 64 - modelNameLength); + domainName[64] = 0; domain = MmsDomain_create(domainName); @@ -1868,22 +1872,29 @@ exit_function: return domain; } -static void +static bool createMmsDataModel(MmsMapping* self, int iedDeviceCount, MmsDevice* mmsDevice, IedModel* iedModel) { - mmsDevice->domains = (MmsDomain**) GLOBAL_MALLOC((iedDeviceCount) * sizeof(MmsDomain*)); + mmsDevice->domains = (MmsDomain**) GLOBAL_CALLOC(1, (iedDeviceCount) * sizeof(MmsDomain*)); mmsDevice->domainCount = iedDeviceCount; LogicalDevice* logicalDevice = iedModel->firstChild; int i = 0; while (logicalDevice != NULL) { - mmsDevice->domains[i] = createMmsDomainFromIedDevice(self, - logicalDevice); + mmsDevice->domains[i] = createMmsDomainFromIedDevice(self, logicalDevice); + + if (mmsDevice->domains[i] == NULL) { + mmsDevice->domainCount = i; + return false; + } + i++; logicalDevice = (LogicalDevice*) logicalDevice->sibling; } + + return true; } static void @@ -1962,9 +1973,13 @@ createMmsModelFromIedModel(MmsMapping* self, IedModel* iedModel) int iedDeviceCount = IedModel_getLogicalDeviceCount(iedModel); - createMmsDataModel(self, iedDeviceCount, mmsDevice, iedModel); - - createDataSets(mmsDevice, iedModel); + if (createMmsDataModel(self, iedDeviceCount, mmsDevice, iedModel)) { + createDataSets(mmsDevice, iedModel); + } + else { + MmsDevice_destroy(mmsDevice); + mmsDevice = NULL; + } } return mmsDevice; @@ -2015,6 +2030,11 @@ MmsMapping_create(IedModel* model, IedServer iedServer) /* create data model specification */ self->mmsDevice = createMmsModelFromIedModel(self, model); + if (self->mmsDevice == false) { + MmsMapping_destroy(self); + self = NULL; + } + return self; } @@ -2029,7 +2049,7 @@ MmsMapping_destroy(MmsMapping* self) } #endif - if (self->mmsDevice != NULL) + if (self->mmsDevice) MmsDevice_destroy(self->mmsDevice); #if (CONFIG_IEC61850_REPORT_SERVICE == 1)