static void ICLogicalDevice_destroy(ICLogicalDevice* self) { free(self->name); if (self->variables != NULL) LinkedList_destroy(self->variables); if (self->dataSets != NULL) LinkedList_destroy(self->dataSets); free(self); }
void IsoServer_destroy(IsoServer self) { #if (CONFIG_MMS_THREADLESS_STACK != 1) if (self->state == ISO_SVR_STATE_RUNNING) IsoServer_stopListening(self); #endif #if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) #if (CONFIG_MMS_SINGLE_THREADED == 1) if (self->openClientConnections != NULL) LinkedList_destroy(self->openClientConnections); #else if (self->openClientConnections != NULL) LinkedList_destroyStatic(self->openClientConnections); #endif /* (CONFIG_MMS_SINGLE_THREADED == 1) */ #if (CONFIG_MMS_THREADLESS_STACK != 1) lockClientConnections(self); Semaphore_destroy(self->openClientConnectionsMutex); #endif #else GLOBAL_FREEMEM(self->openClientConnections); #endif /* (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) */ #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_destroy(self->connectionCounterMutex); #endif GLOBAL_FREEMEM(self); }
void IedConnection_getDeviceModelFromServer(IedConnection self, IedClientError* error) { MmsError mmsError = MMS_ERROR_NONE; *error = IED_ERROR_OK; LinkedList logicalDeviceNames = MmsConnection_getDomainNames(self->connection, &mmsError); if (logicalDeviceNames != NULL) { if (self->logicalDevices != NULL) { LinkedList_destroyDeep(self->logicalDevices, (LinkedListValueDeleteFunction) ICLogicalDevice_destroy); self->logicalDevices = NULL; } LinkedList logicalDevice = LinkedList_getNext(logicalDeviceNames); LinkedList logicalDevices = LinkedList_create(); while (logicalDevice != NULL) { char* name = (char*) logicalDevice->data; ICLogicalDevice* icLogicalDevice = ICLogicalDevice_create(name); LinkedList variables = MmsConnection_getDomainVariableNames(self->connection, &mmsError, name); if (variables != NULL) ICLogicalDevice_setVariableList(icLogicalDevice, variables); else { *error = iedConnection_mapMmsErrorToIedError(mmsError); break; } LinkedList dataSets = MmsConnection_getDomainVariableListNames(self->connection, &mmsError, name); if (dataSets != NULL) ICLogicalDevice_setDataSetList(icLogicalDevice, dataSets); else { *error = iedConnection_mapMmsErrorToIedError(mmsError); break; } LinkedList_add(logicalDevices, icLogicalDevice); logicalDevice = LinkedList_getNext(logicalDevice); } self->logicalDevices = logicalDevices; LinkedList_destroy(logicalDeviceNames); } else { *error = iedConnection_mapMmsErrorToIedError(mmsError); } }
int main(void) { LinkedList* list = LinkedList_new(); char* elem1 = "cat"; LinkedList_add(list, &elem1); char* elem2 = "rat"; LinkedList_add(list, &elem2); char* elem3 = "dog"; LinkedList_add(list, &elem3); char* elem4 = "sheep"; LinkedList_add(list, &elem4); char* elem5 = "goat"; LinkedList_add(list, &elem5); char* elem6 = "kebab"; LinkedList_add(list, &elem6); char* elem7 = "pig"; LinkedList_add(list, &elem7); char* elem8 = "cow"; LinkedList_add(list, &elem8); char* elem9 = "chicken"; LinkedList_add(list, &elem9); char* elem10 = "duck"; LinkedList_add(list, &elem10); char* elem11 = "fox"; LinkedList_add(list, &elem11); char* elem12 = "rabbit"; LinkedList_add(list, &elem12); char* elem13 = "mouse"; LinkedList_add(list, &elem13); char* elem14 = "hedgehog"; LinkedList_add(list, &elem14); printf("list before: \n"); for (int i = 0; i < LinkedList_size(list); i++) { if (LinkedList_get(list, i) != NULL) { printf("%d: %s \n", i, *(char**)LinkedList_get(list, i)); } } printf("\nremoving element 5, %s\n", *(char**)LinkedList_get(list, 5)); LinkedList_remove(list, 5); printf("\nlist after: \n"); for (int i = 0; i < LinkedList_size(list); i++) { if (LinkedList_get(list, i) != NULL) { printf("%d: %s \n", i, *(char**)LinkedList_get(list, i)); } } LinkedList_destroy(list); free(list); }
void ObjectType_destroy(void* obj) { ObjectType* self = (ObjectType*)obj; GameObjectList_destroy(self->objectlist); if (self->collisionListeners != NULL) { LinkedList_destroy(self->collisionListeners); } self->id = OBJECTTYPE_UNDEFINED; free(self); }
void Map_deleteDeep(Map map, bool deleteKey, void (*valueDeleteFunction) (void*)) { LinkedList element = map->entries; MapEntry* entry; while ((element = LinkedList_getNext(element)) != NULL) { entry = (MapEntry*) element->data; if (deleteKey == true) free(entry->key); valueDeleteFunction(entry->value); } LinkedList_destroy(map->entries); free(map); }
void Map_deleteStatic(Map map, bool deleteKey) { LinkedList element = map->entries; MapEntry* entry; if (deleteKey == true) { while ((element = LinkedList_getNext(element)) != NULL) { entry = (MapEntry*) element->data; free(entry->key); } } LinkedList_destroy(map->entries); free(map); }
void IsoServer_destroy(IsoServer self) { #if (CONFIG_MMS_THREADLESS_STACK != 1) if (self->state == ISO_SVR_STATE_RUNNING) IsoServer_stopListening(self); #endif #if (CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS == -1) LinkedList_destroy(self->openClientConnections); #else free(self->openClientConnections); #endif #if (CONFIG_MMS_THREADLESS_STACK != 1) Semaphore_destroy(self->connectionCounterMutex); #endif free(self); }
int main(int argc, char** argv) { char* hostname; int tcpPort = 102; if (argc > 1) hostname = argv[1]; else hostname = "localhost"; if (argc > 2) tcpPort = atoi(argv[2]); MmsConnection con = MmsConnection_create(); MmsIndication indication; indication = MmsConnection_connect(con, hostname, tcpPort); if (indication != MMS_OK) { printf("MMS connect failed!\n"); goto exit; } else printf("MMS connected.\n\n"); printf("Domains present on server:\n--------------------------\n"); LinkedList nameList = MmsConnection_getDomainNames(con); LinkedList_printStringList(nameList); LinkedList_destroy(nameList); printf("\n"); exit: MmsConnection_destroy(con); }
bool mmsClient_parseGetNameListResponse(LinkedList* nameList, ByteBuffer* message, uint32_t* invokeId) { bool moreFollows = true; uint8_t* buffer = message->buffer; int maxBufPos = message->size; int bufPos = 0; int length; uint8_t tag = buffer[bufPos++]; if (tag == 0xa2) { // TODO parse confirmed error PDU goto exit_error; } if (tag != 0xa1) goto exit_error; bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos); if (bufPos < 0) goto exit_error; /* get invokeId */ tag = buffer[bufPos++]; if (tag != 0x02) goto exit_error; bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos); if (bufPos < 0) goto exit_error; if (invokeId != NULL) *invokeId = BerDecoder_decodeUint32(buffer, length, bufPos); bufPos += length; tag = buffer[bufPos++]; if (tag != 0xa1) goto exit_error; bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos); if (bufPos < 0) goto exit_error; tag = buffer[bufPos++]; if (tag != 0xa0) goto exit_error; bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos); if (bufPos < 0) goto exit_error; int listEndPos = bufPos + length; if (listEndPos > maxBufPos) goto exit_error; if (*nameList == NULL) *nameList = LinkedList_create(); LinkedList element = LinkedList_getLastElement(*nameList); while (bufPos < listEndPos) { tag = buffer[bufPos++]; if (tag != 0x1a) goto exit_error; bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos); if (bufPos < 0) goto exit_error; char* variableName = createStringFromBuffer(buffer + bufPos, length); element = LinkedList_insertAfter(element, variableName); bufPos += length; } if (bufPos < maxBufPos) { tag = buffer[bufPos++]; if (tag != 0x81) goto exit_error; bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos); if (bufPos < 0) goto exit_error; if (length != 1) goto exit_error; if (buffer[bufPos++] > 0) moreFollows = true; else moreFollows = false; } return moreFollows; exit_error: if (*nameList != NULL) { LinkedList_destroy(*nameList); } if (DEBUG) printf("parseNameListResponse: error parsing message!\n"); return false; }
int main(int argc, char** argv) { char* hostname; int tcpPort = 102; if (argc > 1) hostname = argv[1]; else hostname = "localhost"; if (argc > 2) tcpPort = atoi(argv[2]); IedClientError error; IedConnection con = IedConnection_create(); IedConnection_connect(con, &error, hostname, tcpPort); if (error == IED_ERROR_OK) { printf("Get logical device list...\n"); LinkedList deviceList = IedConnection_getLogicalDeviceList(con, &error); LinkedList device = LinkedList_getNext(deviceList); while (device != NULL) { printf("LD: %s\n", (char*) device->data); LinkedList logicalNodes = IedConnection_getLogicalDeviceDirectory(con, &error, (char*) device->data); LinkedList logicalNode = LinkedList_getNext(logicalNodes); while (logicalNode != NULL) { printf(" LN: %s\n", (char*) logicalNode->data); char* lnRef = (char*) alloca(129); sprintf(lnRef, "%s/%s", (char*) device->data, (char*) logicalNode->data); LinkedList dataObjects = IedConnection_getLogicalNodeDirectory(con, &error, lnRef, ACSI_CLASS_DATA_OBJECT); LinkedList dataObject = LinkedList_getNext(dataObjects); while (dataObject != NULL) { char* dataObjectName = (char*) dataObject->data; printf(" DO: %s\n", dataObjectName); dataObject = LinkedList_getNext(dataObject); char* doRef = (char*) alloca(129); sprintf(doRef, "%s/%s.%s", (char*) device->data, (char*) logicalNode->data, dataObjectName); printDataDirectory(doRef, con, 6); } LinkedList_destroy(dataObjects); LinkedList dataSets = IedConnection_getLogicalNodeDirectory(con, &error, lnRef, ACSI_CLASS_DATA_SET); LinkedList dataSet = LinkedList_getNext(dataSets); while (dataSet != NULL) { char* dataSetName = (char*) dataSet->data; printf(" DS: %s\n", dataSetName); dataSet = LinkedList_getNext(dataSet); } LinkedList_destroy(dataSets); LinkedList reports = IedConnection_getLogicalNodeDirectory(con, &error, lnRef, ACSI_CLASS_URCB); LinkedList report = LinkedList_getNext(reports); while (report != NULL) { char* reportName = (char*) report->data; printf(" RP: %s\n", reportName); report = LinkedList_getNext(report); } LinkedList_destroy(reports); reports = IedConnection_getLogicalNodeDirectory(con, &error, lnRef, ACSI_CLASS_BRCB); report = LinkedList_getNext(reports); while (report != NULL) { char* reportName = (char*) report->data; printf(" BR: %s\n", reportName); report = LinkedList_getNext(report); } LinkedList_destroy(reports); logicalNode = LinkedList_getNext(logicalNode); } LinkedList_destroy(logicalNodes); device = LinkedList_getNext(device); } LinkedList_destroy(deviceList); IedConnection_close(con); } else { printf("Connection failed!\n"); } IedConnection_destroy(con); }
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; }
void Physics_destroy() { LinkedList_destroy(activeCollisionChecks); }
Clause* DIMACSParser_parse_clause(char* line, LinkedList* all_literals) { // Empty lines are not permitted if (strcmp(line, "") == 0) { fprintf(stderr, "Error - empty lines are not permitted!\n"); return NULL; } // Split line by space unsigned int line_c = 30; char** line_v = malloc(line_c * sizeof(char*)); { unsigned int line_filled = 0; char* tmp = strtok(line, " "); while (tmp != NULL) { // Resize if necessary if (line_filled + 1 > line_c) { line_c *= 4; line_v = realloc(line_v, line_c * sizeof(char*)); } // Add to array line_v[line_filled++] = tmp; // Split off next line from string tmp = strtok(NULL, " "); } // Shrink array to minimum size required line_c = line_filled; line_v = realloc(line_v, line_c * sizeof(char*)); } // Create list of Literals in Clause LinkedList* clause_literals = LinkedList_create((void(*)(void*))Literal_destroy); // Parse each Literal separately for (int i = 0; i < line_c; i++) { // Parse Literal int (name) signed int a = strtol(line_v[i], NULL, 10); // The last element of each line has to be 0 if (i == line_c - 1) { if (a != 0) { fprintf(stderr, "Error - Last element of line was not 0!\n"); return NULL; } break; } // 0 is only allowed to be the last element of each line. if (a == 0) { fprintf(stderr, "Error - Found Literal 0, which is not permitted!\n"); return NULL; } // Parse Literal bool negated = false; char* name = malloc(sizeof(int) * sizeof(char) + 1 * sizeof(char)); if (a < 0) { negated = true; a = abs(a); } snprintf(name, 33, "%d", a); name = realloc(name, (strlen(name) + 1) * sizeof(char)); // Create new GenericLiteral GenericLiteral* new_literal = GenericLiteral_create(name, LiteralAssignment_UNSET); // Check if Literal is already contained in list of all Literals // If it is take that one, if not create a new one and add it to // the list of all Literals. bool literal_already_contained = false; for (LinkedListNode* iter = all_literals->head; iter != NULL; iter = iter->next) { GenericLiteral* found_literal = iter->data; if (GenericLiteral_equals(found_literal, new_literal)) { GenericLiteral_destroy(new_literal); new_literal = found_literal; literal_already_contained = true; break; } } if (!literal_already_contained) { LinkedList_append(all_literals, new_literal); } // Create new Literal Literal* literal = Literal_create(new_literal, negated); GenericLiteral_increase_occurrences(new_literal); // Add Literal to list of Literals LinkedList_append(clause_literals, literal); } free(line_v); // Create array of Literals from list of Literals unsigned int literals_c = clause_literals->size; Literal** literals_v = malloc(sizeof(Literal*) * literals_c); { int i = 0; for (LinkedListNode* iter = clause_literals->head; iter != NULL; iter = iter->next) { literals_v[i] = iter->data; i++; } } LinkedList_destroy(clause_literals, false); return Clause_create(literals_v, literals_c); }
Formula* DIMACSParser_parse_formula(char* str) { // Split string into array of lines unsigned int lines_c = 10; char** lines_v = malloc(lines_c * sizeof(char*)); { unsigned int lines_filled = 0; char* tmp = strtok(str, "\n"); while (tmp != NULL) { // Resize if necessary if (lines_filled + 1 > lines_c) { lines_c *= 4; lines_v = realloc(lines_v, lines_c * sizeof(char*)); } // Add to array lines_v[lines_filled++] = tmp; // Split off next line from string tmp = strtok(NULL, "\n"); } // Shrink array to minimum size required lines_c = lines_filled; lines_v = realloc(lines_v, lines_c * sizeof(char*)); } // Skip first lines with comments unsigned int linec = 0; for (linec = 0; linec < lines_c; linec++) { if (lines_v[linec][0] == 'c') { // skip } else { break; } } unsigned int literals_count = 0; unsigned int clauses_count = 0; // Parse problem line { bool problem_line_error = false; // Check if problem line has exactly these values separated by whitespaces: // "p" // "cnf" // <Number of Literals> // <Number of Clauses> int i = 0; char* tmp = strtok(lines_v[linec], " "); while (tmp != NULL) { if (i == 0 && !strcmp(tmp, "p") == 0) { problem_line_error = true; } else if (i == 1 && !strcmp(tmp, "cnf") == 0) { problem_line_error = true; } else if (i == 2) { literals_count = strtol(tmp, NULL, 10); } else if (i == 3) { clauses_count = strtol(tmp, NULL, 10); } i++; tmp = strtok(NULL, " "); } if (i != 4) { problem_line_error = true; } if (problem_line_error) { fprintf(stderr, "Error - missing/malformed problem line\n"); free(lines_v); return NULL; } if (literals_count == 0) { fprintf(stderr, "Error - number of literals is 0 according to problem line!\n"); fprintf(stderr, " - this can't be right\n"); free(lines_v); return NULL; } if (clauses_count == 0) { fprintf(stderr, "Error - number of clauses is 0 according to problem line!\n"); fprintf(stderr, " - this can't be right\n"); free(lines_v); return NULL; } } linec++; // Create list of ALL Literals in this Formula LinkedList* all_literals = LinkedList_create((void(*)(void*))GenericLiteral_destroy); // Create list of Clauses in this Formula LinkedList* clauses = LinkedList_create((void(*)(void*))Clause_destroy); // Parse Clauses unsigned int clauses_found = 0; for (; linec < lines_c; linec++) { // Ignore it if the last line is empty if (linec == lines_c - 1) { if (strcmp(lines_v[linec],"") == 0) { continue; } } Clause* clause = DIMACSParser_parse_clause(lines_v[linec], all_literals); if (clause == NULL) { free(lines_v); LinkedList_destroy(all_literals, true); LinkedList_destroy(clauses, true); return NULL; } LinkedList_append(clauses, clause); clauses_found++; } free(lines_v); // Check if given number of Clauses was correct if (clauses_count != clauses_found) { fprintf(stderr, "Error - number of clauses given in problem line is not correct!\n"); LinkedList_destroy(all_literals, true); LinkedList_destroy(clauses, true); return NULL; } // Check if given number of Literals was correct if (literals_count != all_literals->size) { fprintf(stderr, "Error - number of literals given in problem line is not correct!\n"); LinkedList_destroy(all_literals, true); LinkedList_destroy(clauses, true); return NULL; } // Convert list of all literals to array int all_literals_c = all_literals->size; GenericLiteral** all_literals_v = malloc(all_literals_c * sizeof(GenericLiteral*)); { int i = 0; for (LinkedListNode* iter = all_literals->head; iter != NULL; iter = iter->next) { GenericLiteral* lit = iter->data; all_literals_v[i] = lit; i++; } } LinkedList_destroy(all_literals, false); // Create Formula from list of Clauses and array of all Literals return Formula_create(clauses, all_literals_v, all_literals_c); }
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); }
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); }