private static bool myInterrogationHandler(object parameter, IMasterConnection connection, ASDU asdu, byte qoi) { if (asdu.Ca == slaveAddress) { Console.WriteLine("Interrogation for group " + qoi); connection.SendACT_CON(asdu, false); // send information objects ASDU newAsdu = new ASDU(connection.GetApplicationLayerParameters(), CauseOfTransmission.INTERROGATED_BY_STATION, false, false, 2, slaveAddress, false); newAsdu.AddInformationObject(new MeasuredValueScaled(100, -1, new QualityDescriptor())); newAsdu.AddInformationObject(new MeasuredValueScaled(101, 23, new QualityDescriptor())); newAsdu.AddInformationObject(new MeasuredValueScaled(102, 2300, new QualityDescriptor())); connection.SendASDU(newAsdu); // send sequence of information objects newAsdu = new ASDU(connection.GetApplicationLayerParameters(), CauseOfTransmission.INTERROGATED_BY_STATION, false, false, 2, slaveAddress, true); newAsdu.AddInformationObject(new SinglePointInformation(200, true, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(201, false, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(202, true, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(203, false, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(204, true, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(205, false, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(206, true, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(207, false, new QualityDescriptor())); connection.SendASDU(newAsdu); connection.SendACT_TERM(asdu); } return(true); }
private static bool OnInterrogation(object parameter, IMasterConnection connection, ASDU asdu, byte qoi) { if (qoi != 20 && qoi != 21) { return(false); } var cp = connection.GetApplicationLayerParameters(); connection.SendACT_CON(asdu, false); var newAsdu = new ASDU(cp, TypeID.M_ME_TF_1, CauseOfTransmission.INTERROGATED_BY_STATION, false, false, 0, _settings.RTUID, false); var time = new CP56Time2a(DateTime.UtcNow.AddSeconds(-_settings.RequestDepth)); lock (_lastSentData) { foreach (var pair in _lastSentData) { if (!newAsdu.AddInformationObject(new MeasuredValueShortWithCP56Time2a(pair.Key, pair.Value, _qd, time))) { connection.SendASDU(newAsdu); newAsdu = new ASDU(cp, TypeID.M_ME_TF_1, CauseOfTransmission.INTERROGATED_BY_STATION, false, false, 0, _settings.RTUID, false); } } } if (newAsdu.NumberOfElements > 0) { connection.SendASDU(newAsdu); } connection.SendACT_TERM(asdu); return(true); }
private static bool asduHandler(object parameter, IMasterConnection connection, ASDU asdu) { if (asdu.TypeId == TypeID.C_SC_NA_1) { SingleCommand sc = (SingleCommand)asdu.GetElement(0); if (sc.ObjectAddress != 100) { // Unkown IOA --> send negative confirmation asdu.Cot = CauseOfTransmission.UNKNOWN_INFORMATION_OBJECT_ADDRESS; asdu.IsNegative = true; connection.SendASDU(asdu); } else { // execute command // send positive confirmation connection.SendACT_CON(asdu, false); } } if (asdu.TypeId == TypeID.C_SC_NA_1) { Console.WriteLine("Single command"); SingleCommand sc = (SingleCommand)asdu.GetElement(0); Console.WriteLine(sc.ToString()); } else if (asdu.TypeId == TypeID.M_EI_NA_1) { Console.WriteLine("End of initialization received"); } else if (asdu.TypeId == TypeID.F_DR_TA_1) { Console.WriteLine("Received file directory"); } else if (asdu.TypeId == TypeID.C_CS_NA_1) { ClockSynchronizationCommand qsc = (ClockSynchronizationCommand)asdu.GetElement(0); Console.WriteLine("Received clock sync command with time " + qsc.NewTime.ToString()); } return(true); }
private static bool interrogationHandler(object parameter, IMasterConnection connection, ASDU asdu, byte qoi) { Console.WriteLine("Interrogation for group " + qoi); ApplicationLayerParameters cp = connection.GetApplicationLayerParameters(); connection.SendACT_CON(asdu, false); // send sequence of information objects ASDU newAsdu = new ASDU(cp, CauseOfTransmission.INTERROGATED_BY_STATION, false, false, 1, 1, true); rfile( ); ToServer(ref newAsdu); connection.SendASDU(newAsdu); connection.SendACT_TERM(asdu); return(true); }
public bool HandleFileAsdu(ASDU asdu) { bool handled = true; switch (asdu.TypeId) { case TypeID.F_AF_NA_1: /* 124 - ACK file, ACK section */ logger("Received file/section ACK F_AF_NA_1"); if (asdu.Cot == CauseOfTransmission.FILE_TRANSFER) { if (transferState != FileServerState.UNSELECTED_IDLE) { IFileProvider file = selectedFile.provider; FileACK ack = (FileACK)asdu.GetElement(0); if (ack.AckQualifier == AcknowledgeQualifier.POS_ACK_FILE) { logger("Received positive file ACK"); if (transferState == FileServerState.WAITING_FOR_FILE_ACK) { selectedFile.provider.TransferComplete(true); availableFiles.RemoveFile(selectedFile.provider); selectedFile = null; transferState = FileServerState.UNSELECTED_IDLE; } else { logger("Unexpected file transfer state --> abort file transfer"); transferState = FileServerState.SEND_ABORT; } } else if (ack.AckQualifier == AcknowledgeQualifier.NEG_ACK_FILE) { logger("Received negative file ACK - stop transfer"); if (transferState == FileServerState.WAITING_FOR_FILE_ACK) { selectedFile.provider.TransferComplete(false); selectedFile.selectedBy = null; selectedFile = null; transferState = FileServerState.UNSELECTED_IDLE; } else { logger("Unexpected file transfer state --> abort file transfer"); transferState = FileServerState.SEND_ABORT; } } else if (ack.AckQualifier == AcknowledgeQualifier.NEG_ACK_SECTION) { logger("Received negative file section ACK - repeat section"); if (transferState == FileServerState.WAITING_FOR_SECTION_ACK) { currentSectionOffset = 0; sectionChecksum = 0; ASDU sectionReady = new ASDU(alParameters, CauseOfTransmission.FILE_TRANSFER, false, false, 0, file.GetCA(), false); sectionReady.AddInformationObject( new SectionReady(selectedFile.provider.GetIOA(), selectedFile.provider.GetNameOfFile(), currentSectionNumber, currentSectionSize, false)); connection.SendASDU(sectionReady); transferState = FileServerState.TRANSMIT_SECTION; } else { logger("Unexpected file transfer state --> abort file transfer"); transferState = FileServerState.SEND_ABORT; } } else if (ack.AckQualifier == AcknowledgeQualifier.POS_ACK_SECTION) { if (transferState == FileServerState.WAITING_FOR_SECTION_ACK) { currentSectionNumber++; int nextSectionSize = selectedFile.provider.GetSectionSize(currentSectionNumber); ASDU responseAsdu = new ASDU(alParameters, CauseOfTransmission.FILE_TRANSFER, false, false, 0, file.GetCA(), false); if (nextSectionSize == -1) { logger("Reveived positive file section ACK - send last section indication"); responseAsdu.AddInformationObject( new FileLastSegmentOrSection(file.GetIOA(), file.GetNameOfFile(), (byte)currentSectionNumber, LastSectionOrSegmentQualifier.FILE_TRANSFER_WITHOUT_DEACT, fileChecksum)); transferState = FileServerState.WAITING_FOR_FILE_ACK; } else { logger("Reveived positive file section ACK - send next section ready indication"); currentSectionSize = nextSectionSize; responseAsdu.AddInformationObject( new SectionReady(selectedFile.provider.GetIOA(), selectedFile.provider.GetNameOfFile(), currentSectionNumber, currentSectionSize, false)); transferState = FileServerState.WAITING_FOR_SECTION_CALL; } connection.SendASDU(responseAsdu); sectionChecksum = 0; } else { logger("Unexpected file transfer state --> abort file transfer"); transferState = FileServerState.SEND_ABORT; } } } else { // No file transmission in progress --> what to do? logger("Unexpected File ACK message -> ignore"); } } else { asdu.Cot = CauseOfTransmission.UNKNOWN_CAUSE_OF_TRANSMISSION; connection.SendASDU(asdu); } break; case TypeID.F_SC_NA_1: /* 122 - Call/Select directoy/file/section */ logger("Received call/select F_SC_NA_1"); if (asdu.Cot == CauseOfTransmission.FILE_TRANSFER) { FileCallOrSelect sc = (FileCallOrSelect)asdu.GetElement(0); if (sc.SCQ == SelectAndCallQualifier.SELECT_FILE) { if (transferState == FileServerState.UNSELECTED_IDLE) { logger("Received SELECT FILE"); CS101n104File file = availableFiles.GetFile(asdu.Ca, sc.ObjectAddress, sc.NOF); if (file == null) { asdu.Cot = CauseOfTransmission.UNKNOWN_INFORMATION_OBJECT_ADDRESS; connection.SendASDU(asdu); } else { ASDU fileReady = new ASDU(alParameters, CauseOfTransmission.FILE_TRANSFER, false, false, 0, asdu.Ca, false); // check if already selected if (file.selectedBy == null) { file.selectedBy = this; fileReady.AddInformationObject(new FileReady(sc.ObjectAddress, sc.NOF, file.provider.GetFileSize(), true)); } else { fileReady.AddInformationObject(new FileReady(sc.ObjectAddress, sc.NOF, 0, false)); } connection.SendASDU(fileReady); selectedFile = file; transferState = FileServerState.WAITING_FOR_FILE_CALL; } } else { logger("Unexpected SELECT FILE message"); } } else if (sc.SCQ == SelectAndCallQualifier.DEACTIVATE_FILE) { logger("Received DEACTIVATE FILE"); if (transferState != FileServerState.UNSELECTED_IDLE) { if (selectedFile != null) { selectedFile.selectedBy = null; selectedFile = null; } transferState = FileServerState.UNSELECTED_IDLE; } else { logger("Unexpected DEACTIVATE FILE message"); } } else if (sc.SCQ == SelectAndCallQualifier.REQUEST_FILE) { logger("Received CALL FILE"); if (transferState == FileServerState.WAITING_FOR_FILE_CALL) { if (selectedFile.provider.GetIOA() != sc.ObjectAddress) { logger("Unkown IOA"); asdu.Cot = CauseOfTransmission.UNKNOWN_INFORMATION_OBJECT_ADDRESS; connection.SendASDU(asdu); } else { ASDU sectionReady = new ASDU(alParameters, CauseOfTransmission.FILE_TRANSFER, false, false, 0, asdu.Ca, false); sectionReady.AddInformationObject(new SectionReady(sc.ObjectAddress, selectedFile.provider.GetNameOfFile(), 0, 0, false)); connection.SendASDU(sectionReady); logger("Send SECTION READY"); currentSectionNumber = 0; currentSectionOffset = 0; currentSectionSize = selectedFile.provider.GetSectionSize(0); transferState = FileServerState.WAITING_FOR_SECTION_CALL; } } else { logger("Unexpected FILE CALL message"); } } else if (sc.SCQ == SelectAndCallQualifier.REQUEST_SECTION) { logger("Received CALL SECTION"); if (transferState == FileServerState.WAITING_FOR_SECTION_CALL) { if (selectedFile.provider.GetIOA() != sc.ObjectAddress) { logger("Unkown IOA"); asdu.Cot = CauseOfTransmission.UNKNOWN_INFORMATION_OBJECT_ADDRESS; connection.SendASDU(asdu); } else { transferState = FileServerState.TRANSMIT_SECTION; } } else { logger("Unexpected SECTION CALL message"); } } } else if (asdu.Cot == CauseOfTransmission.REQUEST) { logger("Call directory received"); availableFiles.SendDirectoy(connection, false); } else { asdu.Cot = CauseOfTransmission.UNKNOWN_CAUSE_OF_TRANSMISSION; connection.SendASDU(asdu); } break; default: handled = false; break; } return(handled); }
internal void SendDirectoy(IMasterConnection masterConnection, bool spontaneous) { CauseOfTransmission cot; if (spontaneous) { cot = CauseOfTransmission.SPONTANEOUS; } else { cot = CauseOfTransmission.REQUEST; } lock (availableFiles) { int size = availableFiles.Count; int i = 0; int currentCa = -1; int currentIOA = -1; ASDU directoryAsdu = null; foreach (CS101n104File file in availableFiles) { bool newAsdu = false; if (file.provider.GetCA() != currentCa) { currentCa = file.provider.GetCA(); newAsdu = true; } if (currentIOA != (file.provider.GetIOA() - 1)) { newAsdu = true; } if (newAsdu) { if (directoryAsdu != null) { masterConnection.SendASDU(directoryAsdu); directoryAsdu = null; } } currentIOA = file.provider.GetIOA(); i++; if (directoryAsdu == null) { directoryAsdu = new ASDU(masterConnection.GetApplicationLayerParameters(), cot, false, false, 0, currentCa, true); } bool lastFile = (i == size); byte sof = 0; if (lastFile) { sof = 0x20; } InformationObject io = new FileDirectory(currentIOA, file.provider.GetNameOfFile(), file.provider.GetFileSize(), sof, new CP56Time2a(file.provider.GetFileDate())); if (!directoryAsdu.AddInformationObject(io) == false) { masterConnection.SendASDU(directoryAsdu); directoryAsdu = new ASDU(masterConnection.GetApplicationLayerParameters(), cot, false, false, 0, currentCa, true); directoryAsdu.AddInformationObject(io); } } if (directoryAsdu != null) { masterConnection.SendASDU(directoryAsdu); } } }
private static bool interrogationHandler(object parameter, IMasterConnection connection, ASDU asdu, byte qoi) { Console.WriteLine("Interrogation for group " + qoi); ApplicationLayerParameters cp = connection.GetApplicationLayerParameters(); connection.SendACT_CON(asdu, false); // send information objects ASDU newAsdu = new ASDU(cp, CauseOfTransmission.INTERROGATED_BY_STATION, false, false, 2, 1, false); newAsdu.AddInformationObject(new MeasuredValueScaled(100, -1, new QualityDescriptor())); newAsdu.AddInformationObject(new MeasuredValueScaled(101, 23, new QualityDescriptor())); newAsdu.AddInformationObject(new MeasuredValueScaled(102, 2300, new QualityDescriptor())); connection.SendASDU(newAsdu); newAsdu = new ASDU(cp, CauseOfTransmission.INTERROGATED_BY_STATION, false, false, 3, 1, false); newAsdu.AddInformationObject(new MeasuredValueScaledWithCP56Time2a(103, 3456, new QualityDescriptor(), new CP56Time2a(DateTime.Now))); connection.SendASDU(newAsdu); newAsdu = new ASDU(cp, CauseOfTransmission.INTERROGATED_BY_STATION, false, false, 2, 1, false); newAsdu.AddInformationObject(new SinglePointWithCP56Time2a(104, true, new QualityDescriptor(), new CP56Time2a(DateTime.Now))); connection.SendASDU(newAsdu); // send sequence of information objects newAsdu = new ASDU(cp, CauseOfTransmission.INTERROGATED_BY_STATION, false, false, 2, 1, true); newAsdu.AddInformationObject(new SinglePointInformation(200, true, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(201, false, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(202, true, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(203, false, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(204, true, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(205, false, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(206, true, new QualityDescriptor())); newAsdu.AddInformationObject(new SinglePointInformation(207, false, new QualityDescriptor())); connection.SendASDU(newAsdu); newAsdu = new ASDU(cp, CauseOfTransmission.INTERROGATED_BY_STATION, false, false, 2, 1, true); newAsdu.AddInformationObject(new MeasuredValueNormalizedWithoutQuality(300, -1.0f)); newAsdu.AddInformationObject(new MeasuredValueNormalizedWithoutQuality(301, -0.5f)); newAsdu.AddInformationObject(new MeasuredValueNormalizedWithoutQuality(302, -0.1f)); newAsdu.AddInformationObject(new MeasuredValueNormalizedWithoutQuality(303, .0f)); newAsdu.AddInformationObject(new MeasuredValueNormalizedWithoutQuality(304, 0.1f)); newAsdu.AddInformationObject(new MeasuredValueNormalizedWithoutQuality(305, 0.2f)); newAsdu.AddInformationObject(new MeasuredValueNormalizedWithoutQuality(306, 0.5f)); newAsdu.AddInformationObject(new MeasuredValueNormalizedWithoutQuality(307, 0.7f)); newAsdu.AddInformationObject(new MeasuredValueNormalizedWithoutQuality(308, 0.99f)); newAsdu.AddInformationObject(new MeasuredValueNormalizedWithoutQuality(309, 1f)); connection.SendASDU(newAsdu); connection.SendACT_TERM(asdu); return(true); }
InterrogationHandler( object parameter, IMasterConnection connection, ASDU asdu, byte qoi ) { var srv = IEC10Xconns[(int)parameter]; var conNameStr = srv.name + " - "; Log(conNameStr + "[" + qoi + "] Group interrogation BEGIN", LogLevelBasic); try { var Client = new MongoClient(JSConfig.mongoConnectionString); var DB = Client.GetDatabase(JSConfig.mongoDatabaseName); var collection = DB.GetCollection <rtData>(RealtimeDataCollectionName); ApplicationLayerParameters cp = connection.GetApplicationLayerParameters(); // query mongodb for all data to distribute in this connection // for group 20 (general interogation) request filter by all in destination connection but those marked with group -1 // for other groups requests filter by by those marked with group this same group var filter_conn = Builders <rtData> .Filter.Eq("protocolDestinations.protocolDestinationConnectionNumber", srv.protocolConnectionNumber); var filter_cmd = Builders <rtData> .Filter.Ne("origin", "command"); var filter_gen_int = Builders <rtData> .Filter.And(filter_conn, filter_cmd, Builders <rtData> .Filter.Ne("protocolDestinations.protocolDestinationGroup", -1)); var filter_oth_grp = Builders <rtData> .Filter.And(filter_conn, filter_cmd, Builders <rtData> .Filter.Or( Builders <rtData> .Filter.Eq("protocolDestinations.protocolDestinationGroup", qoi), // accept 20-36 or 0-16 Builders <rtData> .Filter.Eq("protocolDestinations.protocolDestinationGroup", qoi - 20) ) ); var sort = Builders <rtData> .Sort.Descending("$natural"); var options = new FindOptions <rtData, rtData>(); options.Sort = sort; var filter = filter_gen_int; if (qoi != 20) { filter = filter_oth_grp; } var list = collection.Find(filter).ToList(); int CompareASDUInDest(rtData x, rtData y) { var asdu1 = x.protocolDestinations[0].protocolDestinationASDU; foreach (var dst in x.protocolDestinations) { if (dst.protocolDestinationConnectionNumber == srv.protocolConnectionNumber) { asdu1 = dst.protocolDestinationASDU; } } var asdu2 = y.protocolDestinations[0].protocolDestinationASDU; foreach (var dst in y.protocolDestinations) { if (dst.protocolDestinationConnectionNumber == srv.protocolConnectionNumber) { asdu2 = dst.protocolDestinationASDU; } } if (asdu1 == asdu2) { return(0); } if (asdu1 > asdu2) { return(1); } return(-1); } list.Sort(CompareASDUInDest); // order by ASDU Log(conNameStr + "[" + qoi + "] Group request, " + list.Count() + " objects to send.", LogLevelBasic); connection.SendACT_CON(asdu, false); // confirm positive var lastasdu = -1; var cntasduobj = 0; ASDU nwasdu = null; foreach (rtData entry in list) { Log(conNameStr + "[" + qoi + "] " + entry.tag.ToString() + " " + entry.value + " Key " + entry._id, LogLevelDetailed); foreach (var dst in entry.protocolDestinations) { var q = new QualityDescriptor(); q.Invalid = entry.invalid.ToBoolean(); q.Substituted = entry.substituted.ToBoolean(); q.NonTopical = false; q.Blocked = false; q.Overflow = entry.overflow.ToBoolean(); if (dst.protocolDestinationConnectionNumber == srv.protocolConnectionNumber) { if ((lastasdu != dst.protocolDestinationASDU && cntasduobj > 0) || cntasduobj >= 30) { if (nwasdu != null) { Log(conNameStr + "[" + qoi + "] Send ASDU TI:" + System.Convert.ToByte(nwasdu.TypeId) + "." + nwasdu.TypeId + " CA:" + nwasdu.Ca + " with " + nwasdu.NumberOfElements + " objects."); connection.SendASDU(nwasdu); nwasdu = null; cntasduobj = 0; lastasdu = -1; } } switch (dst.protocolDestinationASDU.ToInt32()) { case 1: case 30: if (cntasduobj == 0) { nwasdu = new ASDU(cp, (CauseOfTransmission)qoi, false, false, System.Convert.ToByte(cp.OA), System.Convert.ToInt32(dst.protocolDestinationCommonAddress.ToDouble()), false); } if (nwasdu != null) { var bval = entry.value != 0 ? true : false; if (dst.protocolDestinationKConv1 == -1) { bval = !bval; } nwasdu .AddInformationObject(new SinglePointInformation(System.Convert.ToInt32(dst.protocolDestinationObjectAddress.ToDouble()), bval, q)); cntasduobj++; } break; case 3: case 31: if (cntasduobj == 0) { nwasdu = new ASDU(cp, (CauseOfTransmission)qoi, false, false, System.Convert.ToByte(cp.OA), System.Convert.ToInt32(dst.protocolDestinationCommonAddress.ToDouble()), false); } if (nwasdu != null) { var dpval = entry.value != 0 ? DoublePointValue.ON : DoublePointValue.OFF; if (dst.protocolDestinationKConv1 == -1) { dpval = entry.value != 0 ? DoublePointValue.OFF : DoublePointValue.ON; } if (entry.transient.ToBoolean()) { dpval = DoublePointValue.INTERMEDIATE; } nwasdu .AddInformationObject(new DoublePointInformation(System.Convert.ToInt32(dst.protocolDestinationObjectAddress.ToDouble()), dpval, q)); cntasduobj++; } break; case 5: case 32: if (cntasduobj == 0) { nwasdu = new ASDU(cp, (CauseOfTransmission)qoi, false, false, System.Convert.ToByte(cp.OA), System.Convert.ToInt32(dst.protocolDestinationCommonAddress.ToDouble()), false); } if (nwasdu != null) { var val = dst.protocolDestinationKConv1.ToDouble() * System.Convert.ToDouble(entry.value) + dst.protocolDestinationKConv2.ToDouble(); if (val > 63) { val = 63; q.Overflow = true; } else if (val < -64) { val = -64; q.Overflow = true; } nwasdu .AddInformationObject(new StepPositionInformation(System.Convert.ToInt32(dst.protocolDestinationObjectAddress.ToDouble()), System.Convert.ToInt16(val), entry.transient.ToBoolean(), q)); cntasduobj++; } break; case 9: case 34: if (cntasduobj == 0) { nwasdu = new ASDU(cp, (CauseOfTransmission)qoi, false, false, System.Convert.ToByte(cp.OA), System.Convert.ToInt32(dst.protocolDestinationCommonAddress.ToDouble()), false); } if (nwasdu != null) { var val = dst.protocolDestinationKConv1.ToDouble() * System.Convert.ToDouble(entry.value) + dst.protocolDestinationKConv2.ToDouble(); if (val > 32767) { val = 32767; q.Overflow = true; } else if (val < -32768) { val = -32768; q.Overflow = true; } nwasdu .AddInformationObject(new MeasuredValueNormalized(System.Convert.ToInt32(dst.protocolDestinationObjectAddress.ToDouble()), System.Convert.ToInt16(val), new QualityDescriptor())); cntasduobj++; } break; case 11: case 35: if (cntasduobj == 0) { nwasdu = new ASDU(cp, (CauseOfTransmission)qoi, false, false, System.Convert.ToByte(cp.OA), System.Convert.ToInt32(dst.protocolDestinationCommonAddress.ToDouble()), false); } if (nwasdu != null) { var val = dst.protocolDestinationKConv1.ToDouble() * System.Convert.ToDouble(entry.value) + dst.protocolDestinationKConv2.ToDouble(); if (val > 32767) { val = 32767; q.Overflow = true; } else if (val < -32768) { val = -32768; q.Overflow = true; } nwasdu .AddInformationObject(new MeasuredValueScaled(System.Convert.ToInt32(dst.protocolDestinationObjectAddress.ToDouble()), System.Convert.ToInt16(val), new QualityDescriptor())); cntasduobj++; } break; case 13: case 36: if (cntasduobj == 0) { nwasdu = new ASDU(cp, (CauseOfTransmission)qoi, false, false, System.Convert.ToByte(cp.OA), System.Convert.ToInt32(dst.protocolDestinationCommonAddress.ToDouble()), false); } if (nwasdu != null) { var val = dst.protocolDestinationKConv1.ToDouble() * System.Convert.ToDouble(entry.value) + dst.protocolDestinationKConv2.ToDouble(); nwasdu .AddInformationObject(new MeasuredValueShort(System.Convert.ToInt32(dst.protocolDestinationObjectAddress.ToDouble()), System.Convert.ToSingle(val), new QualityDescriptor())); cntasduobj++; } break; default: break; } lastasdu = dst.protocolDestinationASDU.ToInt32(); break; } } } if (nwasdu != null) { Log(conNameStr + "[" + qoi + "] Send ASDU TI:" + System.Convert.ToByte(nwasdu.TypeId) + "." + nwasdu.TypeId + " CA:" + nwasdu.Ca + " with " + nwasdu.NumberOfElements + " objects.", LogLevelBasic); connection.SendASDU(nwasdu); nwasdu = null; } connection.SendACT_TERM(asdu); Log(conNameStr + "[" + qoi + "] Group interrogation END", LogLevelBasic); } catch (Exception e) { if (e.Message == "Connection not active") { return(true); } Log("Exception on Interrogation"); Log(e); Log(e .ToString() .Substring(0, e.ToString().IndexOf(Environment.NewLine))); System.Threading.Thread.Sleep(3000); connection.SendACT_CON(asdu, true); // negative confirm return(true); } return(true); }