/// <summary> /// 创建选项包 /// </summary> /// <param name="otype">选项类型</param> /// <param name="ovalue">数据</param> /// <param name="val_len">包长</param> /// <returns>返回一个mesh_header_option_format结构</returns> public static mesh_header_option_format?espconn_mesh_create_option(byte otype, byte[] ovalue, byte val_len) { mesh_header_option_format option = new mesh_header_option_format(); if (ovalue.Length != val_len) { return(null); } option.otype = otype; option.olen = (byte)(val_len + 2); option.ovalue = ovalue; return(option); }
/// <summary> /// 向mesh包中添加一个选项包 /// </summary> /// <param name="head">mesh包头</param> /// <param name="option">选项包</param> /// <returns>返回一个添加好option的mesh包</returns> public static mesh_header_format?espconn_mesh_add_option(mesh_header_format head, mesh_header_option_format option) { if (head.option[0].olist == null) { mesh_header_option_format[] options = new mesh_header_option_format[1]; options[0] = option; head.option[0].olist = options; } else { int op_count = head.option[0].olist.Length; /* mesh头中的选项个数 */ mesh_header_option_format[] options = new mesh_header_option_format[op_count + 1]; head.option[0].olist.CopyTo(options, 0); /* 将mesh头中的选项复制出来 */ options[op_count] = option; head.option[0].olist = options; } return(head); }
/// <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); }