Pack_Proto.cs 3.68 KB
Newer Older
潘栩锋's avatar
潘栩锋 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FLY.Modbus
{
    public static class COMMON 
    {
        /// <summary>
        /// 把2个byte 转为 uint16
        /// </summary>
        /// <param name="value"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        public static UInt16 ToUInt16_Big_endian(byte[] value, int startIndex) 
        {
            return (UInt16)((value[startIndex] << 8) | value[startIndex+1]);
        }
        /// <summary>
        /// 把 uint16 转为2个byte
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static byte[] GetBytes_Big_endian(this UInt16 value)
        {
            byte[] b = new byte[2];
            b[0] = (byte)(value >> 8);
            b[1] = (byte)value;
            return b;
        }
    }
潘栩锋's avatar
潘栩锋 committed
33 34 35
    /// <summary>
    /// 
    /// </summary>
潘栩锋's avatar
潘栩锋 committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
    public class Pack_Proto
    {
        public UInt16 tranid;
        public byte unitid;
        public byte func;
        public byte[] buf = null;

        //格式——————————————                
        //MBAP
        //域                         长度          描述
        //事务标识符         2byte           MODBUS请求/响应的识别码    
        //协议标识符         2byte           0=MODBUS协议
        //——长度—         2byte           以下字节的数量
        //单元标识符         1byte           串行链路或其它总线过来的识别码


        //PDU
        //功能码——         1byte
        //数据                    nbyte

        public byte[] ToBytes()
        {
            List<byte> buf = new List<byte>();
            buf.AddRange(tranid.GetBytes_Big_endian());
            buf.AddRange(((UInt16)0).GetBytes_Big_endian());
            UInt16 len = (UInt16)(1 + 1 + this.buf.Count());
            buf.AddRange(len.GetBytes_Big_endian());
            buf.Add(unitid);
            buf.Add(func);
            if (this.buf != null)
                buf.AddRange(this.buf);

            return buf.ToArray();
        }

潘栩锋's avatar
潘栩锋 committed
71
        public bool TryParse(byte[] value, int startIndex, int value_len, out int rlen)
潘栩锋's avatar
潘栩锋 committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
        {
            //格式——————————————                
            //MBAP
            //域                         长度          描述
            //事务标识符         2byte           MODBUS请求/响应的识别码    
            //协议标识符         2byte           0=MODBUS协议
            //——长度—         2byte           以下字节的数量
            //单元标识符         1byte           串行链路或其它总线过来的识别码


            //PDU
            //功能码——         1byte
            //数据                    nbyte

            rlen = 0;
            int cnt = 7 + 1;
潘栩锋's avatar
潘栩锋 committed
88
            if (value_len < cnt)
潘栩锋's avatar
潘栩锋 committed
89 90 91 92 93 94 95 96 97 98 99
                return false;
            int index = startIndex;
            tranid = COMMON.ToUInt16_Big_endian(value, index);
            index += 2;
            UInt16 protoid = COMMON.ToUInt16_Big_endian(value, index);
            index += 2;
            
            int len = COMMON.ToUInt16_Big_endian(value, index);
            index += 2;
            
            cnt += len - 2;
潘栩锋's avatar
潘栩锋 committed
100
            if (value_len < cnt)
潘栩锋's avatar
潘栩锋 committed
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
                return false;

            unitid = value[index];
            index++;

            func = value[index];
            index++;

            len -= 2;
            if (len > 0)
            {
                buf = new byte[len];
                Array.Copy(value, index, buf, 0, len);
            }
            rlen = cnt;

            return true;
        }
    }
}