From 665501c9faf57474a4d57ac2447e698ac2f4545b Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Thu, 13 Jul 2023 19:36:43 +0100 Subject: [PATCH 01/12] - extended data model helper function to be able to be used in array elements --- src/iec61850/server/model/cdc.c | 87 ++++++++++++++++----------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/src/iec61850/server/model/cdc.c b/src/iec61850/server/model/cdc.c index 122fa8bd..211e925e 100644 --- a/src/iec61850/server/model/cdc.c +++ b/src/iec61850/server/model/cdc.c @@ -3,7 +3,7 @@ * * Helper functions for the dynamic creation of Common Data Classes (CDCs) * - * Copyright 2014 Michael Zillgith + * Copyright 2014-2023 Michael Zillgith * * This file is part of libIEC61850. * @@ -35,7 +35,7 @@ DataAttribute* CAC_AnalogueValue_create(const char* name, ModelNode* parent, FunctionalConstraint fc, uint8_t triggerOptions, bool isIntegerNotFloat) { - DataAttribute* analogeValue = DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, fc, triggerOptions, 0, 0); + DataAttribute* analogeValue = (name == NULL) ? (DataAttribute*)parent : DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, fc, triggerOptions, 0, 0); if (isIntegerNotFloat) DataAttribute_create("i", (ModelNode*) analogeValue, IEC61850_INT32, fc, triggerOptions, 0, 0); @@ -48,7 +48,7 @@ CAC_AnalogueValue_create(const char* name, ModelNode* parent, FunctionalConstrai DataAttribute* CAC_ValWithTrans_create(const char* name, ModelNode* parent, FunctionalConstraint fc, uint8_t triggerOptions, bool hasTransientIndicator) { - DataAttribute* valWithTrans = DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, fc, triggerOptions, 0, 0); + DataAttribute* valWithTrans = (name == NULL) ? (DataAttribute*)parent : DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, fc, triggerOptions, 0, 0); DataAttribute_create("posVal", (ModelNode*) valWithTrans, IEC61850_INT8, fc, triggerOptions, 0, 0); @@ -64,7 +64,7 @@ CAC_ValWithTrans_create(const char* name, ModelNode* parent, FunctionalConstrain DataAttribute* CAC_Vector_create(const char* name, ModelNode* parent, uint32_t options, FunctionalConstraint fc, uint8_t triggerOptions) { - DataAttribute* vector = DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, fc, triggerOptions, 0, 0); + DataAttribute* vector = (name == NULL) ? (DataAttribute*)parent : DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, fc, triggerOptions, 0, 0); CAC_AnalogueValue_create("mag", (ModelNode*) vector, fc, triggerOptions, false); @@ -77,7 +77,7 @@ CAC_Vector_create(const char* name, ModelNode* parent, uint32_t options, Functio DataAttribute* CAC_Point_create(const char* name, ModelNode* parent, FunctionalConstraint fc, uint8_t triggerOptions, bool hasZVal) { - DataAttribute* point = DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, fc, triggerOptions, 0, 0); + DataAttribute* point = (name == NULL) ? (DataAttribute*)parent : DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, fc, triggerOptions, 0, 0); DataAttribute_create("xVal", (ModelNode*) point, IEC61850_FLOAT32, fc, triggerOptions, 0, 0); DataAttribute_create("yVal", (ModelNode*) point, IEC61850_FLOAT32, fc, triggerOptions, 0, 0); @@ -91,7 +91,7 @@ CAC_Point_create(const char* name, ModelNode* parent, FunctionalConstraint fc, u DataAttribute* CAC_ScaledValueConfig_create(const char* name, ModelNode* parent) { - DataAttribute* scaling = DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, IEC61850_FC_CF, TRG_OPT_DATA_CHANGED, 0, 0); + DataAttribute* scaling = (name == NULL) ? (DataAttribute*)parent : DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, IEC61850_FC_CF, TRG_OPT_DATA_CHANGED, 0, 0); DataAttribute_create("scaleFactor", (ModelNode*) scaling, IEC61850_FLOAT32, IEC61850_FC_CF, TRG_OPT_DATA_CHANGED, 0, 0); DataAttribute_create("offset", (ModelNode*) scaling, IEC61850_FLOAT32, IEC61850_FC_CF, TRG_OPT_DATA_CHANGED, 0, 0); @@ -102,7 +102,7 @@ CAC_ScaledValueConfig_create(const char* name, ModelNode* parent) DataAttribute* CAC_Unit_create(const char* name, ModelNode* parent, bool hasMagnitude) { - DataAttribute* unit = DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, IEC61850_FC_CF, TRG_OPT_DATA_CHANGED, 0, 0); + DataAttribute* unit = (name == NULL) ? (DataAttribute*)parent : DataAttribute_create(name, parent, IEC61850_CONSTRUCTED, IEC61850_FC_CF, TRG_OPT_DATA_CHANGED, 0, 0); DataAttribute_create("SIUnit", (ModelNode*) unit, IEC61850_ENUMERATED, IEC61850_FC_CF, TRG_OPT_DATA_CHANGED, 0, 0); @@ -255,7 +255,7 @@ CDC_addStandardOptions(DataObject* dataObject, uint32_t options) DataObject* CDC_SPS_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newSPS = DataObject_create(dataObjectName, parent, 0); + DataObject* newSPS = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CDC_addStatusToDataObject(newSPS, IEC61850_BOOLEAN); @@ -273,7 +273,7 @@ CDC_SPS_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_DPS_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newDPS = DataObject_create(dataObjectName, parent, 0); + DataObject* newDPS = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CDC_addStatusToDataObject(newDPS, IEC61850_CODEDENUM); @@ -291,7 +291,7 @@ CDC_DPS_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_INS_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newINS = DataObject_create(dataObjectName, parent, 0); + DataObject* newINS = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CDC_addStatusToDataObject(newINS, IEC61850_INT32); @@ -310,7 +310,7 @@ CDC_INS_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_ENS_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newENS = DataObject_create(dataObjectName, parent, 0); + DataObject* newENS = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CDC_addStatusToDataObject(newENS, IEC61850_ENUMERATED); @@ -328,7 +328,7 @@ CDC_ENS_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_BCR_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newBCR = DataObject_create(dataObjectName, parent, 0); + DataObject* newBCR = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); DataAttribute_create("actVal", (ModelNode*) newBCR, IEC61850_INT64, IEC61850_FC_ST, TRG_OPT_DATA_CHANGED, 0, 0); @@ -359,7 +359,7 @@ CDC_BCR_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_SEC_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newSEC = DataObject_create(dataObjectName, parent, 0); + DataObject* newSEC = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); DataAttribute_create("cnt", (ModelNode*) newSEC, IEC61850_INT32U, IEC61850_FC_ST, TRG_OPT_DATA_CHANGED, 0, 0); DataAttribute_create("sev", (ModelNode*) newSEC, IEC61850_ENUMERATED, IEC61850_FC_ST, 0, 0, 0); @@ -380,7 +380,7 @@ CDC_SEC_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_VSS_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newSPS = DataObject_create(dataObjectName, parent, 0); + DataObject* newSPS = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CDC_addStatusToDataObject(newSPS, IEC61850_VISIBLE_STRING_255); @@ -403,7 +403,7 @@ CDC_VSS_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_MV_create(const char* dataObjectName, ModelNode* parent, uint32_t options, bool isIntegerNotFloat) { - DataObject* newMV = DataObject_create(dataObjectName, parent, 0); + DataObject* newMV = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); if (options & CDC_OPTION_INST_MAG) CAC_AnalogueValue_create("instMag", (ModelNode*) newMV, IEC61850_FC_MX, 0, isIntegerNotFloat); @@ -432,7 +432,7 @@ CDC_MV_create(const char* dataObjectName, ModelNode* parent, uint32_t options, b DataObject* CDC_CMV_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newMV = DataObject_create(dataObjectName, parent, 0); + DataObject* newMV = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); if (options & CDC_OPTION_INST_MAG) CAC_Vector_create("instCVal", (ModelNode*) newMV, options, IEC61850_FC_MX, 0); @@ -465,7 +465,7 @@ CDC_CMV_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_SAV_create(const char* dataObjectName, ModelNode* parent, uint32_t options, bool isIntegerNotFloat) { - DataObject* newSAV = DataObject_create(dataObjectName, parent, 0); + DataObject* newSAV = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CAC_AnalogueValue_create("instMag", (ModelNode*) newSAV, IEC61850_FC_MX, 0, isIntegerNotFloat); @@ -491,7 +491,7 @@ CDC_SAV_create(const char* dataObjectName, ModelNode* parent, uint32_t options, DataObject* CDC_HST_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint16_t maxPts) { - DataObject* newHST = DataObject_create(dataObjectName, parent, 0); + DataObject* newHST = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); DataAttribute_create("hstVal", (ModelNode*) newHST, IEC61850_INT32, IEC61850_FC_ST, TRG_OPT_DATA_CHANGED | TRG_OPT_DATA_UPDATE, maxPts, 0); @@ -577,7 +577,7 @@ addCommonControlAttributes(DataObject* dobj, uint32_t controlOptions) DataObject* CDC_SPC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions) { - DataObject* newSPC = DataObject_create(dataObjectName, parent, 0); + DataObject* newSPC = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); addOriginatorAndCtlNumOptions((ModelNode*) newSPC, controlOptions); @@ -613,7 +613,7 @@ CDC_SPC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, DataObject* CDC_DPC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions) { - DataObject* newDPC = DataObject_create(dataObjectName, parent, 0); + DataObject* newDPC = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); addOriginatorAndCtlNumOptions((ModelNode*) newDPC, controlOptions); @@ -695,7 +695,7 @@ addControlStatusAttributesForAnalogControl(DataObject* dobj, uint32_t controlOpt DataObject* CDC_APC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool isIntegerNotFloat) { - DataObject* newAPC = DataObject_create(dataObjectName, parent, 0); + DataObject* newAPC = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); addControlStatusAttributesForAnalogControl(newAPC, controlOptions); @@ -728,7 +728,7 @@ CDC_APC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, DataObject* CDC_INC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions) { - DataObject* newINC = DataObject_create(dataObjectName, parent, 0); + DataObject* newINC = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); addOriginatorAndCtlNumOptions((ModelNode*) newINC, controlOptions); @@ -764,7 +764,7 @@ CDC_INC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, DataObject* CDC_ENC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions) { - DataObject* newENC = DataObject_create(dataObjectName, parent, 0); + DataObject* newENC = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); addOriginatorAndCtlNumOptions((ModelNode*) newENC, controlOptions); @@ -791,7 +791,7 @@ CDC_ENC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, DataObject* CDC_BSC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool hasTransientIndicator) { - DataObject* newBSC = DataObject_create(dataObjectName, parent, 0); + DataObject* newBSC = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); addOriginatorAndCtlNumOptions((ModelNode*) newBSC, controlOptions); @@ -821,7 +821,7 @@ CDC_BSC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, DataObject* CDC_ISC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool hasTransientIndicator) { - DataObject* newISC = DataObject_create(dataObjectName, parent, 0); + DataObject* newISC = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); addOriginatorAndCtlNumOptions((ModelNode*) newISC, controlOptions); @@ -855,7 +855,7 @@ CDC_ISC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, DataObject* CDC_BAC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool isIntegerNotFloat) { - DataObject* newBAC = DataObject_create(dataObjectName, parent, 0); + DataObject* newBAC = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); addControlStatusAttributesForAnalogControl(newBAC, controlOptions); @@ -899,7 +899,7 @@ CDC_BAC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, DataObject* CDC_LPL_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newLPL = DataObject_create(dataObjectName, parent, 0); + DataObject* newLPL = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); DataAttribute_create("vendor", (ModelNode*) newLPL, IEC61850_VISIBLE_STRING_255, IEC61850_FC_DC, 0, 0, 0); DataAttribute_create("swRev", (ModelNode*) newLPL, IEC61850_VISIBLE_STRING_255, IEC61850_FC_DC, 0, 0, 0); @@ -921,7 +921,7 @@ CDC_LPL_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_DPL_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newDPL = DataObject_create(dataObjectName, parent, 0); + DataObject* newDPL = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); DataAttribute_create("vendor", (ModelNode*) newDPL, IEC61850_VISIBLE_STRING_255, IEC61850_FC_DC, 0, 0, 0); @@ -949,7 +949,7 @@ CDC_DPL_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_ACD_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newACD = DataObject_create(dataObjectName, parent, 0); + DataObject* newACD = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); DataAttribute_create("general", (ModelNode*) newACD, IEC61850_BOOLEAN, IEC61850_FC_ST, TRG_OPT_DATA_CHANGED, 0, 0); DataAttribute_create("dirGeneral", (ModelNode*) newACD, IEC61850_ENUMERATED, IEC61850_FC_ST, TRG_OPT_DATA_CHANGED, 0, 0); @@ -984,7 +984,7 @@ CDC_ACD_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_ACT_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newACT = DataObject_create(dataObjectName, parent, 0); + DataObject* newACT = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); DataAttribute_create("general", (ModelNode*) newACT, IEC61850_BOOLEAN, IEC61850_FC_ST, TRG_OPT_DATA_CHANGED, 0, 0); @@ -1010,7 +1010,7 @@ CDC_ACT_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_WYE_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newWYE = DataObject_create(dataObjectName, parent, 0); + DataObject* newWYE = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); /* TODO check if some options should be masked */ /* TODO take care for GC_1 */ @@ -1033,7 +1033,7 @@ CDC_WYE_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_DEL_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newDEL = DataObject_create(dataObjectName, parent, 0); + DataObject* newDEL = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); /* TODO check if some options should be masked */ CDC_CMV_create("phsAB", (ModelNode*) newDEL, options); @@ -1052,7 +1052,7 @@ CDC_DEL_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_SPG_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newSPG = DataObject_create(dataObjectName, parent, 0); + DataObject* newSPG = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); DataAttribute_create("setVal", (ModelNode*) newSPG, IEC61850_BOOLEAN, IEC61850_FC_SP, TRG_OPT_DATA_CHANGED, 0, 0); @@ -1064,7 +1064,7 @@ CDC_SPG_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_VSG_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newSPG = DataObject_create(dataObjectName, parent, 0); + DataObject* newSPG = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); DataAttribute_create("setVal", (ModelNode*) newSPG, IEC61850_VISIBLE_STRING_255, IEC61850_FC_SP, TRG_OPT_DATA_CHANGED, 0, 0); @@ -1077,7 +1077,7 @@ CDC_VSG_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_ENG_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newENG = DataObject_create(dataObjectName, parent, 0); + DataObject* newENG = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); DataAttribute_create("setVal", (ModelNode*) newENG, IEC61850_ENUMERATED, IEC61850_FC_SP, TRG_OPT_DATA_CHANGED, 0, 0); @@ -1089,7 +1089,7 @@ CDC_ENG_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_ING_create(const char* dataObjectName, ModelNode* parent, uint32_t options) { - DataObject* newING = DataObject_create(dataObjectName, parent, 0); + DataObject* newING = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); DataAttribute_create("setVal", (ModelNode*) newING, IEC61850_INT32, IEC61850_FC_SP, TRG_OPT_DATA_CHANGED, 0, 0); @@ -1114,7 +1114,7 @@ CDC_ING_create(const char* dataObjectName, ModelNode* parent, uint32_t options) DataObject* CDC_ASG_create(const char* dataObjectName, ModelNode* parent, uint32_t options, bool isIntegerNotFloat) { - DataObject* newASG = DataObject_create(dataObjectName, parent, 0); + DataObject* newASG = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CAC_AnalogueValue_create("setMag", (ModelNode*) newASG, IEC61850_FC_SP, TRG_OPT_DATA_CHANGED, isIntegerNotFloat); @@ -1145,7 +1145,7 @@ CDC_ASG_create(const char* dataObjectName, ModelNode* parent, uint32_t options, DataObject* CDC_SPV_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, uint32_t wpOptions, bool hasChaManRs) { - DataObject* newSPV = DataObject_create(dataObjectName, parent, 0); + DataObject* newSPV = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); if (hasChaManRs) CDC_SPC_create("chaManRs", (ModelNode*) newSPV, 0, CDC_CTL_MODEL_DIRECT_NORMAL); @@ -1196,7 +1196,7 @@ CDC_STV_create(const char* dataObjectName, ModelNode* parent, (void)controlOptions; /* TODO implement */ (void)wpOptions; /* TODO implement */ - DataObject* newSTV = DataObject_create(dataObjectName, parent, 0); + DataObject* newSTV = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CDC_INS_create("actSt", (ModelNode*) newSTV, 0); @@ -1218,7 +1218,7 @@ CDC_ALM_create(const char* dataObjectName, ModelNode* parent, (void)controlOptions; /* TODO implement */ (void)wpOptions; /* TODO implement */ - DataObject* newALM = DataObject_create(dataObjectName, parent, 0); + DataObject* newALM = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CDC_SPC_create("almAck", (ModelNode*) newALM, 0, CDC_CTL_MODEL_DIRECT_NORMAL | CDC_CTL_OPTION_ORIGIN); @@ -1244,7 +1244,7 @@ CDC_CMD_create(const char* dataObjectName, ModelNode* parent, (void)hasCmTm; /* TODO implement */ (void)hasCmCt; /* TODO implement */ - DataObject* newCMD = DataObject_create(dataObjectName, parent, 0); + DataObject* newCMD = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CDC_INC_create("actSt", (ModelNode*) newCMD, 0, controlOptions); @@ -1272,7 +1272,7 @@ CDC_CTE_create(const char* dataObjectName, ModelNode* parent, { (void)controlOptions; /* TODO implement */ - DataObject* newCTE = DataObject_create(dataObjectName, parent, 0); + DataObject* newCTE = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CDC_SPC_create("manRs", (ModelNode*) newCTE, 0, CDC_CTL_MODEL_DIRECT_NORMAL | CDC_CTL_OPTION_ORIGIN); @@ -1313,7 +1313,7 @@ CDC_TMS_create(const char* dataObjectName, ModelNode* parent, { (void)controlOptions; /* TODO implement */ - DataObject* newTMS = DataObject_create(dataObjectName, parent, 0); + DataObject* newTMS = (dataObjectName == NULL) ? (DataObject*)parent : DataObject_create(dataObjectName, parent, 0); CDC_SPC_create("manRs", (ModelNode*) newTMS, 0, CDC_CTL_MODEL_DIRECT_NORMAL | CDC_CTL_OPTION_ORIGIN); @@ -1344,4 +1344,3 @@ CDC_TMS_create(const char* dataObjectName, ModelNode* parent, return newTMS; } - From 5a24981048dc063bc96c3f14400ff4b5bc2df093 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Sun, 30 Jul 2023 19:01:32 +0100 Subject: [PATCH 02/12] - IED server: added code to create SMVCBs with the dynamic model API (LIB61850-67) --- src/iec61850/server/model/dynamic_model.c | 33 +++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/iec61850/server/model/dynamic_model.c b/src/iec61850/server/model/dynamic_model.c index 790c9be3..68710320 100644 --- a/src/iec61850/server/model/dynamic_model.c +++ b/src/iec61850/server/model/dynamic_model.c @@ -166,7 +166,6 @@ IedModel_addSettingGroupControlBlock(IedModel* self, SettingGroupControlBlock* s } #endif /* (CONFIG_IEC61850_SETTING_GROUPS == 1) */ - static void IedModel_addGSEControlBlock(IedModel* self, GSEControlBlock* gcb) { @@ -175,13 +174,29 @@ IedModel_addGSEControlBlock(IedModel* self, GSEControlBlock* gcb) else { GSEControlBlock* lastGcb = self->gseCBs; - while (lastGcb->sibling != NULL) + while (lastGcb->sibling) lastGcb = lastGcb->sibling; lastGcb->sibling = gcb; } } +static void +IedModel_addSMVControlBlock(IedModel* self, SVControlBlock* smvcb) +{ + if (self->svCBs == NULL) { + self->svCBs = smvcb; + } + else { + SVControlBlock* lastSvCB = self->svCBs; + + while (lastSvCB->sibling) + lastSvCB = lastSvCB->sibling; + + lastSvCB->sibling = smvcb; + } +} + LogicalDevice* LogicalDevice_createEx(const char* inst, IedModel* parent, const char* ldName) { @@ -512,6 +527,14 @@ GSEControlBlock_create(const char* name, LogicalNode* parent, const char* appId, return self; } +static void +LogicalNode_addSMVControlBlock(LogicalNode* self, SVControlBlock* smvcb) +{ + IedModel* model = (IedModel*) self->parent->parent; + + IedModel_addSMVControlBlock(model, smvcb); +} + SVControlBlock* SVControlBlock_create(const char* name, LogicalNode* parent, const char* svID, const char* dataSet, uint32_t confRev, uint8_t smpMod, uint16_t smpRate, uint8_t optFlds, bool isUnicast) @@ -536,6 +559,12 @@ SVControlBlock_create(const char* name, LogicalNode* parent, const char* svID, c self->optFlds = optFlds; self->isUnicast = isUnicast; + + self->dstAddress = NULL; + self->sibling = NULL; + + if (parent) + LogicalNode_addSMVControlBlock(parent, self); } return self; From 405124b8d90d3243121363a1008a3a82b50a220f Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Sun, 30 Jul 2023 19:04:39 +0100 Subject: [PATCH 03/12] - config file generator: added code to add SMVCBs to config files (LIB61850-67) --- .../scl/communication/ConnectedAP.java | 14 +++++- .../tools/DynamicModelGenerator.java | 48 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java b/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java index d9765b04..b3cf608d 100644 --- a/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java +++ b/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java @@ -85,7 +85,7 @@ public class ConnectedAP { public List getSmvs() { return smvs; } - + public GSE lookupGSE(String logicalDeviceName, String name) { for (GSE gse : this.getGses()) { @@ -97,6 +97,18 @@ public class ConnectedAP { return null; } + + public SMV lookupSMV(String logicalDeviceName, String name) { + + for (SMV smv : this.getSmvs()) { + if (smv.getLdInst().equals(logicalDeviceName)) { + if (smv.getCbName().equals(name)) + return smv; + } + } + + return null; + } public PhyComAddress lookupSMVAddress(String logicalDeviceName, String name) { diff --git a/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java b/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java index cd1d4593..e94ca7ab 100644 --- a/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java +++ b/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java @@ -37,6 +37,7 @@ import com.libiec61850.scl.SclParserException; import com.libiec61850.scl.communication.ConnectedAP; import com.libiec61850.scl.communication.GSE; import com.libiec61850.scl.communication.PhyComAddress; +import com.libiec61850.scl.communication.SMV; import com.libiec61850.scl.model.AccessPoint; import com.libiec61850.scl.model.DataAttribute; import com.libiec61850.scl.model.DataModelValue; @@ -51,6 +52,7 @@ import com.libiec61850.scl.model.LogicalDevice; import com.libiec61850.scl.model.LogicalNode; import com.libiec61850.scl.model.ReportControlBlock; import com.libiec61850.scl.model.ReportSettings; +import com.libiec61850.scl.model.SampledValueControl; import com.libiec61850.scl.model.Services; import com.libiec61850.scl.model.SettingControl; @@ -166,6 +168,52 @@ public class DynamicModelGenerator { for (Log log : logicalNode.getLogs()) output.println("LOG(" + log.getName() + ");"); + + for (SampledValueControl svcb : logicalNode.getSampledValueControlBlocks()) { + LogicalDevice ld = logicalNode.getParentLogicalDevice(); + + SMV smv = null; + PhyComAddress smvAddress = null; + + if (connectedAP != null) { + smv = connectedAP.lookupSMV(ld.getInst(), svcb.getName()); + + if (smv != null) + smvAddress = smv.getAddress(); + } + else + System.out.println("WARNING: IED \"" + ied.getName() + "\" has no connected access point!"); + + output.print("SMVC("); + output.print(svcb.getName() + " "); + output.print(svcb.getSmvID() + " "); + output.print(svcb.getDatSet() + " "); + output.print(svcb.getConfRev() + " "); + output.print("0" + " "); + output.print(svcb.getSmpRate() + " "); + output.print(svcb.getSmvOpts().getIntValue() + " "); + output.print(svcb.isMulticast() ? "0" : "1"); + output.print(")"); + + if (smvAddress != null) { + output.println("{"); + + output.print("PA("); + output.print(smvAddress.getVlanPriority() + " "); + output.print(smvAddress.getVlanId() + " "); + output.print(smvAddress.getAppId() + " "); + + for (int i = 0; i < 6; i++) + output.printf("%02x", smvAddress.getMacAddress()[i]); + + output.println(");"); + + output.println("}"); + } + else { + output.println(";"); + } + } for (GSEControl gcb : logicalNode.getGSEControlBlocks()) { LogicalDevice ld = logicalNode.getParentLogicalDevice(); From 0622bae0f6eda6611352621bdc094f8b99fefa72 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Sun, 30 Jul 2023 20:02:37 +0100 Subject: [PATCH 04/12] - config file generator/static model generator: added support for SampledValueControl.smpMod (LIB61850-67) --- examples/iec61850_9_2_LE_example/sv.icd | 2 +- .../scl/model/SampledValueControl.java | 31 +++++++--- .../src/com/libiec61850/scl/model/SmpMod.java | 56 +++++++++++++++++++ .../tools/DynamicModelGenerator.java | 2 +- .../tools/StaticModelGenerator.java | 4 +- 5 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 tools/model_generator/src/com/libiec61850/scl/model/SmpMod.java diff --git a/examples/iec61850_9_2_LE_example/sv.icd b/examples/iec61850_9_2_LE_example/sv.icd index b52f8d92..af5fe962 100644 --- a/examples/iec61850_9_2_LE_example/sv.icd +++ b/examples/iec61850_9_2_LE_example/sv.icd @@ -93,7 +93,7 @@ SCL.xsd"> + smvID="xxxxMUnn01" smpRate="80" nofASDU="1" confRev="1" smpMod="SmpPerPeriod"> diff --git a/tools/model_generator/src/com/libiec61850/scl/model/SampledValueControl.java b/tools/model_generator/src/com/libiec61850/scl/model/SampledValueControl.java index f2f03b66..6ef8c29b 100644 --- a/tools/model_generator/src/com/libiec61850/scl/model/SampledValueControl.java +++ b/tools/model_generator/src/com/libiec61850/scl/model/SampledValueControl.java @@ -16,9 +16,8 @@ public class SampledValueControl { private int nofASDU; private boolean multicast = false; private SmvOpts smvOpts; - - - + private SmpMod smpMod = SmpMod.SMP_PER_PERIOD; + public SampledValueControl(Node smvControlNode) throws SclParserException { this.name = ParserUtils.parseAttribute(smvControlNode, "name"); this.desc = ParserUtils.parseAttribute(smvControlNode, "desc"); @@ -49,10 +48,25 @@ public class SampledValueControl { Node smvOptsNode = ParserUtils.getChildNodeWithTag(smvControlNode, "SmvOpts"); this.smvOpts = new SmvOpts(smvOptsNode); + + String smpModString = ParserUtils.parseAttribute(smvControlNode, "smpMod"); + + if (smpModString != null) { + if (smpModString.equals("SmpPerPeriod")) { + smpMod = SmpMod.SMP_PER_PERIOD; + } + else if (smpModString.equals("SmpPerSec")) { + smpMod = SmpMod.SMP_PER_SECOND; + } + else if (smpModString.equals("SecPerSmp")) { + smpMod = SmpMod.SEC_PER_SMP; + } + else { + throw new SclParserException(smvControlNode, "Invalid smpMod value " + smpModString); + } + } } - - - + public String getName() { return name; } @@ -88,5 +102,8 @@ public class SampledValueControl { public SmvOpts getSmvOpts() { return smvOpts; } - + + public SmpMod getSmpMod() { + return smpMod; + } } diff --git a/tools/model_generator/src/com/libiec61850/scl/model/SmpMod.java b/tools/model_generator/src/com/libiec61850/scl/model/SmpMod.java new file mode 100644 index 00000000..4de9f6eb --- /dev/null +++ b/tools/model_generator/src/com/libiec61850/scl/model/SmpMod.java @@ -0,0 +1,56 @@ +package com.libiec61850.scl.model; + +/* + * Copyright 2023 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +public enum SmpMod +{ + SMP_PER_PERIOD(0), + SMP_PER_SECOND(1), + SEC_PER_SMP(2); + + private int value; + + private SmpMod(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + public boolean compare(int i) + { + return (value == i); + } + + public static SmpMod fromValue(int val) + { + SmpMod[] errors = SmpMod.values(); + + for (int i = 0; i < errors.length; i++) { + if (errors[i].compare(val)) + return errors[i]; + } + + return SmpMod.SMP_PER_PERIOD; + } +} diff --git a/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java b/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java index e94ca7ab..0c05fd57 100644 --- a/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java +++ b/tools/model_generator/src/com/libiec61850/tools/DynamicModelGenerator.java @@ -189,7 +189,7 @@ public class DynamicModelGenerator { output.print(svcb.getSmvID() + " "); output.print(svcb.getDatSet() + " "); output.print(svcb.getConfRev() + " "); - output.print("0" + " "); + output.print(svcb.getSmpMod().getValue() + " "); output.print(svcb.getSmpRate() + " "); output.print(svcb.getSmvOpts().getIntValue() + " "); output.print(svcb.isMulticast() ? "0" : "1"); diff --git a/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java b/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java index 4381aff0..a06313a0 100644 --- a/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java +++ b/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java @@ -1247,8 +1247,10 @@ public class StaticModelGenerator { svString += "NULL, "; svString += svCB.getSmvOpts().getIntValue() + ", "; + + svString += svCB.getSmpMod().getValue() + ", "; - svString += "0, " + svCB.getSmpRate() + ", "; + svString += svCB.getSmpRate() + ", "; svString += svCB.getConfRev() + ", "; From 15359059212929e1d2594a081c2a02aaf0363155 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Sun, 30 Jul 2023 20:06:42 +0100 Subject: [PATCH 05/12] - added updated compiled versions of config file and static model generator (LIB61850-67) --- tools/model_generator/genconfig.jar | Bin 97408 -> 100509 bytes tools/model_generator/genmodel.jar | Bin 98733 -> 100549 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tools/model_generator/genconfig.jar b/tools/model_generator/genconfig.jar index 2c9ed1fc32bfed1a96eac95456e1f376101d23df..6f42a2ba6247a31d4ea4ed573b23e23305214280 100644 GIT binary patch delta 40581 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

>CojhY(G()abf3Sm<%HU}%UNlAqRU=HF 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