コード例 #1
0
        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));
        }
コード例 #2
0
        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));
        }
コード例 #3
0
        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();
        }
コード例 #4
0
        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));
        }
コード例 #5
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();
        }
コード例 #6
0
        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();
        }
コード例 #7
0
        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();
        }
コード例 #8
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();

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