static MmsValue* createOptFlds(ReportControlBlock* reportControlBlock) { MmsValue* optFlds = MmsValue_newBitString(10); uint8_t options = reportControlBlock->options; if (options & 0x01) MmsValue_setBitStringBit(optFlds, 1, true); if (options & 0x02) MmsValue_setBitStringBit(optFlds, 2, true); if (options & 0x04) MmsValue_setBitStringBit(optFlds, 3, true); if (options & 0x08) MmsValue_setBitStringBit(optFlds, 4, true); if (options & 0x10) MmsValue_setBitStringBit(optFlds, 5, true); if (options & 0x20) MmsValue_setBitStringBit(optFlds, 6, true); if (options & 0x40) MmsValue_setBitStringBit(optFlds, 7, true); if (options & 0x80) MmsValue_setBitStringBit(optFlds, 8, true); return optFlds; }
static MmsValue* createTrgOps(ReportControlBlock* reportControlBlock) { MmsValue* trgOps = MmsValue_newBitString(6); uint8_t triggerOps = reportControlBlock->trgOps; if (triggerOps & 0x02) MmsValue_setBitStringBit(trgOps, 1, true); if (triggerOps & 0x04) MmsValue_setBitStringBit(trgOps, 2, true); if (triggerOps & 0x08) MmsValue_setBitStringBit(trgOps, 3, true); if (triggerOps & 0x10) MmsValue_setBitStringBit(trgOps, 4, true); if (triggerOps & 0x20) MmsValue_setBitStringBit(trgOps, 5, true); return trgOps; }
bool ControlObjectClient_selectWithValue(ControlObjectClient self, MmsValue* ctlVal) { resetLastApplError(self); char domainId[65]; char itemId[65]; MmsMapping_getMmsDomainFromObjectReference(self->objectReference, domainId); convertToMmsAndInsertFC(itemId, self->objectReference + strlen(domainId) + 1, "CO"); strncat(itemId, "$SBOw", 64); if (DEBUG_IED_CLIENT) printf("IED_CLIENT: select with value: %s/%s\n", domainId, itemId); MmsError mmsError; MmsValue* selValParameters; if (self->hasTimeActivatedMode) selValParameters = MmsValue_createEmptyStructure(7); else selValParameters = MmsValue_createEmptyStructure(6); MmsValue_setElement(selValParameters, 0, ctlVal); int index = 1; if (self->hasTimeActivatedMode) { MmsValue* operTm = MmsValue_newUtcTimeByMsTime(0); MmsValue_setElement(selValParameters, index++, operTm); } MmsValue* origin = createOriginValue(self); MmsValue_setElement(selValParameters, index++, origin); self->ctlNum++; MmsValue* ctlNum = MmsValue_newUnsignedFromUint32(self->ctlNum); MmsValue_setElement(selValParameters, 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(selValParameters, index++, ctlTime); MmsValue* ctlTest = MmsValue_newBoolean(self->test); MmsValue_setElement(selValParameters, index++, ctlTest); MmsValue* check = MmsValue_newBitString(2); MmsValue_setBitStringBit(check, 1, self->interlockCheck); MmsValue_setBitStringBit(check, 0, self->synchroCheck); MmsValue_setElement(selValParameters, index++, check); MmsConnection_writeVariable(IedConnection_getMmsConnection(self->connection), &mmsError, domainId, itemId, selValParameters); MmsValue_setElement(selValParameters, 0, NULL); MmsValue_delete(selValParameters); if (mmsError != MMS_ERROR_NONE) { if (DEBUG_IED_CLIENT) printf("IED_CLIENT: select-with-value failed!\n"); return false; } MmsValue_update(self->ctlVal, ctlVal); 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 void sendReport(ReportControl* self, bool isIntegrity, bool isGI) { LinkedList reportElements = LinkedList_create(); LinkedList deletableElements = LinkedList_create(); MmsValue* rptId = ReportControl_getRCBValue(self, "RptID"); MmsValue* optFlds = ReportControl_getRCBValue(self, "OptFlds"); MmsValue* datSet = ReportControl_getRCBValue(self, "DatSet"); LinkedList_add(reportElements, rptId); LinkedList_add(reportElements, optFlds); /* delete option fields for unsupported options */ MmsValue_setBitStringBit(optFlds, 5, false); /* data-reference */ MmsValue_setBitStringBit(optFlds, 7, false); /* entryID */ MmsValue_setBitStringBit(optFlds, 9, false); /* segmentation */ MmsValue* sqNum = ReportControl_getRCBValue(self, "SqNum"); if (MmsValue_getBitStringBit(optFlds, 1)) /* sequence number */ LinkedList_add(reportElements, sqNum); if (MmsValue_getBitStringBit(optFlds, 2)) { /* report time stamp */ LinkedList_add(reportElements, self->timeOfEntry); } if (MmsValue_getBitStringBit(optFlds, 4)) /* data set reference */ LinkedList_add(reportElements, datSet); if (MmsValue_getBitStringBit(optFlds, 6)) { /* bufOvfl */ MmsValue* bufOvfl = MmsValue_newBoolean(false); LinkedList_add(reportElements, bufOvfl); LinkedList_add(deletableElements, bufOvfl); } if (MmsValue_getBitStringBit(optFlds, 8)) LinkedList_add(reportElements, self->confRev); if (isGI || isIntegrity) MmsValue_setAllBitStringBits(self->inclusionField); else MmsValue_deleteAllBitStringBits(self->inclusionField); LinkedList_add(reportElements, self->inclusionField); /* add data set value elements */ int i = 0; for (i = 0; i < self->dataSet->elementCount; i++) { if (isGI || isIntegrity) LinkedList_add(reportElements, self->dataSet->fcda[i]->value); else { if (self->inclusionFlags[i] != REPORT_CONTROL_NONE) { LinkedList_add(reportElements, self->dataSet->fcda[i]->value); MmsValue_setBitStringBit(self->inclusionField, i, true); } } } /* add reason code to report if requested */ if (MmsValue_getBitStringBit(optFlds, 3)) { for (i = 0; i < self->dataSet->elementCount; i++) { if (isGI || isIntegrity) { MmsValue* reason = MmsValue_newBitString(6); if (isGI) MmsValue_setBitStringBit(reason, 5, true); if (isIntegrity) MmsValue_setBitStringBit(reason, 4, true); LinkedList_add(reportElements, reason); LinkedList_add(deletableElements, reason); } else if (self->inclusionFlags[i] != REPORT_CONTROL_NONE) { MmsValue* reason = MmsValue_newBitString(6); switch(self->inclusionFlags[i]) { case REPORT_CONTROL_QUALITY_CHANGED: MmsValue_setBitStringBit(reason, 2, true); break; case REPORT_CONTROL_VALUE_CHANGED: MmsValue_setBitStringBit(reason, 1, true); break; case REPORT_CONTROL_VALUE_UPDATE: MmsValue_setBitStringBit(reason, 3, true); break; } LinkedList_add(reportElements, reason); LinkedList_add(deletableElements, reason); } } } /* clear inclusion flags */ for (i = 0; i < self->dataSet->elementCount; i++) { self->inclusionFlags[i] = REPORT_CONTROL_NONE; } MmsServerConnection_sendInformationReportVMDSpecific(self->clientConnection, "RPT", reportElements); /* Increase sequence number */ self->sqNum++; MmsValue_setUint16(sqNum, self->sqNum); LinkedList_destroyDeep(deletableElements, (LinkedListValueDeleteFunction) MmsValue_delete); LinkedList_destroyStatic(reportElements); /* clear GI flag */ if (isGI) { MmsValue* gi = ReportControl_getRCBValue(self, "GI"); self->gi = false; MmsValue_setBoolean(gi, false); } }