Пример #1
0
        private static bool asduHandler(object parameter, IMasterConnection connection, ASDU asdu)
        {
            if (asdu.TypeId == TypeID.C_SC_NA_1)
            {
                Console.WriteLine("Single command");

                SingleCommand sc = (SingleCommand)asdu.GetElement(0);

                if (sc.Select)
                {
                    Console.WriteLine("  received select");
                }
                else
                {
                    Console.WriteLine("  received execute");
                }

                Console.WriteLine(sc.ToString());

                connection.SendACT_CON(asdu, false);
            }
            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());

                connection.SendACT_CON(asdu, false);
            }

            return(true);
        }
Пример #2
0
        private static bool asduHandler(object parameter, IMasterConnection connection, ASDU asdu)
        {
            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);
        }
Пример #3
0
        private static bool asduHandler(object parameter, IMasterConnection connection, ASDU asdu)
        {
            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.C_CS_NA_1)
            {
                ClockSynchronizationCommand qsc = (ClockSynchronizationCommand)asdu.GetElement(0);

                Console.WriteLine("Received clock sync command with time " + qsc.NewTime.ToString());
            }

            if (asdu.TypeId == TypeID.M_ME_TF_1)
            {
                MeasuredValueShortWithCP56Time2a sc = (MeasuredValueShortWithCP56Time2a)asdu.GetElement(0);
                Console.WriteLine(sc.ToString());
            }
            if (asdu.TypeId == TypeID.M_ME_NC_1)
            {
                MeasuredValueShort sc = (MeasuredValueShort)asdu.GetElement(0);
                Console.WriteLine(sc.ToString());
            }
            return(true);
        }
Пример #4
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);
        }
Пример #5
0
        BuildInfoObj(
            Int32 asdu,
            Int32 addr,
            Double value,
            Boolean sbo               = false,
            Int32 cmdqualif           = 0,
            QualityDescriptor quality = null,
            CP56Time2a time_tag       = null,
            Double kconv1             = 1,
            Double kconv2             = 0,
            Boolean transient         = false
            )
        {
            InformationObject sc = null;

            if (time_tag == null)
            {
                time_tag = new CP56Time2a(DateTime.Now);
            }
            else
            { // has time tag, so change ASDU if necessary to embed a timetag
                var maptowithcp56time = new Dictionary <TypeID, TypeID>();
                maptowithcp56time.Add(TypeID.M_SP_NA_1, TypeID.M_SP_TB_1);
                maptowithcp56time.Add(TypeID.M_DP_NA_1, TypeID.M_DP_TB_1);
                maptowithcp56time.Add(TypeID.M_ST_NA_1, TypeID.M_ST_TB_1);
                maptowithcp56time.Add(TypeID.M_BO_NA_1, TypeID.M_BO_TB_1);
                maptowithcp56time.Add(TypeID.M_ME_NA_1, TypeID.M_ME_TD_1);
                maptowithcp56time.Add(TypeID.M_ME_NB_1, TypeID.M_ME_TE_1);
                maptowithcp56time.Add(TypeID.M_ME_NC_1, TypeID.M_ME_TF_1);
                maptowithcp56time.Add(TypeID.M_IT_NA_1, TypeID.M_IT_TB_1);
                if (maptowithcp56time.TryGetValue((TypeID)asdu, out var newasdu))
                {
                    asdu = (Int32)newasdu;
                }
            }

            Boolean bval;
            Int32   ival;
            UInt32  uival;

            switch ((TypeID)asdu)
            {
            case TypeID.M_SP_NA_1:     // 1
                bval = value != 0 ? true : false;
                if (kconv1 == -1)
                {
                    bval = !bval;
                }
                sc =
                    new SinglePointInformation(addr,
                                               bval,
                                               quality);
                break;

            case TypeID.M_SP_TB_1:     // 30
                bval = value != 0 ? true : false;
                if (kconv1 == -1)
                {
                    bval = !bval;
                }
                sc =
                    new SinglePointWithCP56Time2a(addr,
                                                  bval,
                                                  quality,
                                                  time_tag
                                                  );
                break;

            case TypeID.M_DP_NA_1:     // 3
                if (transient)
                {
                    sc =
                        new DoublePointInformation(addr,
                                                   DoublePointValue.INTERMEDIATE,
                                                   quality);
                }
                else
                if (kconv1 == -1)
                {
                    sc =
                        new DoublePointInformation(addr,
                                                   value != 0 ? DoublePointValue.OFF : DoublePointValue.ON,
                                                   quality);
                }
                else
                {
                    sc =
                        new DoublePointInformation(addr,
                                                   value != 0 ? DoublePointValue.ON : DoublePointValue.OFF,
                                                   quality);
                }
                break;

            case TypeID.M_DP_TB_1:     // 31
                if (transient)
                {
                    sc =
                        new DoublePointWithCP56Time2a(addr,
                                                      DoublePointValue.INTERMEDIATE,
                                                      quality,
                                                      time_tag);
                }
                else
                if (kconv1 == -1)
                {
                    sc =
                        new DoublePointWithCP56Time2a(addr,
                                                      value != 0 ? DoublePointValue.OFF : DoublePointValue.ON,
                                                      quality,
                                                      time_tag);
                }
                else
                {
                    sc =
                        new DoublePointWithCP56Time2a(addr,
                                                      value != 0 ? DoublePointValue.ON : DoublePointValue.OFF,
                                                      quality,
                                                      time_tag);
                }
                break;

            case TypeID.M_ST_NA_1:     // 5
                value = value * kconv1 + kconv2;
                if (value > 63)
                {
                    value            = 63;
                    quality.Overflow = true;
                }
                else
                if (value < -64)
                {
                    value            = -64;
                    quality.Overflow = true;
                }
                sc = new StepPositionInformation(addr,
                                                 System.Convert.ToInt16(value),
                                                 transient,
                                                 quality);
                break;

            case TypeID.M_ST_TB_1:     // 32
                value = value * kconv1 + kconv2;
                if (value > 63)
                {
                    value            = 63;
                    quality.Overflow = true;
                }
                else
                if (value < -64)
                {
                    value            = -64;
                    quality.Overflow = true;
                }
                sc = new StepPositionWithCP56Time2a(addr,
                                                    System.Convert.ToInt16(value),
                                                    transient,
                                                    quality,
                                                    time_tag);
                break;

            case TypeID.M_ME_NA_1:     // 9
                value = value * kconv1 + kconv2;
                if (value > 32767)
                {
                    value            = 32767;
                    quality.Overflow = true;
                }
                else
                if (value < -32768)
                {
                    value            = -32768;
                    quality.Overflow = true;
                }
                sc = new MeasuredValueNormalized(addr,
                                                 System.Convert.ToInt16(value),
                                                 quality);
                break;

            case TypeID.M_ME_ND_1:     // 21
                value = value * kconv1 + kconv2;
                if (value > 32767)
                {
                    value            = 32767;
                    quality.Overflow = true;
                }
                else
                if (value < -32768)
                {
                    value            = -32768;
                    quality.Overflow = true;
                }
                sc = new MeasuredValueNormalizedWithoutQuality(addr,
                                                               System.Convert.ToInt16(value));
                break;

            case TypeID.M_ME_TD_1:     // 34
                value = value * kconv1 + kconv2;
                if (value > 32767)
                {
                    value            = 32767;
                    quality.Overflow = true;
                }
                else
                if (value < -32768)
                {
                    value            = -32768;
                    quality.Overflow = true;
                }
                sc = new MeasuredValueNormalizedWithCP56Time2a(addr,
                                                               System.Convert.ToInt16(value),
                                                               quality,
                                                               time_tag);
                break;

            case TypeID.M_ME_NB_1:     // 11
                value = value * kconv1 + kconv2;
                if (value > 32767)
                {
                    value            = 32767;
                    quality.Overflow = true;
                }
                else
                if (value < -32768)
                {
                    value            = -32768;
                    quality.Overflow = true;
                }
                sc = new MeasuredValueScaled(addr,
                                             System.Convert.ToInt16(value),
                                             quality);
                break;

            case TypeID.M_ME_TE_1:     // 35
                value = value * kconv1 + kconv2;
                if (value > 32767)
                {
                    value            = 32767;
                    quality.Overflow = true;
                }
                else
                if (value < -32768)
                {
                    value            = -32768;
                    quality.Overflow = true;
                }
                sc = new MeasuredValueScaledWithCP56Time2a(addr,
                                                           System.Convert.ToInt16(value),
                                                           quality,
                                                           time_tag);
                break;

            case TypeID.M_ME_NC_1:     // 13
                value = value * kconv1 + kconv2;
                sc    = new MeasuredValueShort(addr,
                                               System.Convert.ToSingle(value),
                                               quality);
                break;

            case TypeID.M_ME_TF_1:     // 36
                value = value * kconv1 + kconv2;
                sc    = new MeasuredValueShortWithCP56Time2a(addr,
                                                             System.Convert.ToSingle(value),
                                                             quality,
                                                             time_tag);
                break;

            case TypeID.M_IT_NA_1:     //15
                break;

            case TypeID.M_IT_TB_1:     // 37
                break;

            case TypeID.M_PS_NA_1:     // 20
                Log(" TODO Packed single point information with status change detection! ");
                break;

            case TypeID.M_EP_TD_1:     // 38
                break;

            case TypeID.M_EP_TE_1:     // 39
                break;

            case TypeID.M_EP_TF_1:     // 40
                break;

            case TypeID.M_BO_NA_1:     // 7
                uival = System.Convert.ToUInt32(value);
                if (kconv1 == -1)
                {
                    uival = ~uival;
                }
                sc = new Bitstring32(addr, uival, quality);
                break;

            case TypeID.M_BO_TB_1:     // 33
                uival = System.Convert.ToUInt32(value);
                if (kconv1 == -1)
                {
                    uival = ~uival;
                }
                sc = new Bitstring32WithCP56Time2a(addr, uival, quality, time_tag);
                break;

            case TypeID.C_SC_NA_1:     // 45
                bval = value != 0 ? true : false;
                if (kconv1 == -1)
                {
                    bval = !bval;
                }
                sc =
                    new SingleCommand(addr,
                                      bval,
                                      sbo,
                                      cmdqualif);
                break;

            case TypeID.C_DC_NA_1:     // 46
                if (kconv1 == -1)
                {
                    ival = value != 0 ? System.Convert.ToInt32(DoublePointValue.OFF) : System.Convert.ToInt32(DoublePointValue.ON);
                }
                else
                {
                    ival = value != 0 ? System.Convert.ToInt32(DoublePointValue.ON) : System.Convert.ToInt32(DoublePointValue.OFF);
                }
                sc =
                    new DoubleCommand(addr,
                                      ival,
                                      sbo,
                                      cmdqualif);
                break;

            case TypeID.C_RC_NA_1:     // 47
                if (kconv1 == -1)
                {
                    sc =
                        new StepCommand(addr,
                                        value >= 1
                                    ? StepCommandValue.LOWER
                                    : StepCommandValue.HIGHER,
                                        sbo,
                                        cmdqualif);
                }
                else
                {
                    sc =
                        new StepCommand(addr,
                                        value >= 1
                                    ? StepCommandValue.HIGHER
                                    : StepCommandValue.LOWER,
                                        sbo,
                                        cmdqualif);
                }
                break;

            case TypeID.C_SE_NA_1:     // 48
                value = value * kconv1 + kconv2;
                if (value > 32767)
                {
                    value = 32767;
                }
                else
                if (value < -32768)
                {
                    value = -32768;
                }
                sc =
                    new SetpointCommandNormalized(addr,
                                                  System.Convert.ToInt16(value),
                                                  new SetpointCommandQualifier(sbo, 0));
                break;

            case TypeID.C_SE_NB_1:     // 49
                value = value * kconv1 + kconv2;
                if (value > 32767)
                {
                    value = 32767;
                }
                else
                if (value < -32768)
                {
                    value = -32768;
                }
                sc =
                    new SetpointCommandScaled(addr,
                                              new ScaledValue(System.Convert.ToInt16(value)),
                                              new SetpointCommandQualifier(sbo, 0));
                break;

            case TypeID.C_SE_NC_1:     // 50
                value = value * kconv1 + kconv2;
                sc    =
                    new SetpointCommandShort(addr,
                                             System.Convert.ToSingle(value),
                                             new SetpointCommandQualifier(sbo, 0));
                break;

            case TypeID.C_BO_NA_1:     // 51
                uival = System.Convert.ToUInt32(value);
                if (kconv1 == -1)
                {
                    uival = ~uival;
                }
                sc =
                    new Bitstring32Command(addr,
                                           uival);
                break;

            case TypeID.C_SC_TA_1:     //  58
                bval = value != 0 ? true : false;
                if (kconv1 == -1)
                {
                    bval = !bval;
                }
                sc =
                    new SingleCommandWithCP56Time2a(addr,
                                                    bval,
                                                    sbo,
                                                    cmdqualif,
                                                    time_tag);
                break;

            case TypeID.C_DC_TA_1:     // 59
                if (kconv1 == -1)
                {
                    ival = value != 0 ? System.Convert.ToInt32(DoublePointValue.OFF) : System.Convert.ToInt32(DoublePointValue.ON);
                }
                else
                {
                    ival = value != 0 ? System.Convert.ToInt32(DoublePointValue.ON) : System.Convert.ToInt32(DoublePointValue.OFF);
                }
                sc =
                    new DoubleCommandWithCP56Time2a(addr,
                                                    ival,
                                                    sbo,
                                                    cmdqualif,
                                                    time_tag);
                break;

            case TypeID.C_RC_TA_1:     // 60
                if (kconv1 == -1)
                {
                    sc =
                        new StepCommandWithCP56Time2a(addr,
                                                      value >= 1
                                    ? StepCommandValue.LOWER
                                    : StepCommandValue.HIGHER,
                                                      sbo,
                                                      cmdqualif,
                                                      time_tag);
                }
                else
                {
                    sc =
                        new StepCommandWithCP56Time2a(addr,
                                                      value >= 1
                                    ? StepCommandValue.HIGHER
                                    : StepCommandValue.LOWER,
                                                      sbo,
                                                      cmdqualif,
                                                      time_tag);
                }
                break;

            case TypeID.C_SE_TA_1:     // 61
                value = value * kconv1 + kconv2;
                if (value > 32767)
                {
                    value = 32767;
                }
                else
                if (value < -32768)
                {
                    value = -32768;
                }
                sc =
                    new SetpointCommandNormalizedWithCP56Time2a(addr,
                                                                System.Convert.ToInt16(value),
                                                                new SetpointCommandQualifier(sbo, 0),
                                                                time_tag);
                break;

            case TypeID.C_SE_TB_1:     // 62
                value = value * kconv1 + kconv2;
                if (value > 32767)
                {
                    value = 32767;
                }
                else
                if (value < -32768)
                {
                    value = -32768;
                }
                sc =
                    new SetpointCommandScaledWithCP56Time2a(addr,
                                                            new ScaledValue(System.Convert.ToInt16(value)),
                                                            new SetpointCommandQualifier(sbo, 0),
                                                            time_tag);
                break;

            case TypeID.C_SE_TC_1:     // 63
                value = value * kconv1 + kconv2;
                sc    =
                    new SetpointCommandShortWithCP56Time2a(addr,
                                                           System.Convert.ToSingle(value),
                                                           new SetpointCommandQualifier(sbo, 0),
                                                           time_tag);
                break;

            case TypeID.C_BO_TA_1:     // 64
                uival = System.Convert.ToUInt32(value);
                if (kconv1 == -1)
                {
                    uival = ~uival;
                }
                sc =
                    new Bitstring32CommandWithCP56Time2a(addr,
                                                         uival,
                                                         time_tag);
                break;

            case TypeID.C_IC_NA_1:     // 100
                sc =
                    new InterrogationCommand(0,
                                             System.Convert.ToByte(cmdqualif));
                break;

            case TypeID.C_CI_NA_1:     // 101
                sc =
                    new CounterInterrogationCommand(0,
                                                    System.Convert.ToByte(cmdqualif));
                break;

            case TypeID.C_RD_NA_1:     // 102
                sc = new ReadCommand(addr);
                break;

            case TypeID.C_CS_NA_1:     // 103
                sc = new ClockSynchronizationCommand(0, time_tag);
                break;

            case TypeID.C_RP_NA_1:     // 105
                sc =
                    new ResetProcessCommand(addr,
                                            System.Convert.ToByte(cmdqualif));
                break;

            case TypeID.C_TS_TA_1:     // 107
                sc =
                    new TestCommandWithCP56Time2a(System
                                                  .Convert
                                                  .ToUInt16(value),
                                                  time_tag);
                break;

            case TypeID.P_ME_NA_1:     // 110
                value = value * kconv1 + kconv2;
                if (value > 32767)
                {
                    value = 32767;
                }
                else
                if (value < -32768)
                {
                    value = -32768;
                }
                sc =
                    new ParameterNormalizedValue(System
                                                 .Convert
                                                 .ToInt32(addr),
                                                 System.Convert.ToInt32(value),
                                                 System.Convert.ToByte(cmdqualif));
                break;

            case TypeID.P_ME_NB_1:     // 111
                value = value * kconv1 + kconv2;
                if (value > 32767)
                {
                    value = 32767;
                }
                else
                if (value < -32768)
                {
                    value = -32768;
                }
                sc =
                    new ParameterScaledValue(addr,
                                             new ScaledValue(System.Convert.ToInt16(value)),
                                             System.Convert.ToByte(cmdqualif));
                break;

            case TypeID.P_ME_NC_1:     // 112
                value = value * kconv1 + kconv2;
                sc    =
                    new ParameterFloatValue(addr,
                                            System.Convert.ToSingle(value),
                                            System.Convert.ToByte(cmdqualif));
                break;

            case TypeID.P_AC_NA_1:     // 113
                sc =
                    new ParameterActivation(System.Convert.ToInt32(addr),
                                            System.Convert.ToByte(cmdqualif));
                break;

            default:
                break;
            }
            return(sc);
        }
Пример #6
0
        private void HandleASDU(ASDU asdu)
        {
            DebugLog("Handle received ASDU");

            bool messageHandled = false;

            switch (asdu.TypeId)
            {
            case TypeID.C_IC_NA_1:             /* 100 - interrogation command */

                DebugLog("Rcvd interrogation command C_IC_NA_1");

                if ((asdu.Cot == CauseOfTransmission.ACTIVATION) || (asdu.Cot == CauseOfTransmission.DEACTIVATION))
                {
                    if (server.interrogationHandler != null)
                    {
                        InterrogationCommand irc = (InterrogationCommand)asdu.GetElement(0);

                        if (server.interrogationHandler(server.InterrogationHandlerParameter, this, asdu, irc.QOI))
                        {
                            messageHandled = true;
                        }
                    }
                }
                else
                {
                    asdu.Cot = CauseOfTransmission.UNKNOWN_CAUSE_OF_TRANSMISSION;
                    this.SendASDUInternal(asdu);
                }

                break;

            case TypeID.C_CI_NA_1:             /* 101 - counter interrogation command */

                DebugLog("Rcvd counter interrogation command C_CI_NA_1");

                if ((asdu.Cot == CauseOfTransmission.ACTIVATION) || (asdu.Cot == CauseOfTransmission.DEACTIVATION))
                {
                    if (server.counterInterrogationHandler != null)
                    {
                        CounterInterrogationCommand cic = (CounterInterrogationCommand)asdu.GetElement(0);

                        if (server.counterInterrogationHandler(server.counterInterrogationHandlerParameter, this, asdu, cic.QCC))
                        {
                            messageHandled = true;
                        }
                    }
                }
                else
                {
                    asdu.Cot = CauseOfTransmission.UNKNOWN_CAUSE_OF_TRANSMISSION;
                    this.SendASDUInternal(asdu);
                }

                break;

            case TypeID.C_RD_NA_1:             /* 102 - read command */

                DebugLog("Rcvd read command C_RD_NA_1");

                if (asdu.Cot == CauseOfTransmission.REQUEST)
                {
                    DebugLog("Read request for object: " + asdu.Ca);

                    if (server.readHandler != null)
                    {
                        ReadCommand rc = (ReadCommand)asdu.GetElement(0);

                        if (server.readHandler(server.readHandlerParameter, this, asdu, rc.ObjectAddress))
                        {
                            messageHandled = true;
                        }
                    }
                }
                else
                {
                    asdu.Cot = CauseOfTransmission.UNKNOWN_CAUSE_OF_TRANSMISSION;
                    this.SendASDUInternal(asdu);
                }

                break;

            case TypeID.C_CS_NA_1:             /* 103 - Clock synchronization command */

                DebugLog("Rcvd clock sync command C_CS_NA_1");

                if (asdu.Cot == CauseOfTransmission.ACTIVATION)
                {
                    if (server.clockSynchronizationHandler != null)
                    {
                        ClockSynchronizationCommand csc = (ClockSynchronizationCommand)asdu.GetElement(0);

                        if (server.clockSynchronizationHandler(server.clockSynchronizationHandlerParameter,
                                                               this, asdu, csc.NewTime))
                        {
                            messageHandled = true;
                        }
                    }
                }
                else
                {
                    asdu.Cot = CauseOfTransmission.UNKNOWN_CAUSE_OF_TRANSMISSION;
                    this.SendASDUInternal(asdu);
                }

                break;

            case TypeID.C_TS_NA_1:             /* 104 - test command */

                DebugLog("Rcvd test command C_TS_NA_1");

                if (asdu.Cot != CauseOfTransmission.ACTIVATION)
                {
                    asdu.Cot = CauseOfTransmission.UNKNOWN_CAUSE_OF_TRANSMISSION;
                }
                else
                {
                    asdu.Cot = CauseOfTransmission.ACTIVATION_CON;
                }

                this.SendASDUInternal(asdu);

                messageHandled = true;

                break;

            case TypeID.C_RP_NA_1:             /* 105 - Reset process command */

                DebugLog("Rcvd reset process command C_RP_NA_1");

                if (asdu.Cot == CauseOfTransmission.ACTIVATION)
                {
                    if (server.resetProcessHandler != null)
                    {
                        ResetProcessCommand rpc = (ResetProcessCommand)asdu.GetElement(0);

                        if (server.resetProcessHandler(server.resetProcessHandlerParameter,
                                                       this, asdu, rpc.QRP))
                        {
                            messageHandled = true;
                        }
                    }
                }
                else
                {
                    asdu.Cot = CauseOfTransmission.UNKNOWN_CAUSE_OF_TRANSMISSION;
                    this.SendASDUInternal(asdu);
                }


                break;

            case TypeID.C_CD_NA_1:             /* 106 - Delay acquisition command */

                DebugLog("Rcvd delay acquisition command C_CD_NA_1");

                if ((asdu.Cot == CauseOfTransmission.ACTIVATION) || (asdu.Cot == CauseOfTransmission.SPONTANEOUS))
                {
                    if (server.delayAcquisitionHandler != null)
                    {
                        DelayAcquisitionCommand dac = (DelayAcquisitionCommand)asdu.GetElement(0);

                        if (server.delayAcquisitionHandler(server.delayAcquisitionHandlerParameter,
                                                           this, asdu, dac.Delay))
                        {
                            messageHandled = true;
                        }
                    }
                }
                else
                {
                    asdu.Cot = CauseOfTransmission.UNKNOWN_CAUSE_OF_TRANSMISSION;
                    this.SendASDUInternal(asdu);
                }

                break;
            }

            if (messageHandled == false)
            {
                messageHandled = fileServer.HandleFileAsdu(asdu);
            }

            if ((messageHandled == false) && (server.asduHandler != null))
            {
                if (server.asduHandler(server.asduHandlerParameter, this, asdu))
                {
                    messageHandled = true;
                }
            }

            if (messageHandled == false)
            {
                asdu.Cot = CauseOfTransmission.UNKNOWN_TYPE_ID;
                this.SendASDUInternal(asdu);
            }
        }
Пример #7
0
        AsduReceivedHandler(object parameter, IMasterConnection connection, ASDU asdu)
        {
            var srv        = IEC10Xconns[(int)parameter];
            var conNameStr = srv.name + " - ";

            Log(conNameStr + asdu.ToString(), LogLevelDetailed);

            try
            {
                if (IsMongoLive)
                {
                    var DB             = Client.GetDatabase(JSConfig.mongoDatabaseName);
                    var collection_rtd =
                        DB
                        .GetCollection
                        <rtData>(RealtimeDataCollectionName);
                    Double   val        = 0;
                    Int32    objaddr    = 0;
                    Int32    dur        = 0;
                    Boolean  isselect   = false;
                    Boolean  cmdhastime = false;
                    DateTime cmdtime    = new DateTime();

                    Double  dstkconv1 = 1;
                    Double  dstkconv2 = 0;
                    Boolean dstsbo    = false;
                    Int32   dstdur    = 0;

                    Double  srcval      = 0;
                    Int32   srcobjaddr  = 0;
                    Int32   srcconn     = 0;
                    Boolean srcsbo      = false;
                    Int32   srcdur      = 0;
                    Int32   srcasdu     = 0;
                    Int32   srcca       = 0;
                    Int32   srcpointkey = 0;
                    String  srctag      = "";
                    Double  srckconv1   = 1;
                    Double  srckconv2   = 0;

                    switch (asdu.TypeId)
                    {
                    case TypeID.C_SC_NA_1:     // 45
                    {
                        var cmd = (SingleCommand)asdu.GetElement(0);
                        isselect = cmd.Select;
                        dur      = cmd.QU;
                        objaddr  = cmd.ObjectAddress;
                        val      = System.Convert.ToDouble(cmd.State);
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_SC_TA_1:     // 58
                    {
                        var cmd = (SingleCommandWithCP56Time2a)asdu.GetElement(0);
                        isselect   = cmd.Select;
                        dur        = cmd.QU;
                        objaddr    = cmd.ObjectAddress;
                        val        = System.Convert.ToDouble(cmd.State);
                        cmdtime    = cmd.Timestamp.GetDateTime();
                        cmdhastime = true;
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_DC_NA_1:     // 46
                    {
                        var cmd = (DoubleCommand)asdu.GetElement(0);
                        isselect = cmd.Select;
                        dur      = cmd.QU;
                        objaddr  = cmd.ObjectAddress;
                        if (cmd.State != DoubleCommand.ON && cmd.State != DoubleCommand.OFF)
                        {
                            connection.SendACT_CON(asdu, true);         // activation confirm negative
                            Log(conNameStr + "  Invalid double state command " + cmd.State, LogLevelBasic);
                            LastPointKeySelectedOk = 0;
                            return(true);
                        }
                        val = cmd.State == DoubleCommand.ON ? 1 : 0;
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_DC_TA_1:     // 59
                    {
                        var cmd = (DoubleCommandWithCP56Time2a)asdu.GetElement(0);
                        isselect = cmd.Select;
                        dur      = cmd.QU;
                        objaddr  = cmd.ObjectAddress;
                        if (cmd.State != DoubleCommand.ON && cmd.State != DoubleCommand.OFF)
                        {
                            connection.SendACT_CON(asdu, true);         // activation confirm negative
                            Log(conNameStr + "  Invalid double state command " + cmd.State, LogLevelBasic);
                            LastPointKeySelectedOk = 0;
                            return(true);
                        }
                        cmdtime    = cmd.Timestamp.GetDateTime();
                        cmdhastime = true;
                        val        = cmd.State == DoubleCommand.ON ? 1 : 0;
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_RC_NA_1:     // 47
                    {
                        var cmd = (StepCommand)asdu.GetElement(0);
                        isselect = cmd.Select;
                        dur      = cmd.QU;
                        objaddr  = cmd.ObjectAddress;
                        if (cmd.State != StepCommandValue.HIGHER && cmd.State != StepCommandValue.LOWER)
                        {
                            connection.SendACT_CON(asdu, true);         // activation confirm negative
                            Log(conNameStr + "  Invalid step state command " + cmd.State, LogLevelBasic);
                            LastPointKeySelectedOk = 0;
                            return(true);
                        }
                        val = cmd.State == StepCommandValue.HIGHER ? 1 : 0;
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_RC_TA_1:     // 60
                    {
                        var cmd = (StepCommandWithCP56Time2a)asdu.GetElement(0);
                        isselect = cmd.Select;
                        dur      = cmd.QU;
                        objaddr  = cmd.ObjectAddress;
                        if (cmd.State != StepCommandValue.HIGHER && cmd.State != StepCommandValue.LOWER)
                        {
                            connection.SendACT_CON(asdu, true);         // activation confirm negative
                            Log(conNameStr + "  Invalid step state command " + cmd.State, LogLevelBasic);
                            LastPointKeySelectedOk = 0;
                            return(true);
                        }
                        cmdtime    = cmd.Timestamp.GetDateTime();
                        cmdhastime = true;
                        val        = cmd.State == StepCommandValue.HIGHER ? 1 : 0;
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_SE_NA_1:     // 48
                    {
                        var cmd = (SetpointCommandNormalized)asdu.GetElement(0);
                        isselect = cmd.QOS.Select;
                        dur      = cmd.QOS.QL;
                        objaddr  = cmd.ObjectAddress;
                        val      = cmd.NormalizedValue;
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_SE_TA_1:     // 61
                    {
                        var cmd = (SetpointCommandNormalizedWithCP56Time2a)asdu.GetElement(0);
                        isselect   = cmd.QOS.Select;
                        dur        = cmd.QOS.QL;
                        objaddr    = cmd.ObjectAddress;
                        cmdtime    = cmd.Timestamp.GetDateTime();
                        cmdhastime = true;
                        val        = cmd.NormalizedValue;
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_SE_NB_1:     // 49
                    {
                        var cmd = (SetpointCommandScaled)asdu.GetElement(0);
                        isselect = cmd.QOS.Select;
                        dur      = cmd.QOS.QL;
                        objaddr  = cmd.ObjectAddress;
                        val      = System.Convert.ToDouble(cmd.ScaledValue);
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_SE_TB_1:     // 62
                    {
                        var cmd = (SetpointCommandScaledWithCP56Time2a)asdu.GetElement(0);
                        isselect   = cmd.QOS.Select;
                        dur        = cmd.QOS.QL;
                        objaddr    = cmd.ObjectAddress;
                        cmdtime    = cmd.Timestamp.GetDateTime();
                        cmdhastime = true;
                        val        = System.Convert.ToDouble(cmd.ScaledValue);
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_SE_NC_1:     // 50
                    {
                        var cmd = (SetpointCommandShort)asdu.GetElement(0);
                        isselect = cmd.QOS.Select;
                        dur      = cmd.QOS.QL;
                        objaddr  = cmd.ObjectAddress;
                        val      = System.Convert.ToDouble(cmd.Value);
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_SE_TC_1:     // 63
                    {
                        var cmd = (SetpointCommandShortWithCP56Time2a)asdu.GetElement(0);
                        isselect   = cmd.QOS.Select;
                        dur        = cmd.QOS.QL;
                        objaddr    = cmd.ObjectAddress;
                        cmdtime    = cmd.Timestamp.GetDateTime();
                        cmdhastime = true;
                        val        = System.Convert.ToDouble(cmd.Value);
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_BO_NA_1:     // 51
                    {
                        var cmd = (Bitstring32Command)asdu.GetElement(0);
                        isselect = false;
                        dur      = 0;
                        objaddr  = cmd.ObjectAddress;
                        val      = System.Convert.ToDouble(cmd.Value);
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_BO_TA_1:     // 64
                    {
                        var cmd = (Bitstring32CommandWithCP56Time2a)asdu.GetElement(0);
                        isselect   = false;
                        dur        = 0;
                        objaddr    = cmd.ObjectAddress;
                        cmdtime    = cmd.Timestamp.GetDateTime();
                        cmdhastime = true;
                        val        = System.Convert.ToDouble(cmd.Value);
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.P_ME_NA_1:     // 110
                    {
                        var cmd = (ParameterNormalizedValue)asdu.GetElement(0);
                        isselect = false;
                        dur      = cmd.QPM;
                        objaddr  = cmd.ObjectAddress;
                        val      = System.Convert.ToDouble(cmd.NormalizedValue);
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.P_ME_NB_1:     // 111
                    {
                        var cmd = (ParameterScaledValue)asdu.GetElement(0);
                        isselect = false;
                        dur      = cmd.QPM;
                        objaddr  = cmd.ObjectAddress;
                        val      = System.Convert.ToDouble(cmd.ScaledValue);
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.P_ME_NC_1:     // 112
                    {
                        var cmd = (ParameterFloatValue)asdu.GetElement(0);
                        isselect = false;
                        dur      = cmd.QPM;
                        objaddr  = cmd.ObjectAddress;
                        val      = System.Convert.ToDouble(cmd.Value);
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.P_AC_NA_1:     // 113
                    {
                        var cmd = (ParameterActivation)asdu.GetElement(0);
                        isselect = false;
                        dur      = cmd.QPA;
                        objaddr  = cmd.ObjectAddress;
                        val      = 0;
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_RP_NA_1:     // 105 reset process
                    {
                        var cmd = (ResetProcessCommand)asdu.GetElement(0);
                        isselect = false;
                        dur      = cmd.QRP;
                        objaddr  = cmd.ObjectAddress;
                        val      = 0;
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    // case TypeID.C_IC_NA_1: // 100 already managed by interrogation handler function
                    case TypeID.C_TS_NA_1:     // 104 test command
                    {
                        Log(conNameStr + "  Test command C_TS_NA_1", LogLevelDetailed);
                        connection.SendACT_CON(asdu, false);         // activation confirm positive
                    }
                        return(true);

                    case TypeID.C_TS_TA_1:     // 107 test command
                    {
                        Log(conNameStr + "  Test command C_TS_TA_1", LogLevelDetailed);
                        connection.SendACT_CON(asdu, false);         // activation confirm positive
                    }
                        return(true);

                    case TypeID.C_CI_NA_1:     // 101
                    {
                        var cmd = (CounterInterrogationCommand)asdu.GetElement(0);
                        isselect = false;
                        dur      = cmd.QCC;
                        objaddr  = cmd.ObjectAddress;        // should be zero
                        val      = 0;
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_RD_NA_1:     // 102
                    {
                        var cmd = (ReadCommand)asdu.GetElement(0);
                        objaddr = cmd.ObjectAddress;
                        Log(conNameStr + "  " + cmd.ToString() + " Obj Address " + objaddr, LogLevelBasic);
                    }
                    break;

                    case TypeID.C_CS_NA_1:     // 103 clock sync
                    {
                        ClockSynchronizationCommand qsc =
                            (ClockSynchronizationCommand)asdu.GetElement(0);
                        connection.SendACT_CON(asdu, false);         // activation confirm positive
                        Log(conNameStr + "  Received clock sync command with time " +
                            qsc.NewTime.ToString(), LogLevelBasic);
                        LastPointKeySelectedOk = 0;
                        return(true);
                    }

                    default:
                        connection.SendACT_CON(asdu, true);
                        Log(conNameStr + "  Not implemented type of ASDU received: " + asdu.TypeId, LogLevelBasic);
                        LastPointKeySelectedOk = 0;
                        return(true);
                    }

                    var filter1 = Builders <rtData> .Filter.Eq("protocolDestinations.protocolDestinationConnectionNumber", srv.protocolConnectionNumber);

                    var filter2 = Builders <rtData> .Filter.Eq("protocolDestinations.protocolDestinationCommonAddress", asdu.Ca);

                    var filter3 = Builders <rtData> .Filter.Eq("protocolDestinations.protocolDestinationObjectAddress", objaddr);

                    var filter4 = Builders <rtData> .Filter.Eq("protocolDestinations.protocolDestinationASDU", asdu.TypeId);

                    var filter = Builders <rtData>
                                 .Filter
                                 .And(filter1, filter2, filter3, filter4);

                    if (asdu.TypeId == TypeID.C_RD_NA_1)
                    { // READ COMMAND, look for object by object address of any type to send it
                        filter = Builders <rtData>
                                 .Filter
                                 .And(filter1, filter2, filter3);
                    }

                    var list =
                        collection_rtd.Find(filter).ToList();
                    if (list.Count > 0)
                    {
                        Log(conNameStr + "  Command found.", LogLevelBasic);
                        foreach (var dst in list[0].protocolDestinations)
                        {
                            if (dst.protocolDestinationConnectionNumber == srv.protocolConnectionNumber)
                            {
                                dstkconv1 = dst.protocolDestinationKConv1.ToDouble();
                                dstkconv2 = dst.protocolDestinationKConv2.ToDouble();
                                dstsbo    = dst.protocolDestinationCommandUseSBO.ToBoolean();
                                dstdur    = dst.protocolDestinationCommandDuration.ToInt32();

                                if (asdu.TypeId == TypeID.C_RD_NA_1)
                                {                                        // READ REQUEST
                                    connection.SendACT_CON(asdu, false); // activation confirm positive
                                    ApplicationLayerParameters cp =
                                        srv.server.GetApplicationLayerParameters();
                                    var newAsdu = new ASDU(cp,
                                                           CauseOfTransmission.REQUEST,
                                                           false,
                                                           false,
                                                           System.Convert.ToByte(dst.protocolDestinationCommonAddress),
                                                           dst.protocolDestinationCommonAddress.ToInt32(),
                                                           true);
                                    var quality = new QualityDescriptor();
                                    quality.Invalid = list[0].invalid.ToBoolean() ||
                                                      list[0].overflow.ToBoolean() ||
                                                      list[0].transient.ToBoolean();
                                    quality.Substituted = list[0].substituted.ToBoolean();
                                    quality.Blocked     = false;
                                    quality.NonTopical  = false;
                                    InformationObject io = BuildInfoObj(
                                        System.Convert.ToInt32(dst.protocolDestinationASDU),
                                        System.Convert.ToInt32(dst.protocolDestinationObjectAddress),
                                        list[0].value.ToDouble(),
                                        false,
                                        0,
                                        quality
                                        );
                                    if (io != null)
                                    {
                                        newAsdu.AddInformationObject(io);
                                        srv.server.EnqueueASDU(newAsdu);
                                    }
                                    return(true);
                                }

                                if (isselect && !dstsbo)
                                {                                       // tried a select when there is no select
                                    connection.SendACT_CON(asdu, true); // activation confirm negative
                                    Log(conNameStr + "  Select tried but not expected!", LogLevelBasic);
                                    LastPointKeySelectedOk = 0;
                                    return(true);
                                }

                                if (dur != dstdur)
                                {                                       // duration spec different than expected, reject commmand
                                    connection.SendACT_CON(asdu, true); // activation confirm negative
                                    Log(conNameStr + "  QU/QL command qualifier not expected: " + dur + ", " + dstdur + " wanted ", LogLevelBasic);
                                    LastPointKeySelectedOk = 0;
                                    return(true);
                                }

                                srcconn     = list[0].protocolSourceConnectionNumber.ToInt32();
                                srcdur      = list[0].protocolSourceCommandDuration.ToInt32();
                                srcobjaddr  = list[0].protocolSourceObjectAddress.ToInt32();
                                srcasdu     = list[0].protocolSourceASDU.ToInt32();
                                srcca       = list[0].protocolSourceCommonAddress.ToInt32();
                                srckconv1   = list[0].kconv1.ToDouble();
                                srckconv2   = list[0].kconv2.ToDouble();
                                srcpointkey = list[0]._id.ToInt32();
                                srctag      = list[0].tag.ToString();
                                break;
                            }
                        }
                    }
                    else
                    {
                        connection.SendACT_CON(asdu, true); // activation confirm negative
                        if (asdu.TypeId == TypeID.C_RD_NA_1)
                        {
                            Log(conNameStr + "  Request to read object not found, address: " + objaddr, LogLevelBasic);
                        }
                        else
                        {
                            Log(conNameStr + "  Command not found!", LogLevelBasic);
                        }
                        LastPointKeySelectedOk = 0;
                        return(true);
                    }

                    if (srcasdu == 0)
                    {
                        Log(conNameStr + "  Command rejected!", LogLevelBasic);
                        connection.SendACT_CON(asdu, true); // activation confirm negative
                        LastPointKeySelectedOk = 0;
                        return(true);
                    }

                    if (cmdhastime) // check command time
                    {
                        if (DateTime.Now.Subtract(cmdtime).TotalSeconds > timeToExpireCommandsWithTime)
                        { // expired
                            Log(conNameStr + "  Command with time expired after " +
                                timeToExpireCommandsWithTime + "s, diff: " +
                                (DateTime.Now.Subtract(cmdtime).TotalSeconds - timeToExpireCommandsWithTime) + "s",
                                LogLevelBasic);
                            connection.SendACT_CON(asdu, true); // activation confirm negative
                            LastPointKeySelectedOk = 0;
                            return(true);
                        }
                    }

                    connection.SendACT_CON(asdu, false); // activation confirm positive

                    if (isselect)
                    {
                        LastPointKeySelectedOk = srcpointkey; // flag selected point
                        Log(conNameStr + "  Select!", LogLevelBasic);
                        return(true);                         // do not forward a select
                    }

                    if (!isselect && dstsbo && LastPointKeySelectedOk != srcpointkey)
                    {  // tried execute without select first when there is select expected
                        connection.SendACT_CON(asdu, true);
                        Log(conNameStr + "  Tried execute without select first!", LogLevelBasic);
                        LastPointKeySelectedOk = 0;
                        return(true);
                    }
                    LastPointKeySelectedOk = 0;
                    Log(conNameStr + "  Execute (forward to queue)!", LogLevelBasic);

                    switch (asdu.TypeId)
                    {
                    case TypeID.C_SC_NA_1:     // 45
                    case TypeID.C_SC_TA_1:     // 58
                    case TypeID.C_DC_NA_1:     // 46
                    case TypeID.C_DC_TA_1:     // 59
                    case TypeID.C_RC_NA_1:     // 47
                    case TypeID.C_RC_TA_1:     // 60
                        if (dstkconv1 == -1)   // invert digital for kconv1 -1
                        {
                            val = val == 0 ? 1 : 0;
                        }
                        break;

                    case TypeID.C_SE_NA_1:     // 48
                    case TypeID.C_SE_TA_1:     // 61
                    case TypeID.C_SE_NB_1:     // 49
                    case TypeID.C_SE_TB_1:     // 62
                    case TypeID.C_SE_NC_1:     // 50
                    case TypeID.C_SE_TC_1:     // 63
                    case TypeID.P_ME_NA_1:     // 110
                    case TypeID.P_ME_NB_1:     // 111
                    case TypeID.P_ME_NC_1:     // 112
                    case TypeID.P_AC_NA_1:     // 113
                    case TypeID.C_RP_NA_1:     // 105
                        val = val * dstkconv1 + dstkconv2;
                        break;

                    case TypeID.C_BO_NA_1:     // 51
                    case TypeID.C_BO_TA_1:     // 64
                        if (dstkconv1 == -1)   // invert digital bits for kconv1 -1
                        {
                            val = System.Convert.ToInt32(val);
                        }
                        break;

                    default:
                        break;
                    }

                    switch ((TypeID)srcasdu)
                    {
                    case TypeID.C_SC_NA_1:     // 45
                    case TypeID.C_SC_TA_1:     // 58
                    case TypeID.C_DC_NA_1:     // 46
                    case TypeID.C_DC_TA_1:     // 59
                    case TypeID.C_RC_NA_1:     // 47
                    case TypeID.C_RC_TA_1:     // 60
                        if (srckconv1 == -1)   // invert digital for kconv1 -1
                        {
                            srcval = val == 0 ? 1 : 0;
                        }
                        else
                        {
                            srcval = val;
                        }
                        break;

                    case TypeID.C_SE_NA_1:     // 48
                    case TypeID.C_SE_TA_1:     // 61
                    case TypeID.C_SE_NB_1:     // 49
                    case TypeID.C_SE_TB_1:     // 62
                    case TypeID.C_SE_NC_1:     // 50
                    case TypeID.C_SE_TC_1:     // 63
                    case TypeID.P_ME_NA_1:     // 110
                    case TypeID.P_ME_NB_1:     // 111
                    case TypeID.P_ME_NC_1:     // 112
                    case TypeID.P_AC_NA_1:     // 113
                    case TypeID.C_RP_NA_1:     // 105
                        srcval = val * srckconv1 + srckconv2;
                        break;

                    case TypeID.C_BO_NA_1:     // 51
                    case TypeID.C_BO_TA_1:     // 64
                        if (srckconv1 == -1)   // invert digital bits for kconv1 -1
                        {
                            srcval = ~System.Convert.ToInt32(val);
                        }
                        else
                        {
                            srcval = System.Convert.ToInt32(val);
                        }
                        break;

                    default:
                        break;
                    }

                    // not sure how to detect the client connection as can be more than one
                    String orgip = "";
                    foreach (var conn in srv.clientConnections)
                    {
                        orgip = orgip + srv.clientConnections[0].RemoteEndpoint.ToString() + " ";
                    }

                    var collection_cmd =
                        DB
                        .GetCollection
                        <rtCommandNoAck>(CommandsQueueCollectionName);
                    var rtcmd = new rtCommandNoAck
                    {
                        protocolSourceConnectionNumber = srcconn,
                        protocolSourceCommonAddress    = srcca,
                        protocolSourceObjectAddress    = srcobjaddr,
                        protocolSourceASDU             = srcasdu,
                        protocolSourceCommandDuration  = srcdur,
                        protocolSourceCommandUseSBO    = srcsbo,
                        pointKey            = srcpointkey,
                        tag                 = srctag,
                        value               = srcval,
                        valueString         = srcval.ToString(),
                        originatorUserName  = "******" + srv.name,
                        originatorIpAddress = orgip,
                        timeTag             = DateTime.Now
                    };
                    collection_cmd.InsertOne(rtcmd);
                }
            }
            catch (Exception e)
            {
                Log("  Exception Mongo");
                Log(e);
                Log(e
                    .ToString()
                    .Substring(0,
                               e.ToString().IndexOf(Environment.NewLine)));
            }

            return(true);
        }