Esempio n. 1
0
MmsValue*
IedConnection_readObject(IedConnection self, IedClientError* error, char* objectReference,
        FunctionalConstraint fc)
{
    char domainIdBuffer[65];
    char itemIdBuffer[129];
    MmsValue* value = NULL;

    char* domainId;
    char* itemId;

    domainId = MmsMapping_getMmsDomainFromObjectReference(objectReference, domainIdBuffer);
    itemId = MmsMapping_createMmsVariableNameFromObjectReference(objectReference, fc, itemIdBuffer);

    if ((domainId == NULL) || (itemId == NULL)) {
        *error = IED_ERROR_OBJECT_REFERENCE_INVALID;
        return NULL;
    }

    MmsError mmsError;

    value = MmsConnection_readVariable(self->connection, &mmsError, domainId, itemId);

    if (value != NULL) {
        *error = IED_ERROR_OK;
    }
    else
        *error = iedConnection_mapMmsErrorToIedError(mmsError);

    return value;
}
Esempio n. 2
0
void
IedConnection_deleteDataSet(IedConnection self, IedClientError* error, char* dataSetReference)
{
    char domainId[65];
    char itemId[129];
    bool isAssociationSpecific = false;

    if (dataSetReference[0] != '@') {
        MmsMapping_getMmsDomainFromObjectReference(dataSetReference, domainId);
        copyStringToBuffer(dataSetReference + strlen(domainId) + 1, itemId);
        StringUtils_replace(itemId, '.', '$');
    }
    else {
        strncpy(itemId, dataSetReference, 128);
        itemId[128] = 0;
        isAssociationSpecific = true;
    }

    MmsError mmsError;

    if (isAssociationSpecific)
        MmsConnection_deleteAssociationSpecificNamedVariableList(self->connection, &mmsError, itemId);
    else
        MmsConnection_deleteNamedVariableList(self->connection, &mmsError, domainId, itemId);

    *error = iedConnection_mapMmsErrorToIedError(mmsError);
}
Esempio n. 3
0
MmsVariableSpecification*
IedConnection_getVariableSpecification(IedConnection self, IedClientError* error, char* objectReference,
        FunctionalConstraint fc)
{
    char domainIdBuffer[65];
    char itemIdBuffer[129];

    char* domainId;
    char* itemId;

    MmsError mmsError;
    MmsVariableSpecification* varSpec = NULL;

    domainId = MmsMapping_getMmsDomainFromObjectReference(objectReference, domainIdBuffer);
    itemId = MmsMapping_createMmsVariableNameFromObjectReference(objectReference, fc, itemIdBuffer);

    if ((domainId == NULL) || (itemId == NULL)) {
        *error = IED_ERROR_OBJECT_REFERENCE_INVALID;
        goto cleanup_and_exit;
    }

    varSpec =
            MmsConnection_getVariableAccessAttributes(self->connection, &mmsError, domainId, itemId);

    if (varSpec != NULL) {
        *error = IED_ERROR_OK;
    }
    else
        *error = iedConnection_mapMmsErrorToIedError(mmsError);

    cleanup_and_exit:

    return varSpec;
}
ClientReportControlBlock
IedConnection_getRCBValues(IedConnection self, IedClientError* error, char* rcbReference,
        ClientReportControlBlock updateRcb)
{
    MmsError mmsError = MMS_ERROR_NONE;

    ClientReportControlBlock returnRcb = updateRcb;

    char domainId[65];
    char itemId[129];

    MmsMapping_getMmsDomainFromObjectReference(rcbReference, domainId);

    strcpy(itemId, rcbReference + strlen(domainId) + 1);

    StringUtils_replace(itemId, '.', '$');

    if (DEBUG_IED_CLIENT)
        printf("DEBUG_IED_CLIENT: readRCBValues for %s\n", rcbReference);

    MmsValue* rcb = MmsConnection_readVariable(self->connection, &mmsError, domainId, itemId);

    if (mmsError != MMS_ERROR_NONE) {
        *error = iedConnection_mapMmsErrorToIedError(mmsError);

        return NULL;
    }

    if (rcb == NULL) {
        *error = IED_ERROR_OBJECT_DOES_NOT_EXIST;
        return NULL;
    }

    if (MmsValue_getType(rcb) != MMS_STRUCTURE) {
        if (DEBUG_IED_CLIENT)
            printf("DEBUG_IED_CLIENT: getRCBValues returned wrong type!\n");

        MmsValue_delete(rcb);

        *error = IED_ERROR_UNKNOWN;
        return NULL;
    }

    if (returnRcb == NULL)
        returnRcb = ClientReportControlBlock_create(rcbReference);

    private_ClientReportControlBlock_updateValues(returnRcb, rcb);

    MmsValue_delete(rcb);

    *error = IED_ERROR_OK;

    return returnRcb;
}
Esempio n. 5
0
ClientDataSet
IedConnection_readDataSetValues(IedConnection self, IedClientError* error, char* dataSetReference,
        ClientDataSet dataSet)
{
    char domainIdBuffer[65];
    char itemIdBuffer[129];

    char* domainId = NULL;
    char* itemId = NULL;


    bool isAssociationSpecific = false;

    if (dataSetReference[0] != '@') {
        domainId = MmsMapping_getMmsDomainFromObjectReference(dataSetReference, domainIdBuffer);
        itemId = copyStringToBuffer(dataSetReference + strlen(domainId) + 1, itemIdBuffer);
        StringUtils_replace(itemId, '.', '$');
    }
    else {
        itemId = dataSetReference;
        isAssociationSpecific = true;
    }

    MmsError mmsError;

    MmsValue* dataSetVal;

    if (isAssociationSpecific)
        dataSetVal = MmsConnection_readNamedVariableListValuesAssociationSpecific(self->connection,
                &mmsError, itemId, true);
    else
        dataSetVal= MmsConnection_readNamedVariableListValues(self->connection, &mmsError,
                    domainId, itemId, true);

    if (dataSetVal == NULL) {
        *error = iedConnection_mapMmsErrorToIedError(mmsError);
        goto cleanup_and_exit;
    }
    else
        *error = IED_ERROR_OK;

    if (dataSet == NULL) {
        dataSet = ClientDataSet_create(dataSetReference);
        ClientDataSet_setDataSetValues(dataSet, dataSetVal);
    }
    else {
        MmsValue* dataSetValues = ClientDataSet_getValues(dataSet);
        MmsValue_update(dataSetValues, dataSetVal);
    }

    cleanup_and_exit:
    return dataSet;
}
Esempio n. 6
0
void
IedConnection_createDataSet(IedConnection self, IedClientError* error, char* dataSetReference,
        LinkedList /* <char*> */dataSetElements)
{

    char domainIdBuffer[65];
    char itemIdBuffer[129];

    char* domainId;
    char* itemId;
    bool isAssociationSpecific = false;

    if (dataSetReference[0] != '@') {
        domainId = MmsMapping_getMmsDomainFromObjectReference(dataSetReference, domainIdBuffer);
        itemId = copyStringToBuffer(dataSetReference + strlen(domainId) + 1, itemIdBuffer);
        StringUtils_replace(itemId, '.', '$');
    }
    else {
        itemId = dataSetReference;
        isAssociationSpecific = true;
    }

    MmsError mmsError;

    LinkedList dataSetEntries = LinkedList_create();

    LinkedList dataSetElement = LinkedList_getNext(dataSetElements);

    while (dataSetElement != NULL) {

        MmsVariableAccessSpecification* dataSetEntry =
                MmsMapping_ObjectReferenceToVariableAccessSpec((char*) dataSetElement->data);

        LinkedList_add(dataSetEntries, (void*) dataSetEntry);

        dataSetElement = LinkedList_getNext(dataSetElement);
    }

    if (isAssociationSpecific)
        MmsConnection_defineNamedVariableListAssociationSpecific(self->connection, &mmsError,
                itemId, dataSetEntries);
    else
        MmsConnection_defineNamedVariableList(self->connection, &mmsError,
                domainId, itemId, dataSetEntries);

    /* delete list and all elements */
    LinkedList_destroyDeep(dataSetEntries, (LinkedListValueDeleteFunction) MmsVariableAccessSpecification_destroy);

    *error = iedConnection_mapMmsErrorToIedError(mmsError);
}
Esempio n. 7
0
static void
createDataSetsFromLogicalNode(MmsDevice* mmsDevice, LogicalNode* logicalNode, MmsDomain* domain)
{
	if (logicalNode->dataSets != NULL) {
		int dataSetCount = ArrayList_listSize((void**) (logicalNode->dataSets));

		int i;

		for (i = 0; i < dataSetCount; i++) {

			char* dataSetName = createString(3, logicalNode->name, "$", logicalNode->dataSets[i]->name);

			MmsNamedVariableList varList = MmsNamedVariableList_create(dataSetName, false);

			int fcdaCount = ArrayList_listSize((void**) (logicalNode->dataSets[i]->fcda));

			int j;

			MmsNamedVariableListEntry variableListEntry;

			for (j = 0; j < fcdaCount; j++) {
				char* variableName = MmsMapping_createMmsVariableNameFromObjectReference(
						logicalNode->dataSets[i]->fcda[j]->objectReference,
						logicalNode->dataSets[i]->fcda[j]->fc);

				char* domainName = MmsMapping_getMmsDomainFromObjectReference(
						logicalNode->dataSets[i]->fcda[j]->objectReference);

				MmsDomain* variableDomain;

				if (domainName != NULL)
					variableDomain = MmsDevice_getDomain(mmsDevice, domainName);
				else
					variableDomain = domain;

				variableListEntry =
						MmsNamedVariableListEntry_create(variableDomain, variableName);

				MmsNamedVariableList_addVariable(varList, variableListEntry);

				free(domainName);
				free(variableName);
			}

			MmsDomain_addNamedVariableList(domain, varList);

			free(dataSetName);
		}
	}
}
Esempio n. 8
0
static void
installDefaultValuesForDataAttribute(IedServer self, DataAttribute* dataAttribute,
        char* objectReference, int position)
{
    sprintf(objectReference + position, ".%s", dataAttribute->name);

    char mmsVariableName[65]; /* maximum size is 64 according to 61850-8-1 */

    MmsValue* value = dataAttribute->mmsValue;

    MmsMapping_createMmsVariableNameFromObjectReference(objectReference, dataAttribute->fc, mmsVariableName);

    char domainName[65];

    MmsMapping_getMmsDomainFromObjectReference(objectReference, domainName);

    MmsDomain* domain = MmsDevice_getDomain(self->mmsDevice, domainName);

    if (domain == NULL) {
        if (DEBUG_IED_SERVER)
            printf("Error domain (%s) not found!\n", domainName);
        return;
    }

    MmsValue* cacheValue = MmsServer_getValueFromCache(self->mmsServer, domain, mmsVariableName);

    dataAttribute->mmsValue = cacheValue;

    if (value != NULL) {
        MmsValue_update(cacheValue, value);
        MmsValue_delete(value);
    }

    int childPosition = strlen(objectReference);
    DataAttribute* subDataAttribute = (DataAttribute*) dataAttribute->firstChild;

    while (subDataAttribute != NULL) {
        installDefaultValuesForDataAttribute(self, subDataAttribute, objectReference, childPosition);

        subDataAttribute = (DataAttribute*) subDataAttribute->sibling;
    }
}
Esempio n. 9
0
bool
ControlObjectClient_cancel(ControlObjectClient self)
{
    resetLastApplError(self);

    MmsValue* cancelParameters;

    if (self->hasTimeActivatedMode)
        cancelParameters = MmsValue_createEmptyStructure(6);
    else
        cancelParameters = MmsValue_createEmptyStructure(5);

    MmsValue_setElement(cancelParameters, 0, self->ctlVal);

    int index = 1;

    if (self->hasTimeActivatedMode) {
        MmsValue* operTm = MmsValue_newUtcTimeByMsTime(self->opertime);
        MmsValue_setElement(cancelParameters, index++, operTm);
    }

    MmsValue* origin = createOriginValue(self);

    MmsValue_setElement(cancelParameters, index++, origin);

    MmsValue* ctlNum = MmsValue_newUnsignedFromUint32(self->ctlNum);
    MmsValue_setElement(cancelParameters, index++, ctlNum);

    uint64_t timestamp = Hal_getTimeInMs();
    MmsValue* ctlTime;

    if (self->edition == 2)
        ctlTime = MmsValue_newUtcTimeByMsTime(timestamp);
    else {
        ctlTime = MmsValue_newBinaryTime(false);
        MmsValue_setBinaryTime(ctlTime, timestamp);
    }
    MmsValue_setElement(cancelParameters, index++, ctlTime);

    MmsValue* ctlTest = MmsValue_newBoolean(self->test);
    MmsValue_setElement(cancelParameters, index++, ctlTest);

    char domainId[65];
    char itemId[65];

    MmsMapping_getMmsDomainFromObjectReference(self->objectReference, domainId);

    convertToMmsAndInsertFC(itemId, self->objectReference + strlen(domainId) + 1, "CO");

    strncat(itemId, "$Cancel", 64);

    if (DEBUG_IED_CLIENT)
        printf("IED_CLIENT: cancel: %s/%s\n", domainId, itemId);

    MmsError mmsError;

    MmsConnection_writeVariable(IedConnection_getMmsConnection(self->connection),
            &mmsError, domainId, itemId, cancelParameters);

    MmsValue_setElement(cancelParameters, 0, NULL);
    MmsValue_delete(cancelParameters);

    if (mmsError != MMS_ERROR_NONE) {
        if (DEBUG_IED_CLIENT)
            printf("IED_CLIENT: cancel failed!\n");
        return false;
    }

    return true;
}
Esempio n. 10
0
bool
ControlObjectClient_select(ControlObjectClient self)
{
    resetLastApplError(self);

    char domainId[65];
    char itemId[65];

    MmsMapping_getMmsDomainFromObjectReference(self->objectReference, domainId);

    convertToMmsAndInsertFC(itemId, self->objectReference + strlen(domainId) + 1, "CO");

    strncat(itemId, "$SBO", 64);

    if (DEBUG_IED_CLIENT)
        printf("IED_CLIENT: select: %s/%s\n", domainId, itemId);

    MmsError mmsError;

    MmsValue* value = MmsConnection_readVariable(IedConnection_getMmsConnection(self->connection),
            &mmsError, domainId, itemId);

    bool selected = false;

    self->ctlNum++;

    if (value == NULL) {
        if (DEBUG_IED_CLIENT)
            printf("IED_CLIENT: select: read SBO failed!\n");
        goto exit_function;
    }

    char sboReference[130];

    snprintf(sboReference, 129, "%s/%s", domainId, itemId);

    if (MmsValue_getType(value) == MMS_VISIBLE_STRING) {
        if (strcmp(MmsValue_toString(value),  "") == 0) {
            if (DEBUG_IED_CLIENT)
                printf("select-response-\n");
        }
        else if (strcmp(MmsValue_toString(value), sboReference)) {
            if (DEBUG_IED_CLIENT)
                printf("select-response+: (%s)\n", MmsValue_toString(value));
            selected = true;
        }
        else {
            if (DEBUG_IED_CLIENT)
                printf("IED_CLIENT: select-response: (%s)\n", MmsValue_toString(value));
        }
    }
    else {
        if (DEBUG_IED_CLIENT)
            printf("IED_CLIENT: select: unexpected response from server!\n");
    }

    MmsValue_delete(value);

exit_function:
    return selected;
}
Esempio n. 11
0
bool
ControlObjectClient_operate(ControlObjectClient self, MmsValue* ctlVal, uint64_t operTime)
{
    bool success = false;

    if (ctlVal == NULL) {
        if (DEBUG_IED_CLIENT)
            printf("IED_CLIENT: operate - (ctlVal == NULL)!\n");

        goto exit_function;
    }

    resetLastApplError(self);

    MmsValue* operParameters;

    if (self->hasTimeActivatedMode)
        operParameters = MmsValue_createEmptyStructure(7);
    else
        operParameters = MmsValue_createEmptyStructure(6);

    MmsValue_setElement(operParameters, 0, ctlVal);

    int index = 1;

    if (self->hasTimeActivatedMode) {
        MmsValue* operTm = MmsValue_newUtcTimeByMsTime(operTime);
        MmsValue_setElement(operParameters, index++, operTm);
    }

    MmsValue* origin = createOriginValue(self);
    MmsValue_setElement(operParameters, index++, origin);

    if (!((self->ctlModel == CONTROL_MODEL_SBO_NORMAL) ||
            (self->ctlModel == CONTROL_MODEL_SBO_ENHANCED)))
    {
        self->ctlNum++;
    }

    MmsValue* ctlNum = MmsValue_newUnsignedFromUint32(self->ctlNum);
    MmsValue_setElement(operParameters, index++, ctlNum);

    uint64_t timestamp = Hal_getTimeInMs();
    MmsValue* ctlTime;

    if (self->edition == 2)
        ctlTime = MmsValue_newUtcTimeByMsTime(timestamp);
    else {
        ctlTime = MmsValue_newBinaryTime(false);
        MmsValue_setBinaryTime(ctlTime, timestamp);
    }

    MmsValue_setElement(operParameters, index++, ctlTime);

    MmsValue* ctlTest = MmsValue_newBoolean(self->test);
    MmsValue_setElement(operParameters, index++, ctlTest);

    MmsValue* check = MmsValue_newBitString(2);
    MmsValue_setBitStringBit(check, 1, self->interlockCheck);
    MmsValue_setBitStringBit(check, 0, self->synchroCheck);
    MmsValue_setElement(operParameters, index++, check);

    char domainId[65];
    char itemId[65];

    MmsMapping_getMmsDomainFromObjectReference(self->objectReference, domainId);

    convertToMmsAndInsertFC(itemId, self->objectReference + strlen(domainId) + 1, "CO");

    int controlObjectItemIdLen = strlen(itemId);

    strncat(itemId, "$Oper", 64 - controlObjectItemIdLen);

    if (DEBUG_IED_CLIENT)
        printf("IED_CLIENT: operate: %s/%s\n", domainId, itemId);

    MmsError mmsError;

    MmsConnection_writeVariable(IedConnection_getMmsConnection(self->connection),
            &mmsError, domainId, itemId, operParameters);

    MmsValue_setElement(operParameters, 0, NULL);
    MmsValue_delete(operParameters);

    if (mmsError != MMS_ERROR_NONE) {
        if (DEBUG_IED_CLIENT)
            printf("IED_CLIENT: operate failed!\n");

        goto exit_function;
    }

    MmsValue_update(self->ctlVal, ctlVal);
    self->opertime = operTime;

    success = true;

exit_function:
    return success;
}
Esempio n. 12
0
ControlObjectClient
ControlObjectClient_create(const char* objectReference, IedConnection connection)
{
    ControlObjectClient self = NULL;

    /* request control model from server */
    char domainId[65];
    char itemId[65];

    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 */
    bool hasTimeActivatedControl = 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;
            break;
        }

        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 = copyString(objectReference);
    self->connection = connection;
    self->ctlModel = (ControlModel) ctlModelVal;
    self->hasTimeActivatedMode = hasTimeActivatedControl;
    self->ctlVal = MmsValue_getElement(oper, 0);

    /* Check for T element type (EntryTime -> Ed.1, Timestamp -> Ed.2) */
    MmsValue* t;

    if (hasTimeActivatedControl)
        t = MmsValue_getElement(oper, 4);
    else
        t = MmsValue_getElement(oper, 3);

    if (MmsValue_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);

    MmsValue_setElement(oper, 0, NULL);
    MmsValue_delete(oper);

    private_IedConnection_addControlClient(connection, self);

exit_function:
    return self;
}
Esempio n. 13
0
LinkedList /* <char*> */
IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, char* dataSetReference, bool* isDeletable)
{
    bool deletable = false;

    LinkedList dataSetMembers = NULL;

    char domainIdBuffer[65];
    char itemIdBuffer[129];

    char* domainId = NULL;
    char* itemId = NULL;

    bool isAssociationSpecific = false;

    if (dataSetReference[0] != '@') {
        domainId = MmsMapping_getMmsDomainFromObjectReference(dataSetReference, domainIdBuffer);
        itemId = copyStringToBuffer(dataSetReference + strlen(domainId) + 1, itemIdBuffer);
        StringUtils_replace(itemId, '.', '$');
    }
    else {
        itemId = dataSetReference;
        isAssociationSpecific = true;
    }

    MmsError mmsError;

    LinkedList entries;

    if (isAssociationSpecific)
        entries = MmsConnection_readNamedVariableListDirectoryAssociationSpecific(self->connection,
                &mmsError, itemId, &deletable);
    else
        entries = MmsConnection_readNamedVariableListDirectory(self->connection,
                &mmsError, domainId, itemId, &deletable);

    if (mmsError == MMS_ERROR_NONE) {

        LinkedList entry = LinkedList_getNext(entries);

        dataSetMembers = LinkedList_create();

        while (entry != NULL) {
            MmsVariableAccessSpecification* varAccessSpec = (MmsVariableAccessSpecification*) entry->data;

            char* objectReference = MmsMapping_varAccessSpecToObjectReference(varAccessSpec);

            LinkedList_add(dataSetMembers, objectReference);

            entry = LinkedList_getNext(entry);
        }

        if (isDeletable != NULL)
            *isDeletable = deletable;

        LinkedList_destroyDeep(entries, (LinkedListValueDeleteFunction) MmsVariableAccessSpecification_destroy);
    }

    *error = iedConnection_mapMmsErrorToIedError(mmsError);

    return dataSetMembers;
}
Esempio n. 14
0
void
IedConnection_setRCBValues(IedConnection self, IedClientError* error, ClientReportControlBlock rcb,
        uint32_t parametersMask, bool singleRequest)
{
    *error = IED_ERROR_OK;

    MmsError mmsError = MMS_ERROR_NONE;

    bool isBuffered = ClientReportControlBlock_isBuffered(rcb);

    char domainId[65];
    char itemId[129];

    char* rcbReference = ClientReportControlBlock_getObjectReference(rcb);

    MmsMapping_getMmsDomainFromObjectReference(rcbReference, domainId);

    strcpy(itemId, rcbReference + strlen(domainId) + 1);

    StringUtils_replace(itemId, '.', '$');

    if (DEBUG_IED_CLIENT)
        printf("DEBUG_IED_CLIENT: setRCBValues for %s\n", rcbReference);

    int itemIdLen = strlen(itemId);

    /* create the list of requested itemIds references */
    LinkedList itemIds = LinkedList_create();
    LinkedList values = LinkedList_create();

    /* add resv/resvTms as first element and rptEna as last element */
    if (parametersMask & RCB_ELEMENT_RESV) {
        if (isBuffered)
            goto error_invalid_parameter;

        strcpy(itemId + itemIdLen, "$Resv");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->resv);
    }

    if (parametersMask & RCB_ELEMENT_RESV_TMS) {
        if (!isBuffered)
            goto error_invalid_parameter;

        strcpy(itemId + itemIdLen, "$ResvTms");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->resvTms);
    }

    if (parametersMask & RCB_ELEMENT_RPT_ID) {
        strcpy(itemId + itemIdLen, "$RptID");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->rptId);
    }

    if (parametersMask & RCB_ELEMENT_DATSET) {
        strcpy(itemId + itemIdLen, "$DatSet");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->datSet);
    }

    if (parametersMask & RCB_ELEMENT_ENTRY_ID) {
        strcpy(itemId + itemIdLen, "$EntryID");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->entryId);
    }

    if (parametersMask & RCB_ELEMENT_OPT_FLDS) {
        strcpy(itemId + itemIdLen, "$OptFlds");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->optFlds);
    }

    if (parametersMask & RCB_ELEMENT_BUF_TM) {
        strcpy(itemId + itemIdLen, "$BufTm");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->bufTm);
    }

    if (parametersMask & RCB_ELEMENT_TRG_OPS) {
        strcpy(itemId + itemIdLen, "$TrgOps");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->trgOps);
    }

    if (parametersMask & RCB_ELEMENT_INTG_PD) {
        strcpy(itemId + itemIdLen, "$IntgPd");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->intgPd);
    }

    if (parametersMask & RCB_ELEMENT_GI) {
        strcpy(itemId + itemIdLen, "$GI");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->gi);
    }

    if (parametersMask & RCB_ELEMENT_PURGE_BUF) {
        if (!isBuffered)
            goto error_invalid_parameter;

        strcpy(itemId + itemIdLen, "$PurgeBuf");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->purgeBuf);
    }

    if (parametersMask & RCB_ELEMENT_TIME_OF_ENTRY) {
        if (!isBuffered)
            goto error_invalid_parameter;

        strcpy(itemId + itemIdLen, "$TimeOfEntry");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->timeOfEntry);
    }

    if (parametersMask & RCB_ELEMENT_RPT_ENA) {
        strcpy(itemId + itemIdLen, "$RptEna");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, rcb->rptEna);
    }

    if (singleRequest) {
        LinkedList accessResults = NULL;

        MmsConnection_writeMultipleVariables(self->connection, &mmsError, domainId, itemIds, values, &accessResults);

        if (accessResults != NULL)
            LinkedList_destroyDeep(accessResults, (LinkedListValueDeleteFunction) MmsValue_delete);

        *error = iedConnection_mapMmsErrorToIedError(mmsError);
        goto exit_function;
    }
    else {
        LinkedList itemIdElement = LinkedList_getNext(itemIds);
        LinkedList valueElement = LinkedList_getNext(values);

        while (itemIdElement != NULL) {
            char* rcbItemId = (char*) itemIdElement->data;
            MmsValue* value = (MmsValue*) valueElement->data;

            MmsConnection_writeVariable(self->connection, &mmsError, domainId, rcbItemId, value);

            if (mmsError != MMS_ERROR_NONE)
                break;

            itemIdElement = LinkedList_getNext(itemIdElement);
            valueElement = LinkedList_getNext(valueElement);
        }

        *error = iedConnection_mapMmsErrorToIedError(mmsError);
        goto exit_function;
    }

    error_invalid_parameter:
    *error = IED_ERROR_USER_PROVIDED_INVALID_ARGUMENT;

    exit_function:
    LinkedList_destroy(itemIds);
    LinkedList_destroyStatic(values);
}
Esempio n. 15
0
void
IedConnection_setGoCBValues(IedConnection self, IedClientError* error, ClientGooseControlBlock goCB,
        uint32_t parametersMask, bool singleRequest)
{
    *error = IED_ERROR_OK;

    MmsError mmsError = MMS_ERROR_NONE;

    char domainId[65];
    char itemId[129];

    MmsMapping_getMmsDomainFromObjectReference(goCB->objectReference, domainId);

    char* itemIdStart = goCB->objectReference + strlen(domainId) + 1;

    char* separator = strchr(itemIdStart, '.');

    if (separator == NULL) {
        *error = IED_ERROR_OBJECT_REFERENCE_INVALID;
        return;
    }

    int separatorOffset = separator - itemIdStart;

    memcpy(itemId, itemIdStart, separatorOffset);

    itemId[separatorOffset] = '$';
    itemId[separatorOffset + 1] = 'G';
    itemId[separatorOffset + 2] = 'O';
    itemId[separatorOffset + 3] = '$';

    strcpy(itemId + separatorOffset + 4, separator + 1);

    if (DEBUG_IED_CLIENT)
        printf("DEBUG_IED_CLIENT: setGoCBValues for %s\n", goCB->objectReference);

    int itemIdLen = strlen(itemId);

    /* create the list of requested itemIds references */
    LinkedList itemIds = LinkedList_create();
    LinkedList values = LinkedList_create();

    /* add rGoEna as last element */
    if (parametersMask & GOCB_ELEMENT_GO_ID) {
        strcpy(itemId + itemIdLen, "$GoID");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, goCB->goID);
    }

    if (parametersMask & GOCB_ELEMENT_DATSET) {
        strcpy(itemId + itemIdLen, "$DatSet");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, goCB->datSet);
    }

    if (parametersMask & GOCB_ELEMENT_CONF_REV) {
        strcpy(itemId + itemIdLen, "$ConfRev");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, goCB->confRev);
    }

    if (parametersMask & GOCB_ELEMENT_NDS_COMM) {
        strcpy(itemId + itemIdLen, "$NdsCom");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, goCB->ndsCom);
    }

    if (parametersMask & GOCB_ELEMENT_DST_ADDRESS) {
        strcpy(itemId + itemIdLen, "$DstAddress");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, goCB->dstAddress);
    }

    if (parametersMask & GOCB_ELEMENT_MIN_TIME) {
        strcpy(itemId + itemIdLen, "$MinTime");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, goCB->minTime);
    }

    if (parametersMask & GOCB_ELEMENT_MAX_TIME) {
        strcpy(itemId + itemIdLen, "$MaxTime");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, goCB->maxTime);
    }

    if (parametersMask & GOCB_ELEMENT_FIXED_OFFS) {
        strcpy(itemId + itemIdLen, "$FixedOffs");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, goCB->fixedOffs);
    }


    if (parametersMask & GOCB_ELEMENT_GO_ENA) {
        strcpy(itemId + itemIdLen, "$GoEna");

        LinkedList_add(itemIds, copyString(itemId));
        LinkedList_add(values, goCB->goEna);
    }

    if (singleRequest) {
        LinkedList accessResults = NULL;

        MmsConnection_writeMultipleVariables(self->connection, &mmsError, domainId, itemIds, values, &accessResults);

        if (accessResults != NULL) {
            LinkedList element = LinkedList_getNext(accessResults);

            while (element != NULL) {
                MmsValue* accessResult = (MmsValue*) element->data;

                if (MmsValue_getDataAccessError(accessResult) != DATA_ACCESS_ERROR_SUCCESS) {
                    mmsError = MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT;
                    break;
                }

                element = LinkedList_getNext(element);
            }

            LinkedList_destroyDeep(accessResults, (LinkedListValueDeleteFunction) MmsValue_delete);
        }

        *error = iedConnection_mapMmsErrorToIedError(mmsError);
        goto exit_function;
    }
    else {
        LinkedList itemIdElement = LinkedList_getNext(itemIds);
        LinkedList valueElement = LinkedList_getNext(values);

        while (itemIdElement != NULL) {
            char* rcbItemId = (char*) itemIdElement->data;
            MmsValue* value = (MmsValue*) valueElement->data;

            MmsConnection_writeVariable(self->connection, &mmsError, domainId, rcbItemId, value);

            if (mmsError != MMS_ERROR_NONE)
                break;

            itemIdElement = LinkedList_getNext(itemIdElement);
            valueElement = LinkedList_getNext(valueElement);
        }

        *error = iedConnection_mapMmsErrorToIedError(mmsError);
        goto exit_function;
    }

exit_function:
    LinkedList_destroy(itemIds);
    LinkedList_destroyStatic(values);
}
Esempio n. 16
0
ClientGooseControlBlock
IedConnection_getGoCBValues(IedConnection self, IedClientError* error, const char* goCBReference, ClientGooseControlBlock updateGoCB)
{
    MmsError mmsError = MMS_ERROR_NONE;
    *error = IED_ERROR_OK;

    ClientGooseControlBlock returnGoCB = updateGoCB;

    char domainId[65];
    char itemId[129];

    MmsMapping_getMmsDomainFromObjectReference(goCBReference, domainId);

    const char* itemIdStart = goCBReference + strlen(domainId) + 1;

    const char* separator = strchr(itemIdStart, '.');

    if (separator == NULL) {
        *error = IED_ERROR_OBJECT_REFERENCE_INVALID;
        return NULL;
    }

    int separatorOffset = separator - itemIdStart;

    memcpy(itemId, itemIdStart, separatorOffset);

    itemId[separatorOffset] = '$';
    itemId[separatorOffset + 1] = 'G';
    itemId[separatorOffset + 2] = 'O';
    itemId[separatorOffset + 3] = '$';

    strcpy(itemId + separatorOffset + 4, separator + 1);

    if (DEBUG_IED_CLIENT)
        printf("DEBUG_IED_CLIENT: getGoCBValues for %s\n", goCBReference);

    MmsValue* goCB = MmsConnection_readVariable(self->connection, &mmsError, domainId, itemId);

    if (mmsError != MMS_ERROR_NONE) {
        *error = iedConnection_mapMmsErrorToIedError(mmsError);

        return NULL;
    }

    if (goCB == NULL) {
        *error = IED_ERROR_OBJECT_DOES_NOT_EXIST;
        return NULL;
    }

    if (MmsValue_getType(goCB) != MMS_STRUCTURE) {
        if (DEBUG_IED_CLIENT)
            printf("DEBUG_IED_CLIENT: getRCBValues returned wrong type!\n");

        MmsValue_delete(goCB);

        *error = IED_ERROR_UNKNOWN;
        return NULL;
    }

    if (returnGoCB == NULL)
        returnGoCB = ClientGooseControlBlock_create(goCBReference);

    if (private_ClientGooseControlBlock_updateValues(returnGoCB, goCB))
        *error = IED_ERROR_OK;
    else
        *error = IED_ERROR_UNEXPECTED_VALUE_RECEIVED;

    MmsValue_delete(goCB);

    return returnGoCB;
}