From 64199f791c0aec1094b0bed0569e87151e1500d2 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Tue, 20 Oct 2015 15:59:44 +0200 Subject: [PATCH] - changed ControlObjectClient_create function: doesn't read "Oper" and uses GetVarSpec instead of GetNameList service --- CHANGELOG | 1 + src/iec61850/client/client_control.c | 112 ++++++++++++++++++++++ src/mms/iso_mms/client/mms_client_write.c | 1 - 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 250f33e6..054899dd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Changes to version 0.8.7 ------------------------ +- changed ControlObjectClient_create function: doesn't read "Oper" and uses GetVarSpec instead of GetNameList service - extended beoglebone demo (write access to GAPC settings, ...) - File service: support for wildcard character ('*') in requests - server: changed signature of WriteAccessHandler: Handler now return MmsDataAccessError instead of boolean value! diff --git a/src/iec61850/client/client_control.c b/src/iec61850/client/client_control.c index c12eaf05..ce2823e0 100644 --- a/src/iec61850/client/client_control.c +++ b/src/iec61850/client/client_control.c @@ -109,6 +109,117 @@ resetLastApplError(ControlObjectClient self) self->lastApplError.ctlNum = 0; } +ControlObjectClient +ControlObjectClient_create(const char* objectReference, IedConnection connection) +{ + ControlObjectClient self = NULL; + + /* request control model from server */ + char reference[129]; + + if (strlen(objectReference) < 121) { + strcpy(reference, objectReference); + strcat(reference, ".ctlModel"); + } + else + goto exit_function; + + IedClientError error; + + uint32_t ctlModel = IedConnection_readUnsigned32Value(connection, &error, reference, IEC61850_FC_CF); + + if (error != IED_ERROR_OK) { + if (DEBUG_IED_CLIENT) + printf("IED_CLIENT: ControlObjectClient_create: failed to get %s from server\n", reference); + + goto exit_function; + } + + MmsVariableSpecification* ctlVarSpec = + IedConnection_getVariableSpecification(connection, &error, objectReference, IEC61850_FC_CO); + + if (error != IED_ERROR_OK) { + if (DEBUG_IED_CLIENT) + printf("IED_CLIENT: ControlObjectClient_create: failed to get data directory of control object\n"); + + goto exit_function; + } + + /* check what control elements are available */ + bool hasOper = false; + bool hasTimeActivatedControl = false; + bool hasCtlNum = false; + MmsVariableSpecification* ctlVal = NULL; + MmsVariableSpecification* t = NULL; + + if (MmsVariableSpecification_getType(ctlVarSpec) == MMS_STRUCTURE) { + MmsVariableSpecification* oper = MmsVariableSpecification_getNamedVariableRecursive(ctlVarSpec, "Oper"); + + if (oper) + { + hasOper = true; + + MmsVariableSpecification* operTm = MmsVariableSpecification_getNamedVariableRecursive(oper, "operTm"); + + if (operTm) + hasTimeActivatedControl = true; + + MmsVariableSpecification* ctlNum = MmsVariableSpecification_getNamedVariableRecursive(oper, "ctlNum"); + + if (ctlNum) + hasCtlNum = true; + + ctlVal = MmsVariableSpecification_getNamedVariableRecursive(oper, "ctlVal"); + t = MmsVariableSpecification_getNamedVariableRecursive(oper, "T"); + } + } + + if (hasOper == false) { + if (DEBUG_IED_CLIENT) + printf("IED_CLIENT: control is missing required element \"Oper\"\n"); + + goto exit_function; + } + + if ((ctlVal == NULL) || (t == NULL)) { + if (DEBUG_IED_CLIENT) + printf("IED_CLIENT: \"Oper\" is missing required element\n"); + + goto free_varspec; + } + + self = (ControlObjectClient) GLOBAL_CALLOC(1, sizeof(struct sControlObjectClient)); + + if (self == NULL) + goto exit_function; + + self->objectReference = copyString(objectReference); + self->connection = connection; + self->ctlModel = (ControlModel) ctlModel; + self->hasTimeActivatedMode = hasTimeActivatedControl; + self->hasCtlNum = hasCtlNum; + self->ctlVal = MmsValue_newDefaultValue(ctlVal); + + /* Check for T element type (Binary time -> Ed.1,UTC time -> Ed.2) */ + if (MmsVariableSpecification_getType(t) == MMS_BINARY_TIME) + self->edition = 1; + else + self->edition = 2; + + if (DEBUG_IED_CLIENT) + printf("IED_CLIENT: Detected edition %i control\n", self->edition); + + private_IedConnection_addControlClient(connection, self); + +free_varspec: + MmsVariableSpecification_destroy(ctlVarSpec); + +exit_function: + return self; +} + + +#if 0 ControlObjectClient ControlObjectClient_create(const char* objectReference, IedConnection connection) { @@ -261,6 +372,7 @@ ControlObjectClient_create(const char* objectReference, IedConnection connection exit_function: return self; } +#endif void ControlObjectClient_destroy(ControlObjectClient self) diff --git a/src/mms/iso_mms/client/mms_client_write.c b/src/mms/iso_mms/client/mms_client_write.c index 5d7c822a..8163cdd8 100644 --- a/src/mms/iso_mms/client/mms_client_write.c +++ b/src/mms/iso_mms/client/mms_client_write.c @@ -282,7 +282,6 @@ mmsClient_createWriteMultipleItemsRequest(uint32_t invokeId, const char* domainI for (i = 0; i < numberOfItems; i++) { GLOBAL_FREEMEM(request->variableAccessSpecification.choice.listOfVariable.list.array[i]); deleteDataElement(request->listOfData.list.array[i]); - } GLOBAL_FREEMEM(request->variableAccessSpecification.choice.listOfVariable.list.array);