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); }
static ControlObject* lookupControlObject(IedServer self, DataObject* node) { char objectReference[130]; ModelNode_getObjectReference((ModelNode*) node, objectReference); char* separator = strchr(objectReference, '/'); *separator = 0; MmsDomain* domain = MmsDevice_getDomain(self->mmsDevice, objectReference); char* lnName = separator + 1; separator = strchr(lnName, '.'); assert(separator != NULL); *separator = 0; char* objectName = separator + 1; StringUtils_replace(objectName, '.', '$'); if (DEBUG_IED_SERVER) printf("IED_SERVER: looking for control object: %s\n", objectName); ControlObject* controlObject = MmsMapping_getControlObject(self->mmsMapping, domain, lnName, objectName); return controlObject; }
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; }
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; }
static ClientDataSet ClientDataSet_create(char* dataSetReference) { ClientDataSet self = (ClientDataSet) calloc(1, sizeof(struct sClientDataSet)); self->dataSetReference = copyString(dataSetReference); StringUtils_replace(self->dataSetReference, '.', '$'); self->dataSetValues = NULL; return self; }
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); }
ModelNode* LogicalDevice_getChildByMmsVariableName(LogicalDevice* logicalDevice, const char* mmsVariableName) { char fcString[3]; char nameRef[65]; const char* separator = strchr(mmsVariableName,'$'); if (separator == NULL) return NULL; if (strlen(separator) > 4) { fcString[0] = separator[1]; fcString[1] = separator[2]; fcString[2] = 0; const char* strpos = mmsVariableName; int targetPos = 0; while (strpos < separator) { nameRef[targetPos++] = strpos[0]; strpos++; } nameRef[targetPos++] = '.'; strpos = separator + 4; while (strpos[0] != 0) { nameRef[targetPos++] = strpos[0]; strpos++; } nameRef[targetPos++] = 0; StringUtils_replace(nameRef, '$', '.'); FunctionalConstraint fc = FunctionalConstraint_fromString(fcString); return ModelNode_getChildWithFc((ModelNode*) logicalDevice, nameRef, fc); } return NULL; }
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; }
static LinkedList getDataDirectory(IedConnection self, IedClientError* error, char* dataReference, bool withFc) { if (self->logicalDevices == NULL) IedConnection_getDeviceModelFromServer(self, error); char dataRefCopy[193]; strncpy(dataRefCopy, dataReference, 192); dataRefCopy[192] = 0; char* ldSep = strchr(dataRefCopy, '/'); *ldSep = 0; char* logicalDeviceName = dataRefCopy; char* logicalNodeName = ldSep + 1; char* logicalNodeNameEnd = strchr(logicalNodeName, '.'); if (logicalNodeNameEnd == NULL) { *error = IED_ERROR_OBJECT_REFERENCE_INVALID; return NULL; } int logicalNodeNameLen = logicalNodeNameEnd - logicalNodeName; char* dataNamePart = logicalNodeNameEnd + 1; int dataNamePartLen = strlen(dataNamePart); if (dataNamePartLen < 1) { *error = IED_ERROR_OBJECT_REFERENCE_INVALID; return NULL; } StringUtils_replace(dataNamePart, '.', '$'); // search for logical device LinkedList device = LinkedList_getNext(self->logicalDevices); bool deviceFound = false; ICLogicalDevice* ld; while (device != NULL) { ld = (ICLogicalDevice*) device->data; if (strcmp(logicalDeviceName, ld->name) == 0) { deviceFound = true; break; } device = LinkedList_getNext(device); } if (!deviceFound) { *error = IED_ERROR_OBJECT_REFERENCE_INVALID; return NULL; } LinkedList variable = LinkedList_getNext(ld->variables); LinkedList dataDirectory = LinkedList_create(); while (variable != NULL) { char* variableName = (char*) variable->data; char* fcPos = strchr(variableName, '$'); if (fcPos != NULL) { int lnNameLen = fcPos - variableName; if (logicalNodeNameLen == lnNameLen) { if (memcmp(variableName, logicalNodeName, lnNameLen) == 0) { /* ok we are in the correct logical node */ /* skip FC */ char* fcEnd = strchr(fcPos + 1, '$'); if (fcEnd == NULL) goto next_variable; char* remainingPart = fcEnd + 1; int remainingLen = strlen(remainingPart); if (remainingLen <= dataNamePartLen) goto next_variable; if (remainingPart[dataNamePartLen] == '$') { if (memcmp(dataNamePart, remainingPart, dataNamePartLen) == 0) { char* subElementName = remainingPart + dataNamePartLen + 1; char* subElementNameSep = strchr(subElementName, '$'); if (subElementNameSep != NULL) goto next_variable; char* elementName; if (withFc) { int elementNameLen = strlen(subElementName); elementName = (char*) malloc(elementNameLen + 5); memcpy(elementName, subElementName, elementNameLen); elementName[elementNameLen] = '['; elementName[elementNameLen + 1] = *(fcPos + 1); elementName[elementNameLen + 2] = *(fcPos + 2); elementName[elementNameLen + 3] = ']'; elementName[elementNameLen + 4] = 0; } else elementName = copyString(subElementName); if (!addToStringSet(dataDirectory, elementName)) free(elementName); } } } } } next_variable: variable = LinkedList_getNext(variable); } *error = IED_ERROR_OK; return dataDirectory; }
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); }