- fixed code to support arrays of complex data attributes

v1.6_develop_rgoose_sntp
Michael Zillgith 3 years ago
parent 9e1a9a63ba
commit 6b23f87b23

@ -40,14 +40,17 @@ StringUtils_copySubString(char* startPos, char* endPos)
} }
char* char*
StringUtils_copyString(const char* string) StringUtils_copyString(const char* str)
{ {
int newStringLength = strlen(string) + 1; if (str == NULL)
return NULL;
int newStringLength = strlen(str) + 1;
char* newString = (char*) GLOBAL_MALLOC(newStringLength); char* newString = (char*) GLOBAL_MALLOC(newStringLength);
if (newString) if (newString)
memcpy(newString, string, newStringLength); memcpy(newString, str, newStringLength);
return newString; return newString;
} }

@ -247,6 +247,10 @@ installDefaultValuesForDataAttribute(IedServer self, LogicalDevice* ld, DataAttr
sprintf(componentId + compIdPos, "$%s", dataAttribute->name); 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 */ 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; DataAttribute* subDataAttribute = (DataAttribute*) dataAttribute->firstChild;
int childIdPos = childCompIdPos;
while (subDataAttribute != NULL) { while (subDataAttribute != NULL) {
installDefaultValuesForDataAttribute(self, ld, subDataAttribute, objectReference, childPosition, subIdx, componentId, childCompIdPos); installDefaultValuesForDataAttribute(self, ld, subDataAttribute, objectReference, childPosition, subIdx, componentId, childIdPos);
subIdx++; subIdx++;
@ -317,8 +323,10 @@ installDefaultValuesForDataAttribute(IedServer self, LogicalDevice* ld, DataAttr
else { else {
DataAttribute* subDataAttribute = (DataAttribute*) dataAttribute->firstChild; DataAttribute* subDataAttribute = (DataAttribute*) dataAttribute->firstChild;
int childIdPos = childCompIdPos;
while (subDataAttribute != NULL) { 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; subDataAttribute = (DataAttribute*) subDataAttribute->sibling;
} }

@ -126,9 +126,12 @@ createNamedVariableFromDataAttribute(DataAttribute* attribute)
MmsVariableSpecification* namedVariable = origNamedVariable; MmsVariableSpecification* namedVariable = origNamedVariable;
bool isBasicArray = false; bool isBasicArray = false;
bool isArray = false;
if (attribute->elementCount > 0) if (attribute->elementCount > 0)
{ {
isArray = true;
namedVariable->type = MMS_ARRAY; namedVariable->type = MMS_ARRAY;
namedVariable->typeSpec.array.elementCount = attribute->elementCount; namedVariable->typeSpec.array.elementCount = attribute->elementCount;
namedVariable->typeSpec.array.elementTypeSpec = (MmsVariableSpecification*) GLOBAL_CALLOC(1, namedVariable->typeSpec.array.elementTypeSpec = (MmsVariableSpecification*) GLOBAL_CALLOC(1,
@ -141,6 +144,11 @@ createNamedVariableFromDataAttribute(DataAttribute* attribute)
} }
if ((attribute->firstChild != NULL) && (isBasicArray == false)) { if ((attribute->firstChild != NULL) && (isBasicArray == false)) {
if (isArray) {
attribute = (DataAttribute*)attribute->firstChild;
}
namedVariable->type = MMS_STRUCTURE; namedVariable->type = MMS_STRUCTURE;
int componentCount = ModelNode_getChildCount((ModelNode*) attribute); int componentCount = ModelNode_getChildCount((ModelNode*) attribute);

@ -242,6 +242,7 @@ LogicalNode_create(const char* name, LogicalDevice* parent)
{ {
LogicalNode* self = (LogicalNode*) GLOBAL_MALLOC(sizeof(LogicalNode)); LogicalNode* self = (LogicalNode*) GLOBAL_MALLOC(sizeof(LogicalNode));
if (self) {
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->parent = (ModelNode*) parent; self->parent = (ModelNode*) parent;
self->modelType = LogicalNodeModelType; self->modelType = LogicalNodeModelType;
@ -249,6 +250,7 @@ LogicalNode_create(const char* name, LogicalDevice* parent)
self->sibling = NULL; self->sibling = NULL;
LogicalDevice_addLogicalNode(parent, self); LogicalDevice_addLogicalNode(parent, self);
}
return self; return self;
} }
@ -294,11 +296,13 @@ Log_create(const char* name, LogicalNode* parent)
{ {
Log* self = (Log*) GLOBAL_MALLOC(sizeof(Log)); Log* self = (Log*) GLOBAL_MALLOC(sizeof(Log));
if (self) {
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->parent = parent; self->parent = parent;
self->sibling = NULL; self->sibling = NULL;
LogicalNode_addLog(parent, self); LogicalNode_addLog(parent, self);
}
return self; return self;
} }
@ -317,6 +321,7 @@ LogControlBlock_create(const char* name, LogicalNode* parent, const char* dataSe
{ {
LogControlBlock* self = (LogControlBlock*) GLOBAL_MALLOC(sizeof(LogControlBlock)); LogControlBlock* self = (LogControlBlock*) GLOBAL_MALLOC(sizeof(LogControlBlock));
if (self) {
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->parent = parent; self->parent = parent;
self->sibling = NULL; self->sibling = NULL;
@ -337,6 +342,7 @@ LogControlBlock_create(const char* name, LogicalNode* parent, const char* dataSe
self->reasonCode = reasonCode; self->reasonCode = reasonCode;
LogicalNode_addLogControlBlock(parent, self); LogicalNode_addLogControlBlock(parent, self);
}
return self; return self;
} }
@ -355,6 +361,7 @@ ReportControlBlock_create(const char* name, LogicalNode* parent, const char* rpt
{ {
ReportControlBlock* self = (ReportControlBlock*) GLOBAL_MALLOC(sizeof(ReportControlBlock)); ReportControlBlock* self = (ReportControlBlock*) GLOBAL_MALLOC(sizeof(ReportControlBlock));
if (self) {
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->parent = parent; self->parent = parent;
@ -379,6 +386,7 @@ ReportControlBlock_create(const char* name, LogicalNode* parent, const char* rpt
self->clientReservation[0] = 0; /* no pre-configured client */ self->clientReservation[0] = 0; /* no pre-configured client */
LogicalNode_addReportControlBlock(parent, self); LogicalNode_addReportControlBlock(parent, self);
}
return self; return self;
} }
@ -434,6 +442,7 @@ SettingGroupControlBlock_create(LogicalNode* parent, uint8_t actSG, uint8_t numO
SettingGroupControlBlock* self = (SettingGroupControlBlock*) GLOBAL_MALLOC(sizeof(SettingGroupControlBlock)); SettingGroupControlBlock* self = (SettingGroupControlBlock*) GLOBAL_MALLOC(sizeof(SettingGroupControlBlock));
if (self) {
self->parent = parent; self->parent = parent;
self->actSG = actSG; self->actSG = actSG;
self->numOfSGs = numOfSGs; self->numOfSGs = numOfSGs;
@ -441,6 +450,7 @@ SettingGroupControlBlock_create(LogicalNode* parent, uint8_t actSG, uint8_t numO
self->editSG = 0; self->editSG = 0;
LogicalNode_addSettingGroupControlBlock(parent, self); LogicalNode_addSettingGroupControlBlock(parent, self);
}
return self; return self;
} }
@ -460,6 +470,7 @@ GSEControlBlock_create(const char* name, LogicalNode* parent, const char* appId,
{ {
GSEControlBlock* self = (GSEControlBlock*) GLOBAL_MALLOC(sizeof(GSEControlBlock)); GSEControlBlock* self = (GSEControlBlock*) GLOBAL_MALLOC(sizeof(GSEControlBlock));
if (self) {
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->parent = parent; self->parent = parent;
@ -484,6 +495,7 @@ GSEControlBlock_create(const char* name, LogicalNode* parent, const char* appId,
if (parent != NULL) if (parent != NULL)
LogicalNode_addGSEControlBlock(parent, self); LogicalNode_addGSEControlBlock(parent, self);
}
return self; return self;
} }
@ -494,6 +506,7 @@ SVControlBlock_create(const char* name, LogicalNode* parent, const char* svID, c
{ {
SVControlBlock* self = (SVControlBlock*) GLOBAL_MALLOC(sizeof(SVControlBlock)); SVControlBlock* self = (SVControlBlock*) GLOBAL_MALLOC(sizeof(SVControlBlock));
if (self) {
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->parent = parent; self->parent = parent;
@ -511,6 +524,7 @@ SVControlBlock_create(const char* name, LogicalNode* parent, const char* svID, c
self->optFlds = optFlds; self->optFlds = optFlds;
self->isUnicast = isUnicast; self->isUnicast = isUnicast;
}
return self; 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)); PhyComAddress* self = (PhyComAddress*) GLOBAL_MALLOC(sizeof(PhyComAddress));
if (self) {
self->vlanPriority = vlanPriority; self->vlanPriority = vlanPriority;
self->vlanId = vlanId; self->vlanId = vlanId;
self->appId = appId; self->appId = appId;
memcpy(self->dstAddress, dstAddress, 6); memcpy(self->dstAddress, dstAddress, 6);
}
return self; return self;
} }
@ -573,6 +589,7 @@ DataObject_create(const char* name, ModelNode* parent, int arrayElements)
{ {
DataObject* self = (DataObject*) GLOBAL_MALLOC(sizeof(DataObject)); DataObject* self = (DataObject*) GLOBAL_MALLOC(sizeof(DataObject));
if (self) {
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->modelType = DataObjectModelType; self->modelType = DataObjectModelType;
self->firstChild = NULL; self->firstChild = NULL;
@ -588,6 +605,7 @@ DataObject_create(const char* name, ModelNode* parent, int arrayElements)
for (i = 0; i < arrayElements; i++) { for (i = 0; i < arrayElements; i++) {
DataObject* arrayElement = (DataObject*) GLOBAL_MALLOC(sizeof(DataObject)); DataObject* arrayElement = (DataObject*) GLOBAL_MALLOC(sizeof(DataObject));
if (self) {
self->name = NULL; self->name = NULL;
self->modelType = DataObjectModelType; self->modelType = DataObjectModelType;
self->firstChild = NULL; self->firstChild = NULL;
@ -600,11 +618,13 @@ DataObject_create(const char* name, ModelNode* parent, int arrayElements)
DataObject_addChild(self, (ModelNode*) arrayElement); DataObject_addChild(self, (ModelNode*) arrayElement);
} }
} }
}
if (parent->modelType == LogicalNodeModelType) if (parent->modelType == LogicalNodeModelType)
LogicalNode_addDataObject((LogicalNode*) parent, self); LogicalNode_addDataObject((LogicalNode*) parent, self);
else if (parent->modelType == DataObjectModelType) else if (parent->modelType == DataObjectModelType)
DataObject_addChild((DataObject*) parent, (ModelNode*) self); DataObject_addChild((DataObject*) parent, (ModelNode*) self);
}
return self; return self;
} }
@ -642,8 +662,10 @@ DataAttribute_create(const char* name, ModelNode* parent, DataAttributeType type
{ {
DataAttribute* self = (DataAttribute*) GLOBAL_MALLOC(sizeof(DataAttribute)); DataAttribute* self = (DataAttribute*) GLOBAL_MALLOC(sizeof(DataAttribute));
if (self) {
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->elementCount = arrayElements; self->elementCount = arrayElements;
self->arrayIndex = -1;
self->modelType = DataAttributeModelType; self->modelType = DataAttributeModelType;
self->type = type; self->type = type;
self->fc = fc; self->fc = fc;
@ -654,10 +676,36 @@ DataAttribute_create(const char* name, ModelNode* parent, DataAttributeType type
self->triggerOptions = triggerOptions; self->triggerOptions = triggerOptions;
self->sAddr = sAddr; 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) if (parent->modelType == DataObjectModelType)
DataObject_addChild((DataObject*) parent, (ModelNode*) self); DataObject_addChild((DataObject*) parent, (ModelNode*) self);
else if (parent->modelType == DataAttributeModelType) else if (parent->modelType == DataAttributeModelType)
DataAttribute_addChild((DataAttribute*) parent, (ModelNode*) self); DataAttribute_addChild((DataAttribute*) parent, (ModelNode*) self);
}
return self; return self;
} }
@ -696,6 +744,7 @@ DataSet_create(const char* name, LogicalNode* parent)
{ {
DataSet* self = (DataSet*) GLOBAL_MALLOC(sizeof(DataSet)); DataSet* self = (DataSet*) GLOBAL_MALLOC(sizeof(DataSet));
if (self) {
LogicalDevice* ld = (LogicalDevice*) parent->parent; LogicalDevice* ld = (LogicalDevice*) parent->parent;
self->name = StringUtils_createString(3, parent->name, "$", name); self->name = StringUtils_createString(3, parent->name, "$", name);
@ -705,6 +754,7 @@ DataSet_create(const char* name, LogicalNode* parent)
self->fcdas = NULL; self->fcdas = NULL;
IedModel_addDataSet((IedModel*) ld->parent, self); IedModel_addDataSet((IedModel*) ld->parent, self);
}
return self; return self;
} }
@ -760,6 +810,7 @@ DataSetEntry_create(DataSet* dataSet, const char* variable, int index, const cha
{ {
DataSetEntry* self = (DataSetEntry*) GLOBAL_MALLOC(sizeof(DataSetEntry)); DataSetEntry* self = (DataSetEntry*) GLOBAL_MALLOC(sizeof(DataSetEntry));
if (self) {
char variableName[130]; char variableName[130];
StringUtils_copyStringMax(variableName, 130, variable); StringUtils_copyStringMax(variableName, 130, variable);
@ -791,6 +842,7 @@ DataSetEntry_create(DataSet* dataSet, const char* variable, int index, const cha
self->value = NULL; self->value = NULL;
DataSet_addEntry(dataSet, self); DataSet_addEntry(dataSet, self);
}
return self; return self;
} }
@ -838,8 +890,11 @@ IedModel_destroy(IedModel* model)
while (ld != NULL) { while (ld != NULL) {
if (ld->name)
GLOBAL_FREEMEM(ld->name);
if (ld->ldName) if (ld->ldName)
GLOBAL_FREEMEM (ld->name); GLOBAL_FREEMEM (ld->ldName);
LogicalNode* ln = (LogicalNode*) ld->firstChild; LogicalNode* ln = (LogicalNode*) ld->firstChild;

@ -185,6 +185,7 @@ searchCacheForValueEx(MmsValueCache self, const char* itemId, char* parentId, in
if (elementValue) { if (elementValue) {
if ((componentId != NULL) && (componentId[0] != 0)) { if ((componentId != NULL) && (componentId[0] != 0)) {
MmsVariableSpecification* childSpec = MmsVariableSpecification_getNamedVariableRecursive(typeSpec, childId); MmsVariableSpecification* childSpec = MmsVariableSpecification_getNamedVariableRecursive(typeSpec, childId);
if (childSpec) { if (childSpec) {
@ -234,13 +235,12 @@ MmsValueCache_lookupValueEx(MmsValueCache self, const char* itemId, int idx, con
char itemIdCopy[65]; char itemIdCopy[65];
char componentIdCopyBuf[65]; char componentIdCopyBuf[65];
StringUtils_copyStringToBuffer(itemId, itemIdCopy); StringUtils_copyStringMax(itemIdCopy, 65, itemId);
char* componentIdCopy = NULL; char* componentIdCopy = NULL;
if (componentId) { if (componentId) {
componentIdCopy = StringUtils_copyStringToBuffer(componentId, componentIdCopyBuf); componentIdCopy = StringUtils_copyStringMax(componentIdCopyBuf, 65, componentId);
} }
char* parentItemId = getParentSubString(itemIdCopy); char* parentItemId = getParentSubString(itemIdCopy);

Loading…
Cancel
Save