Esempio n. 1
0
        /// <summary>
        /// 创建mesh包
        /// </summary>
        /// <param name="dst_addr">destination address (6 Bytes)</param>
        /// <param name="src_addr">source address (6 Bytes)</param>
        /// <param name="p2p">node-to-node packet</param>
        /// <param name="piggyback_cr">piggyback flow request</param>
        /// <param name="proto">protocol used by user data</param>
        /// <param name="data_len">length of user data</param>
        /// <param name="option">option flag</param>
        /// <param name="ot_len">option total length</param>
        /// <param name="frag">fragmentation flag</param>
        /// <param name="frag_type">fragmentation type</param>
        /// <param name="mf">fragmentation</param>
        /// <param name="frag_idx">fragmentation index</param>
        /// <param name="frag_id">fragmentation id</param>
        /// <returns>NULL: create mesh packet fail. mesh_header_format: mesh packet.</returns>
        public static mesh_header_format?espconn_mesh_create_packet(byte[] dst_addr, byte[] src_addr, bool p2p,
                                                                    bool piggyback_cr, mesh_usr_proto_type proto,
                                                                    UInt16 data_len, bool option, UInt16 ot_len,
                                                                    bool frag, mesh_option_type frag_type,
                                                                    bool mf, UInt16 frag_idx, UInt16 frag_id)
        {
            mesh_header_format header = new mesh_header_format();

            mesh_header_option_header_type[] option_header = new mesh_header_option_header_type[option ? 1 : 0];

            if (dst_addr.Length < 6)
            {
                return(null);
            }
            if (src_addr.Length < 6)
            {
                return(null);
            }
            if (src_addr.Length < 6)
            {
                return(null);
            }
            if ((byte)proto > (byte)mesh_usr_proto_type.M_PROTO_BIN)
            {
                return(null);
            }
            if ((byte)frag_type > (byte)mesh_option_type.M_O_USR_OPTION)
            {
                return(null);
            }
            if ((MESH_HEADER_SIZE + ot_len + data_len) > 1300)
            {
                return(null);
            }

            header.ver            = (byte)MESH_VER;                                 /* mesh版本 */
            header.oe             = (byte)(option ? 1 : 0);                         /* 选项标志 */
            header.cp             = 0;                                              /* 数据包捎带流量应答 */
            header.cr             = (byte)(piggyback_cr ? 1 : 0);                   /* 数据包捎带流量请求 */
            header.rsv            = 0;                                              /* 保留字段 */
            header.proto.d        = 0;                                              /* 数据包流向 1:向上, 0:向下 */
            header.proto.p2p      = (byte)(p2p ? 1 : 0);                            /* 节点到节点的数据包 */
            header.proto.protocol = (byte)proto;                                    /* 用户数据格式 */
            header.len            = (UInt16)(MESH_HEADER_SIZE + data_len + ot_len); /* mesh的数据包长度(包含mesh头信息) */
            header.dst_addr       = dst_addr;                                       /* 目的地址 */
            header.src_addr       = src_addr;                                       /* 源地址 */
            if (option)
            {
                header.option           = option_header; /* 选项头 */
                header.option[0].ot_len = ot_len;        /* 选项总长度 */
            }

            return(header);
        }
Esempio n. 2
0
        /// <summary>
        /// 解析mesh包
        /// </summary>
        /// <param name="data">mesh包数组</param>
        /// <returns>返回一个mesh_header_format结构</returns>
        public static mesh_header_format?espconn_mesh_analysis_packet(byte[] data)
        {
            mesh_header_format header = new mesh_header_format();

            mesh_header_option_header_type[] option_header;
            mesh_header_option_format[]      options;
            byte[] dst_addr = { data[4], data[5], data[6], data[7], data[8], data[9] };
            byte[] src_addr = { data[10], data[11], data[12], data[13], data[14], data[15] };
            UInt16 len      = (UInt16)(data[2] + (data[3] << 8));        /* 整包长度 */
            UInt16 ot_len   = 0;                                         /* 选项长度 */
            byte   op_count = 0;                                         /* 选项个数 */
            int    index    = 0;                                         /* 数组索引 */

            if (data.Length < 16)
            {
                return(null);
            }
            if (data.Length > 1284)
            {
                return(null);
            }
            if (data.Length != len)
            {
                return(null);
            }                                                            /* 安全检查 */
            header.ver            = (byte)((data[index] & 0x03) >> 0);   /* mesh版本 */
            header.oe             = (byte)((data[index] & 0x04) >> 2);   /* 选项标志 */
            header.cp             = (byte)((data[index] & 0x08) >> 3);   /* 数据包捎带流量应答 */
            header.cr             = (byte)((data[index] & 0x10) >> 4);   /* 数据包捎带流量请求 */
            header.rsv            = (byte)((data[index++] & 0xE0) >> 5); /* 保留字段 */
            header.proto.d        = (byte)((data[index] & 0x01) >> 0);   /* 数据包流向 1:向上, 0:向下 */
            header.proto.p2p      = (byte)((data[index] & 0x02) >> 1);   /* 节点到节点的数据包 */
            header.proto.protocol = (byte)((data[index++] & 0xFC) >> 2); /* 数据协议 */
            header.len            = len;                                 /* mesh的数据包长度(包含mesh头信息) */
            header.dst_addr       = dst_addr;                            /* 目的地址 */
            header.src_addr       = src_addr;                            /* 源地址 */
            if (header.oe == 1)
            {
                ot_len = (UInt16)(data[MESH_HEADER_SIZE] + (data[MESH_HEADER_SIZE + 1] << 8)); /* 选项字节数 */
                index  = MESH_HEADER_SIZE + 2 /* ot_len */ + 1 /* otype */;
                while (true)                                                                   /* 计算选项个数 */
                {
                    byte olen = data[index];
                    index += olen;
                    op_count++;
                    if (index >= MESH_HEADER_SIZE + ot_len - 1)
                    {
                        break;
                    }
                }
                option_header = new mesh_header_option_header_type[1];
                options       = new mesh_header_option_format[op_count];
                index         = MESH_HEADER_SIZE + 2 /* ot_len */;
                for (int i = 0; i < op_count; i++)
                {
                    byte   otype  = data[index++];
                    byte   olen   = data[index++];
                    byte[] ovalue = new byte[olen - 2];
                    for (int j = 0; j < olen - 2; j++)
                    {
                        ovalue[j] = data[index++];
                    }
                    options[i].otype  = otype;
                    options[i].olen   = olen;
                    options[i].ovalue = ovalue;
                }
                option_header[0].ot_len = ot_len;
                option_header[0].olist  = options;
                header.option           = option_header;
            }

            UInt16 data_len = (UInt16)(len - MESH_HEADER_SIZE - ot_len); /* 用户数据长度 */

            if (data_len > 0)
            {
                byte[] user_data = new byte[data_len];
                for (int i = 0; i < data_len; i++)
                {
                    user_data[i] = data[i + MESH_HEADER_SIZE + ot_len];
                }
                header.user_data = user_data;
            }

            return(header);
        }