示例#1
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
        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);
                }
            }
        }
示例#7
0
        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);
        }