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); } }
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); }
/// <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); }