CommResponse IProtocolCodec.ServerDecode(CommDataBase data) { var server = (ModbusServer)data.OwnerProtocol; var incoming = data.IncomingData; //validate header first if (incoming.Length < 6) { goto LabelUnknown; } //transaction-id var transId = incoming.ReadUInt16BE(); //protocol-identifier var protId = incoming.ReadInt16BE(); if (protId != 0) { goto LabelIgnore; } //message length var length = incoming.ReadInt16BE(); if (incoming.Length < (length + 6)) { goto LabelUnknown; } //address var address = incoming.ReadByte(); data.Address = server.AddressFromIncommingData ? address : server.Address; if (server.CanHandleIncommingData(address)) { //function code var fncode = incoming.ReadByte(); if (!CommandCodecs.ContainsKey(fncode)) { return(new CommResponse(null, CommResponse.Unknown)); } //create a new command var command = new ModbusCommand(fncode); data.UserData = command; command.TransId = transId; // var body = new ByteArrayReader(incoming.ReadToEnd()); //encode the command body, if applies var codec = CommandCodecs[fncode]; if (codec != null) { codec.ServerDecode(command, body); } return(new CommResponse( data, CommResponse.Ack)); } //exception LabelIgnore: return(new CommResponse( data, CommResponse.Ignore)); LabelUnknown: return(new CommResponse( data, CommResponse.Unknown)); }
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(); data.Address = server.AddressFromIncommingData ? address : server.Address; if (server.CanHandleIncommingData(address)) { //function code var fncode = incoming.ReadByte(); if (CommandCodecs.ContainsKey(fncode)) { //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)); }