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