1ESP-MESH Programming Guide 2========================== 3 4This is a programming guide for ESP-MESH, including the API reference and coding examples. This guide is split into the following parts: 5 61. :ref:`mesh-programming-model` 7 82. :ref:`mesh-writing-mesh-application` 9 103. :ref:`mesh-self-organized-behavior` 11 124. :ref:`mesh-application-examples` 13 145. :ref:`mesh-api-reference` 15 16For documentation regarding the ESP-MESH protocol, please see the :doc:`ESP-MESH API Guide<../../api-guides/mesh>`. For more information about ESP-MESH Development Framework, please see `ESP-MESH Development Framework <https://github.com/espressif/esp-mdf>`_. 17 18 19.. ---------------------- ESP-MESH Programming Model -------------------------- 20 21.. _mesh-programming-model: 22 23ESP-MESH Programming Model 24-------------------------- 25 26Software Stack 27^^^^^^^^^^^^^^ 28 29The ESP-MESH software stack is built atop the Wi-Fi Driver/FreeRTOS and may use the LwIP Stack in some instances (i.e. the root node). The following diagram illustrates the ESP-MESH software stack. 30 31.. _mesh-going-to-software-stack: 32 33.. figure:: ../../../_static/mesh-software-stack.png 34 :align: center 35 :alt: ESP-MESH Software Stack 36 :figclass: align-center 37 38 ESP-MESH Software Stack 39 40.. _mesh-events: 41 42System Events 43^^^^^^^^^^^^^ 44 45An application interfaces with ESP-MESH via **ESP-MESH Events**. Since ESP-MESH is built atop the Wi-Fi stack, it is also possible for the application to interface with the Wi-Fi driver via the **Wi-Fi Event Task**. The following diagram illustrates the interfaces for the various System Events in an ESP-MESH application. 46 47.. figure:: ../../../_static/mesh-events-delivery.png 48 :align: center 49 :alt: ESP-MESH System Events Delivery 50 :figclass: align-center 51 52 ESP-MESH System Events Delivery 53 54The :cpp:type:`mesh_event_id_t` defines all possible ESP-MESH events and can indicate events such as the connection/disconnection of parent/child. Before ESP-MESH events can be used, the application must register a **Mesh Events handler** via :cpp:func:`esp_event_handler_register` to the default event task. The Mesh Events handler that is registered contain handlers for each ESP-MESH event relevant to the application. 55 56Typical use cases of mesh events include using events such as :cpp:enumerator:`MESH_EVENT_PARENT_CONNECTED` and :cpp:enumerator:`MESH_EVENT_CHILD_CONNECTED` to indicate when a node can begin transmitting data upstream and downstream respectively. Likewise, :cpp:enumerator:`IP_EVENT_STA_GOT_IP` and :cpp:enumerator:`IP_EVENT_STA_LOST_IP` can be used to indicate when the root node can and cannot transmit data to the external IP network. 57 58.. warning:: 59 When using ESP-MESH under self-organized mode, users must ensure that no calls to Wi-Fi API are made. This is due to the fact that the self-organizing mode will internally make Wi-Fi API calls to connect/disconnect/scan etc. **Any Wi-Fi calls from the application (including calls from callbacks and handlers of Wi-Fi events) may interfere with ESP-MESH's self-organizing behavior**. Therefore, user's should not call Wi-Fi APIs after :cpp:func:`esp_mesh_start` is called, and before :cpp:func:`esp_mesh_stop` is called. 60 61LwIP & ESP-MESH 62^^^^^^^^^^^^^^^ 63 64The application can access the ESP-MESH stack directly without having to go through the LwIP stack. The LwIP stack is only required by the root node to transmit/receive data to/from an external IP network. However, since every node can potentially become the root node (due to automatic root node selection), each node must still initialize the LwIP stack. 65 66**Each node is required to initialize LwIP by calling** :cpp:func:`tcpip_adapter_init`. In order to prevent non-root node access to LwIP, the application should stop the following services after LwIP initialization: 67 68 - DHCP server service on the softAP interface. 69 - DHCP client service on the station interface. 70 71The following code snippet demonstrates how to initialize LwIP for ESP-MESH applications. 72 73.. code-block:: c 74 75 /* tcpip initialization */ 76 tcpip_adapter_init(); 77 /* 78 * for mesh 79 * stop DHCP server on softAP interface by default 80 * stop DHCP client on station interface by default 81 */ 82 ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP)); 83 ESP_ERROR_CHECK(tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA)); 84 85.. note:: 86 87 ESP-MESH requires a root node to be connected with a router. Therefore, in the event that a node becomes the root, **the corresponding handler must start the DHCP client service and immediately obtain an IP address**. Doing so will allow other nodes to begin transmitting/receiving packets to/from the external IP network. However, this step is unnecessary if static IP settings are used. 88 89 90.. ---------------------- Writing a Mesh Application -------------------------- 91 92.. _mesh-writing-mesh-application: 93 94Writing an ESP-MESH Application 95------------------------------- 96 97The prerequisites for starting ESP-MESH is to initialize LwIP and Wi-Fi, The following code snippet demonstrates the necessary prerequisite steps before ESP-MESH itself can be initialized. 98 99.. code-block:: c 100 101 tcpip_adapter_init(); 102 /* 103 * for mesh 104 * stop DHCP server on softAP interface by default 105 * stop DHCP client on station interface by default 106 */ 107 ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP)); 108 ESP_ERROR_CHECK(tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA)); 109 110 /* event initialization */ 111 ESP_ERROR_CHECK(esp_event_loop_create_default()); 112 113 /* Wi-Fi initialization */ 114 wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); 115 ESP_ERROR_CHECK(esp_wifi_init(&config)); 116 /* register IP events handler */ 117 ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL)); 118 ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_FLASH)); 119 ESP_ERROR_CHECK(esp_wifi_start()); 120 121After initializing LwIP and Wi-Fi, the process of getting an ESP-MESH network up and running can be summarized into the following three steps: 122 1231. :ref:`mesh-initialize-mesh` 1242. :ref:`mesh-configuring-mesh` 1253. :ref:`mesh-start-mesh` 126 127.. _mesh-initialize-mesh: 128 129Initialize Mesh 130^^^^^^^^^^^^^^^ 131 132The following code snippet demonstrates how to initialize ESP-MESH 133 134.. code-block:: c 135 136 /* mesh initialization */ 137 ESP_ERROR_CHECK(esp_mesh_init()); 138 /* register mesh events handler */ 139 ESP_ERROR_CHECK(esp_event_handler_register(MESH_EVENT, ESP_EVENT_ANY_ID, &mesh_event_handler, NULL)); 140 141.. _mesh-configuring-mesh: 142 143Configuring an ESP-MESH Network 144^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 145 146.. todo - Add note about unified configuration 147 148ESP-MESH is configured via :cpp:func:`esp_mesh_set_config` which receives its arguments using the :cpp:type:`mesh_cfg_t` structure. The structure contains the following parameters used to configure ESP-MESH: 149 150+------------------+-------------------------------------+ 151| Parameter | Description | 152+==================+=====================================+ 153| Channel | Range from 1 to 14 | 154+------------------+-------------------------------------+ 155| Mesh ID | ID of ESP-MESH Network, | 156| | see :cpp:type:`mesh_addr_t` | 157+------------------+-------------------------------------+ 158| Router | Router Configuration, | 159| | see :cpp:type:`mesh_router_t` | 160+------------------+-------------------------------------+ 161| Mesh AP | Mesh AP Configuration, | 162| | see :cpp:type:`mesh_ap_cfg_t` | 163+------------------+-------------------------------------+ 164| Crypto Functions | Crypto Functions for Mesh IE, | 165| | see :cpp:type:`mesh_crypto_funcs_t` | 166+------------------+-------------------------------------+ 167 168The following code snippet demonstrates how to configure ESP-MESH. 169 170.. code-block:: c 171 172 /* Enable the Mesh IE encryption by default */ 173 mesh_cfg_t cfg = MESH_INIT_CONFIG_DEFAULT(); 174 /* mesh ID */ 175 memcpy((uint8_t *) &cfg.mesh_id, MESH_ID, 6); 176 /* channel (must match the router's channel) */ 177 cfg.channel = CONFIG_MESH_CHANNEL; 178 /* router */ 179 cfg.router.ssid_len = strlen(CONFIG_MESH_ROUTER_SSID); 180 memcpy((uint8_t *) &cfg.router.ssid, CONFIG_MESH_ROUTER_SSID, cfg.router.ssid_len); 181 memcpy((uint8_t *) &cfg.router.password, CONFIG_MESH_ROUTER_PASSWD, 182 strlen(CONFIG_MESH_ROUTER_PASSWD)); 183 /* mesh softAP */ 184 cfg.mesh_ap.max_connection = CONFIG_MESH_AP_CONNECTIONS; 185 memcpy((uint8_t *) &cfg.mesh_ap.password, CONFIG_MESH_AP_PASSWD, 186 strlen(CONFIG_MESH_AP_PASSWD)); 187 ESP_ERROR_CHECK(esp_mesh_set_config(&cfg)); 188 189.. _mesh-start-mesh: 190 191Start Mesh 192^^^^^^^^^^ 193 194The following code snippet demonstrates how to start ESP-MESH. 195 196.. code-block:: c 197 198 /* mesh start */ 199 ESP_ERROR_CHECK(esp_mesh_start()); 200 201After starting ESP-MESH, the application should check for ESP-MESH events to determine when it has connected to the network. After connecting, the application can start transmitting and receiving packets over the ESP-MESH network using :cpp:func:`esp_mesh_send` and :cpp:func:`esp_mesh_recv`. 202 203 204.. --------------------- ESP-MESH Application Examples ------------------------ 205 206.. _mesh-self-organized-behavior: 207 208Self Organized Networking 209------------------------- 210 211Self organized networking is a feature of ESP-MESH where nodes can autonomously scan/select/connect/reconnect to other nodes and routers. This feature allows an ESP-MESH network to operate with high degree of autonomy by making the network robust to dynamic network topologies and conditions. With self organized networking enabled, nodes in an ESP-MESH network are able to carry out the following actions without autonomously: 212 213- Selection or election of the root node (see **Automatic Root Node Selection** in :ref:`mesh-building-a-network`) 214- Selection of a preferred parent node (see **Parent Node Selection** in :ref:`mesh-building-a-network`) 215- Automatic reconnection upon detecting a disconnection (see **Intermediate Parent Node Failure** in :ref:`mesh-managing-a-network`) 216 217When self organized networking is enabled, the ESP-MESH stack will internally make calls to Wi-Fi APIs. Therefore, **the application layer should not make any calls to Wi-Fi APIs whilst self organized networking is enabled as doing so would risk interfering with ESP-MESH**. 218 219Toggling Self Organized Networking 220^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 221 222Self organized networking can be enabled or disabled by the application at runtime by calling the :cpp:func:`esp_mesh_set_self_organized` function. The function has the two following parameters: 223 224- ``bool enable`` specifies whether to enable or disable self organized networking. 225 226- ``bool select_parent`` specifies whether a new parent node should be selected when enabling self organized networking. Selecting a new parent has different effects depending the node type and the node's current state. This parameter is unused when disabling self organized networking. 227 228Disabling Self Organized Networking 229""""""""""""""""""""""""""""""""""" 230The following code snippet demonstrates how to disable self organized networking. 231 232.. code-block:: c 233 234 //Disable self organized networking 235 esp_mesh_set_self_organized(false, false); 236 237ESP-MESH will attempt to maintain the node's current Wi-Fi state when disabling self organized networking. 238 239- If the node was previously connected to other nodes, it will remain connected. 240- If the node was previously disconnected and was scanning for a parent node or router, it will stop scanning. 241- If the node was previously attempting to reconnect to a parent node or router, it will stop reconnecting. 242 243Enabling Self Organized Networking 244"""""""""""""""""""""""""""""""""" 245 246ESP-MESH will attempt to maintain the node's current Wi-Fi state when enabling self organized networking. However, depending on the node type and whether a new parent is selected, the Wi-Fi state of the node can change. The following table shows effects of enabling self organized networking. 247 248+---------------+--------------+------------------------------------------------------------------------------------------------------------------+ 249| Select Parent | Is Root Node | Effects | 250+===============+==============+==================================================================================================================+ 251| N | N | - Nodes already connected to a parent node will remain connected. | 252| | | - Nodes previously scanning for a parent nodes will stop scanning. Call :cpp:func:`esp_mesh_connect` to restart. | 253| +--------------+------------------------------------------------------------------------------------------------------------------+ 254| | Y | - A root node already connected to router will stay connected. | 255| | | - A root node disconnected from router will need to call :cpp:func:`esp_mesh_connect` to reconnect. | 256+---------------+--------------+------------------------------------------------------------------------------------------------------------------+ 257| Y | N | - Nodes without a parent node will automatically select a preferred parent and connect. | 258| | | - Nodes already connected to a parent node will disconnect, reselect a preferred parent node, and connect. | 259| +--------------+------------------------------------------------------------------------------------------------------------------+ 260| | Y | - For a root node to connect to a parent node, it must give up it's role as root. Therefore, a root node will | 261| | | disconnect from the router and all child nodes, select a preferred parent node, and connect. | 262+---------------+--------------+------------------------------------------------------------------------------------------------------------------+ 263 264The following code snipping demonstrates how to enable self organized networking. 265 266.. code-block:: c 267 268 //Enable self organized networking and select a new parent 269 esp_mesh_set_self_organized(true, true); 270 271 ... 272 273 //Enable self organized networking and manually reconnect 274 esp_mesh_set_self_organized(true, false); 275 esp_mesh_connect(); 276 277 278Calling Wi-Fi API 279^^^^^^^^^^^^^^^^^ 280 281There can be instances in which an application may want to directly call Wi-Fi API whilst using ESP-MESH. For example, an application may want to manually scan for neighboring APs. However, **self organized networking must be disabled before the application calls any Wi-Fi APIs**. This will prevent the ESP-MESH stack from attempting to call any Wi-Fi APIs and potentially interfering with the application's calls. 282 283Therefore, application calls to Wi-Fi APIs should be placed in between calls of :cpp:func:`esp_mesh_set_self_organized` which disable and enable self organized networking. The following code snippet demonstrates how an application can safely call :cpp:func:`esp_wifi_scan_start` whilst using ESP-MESH. 284 285.. code-block:: c 286 287 //Disable self organized networking 288 esp_mesh_set_self_organized(0, 0); 289 290 //Stop any scans already in progress 291 esp_wifi_scan_stop(); 292 //Manually start scan. Will automatically stop when run to completion 293 esp_wifi_scan_start(); 294 295 //Process scan results 296 297 ... 298 299 //Re-enable self organized networking if still connected 300 esp_mesh_set_self_organized(1, 0); 301 302 ... 303 304 //Re-enable self organized networking if non-root and disconnected 305 esp_mesh_set_self_organized(1, 1); 306 307 ... 308 309 //Re-enable self organized networking if root and disconnected 310 esp_mesh_set_self_organized(1, 0); //Don't select new parent 311 esp_mesh_connect(); //Manually reconnect to router 312 313 314.. --------------------- ESP-MESH Application Examples ------------------------ 315 316.. _mesh-application-examples: 317 318Application Examples 319-------------------- 320 321ESP-IDF contains these ESP-MESH example projects: 322 323:example:`The Internal Communication Example<mesh/internal_communication>` demonstrates how to set up a ESP-MESH network and have the root node send a data packet to every node within the network. 324 325:example:`The Manual Networking Example<mesh/manual_networking>` demonstrates how to use ESP-MESH without the self-organizing features. This example shows how to program a node to manually scan for a list of potential parent nodes and select a parent node based on custom criteria. 326 327 328.. ------------------------- ESP-MESH API Reference --------------------------- 329 330.. _mesh-api-reference: 331 332API Reference 333-------------- 334 335.. include-build-file:: inc/esp_mesh.inc 336