static void initializeValues() { iedModel_ComplexArray_LLN0_Mod_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(0); iedModel_ComplexArray_MHAI1_HA_numHar.mmsValue = MmsValue_newUnsignedFromUint32(16); }
void ClientReportControlBlock_setIntgPd(ClientReportControlBlock self, uint32_t intgPd) { if (self->intgPd == NULL) self->intgPd = MmsValue_newUnsignedFromUint32(intgPd); else MmsValue_setUint32(self->intgPd, intgPd); }
void ClientReportControlBlock_setBufTm(ClientReportControlBlock self, uint32_t bufTm) { if (self->bufTm == NULL) self->bufTm = MmsValue_newUnsignedFromUint32(bufTm); else MmsValue_setUint32(self->bufTm, bufTm); }
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; }
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; }
static MmsVariableSpecification* createBufferedReportControlBlock(ReportControlBlock* reportControlBlock, ReportControl* reportControl) { MmsVariableSpecification* rcb = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); rcb->name = copyString(reportControlBlock->name); rcb->type = MMS_STRUCTURE; MmsValue* mmsValue = (MmsValue*) calloc(1, sizeof(MmsValue)); mmsValue->deleteValue = false; mmsValue->type = MMS_STRUCTURE; mmsValue->value.structure.size = 15; mmsValue->value.structure.components = (MmsValue**) calloc(15, sizeof(MmsValue*)); rcb->typeSpec.structure.elementCount = 15; rcb->typeSpec.structure.elements = (MmsVariableSpecification**) calloc(15, sizeof(MmsVariableSpecification*)); MmsVariableSpecification* namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("RptID"); namedVariable->typeSpec.visibleString = -129; namedVariable->type = MMS_VISIBLE_STRING; rcb->typeSpec.structure.elements[0] = namedVariable; mmsValue->value.structure.components[0] = MmsValue_newVisibleString( reportControlBlock->rptId); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("RptEna"); namedVariable->type = MMS_BOOLEAN; rcb->typeSpec.structure.elements[1] = namedVariable; mmsValue->value.structure.components[1] = MmsValue_newBoolean(false); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("DatSet"); namedVariable->typeSpec.visibleString = -129; namedVariable->type = MMS_VISIBLE_STRING; rcb->typeSpec.structure.elements[2] = namedVariable; if (reportControlBlock->dataSetName != NULL) { char* dataSetReference = createDataSetReferencForDefaultDataSet(reportControlBlock, reportControl); mmsValue->value.structure.components[2] = MmsValue_newVisibleString(dataSetReference); free(dataSetReference); } else mmsValue->value.structure.components[2] = MmsValue_newVisibleString(""); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("ConfRev"); namedVariable->type = MMS_UNSIGNED; namedVariable->typeSpec.unsignedInteger = 32; rcb->typeSpec.structure.elements[3] = namedVariable; mmsValue->value.structure.components[3] = MmsValue_newUnsignedFromUint32(reportControlBlock->confRef); reportControl->confRev = mmsValue->value.structure.components[3]; namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("OptFlds"); namedVariable->type = MMS_BIT_STRING; namedVariable->typeSpec.bitString = 10; rcb->typeSpec.structure.elements[4] = namedVariable; mmsValue->value.structure.components[4] = createOptFlds(reportControlBlock); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("BufTm"); namedVariable->type = MMS_UNSIGNED; namedVariable->typeSpec.unsignedInteger = 32; rcb->typeSpec.structure.elements[5] = namedVariable; mmsValue->value.structure.components[5] = MmsValue_newUnsignedFromUint32(reportControlBlock->bufferTime); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("SqNum"); namedVariable->type = MMS_UNSIGNED; namedVariable->typeSpec.unsignedInteger = 16; rcb->typeSpec.structure.elements[6] = namedVariable; mmsValue->value.structure.components[6] = MmsValue_newUnsigned(16); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("TrgOps"); namedVariable->type = MMS_BIT_STRING; namedVariable->typeSpec.bitString = 6; rcb->typeSpec.structure.elements[7] = namedVariable; mmsValue->value.structure.components[7] = createTrgOps(reportControlBlock); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("IntgPd"); namedVariable->type = MMS_UNSIGNED; namedVariable->typeSpec.unsignedInteger = 32; rcb->typeSpec.structure.elements[8] = namedVariable; mmsValue->value.structure.components[8] = MmsValue_newUnsignedFromUint32(reportControlBlock->intPeriod); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("GI"); namedVariable->type = MMS_BOOLEAN; rcb->typeSpec.structure.elements[9] = namedVariable; mmsValue->value.structure.components[9] = MmsValue_newBoolean(false); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("PurgeBuf"); namedVariable->type = MMS_BOOLEAN; rcb->typeSpec.structure.elements[10] = namedVariable; mmsValue->value.structure.components[10] = MmsValue_newBoolean(false); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("EntryID"); namedVariable->type = MMS_OCTET_STRING; namedVariable->typeSpec.octetString = 8; rcb->typeSpec.structure.elements[11] = namedVariable; mmsValue->value.structure.components[11] = MmsValue_newOctetString(8, 8); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("TimeOfEntry"); namedVariable->type = MMS_BINARY_TIME; rcb->typeSpec.structure.elements[12] = namedVariable; mmsValue->value.structure.components[12] = MmsValue_newBinaryTime(false); reportControl->timeOfEntry = mmsValue->value.structure.components[12]; namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("ResvTms"); namedVariable->type = MMS_UNSIGNED; namedVariable->typeSpec.unsignedInteger = 32; rcb->typeSpec.structure.elements[13] = namedVariable; mmsValue->value.structure.components[13] = MmsValue_newUnsigned(32); namedVariable = (MmsVariableSpecification*) calloc(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("Owner"); namedVariable->type = MMS_OCTET_STRING; namedVariable->typeSpec.octetString = -128; rcb->typeSpec.structure.elements[14] = namedVariable; mmsValue->value.structure.components[14] = MmsValue_newOctetString(0, 128); reportControl->rcbValues = mmsValue; return rcb; }
IedModel* ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle) { int bytesRead = 1; bool stateInModel = false; int indendation = 0; IedModel* model = NULL; LogicalDevice* currentLD = NULL; LogicalNode* currentLN = NULL; ModelNode* currentModelNode = NULL; DataSet* currentDataSet = NULL; GSEControlBlock* currentGoCB = NULL; char nameString[130]; char nameString2[130]; char nameString3[130]; int currentLine = 0; while (bytesRead > 0) { bytesRead = readLine(fileHandle, lineBuffer, READ_BUFFER_MAX_SIZE); currentLine++; if (bytesRead > 0) { lineBuffer[bytesRead] = 0; if (stateInModel) { if (StringUtils_startsWith((char*) lineBuffer, "}")) { if (indendation == 1) { stateInModel = false; indendation = 0; } else if (indendation == 2) { indendation = 1; } else if (indendation == 3) { indendation = 2; } else if (indendation == 4) { indendation = 3; } else if (indendation > 4) { currentModelNode = currentModelNode->parent; indendation--; } } else if (indendation == 1) { if (StringUtils_startsWith((char*) lineBuffer, "LD")) { indendation = 2; if (sscanf((char*) lineBuffer, "LD(%s)", nameString) < 1) goto exit_error; terminateString(nameString, ')'); currentLD = LogicalDevice_create(nameString, model); } else goto exit_error; } else if (indendation == 2) { if (StringUtils_startsWith((char*) lineBuffer, "LN")) { indendation = 3; if (sscanf((char*) lineBuffer, "LN(%s)", nameString) < 1) goto exit_error; terminateString(nameString, ')'); currentLN = LogicalNode_create(nameString, currentLD); } else goto exit_error; } else if (indendation == 3) { if (StringUtils_startsWith((char*) lineBuffer, "DO")) { indendation = 4; int arrayElements = 0; sscanf((char*) lineBuffer, "DO(%s %i)", nameString, &arrayElements); currentModelNode = (ModelNode*) DataObject_create(nameString, (ModelNode*) currentLN, arrayElements); } else if (StringUtils_startsWith((char*) lineBuffer, "DS")) { indendation = 4; sscanf((char*) lineBuffer, "DS(%s)", nameString); terminateString(nameString, ')'); currentDataSet = DataSet_create(nameString, currentLN); } else if (StringUtils_startsWith((char*) lineBuffer, "RC")) { int isBuffered; uint32_t confRef; int trgOps; int options; uint32_t bufTm; uint32_t intgPd; int matchedItems = sscanf((char*) lineBuffer, "RC(%s %s %i %s %u %i %i %u %u)", nameString, nameString2, &isBuffered, nameString3, &confRef, &trgOps, &options, &bufTm, &intgPd); if (matchedItems < 9) goto exit_error; char* rptId = NULL; if (strcmp(nameString2, "-") != 0) rptId = nameString2; char* dataSetName = NULL; if (strcmp(nameString3, "-") != 0) dataSetName = nameString3; ReportControlBlock_create(nameString, currentLN, rptId, (bool) isBuffered, dataSetName, confRef, trgOps, options, bufTm, intgPd); } else if (StringUtils_startsWith((char*) lineBuffer, "LC")) { uint32_t trgOps; uint32_t intgPd; int logEna; int withReasonCode; int matchedItems = sscanf((char*) lineBuffer, "LC(%s %s %s %u %u %i %i)", nameString, nameString2, nameString3, &trgOps, &intgPd, &logEna, &withReasonCode); if (matchedItems < 7) goto exit_error; char* dataSet = NULL; if (strcmp(nameString2, "-") != 0) dataSet = nameString2; char* logRef = NULL; if (strcmp(nameString3, "-") != 0) logRef = nameString3; LogControlBlock_create(nameString, currentLN, dataSet, logRef, trgOps, intgPd, logEna, withReasonCode); } else if (StringUtils_startsWith((char*) lineBuffer, "LOG")) { int matchedItems = sscanf((char*) lineBuffer, "LOG(%s)", nameString); if (matchedItems < 1) goto exit_error; /* remove trailing ')' character */ int nameLen = strlen(nameString); nameString[nameLen - 1] = 0; Log_create(nameString, currentLN); } else if (StringUtils_startsWith((char*) lineBuffer, "GC")) { uint32_t confRef; int fixedOffs; int minTime = -1; int maxTime = -1; int matchedItems = sscanf((char*) lineBuffer, "GC(%s %s %s %u %i %i %i)", nameString, nameString2, nameString3, &confRef, &fixedOffs, &minTime, &maxTime); if (matchedItems < 5) goto exit_error; currentGoCB = GSEControlBlock_create(nameString, currentLN, nameString2, nameString3, confRef, fixedOffs, minTime, maxTime); indendation = 4; } #if (CONFIG_IEC61850_SETTING_GROUPS == 1) else if (StringUtils_startsWith((char*) lineBuffer, "SG")) { if (strcmp(currentLN->name, "LLN0") != 0) { if (DEBUG_IED_SERVER) printf("Setting group control is not defined in LLN0\n"); goto exit_error; } int actSG; int numOfSGs; int matchedItems = sscanf((char*) lineBuffer, "SG(%i %i)", &actSG, &numOfSGs); if (matchedItems < 2) goto exit_error; SettingGroupControlBlock_create(currentLN, actSG, numOfSGs); } #endif /* (CONFIG_IEC61850_SETTING_GROUPS == 1) */ else { if (DEBUG_IED_SERVER) printf("IED_SERVER: Unknown identifier (%s)\n", lineBuffer); goto exit_error; } } else if (indendation > 3) { if (StringUtils_startsWith((char*) lineBuffer, "DO")) { indendation++; int arrayElements = 0; int matchedItems = sscanf((char*) lineBuffer, "DO(%s %i)", nameString, &arrayElements); if (matchedItems != 2) goto exit_error; currentModelNode = (ModelNode*) DataObject_create(nameString, currentModelNode, arrayElements); } else if (StringUtils_startsWith((char*) lineBuffer, "DA")) { int arrayElements = 0; int attributeType = 0; int functionalConstraint = 0; int triggerOptions = 0; uint32_t sAddr = 0; sscanf((char*) lineBuffer, "DA(%s %i %i %i %i %u)", nameString, &arrayElements, &attributeType, &functionalConstraint, &triggerOptions, &sAddr); DataAttribute* dataAttribute = DataAttribute_create(nameString, currentModelNode, (DataAttributeType) attributeType, (FunctionalConstraint) functionalConstraint, triggerOptions, arrayElements, sAddr); char* valueIndicator = strchr((char*) lineBuffer, '='); if (valueIndicator != NULL) { switch (dataAttribute->type) { case IEC61850_UNICODE_STRING_255: { char* stringStart = valueIndicator + 2; terminateString(stringStart, '"'); dataAttribute->mmsValue = MmsValue_newMmsString(stringStart); } break; case IEC61850_VISIBLE_STRING_255: case IEC61850_VISIBLE_STRING_129: case IEC61850_VISIBLE_STRING_65: case IEC61850_VISIBLE_STRING_64: case IEC61850_VISIBLE_STRING_32: { char* stringStart = valueIndicator + 2; terminateString(stringStart, '"'); dataAttribute->mmsValue = MmsValue_newVisibleString(stringStart); } break; case IEC61850_INT8: case IEC61850_INT16: case IEC61850_INT32: case IEC61850_INT64: case IEC61850_INT128: case IEC61850_ENUMERATED: { int32_t intValue; if (sscanf(valueIndicator + 1, "%i", &intValue) != 1) goto exit_error; dataAttribute->mmsValue = MmsValue_newIntegerFromInt32(intValue); } break; case IEC61850_INT8U: case IEC61850_INT16U: case IEC61850_INT24U: case IEC61850_INT32U: { uint32_t uintValue; if (sscanf(valueIndicator + 1, "%u", &uintValue) != 1) goto exit_error; dataAttribute->mmsValue = MmsValue_newUnsignedFromUint32(uintValue); } break; case IEC61850_FLOAT32: { float floatValue; if (sscanf(valueIndicator + 1, "%f", &floatValue) != 1) goto exit_error; dataAttribute->mmsValue = MmsValue_newFloat(floatValue); } break; case IEC61850_FLOAT64: { double doubleValue; if (sscanf(valueIndicator + 1, "%lf", &doubleValue) != 1) goto exit_error; dataAttribute->mmsValue = MmsValue_newDouble(doubleValue); } break; case IEC61850_BOOLEAN: { int boolean; if (sscanf(valueIndicator + 1, "%i", &boolean) != 1) goto exit_error; dataAttribute->mmsValue = MmsValue_newBoolean((bool) boolean); } break; default: break; } } int lineLength = strlen((char*) lineBuffer); if (lineBuffer[lineLength - 1] == '{') { indendation++; currentModelNode = (ModelNode*) dataAttribute; } } else if (StringUtils_startsWith((char*) lineBuffer, "DE")) { sscanf((char*) lineBuffer, "DE(%s)", nameString); terminateString(nameString, ')'); DataSetEntry_create(currentDataSet, nameString, -1, NULL); } else if (StringUtils_startsWith((char*) lineBuffer, "PA")) { uint32_t vlanPrio; uint32_t vlanId; uint32_t appId; int matchedItems = sscanf((char*) lineBuffer, "PA(%u %u %u %s)", &vlanPrio, &vlanId, &appId, nameString); if ((matchedItems != 4) || (currentGoCB == NULL)) goto exit_error; terminateString(nameString, ')'); if (strlen(nameString) != 12) goto exit_error; if (StringUtils_createBufferFromHexString(nameString, (uint8_t*) nameString2) != 6) goto exit_error; PhyComAddress* dstAddress = PhyComAddress_create((uint8_t) vlanPrio, (uint16_t) vlanId, (uint16_t) appId, (uint8_t*) nameString2); GSEControlBlock_addPhyComAddress(currentGoCB, dstAddress); } else goto exit_error; } } else { if (StringUtils_startsWith((char*) lineBuffer, "MODEL{")) { model = IedModel_create(""); stateInModel = true; indendation = 1; } else if (StringUtils_startsWith((char*) lineBuffer, "MODEL(")) { sscanf((char*) lineBuffer, "MODEL(%s)", nameString); terminateString(nameString, ')'); model = IedModel_create(nameString); stateInModel = true; indendation = 1; } else goto exit_error; } } } return model; exit_error: if (DEBUG_IED_SERVER) printf("IED_SERVER: error parsing line %i (indendation level = %i)\n", currentLine, indendation); IedModel_destroy(model); return NULL; }