diff --git a/src/iec61850/inc_private/control.h b/src/iec61850/inc_private/control.h index 1c8a1ac3..844c74b6 100644 --- a/src/iec61850/inc_private/control.h +++ b/src/iec61850/inc_private/control.h @@ -104,7 +104,7 @@ struct sControlObject }; ControlObject* -ControlObject_create(IedServer iedServer, MmsDomain* domain, char* lnName, char* name); +ControlObject_create(IedServer iedServer, MmsDomain* domain, char* lnName, char* name, MmsVariableSpecification* operSpec); void ControlObject_initialize(ControlObject* self); diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index 16686fc5..dc487c3a 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -59,7 +59,6 @@ createControlObjects(IedServer self, MmsDomain* domain, char* lnName, MmsVariabl strcat(objectName, "$"); } - bool isControlObject = false; bool hasCancel = false; int cancelIndex = 0; bool hasSBOw = false; @@ -72,12 +71,14 @@ createControlObjects(IedServer self, MmsDomain* domain, char* lnName, MmsVariabl int coElementCount = coSpec->typeSpec.structure.elementCount; + MmsVariableSpecification* operSpec = NULL; + int j; for (j = 0; j < coElementCount; j++) { MmsVariableSpecification* coElementSpec = coSpec->typeSpec.structure.elements[j]; if (strcmp(coElementSpec->name, "Oper") == 0) { - isControlObject = true; + operSpec = coElementSpec; operIndex = j; } else if (strcmp(coElementSpec->name, "Cancel") == 0) { @@ -96,14 +97,14 @@ createControlObjects(IedServer self, MmsDomain* domain, char* lnName, MmsVariabl } } - if (isControlObject) { + if (operSpec) { strcat(objectName, coSpec->name); if (DEBUG_IED_SERVER) printf("IED_SERVER: create control object LN:%s DO:%s\n", lnName, objectName); - ControlObject* controlObject = ControlObject_create(self, domain, lnName, objectName); + ControlObject* controlObject = ControlObject_create(self, domain, lnName, objectName, operSpec); if (controlObject == NULL) goto exit_function; diff --git a/src/iec61850/server/mms_mapping/control.c b/src/iec61850/server/mms_mapping/control.c index 4d50585c..d8f37e1a 100644 --- a/src/iec61850/server/mms_mapping/control.c +++ b/src/iec61850/server/mms_mapping/control.c @@ -110,82 +110,6 @@ updateSboTimeoutValue(ControlObject* self) self->selectTimeout = CONFIG_CONTROL_DEFAULT_SBO_TIMEOUT; } -void -ControlObject_initialize(ControlObject* self) -{ - MmsServer mmsServer = IedServer_getMmsServer(self->iedServer); - - self->emptyString = MmsValue_newVisibleString(NULL); - - char strBuf[129]; - - char* ctlModelName = StringUtils_createStringInBuffer(strBuf, 4, self->lnName, "$CF$", self->name, "$ctlModel"); - - if (DEBUG_IED_SERVER) - printf("initialize control for %s\n", ctlModelName); - - MmsValue* ctlModel = MmsServer_getValueFromCache(mmsServer, - self->mmsDomain, ctlModelName); - - if (ctlModel == NULL) { - if (DEBUG_IED_SERVER) - printf("No control model found for variable %s\n", ctlModelName); - } - - char* sboClassName = StringUtils_createStringInBuffer(strBuf, 4, self->lnName, "$CF$", self->name, "$sboClass"); - - self->sboClass = MmsServer_getValueFromCache(mmsServer, self->mmsDomain, sboClassName); - - 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); - - if (ctlModel != NULL) { - uint32_t ctlModelVal = MmsValue_toInt32(ctlModel); - - self->ctlModel = ctlModelVal; - - if (DEBUG_IED_SERVER) - printf(" ctlModel: %i\n", ctlModelVal); - - if ((ctlModelVal == 2) || (ctlModelVal == 4)) { /* SBO */ - - - char* controlObjectReference = StringUtils_createStringInBuffer(strBuf, 6, self->mmsDomain->domainName, - "/", self->lnName, "$", self->name, "$SBO"); - - self->sbo = MmsValue_newVisibleString(controlObjectReference); - - char* sboTimeoutName = StringUtils_createStringInBuffer(strBuf, 4, self->lnName, "$CF$", self->name, "$sboTimeout"); - - self->sboTimeout = MmsServer_getValueFromCache(mmsServer, - self->mmsDomain, sboTimeoutName); - - updateSboTimeoutValue(self); - - setState(self, STATE_UNSELECTED); - - if (DEBUG_IED_SERVER) - printf("timeout for %s is %i\n", sboTimeoutName, self->selectTimeout); - } - else { - self->sbo = MmsValue_newVisibleString(NULL); - - setState(self, STATE_READY); - } - } -} - static bool isSboClassOperateOnce(ControlObject* self) { @@ -359,7 +283,7 @@ executeStateMachine: } ControlObject* -ControlObject_create(IedServer iedServer, MmsDomain* domain, char* lnName, char* name) +ControlObject_create(IedServer iedServer, MmsDomain* domain, char* lnName, char* name, MmsVariableSpecification* operSpec) { ControlObject* self = (ControlObject*) GLOBAL_CALLOC(1, sizeof(ControlObject)); @@ -391,10 +315,94 @@ ControlObject_create(IedServer iedServer, MmsDomain* domain, char* lnName, char* self->mmsDomain = domain; self->iedServer = iedServer; + MmsVariableSpecification* ctlValSpec = MmsVariableSpecification_getChildSpecificationByName(operSpec, "ctlVal", NULL); + self->ctlVal = MmsValue_newDefaultValue(ctlValSpec); + + MmsVariableSpecification* originSpec = MmsVariableSpecification_getChildSpecificationByName(operSpec, "origin", NULL); + self->origin = MmsValue_newDefaultValue(originSpec); + + self->ctlNum = MmsValue_newUnsigned(8); + exit_function: return self; } +void +ControlObject_initialize(ControlObject* self) +{ + MmsServer mmsServer = IedServer_getMmsServer(self->iedServer); + + self->emptyString = MmsValue_newVisibleString(NULL); + + char strBuf[129]; + + char* ctlModelName = StringUtils_createStringInBuffer(strBuf, 4, self->lnName, "$CF$", self->name, "$ctlModel"); + + if (DEBUG_IED_SERVER) + printf("initialize control for %s\n", ctlModelName); + + MmsValue* ctlModel = MmsServer_getValueFromCache(mmsServer, + self->mmsDomain, ctlModelName); + + if (ctlModel == NULL) { + if (DEBUG_IED_SERVER) + printf("No control model found for variable %s\n", ctlModelName); + } + + char* sboClassName = StringUtils_createStringInBuffer(strBuf, 4, self->lnName, "$CF$", self->name, "$sboClass"); + + self->sboClass = MmsServer_getValueFromCache(mmsServer, self->mmsDomain, sboClassName); + + 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); + + if (ctlModel != NULL) { + uint32_t ctlModelVal = MmsValue_toInt32(ctlModel); + + self->ctlModel = ctlModelVal; + + if (DEBUG_IED_SERVER) + printf(" ctlModel: %i\n", ctlModelVal); + + if ((ctlModelVal == 2) || (ctlModelVal == 4)) { /* SBO */ + + + char* controlObjectReference = StringUtils_createStringInBuffer(strBuf, 6, self->mmsDomain->domainName, + "/", self->lnName, "$", self->name, "$SBO"); + + self->sbo = MmsValue_newVisibleString(controlObjectReference); + + char* sboTimeoutName = StringUtils_createStringInBuffer(strBuf, 4, self->lnName, "$CF$", self->name, "$sboTimeout"); + + self->sboTimeout = MmsServer_getValueFromCache(mmsServer, + self->mmsDomain, sboTimeoutName); + + updateSboTimeoutValue(self); + + setState(self, STATE_UNSELECTED); + + if (DEBUG_IED_SERVER) + printf("timeout for %s is %i\n", sboTimeoutName, self->selectTimeout); + } + else { + self->sbo = MmsValue_newVisibleString(NULL); + + setState(self, STATE_READY); + } + } +} + void ControlObject_destroy(ControlObject* self) { @@ -890,18 +898,9 @@ ControlObject_sendLastApplError(ControlObject* self, MmsServerConnection connect static void updateControlParameters(ControlObject* controlObject, MmsValue* ctlVal, MmsValue* ctlNum, MmsValue* origin) { - if (controlObject->ctlVal != NULL) - MmsValue_delete(controlObject->ctlVal); - - if (controlObject->ctlNum != NULL) - MmsValue_delete(controlObject->ctlNum); - - if (controlObject->origin != NULL) - MmsValue_delete(controlObject->origin); - - controlObject->ctlVal = MmsValue_clone(ctlVal); - controlObject->ctlNum = MmsValue_clone(ctlNum); - controlObject->origin = MmsValue_clone(origin); + MmsValue_update(controlObject->ctlVal, ctlVal); + MmsValue_update(controlObject->ctlNum, ctlNum); + MmsValue_update(controlObject->origin, origin); if (controlObject->ctlNumSt) MmsValue_update(controlObject->ctlNumSt, ctlNum); @@ -999,8 +998,6 @@ Control_readAccessControlObject(MmsMapping* self, MmsDomain* domain, char* varia if (controlObject != NULL) { - //initialize(controlObject); - if (varName != NULL) { if (strcmp(varName, "Oper") == 0) value = controlObject->oper; @@ -1166,8 +1163,6 @@ Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, char* vari goto free_and_return; } - //initialize(controlObject); - if (strcmp(varName, "SBOw") == 0) { /* select with value */ if (controlObject->ctlModel == 4) {