ESP8266 Mesh发包流程介绍

原创 2016年09月01日 22:32:24

前言

最近在调试ESP8266的mesh功能,盯了几天的代码和调试信息,终于发现了mesh在使用上十分简单(遗憾的是对它的工作原理一无所知),个人感觉其他的发包程序基本上都是按照这个流程来的,因此决定把这个mesh的json发包函数的流程记录下来,以供日后参考。

程序源码

void ICACHE_FLASH_ATTR mesh_json_bcast_test()
{
    char buf[32];
    uint8_t src[6];
    uint8_t dst[6];
    struct mesh_header_format *header = NULL;
    /** 获取mac地址 */
    if (!wifi_get_macaddr(STATION_IF, src)) 
    {
        MESH_PARSER_PRINT("bcast get sta mac fail\n");
        return;
    }

    os_memset(buf, 0, sizeof(buf));
    os_sprintf(buf, "%s", "{\"bcast\":\"");
    os_sprintf(buf + os_strlen(buf), MACSTR, MAC2STR(src));
    os_sprintf(buf + os_strlen(buf), "%s", "\"}\r\n");

    os_memset(dst, 0, sizeof(dst));  // use bcast to get all the devices working in mesh from root.
    /** 创建一个数据包 */
    header = (struct mesh_header_format *)espconn_mesh_create_packet(
    dst,     // destiny address (bcast)
    src,     // source address
    false,   // not p2p packet
    true,    // piggyback congest request
    M_PROTO_JSON,   // packe with JSON format
    os_strlen(buf), // data length
    false,   // no option
    0,       // option total len
    false,   // no frag
    0,       // frag type, this packet doesn't use frag
    false,   // more frag
    0,       // frag index
    0);      // frag length
    /** 进行数据包地址正确性检查 */
    if (!header) 
    {
        MESH_PARSER_PRINT("bcast create packet fail\n");
        return;
    }
    /** 设置用户数据 */
    if (!espconn_mesh_set_usr_data(header, buf, os_strlen(buf))) 
    {
        MESH_DEMO_PRINT("bcast set user data fail\n");
        MESH_DEMO_FREE(header);
        return;
    }
    /** 发送数据 */
    if (espconn_mesh_sent(&g_ser_conn, (uint8_t *)header, header->len)) 
    {
        MESH_DEMO_PRINT("bcast mesh is busy\n");
        espconn_mesh_connect(&g_ser_conn);
        MESH_DEMO_FREE(header);
        return;
    }

    MESH_DEMO_FREE(header);
}

流程介绍

  1. 首先通过wifi_get_macaddr来获取模块的mac地址。
  2. 配置用户数据包(buf)的内容。
  3. 初始化目标mac地址(MAC地址为零的话视为向网络中所有设备发送数据包)。
  4. 通过调用espconn_mesh_create_packet函数创建一个数据包(由指针header指向这个数据包)。
  5. 通过调用espconn_mesh_set_usr_data函数将用户数据包中的内容添加进将要发送的数据包中。
  6. 通过调用espconn_mesh_sent函数发送数据(数据发送完成后需要用户手动释放这个数据包的内存)。

从上述流程图可以看出json发包首先需要创建并配置数据包,然后设置该数据包的用户数据,最后在通过发包程序发送数据。

相关API介绍

一、wifi_get_macaddr

功能 查询MAC地址 -
函数原型 bool wifi_get_macaddr(uint8 if_index,uint8 *macaddr) -
参数 if_index 获取到的soft-ap当前的配置
参数枚举 STATION_IF 0x00
- SOFTAP_IF 0x01
参数 *macaddr 获取到的mac地址
返回值 true 获取mac地址成功
- false 获取mac地址失败

二、espconn_mesh_create_packet

功能 创建mesh数据包 -
函数原型 void * espconn_mesh_create_packet ( uint8_t* dst_addr, uint8_t* src_addr, bool p2p, bool piggyback_cr, enum mesh_usr_proto_type proto, uint16_t data_len, bool option, uint16_t ot_len, bool frag, enum mesh_option_type frag_type, bool mf, uint16_t frag_idx, uint16_t frag_id ) -
参数 *dst_addr 接收方的mac地址(为零的话表示接收方为网内的所有设备)
参数 *src_addr 发送方的mac地址
参数 p2p 是否为节点到节点的数据包(bool类型)
参数 piggyback_cr piggyback流请求(bool类型)
参数 proto 获取到的soft-ap当前的配置
参数枚举 M_PROTO_NONE 用户数据为网络管理包
- M_PROTO_HTTP 用户数据风格为HTTP风格
- M_PROTO_JSON 用户数据风格为JSON风格
- M_PROTO_MQTT 用户数据风格为MQTT风格
- M_PROTO_BIN 用户数据风格为二进制风格
参数 data_len 用户数据的长度
参数 option 操作选项使能(bool类型)
参数 ot_len 操作选项数据长度
参数 frag fragmentation使能标志(bool类型)
参数 frag_type fragmentation类型
参数枚举 M_O_CONGEST_REQ 堵塞请求
- M_O_CONGEST_RESP 响应堵塞请求
- M_O_ROUTER_SPREAD 路由器信息拓展选项
- M_O_ROUTE_ADD 节点加入选项
- M_O_ROUTE_DEL 节点推出选项
- M_O_TOPO_REQ 拓扑请求选项
- M_O_TOPO_RESP 拓扑响应选项
- M_O_MCAST_GRP 组列表的群播
- M_O_MESH_FRAG mesh管理片段选项
- M_O_USR_FRAG 用户数据片段
- M_O_USR_OPTION 用户选项
参数 mf 更多的fragmentation
参数 frag_idx fragmentation首
参数 frag_id fragmentation id
返回值 void * 返回一个由系统创建的数据包的地址(该地址空间需要用户手动释放)

三、 espconn_mesh_set_usr_data

功能 设置mesh发送包的用户数据 -
函数原型 bool espconn_mesh_set_usr_data ( struct mesh_header_format* head, uint8_t* usr_data, uint16_t data_len ) -
参数 *head 发送包的地址
参数 *usr_data 用户数据缓存区
参数 data_len 数据长度
返回值 true 设置成功
- false 设置失败

四、 espconn_mesh_sent

功能 mesh发送数据包 -
函数原型 int8_t espconn_mesh_sent ( struct espconn* usr_esp, uint8* pdata, uint16 len ) -
参数 *usr_esp 网络连接结构体
参数 *pdata 数据包的地址
参数 len 数据包的长度
返回值 ESPCONN_OK(0) 发送成功
- ESPCONN_MEM(-1) 内存不足
- ESPCONN_MAXNUM(-7) 发送数据缓存区已满
- ESPCONN_ARG(-12) 非法参数
- ESPCONN_IF(-14) 发送UDP数据失败

参考资料

[1]. ESP8266 Mesh 用户手册
[2]. ESP8266 ESP-MESH API 参考
[3]. ESP8266Non-OS SDK API参考

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_15647227/article/details/52403998

发现ESP-NOW之旅——用ESP8266做灯控开关

我是一名从事智能照明的工程师,今年智能照明特别火爆,远超出我的想象。而且有量就压价,客户都不是省油的灯,所以设计也不能大手大脚的,新上手的ESP8266便宜好用,过我手的就有不少项目。我在“2C-ES...
  • eezata
  • eezata
  • 2015年11月12日 17:11
  • 7370

esp8266 mesh程序,亲测可用

  • 2017年09月20日 10:03
  • 3.87MB
  • 下载

ESP8266学习笔记(一)

新建一个新的工程,并使一个LED灯闪烁。
  • qq_15647227
  • qq_15647227
  • 2016年06月06日 10:11
  • 9169

ESP8266 WiFi探针 MAC

WiFi探针原理(转载):            当一个设备给另外一个设备通过无线传输技术发送信息时,周围的其他同类设备都是能够收到这些信息的,WiFi探针技术就是基于这个原理。具体来说,只要...
  • u014377238
  • u014377238
  • 2017年08月02日 11:13
  • 3371

ESP8266学习笔记6:ESP8266规范wifi连接操作

几周前,有网友就问我esp8266重新上电无法自动连接之前配置的路由器。这确实是目前DEMO最缺的一个功能,当首次将设备接入wifi之后,设备应该保存住SSID和PWD,在后续上电时能自己去连接wif...
  • zddxmu
  • zddxmu
  • 2015年08月21日 12:09
  • 17766

[ESP8266]--开启服务器模式和客户端模式

这两天突然心血来潮想搞下ESP8266,正好之前用蓝牙传输数据的方式宣告失败,直接换WIFI,那么问题来了,这玩意怎么开始呢?下面就让我们一步一步的开启Wifi数据传输之旅。Step 1:最小系统启动...
  • wangyijieonline
  • wangyijieonline
  • 2016年11月08日 20:27
  • 12984

WIFI 一键配置原理-ESP8266

1wifi模块可以连接路由器,是不是就能实现远程控制呢? wifi模块可以连接路由器,说明实现路由器的局域网控制没有问题。 2远程控制的过程中,自己家里面搭建服务器可以吗? 远程控制需要服务器,...
  • gizwits_csdn
  • gizwits_csdn
  • 2017年07月26日 12:11
  • 635

ESP32无线模块开发

最近在做一款低功耗设备,SoC选用上海乐鑫科技的一款ESP32 wifi模组。乐鑫官网。 ESP32简介ESP32是集成了2.4GHz WiFi和蓝牙双模块的单芯片方案,专为移动设备、可穿戴设备和...
  • superhcq
  • superhcq
  • 2017年04月19日 13:57
  • 12296

如何辨别ESP8266系列模组

ESP8266 系列 模块如何区别,ESP8266 系列模组是安信可(Ai-thinker)公司采用乐鑫ESP8266芯片开发的一系列wifi 模组模块。...
  • wifimodule
  • wifimodule
  • 2016年04月18日 18:03
  • 1310

mesh和wifi

Mesh的定义 与WiFi的区别 无线Mesh网络(无线网状网络)也称为“多跳(multi-hop)”网络,它是一种与传统无线网络完全不同的新型无线网络技术。无线网状网是一种基于多跳路由、对等网...
  • u011361107
  • u011361107
  • 2013年08月02日 13:55
  • 767
收藏助手
不良信息举报
您举报文章:ESP8266 Mesh发包流程介绍
举报原因:
原因补充:

(最多只允许输入30个字)