CommResponse IProtocolCodec.ClientDecode(CommDataBase data) { var client = (ModbusClient)data.OwnerProtocol; var command = (ModbusCommand)data.UserData; var incoming = data.IncomingData; var bodyLen = incoming.Length - 4; //validate address first if (bodyLen >= 0 && incoming.ReadByte() == client.Address) { //extract function code var fncode = incoming.ReadByte(); //extract the message body var body = new ByteArrayReader(incoming.ReadBytes(bodyLen)); //calculate the CRC-16 over the received stream ushort crc = ByteArrayHelpers.CalcCRC16( incoming.ToArray(), 2, incoming.Length - 2); //validate the CRC-16 if (incoming.ReadInt16LE() == (short)crc) { //message looks consistent (although the body can be empty) if ((fncode & 0x7F) == command.FunctionCode) { if (fncode <= 0x7F) { // //encode the command body, if applies var codec = CommandCodecs[fncode]; if (codec != null) { codec.ClientDecode(command, body); } return(new CommResponse( data, CommResponse.Ack)); } else { //exception command.ExceptionCode = incoming.ReadByte(); return(new CommResponse( data, CommResponse.Critical)); } } } } return(new CommResponse( data, CommResponse.Unknown)); }
CommResponse IProtocolCodec.ServerDecode(CommDataBase data) { ModbusServer ownerProtocol = (ModbusServer)data.OwnerProtocol; ByteArrayReader incomingData = data.IncomingData; int length = incomingData.Length; if (length < 4) { return(new CommResponse(data, 0)); } if ((int)incomingData.ReadByte() == (int)ownerProtocol.Address) { byte fc = incomingData.ReadByte(); if ((int)fc < ModbusCodecBase.CommandCodecs.Length) { ModbusCommand command = new ModbusCommand(fc); data.UserData = (object)command; command.QueryTotalLength = 6; ModbusCommandCodec commandCodec = ModbusCodecBase.CommandCodecs[(int)fc]; ByteArrayReader body = new ByteArrayReader(incomingData.ReadBytes(length - 4)); commandCodec.ServerDecode(command, body); ushort num = ByteArrayHelpers.CalcCRC16(incomingData.ToArray(), 0, command.QueryTotalLength - 2); if ((int)ByteArrayHelpers.ReadInt16LE(((IByteArray)incomingData).Data, command.QueryTotalLength - 2) == (int)(short)num) { return(new CommResponse(data, 3)); } } } return(new CommResponse(data, 1)); }
void IProtocolCodec.ServerEncode(CommDataBase data) { ModbusServer ownerProtocol = (ModbusServer)data.OwnerProtocol; ModbusCommand userData = (ModbusCommand)data.UserData; byte functionCode = userData.FunctionCode; ByteArrayWriter byteArrayWriter1 = new ByteArrayWriter(); ModbusCodecBase.CommandCodecs[(int)functionCode]?.ServerEncode(userData, byteArrayWriter1); if (userData.ExceptionCode == (byte)0) { int length = byteArrayWriter1.Length; } ByteArrayWriter byteArrayWriter2 = new ByteArrayWriter(); byteArrayWriter2.WriteByte(ownerProtocol.Address); if (userData.ExceptionCode == (byte)0) { byteArrayWriter2.WriteByte(userData.FunctionCode); byteArrayWriter2.WriteBytes(byteArrayWriter1); } else { byteArrayWriter2.WriteByte((byte)((uint)userData.FunctionCode | 128U)); byteArrayWriter2.WriteByte(userData.ExceptionCode); } ushort num = ByteArrayHelpers.CalcCRC16(byteArrayWriter2.ToArray(), 0, byteArrayWriter2.Length); byteArrayWriter2.WriteInt16LE((short)num); data.OutgoingData = byteArrayWriter2.ToReader(); }
CommResponse IProtocolCodec.ClientDecode(CommDataBase data) { ModbusClient ownerProtocol = (ModbusClient)data.OwnerProtocol; ModbusCommand userData = (ModbusCommand)data.UserData; ByteArrayReader incomingData = data.IncomingData; int count = incomingData.Length - 4; if (count >= 0 && (int)incomingData.ReadByte() == (int)ownerProtocol.Address) { byte num1 = incomingData.ReadByte(); ByteArrayReader body = new ByteArrayReader(incomingData.ReadBytes(count)); ushort num2 = ByteArrayHelpers.CalcCRC16(incomingData.ToArray(), 0, incomingData.Length - 2); if ((int)incomingData.ReadInt16LE() == (int)(short)num2 && ((int)num1 & (int)sbyte.MaxValue) == (int)userData.FunctionCode) { if (num1 <= (byte)127) { ModbusCodecBase.CommandCodecs[(int)num1]?.ClientDecode(userData, body); return(new CommResponse(data, 3)); } if (incomingData.CanRead(1)) { userData.ExceptionCode = incomingData.ReadByte(); } return(new CommResponse(data, 2)); } } return(new CommResponse(data, 0)); }
void IProtocolCodec.ServerEncode(CommDataBase data) { var server = (ModbusServer)data.OwnerProtocol; var command = (ModbusCommand)data.UserData; var fncode = command.FunctionCode; //encode the command body, if applies var body = new ByteArrayWriter(); var codec = CommandCodecs[fncode]; if (codec != null) { codec.ServerEncode(command, body); } //calculate length field var length = (command.ExceptionCode == 0) ? 2 + body.Length : 3; //create a writer for the outgoing data var writer = new ByteArrayWriter(); //unit identifier (address) writer.WriteByte(server.Address); if (command.ExceptionCode == 0) { //function code writer.WriteByte(command.FunctionCode); //body data writer.WriteBytes(body); } else { //function code writer.WriteByte((byte)(command.FunctionCode | 0x80)); //exception code writer.WriteByte(command.ExceptionCode); } //CRC-16 ushort crc = ByteArrayHelpers.CalcCRC16( writer.ToArray(), 0, writer.Length); writer.WriteInt16LE((short)crc); data.OutgoingData = writer.ToReader(); }
void IProtocolCodec.ClientEncode(CommDataBase data) { ModbusClient ownerProtocol = (ModbusClient)data.OwnerProtocol; ModbusCommand userData = (ModbusCommand)data.UserData; byte functionCode = userData.FunctionCode; ByteArrayWriter byteArrayWriter1 = new ByteArrayWriter(); ModbusCodecBase.CommandCodecs[(int)functionCode]?.ClientEncode(userData, byteArrayWriter1); ByteArrayWriter byteArrayWriter2 = new ByteArrayWriter(); byteArrayWriter2.WriteByte(ownerProtocol.Address); byteArrayWriter2.WriteByte(functionCode); byteArrayWriter2.WriteBytes(byteArrayWriter1); ushort num = ByteArrayHelpers.CalcCRC16(byteArrayWriter2.ToArray(), 0, byteArrayWriter2.Length); byteArrayWriter2.WriteInt16LE((short)num); data.OutgoingData = byteArrayWriter2.ToReader(); }
void IProtocolCodec.ClientEncode(CommDataBase data) { var client = (ModbusClient)data.OwnerProtocol; var command = (ModbusCommand)data.UserData; var fncode = command.FunctionCode; //encode the command body, if applies var body = new ByteArrayWriter(); var codec = CommandCodecs[fncode]; if (codec != null) { codec.ClientEncode(command, body); } //create a writer for the outgoing data var writer = new ByteArrayWriter(); //unit identifier (address) writer.WriteByte(client.Address); //function code writer.WriteByte(fncode); //body data writer.WriteBytes(body); //CRC-16 ushort crc = ByteArrayHelpers.CalcCRC16( writer.ToArray(), 0, writer.Length); writer.WriteInt16LE((short)crc); data.OutgoingData = writer.ToReader(); }
CommResponse IProtocolCodec.ServerDecode(CommDataBase data) { var server = (ModbusServer)data.OwnerProtocol; var incoming = data.IncomingData; //validate header first var length = incoming.Length; if (length < 4) { goto LabelUnknown; } //address var address = incoming.ReadByte(); if (address == server.Address) { //function code var fncode = incoming.ReadByte(); if (fncode < CommandCodecs.Length) { //create a new command var command = new ModbusCommand(fncode); data.UserData = command; command.QueryTotalLength = 6; //= addr + fn + offset + crc //get the command codec var codec = CommandCodecs[fncode]; //decode the command, where possible var body = new ByteArrayReader(incoming.ReadBytes(length - 4)); codec.ServerDecode(command, body); //calculate the CRC-16 over the received stream ushort crcCalc = ByteArrayHelpers.CalcCRC16( incoming.ToArray(), 0, command.QueryTotalLength - 2); //validate the CRC-16 var crcRead = ByteArrayHelpers.ReadInt16LE( ((IByteArray)incoming).Data, command.QueryTotalLength - 2); if (crcRead == (short)crcCalc) { return(new CommResponse( data, CommResponse.Ack)); } } } //exception return(new CommResponse( data, CommResponse.Ignore)); LabelUnknown: return(new CommResponse( data, CommResponse.Unknown)); }