- IEC 61850 client: fixed bug in APC control handling

pull/44/merge
Michael Zillgith 8 years ago
parent 0e97f4ac6b
commit d3eee25a3a

@ -149,6 +149,7 @@ ControlObjectClient_create(const char* objectReference, IedConnection connection
bool hasOper = false; bool hasOper = false;
bool hasTimeActivatedControl = false; bool hasTimeActivatedControl = false;
bool hasCtlNum = false; bool hasCtlNum = false;
bool isAPC = false;
MmsVariableSpecification* ctlVal = NULL; MmsVariableSpecification* ctlVal = NULL;
MmsVariableSpecification* t = NULL; MmsVariableSpecification* t = NULL;
@ -159,6 +160,11 @@ ControlObjectClient_create(const char* objectReference, IedConnection connection
{ {
hasOper = true; hasOper = true;
ctlVal = MmsVariableSpecification_getNamedVariableRecursive(oper, "ctlVal");
if (MmsVariableSpecification_getType(ctlVal) == MMS_STRUCTURE)
isAPC = true;
MmsVariableSpecification* operTm = MmsVariableSpecification_getNamedVariableRecursive(oper, "operTm"); MmsVariableSpecification* operTm = MmsVariableSpecification_getNamedVariableRecursive(oper, "operTm");
if (operTm) if (operTm)
@ -169,7 +175,6 @@ ControlObjectClient_create(const char* objectReference, IedConnection connection
if (ctlNum) if (ctlNum)
hasCtlNum = true; hasCtlNum = true;
ctlVal = MmsVariableSpecification_getNamedVariableRecursive(oper, "ctlVal");
t = MmsVariableSpecification_getNamedVariableRecursive(oper, "T"); t = MmsVariableSpecification_getNamedVariableRecursive(oper, "T");
} }
} }
@ -200,163 +205,13 @@ ControlObjectClient_create(const char* objectReference, IedConnection connection
self->hasCtlNum = hasCtlNum; self->hasCtlNum = hasCtlNum;
self->ctlVal = MmsValue_newDefaultValue(ctlVal); self->ctlVal = MmsValue_newDefaultValue(ctlVal);
/* Check for T element type (Binary time -> Ed.1,UTC time -> Ed.2) */ if (isAPC)
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)
{
ControlObjectClient self = NULL;
/* request control model from server */
char domainId[65];
char itemId[129];
char* domainName = MmsMapping_getMmsDomainFromObjectReference(objectReference, domainId);
if (domainName == NULL)
goto exit_function;
convertToMmsAndInsertFC(itemId, objectReference + strlen(domainId) + 1, "CF");
int controlObjectItemIdLen = strlen(itemId);
strncat(itemId, "$ctlModel", 64 - controlObjectItemIdLen);
MmsError mmsError;
MmsValue* ctlModel = MmsConnection_readVariable(IedConnection_getMmsConnection(connection),
&mmsError, domainId, itemId);
if (ctlModel == NULL) {
if (DEBUG_IED_CLIENT)
printf("IED_CLIENT: ControlObjectClient_create: failed to get ctlModel from server\n");
goto exit_function;
}
int ctlModelVal = MmsValue_toUint32(ctlModel);
MmsValue_delete(ctlModel);
IedClientError error;
LinkedList dataDirectory =
IedConnection_getDataDirectory(connection, &error, objectReference);
if (dataDirectory == NULL) {
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;
LinkedList element = LinkedList_getNext(dataDirectory);
while (element != NULL) {
char* objectName = (char*) element->data;
if (strcmp(objectName, "Oper") == 0)
hasOper = true;
element = LinkedList_getNext(element);
}
LinkedList_destroy(dataDirectory);
if (hasOper == false) {
if (DEBUG_IED_CLIENT)
printf("IED_CLIENT: control is missing required element \"Oper\"\n");
goto exit_function;
}
/* check for time activated control and ctlNum */
bool hasTimeActivatedControl = false;
bool hasCtlNum = false;
strcpy(itemId, objectReference);
strcat(itemId, ".Oper");
dataDirectory = IedConnection_getDataDirectory(connection, &error, itemId);
if (dataDirectory == NULL)
goto exit_function;
element = LinkedList_getNext(dataDirectory);
while (element != NULL) {
char* objectName = (char*) element->data;
if (strcmp(objectName, "operTm") == 0) {
hasTimeActivatedControl = true;
}
else if (strcmp(objectName, "ctlNum") == 0) {
hasCtlNum = true;
}
element = LinkedList_getNext(element);
}
LinkedList_destroy(dataDirectory);
/* get default parameters for Oper control variable */
MmsValue* oper = IedConnection_readObject(connection, &error, itemId, IEC61850_FC_CO);
if (oper == NULL) {
if (DEBUG_IED_CLIENT)
printf("IED_CLIENT: reading \"Oper\" failed!\n");
goto exit_function;
}
self = (ControlObjectClient) GLOBAL_CALLOC(1, sizeof(struct sControlObjectClient));
if (self == NULL)
goto exit_function;
self->objectReference = StringUtils_copyString(objectReference);
self->connection = connection;
self->ctlModel = (ControlModel) ctlModelVal;
self->hasTimeActivatedMode = hasTimeActivatedControl;
self->hasCtlNum = hasCtlNum;
self->ctlVal = MmsValue_getElement(oper, 0);
if (MmsValue_getType(self->ctlVal) == MMS_STRUCTURE)
self->analogValue = MmsValue_createEmptyStructure(1); self->analogValue = MmsValue_createEmptyStructure(1);
else else
self->analogValue = NULL; self->analogValue = NULL;
/* Check for T element type (Binary time -> Ed.1,UTC time -> Ed.2) */ /* Check for T element type (Binary time -> Ed.1,UTC time -> Ed.2) */
MmsValue* t; if (MmsVariableSpecification_getType(t) == MMS_BINARY_TIME)
if (hasTimeActivatedControl)
t = MmsValue_getElement(oper, 4);
else
t = MmsValue_getElement(oper, 3);
if (MmsValue_getType(t) == MMS_BINARY_TIME)
self->edition = 1; self->edition = 1;
else else
self->edition = 2; self->edition = 2;
@ -364,15 +219,14 @@ ControlObjectClient_create(const char* objectReference, IedConnection connection
if (DEBUG_IED_CLIENT) if (DEBUG_IED_CLIENT)
printf("IED_CLIENT: Detected edition %i control\n", self->edition); printf("IED_CLIENT: Detected edition %i control\n", self->edition);
MmsValue_setElement(oper, 0, NULL);
MmsValue_delete(oper);
private_IedConnection_addControlClient(connection, self); private_IedConnection_addControlClient(connection, self);
free_varspec:
MmsVariableSpecification_destroy(ctlVarSpec);
exit_function: exit_function:
return self; return self;
} }
#endif
void void
ControlObjectClient_destroy(ControlObjectClient self) ControlObjectClient_destroy(ControlObjectClient self)

Loading…
Cancel
Save