|
|
@ -1,7 +1,7 @@
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* config_file_parser.c
|
|
|
|
* config_file_parser.c
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Copyright 2014-2022 Michael Zillgith
|
|
|
|
* Copyright 2014-2023 Michael Zillgith
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This file is part of libIEC61850.
|
|
|
|
* This file is part of libIEC61850.
|
|
|
|
*
|
|
|
|
*
|
|
|
@ -28,6 +28,8 @@
|
|
|
|
#include "libiec61850_platform_includes.h"
|
|
|
|
#include "libiec61850_platform_includes.h"
|
|
|
|
#include "stack_config.h"
|
|
|
|
#include "stack_config.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
|
|
|
|
#define READ_BUFFER_MAX_SIZE 1024
|
|
|
|
#define READ_BUFFER_MAX_SIZE 1024
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
static int
|
|
|
@ -112,6 +114,112 @@ ConfigFileParser_createModelFromConfigFileEx(const char* filename)
|
|
|
|
return model;
|
|
|
|
return model;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
|
|
|
setValue(char* lineBuffer, DataAttribute* dataAttribute)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char* valueIndicator = strchr((char*) lineBuffer, '=');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (valueIndicator != NULL) {
|
|
|
|
|
|
|
|
switch (dataAttribute->type) {
|
|
|
|
|
|
|
|
case IEC61850_UNICODE_STRING_255:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char* stringStart = valueIndicator + 2;
|
|
|
|
|
|
|
|
terminateString(stringStart, '"');
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newMmsString(stringStart);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_VISIBLE_STRING_255:
|
|
|
|
|
|
|
|
case IEC61850_VISIBLE_STRING_129:
|
|
|
|
|
|
|
|
case IEC61850_VISIBLE_STRING_65:
|
|
|
|
|
|
|
|
case IEC61850_VISIBLE_STRING_64:
|
|
|
|
|
|
|
|
case IEC61850_VISIBLE_STRING_32:
|
|
|
|
|
|
|
|
case IEC61850_CURRENCY:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char* stringStart = valueIndicator + 2;
|
|
|
|
|
|
|
|
terminateString(stringStart, '"');
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newVisibleString(stringStart);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_INT8:
|
|
|
|
|
|
|
|
case IEC61850_INT16:
|
|
|
|
|
|
|
|
case IEC61850_INT32:
|
|
|
|
|
|
|
|
case IEC61850_INT64:
|
|
|
|
|
|
|
|
case IEC61850_INT128:
|
|
|
|
|
|
|
|
case IEC61850_ENUMERATED:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int32_t intValue;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%i", &intValue) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newIntegerFromInt32(intValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_INT8U:
|
|
|
|
|
|
|
|
case IEC61850_INT16U:
|
|
|
|
|
|
|
|
case IEC61850_INT24U:
|
|
|
|
|
|
|
|
case IEC61850_INT32U:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint32_t uintValue;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%u", &uintValue) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newUnsignedFromUint32(uintValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_FLOAT32:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
float floatValue;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%f", &floatValue) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newFloat(floatValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_FLOAT64:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
double doubleValue;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%lf", &doubleValue) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newDouble(doubleValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_BOOLEAN:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int boolean;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%i", &boolean) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newBoolean((bool) boolean);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_OPTFLDS:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int value;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%i", &value) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newBitString(-10);
|
|
|
|
|
|
|
|
MmsValue_setBitStringFromIntegerBigEndian(dataAttribute->mmsValue, value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_TRGOPS:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int value;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%i", &value) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newBitString(-6);
|
|
|
|
|
|
|
|
MmsValue_setBitStringFromIntegerBigEndian(dataAttribute->mmsValue, value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exit_error:
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
IedModel*
|
|
|
|
IedModel*
|
|
|
|
ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
|
|
|
|
ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -124,11 +232,14 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
|
|
|
|
|
|
|
|
|
|
|
|
bool stateInModel = false;
|
|
|
|
bool stateInModel = false;
|
|
|
|
int indendation = 0;
|
|
|
|
int indendation = 0;
|
|
|
|
|
|
|
|
bool inArray = false;
|
|
|
|
|
|
|
|
bool inArrayElement = false;
|
|
|
|
|
|
|
|
|
|
|
|
IedModel* model = NULL;
|
|
|
|
IedModel* model = NULL;
|
|
|
|
LogicalDevice* currentLD = NULL;
|
|
|
|
LogicalDevice* currentLD = NULL;
|
|
|
|
LogicalNode* currentLN = NULL;
|
|
|
|
LogicalNode* currentLN = NULL;
|
|
|
|
ModelNode* currentModelNode = NULL;
|
|
|
|
ModelNode* currentModelNode = NULL;
|
|
|
|
|
|
|
|
ModelNode* currentArrayNode = NULL;
|
|
|
|
DataSet* currentDataSet = NULL;
|
|
|
|
DataSet* currentDataSet = NULL;
|
|
|
|
GSEControlBlock* currentGoCB = NULL;
|
|
|
|
GSEControlBlock* currentGoCB = NULL;
|
|
|
|
SVControlBlock* currentSMVCB = NULL;
|
|
|
|
SVControlBlock* currentSMVCB = NULL;
|
|
|
@ -147,6 +258,18 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
|
|
|
|
if (bytesRead > 0) {
|
|
|
|
if (bytesRead > 0) {
|
|
|
|
lineBuffer[bytesRead] = 0;
|
|
|
|
lineBuffer[bytesRead] = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* trim trailing spaces */
|
|
|
|
|
|
|
|
while (bytesRead > 1) {
|
|
|
|
|
|
|
|
bytesRead--;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isspace(lineBuffer[bytesRead])) {
|
|
|
|
|
|
|
|
lineBuffer[bytesRead] = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (stateInModel) {
|
|
|
|
if (stateInModel) {
|
|
|
|
|
|
|
|
|
|
|
|
if (StringUtils_startsWith((char*) lineBuffer, "}")) {
|
|
|
|
if (StringUtils_startsWith((char*) lineBuffer, "}")) {
|
|
|
@ -164,11 +287,21 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
|
|
|
|
indendation = 3;
|
|
|
|
indendation = 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (indendation > 4) {
|
|
|
|
else if (indendation > 4) {
|
|
|
|
currentModelNode = currentModelNode->parent;
|
|
|
|
|
|
|
|
|
|
|
|
if (inArrayElement && currentModelNode->parent == currentArrayNode) {
|
|
|
|
|
|
|
|
inArrayElement = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
indendation--;
|
|
|
|
indendation--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (inArray && currentModelNode == currentArrayNode) {
|
|
|
|
|
|
|
|
inArray = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
currentModelNode = currentModelNode->parent;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else if (indendation == 1) {
|
|
|
|
else if (indendation == 1) {
|
|
|
|
if (StringUtils_startsWith((char*) lineBuffer, "LD")) {
|
|
|
|
if (StringUtils_startsWith((char*) lineBuffer, "LD")) {
|
|
|
|
indendation = 2;
|
|
|
|
indendation = 2;
|
|
|
@ -213,7 +346,9 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
|
|
|
|
|
|
|
|
|
|
|
|
int arrayElements = 0;
|
|
|
|
int arrayElements = 0;
|
|
|
|
|
|
|
|
|
|
|
|
sscanf((char*) lineBuffer, "DO(%129s %i)", nameString, &arrayElements);
|
|
|
|
if (sscanf((char*)lineBuffer, "DO(%129s %i)", nameString, &arrayElements) != 2) {
|
|
|
|
|
|
|
|
goto exit_error;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
currentModelNode = (ModelNode*)
|
|
|
|
currentModelNode = (ModelNode*)
|
|
|
|
DataObject_create(nameString, (ModelNode*) currentLN, arrayElements);
|
|
|
|
DataObject_create(nameString, (ModelNode*) currentLN, arrayElements);
|
|
|
@ -221,7 +356,10 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
|
|
|
|
else if (StringUtils_startsWith((char*) lineBuffer, "DS")) {
|
|
|
|
else if (StringUtils_startsWith((char*) lineBuffer, "DS")) {
|
|
|
|
indendation = 4;
|
|
|
|
indendation = 4;
|
|
|
|
|
|
|
|
|
|
|
|
sscanf((char*) lineBuffer, "DS(%129s)", nameString);
|
|
|
|
if (sscanf((char*)lineBuffer, "DS(%129s)", nameString) != 1) {
|
|
|
|
|
|
|
|
goto exit_error;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
terminateString(nameString, ')');
|
|
|
|
terminateString(nameString, ')');
|
|
|
|
|
|
|
|
|
|
|
|
currentDataSet = DataSet_create(nameString, currentLN);
|
|
|
|
currentDataSet = DataSet_create(nameString, currentLN);
|
|
|
@ -299,7 +437,6 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
|
|
|
|
nameString3, confRef, fixedOffs, minTime, maxTime);
|
|
|
|
nameString3, confRef, fixedOffs, minTime, maxTime);
|
|
|
|
|
|
|
|
|
|
|
|
indendation = 4;
|
|
|
|
indendation = 4;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (StringUtils_startsWith((char*) lineBuffer, "SMVC")) {
|
|
|
|
else if (StringUtils_startsWith((char*) lineBuffer, "SMVC")) {
|
|
|
|
uint32_t confRev;
|
|
|
|
uint32_t confRev;
|
|
|
@ -316,7 +453,6 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
|
|
|
|
currentSMVCB = SVControlBlock_create(nameString, currentLN, nameString2, nameString3, confRev, smpMod, smpRate, optFlds, (bool) isUnicast);
|
|
|
|
currentSMVCB = SVControlBlock_create(nameString, currentLN, nameString2, nameString3, confRev, smpMod, smpRate, optFlds, (bool) isUnicast);
|
|
|
|
|
|
|
|
|
|
|
|
indendation = 4;
|
|
|
|
indendation = 4;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#if (CONFIG_IEC61850_SETTING_GROUPS == 1)
|
|
|
|
#if (CONFIG_IEC61850_SETTING_GROUPS == 1)
|
|
|
|
else if (StringUtils_startsWith((char*) lineBuffer, "SG")) {
|
|
|
|
else if (StringUtils_startsWith((char*) lineBuffer, "SG")) {
|
|
|
@ -360,117 +496,64 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
|
|
|
|
|
|
|
|
|
|
|
|
currentModelNode = (ModelNode*) DataObject_create(nameString, currentModelNode, arrayElements);
|
|
|
|
currentModelNode = (ModelNode*) DataObject_create(nameString, currentModelNode, arrayElements);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (StringUtils_startsWith((char*) lineBuffer, "DA")) {
|
|
|
|
else if (StringUtils_startsWith((char*) lineBuffer, "[")) {
|
|
|
|
|
|
|
|
if (inArray == false) {
|
|
|
|
int arrayElements = 0;
|
|
|
|
goto exit_error;
|
|
|
|
|
|
|
|
}
|
|
|
|
int attributeType = 0;
|
|
|
|
|
|
|
|
int functionalConstraint = 0;
|
|
|
|
|
|
|
|
int triggerOptions = 0;
|
|
|
|
|
|
|
|
uint32_t sAddr = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sscanf((char*) lineBuffer, "DA(%129s %i %i %i %i %u)", nameString, &arrayElements, &attributeType, &functionalConstraint, &triggerOptions, &sAddr);
|
|
|
|
int arrayIndex;
|
|
|
|
|
|
|
|
|
|
|
|
DataAttribute* dataAttribute = DataAttribute_create(nameString, currentModelNode,
|
|
|
|
if (sscanf((char*)lineBuffer, "[%i]", &arrayIndex) != 1) {
|
|
|
|
(DataAttributeType) attributeType, (FunctionalConstraint) functionalConstraint, triggerOptions, arrayElements, sAddr);
|
|
|
|
goto exit_error;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char* valueIndicator = strchr((char*) lineBuffer, '=');
|
|
|
|
if (StringUtils_endsWith((char*)lineBuffer, ";")) {
|
|
|
|
|
|
|
|
/* array of basic data attribute */
|
|
|
|
|
|
|
|
ModelNode* arrayElementNode = ModelNode_getChildWithIdx(currentArrayNode, arrayIndex);
|
|
|
|
|
|
|
|
|
|
|
|
if (valueIndicator != NULL) {
|
|
|
|
if (arrayElementNode) {
|
|
|
|
switch (dataAttribute->type) {
|
|
|
|
setValue((char*)lineBuffer, (DataAttribute*)arrayElementNode);
|
|
|
|
case IEC61850_UNICODE_STRING_255:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char* stringStart = valueIndicator + 2;
|
|
|
|
|
|
|
|
terminateString(stringStart, '"');
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newMmsString(stringStart);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
else {
|
|
|
|
|
|
|
|
goto exit_error;
|
|
|
|
case IEC61850_VISIBLE_STRING_255:
|
|
|
|
|
|
|
|
case IEC61850_VISIBLE_STRING_129:
|
|
|
|
|
|
|
|
case IEC61850_VISIBLE_STRING_65:
|
|
|
|
|
|
|
|
case IEC61850_VISIBLE_STRING_64:
|
|
|
|
|
|
|
|
case IEC61850_VISIBLE_STRING_32:
|
|
|
|
|
|
|
|
case IEC61850_CURRENCY:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char* stringStart = valueIndicator + 2;
|
|
|
|
|
|
|
|
terminateString(stringStart, '"');
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newVisibleString(stringStart);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_INT8:
|
|
|
|
|
|
|
|
case IEC61850_INT16:
|
|
|
|
|
|
|
|
case IEC61850_INT32:
|
|
|
|
|
|
|
|
case IEC61850_INT64:
|
|
|
|
|
|
|
|
case IEC61850_INT128:
|
|
|
|
|
|
|
|
case IEC61850_ENUMERATED:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int32_t intValue;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%i", &intValue) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newIntegerFromInt32(intValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
else if (StringUtils_endsWith((char*)lineBuffer, "{")) {
|
|
|
|
|
|
|
|
/* array of constructed data attribtute */
|
|
|
|
|
|
|
|
currentModelNode = ModelNode_getChildWithIdx(currentArrayNode, arrayIndex);
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_INT8U:
|
|
|
|
if (currentModelNode) {
|
|
|
|
case IEC61850_INT16U:
|
|
|
|
inArrayElement = true;
|
|
|
|
case IEC61850_INT24U:
|
|
|
|
|
|
|
|
case IEC61850_INT32U:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint32_t uintValue;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%u", &uintValue) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newUnsignedFromUint32(uintValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
else {
|
|
|
|
|
|
|
|
goto exit_error;
|
|
|
|
case IEC61850_FLOAT32:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
float floatValue;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%f", &floatValue) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newFloat(floatValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_FLOAT64:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
double doubleValue;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%lf", &doubleValue) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newDouble(doubleValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_BOOLEAN:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int boolean;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%i", &boolean) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newBoolean((bool) boolean);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
else if (StringUtils_startsWith((char*) lineBuffer, "DA")) {
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_OPTFLDS:
|
|
|
|
int arrayElements = 0;
|
|
|
|
{
|
|
|
|
|
|
|
|
int value;
|
|
|
|
|
|
|
|
if (sscanf(valueIndicator + 1, "%i", &value) != 1) goto exit_error;
|
|
|
|
|
|
|
|
dataAttribute->mmsValue = MmsValue_newBitString(-10);
|
|
|
|
|
|
|
|
MmsValue_setBitStringFromIntegerBigEndian(dataAttribute->mmsValue, value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case IEC61850_TRGOPS:
|
|
|
|
int attributeType = 0;
|
|
|
|
{
|
|
|
|
int functionalConstraint = 0;
|
|
|
|
int value;
|
|
|
|
int triggerOptions = 0;
|
|
|
|
if (sscanf(valueIndicator + 1, "%i", &value) != 1) goto exit_error;
|
|
|
|
uint32_t sAddr = 0;
|
|
|
|
dataAttribute->mmsValue = MmsValue_newBitString(-6);
|
|
|
|
|
|
|
|
MmsValue_setBitStringFromIntegerBigEndian(dataAttribute->mmsValue, value);
|
|
|
|
if (sscanf((char*)lineBuffer, "DA(%129s %i %i %i %i %u)", nameString, &arrayElements, &attributeType, &functionalConstraint, &triggerOptions, &sAddr) != 6) {
|
|
|
|
|
|
|
|
goto exit_error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
DataAttribute* dataAttribute = DataAttribute_create(nameString, currentModelNode,
|
|
|
|
break;
|
|
|
|
(DataAttributeType) attributeType, (FunctionalConstraint) functionalConstraint, triggerOptions, arrayElements, sAddr);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
if (arrayElements > 0) {
|
|
|
|
|
|
|
|
inArray = true;
|
|
|
|
|
|
|
|
currentArrayNode = (ModelNode*)dataAttribute;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setValue((char*)lineBuffer, dataAttribute);
|
|
|
|
|
|
|
|
|
|
|
|
int lineLength = (int) strlen((char*) lineBuffer);
|
|
|
|
int lineLength = (int) strlen((char*) lineBuffer);
|
|
|
|
|
|
|
|
|
|
|
|
if (lineBuffer[lineLength - 1] == '{') {
|
|
|
|
if (lineBuffer[lineLength - 1] == '{') {
|
|
|
@ -553,7 +636,9 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle)
|
|
|
|
indendation = 1;
|
|
|
|
indendation = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (StringUtils_startsWith((char*) lineBuffer, "MODEL(")) {
|
|
|
|
else if (StringUtils_startsWith((char*) lineBuffer, "MODEL(")) {
|
|
|
|
sscanf((char*) lineBuffer, "MODEL(%129s)", nameString);
|
|
|
|
if (sscanf((char*)lineBuffer, "MODEL(%129s)", nameString) != 1)
|
|
|
|
|
|
|
|
goto exit_error;
|
|
|
|
|
|
|
|
|
|
|
|
terminateString(nameString, ')');
|
|
|
|
terminateString(nameString, ')');
|
|
|
|
model = IedModel_create(nameString);
|
|
|
|
model = IedModel_create(nameString);
|
|
|
|
stateInModel = true;
|
|
|
|
stateInModel = true;
|
|
|
|