示例#1
0
        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));
        }
示例#2
0
        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));
        }