ESP32 WiFi Mesh开发(二):ESP WiFi Mesh接口简析

2023-05-16

1 ESP-MDF架构

ESP-MDF是ESP-Mesh Development Framework的缩写,也就是”ESP Mesh开发架构”,其结构如下:

红框部分是WiFi Mesh协议栈,其代码路径是:

\esp-mdf\components\protocol_stacks\mdf_wifi_mesh

 

2 ESP WiFi Mesh协议栈

 

2.1 ESP WiFi Mesh配置

CONFIG_WIFI_MESH_MAX_LAYER                  

ESP WiFi Mesh树状拓扑结构最大层数

 

CONFIG_WIFI_MESH_AP_CONNECTIONS

AP模式支持最大连接数(应该是单个父节点可连接的最大子节点个数)

 

CONFIG_WIFI_MESH_VOTE_PERCENTAGE

投票比例阈值,ESP-MESH选举生成根节点时使用,即Mesh网络所有设备中超过多少比例赞成某节点成为根节点。

 

CONFIG_WIFI_MESH_AP_ASSOC_EXPIRE

softAP模式下连接失效时间,若softAP节点此时间内未收到子节点任何数据,则与子节点断开连接

 

CONFIG_WIFI_MESH_ATTEMPT_SCAN_TIME

ESP WiFi MESH内某节点成为根节点前最低扫描时间

 

CONFIG_WIFI_WIFI_MESH_AUTH_MODE

WiFi MESH认证模式 OPEN/WEP/WAP_PSK……

 

2.2 ESP WiFi Mesh数据结构

 

2.2.1 wifi_mesh_config_t

 

2.2.2 wifi_mesh_data_type_t

 

2.2.3 wifi_mesh_head_data_t

 

wifi_mesh_addr_t实际上的定义是:

初步看来,在ESP WiFi Mesh内的节点,用MAC来识别;如需通过根节点转发到外部IP网络,用IP+PORT模式。

 

2.3 ESP WiFi Mesh API

 

2.3.1 mdf_wifi_mesh_init

函数mdf_wifi_mesh_init(const wifi_mesh_config_t *config)用于初始化ESP WiFi Mesh,主要步骤:

<1> 设置ESP WiFi Mesh(默认)事件回调函数为esp_mesh_event_cb

<2> 设置ESP WiFI Mesh的主要参数,见2.1

这里涉及到一个数据结构:mesh_cfg_t

mdf_wifi_mesh_init参数wifi_mesh_config_t *config内的数据会被填入mesh_config最终通过esp_mesh_set_config设置。

<3> 调用esp_mesh_start启动ESP WiFi Mesh

 

2.3.2 mdf_wifi_mesh_send

2.3.2.1 mdf_wifi_mesh_send

函数mdf_wifi_mesh_send用于向ESP WiFi Mesh内任意节点或者外部IP网络发送数据包,输入参数是目的地址,数据类型,数据地址,数据大小;

发送的数据包会被拆成最大WIFI_MESH_PACKET_MAX_SIZE字节的单个包,并且加入序列号发送,发送最终调用esp_mesh_send执行;esp_mesh_send可以设置重发,并且有响应错误码。

2.3.2.2 esp_mesh_send

重点关注函数esp_mesh_send(const mesh_addr_t *to, const mesh_data_t *data,

int flag, const mesh_opt_t opt[],  int opt_count):

该函数是抽象出的用于ESP Mesh的通用接口。

<1> 该函数用于通过ESP WiFi Mesh发送数据包,可以向WiFi Mesh内任意设备或外部IP网络发送。该函数不可重入

<2> 参数const mesh_addr_t *to:

数据包目的地址(MAC/IP);

若数据包发送给根节点,该参数设置为NULL;

若数据包发送给外部IP网络,该数据包会首先传输给根节点,再由根节点传递到外部网络,此时需将IPv4:PORT写入参数。

<3> 参数const mesh_data_t *data:

发送的ESP Mesh数据包指针;

需指定数据协议,默认是二进制数据

(MESH_PROTO_BIN/MESH_PROTO_HTTP/MESH_PROTO_JSON/MESH_PROTO_MQTT)

需指定传输类型,默认是P2P类型

(MESH_TOS_P2P/MESH_TOS_E2E/MESH_TOS_DEF)

<4> 参数int flag:

MESH_DATA_ENC        /**< data encrypted(Unimplemented) */

MESH_DATA_P2P        /**< point-to-point delivery over the mesh network */

MESH_DATA_FROMDS    /**< receive from external IP network */

MESH_DATA_TODS       /**< identify this packet is target to external IP network */

MESH_DATA_NONBLOCK  /**< esp_mesh_send() non-block */

MESH_DATA_DROP       /**< in the situation of root having been changed, identify this packet can be dropped by new root */

MESH_DATA_GROUP      /**< identify this packet is target to a group address */

若数据包发送给ESP Mesh内部节点,需设置MESH_DATA_P2P;

若数据包发送给外部IP节点,需设置MESH_DATA_TODS;

若数据包由根节点发送给ESP Mesh内部节点,需设置MESH_DATA_FROMDS;

若数据包发送不阻塞,需设置MESH_DATA_NONBLOCK,默认阻塞;

在出现根节点变更时,MESH_DATA_DROP标识位意味着上传到外部IP网络的数据包可以被新的根节点丢弃。虽然尽力避免在根节点变更时的丢包现象,但因(新的根节点)调用esp_mesh_recv_toDS却未能及时读取而挂起过多数据包造成的新节点内存溢出仍然是个风险。总的来说,建议在于IP网络建立连接后再调用esp_mesh_recv_toDS,这样的话通过socket传输到外部网络的数据只来自于esp_mesh_recv_toDS,以避免不必要的内存拷贝动作。

<5> const mesh_opt_t opt[]:

若数据包发送给指定组,MESH_OPT_SEND_GROUP需被设置,且需指定目标接收地址(?);

若根节点发送来自外部IP网络的数据包到ESP Mesh内部设备,且需要该内部设备回复该数据包(到外部IP网络?),标识位MESH_OPT_RECV_DS_ADDR需要添加到目标域名地址。

<6> int opt_count:选项个数,通常情况下若只有1个opt即设置为1。

 

2.3.3 mdf_wifi_mesh_recv

2.3.3.1 mdf_wifi_mesh_recv

         函数mdf_wifi_mesh_recv接收通过ESP WiFi Mesh网络发送到自身的数据包。通过该函数可以获取数据包的源地址,数据包类型,数据包大小等。

         该函数调用esp_mesh_recv实现

 

2.3.4 mdf_wifi_mesh_root_send

         函数mdf_wifi_mesh_root_send用于接收来自外部IP网络的数据包并发送到ESP WiFi Mesh。

         参考:mdf_reconfig_network

 

2.3.5 mdf_wifi_mesh_root_recv

         函数mdf_wifi_mesh_root_recv用于接收来自ESP WiFi Mesh网络内且目的地址是外网的数据包(应该只有根节点使用)。根节点接收到这类数据包后会通过socket通讯传输到外网。

         若接收到此类数据包时根节点还未创建socker连接或者应用程序未调用接口

esp_mesh_recv_toDS发送数据包到外网,这些数据包会挂起到“toDS队列”(?)。

使用接口esp_mesh_get_rx_pending查询挂起的数据包个数以避免根节点内存溢出。

使用接口esp_mesh_set_xon_qsize配置队列的大小。若队列过大且esp_mesh_recv_toDS未及时调用(将数据包发送出列),会有导致大量系统内存溢出的风险;若队列设置过小,则会影响数据上传的效力。应根据实际应用调整接收队列大小,该队列默认大小是72。

 

2.3.6 esp_mesh_event_cb

 ESP WiFi Mesh协议栈的事件回调函数,事件:

<1> MESH_EVENT_PARENT_CONNECTED:连接到父节点

若当前节点为根节点,tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA)

否则tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA)

<2> MESH_EVENT_PARENT_DISCONNECTED:与父节点连接断开

连接断开原因:

WIFI_REASON_HANDSHAKE_TIMEOUT/ WIFI_REASON_MIC_FAILURE/

WIFI_REASON_BEACON_TIMEOUT/ WIFI_REASON_AUTH_LEAVE/ WIFI_REASON_ASSOC_EXPIRE

(以上原因多为密码错误?)若当前节点为根节点,执行mdf_network_enable_blufi。(应该是蓝牙配网)

WIFI_REASON_AUTH_EXPIRE

认证超时且超过最大限定的超时次数,重启设备esp_restart

最后会执行mdf_server_deinit关闭相关网络服务。

<3> MESH_EVENT_ROOT_GOT_IP:获取到路由器分配的IP,启动根节点的相关服务任务mdf_server_init

<4> MESH_EVENT_ROOT_LOST_IP:失去分配的IP,重连esp_wifi_connect

<5> MESH_EVENT_ROUTING_TABLE_ADD/MESH_EVENT_ROUTING_TABLE_REMOVE:路由表变更

 

另外,事件还会被转发到用户自定义的处理函数中处理,大致的处理流程是:

mdf_device_init_handle注册用户自定义的回调函数

mdf_event_loop_init初始化事件处理任务mdf_event_loop_task

mdf_event_loop_task接收xQueueEvent队列的事件,调用回调函数处理

在esp_mesh_event_cb 的最后,通过mdf_event_loop_send将事件发送到mdf_event_loop_task, mdf_event_loop_task调用

用户自定义的事件回调函数执行用户处理。

 

3 ESP WiFi Mesh应用

由于ESP WiFi Mesh只有根节点可以与外部云服务器连接,其他节点必须通过根节点与云服务器交互,因此事实上根节点需要实现物联网关的功能。且由于根节点可能出现breakdown的情形,对于重新选举出的根节点(根节点变更意味着网关变更),仍然要继续维护整个ESP Mesh网络在云端状态的功能。

从mdf_wifi_mesh_send等接口来看,通过填写目的地址为IP:PORT可以让ESP Mesh子网节点数据包转发到外网,手机APP控制就是如此实现的。但若是云平台开发者以库形式提供认证流程(可能拿不到直接IP+PORT,只有收发回调接口)或者节点过多时,是通过根节点维护所有节点信息还是每个节点通过根节点转发自己维护,实现起来就比较复杂了。

相关还需具体项目的实践。目前为了实现demo,个人使用的方法是:

整个ESP WiFi Mesh只有根节点在云端实现认证;

认证完毕云端获取根节点保存的路由表,路由表内有当前Mesh网络所有设备的MAC信息;

云端通过MAC对设备进行控制;手机APP不在本地的情况下,过云端也是依此控制。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ESP32 WiFi Mesh开发(二):ESP WiFi Mesh接口简析 的相关文章

  • 我可以在 Android 中找到我的接入点的 MAC 地址吗?

    我的 Android 应用程序可以找到它所连接的 Wifi 接入点的 MAC 地址吗 android net wifi WifiInfo getMacAddress 的文档未提供任何详细信息 See http developer andro
  • 环境错误:Gmsh 版本必须 >= 2.0

    我是 fipy 的新手 所以如果我问一些应该显而易见的问题 请原谅我的无知 但我无法运行已经存在的 并且在其他机器上工作的 脚本 无法获取EnvironmentError Gmsh version must be gt 2 0 我可能在安装
  • 如何在 .net 中获取可用的 wifi AP 及其信号强度?

    有没有办法使用 NET 访问所有 WiFi 接入点及其各自的 RSSI 值 如果我可以在不使用非托管代码的情况下完成它 那就太好了 或者如果它可以在 Mono 和 NET 中工作 那就更好了 如果可能的话 我将不胜感激代码示例 谢谢 以下是
  • 我可以使用 WiFi 在两部未连接路由器的 Android 手机之间传输数据/消息吗?

    我知道如果两个Android手机连接到同一个wifi网络 它们可以实现套接字编程来在它们之间传输数据 但我其实想知道是否可以使用wifi作为两部Android手机之间的传输介质 就像蓝牙一样 使用 Android 2 2 可以在一台设备上创
  • 如何在 Mobile Safari 中检测 3G 与 Wifi 连接?

    我特别询问的是移动网页上的 javascript 而不是 Objective C 应用程序 是否有像 Apple Reachability for javascript 这样的东西 以便我可以知道 Edge 3G 或 Wifi 连接何时建立
  • Android:在应用程序中间时从 3G 切换到 WIFI = 网络连接丢失

    我在使用 HTC Legend Android 2 2 时遇到了一个恼人的问题 在 Xperia Galaxy Nexus 等上没有看到此问题 当我在 3G 连接上启动应用程序 获取一些数据 然后进入手机设置并启用 WIFI 时 手机会自动
  • Android 智能手机与其他设备之间的直接 Wifi 通信

    我想在 Android 设备和另一个设备 不是另一个 Android 智能手机 而是使用 C 实现的带 wifi 的设备 之间建立通信 通过 WIFI 我已经发现android提供了直接无线网络 http developer android
  • 如何在 Matlab 中计算 3D 网格的投影

    我正在尝试使用 matlab 从不同视图计算 3d 网格的 2d 投影 我现在使用的解决方案是绘制 3D 网格 旋转它并制作屏幕截图 我想知道是否有任何 matlab 内部函数或任何其他解决方案允许我在给定一组顶点和三角形的情况下计算投影而
  • Android wifimanager总是返回true

    这简直要了我的命 任何帮助将不胜感激 我想使用 wifi 管理器连接到开放网络 我遇到的问题是该代码声称连接到任何网络 甚至是不存在的网络 下面是执行并使用网络 SSID 调用的完整代码 无论您传递给它什么字符串作为网络的 SSID 即使不
  • 优先连接Wifi [无互联网]?

    我有个问题 我开发了一个android应用程序 它也应该连接到无线网络 没有互联网 只是为了控制机器人 网页界面 10 10 0 1 我的问题 如果我连接到机器人 wifi Android 会阻止连接并连接到我的默认家庭 WLAN 我可以更
  • p2p0是android中WIFI DIRECT的无线接口吗? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 当我打印 Android 设备中的所有接口时 03 10 19 50 15 484 I System out 22415 lo 03 10
  • THREE.JS 加载 STL 网格数组

    因此 我有一个数据库 其中包含文件引用列以及对其所需的子 STL 文件的任何引用 我可以将一两个模型加载到 THREE js 查看器中 因此所有这些都可以正常工作 但是当我加载四个左右的数组时 事情开始变得毛茸茸的 分配的网格 ID 开始变
  • 如何在没有互联网的情况下通过 wifi 提供网站服务?

    我想通过开放的 wifi 连接提供网站服务 但我不希望此 wifi 连接能够访问互联网 这是否可能以及我将如何去做 我已经在本地设置了网站 并通过本地主机或 IP 地址在浏览器中进行了访问 但我不确定如何设置网络服务器并通过 wifi 为网
  • 用顶点之间的渐变填充 matplotlib 多边形

    我正在使用 matplotlib 的 Poly3DCollection 绘制多边形 三角形 的集合 三角形位于具有与其关联的颜色的顶点之间 我目前正在用通过平均三个顶点的颜色确定的纯色填充每个三角形 绘制三角形以形成 3D 表面网格 I w
  • 检测wifi是否启用(无论是否连接)

    对于 GPS 跟踪应用程序来说 在打开 WIFI 的情况下记录位置信号会导致数据非常不精确或存在间隙 在开始跟踪之前 我已使用可达性查询来检测 wifi 是否可用 问题是 如果进行该查询时 wifi 已启用但未连接到网络 则表明无法通过 w
  • 在 Three.js 中使用多种材质来合并几何体

    我想使用 2 个网格创建一棵松树 其中 1 个用于树干 另一个用于灌木 这就是我所做的 var pine geometry new THREE Geometry var pine texture 1 THREE ImageUtils loa
  • Android wifi的信号强度[重复]

    这个问题在这里已经有答案了 可能的重复 Android 如何监控WiFi信号强度 https stackoverflow com questions 1206891 android how to monitor wifi signal st
  • iOS wifi扫描、信号强度

    据我所知 不可能扫描范围内的热点并读取它们的 bssid 和信号强度 这在 iOS 4 上可以通过使用私有 API 实现 但在不越狱的 iOS 5 上则不再可能 即使可能 该应用程序也会在 App Store 上被拒绝 是对的吗 一家拥有室
  • Android Wifi 通过具有相同 SSID 的 AP 漫游

    我发现 Android 系统在 Wifi 漫游方面表现不佳 我们有一个 Wifi 集中式网络 其中有许多具有单一 SSID 的 AP Adroid 手机无法无缝漫游 即使有其他 AP 具有相同 SSID 信号良好 Android 手机也会尝
  • 更改 Wi-Fi 配置文件的密码

    在我志愿服务的长期护理医院中 每个月的第一天 访客 Wi Fi 连接的密码都会更改 这给工作人员带来了大量的工作 也给患者带来了很多挫败感 其中许多人的行动能力非常有限 是的 真正的解决方案是让 IT 团队保留相同的密码 但这不会发生 大多

随机推荐