diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index 2acecedd..9dc8e85e 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -1,7 +1,7 @@ /* * ied_server.c * - * Copyright 2013-2023 Michael Zillgith + * Copyright 2013-2024 Michael Zillgith * * This file is part of libIEC61850. * @@ -48,15 +48,17 @@ createControlObjects(IedServer self, MmsDomain* domain, char* lnName, MmsVariabl bool success = false; - if (typeSpec->type == MMS_STRUCTURE) { + if (typeSpec->type == MMS_STRUCTURE) + { int coCount = typeSpec->typeSpec.structure.elementCount; int i; - for (i = 0; i < coCount; i++) { - + for (i = 0; i < coCount; i++) + { char objectName[65]; objectName[0] = 0; - if (namePrefix != NULL) { + if (namePrefix != NULL) + { StringUtils_concatString(objectName, 65, namePrefix, "$"); } @@ -70,33 +72,39 @@ createControlObjects(IedServer self, MmsDomain* domain, char* lnName, MmsVariabl MmsVariableSpecification* coSpec = typeSpec->typeSpec.structure.elements[i]; - if (coSpec->type == MMS_STRUCTURE) { - + if (coSpec->type == MMS_STRUCTURE) + { int coElementCount = coSpec->typeSpec.structure.elementCount; MmsVariableSpecification* operSpec = NULL; int j; - for (j = 0; j < coElementCount; j++) { + for (j = 0; j < coElementCount; j++) + { MmsVariableSpecification* coElementSpec = coSpec->typeSpec.structure.elements[j]; - if (strcmp(coElementSpec->name, "Oper") == 0) { + if (strcmp(coElementSpec->name, "Oper") == 0) + { operSpec = coElementSpec; operIndex = j; } - else if (strcmp(coElementSpec->name, "Cancel") == 0) { + else if (strcmp(coElementSpec->name, "Cancel") == 0) + { hasCancel = true; cancelIndex = j; } - else if (strcmp(coElementSpec->name, "SBOw") == 0) { + else if (strcmp(coElementSpec->name, "SBOw") == 0) + { hasSBOw = true; sBOwIndex = j; } - else if ((strcmp(coElementSpec->name, "SBO") == 0)) { + else if ((strcmp(coElementSpec->name, "SBO") == 0)) + { hasSBO = true; sBOIndex = j; } - else { + else + { if (DEBUG_IED_SERVER) printf("IED_SERVER: createControlObjects: Unknown element in CO: %s\n", coElementSpec->name); @@ -106,8 +114,8 @@ createControlObjects(IedServer self, MmsDomain* domain, char* lnName, MmsVariabl StringUtils_appendString(objectName, 65, coSpec->name); - if (operSpec) { - + if (operSpec) + { if (DEBUG_IED_SERVER) printf("IED_SERVER: create control object LN:%s DO:%s\n", lnName, objectName); @@ -118,7 +126,8 @@ createControlObjects(IedServer self, MmsDomain* domain, char* lnName, MmsVariabl MmsValue* structure = MmsValue_newDefaultValue(coSpec); - if (structure == NULL) { + if (structure == NULL) + { ControlObject_destroy(controlObject); goto exit_function; } @@ -140,7 +149,8 @@ createControlObjects(IedServer self, MmsDomain* domain, char* lnName, MmsVariabl MmsMapping_addControlObject(mapping, controlObject); } - else { + else + { if (createControlObjects(self, domain, lnName, coSpec, objectName) == false) goto exit_function; } @@ -164,14 +174,15 @@ createMmsServerCache(IedServer self) int domain = 0; - for (domain = 0; domain < self->mmsDevice->domainCount; domain++) { - + for (domain = 0; domain < self->mmsDevice->domainCount; domain++) + { /* Install all top level MMS named variables (=Logical nodes) in the MMS server cache */ MmsDomain* logicalDevice = self->mmsDevice->domains[domain]; int i; - for (i = 0; i < logicalDevice->namedVariablesCount; i++) { + for (i = 0; i < logicalDevice->namedVariablesCount; i++) + { char* lnName = logicalDevice->namedVariables[i]->name; if (DEBUG_IED_SERVER) @@ -180,13 +191,15 @@ createMmsServerCache(IedServer self) int fcCount = logicalDevice->namedVariables[i]->typeSpec.structure.elementCount; int j; - for (j = 0; j < fcCount; j++) { + for (j = 0; j < fcCount; j++) + { MmsVariableSpecification* fcSpec = logicalDevice->namedVariables[i]->typeSpec.structure.elements[j]; char* fcName = fcSpec->name; #if (CONFIG_IEC61850_CONTROL_SERVICE == 1) - if (strcmp(fcName, "CO") == 0) { + if (strcmp(fcName, "CO") == 0) + { createControlObjects(self, logicalDevice, lnName, fcSpec, NULL); } else @@ -236,18 +249,21 @@ static void installDefaultValuesForDataAttribute(IedServer self, LogicalDevice* ld, DataAttribute* dataAttribute, char* objectReference, int position, int idx, char* componentId, int compIdPos) { - if (dataAttribute->name) { + if (dataAttribute->name) + { if (idx == -1) { sprintf(objectReference + position, ".%s", dataAttribute->name); } - else { + else + { if (compIdPos == 0) sprintf(componentId, "%s", dataAttribute->name); else sprintf(componentId + compIdPos, "$%s", dataAttribute->name); } } - else { + else + { if (compIdPos == 0) componentId[0] = 0; } @@ -260,20 +276,23 @@ installDefaultValuesForDataAttribute(IedServer self, LogicalDevice* ld, DataAttr char domainName[65]; - if (ld->ldName == NULL) { + if (ld->ldName == NULL) + { char ldInst[65]; MmsMapping_getMmsDomainFromObjectReference(objectReference, ldInst); StringUtils_concatString(domainName, 65, self->model->name, ldInst); } - else { + else + { StringUtils_copyStringMax(domainName, 65, ld->ldName); } MmsDomain* domain = MmsDevice_getDomain(self->mmsDevice, domainName); - if (domain == NULL) { + if (domain == NULL) + { if (DEBUG_IED_SERVER) printf("Error domain (%s) not found for %s!\n", domainName, objectReference); return; @@ -288,9 +307,9 @@ installDefaultValuesForDataAttribute(IedServer self, LogicalDevice* ld, DataAttr dataAttribute->mmsValue = cacheValue; - if (value != NULL) { - - if (cacheValue != NULL) + if (value) + { + if (cacheValue) MmsValue_update(cacheValue, value); #if (DEBUG_IED_SERVER == 1) @@ -305,14 +324,16 @@ installDefaultValuesForDataAttribute(IedServer self, LogicalDevice* ld, DataAttr int childPosition = strlen(objectReference); int childCompIdPos = strlen(componentId); - if (dataAttribute->elementCount > 0) { + if (dataAttribute->elementCount > 0) + { int subIdx = 0; DataAttribute* subDataAttribute = (DataAttribute*) dataAttribute->firstChild; int childIdPos = childCompIdPos; - while (subDataAttribute != NULL) { + while (subDataAttribute) + { installDefaultValuesForDataAttribute(self, ld, subDataAttribute, objectReference, childPosition, subIdx, componentId, childIdPos); subIdx++; @@ -320,12 +341,14 @@ installDefaultValuesForDataAttribute(IedServer self, LogicalDevice* ld, DataAttr subDataAttribute = (DataAttribute*) subDataAttribute->sibling; } } - else { + else + { DataAttribute* subDataAttribute = (DataAttribute*) dataAttribute->firstChild; int childIdPos = childCompIdPos; - while (subDataAttribute != NULL) { + while (subDataAttribute) + { installDefaultValuesForDataAttribute(self, ld, subDataAttribute, objectReference, childPosition, idx, componentId, childIdPos); subDataAttribute = (DataAttribute*) subDataAttribute->sibling; @@ -337,7 +360,8 @@ static void installDefaultValuesForDataObject(IedServer self, LogicalDevice* ld, DataObject* dataObject, char* objectReference, int position, int idx, char* componentId, int compIdPos) { - if (dataObject->elementCount > 0) { + if (dataObject->elementCount > 0) + { if (DEBUG_IED_SERVER) printf("IED_SERVER: DataObject %s is an array\n", dataObject->name); @@ -348,7 +372,8 @@ installDefaultValuesForDataObject(IedServer self, LogicalDevice* ld, DataObject* int arrayIdx = 0; - while (arrayElemNode) { + while (arrayElemNode) + { installDefaultValuesForDataObject(self, ld, (DataObject*)arrayElemNode, objectReference, childPosition, arrayIdx, componentId, compIdPos); arrayIdx++; @@ -358,10 +383,14 @@ installDefaultValuesForDataObject(IedServer self, LogicalDevice* ld, DataObject* return; } - if (dataObject->arrayIndex == -1) { + if (dataObject->arrayIndex == -1) + { if (idx == -1) + { sprintf(objectReference + position, ".%s", dataObject->name); - else { + } + else + { if (compIdPos == 0) sprintf(componentId, "%s", dataObject->name); else @@ -377,11 +406,14 @@ installDefaultValuesForDataObject(IedServer self, LogicalDevice* ld, DataObject* int childPosition = strlen(objectReference); int childCompIdPos = strlen(componentId); - while (childNode) { - if (childNode->modelType == DataObjectModelType) { + while (childNode) + { + if (childNode->modelType == DataObjectModelType) + { installDefaultValuesForDataObject(self, ld, (DataObject*) childNode, objectReference, childPosition, idx, componentId, childCompIdPos); } - else if (childNode->modelType == DataAttributeModelType) { + else if (childNode->modelType == DataAttributeModelType) + { installDefaultValuesForDataAttribute(self, ld, (DataAttribute*) childNode, objectReference, childPosition, idx, componentId, childCompIdPos); } @@ -399,11 +431,10 @@ installDefaultValuesInCache(IedServer self) char objectReference[130]; - LogicalDevice* logicalDevice = model->firstChild; - while (logicalDevice != NULL) { - + while (logicalDevice) + { if (logicalDevice->ldName) sprintf(objectReference, "%s", logicalDevice->ldName); else @@ -413,14 +444,16 @@ installDefaultValuesInCache(IedServer self) char* nodeReference = objectReference + strlen(objectReference); - while (logicalNode != NULL) { + while (logicalNode) + { sprintf(nodeReference, "/%s", logicalNode->name); DataObject* dataObject = (DataObject*) logicalNode->firstChild; int refPosition = strlen(objectReference); - while (dataObject != NULL) { + while (dataObject) + { componentId[0] = 0; installDefaultValuesForDataObject(self, logicalDevice, dataObject, objectReference, refPosition, -1, componentId, 0); @@ -441,25 +474,27 @@ updateDataSetsWithCachedValues(IedServer self) int iedNameLength = strlen(self->model->name); - if (iedNameLength <= 64) { - - while (dataSet != NULL) { - + if (iedNameLength <= 64) + { + while (dataSet) + { DataSetEntry* dataSetEntry = dataSet->fcdas; - while (dataSetEntry != NULL) { - + while (dataSetEntry) + { MmsDomain* domain = NULL; LogicalDevice* ld = IedModel_getDeviceByInst(self->model, dataSetEntry->logicalDeviceName); - if (ld) { - - if (ld->ldName) { + if (ld) + { + if (ld->ldName) + { domain = MmsDevice_getDomain(self->mmsDevice, ld->ldName); } - if (domain == NULL) { + if (domain == NULL) + { char domainName[65]; StringUtils_concatString(domainName, 65, self->model->name, dataSetEntry->logicalDeviceName); @@ -468,7 +503,8 @@ updateDataSetsWithCachedValues(IedServer self) } } - else { + else + { if (DEBUG_IED_SERVER) printf("IED_SERVER: ERROR - LD %s not found\n", dataSetEntry->logicalDeviceName); } @@ -482,52 +518,63 @@ updateDataSetsWithCachedValues(IedServer self) MmsValue* value = MmsServer_getValueFromCacheEx(self->mmsServer, domain, variableName, &typeSpec); - if (value == NULL) { - if (DEBUG_IED_SERVER) { + if (value == NULL) + { + if (DEBUG_IED_SERVER) + { printf("IED_SERVER: LD: %s dataset: %s : error cannot get value from cache for %s -> %s!\n", dataSet->logicalDeviceName, dataSet->name, dataSetEntry->logicalDeviceName, dataSetEntry->variableName); } } - else { + else + { /* check if array element */ - if (dataSetEntry->index != -1) { - if (typeSpec->type == MMS_ARRAY) { + if (dataSetEntry->index != -1) + { + if (typeSpec->type == MMS_ARRAY) + { MmsValue* elementValue = MmsValue_getElement(value, dataSetEntry->index); - if (elementValue) { - - if (dataSetEntry->componentName) { + if (elementValue) + { + if (dataSetEntry->componentName) + { MmsVariableSpecification* elementType = typeSpec->typeSpec.array.elementTypeSpec; MmsValue* subElementValue = MmsVariableSpecification_getChildValue(elementType, elementValue, dataSetEntry->componentName); - if (subElementValue) { + if (subElementValue) + { dataSetEntry->value = subElementValue; } - else { + else + { if (DEBUG_IED_SERVER) printf("IED_SERVER: ERROR - component %s of array element not found\n", dataSetEntry->componentName); } - } - else { + else + { dataSetEntry->value = elementValue; } } - else { + else + { if (DEBUG_IED_SERVER) printf("IED_SERVER: ERROR - array element %i not found\n", dataSetEntry->index); } } - else { + else + { if (DEBUG_IED_SERVER) printf("IED_SERVER: ERROR - variable %s/%s is not an array\n", dataSetEntry->logicalDeviceName, dataSetEntry->variableName); } } - else { + else + { dataSetEntry->value = value; } } @@ -707,9 +754,11 @@ IedServer_setRCBEventHandler(IedServer self, IedServer_RCBEventHandler handler, void IedServer_destroy(IedServer self) { - if (self) { + if (self) + { /* Stop server if running */ - if (self->running) { + if (self->running) + { #if (CONFIG_MMS_THREADLESS_STACK == 1) IedServer_stopThreadless(self); #else @@ -726,7 +775,7 @@ IedServer_destroy(IedServer self) MmsServer_destroy(self->mmsServer); - if (self->localIpAddress != NULL) + if (self->localIpAddress) GLOBAL_FREEMEM(self->localIpAddress); if (self->mmsMapping) @@ -781,7 +830,8 @@ singleThreadedServerThread(void* parameter) if (DEBUG_IED_SERVER) printf("IED_SERVER: server thread started!\n"); - while (running) { + while (running) + { MmsServer_handleIncomingMessages(self->mmsServer); IedServer_performPeriodicTasks(self); @@ -799,8 +849,8 @@ singleThreadedServerThread(void* parameter) void IedServer_start(IedServer self, int tcpPort) { - if (self->running == false) { - + if (self->running == false) + { #if (CONFIG_MMS_SINGLE_THREADED == 1) MmsServer_startListeningThreadless(self->mmsServer, tcpPort); @@ -835,7 +885,8 @@ IedServer_getDataModel(IedServer self) void IedServer_stop(IedServer self) { - if (self->running) { + if (self->running) + { self->running = false; MmsMapping_stopEventWorkerThread(self->mmsMapping); @@ -864,7 +915,7 @@ IedServer_setFilestoreBasepath(IedServer self, const char* basepath) void IedServer_setLocalIpAddress(IedServer self, const char* localIpAddress) { - if (self->localIpAddress != NULL) + if (self->localIpAddress) GLOBAL_FREEMEM(self->localIpAddress); self->localIpAddress = StringUtils_copyString(localIpAddress); @@ -876,7 +927,8 @@ IedServer_setLocalIpAddress(IedServer self, const char* localIpAddress) void IedServer_startThreadless(IedServer self, int tcpPort) { - if (self->running == false) { + if (self->running == false) + { MmsServer_startListeningThreadless(self->mmsServer, tcpPort); self->running = true; } @@ -903,10 +955,12 @@ IedServer_processIncomingData(IedServer self) bool IedServer_addAccessPoint(IedServer self, const char* ipAddr, int tcpPort, TLSConfiguration tlsConfiguration) { - if (self->mmsServer) { + if (self->mmsServer) + { return MmsServer_addAP(self->mmsServer, ipAddr, tcpPort, tlsConfiguration); } - else { + else + { return false; } } @@ -914,7 +968,8 @@ IedServer_addAccessPoint(IedServer self, const char* ipAddr, int tcpPort, TLSCon void IedServer_stopThreadless(IedServer self) { - if (self->running) { + if (self->running) + { self->running = false; MmsServer_stopListeningThreadless(self->mmsServer); @@ -1198,8 +1253,8 @@ static inline void checkForUpdateTrigger(IedServer self, DataAttribute* dataAttribute) { #if ((CONFIG_IEC61850_REPORT_SERVICE == 1) || (CONFIG_IEC61850_LOG_SERVICE == 1)) - if (dataAttribute->triggerOptions & TRG_OPT_DATA_UPDATE) { - + if (dataAttribute->triggerOptions & TRG_OPT_DATA_UPDATE) + { #if (CONFIG_IEC61850_REPORT_SERVICE == 1) MmsMapping_triggerReportObservers(self->mmsMapping, dataAttribute->mmsValue, REPORT_CONTROL_VALUE_UPDATE); @@ -1253,8 +1308,6 @@ checkForChangedTriggers(IedServer self, DataAttribute* dataAttribute) } #endif /* (CONFIG_IEC61850_REPORT_SERVICE== 1) || (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) */ - - } void @@ -1264,13 +1317,15 @@ IedServer_updateAttributeValue(IedServer self, DataAttribute* dataAttribute, Mms assert(dataAttribute != NULL); assert(MmsValue_getType(dataAttribute->mmsValue) == MmsValue_getType(value)); - if (MmsValue_equals(dataAttribute->mmsValue, value) == false) { - - if (dataAttribute->type == IEC61850_BOOLEAN) { + if (MmsValue_equals(dataAttribute->mmsValue, value) == false) + { + if (dataAttribute->type == IEC61850_BOOLEAN) + { /* Special treatment because of transient option */ IedServer_updateBooleanAttributeValue(self, dataAttribute, MmsValue_getBoolean(value)); } - else { + else + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->dataModelLock); #endif @@ -1297,8 +1352,8 @@ IedServer_updateFloatAttributeValue(IedServer self, DataAttribute* dataAttribute float currentValue = MmsValue_toFloat(dataAttribute->mmsValue); - if (currentValue != value) { - + if (currentValue != value) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->dataModelLock); #endif @@ -1321,8 +1376,8 @@ IedServer_updateInt32AttributeValue(IedServer self, DataAttribute* dataAttribute int32_t currentValue = MmsValue_toInt32(dataAttribute->mmsValue); - if (currentValue != value) { - + if (currentValue != value) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->dataModelLock); #endif @@ -1342,8 +1397,8 @@ IedServer_updateDbposValue(IedServer self, DataAttribute* dataAttribute, Dbpos v { Dbpos currentValue = Dbpos_fromMmsValue(dataAttribute->mmsValue); - if (currentValue != value) { - + if (currentValue != value) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->dataModelLock); #endif @@ -1367,8 +1422,8 @@ IedServer_updateInt64AttributeValue(IedServer self, DataAttribute* dataAttribute int64_t currentValue = MmsValue_toInt64(dataAttribute->mmsValue); - if (currentValue != value) { - + if (currentValue != value) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->dataModelLock); #endif @@ -1392,8 +1447,8 @@ IedServer_updateUnsignedAttributeValue(IedServer self, DataAttribute* dataAttrib uint32_t currentValue = MmsValue_toUint32(dataAttribute->mmsValue); - if (currentValue != value) { - + if (currentValue != value) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->dataModelLock); #endif @@ -1417,8 +1472,8 @@ IedServer_updateBitStringAttributeValue(IedServer self, DataAttribute* dataAttri uint32_t currentValue = MmsValue_getBitStringAsInteger(dataAttribute->mmsValue); - if (currentValue != value) { - + if (currentValue != value) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->dataModelLock); #endif @@ -1442,10 +1497,12 @@ IedServer_updateBooleanAttributeValue(IedServer self, DataAttribute* dataAttribu bool currentValue = MmsValue_getBoolean(dataAttribute->mmsValue); - if (currentValue != value) { + if (currentValue != value) + { bool callCheckTriggers = true; - if (dataAttribute->triggerOptions & TRG_OPT_TRANSIENT) { + if (dataAttribute->triggerOptions & TRG_OPT_TRANSIENT) + { if (currentValue == true) callCheckTriggers = false; } @@ -1474,7 +1531,8 @@ IedServer_updateVisibleStringAttributeValue(IedServer self, DataAttribute* dataA const char* currentValue = MmsValue_toString(dataAttribute->mmsValue); - if (strcmp(currentValue, value)) { + if (strcmp(currentValue, value)) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->dataModelLock); #endif @@ -1498,8 +1556,8 @@ IedServer_updateUTCTimeAttributeValue(IedServer self, DataAttribute* dataAttribu uint64_t currentValue = MmsValue_getUtcTimeInMs(dataAttribute->mmsValue); - if (currentValue != value) { - + if (currentValue != value) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->dataModelLock); #endif @@ -1521,8 +1579,8 @@ IedServer_updateTimestampAttributeValue(IedServer self, DataAttribute* dataAttri assert(MmsValue_getType(dataAttribute->mmsValue) == MMS_UTC_TIME); assert(self != NULL); - if (memcmp(dataAttribute->mmsValue->value.utcTime, timestamp->val, 8)) { - + if (memcmp(dataAttribute->mmsValue->value.utcTime, timestamp->val, 8)) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->dataModelLock); #endif @@ -1547,7 +1605,8 @@ IedServer_updateQuality(IedServer self, DataAttribute* dataAttribute, Quality qu uint32_t oldQuality = MmsValue_getBitStringAsInteger(dataAttribute->mmsValue); - if (oldQuality != (uint32_t) quality) { + if (oldQuality != (uint32_t) quality) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->dataModelLock); #endif @@ -1611,8 +1670,10 @@ IedServer_disableGoosePublishing(IedServer self) void IedServer_setWriteAccessPolicy(IedServer self, FunctionalConstraint fc, AccessPolicy policy) { - if (policy == ACCESS_POLICY_ALLOW) { - switch (fc) { + if (policy == ACCESS_POLICY_ALLOW) + { + switch (fc) + { case IEC61850_FC_DC: self->writeAccessPolicies |= ALLOW_WRITE_ACCESS_DC; break; @@ -1632,8 +1693,10 @@ IedServer_setWriteAccessPolicy(IedServer self, FunctionalConstraint fc, AccessPo break; } } - else { - switch (fc) { + else + { + switch (fc) + { case IEC61850_FC_DC: self->writeAccessPolicies &= ~ALLOW_WRITE_ACCESS_DC; break; @@ -1658,11 +1721,13 @@ IedServer_setWriteAccessPolicy(IedServer self, FunctionalConstraint fc, AccessPo void IedServer_handleWriteAccess(IedServer self, DataAttribute* dataAttribute, WriteAccessHandler handler, void* parameter) { - if (dataAttribute == NULL) { + if (dataAttribute == NULL) + { if (DEBUG_IED_SERVER) printf("IED_SERVER: IedServer_handleWriteAccess - dataAttribute == NULL!\n"); } - else { + else + { MmsMapping_installWriteAccessHandler(self->mmsMapping, dataAttribute, handler, parameter); } } @@ -1670,16 +1735,19 @@ IedServer_handleWriteAccess(IedServer self, DataAttribute* dataAttribute, WriteA void IedServer_handleWriteAccessForComplexAttribute(IedServer self, DataAttribute* dataAttribute, WriteAccessHandler handler, void* parameter) { - if (dataAttribute == NULL) { + if (dataAttribute == NULL) + { if (DEBUG_IED_SERVER) printf("IED_SERVER: IedServer_handleWriteAccessForComplexAttribute - dataAttribute == NULL!\n"); } - else { + else + { MmsMapping_installWriteAccessHandler(self->mmsMapping, dataAttribute, handler, parameter); DataAttribute* subDa = (DataAttribute*) dataAttribute->firstChild; - while (subDa) { + while (subDa) + { IedServer_handleWriteAccessForComplexAttribute(self, subDa, handler, parameter); subDa = (DataAttribute*) subDa->sibling; @@ -1690,7 +1758,8 @@ IedServer_handleWriteAccessForComplexAttribute(IedServer self, DataAttribute* da void IedServer_handleWriteAccessForDataObject(IedServer self, DataObject* dataObject, FunctionalConstraint fc, WriteAccessHandler handler, void* parameter) { - if (dataObject == NULL) { + if (dataObject == NULL) + { if (DEBUG_IED_SERVER) printf("IED_SERVER: IedServer_handlerWriteAccessForDataObject - dataObject == NULL!\n"); } @@ -1741,7 +1810,8 @@ IedServer_getFunctionalConstrainedData(IedServer self, DataObject* dataObject, F int nameLen; - while (dataObject->modelType == DataObjectModelType) { + while (dataObject->modelType == DataObjectModelType) + { nameLen = strlen(dataObject->name); currentStart -= nameLen; memcpy(currentStart, dataObject->name, nameLen); @@ -1774,8 +1844,8 @@ IedServer_getFunctionalConstrainedData(IedServer self, DataObject* dataObject, F char domainName[65]; - if ((strlen(self->model->name) + strlen(ld->name)) > 64) { - + if ((strlen(self->model->name) + strlen(ld->name)) > 64) + { if (DEBUG_IED_SERVER) printf("IED_SERVER: LD name too long!\n"); @@ -1786,8 +1856,8 @@ IedServer_getFunctionalConstrainedData(IedServer self, DataObject* dataObject, F MmsDomain* domain = MmsDevice_getDomain(self->mmsDevice, domainName); - if (domain == NULL) { - + if (domain == NULL) + { if (DEBUG_IED_SERVER) printf("IED_SERVER: internal error - domain does not exist!\n"); @@ -1892,10 +1962,12 @@ private_IedServer_getClientConnectionByHandle(IedServer self, void* serverConnec LinkedList element = LinkedList_getNext(self->clientConnections); ClientConnection matchingConnection = NULL; - while (element != NULL) { + while (element != NULL) + { ClientConnection connection = (ClientConnection) element->data; - if (private_ClientConnection_getServerConnectionHandle(connection) == serverConnectionHandle) { + if (private_ClientConnection_getServerConnectionHandle(connection) == serverConnectionHandle) + { matchingConnection = connection; break; } diff --git a/src/iec61850/server/mms_mapping/mms_goose.c b/src/iec61850/server/mms_mapping/mms_goose.c index 5aab2585..3cbb080d 100644 --- a/src/iec61850/server/mms_mapping/mms_goose.c +++ b/src/iec61850/server/mms_mapping/mms_goose.c @@ -1,7 +1,7 @@ /* * mms_goose.c * - * Copyright 2013-2022 Michael Zillgith + * Copyright 2013-2024 Michael Zillgith * * This file is part of libIEC61850. * @@ -87,7 +87,8 @@ setNdsCom(MmsGooseControlBlock mmsGCB, bool value) { MmsValue* ndsComValue = MmsValue_getElement(mmsGCB->mmsValue, 4); - if (ndsComValue) { + if (ndsComValue) + { MmsValue_setBoolean(ndsComValue, value); } } @@ -116,10 +117,12 @@ MmsGooseControlBlock_getGoEna(MmsGooseControlBlock self) { bool retVal = false; - if (self->mmsValue) { + if (self->mmsValue) + { MmsValue* goEnaValue = MmsValue_getElement(self->mmsValue, 0); - if (goEnaValue) { + if (goEnaValue) + { retVal = MmsValue_getBoolean(goEnaValue); } } @@ -127,16 +130,17 @@ MmsGooseControlBlock_getGoEna(MmsGooseControlBlock self) return retVal; } - int MmsGooseControlBlock_getMinTime(MmsGooseControlBlock self) { int retVal = -1; - if (self->mmsValue) { + if (self->mmsValue) + { MmsValue* minTimeValue = MmsValue_getElement(self->mmsValue, 6); - if (minTimeValue) { + if (minTimeValue) + { retVal = MmsValue_toInt32(minTimeValue); } } @@ -149,10 +153,12 @@ MmsGooseControlBlock_getMaxTime(MmsGooseControlBlock self) { int retVal = -1; - if (self->mmsValue) { + if (self->mmsValue) + { MmsValue* maxTimeValue = MmsValue_getElement(self->mmsValue, 7); - if (maxTimeValue) { + if (maxTimeValue) + { retVal = MmsValue_toInt32(maxTimeValue); } } @@ -165,10 +171,12 @@ MmsGooseControlBlock_getFixedOffs(MmsGooseControlBlock self) { bool retVal = false; - if (self->mmsValue) { + if (self->mmsValue) + { MmsValue* fixedOffsValue = MmsValue_getElement(self->mmsValue, 8); - if (fixedOffsValue) { + if (fixedOffsValue) + { retVal = MmsValue_getBoolean(fixedOffsValue); } } @@ -181,7 +189,8 @@ MmsGooseControlBlock_getFixedOffs(MmsGooseControlBlock self) static void copyGCBValuesToTrackingObject(MmsGooseControlBlock gc) { - if (gc->mmsMapping->gocbTrk) { + if (gc->mmsMapping->gocbTrk) + { GocbTrkInstance trkInst = gc->mmsMapping->gocbTrk; if (trkInst->goEna) @@ -202,16 +211,20 @@ copyGCBValuesToTrackingObject(MmsGooseControlBlock gc) MmsValue_setVisibleString(trkInst->datSet->mmsValue, datSet); } - if (trkInst->confRev) { + if (trkInst->confRev) + { uint32_t confRev = MmsValue_toUint32(MmsValue_getElement(gc->mmsValue, 3)); MmsValue_setUint32(trkInst->confRev->mmsValue, confRev); } - if (trkInst->ndsCom) { + + if (trkInst->ndsCom) + { bool ndsCom = MmsValue_getBoolean(MmsValue_getElement(gc->mmsValue, 4)); MmsValue_setBoolean(trkInst->ndsCom->mmsValue, ndsCom); } - if (trkInst->dstAddress) { + if (trkInst->dstAddress) + { MmsValue_update(trkInst->dstAddress->mmsValue, MmsValue_getElement(gc->mmsValue, 5)); } } @@ -222,11 +235,13 @@ updateGenericTrackingObjectValues(MmsGooseControlBlock gc, IEC61850_ServiceType { ServiceTrkInstance trkInst = NULL; - if (gc->mmsMapping->gocbTrk) { + if (gc->mmsMapping->gocbTrk) + { trkInst = (ServiceTrkInstance) gc->mmsMapping->gocbTrk; } - if (trkInst) { + if (trkInst) + { if (trkInst->serviceType) MmsValue_setInt32(trkInst->serviceType->mmsValue, (int) serviceType); @@ -261,7 +276,8 @@ MmsGooseControlBlock_create() { MmsGooseControlBlock self = (MmsGooseControlBlock) GLOBAL_CALLOC(1, sizeof(struct sMmsGooseControlBlock)); - if (self) { + if (self) + { self->useVlanTag = true; #if (CONFIG_MMS_THREADLESS_STACK != 1) self->publisherMutex = Semaphore_create(1); @@ -274,36 +290,35 @@ MmsGooseControlBlock_create() void MmsGooseControlBlock_destroy(MmsGooseControlBlock self) { - if (self) { - + if (self) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_destroy(self->publisherMutex); #endif - if (self->publisher != NULL) + if (self->publisher) GoosePublisher_destroy(self->publisher); - if (self->dataSetValues != NULL) + if (self->dataSetValues) LinkedList_destroyStatic(self->dataSetValues); - if (self->goCBRef != NULL) + if (self->goCBRef) GLOBAL_FREEMEM(self->goCBRef); - if (self->goId != NULL) + if (self->goId) GLOBAL_FREEMEM(self->goId); - if (self->dataSetRef != NULL) + if (self->dataSetRef) GLOBAL_FREEMEM(self->dataSetRef); - if (self->dataSet != NULL) { - if (self->isDynamicDataSet) { - MmsMapping_freeDynamicallyCreatedDataSet(self->dataSet); - self->isDynamicDataSet = false; - self->dataSet = NULL; - } + if (self->dataSet && self->isDynamicDataSet) + { + MmsMapping_freeDynamicallyCreatedDataSet(self->dataSet); + self->isDynamicDataSet = false; + self->dataSet = NULL; } - if (self->gooseInterfaceId != NULL) + if (self->gooseInterfaceId) GLOBAL_FREEMEM(self->gooseInterfaceId); MmsValue_delete(self->mmsValue); @@ -321,7 +336,7 @@ MmsGooseControlBlock_useGooseVlanTag(MmsGooseControlBlock self, bool useVlanTag) void MmsGooseControlBlock_setGooseInterfaceId(MmsGooseControlBlock self, const char* interfaceId) { - if (self->gooseInterfaceId != NULL) + if (self->gooseInterfaceId) GLOBAL_FREEMEM(self->gooseInterfaceId); self->gooseInterfaceId = StringUtils_copyString(interfaceId); @@ -382,7 +397,8 @@ calculateMaxDataSetSize(DataSet* dataSet) DataSetEntry* dataSetEntry = dataSet->fcdas; - while (dataSetEntry) { + while (dataSetEntry) + { dataSetSize += MmsValue_getMaxEncodedSize(dataSetEntry->value); dataSetEntry = dataSetEntry->sibling; @@ -400,19 +416,21 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self, MmsMapping* mmsMapping) Semaphore_wait(self->publisherMutex); #endif - if (!MmsGooseControlBlock_isEnabled(self)) { - - if (self->dataSetRef != NULL) { + if (!MmsGooseControlBlock_isEnabled(self)) + { + if (self->dataSetRef) + { GLOBAL_FREEMEM(self->dataSetRef); - if (self->dataSet != NULL) - if (self->isDynamicDataSet) { - MmsMapping_freeDynamicallyCreatedDataSet(self->dataSet); - self->isDynamicDataSet = false; - self->dataSet = NULL; - } + if (self->dataSet && self->isDynamicDataSet) + { + MmsMapping_freeDynamicallyCreatedDataSet(self->dataSet); + self->isDynamicDataSet = false; + self->dataSet = NULL; + } - if (self->dataSetValues != NULL) { + if (self->dataSetValues) + { LinkedList_destroyStatic(self->dataSetValues); self->dataSetValues = NULL; } @@ -422,24 +440,24 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self, MmsMapping* mmsMapping) const char* dataSetRef = MmsValue_toString(MmsValue_getElement(self->mmsValue, 2)); - if (dataSetRef != NULL) { - + if (dataSetRef) + { self->dataSetRef = StringUtils_copyString(dataSetRef); self->dataSet = IedModel_lookupDataSet(self->mmsMapping->model, self->dataSetRef); self->isDynamicDataSet = false; - if (self->dataSet == NULL) { + if (self->dataSet == NULL) + { self->dataSet = MmsMapping_getDomainSpecificDataSet(self->mmsMapping, self->dataSetRef); self->isDynamicDataSet = true; } - } - if (self->dataSet != NULL) { - + if (self->dataSet) + { int dataSetSize = calculateMaxDataSetSize(self->dataSet); /* Calculate maximum GOOSE message size */ @@ -455,7 +473,8 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self, MmsMapping* mmsMapping) maxGooseMessageSize += dataSetSize; - if (maxGooseMessageSize > GOOSE_MAX_MESSAGE_SIZE) { + if (maxGooseMessageSize > GOOSE_MAX_MESSAGE_SIZE) + { setNdsCom(self, true); #if (CONFIG_IEC61850_SERVICE_TRACKING == 1) @@ -463,7 +482,8 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self, MmsMapping* mmsMapping) updateGenericTrackingObjectValues(self, IEC61850_SERVICE_TYPE_SET_GOCB_VALUES, DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID); #endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */ } - else { + else + { MmsValue* goEna = MmsValue_getElement(self->mmsValue, 0); MmsValue_setBoolean(goEna, true); @@ -479,14 +499,15 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self, MmsMapping* mmsMapping) memcpy(commParameters.dstAddress, MmsValue_getOctetStringBuffer(macAddress), 6); - if (mmsMapping->useIntegratedPublisher) { - + if (mmsMapping->useIntegratedPublisher) + { if (self->gooseInterfaceId) self->publisher = GoosePublisher_createEx(&commParameters, self->gooseInterfaceId, self->useVlanTag); else self->publisher = GoosePublisher_createEx(&commParameters, self->mmsMapping->gooseInterfaceId, self->useVlanTag); - if (self->publisher) { + if (self->publisher) + { self->minTime = MmsValue_toUint32(MmsValue_getElement(self->mmsValue, 6)); self->maxTime = MmsValue_toUint32(MmsValue_getElement(self->mmsValue, 7)); @@ -512,12 +533,14 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self, MmsMapping* mmsMapping) DataSetEntry* dataSetEntry = self->dataSet->fcdas; - while (dataSetEntry != NULL) { + while (dataSetEntry) + { LinkedList_add(self->dataSetValues, dataSetEntry->value); dataSetEntry = dataSetEntry->sibling; } } - else { + else + { if (DEBUG_IED_SERVER) printf("IED_SERVER: Failed to create GOOSE publisher!\n"); } @@ -532,11 +555,10 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self, MmsMapping* mmsMapping) updateGenericTrackingObjectValues(self, IEC61850_SERVICE_TYPE_SET_GOCB_VALUES, DATA_ACCESS_ERROR_SUCCESS); #endif /* (CONFIG_IEC61850_SERVICE_TRACKING == 1) */ } - } - } - else { + else + { if (DEBUG_IED_SERVER) printf("GoCB already enabled!\n"); } @@ -551,7 +573,8 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self, MmsMapping* mmsMapping) void MmsGooseControlBlock_disable(MmsGooseControlBlock self, MmsMapping* mmsMapping) { - if (MmsGooseControlBlock_isEnabled(self)) { + if (MmsGooseControlBlock_isEnabled(self)) + { MmsValue* goEna = MmsValue_getElement(self->mmsValue, 0); MmsValue_setBoolean(goEna, false); @@ -562,8 +585,10 @@ MmsGooseControlBlock_disable(MmsGooseControlBlock self, MmsMapping* mmsMapping) Semaphore_wait(self->publisherMutex); #endif - if (mmsMapping->useIntegratedPublisher) { - if (self->publisher != NULL) { + if (mmsMapping->useIntegratedPublisher) + { + if (self->publisher) + { GoosePublisher_destroy(self->publisher); self->publisher = NULL; LinkedList_destroyStatic(self->dataSetValues); @@ -583,27 +608,27 @@ MmsGooseControlBlock_disable(MmsGooseControlBlock self, MmsMapping* mmsMapping) } } - void MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t currentTime, MmsMapping* mapping) { - if (self->publisher) { - if (currentTime >= self->nextPublishTime) { - + if (self->publisher) + { + if (currentTime >= self->nextPublishTime) + { IedServer_lockDataModel(mapping->iedServer); - if (currentTime >= self->nextPublishTime) { - + if (currentTime >= self->nextPublishTime) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_wait(self->publisherMutex); #endif GoosePublisher_publish(self->publisher, self->dataSetValues); - if (self->retransmissionsLeft > 0) { + if (self->retransmissionsLeft > 0) + { self->nextPublishTime = currentTime + self->minTime; - if (self->retransmissionsLeft > 1) GoosePublisher_setTimeAllowedToLive(self->publisher, self->minTime * 3); else @@ -611,7 +636,8 @@ MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t current self->retransmissionsLeft--; } - else { + else + { GoosePublisher_setTimeAllowedToLive(self->publisher, self->maxTime * 3); self->nextPublishTime = currentTime + self->maxTime; @@ -625,7 +651,8 @@ MmsGooseControlBlock_checkAndPublish(MmsGooseControlBlock self, uint64_t current IedServer_unlockDataModel(mapping->iedServer); } - else if ((self->nextPublishTime - currentTime) > ((uint32_t) self->maxTime * 2)) { + else if ((self->nextPublishTime - currentTime) > ((uint32_t) self->maxTime * 2)) + { self->nextPublishTime = currentTime + self->minTime; } } @@ -643,32 +670,35 @@ MmsGooseControlBlock_publishNewState(MmsGooseControlBlock self) if (self->publisher == false) return; - if (self->stateChangePending) { + if (self->stateChangePending) + { #if (CONFIG_MMS_THREADLESS_STACK != 1) - Semaphore_wait(self->publisherMutex); + Semaphore_wait(self->publisherMutex); #endif - uint64_t currentTime = GoosePublisher_increaseStNum(self->publisher); + uint64_t currentTime = GoosePublisher_increaseStNum(self->publisher); - self->retransmissionsLeft = CONFIG_GOOSE_EVENT_RETRANSMISSION_COUNT; + self->retransmissionsLeft = CONFIG_GOOSE_EVENT_RETRANSMISSION_COUNT; - if (self->retransmissionsLeft > 0) { - self->nextPublishTime = currentTime + self->minTime; + if (self->retransmissionsLeft > 0) + { + self->nextPublishTime = currentTime + self->minTime; - GoosePublisher_setTimeAllowedToLive(self->publisher, self->minTime * 3); - } - else { - self->nextPublishTime = currentTime + self->maxTime; + GoosePublisher_setTimeAllowedToLive(self->publisher, self->minTime * 3); + } + else + { + self->nextPublishTime = currentTime + self->maxTime; - GoosePublisher_setTimeAllowedToLive(self->publisher, self->maxTime * 3); - } + GoosePublisher_setTimeAllowedToLive(self->publisher, self->maxTime * 3); + } - GoosePublisher_publish(self->publisher, self->dataSetValues); + GoosePublisher_publish(self->publisher, self->dataSetValues); - self->stateChangePending = false; + self->stateChangePending = false; #if (CONFIG_MMS_THREADLESS_STACK != 1) - Semaphore_post(self->publisherMutex); + Semaphore_post(self->publisherMutex); #endif } } @@ -754,8 +784,10 @@ getGCBForLogicalNodeWithIndex(MmsMapping* self, LogicalNode* logicalNode, int in GSEControlBlock* gcb = self->model->gseCBs; /* Iterate list of GoCBs */ - while (gcb != NULL ) { - if (gcb->parent == logicalNode) { + while (gcb != NULL ) + { + if (gcb->parent == logicalNode) + { if (gseCount == index) return gcb; @@ -781,13 +813,16 @@ createDataSetReference(char* domainName, char* lnName, char* dataSetName) void GOOSE_sendPendingEvents(MmsMapping* self) { - if (self->useIntegratedPublisher) { + if (self->useIntegratedPublisher) + { LinkedList element = self->gseControls; - while ((element = LinkedList_getNext(element)) != NULL) { + while ((element = LinkedList_getNext(element)) != NULL) + { MmsGooseControlBlock gcb = (MmsGooseControlBlock) element->data; - if (MmsGooseControlBlock_isEnabled(gcb)) { + if (MmsGooseControlBlock_isEnabled(gcb)) + { MmsGooseControlBlock_publishNewState(gcb); } } @@ -809,7 +844,8 @@ GOOSE_createGOOSEControlBlocks(MmsMapping* self, MmsDomain* domain, int currentGCB = 0; - while (currentGCB < gseCount) { + while (currentGCB < gseCount) + { GSEControlBlock* gooseControlBlock = getGCBForLogicalNodeWithIndex( self, logicalNode, currentGCB); @@ -821,11 +857,11 @@ GOOSE_createGOOSEControlBlocks(MmsMapping* self, MmsDomain* domain, MmsGooseControlBlock mmsGCB = MmsGooseControlBlock_create(); - mmsGCB->goCBRef = StringUtils_createString(5, MmsDomain_getName(domain), "/", logicalNode->name, "$GO$", gooseControlBlock->name); - if (gooseControlBlock->appId != NULL) { + if (gooseControlBlock->appId != NULL) + { MmsValue* goID = MmsValue_getElement(gseValues, 1); MmsValue_setVisibleString(goID, gooseControlBlock->appId); @@ -833,11 +869,13 @@ GOOSE_createGOOSEControlBlocks(MmsMapping* self, MmsDomain* domain, mmsGCB->goId = StringUtils_copyString(gooseControlBlock->appId); } - if ((gooseControlBlock->dataSetName != NULL) && (gooseControlBlock->dataSetName[0] != 0)) { + if ((gooseControlBlock->dataSetName != NULL) && (gooseControlBlock->dataSetName[0] != 0)) + { mmsGCB->dataSetRef = createDataSetReference(MmsDomain_getName(domain), logicalNode->name, gooseControlBlock->dataSetName); } - else { + else + { mmsGCB->dataSetRef = NULL; } @@ -851,7 +889,8 @@ GOOSE_createGOOSEControlBlocks(MmsMapping* self, MmsDomain* domain, uint16_t vid = CONFIG_GOOSE_DEFAULT_VLAN_ID; uint16_t appId = CONFIG_GOOSE_DEFAULT_APPID; - if (gooseControlBlock->address != NULL) { + if (gooseControlBlock->address != NULL) + { priority = gooseControlBlock->address->vlanPriority; vid = gooseControlBlock->address->vlanId; appId = gooseControlBlock->address->appId; @@ -922,4 +961,3 @@ GOOSE_createGOOSEControlBlocks(MmsMapping* self, MmsDomain* domain, } #endif /* (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) */ -