- some code format updates

pull/521/head
Michael Zillgith 1 year ago
parent 8b7b0387f1
commit 728c812fc8

@ -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;
}

@ -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) */

Loading…
Cancel
Save