- IED server: extended config file format to support arrays of data objects (LIB61850-415)

pull/515/head
Michael Zillgith 1 year ago
parent 4eebcb96a2
commit f536d1c324

@ -1,7 +1,7 @@
/* /*
* config_file_parser.c * config_file_parser.c
* *
* Copyright 2014-2023 Michael Zillgith * Copyright 2014-2024 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -304,7 +304,6 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
currentModelNode = currentModelNode->parent; currentModelNode = currentModelNode->parent;
} }
} }
else if (indendation == 1) else if (indendation == 1)
{ {
if (StringUtils_startsWith((char*) lineBuffer, "LD")) if (StringUtils_startsWith((char*) lineBuffer, "LD"))
@ -514,8 +513,15 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
if (matchedItems != 2) goto exit_error; if (matchedItems != 2) goto exit_error;
currentModelNode = (ModelNode*) DataObject_create(nameString, currentModelNode, arrayElements); currentModelNode = (ModelNode*) DataObject_create(nameString, currentModelNode, arrayElements);
if (arrayElements > 0)
{
inArray = true;
currentArrayNode = currentModelNode;
}
} }
else if (StringUtils_startsWith((char*) lineBuffer, "[")) { else if (StringUtils_startsWith((char*) lineBuffer, "["))
{
if (inArray == false) { if (inArray == false) {
goto exit_error; goto exit_error;
} }
@ -526,6 +532,12 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
goto exit_error; goto exit_error;
} }
if (arrayIndex < 0) {
goto exit_error;
}
if (currentArrayNode->modelType == DataAttributeModelType)
{
if (StringUtils_endsWith((char*)lineBuffer, ";")) if (StringUtils_endsWith((char*)lineBuffer, ";"))
{ {
/* array of basic data attribute */ /* array of basic data attribute */
@ -551,6 +563,28 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
} }
} }
} }
else if (currentArrayNode->modelType == DataObjectModelType)
{
if (StringUtils_endsWith((char*)lineBuffer, "{"))
{
/* array of constructed data attribtute */
currentModelNode = ModelNode_getChildWithIdx(currentArrayNode, arrayIndex);
if (currentModelNode) {
inArrayElement = true;
}
else {
goto exit_error;
}
}
else
{
if (DEBUG_IED_SERVER)
printf("Unexpected character at end of line: %s\n", lineBuffer);
goto exit_error;
}
}
}
else if (StringUtils_startsWith((char*) lineBuffer, "DA")) else if (StringUtils_startsWith((char*) lineBuffer, "DA"))
{ {
int arrayElements = 0; int arrayElements = 0;
@ -567,7 +601,8 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
DataAttribute* dataAttribute = DataAttribute_create(nameString, currentModelNode, DataAttribute* dataAttribute = DataAttribute_create(nameString, currentModelNode,
(DataAttributeType) attributeType, (FunctionalConstraint) functionalConstraint, triggerOptions, arrayElements, sAddr); (DataAttributeType) attributeType, (FunctionalConstraint) functionalConstraint, triggerOptions, arrayElements, sAddr);
if (arrayElements > 0) { if (arrayElements > 0)
{
inArray = true; inArray = true;
currentArrayNode = (ModelNode*)dataAttribute; currentArrayNode = (ModelNode*)dataAttribute;
} }
@ -576,7 +611,8 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
int lineLength = (int) strlen((char*) lineBuffer); int lineLength = (int) strlen((char*) lineBuffer);
if (lineBuffer[lineLength - 1] == '{') { if (lineBuffer[lineLength - 1] == '{')
{
indendation++; indendation++;
currentModelNode = (ModelNode*) dataAttribute; currentModelNode = (ModelNode*) dataAttribute;
} }
@ -585,7 +621,8 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
{ {
char* start = strchr((char*) lineBuffer, '('); char* start = strchr((char*) lineBuffer, '(');
if (start) { if (start)
{
start++; start++;
StringUtils_copyStringMax(nameString, 130, start); StringUtils_copyStringMax(nameString, 130, start);
@ -598,7 +635,8 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
/* check for index */ /* check for index */
char* sep = strchr(nameString, ' '); char* sep = strchr(nameString, ' ');
if (sep) { if (sep)
{
char* indexStr = sep + 1; char* indexStr = sep + 1;
*sep = 0; *sep = 0;
@ -633,7 +671,6 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
if (StringUtils_createBufferFromHexString(nameString, (uint8_t*) nameString2) != 6) if (StringUtils_createBufferFromHexString(nameString, (uint8_t*) nameString2) != 6)
goto exit_error; goto exit_error;
PhyComAddress* dstAddress = PhyComAddress* dstAddress =
PhyComAddress_create((uint8_t) vlanPrio, (uint16_t) vlanId, (uint16_t) appId, PhyComAddress_create((uint8_t) vlanPrio, (uint16_t) vlanId, (uint16_t) appId,
(uint8_t*) nameString2); (uint8_t*) nameString2);

@ -1,7 +1,7 @@
/* /*
* dynamic_model.c * dynamic_model.c
* *
* Copyright 2014-2022 Michael Zillgith * Copyright 2014-2024 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -75,10 +75,12 @@ IedModel_addDataSet(IedModel* self, DataSet* dataSet)
{ {
if (self->dataSets == NULL) if (self->dataSets == NULL)
self->dataSets = dataSet; self->dataSets = dataSet;
else { else
{
DataSet* lastDataSet = self->dataSets; DataSet* lastDataSet = self->dataSets;
while (lastDataSet != NULL) { while (lastDataSet != NULL)
{
if (lastDataSet->sibling == NULL) { if (lastDataSet->sibling == NULL) {
lastDataSet->sibling = dataSet; lastDataSet->sibling = dataSet;
break; break;
@ -94,7 +96,8 @@ IedModel_addLogicalDevice(IedModel* self, LogicalDevice* lDevice)
{ {
if (self->firstChild == NULL) if (self->firstChild == NULL)
self->firstChild = lDevice; self->firstChild = lDevice;
else { else
{
LogicalDevice* sibling = self->firstChild; LogicalDevice* sibling = self->firstChild;
while (sibling->sibling != NULL) while (sibling->sibling != NULL)
@ -109,7 +112,8 @@ IedModel_addLog(IedModel* self, Log* log)
{ {
if (self->logs == NULL) if (self->logs == NULL)
self->logs = log; self->logs = log;
else { else
{
Log* lastLog = self->logs; Log* lastLog = self->logs;
while (lastLog->sibling != NULL) while (lastLog->sibling != NULL)
@ -124,7 +128,8 @@ IedModel_addLogControlBlock(IedModel* self, LogControlBlock* lcb)
{ {
if (self->lcbs == NULL) if (self->lcbs == NULL)
self->lcbs = lcb; self->lcbs = lcb;
else { else
{
LogControlBlock* lastLcb = self->lcbs; LogControlBlock* lastLcb = self->lcbs;
while (lastLcb->sibling != NULL) while (lastLcb->sibling != NULL)
@ -139,7 +144,8 @@ IedModel_addReportControlBlock(IedModel* self, ReportControlBlock* rcb)
{ {
if (self->rcbs == NULL) if (self->rcbs == NULL)
self->rcbs = rcb; self->rcbs = rcb;
else { else
{
ReportControlBlock* lastRcb = self->rcbs; ReportControlBlock* lastRcb = self->rcbs;
while (lastRcb->sibling != NULL) while (lastRcb->sibling != NULL)
@ -155,7 +161,8 @@ IedModel_addSettingGroupControlBlock(IedModel* self, SettingGroupControlBlock* s
{ {
if (self->sgcbs == NULL) if (self->sgcbs == NULL)
self->sgcbs = sgcb; self->sgcbs = sgcb;
else { else
{
SettingGroupControlBlock* lastSgcb = self->sgcbs; SettingGroupControlBlock* lastSgcb = self->sgcbs;
while (lastSgcb->sibling != NULL) while (lastSgcb->sibling != NULL)
@ -171,7 +178,8 @@ IedModel_addGSEControlBlock(IedModel* self, GSEControlBlock* gcb)
{ {
if (self->gseCBs == NULL) if (self->gseCBs == NULL)
self->gseCBs = gcb; self->gseCBs = gcb;
else { else
{
GSEControlBlock* lastGcb = self->gseCBs; GSEControlBlock* lastGcb = self->gseCBs;
while (lastGcb->sibling) while (lastGcb->sibling)
@ -187,7 +195,8 @@ IedModel_addSMVControlBlock(IedModel* self, SVControlBlock* smvcb)
if (self->svCBs == NULL) { if (self->svCBs == NULL) {
self->svCBs = smvcb; self->svCBs = smvcb;
} }
else { else
{
SVControlBlock* lastSvCB = self->svCBs; SVControlBlock* lastSvCB = self->svCBs;
while (lastSvCB->sibling) while (lastSvCB->sibling)
@ -202,7 +211,8 @@ LogicalDevice_createEx(const char* inst, IedModel* parent, const char* ldName)
{ {
LogicalDevice* self = (LogicalDevice*) GLOBAL_CALLOC(1, sizeof(LogicalDevice)); LogicalDevice* self = (LogicalDevice*) GLOBAL_CALLOC(1, sizeof(LogicalDevice));
if (self) { if (self)
{
self->name = StringUtils_copyString(inst); self->name = StringUtils_copyString(inst);
self->modelType = LogicalDeviceModelType; self->modelType = LogicalDeviceModelType;
self->parent = (ModelNode*) parent; self->parent = (ModelNode*) parent;
@ -257,7 +267,8 @@ LogicalNode_create(const char* name, LogicalDevice* parent)
{ {
LogicalNode* self = (LogicalNode*) GLOBAL_MALLOC(sizeof(LogicalNode)); LogicalNode* self = (LogicalNode*) GLOBAL_MALLOC(sizeof(LogicalNode));
if (self) { 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;
@ -311,7 +322,8 @@ Log_create(const char* name, LogicalNode* parent)
{ {
Log* self = (Log*) GLOBAL_MALLOC(sizeof(Log)); Log* self = (Log*) GLOBAL_MALLOC(sizeof(Log));
if (self) { if (self)
{
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->parent = parent; self->parent = parent;
self->sibling = NULL; self->sibling = NULL;
@ -336,7 +348,8 @@ 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) { if (self)
{
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->parent = parent; self->parent = parent;
self->sibling = NULL; self->sibling = NULL;
@ -388,7 +401,8 @@ 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) { if (self)
{
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->parent = parent; self->parent = parent;
@ -469,7 +483,8 @@ 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) { if (self)
{
self->parent = parent; self->parent = parent;
self->actSG = actSG; self->actSG = actSG;
self->numOfSGs = numOfSGs; self->numOfSGs = numOfSGs;
@ -497,7 +512,8 @@ 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) { if (self)
{
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->parent = parent; self->parent = parent;
@ -541,7 +557,8 @@ 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) { if (self)
{
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->parent = parent; self->parent = parent;
@ -587,7 +604,8 @@ 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) { if (self)
{
self->vlanPriority = vlanPriority; self->vlanPriority = vlanPriority;
self->vlanId = vlanId; self->vlanId = vlanId;
self->appId = appId; self->appId = appId;
@ -630,7 +648,8 @@ 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) { if (self)
{
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->modelType = DataObjectModelType; self->modelType = DataObjectModelType;
self->firstChild = NULL; self->firstChild = NULL;
@ -640,21 +659,23 @@ DataObject_create(const char* name, ModelNode* parent, int arrayElements)
self->elementCount = arrayElements; self->elementCount = arrayElements;
self->arrayIndex = -1; self->arrayIndex = -1;
if (arrayElements > 0) { if (arrayElements > 0)
{
int i; int i;
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) { if (arrayElement) {
self->name = NULL; arrayElement->name = NULL;
self->modelType = DataObjectModelType; arrayElement->modelType = DataObjectModelType;
self->firstChild = NULL; arrayElement->firstChild = NULL;
self->parent = parent; arrayElement->parent = (ModelNode*) self;
self->sibling = NULL; arrayElement->sibling = NULL;
self->elementCount = 0; arrayElement->elementCount = 0;
self->arrayIndex = i; arrayElement->arrayIndex = i;
DataObject_addChild(self, (ModelNode*) arrayElement); DataObject_addChild(self, (ModelNode*) arrayElement);
} }
@ -703,7 +724,8 @@ 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) { if (self)
{
self->name = StringUtils_copyString(name); self->name = StringUtils_copyString(name);
self->elementCount = arrayElements; self->elementCount = arrayElements;
self->arrayIndex = -1; self->arrayIndex = -1;
@ -717,13 +739,16 @@ DataAttribute_create(const char* name, ModelNode* parent, DataAttributeType type
self->triggerOptions = triggerOptions; self->triggerOptions = triggerOptions;
self->sAddr = sAddr; self->sAddr = sAddr;
if (arrayElements > 0) { if (arrayElements > 0)
{
int i; int i;
for (i = 0; i < arrayElements; i++) { for (i = 0; i < arrayElements; i++)
{
DataAttribute* arrayElement = (DataAttribute*) GLOBAL_MALLOC(sizeof(DataAttribute)); DataAttribute* arrayElement = (DataAttribute*) GLOBAL_MALLOC(sizeof(DataAttribute));
if (arrayElement) { if (arrayElement)
{
arrayElement->name = NULL; arrayElement->name = NULL;
arrayElement->elementCount = 0; arrayElement->elementCount = 0;
arrayElement->arrayIndex = i; arrayElement->arrayIndex = i;
@ -785,7 +810,8 @@ DataSet_create(const char* name, LogicalNode* parent)
{ {
DataSet* self = (DataSet*) GLOBAL_MALLOC(sizeof(DataSet)); DataSet* self = (DataSet*) GLOBAL_MALLOC(sizeof(DataSet));
if (self) { 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);
@ -831,11 +857,12 @@ DataSet_addEntry(DataSet* self, DataSetEntry* newEntry)
if (self->fcdas == NULL) if (self->fcdas == NULL)
self->fcdas = newEntry; self->fcdas = newEntry;
else { else
{
DataSetEntry* lastEntry = self->fcdas; DataSetEntry* lastEntry = self->fcdas;
while (lastEntry != NULL) { while (lastEntry != NULL)
{
if (lastEntry->sibling == NULL) { if (lastEntry->sibling == NULL) {
lastEntry->sibling = newEntry; lastEntry->sibling = newEntry;
break; break;
@ -851,21 +878,24 @@ 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) { if (self)
{
char variableName[130]; char variableName[130];
StringUtils_copyStringMax(variableName, 130, variable); StringUtils_copyStringMax(variableName, 130, variable);
char* separator = strchr(variableName, '/'); char* separator = strchr(variableName, '/');
if (separator != NULL) { if (separator != NULL)
{
*separator = 0; *separator = 0;
self->variableName = StringUtils_copyString(separator + 1); self->variableName = StringUtils_copyString(separator + 1);
self->logicalDeviceName = StringUtils_copyString(variableName); self->logicalDeviceName = StringUtils_copyString(variableName);
self->isLDNameDynamicallyAllocated = true; self->isLDNameDynamicallyAllocated = true;
} }
else { else
{
self->variableName = StringUtils_copyString(variable); self->variableName = StringUtils_copyString(variable);
self->logicalDeviceName = dataSet->logicalDeviceName; self->logicalDeviceName = dataSet->logicalDeviceName;
self->isLDNameDynamicallyAllocated = false; self->isLDNameDynamicallyAllocated = false;
@ -891,14 +921,15 @@ DataSetEntry_create(DataSet* dataSet, const char* variable, int index, const cha
static void static void
ModelNode_destroy(ModelNode* modelNode) ModelNode_destroy(ModelNode* modelNode)
{ {
if (modelNode) { if (modelNode)
{
if (modelNode->name) if (modelNode->name)
GLOBAL_FREEMEM(modelNode->name); GLOBAL_FREEMEM(modelNode->name);
ModelNode* currentChild = modelNode->firstChild; ModelNode* currentChild = modelNode->firstChild;
while (currentChild != NULL) { while (currentChild != NULL)
{
ModelNode* nextChild = currentChild->sibling; ModelNode* nextChild = currentChild->sibling;
ModelNode_destroy(currentChild); ModelNode_destroy(currentChild);
@ -906,7 +937,8 @@ ModelNode_destroy(ModelNode* modelNode)
currentChild = nextChild; currentChild = nextChild;
} }
if (modelNode->modelType == DataAttributeModelType) { if (modelNode->modelType == DataAttributeModelType)
{
DataAttribute* dataAttribute = (DataAttribute*) modelNode; DataAttribute* dataAttribute = (DataAttribute*) modelNode;
if (dataAttribute->mmsValue != NULL) { if (dataAttribute->mmsValue != NULL) {
@ -929,8 +961,8 @@ IedModel_destroy(IedModel* model)
LogicalDevice* ld = model->firstChild; LogicalDevice* ld = model->firstChild;
while (ld != NULL) { while (ld != NULL)
{
if (ld->name) if (ld->name)
GLOBAL_FREEMEM(ld->name); GLOBAL_FREEMEM(ld->name);
@ -939,7 +971,8 @@ IedModel_destroy(IedModel* model)
LogicalNode* ln = (LogicalNode*) ld->firstChild; LogicalNode* ln = (LogicalNode*) ld->firstChild;
while (ln != NULL) { while (ln != NULL)
{
GLOBAL_FREEMEM(ln->name); GLOBAL_FREEMEM(ln->name);
/* delete all data objects */ /* delete all data objects */
@ -960,7 +993,6 @@ IedModel_destroy(IedModel* model)
GLOBAL_FREEMEM(currentLn); GLOBAL_FREEMEM(currentLn);
} }
LogicalDevice* currentLd = ld; LogicalDevice* currentLd = ld;
ld = (LogicalDevice*) ld->sibling; ld = (LogicalDevice*) ld->sibling;
@ -1092,4 +1124,3 @@ IedModel_destroy(IedModel* model)
GLOBAL_FREEMEM(model); GLOBAL_FREEMEM(model);
} }
} }

@ -808,12 +808,14 @@ ModelNode_getChildWithIdx(ModelNode* self, int idx)
{ {
ModelNode* foundElement = NULL; ModelNode* foundElement = NULL;
if (self->modelType == DataObjectModelType || self->modelType == DataAttributeModelType) { if (self->modelType == DataObjectModelType || self->modelType == DataAttributeModelType)
{
ModelNode* nextNode = self->firstChild; ModelNode* nextNode = self->firstChild;
int currentIdx = 0; int currentIdx = 0;
while (nextNode) { while (nextNode)
{
if (currentIdx == idx) { if (currentIdx == idx) {
foundElement = nextNode; foundElement = nextNode;
break; break;
@ -845,14 +847,17 @@ ModelNode_getChildWithFc(ModelNode* self, const char* name, FunctionalConstraint
ModelNode* matchingNode = NULL; ModelNode* matchingNode = NULL;
while (nextNode != NULL) { while (nextNode != NULL)
{
int nodeNameLen = strlen(nextNode->name); int nodeNameLen = strlen(nextNode->name);
if (nodeNameLen == nameElementLength) { if (nodeNameLen == nameElementLength)
if (memcmp(nextNode->name, name, nodeNameLen) == 0) { {
if (memcmp(nextNode->name, name, nodeNameLen) == 0)
{
if (separator == NULL) { if (separator == NULL) {
if (nextNode->modelType == DataAttributeModelType) { if (nextNode->modelType == DataAttributeModelType)
{
DataAttribute* da = (DataAttribute*) nextNode; DataAttribute* da = (DataAttribute*) nextNode;
if (da->fc == fc) { if (da->fc == fc) {
@ -861,9 +866,10 @@ ModelNode_getChildWithFc(ModelNode* self, const char* name, FunctionalConstraint
} }
} }
} }
else { else
{
if (nextNode->modelType == DataAttributeModelType) { if (nextNode->modelType == DataAttributeModelType)
{
DataAttribute* da = (DataAttribute*) nextNode; DataAttribute* da = (DataAttribute*) nextNode;
if (da->fc == fc) { if (da->fc == fc) {

@ -3,7 +3,7 @@ package com.libiec61850.tools;
/* /*
* DynamicModelGenerator.java * DynamicModelGenerator.java
* *
* Copyright 2014-2020 Michael Zillgith * Copyright 2014-2024 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -447,11 +447,7 @@ public class DynamicModelGenerator {
output.println("}"); output.println("}");
} }
private void exportDataObject(PrintStream output, DataObject dataObject, boolean isTransient) { private void exportDataObjectChild(PrintStream output, DataObject dataObject, boolean isTransient) {
if (dataObject.isTransient())
isTransient = true;
for (DataObject subDataObject : dataObject.getSubDataObjects()) { for (DataObject subDataObject : dataObject.getSubDataObjects()) {
output.print("DO(" + subDataObject.getName() + " " + subDataObject.getCount() + "){\n"); output.print("DO(" + subDataObject.getName() + " " + subDataObject.getCount() + "){\n");
@ -465,36 +461,29 @@ public class DynamicModelGenerator {
} }
} }
private void exportDataAttribute(PrintStream output, DataAttribute dataAttribute, boolean isTransient) { private void exportDataObject(PrintStream output, DataObject dataObject, boolean isTransient) {
output.print("DA(" + dataAttribute.getName() + " ");
output.print(dataAttribute.getCount() + " ");
output.print(dataAttribute.getType().getIntValue() + " ");
output.print(dataAttribute.getFc().getIntValue() + " ");
int trgOpsVal = dataAttribute.getTriggerOptions().getIntValue(); if (dataObject.isTransient())
isTransient = true;
if (isTransient) if (dataObject.getCount() > 0) {
trgOpsVal += 128; /* data object is an array */
for (int i = 0; i < dataObject.getCount(); i++) {
output.print("[" + i + "]{\n");
output.print(trgOpsVal + " "); exportDataObjectChild(output, dataObject, isTransient);
Long sAddr = null; output.print("}\n");
}
try { }
if (dataAttribute.getShortAddress() != null) else {
sAddr = new Long(dataAttribute.getShortAddress()); exportDataObjectChild(output, dataObject, isTransient);
} catch (NumberFormatException e) {
System.out.println("WARNING: short address \"" + dataAttribute.getShortAddress() + "\" is not valid for libIEC61850!\n");
} }
if (sAddr != null) }
output.print(sAddr.longValue());
else
output.print("0");
output.print(")");
private void printDataAttributeValue(PrintStream output, DataAttribute dataAttribute, boolean isTransient)
{
if (dataAttribute.isBasicAttribute()) { if (dataAttribute.isBasicAttribute()) {
DataModelValue value = dataAttribute.getValue(); DataModelValue value = dataAttribute.getValue();
@ -569,7 +558,52 @@ public class DynamicModelGenerator {
output.println("}"); output.println("}");
} }
}
private void exportDataAttribute(PrintStream output, DataAttribute dataAttribute, boolean isTransient) {
output.print("DA(" + dataAttribute.getName() + " ");
output.print(dataAttribute.getCount() + " ");
output.print(dataAttribute.getType().getIntValue() + " ");
output.print(dataAttribute.getFc().getIntValue() + " ");
int trgOpsVal = dataAttribute.getTriggerOptions().getIntValue();
if (isTransient)
trgOpsVal += 128;
output.print(trgOpsVal + " ");
Long sAddr = null;
try {
if (dataAttribute.getShortAddress() != null)
sAddr = new Long(dataAttribute.getShortAddress());
} catch (NumberFormatException e) {
System.out.println("WARNING: short address \"" + dataAttribute.getShortAddress() + "\" is not valid for libIEC61850!\n");
}
if (sAddr != null)
output.print(sAddr.longValue());
else
output.print("0");
output.print(")");
if (dataAttribute.getCount() > 0) {
output.print("{\n");
for (int i = 0; i < dataAttribute.getCount(); i++) {
output.print("[" + i + "]");
printDataAttributeValue(output, dataAttribute, isTransient);
}
output.print("}\n");
}
else {
printDataAttributeValue(output, dataAttribute, isTransient);
}
} }
public static void main(String[] args) throws FileNotFoundException { public static void main(String[] args) throws FileNotFoundException {

Loading…
Cancel
Save