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) && (server.asduHandler != null))
            {
                if (server.asduHandler(server.asduHandlerParameter, this, asdu))
                {
                    messageHandled = true;
                }
            }

            if (messageHandled == false)
            {
                asdu.Cot = CauseOfTransmission.UNKNOWN_TYPE_ID;
                this.SendASDUInternal(asdu);
            }
        }
Пример #2
0
        public InformationObject GetElement(int index)
        {
            InformationObject retVal = null;

            int elementSize;

            switch (typeId)
            {
            case TypeID.M_SP_NA_1:             /* 1 */

                elementSize = 1;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new SinglePointInformation(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new SinglePointInformation(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_SP_TA_1:             /* 2 */

                elementSize = 4;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new SinglePointWithCP24Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new SinglePointWithCP24Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_DP_NA_1:             /* 3 */

                elementSize = 1;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new DoublePointInformation(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new DoublePointInformation(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_DP_TA_1:             /* 4 */

                elementSize = 4;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new DoublePointWithCP24Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new DoublePointWithCP24Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_ST_NA_1:             /* 5 */

                elementSize = 2;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new StepPositionInformation(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new StepPositionInformation(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_ST_TA_1:             /* 6 */

                elementSize = 5;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new StepPositionWithCP24Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new StepPositionWithCP24Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_BO_NA_1:             /* 7 */

                elementSize = 5;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new Bitstring32(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new Bitstring32(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_BO_TA_1:             /* 8 */

                elementSize = 8;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new Bitstring32WithCP24Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new Bitstring32WithCP24Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_ME_NA_1:             /* 9 */

                elementSize = 3;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new MeasuredValueNormalized(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new MeasuredValueNormalized(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_ME_TA_1:             /* 10 */

                elementSize = 6;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new MeasuredValueNormalizedWithCP24Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new MeasuredValueNormalizedWithCP24Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_ME_NB_1:             /* 11 */

                elementSize = 3;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new MeasuredValueScaled(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new MeasuredValueScaled(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_ME_TB_1:             /* 12 */

                elementSize = 6;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new MeasuredValueScaledWithCP24Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new MeasuredValueScaledWithCP24Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;


            case TypeID.M_ME_NC_1:             /* 13 */

                elementSize = 5;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new MeasuredValueShort(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new MeasuredValueShort(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_ME_TC_1:             /* 14 */

                elementSize = 8;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new MeasuredValueShortWithCP24Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new MeasuredValueShortWithCP24Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_IT_NA_1:             /* 15 */

                elementSize = 5;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new IntegratedTotals(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new IntegratedTotals(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_IT_TA_1:             /* 16 */

                elementSize = 8;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new IntegratedTotalsWithCP24Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new IntegratedTotalsWithCP24Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_EP_TA_1:             /* 17 */

                elementSize = 3;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new EventOfProtectionEquipment(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new EventOfProtectionEquipment(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_EP_TB_1:             /* 18 */

                elementSize = 7;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new PackedStartEventsOfProtectionEquipment(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new PackedStartEventsOfProtectionEquipment(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_EP_TC_1:             /* 19 */

                elementSize = 7;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new PackedOutputCircuitInfo(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new PackedOutputCircuitInfo(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_PS_NA_1:             /* 20 */

                elementSize = 5;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new PackedSinglePointWithSCD(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new PackedSinglePointWithSCD(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }


                break;

            case TypeID.M_ME_ND_1:             /* 21 */

                elementSize = 2;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new MeasuredValueNormalizedWithoutQuality(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new MeasuredValueNormalizedWithoutQuality(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            /* 22 - 29 reserved */

            case TypeID.M_SP_TB_1:             /* 30 */

                elementSize = 8;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new SinglePointWithCP56Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new SinglePointWithCP56Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_DP_TB_1:             /* 31 */

                elementSize = 8;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new DoublePointWithCP56Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new DoublePointWithCP56Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_ST_TB_1:             /* 32 */

                elementSize = 9;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new StepPositionWithCP56Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new StepPositionWithCP56Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_BO_TB_1:             /* 33 */

                elementSize = 12;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new Bitstring32WithCP56Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new Bitstring32WithCP56Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_ME_TD_1:             /* 34 */

                elementSize = 10;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new MeasuredValueNormalizedWithCP56Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new MeasuredValueNormalizedWithCP56Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_ME_TE_1:             /* 35 */

                elementSize = 10;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new MeasuredValueScaledWithCP56Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new MeasuredValueScaledWithCP56Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_ME_TF_1:             /* 36 */

                elementSize = 12;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new MeasuredValueShortWithCP56Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new MeasuredValueShortWithCP56Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_IT_TB_1:             /* 37 */

                elementSize = 12;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new IntegratedTotalsWithCP56Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new IntegratedTotalsWithCP56Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_EP_TD_1:             /* 38 */

                elementSize = 10;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new EventOfProtectionEquipmentWithCP56Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new EventOfProtectionEquipmentWithCP56Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_EP_TE_1:             /* 39 */

                elementSize = 11;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new PackedStartEventsOfProtectionEquipmentWithCP56Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new PackedStartEventsOfProtectionEquipmentWithCP56Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            case TypeID.M_EP_TF_1:             /* 40 */

                elementSize = 11;

                if (IsSquence)
                {
                    int ioa = InformationObject.ParseInformationObjectAddress(parameters, payload, 0);

                    retVal = new PackedOutputCircuitInfoWithCP56Time2a(parameters, payload, parameters.SizeOfIOA + (index * elementSize), true);

                    retVal.ObjectAddress = ioa + index;
                }
                else
                {
                    retVal = new PackedOutputCircuitInfoWithCP56Time2a(parameters, payload, index * (parameters.SizeOfIOA + elementSize), false);
                }

                break;

            /* 41 - 44 reserved */

            case TypeID.C_SC_NA_1:             /* 45 */

                elementSize = parameters.SizeOfIOA + 1;

                retVal = new SingleCommand(parameters, payload, index * elementSize);

                break;

            case TypeID.C_DC_NA_1:             /* 46 */

                elementSize = parameters.SizeOfIOA + 1;

                retVal = new DoubleCommand(parameters, payload, index * elementSize);

                break;

            case TypeID.C_RC_NA_1:             /* 47 */

                elementSize = parameters.SizeOfIOA + 1;

                retVal = new StepCommand(parameters, payload, index * elementSize);

                break;

            case TypeID.C_SE_NA_1:             /* 48 - Set-point command, normalized value */

                elementSize = parameters.SizeOfIOA + 3;

                retVal = new SetpointCommandNormalized(parameters, payload, index * elementSize);

                break;

            case TypeID.C_SE_NB_1:             /* 49 - Set-point command, scaled value */

                elementSize = parameters.SizeOfIOA + 3;

                retVal = new SetpointCommandScaled(parameters, payload, index * elementSize);

                break;

            case TypeID.C_SE_NC_1:             /* 50 - Set-point command, short floating point number */

                elementSize = parameters.SizeOfIOA + 5;

                retVal = new SetpointCommandShort(parameters, payload, index * elementSize);

                break;

            case TypeID.C_BO_NA_1:             /* 51 - Bitstring command */

                elementSize = parameters.SizeOfIOA + 4;

                retVal = new Bitstring32Command(parameters, payload, index * elementSize);

                break;

            /* 52 - 57 reserved */

            case TypeID.C_SC_TA_1:             /* 58 - Single command with CP56Time2a */

                elementSize = parameters.SizeOfIOA + 8;

                retVal = new SingleCommandWithCP56Time2a(parameters, payload, index * elementSize);

                break;

            case TypeID.C_DC_TA_1:             /* 59 - Double command with CP56Time2a */

                elementSize = parameters.SizeOfIOA + 8;

                retVal = new DoubleCommandWithCP56Time2a(parameters, payload, index * elementSize);

                break;

            case TypeID.C_RC_TA_1:             /* 60 - Step command with CP56Time2a */

                elementSize = parameters.SizeOfIOA + 8;

                retVal = new StepCommandWithCP56Time2a(parameters, payload, index * elementSize);

                break;

            case TypeID.C_SE_TA_1:             /* 61 - Setpoint command, normalized value with CP56Time2a */

                elementSize = parameters.SizeOfIOA + 10;

                retVal = new SetpointCommandNormalizedWithCP56Time2a(parameters, payload, index * elementSize);

                break;

            case TypeID.C_SE_TB_1:             /* 62 - Setpoint command, scaled value with CP56Time2a */

                elementSize = parameters.SizeOfIOA + 10;

                retVal = new SetpointCommandScaledWithCP56Time2a(parameters, payload, index * elementSize);

                break;

            case TypeID.C_SE_TC_1:             /* 63 - Setpoint command, short value with CP56Time2a */

                elementSize = parameters.SizeOfIOA + 12;

                retVal = new SetpointCommandShortWithCP56Time2a(parameters, payload, index * elementSize);

                break;

            case TypeID.C_BO_TA_1:             /* 64 - Bitstring command with CP56Time2a */

                elementSize = parameters.SizeOfIOA + 11;

                retVal = new Bitstring32CommandWithCP56Time2a(parameters, payload, index * elementSize);

                break;

            /* 65 - 69 reserved */

            case TypeID.M_EI_NA_1: /* 70 - End of initialization */
                elementSize = parameters.SizeOfCA + 1;

                retVal = new EndOfInitialization(parameters, payload, index * elementSize);

                break;

            case TypeID.C_IC_NA_1:             /* 100 - Interrogation command */

                elementSize = parameters.SizeOfIOA + 1;

                retVal = new InterrogationCommand(parameters, payload, index * elementSize);

                break;

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

                elementSize = parameters.SizeOfIOA + 1;

                retVal = new CounterInterrogationCommand(parameters, payload, index * elementSize);

                break;

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

                elementSize = parameters.SizeOfIOA;

                retVal = new ReadCommand(parameters, payload, index * elementSize);

                break;

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

                elementSize = parameters.SizeOfIOA + 7;

                retVal = new ClockSynchronizationCommand(parameters, payload, index * elementSize);

                break;

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

                elementSize = parameters.SizeOfIOA + 2;

                retVal = new TestCommand(parameters, payload, index * elementSize);

                break;

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

                elementSize = parameters.SizeOfIOA + 1;

                retVal = new ResetProcessCommand(parameters, payload, index * elementSize);

                break;

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

                elementSize = parameters.SizeOfIOA + 2;

                retVal = new DelayAcquisitionCommand(parameters, payload, index * elementSize);

                break;

            case TypeID.C_TS_TA_1: /* 107 - Test command with CP56Time2a */

                elementSize = parameters.SizeOfIOA + 9;

                retVal = new TestCommandWithCP56Time2a(parameters, payload, index * elementSize);

                break;

            /* C_TS_TA_1 (107) is handled by the stack automatically */

            case TypeID.P_ME_NA_1:             /* 110 - Parameter of measured values, normalized value */

                elementSize = parameters.SizeOfIOA + 3;

                retVal = new ParameterNormalizedValue(parameters, payload, index * elementSize);

                break;

            case TypeID.P_ME_NB_1:             /* 111 - Parameter of measured values, scaled value */

                elementSize = parameters.SizeOfIOA + 3;

                retVal = new ParameterScaledValue(parameters, payload, index * elementSize);

                break;

            case TypeID.P_ME_NC_1:             /* 112 - Parameter of measured values, short floating point number */

                elementSize = parameters.SizeOfIOA + 5;

                retVal = new ParameterFloatValue(parameters, payload, index * elementSize);

                break;

            case TypeID.P_AC_NA_1:             /* 113 - Parameter for activation */

                elementSize = parameters.SizeOfIOA + 1;

                retVal = new ParameterActivation(parameters, payload, index * elementSize);

                break;

            /* 114 - 119 reserved */

            default:
                throw new ASDUParsingException("Unknown ASDU type id:" + typeId);
            }

            return(retVal);
        }
Пример #3
0
        /// <summary>
        /// 处理消息
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="buffer"></param>
        /// <param name="msgSize"></param>
        /// <returns></returns>
        private bool HandleMessage(Socket socket, byte[] buffer, int msgSize)
        {
            if ((buffer[2] & 1) == 0)
            {
                if (debugOutput)
                {
                    Console.WriteLine("Received I frame");
                }

                if (msgSize < 7)
                {
                    if (debugOutput)
                    {
                        Console.WriteLine("I msg too small!");
                    }

                    return(false);
                }


                IncreaseReceivedMessageCounters();

                if (isActive)
                {
                    bool messageHandled = false;

                    ASDU asdu = new ASDU(parameters, buffer, msgSize);

                    //根据类型来分别处理
                    switch (asdu.TypeId)
                    {
                    case TypeID.C_IC_NA_1:     /* 100 - interrogation command  总召*/

                        if (debugOutput)
                        {
                            Console.WriteLine("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.SendASDU(asdu);
                        }

                        break;

                    case TypeID.C_CI_NA_1:     /* 101 - counter interrogation command 累计量总召*/

                        if (debugOutput)
                        {
                            Console.WriteLine("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.SendASDU(asdu);
                        }

                        break;

                    case TypeID.C_RD_NA_1:     /* 102 - read command  读命令*/

                        if (debugOutput)
                        {
                            Console.WriteLine("Rcvd read command C_RD_NA_1");
                        }

                        if (asdu.Cot == CauseOfTransmission.REQUEST)
                        {
                            if (debugOutput)
                            {
                                Console.WriteLine("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.SendASDU(asdu);
                        }

                        break;

                    case TypeID.C_CS_NA_1:     /* 103 - Clock synchronization command 时钟同步 */

                        if (debugOutput)
                        {
                            Console.WriteLine("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.SendASDU(asdu);
                        }

                        break;

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

                        if (debugOutput)
                        {
                            Console.WriteLine("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.SendASDU(asdu);

                        messageHandled = true;

                        break;

                    case TypeID.C_RP_NA_1:     /* 105 - Reset process command  复位命令*/

                        if (debugOutput)
                        {
                            Console.WriteLine("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.SendASDU(asdu);
                        }


                        break;

                    case TypeID.C_CD_NA_1:     /* 106 - Delay acquisition command 延时获得*/

                        if (debugOutput)
                        {
                            Console.WriteLine("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.SendASDU(asdu);
                        }

                        break;
                    }

                    //都没处理,就直接当通用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.SendASDU(asdu);
                    }
                }
                else
                {
                    // connection not activated --> skip message
                    if (debugOutput)
                    {
                        Console.WriteLine("Message not activated. Skip I message");
                    }
                }


                return(true);
            }

            // Check for TESTFR_ACT message
            else if ((buffer[2] & 0x43) == 0x43)
            {
                if (debugOutput)
                {
                    Console.WriteLine("Send TESTFR_CON");
                }

                socket.Send(TESTFR_CON_MSG);
            }

            // Check for STARTDT_ACT message
            else if ((buffer[2] & 0x07) == 0x07)
            {
                if (debugOutput)
                {
                    Console.WriteLine("Send STARTDT_CON");
                }

                this.isActive = true;

                socket.Send(STARTDT_CON_MSG);
            }

            // Check for STOPDT_ACT message
            else if ((buffer[2] & 0x13) == 0x13)
            {
                if (debugOutput)
                {
                    Console.WriteLine("Send STOPDT_CON");
                }

                this.isActive = false;

                socket.Send(STOPDT_CON_MSG);
            }

            // S-message  S帧(用于确认对方的接收序号)
            else if (buffer[2] == 0x01)
            {
                int messageCount = (buffer[4] + buffer[5] * 0x100) / 2;

                Console.WriteLine("Recv S(" + messageCount + ") (own sendcounter = " + sendCount + ")");
            }
            else
            {
                Console.WriteLine("Unknown message");

                return(true);
            }

            return(true);
        }