From 020b1f40aa45375ec5aa13b1540d535c3348caff Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Sat, 25 Aug 2018 14:26:03 +0200 Subject: [PATCH] - IEC 61850 server: integrated automatic handling of "origin" and "ctlVal" status (ST) values for controllable CDCs --- .../simpleIO_direct_control.icd | 6 +- .../server_example_basic_io/static_model.c | 112 +++++++++++++----- .../server_example_basic_io/static_model.h | 16 ++- src/iec61850/inc_private/control.h | 3 + src/iec61850/server/mms_mapping/control.c | 24 ++-- 5 files changed, 117 insertions(+), 44 deletions(-) diff --git a/examples/server_example_basic_io/simpleIO_direct_control.icd b/examples/server_example_basic_io/simpleIO_direct_control.icd index 0a0c6355..ce3d8cce 100644 --- a/examples/server_example_basic_io/simpleIO_direct_control.icd +++ b/examples/server_example_basic_io/simpleIO_direct_control.icd @@ -212,11 +212,13 @@ + + - - + + diff --git a/examples/server_example_basic_io/static_model.c b/examples/server_example_basic_io/static_model.c index ddc8dd64..a1c2383d 100644 --- a/examples/server_example_basic_io/static_model.c +++ b/examples/server_example_basic_io/static_model.c @@ -3,7 +3,7 @@ * * automatically generated from simpleIO_direct_control.icd */ -#include "../server_example_basic_io/static_model.h" +#include "static_model.h" static void initializeValues(); @@ -1571,10 +1571,62 @@ DataObject iedModel_GenericIO_GGIO1_SPCSO4 = { "SPCSO4", (ModelNode*) &iedModel_GenericIO_GGIO1, (ModelNode*) &iedModel_GenericIO_GGIO1_Ind1, - (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_stVal, + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_origin, 0 }; +DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_origin = { + DataAttributeModelType, + "origin", + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4, + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_ctlNum, + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_origin_orCat, + 0, + IEC61850_FC_ST, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_origin_orCat = { + DataAttributeModelType, + "orCat", + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_origin, + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_origin_orIdent, + NULL, + 0, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_origin_orIdent = { + DataAttributeModelType, + "orIdent", + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_origin, + NULL, + NULL, + 0, + IEC61850_FC_ST, + IEC61850_OCTET_STRING_64, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_ctlNum = { + DataAttributeModelType, + "ctlNum", + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4, + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_stVal, + NULL, + 0, + IEC61850_FC_ST, + IEC61850_INT8U, + 0, + NULL, + 0}; + DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_stVal = { DataAttributeModelType, "stVal", @@ -1592,7 +1644,7 @@ DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_q = { DataAttributeModelType, "q", (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4, - (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_Oper, + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_t, NULL, 0, IEC61850_FC_ST, @@ -1601,11 +1653,37 @@ DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_q = { NULL, 0}; +DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4, + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_ctlModel, + NULL, + 0, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4, + (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_Oper, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper = { DataAttributeModelType, "Oper", (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4, - (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_ctlModel, + NULL, (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_Oper_ctlVal, 0, IEC61850_FC_CO, @@ -1718,32 +1796,6 @@ DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_Check = { NULL, 0}; -DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_ctlModel = { - DataAttributeModelType, - "ctlModel", - (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4, - (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4_t, - NULL, - 0, - IEC61850_FC_CF, - IEC61850_ENUMERATED, - 0, - NULL, - 0}; - -DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_t = { - DataAttributeModelType, - "t", - (ModelNode*) &iedModel_GenericIO_GGIO1_SPCSO4, - NULL, - NULL, - 0, - IEC61850_FC_ST, - IEC61850_TIMESTAMP, - 0, - NULL, - 0}; - DataObject iedModel_GenericIO_GGIO1_Ind1 = { DataObjectModelType, "Ind1", diff --git a/examples/server_example_basic_io/static_model.h b/examples/server_example_basic_io/static_model.h index b5670e9f..938d789a 100644 --- a/examples/server_example_basic_io/static_model.h +++ b/examples/server_example_basic_io/static_model.h @@ -123,8 +123,14 @@ extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_Oper_Check; extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_ctlModel; extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO3_t; extern DataObject iedModel_GenericIO_GGIO1_SPCSO4; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_origin; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_origin_orCat; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_origin_orIdent; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_ctlNum; extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_stVal; extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_q; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_t; +extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_ctlModel; extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper; extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_ctlVal; extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_origin; @@ -134,8 +140,6 @@ extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_ctlNum; extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_T; extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_Test; extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_Oper_Check; -extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_ctlModel; -extern DataAttribute iedModel_GenericIO_GGIO1_SPCSO4_t; extern DataObject iedModel_GenericIO_GGIO1_Ind1; extern DataAttribute iedModel_GenericIO_GGIO1_Ind1_stVal; extern DataAttribute iedModel_GenericIO_GGIO1_Ind1_q; @@ -267,8 +271,14 @@ extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_t; #define IEDMODEL_GenericIO_GGIO1_SPCSO3_ctlModel (&iedModel_GenericIO_GGIO1_SPCSO3_ctlModel) #define IEDMODEL_GenericIO_GGIO1_SPCSO3_t (&iedModel_GenericIO_GGIO1_SPCSO3_t) #define IEDMODEL_GenericIO_GGIO1_SPCSO4 (&iedModel_GenericIO_GGIO1_SPCSO4) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_origin (&iedModel_GenericIO_GGIO1_SPCSO4_origin) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_origin_orCat (&iedModel_GenericIO_GGIO1_SPCSO4_origin_orCat) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_origin_orIdent (&iedModel_GenericIO_GGIO1_SPCSO4_origin_orIdent) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_ctlNum (&iedModel_GenericIO_GGIO1_SPCSO4_ctlNum) #define IEDMODEL_GenericIO_GGIO1_SPCSO4_stVal (&iedModel_GenericIO_GGIO1_SPCSO4_stVal) #define IEDMODEL_GenericIO_GGIO1_SPCSO4_q (&iedModel_GenericIO_GGIO1_SPCSO4_q) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_t (&iedModel_GenericIO_GGIO1_SPCSO4_t) +#define IEDMODEL_GenericIO_GGIO1_SPCSO4_ctlModel (&iedModel_GenericIO_GGIO1_SPCSO4_ctlModel) #define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper (&iedModel_GenericIO_GGIO1_SPCSO4_Oper) #define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_ctlVal (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_ctlVal) #define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_origin (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_origin) @@ -278,8 +288,6 @@ extern DataAttribute iedModel_GenericIO_GGIO1_Ind4_t; #define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_T (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_T) #define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_Test (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_Test) #define IEDMODEL_GenericIO_GGIO1_SPCSO4_Oper_Check (&iedModel_GenericIO_GGIO1_SPCSO4_Oper_Check) -#define IEDMODEL_GenericIO_GGIO1_SPCSO4_ctlModel (&iedModel_GenericIO_GGIO1_SPCSO4_ctlModel) -#define IEDMODEL_GenericIO_GGIO1_SPCSO4_t (&iedModel_GenericIO_GGIO1_SPCSO4_t) #define IEDMODEL_GenericIO_GGIO1_Ind1 (&iedModel_GenericIO_GGIO1_Ind1) #define IEDMODEL_GenericIO_GGIO1_Ind1_stVal (&iedModel_GenericIO_GGIO1_Ind1_stVal) #define IEDMODEL_GenericIO_GGIO1_Ind1_q (&iedModel_GenericIO_GGIO1_Ind1_q) diff --git a/src/iec61850/inc_private/control.h b/src/iec61850/inc_private/control.h index 3d42ad1d..1c8a1ac3 100644 --- a/src/iec61850/inc_private/control.h +++ b/src/iec61850/inc_private/control.h @@ -62,6 +62,9 @@ struct sControlObject MmsValue* origin; MmsValue* timestamp; + MmsValue* ctlNumSt; + MmsValue* originSt; + char ctlObjectName[130]; /* for LastAppIError */ diff --git a/src/iec61850/server/mms_mapping/control.c b/src/iec61850/server/mms_mapping/control.c index 6eec9335..4d50585c 100644 --- a/src/iec61850/server/mms_mapping/control.c +++ b/src/iec61850/server/mms_mapping/control.c @@ -110,8 +110,8 @@ updateSboTimeoutValue(ControlObject* self) self->selectTimeout = CONFIG_CONTROL_DEFAULT_SBO_TIMEOUT; } -static void -initialize(ControlObject* self) +void +ControlObject_initialize(ControlObject* self) { MmsServer mmsServer = IedServer_getMmsServer(self->iedServer); @@ -139,6 +139,14 @@ initialize(ControlObject* self) StringUtils_createStringInBuffer(self->ctlObjectName, 5, MmsDomain_getName(self->mmsDomain), "/", self->lnName, "$CO$", self->name); + char* ctlNumName = StringUtils_createStringInBuffer(strBuf, 4, self->lnName, "$ST$", self->name, "$ctlNum"); + + self->ctlNumSt = MmsServer_getValueFromCache(mmsServer, self->mmsDomain, ctlNumName); + + char* originName = StringUtils_createStringInBuffer(strBuf, 4, self->lnName, "$ST$", self->name, "$origin"); + + self->originSt = MmsServer_getValueFromCache(mmsServer, self->mmsDomain, originName); + self->error = MmsValue_newIntegerFromInt32(0); self->addCause = MmsValue_newIntegerFromInt32(0); @@ -387,12 +395,6 @@ exit_function: return self; } -void -ControlObject_initialize(ControlObject* self) -{ - initialize(self); -} - void ControlObject_destroy(ControlObject* self) { @@ -900,6 +902,12 @@ updateControlParameters(ControlObject* controlObject, MmsValue* ctlVal, MmsValue controlObject->ctlVal = MmsValue_clone(ctlVal); controlObject->ctlNum = MmsValue_clone(ctlNum); controlObject->origin = MmsValue_clone(origin); + + if (controlObject->ctlNumSt) + MmsValue_update(controlObject->ctlNumSt, ctlNum); + + if (controlObject->originSt) + MmsValue_update(controlObject->originSt, origin); } static bool