diff --git a/src/common/string_utilities.c b/src/common/string_utilities.c index dfb9d620..41fd1192 100644 --- a/src/common/string_utilities.c +++ b/src/common/string_utilities.c @@ -26,30 +26,33 @@ char* StringUtils_copySubString(char* startPos, char* endPos) { - int newStringLength = endPos - startPos; + int newStringLength = endPos - startPos; - char* newString = (char*) GLOBAL_MALLOC(newStringLength + 1); + char* newString = (char*) GLOBAL_MALLOC(newStringLength + 1); - if (newString) { - memcpy(newString, startPos, newStringLength); + if (newString) { + memcpy(newString, startPos, newStringLength); - newString[newStringLength] = 0; - } + newString[newStringLength] = 0; + } - return newString; + return newString; } char* -StringUtils_copyString(const char* string) +StringUtils_copyString(const char* str) { - int newStringLength = strlen(string) + 1; + if (str == NULL) + return NULL; - char* newString = (char*) GLOBAL_MALLOC(newStringLength); + int newStringLength = strlen(str) + 1; - if (newString) - memcpy(newString, string, newStringLength); + char* newString = (char*) GLOBAL_MALLOC(newStringLength); - return newString; + if (newString) + memcpy(newString, str, newStringLength); + + return newString; } char* diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index 69179908..80edcb81 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -247,6 +247,10 @@ installDefaultValuesForDataAttribute(IedServer self, LogicalDevice* ld, DataAttr sprintf(componentId + compIdPos, "$%s", dataAttribute->name); } } + else { + if (compIdPos == 0) + componentId[0] = 0; + } char mmsVariableName[65]; /* maximum size is 64 according to 61850-8-1 */ @@ -306,8 +310,10 @@ installDefaultValuesForDataAttribute(IedServer self, LogicalDevice* ld, DataAttr DataAttribute* subDataAttribute = (DataAttribute*) dataAttribute->firstChild; + int childIdPos = childCompIdPos; + while (subDataAttribute != NULL) { - installDefaultValuesForDataAttribute(self, ld, subDataAttribute, objectReference, childPosition, subIdx, componentId, childCompIdPos); + installDefaultValuesForDataAttribute(self, ld, subDataAttribute, objectReference, childPosition, subIdx, componentId, childIdPos); subIdx++; @@ -317,8 +323,10 @@ installDefaultValuesForDataAttribute(IedServer self, LogicalDevice* ld, DataAttr else { DataAttribute* subDataAttribute = (DataAttribute*) dataAttribute->firstChild; + int childIdPos = childCompIdPos; + while (subDataAttribute != NULL) { - installDefaultValuesForDataAttribute(self, ld, subDataAttribute, objectReference, childPosition, idx, componentId, childCompIdPos); + installDefaultValuesForDataAttribute(self, ld, subDataAttribute, objectReference, childPosition, idx, componentId, childIdPos); subDataAttribute = (DataAttribute*) subDataAttribute->sibling; } diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 248112b2..7efd80d7 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -126,9 +126,12 @@ createNamedVariableFromDataAttribute(DataAttribute* attribute) MmsVariableSpecification* namedVariable = origNamedVariable; bool isBasicArray = false; + bool isArray = false; if (attribute->elementCount > 0) { + isArray = true; + namedVariable->type = MMS_ARRAY; namedVariable->typeSpec.array.elementCount = attribute->elementCount; namedVariable->typeSpec.array.elementTypeSpec = (MmsVariableSpecification*) GLOBAL_CALLOC(1, @@ -141,6 +144,11 @@ createNamedVariableFromDataAttribute(DataAttribute* attribute) } if ((attribute->firstChild != NULL) && (isBasicArray == false)) { + + if (isArray) { + attribute = (DataAttribute*)attribute->firstChild; + } + namedVariable->type = MMS_STRUCTURE; int componentCount = ModelNode_getChildCount((ModelNode*) attribute); diff --git a/src/iec61850/server/model/dynamic_model.c b/src/iec61850/server/model/dynamic_model.c index 92398f3e..c7af1e26 100644 --- a/src/iec61850/server/model/dynamic_model.c +++ b/src/iec61850/server/model/dynamic_model.c @@ -242,13 +242,15 @@ LogicalNode_create(const char* name, LogicalDevice* parent) { LogicalNode* self = (LogicalNode*) GLOBAL_MALLOC(sizeof(LogicalNode)); - self->name = StringUtils_copyString(name); - self->parent = (ModelNode*) parent; - self->modelType = LogicalNodeModelType; - self->firstChild = NULL; - self->sibling = NULL; + if (self) { + self->name = StringUtils_copyString(name); + self->parent = (ModelNode*) parent; + self->modelType = LogicalNodeModelType; + self->firstChild = NULL; + self->sibling = NULL; - LogicalDevice_addLogicalNode(parent, self); + LogicalDevice_addLogicalNode(parent, self); + } return self; } @@ -294,11 +296,13 @@ Log_create(const char* name, LogicalNode* parent) { Log* self = (Log*) GLOBAL_MALLOC(sizeof(Log)); - self->name = StringUtils_copyString(name); - self->parent = parent; - self->sibling = NULL; + if (self) { + self->name = StringUtils_copyString(name); + self->parent = parent; + self->sibling = NULL; - LogicalNode_addLog(parent, self); + LogicalNode_addLog(parent, self); + } return self; } @@ -317,26 +321,28 @@ LogControlBlock_create(const char* name, LogicalNode* parent, const char* dataSe { LogControlBlock* self = (LogControlBlock*) GLOBAL_MALLOC(sizeof(LogControlBlock)); - self->name = StringUtils_copyString(name); - self->parent = parent; - self->sibling = NULL; + if (self) { + self->name = StringUtils_copyString(name); + self->parent = parent; + self->sibling = NULL; - if (dataSetName) - self->dataSetName = StringUtils_copyString(dataSetName); - else - self->dataSetName = NULL; + if (dataSetName) + self->dataSetName = StringUtils_copyString(dataSetName); + else + self->dataSetName = NULL; - if (logRef) - self->logRef = StringUtils_copyString(logRef); - else - self->logRef = NULL; + if (logRef) + self->logRef = StringUtils_copyString(logRef); + else + self->logRef = NULL; - self->trgOps = trgOps; - self->intPeriod = intPeriod; - self->logEna = logEna; - self->reasonCode = reasonCode; + self->trgOps = trgOps; + self->intPeriod = intPeriod; + self->logEna = logEna; + self->reasonCode = reasonCode; - LogicalNode_addLogControlBlock(parent, self); + LogicalNode_addLogControlBlock(parent, self); + } return self; } @@ -355,30 +361,32 @@ ReportControlBlock_create(const char* name, LogicalNode* parent, const char* rpt { ReportControlBlock* self = (ReportControlBlock*) GLOBAL_MALLOC(sizeof(ReportControlBlock)); - self->name = StringUtils_copyString(name); - self->parent = parent; + if (self) { + self->name = StringUtils_copyString(name); + self->parent = parent; - if (rptId) - self->rptId = StringUtils_copyString(rptId); - else - self->rptId = NULL; + if (rptId) + self->rptId = StringUtils_copyString(rptId); + else + self->rptId = NULL; - self->buffered = isBuffered; + self->buffered = isBuffered; - if (dataSetName) - self->dataSetName = StringUtils_copyString(dataSetName); - else - self->dataSetName = NULL; + if (dataSetName) + self->dataSetName = StringUtils_copyString(dataSetName); + else + self->dataSetName = NULL; - self->confRef = confRef; - self->trgOps = trgOps; - self->options = options; - self->bufferTime = bufTm; - self->intPeriod = intgPd; - self->sibling = NULL; - self->clientReservation[0] = 0; /* no pre-configured client */ + self->confRef = confRef; + self->trgOps = trgOps; + self->options = options; + self->bufferTime = bufTm; + self->intPeriod = intgPd; + self->sibling = NULL; + self->clientReservation[0] = 0; /* no pre-configured client */ - LogicalNode_addReportControlBlock(parent, self); + LogicalNode_addReportControlBlock(parent, self); + } return self; } @@ -434,13 +442,15 @@ SettingGroupControlBlock_create(LogicalNode* parent, uint8_t actSG, uint8_t numO SettingGroupControlBlock* self = (SettingGroupControlBlock*) GLOBAL_MALLOC(sizeof(SettingGroupControlBlock)); - self->parent = parent; - self->actSG = actSG; - self->numOfSGs = numOfSGs; - self->sibling = NULL; - self->editSG = 0; + if (self) { + self->parent = parent; + self->actSG = actSG; + self->numOfSGs = numOfSGs; + self->sibling = NULL; + self->editSG = 0; - LogicalNode_addSettingGroupControlBlock(parent, self); + LogicalNode_addSettingGroupControlBlock(parent, self); + } return self; } @@ -460,30 +470,32 @@ GSEControlBlock_create(const char* name, LogicalNode* parent, const char* appId, { GSEControlBlock* self = (GSEControlBlock*) GLOBAL_MALLOC(sizeof(GSEControlBlock)); - self->name = StringUtils_copyString(name); - self->parent = parent; + if (self) { + self->name = StringUtils_copyString(name); + self->parent = parent; - if (appId) - self->appId = StringUtils_copyString(appId); - else - self->appId = NULL; + if (appId) + self->appId = StringUtils_copyString(appId); + else + self->appId = NULL; - if (dataSet) - self->dataSetName = StringUtils_copyString(dataSet); - else - self->dataSetName = NULL; + if (dataSet) + self->dataSetName = StringUtils_copyString(dataSet); + else + self->dataSetName = NULL; - self->confRev = confRef; - self->fixedOffs = fixedOffs; - self->minTime = minTime; - self->maxTime = maxTime; + self->confRev = confRef; + self->fixedOffs = fixedOffs; + self->minTime = minTime; + self->maxTime = maxTime; - self->address = NULL; + self->address = NULL; - self->sibling = NULL; + self->sibling = NULL; - if (parent != NULL) - LogicalNode_addGSEControlBlock(parent, self); + if (parent != NULL) + LogicalNode_addGSEControlBlock(parent, self); + } return self; } @@ -494,23 +506,25 @@ SVControlBlock_create(const char* name, LogicalNode* parent, const char* svID, c { SVControlBlock* self = (SVControlBlock*) GLOBAL_MALLOC(sizeof(SVControlBlock)); - self->name = StringUtils_copyString(name); - self->parent = parent; + if (self) { + self->name = StringUtils_copyString(name); + self->parent = parent; - self->svId = StringUtils_copyString(svID); /* Is there a default value? */ + self->svId = StringUtils_copyString(svID); /* Is there a default value? */ - if (dataSet) - self->dataSetName = StringUtils_copyString(dataSet); - else - self->dataSetName = NULL; + if (dataSet) + self->dataSetName = StringUtils_copyString(dataSet); + else + self->dataSetName = NULL; - self->confRev = confRev; + self->confRev = confRev; - self->smpMod = smpMod; - self->smpRate = smpRate; + self->smpMod = smpMod; + self->smpRate = smpRate; - self->optFlds = optFlds; - self->isUnicast = isUnicast; + self->optFlds = optFlds; + self->isUnicast = isUnicast; + } return self; } @@ -532,11 +546,13 @@ PhyComAddress_create(uint8_t vlanPriority, uint16_t vlanId, uint16_t appId, uint { PhyComAddress* self = (PhyComAddress*) GLOBAL_MALLOC(sizeof(PhyComAddress)); - self->vlanPriority = vlanPriority; - self->vlanId = vlanId; - self->appId = appId; + if (self) { + self->vlanPriority = vlanPriority; + self->vlanId = vlanId; + self->appId = appId; - memcpy(self->dstAddress, dstAddress, 6); + memcpy(self->dstAddress, dstAddress, 6); + } return self; } @@ -573,38 +589,42 @@ DataObject_create(const char* name, ModelNode* parent, int arrayElements) { DataObject* self = (DataObject*) GLOBAL_MALLOC(sizeof(DataObject)); - self->name = StringUtils_copyString(name); - self->modelType = DataObjectModelType; - self->firstChild = NULL; - self->parent = parent; - self->sibling = NULL; + if (self) { + self->name = StringUtils_copyString(name); + self->modelType = DataObjectModelType; + self->firstChild = NULL; + self->parent = parent; + self->sibling = NULL; - self->elementCount = arrayElements; - self->arrayIndex = -1; + self->elementCount = arrayElements; + self->arrayIndex = -1; - if (arrayElements > 0) { - int i; + if (arrayElements > 0) { + int i; - for (i = 0; i < arrayElements; i++) { - DataObject* arrayElement = (DataObject*) GLOBAL_MALLOC(sizeof(DataObject)); + for (i = 0; i < arrayElements; i++) { + DataObject* arrayElement = (DataObject*) GLOBAL_MALLOC(sizeof(DataObject)); - self->name = NULL; - self->modelType = DataObjectModelType; - self->firstChild = NULL; - self->parent = parent; - self->sibling = NULL; + if (self) { + self->name = NULL; + self->modelType = DataObjectModelType; + self->firstChild = NULL; + self->parent = parent; + self->sibling = NULL; - self->elementCount = 0; - self->arrayIndex = i; + self->elementCount = 0; + self->arrayIndex = i; - DataObject_addChild(self, (ModelNode*) arrayElement); + DataObject_addChild(self, (ModelNode*) arrayElement); + } + } } - } - if (parent->modelType == LogicalNodeModelType) - LogicalNode_addDataObject((LogicalNode*) parent, self); - else if (parent->modelType == DataObjectModelType) - DataObject_addChild((DataObject*) parent, (ModelNode*) self); + if (parent->modelType == LogicalNodeModelType) + LogicalNode_addDataObject((LogicalNode*) parent, self); + else if (parent->modelType == DataObjectModelType) + DataObject_addChild((DataObject*) parent, (ModelNode*) self); + } return self; } @@ -642,22 +662,50 @@ DataAttribute_create(const char* name, ModelNode* parent, DataAttributeType type { DataAttribute* self = (DataAttribute*) GLOBAL_MALLOC(sizeof(DataAttribute)); - self->name = StringUtils_copyString(name); - self->elementCount = arrayElements; - self->modelType = DataAttributeModelType; - self->type = type; - self->fc = fc; - self->firstChild = NULL; - self->mmsValue = NULL; - self->parent = parent; - self->sibling = NULL; - self->triggerOptions = triggerOptions; - self->sAddr = sAddr; - - if (parent->modelType == DataObjectModelType) - DataObject_addChild((DataObject*) parent, (ModelNode*) self); - else if (parent->modelType == DataAttributeModelType) - DataAttribute_addChild((DataAttribute*) parent, (ModelNode*) self); + if (self) { + self->name = StringUtils_copyString(name); + self->elementCount = arrayElements; + self->arrayIndex = -1; + self->modelType = DataAttributeModelType; + self->type = type; + self->fc = fc; + self->firstChild = NULL; + self->mmsValue = NULL; + self->parent = parent; + self->sibling = NULL; + self->triggerOptions = triggerOptions; + self->sAddr = sAddr; + + if ((arrayElements > 0) && (type != IEC61850_CONSTRUCTED)) { + int i; + + for (i = 0; i < arrayElements; i++) { + DataAttribute* arrayElement = (DataAttribute*) GLOBAL_MALLOC(sizeof(DataAttribute)); + + if (arrayElement) { + arrayElement->name = NULL; + arrayElement->elementCount = 0; + arrayElement->arrayIndex = i; + arrayElement->modelType = DataAttributeModelType; + arrayElement->type = type; + arrayElement->fc = fc; + arrayElement->firstChild = NULL; + arrayElement->mmsValue = NULL; + arrayElement->parent = parent; + arrayElement->sibling = NULL; + arrayElement->triggerOptions = triggerOptions; + arrayElement->sAddr = sAddr; + + DataAttribute_addChild(self, arrayElement); + } + } + } + + if (parent->modelType == DataObjectModelType) + DataObject_addChild((DataObject*) parent, (ModelNode*) self); + else if (parent->modelType == DataAttributeModelType) + DataAttribute_addChild((DataAttribute*) parent, (ModelNode*) self); + } return self; } @@ -696,15 +744,17 @@ DataSet_create(const char* name, LogicalNode* parent) { DataSet* self = (DataSet*) GLOBAL_MALLOC(sizeof(DataSet)); - LogicalDevice* ld = (LogicalDevice*) parent->parent; + if (self) { + LogicalDevice* ld = (LogicalDevice*) parent->parent; - self->name = StringUtils_createString(3, parent->name, "$", name); - self->elementCount = 0; - self->sibling = NULL; - self->logicalDeviceName = ld->name; - self->fcdas = NULL; + self->name = StringUtils_createString(3, parent->name, "$", name); + self->elementCount = 0; + self->sibling = NULL; + self->logicalDeviceName = ld->name; + self->fcdas = NULL; - IedModel_addDataSet((IedModel*) ld->parent, self); + IedModel_addDataSet((IedModel*) ld->parent, self); + } return self; } @@ -760,37 +810,39 @@ DataSetEntry_create(DataSet* dataSet, const char* variable, int index, const cha { DataSetEntry* self = (DataSetEntry*) GLOBAL_MALLOC(sizeof(DataSetEntry)); - char variableName[130]; + if (self) { + char variableName[130]; - StringUtils_copyStringMax(variableName, 130, variable); + StringUtils_copyStringMax(variableName, 130, variable); - char* separator = strchr(variableName, '/'); + char* separator = strchr(variableName, '/'); - if (separator != NULL) { - *separator = 0; + if (separator != NULL) { + *separator = 0; - self->variableName = StringUtils_copyString(separator + 1); - self->logicalDeviceName = StringUtils_copyString(variableName); - self->isLDNameDynamicallyAllocated = true; - } - else { - self->variableName = StringUtils_copyString(variable); - self->logicalDeviceName = dataSet->logicalDeviceName; - self->isLDNameDynamicallyAllocated = false; - } + self->variableName = StringUtils_copyString(separator + 1); + self->logicalDeviceName = StringUtils_copyString(variableName); + self->isLDNameDynamicallyAllocated = true; + } + else { + self->variableName = StringUtils_copyString(variable); + self->logicalDeviceName = dataSet->logicalDeviceName; + self->isLDNameDynamicallyAllocated = false; + } - if (component != NULL) - self->componentName = StringUtils_copyString(component); - else - self->componentName = NULL; + if (component != NULL) + self->componentName = StringUtils_copyString(component); + else + self->componentName = NULL; - self->index = index; + self->index = index; - self->sibling = NULL; + self->sibling = NULL; - self->value = NULL; + self->value = NULL; - DataSet_addEntry(dataSet, self); + DataSet_addEntry(dataSet, self); + } return self; } @@ -838,8 +890,11 @@ IedModel_destroy(IedModel* model) while (ld != NULL) { + if (ld->name) + GLOBAL_FREEMEM(ld->name); + if (ld->ldName) - GLOBAL_FREEMEM (ld->name); + GLOBAL_FREEMEM (ld->ldName); LogicalNode* ln = (LogicalNode*) ld->firstChild; diff --git a/src/mms/iso_mms/server/mms_value_cache.c b/src/mms/iso_mms/server/mms_value_cache.c index 99075b1f..4880d58c 100644 --- a/src/mms/iso_mms/server/mms_value_cache.c +++ b/src/mms/iso_mms/server/mms_value_cache.c @@ -185,6 +185,7 @@ searchCacheForValueEx(MmsValueCache self, const char* itemId, char* parentId, in if (elementValue) { if ((componentId != NULL) && (componentId[0] != 0)) { + MmsVariableSpecification* childSpec = MmsVariableSpecification_getNamedVariableRecursive(typeSpec, childId); if (childSpec) { @@ -234,13 +235,12 @@ MmsValueCache_lookupValueEx(MmsValueCache self, const char* itemId, int idx, con char itemIdCopy[65]; char componentIdCopyBuf[65]; - StringUtils_copyStringToBuffer(itemId, itemIdCopy); + StringUtils_copyStringMax(itemIdCopy, 65, itemId); char* componentIdCopy = NULL; if (componentId) { - componentIdCopy = StringUtils_copyStringToBuffer(componentId, componentIdCopyBuf); - + componentIdCopy = StringUtils_copyStringMax(componentIdCopyBuf, 65, componentId); } char* parentItemId = getParentSubString(itemIdCopy);