]> granicus.if.org Git - esp-idf/commitdiff
mesh: add channel switch function
authorqiyuexia <qiyuexia@espressif.com>
Wed, 21 Nov 2018 16:57:59 +0000 (00:57 +0800)
committerqiyueixa <qiyuexia@espressif.com>
Tue, 27 Nov 2018 15:36:01 +0000 (23:36 +0800)
1. add network channel switch function.
   - users can obtain the new channel through the event MESH_EVENT_CHANNEL_SWITCH.
   - the entire network will be moved to the same channel as the router without user intervention.
   - if no router is in the network, users can call esp_mesh_switch_channel() on the root side to
     move the entire network to their desired channel.
2. support not configuring the network channel.
3. support not configuring the router BSSID even if the router is hidden.
4. add allow_channel_switch to mesh configuration.
   - if the channel is not specified, this value will be ignored.
   - if the channel is specified and this value is set, when "fail" (mesh_attempts_t) times of parent selection
     or look for networks are reached, device will change to perform a full channel scan for networks that could join.
   - if the channel is specified and this value is set to 0, when a root is not elected, channel switch is not allowed.
     but when a root appears, the root performs a full channel scan during the process of connecting to the router,
     so even allow_channel_switch is set to 0, the root may still switch channel and eventually the entire network
    changes channel.
5. add allow_router_switch to mesh router configuration.
   - if the BSSID of router is not specified, this value will be ignored.
   - if the BSSID of router is specified and this value is set, when the router of this specified BSSID fails to be found
     after "fail" (mesh_attempts_t) times, the entire network is allowed to switch to another router with the same SSID.
6. modify the root to perform a full channel scan when esp_wifi_connect().
7. support handling beacon without DS Paramter Set.

components/esp32/include/esp_mesh.h
components/esp32/lib
docs/en/api-guides/mesh.rst
examples/mesh/internal_communication/main/Kconfig.projbuild
examples/mesh/internal_communication/main/mesh_main.c

index 8256e8cbf758faf1252f62cb95712485d704d7bb..62b05d7c0c9cf4e81dda63fedd3ff175bd9ac963 100644 (file)
@@ -187,6 +187,11 @@ typedef enum {
                                              this event, and add the corresponding scan done handler in this event. */
     MESH_EVENT_NETWORK_STATE,           /**< network state, such as whether current mesh network has a root. */
     MESH_EVENT_STOP_RECONNECTION,       /**< the root stops reconnecting to the router and non-root devices stop reconnecting to their parents. */
+    MESH_EVENT_FIND_NETWORK,            /**< when the channel field in mesh configuration is set to zero, mesh stack will perform a
+                                             full channel scan to find a mesh network that can join, and return the channel value
+                                             after finding it. */
+    MESH_EVENT_ROUTER_SWITCH,           /**< if users specify BSSID of the router in mesh configuration, when the root connects to another
+                                             router with the same SSID, this event will be posted and the new router information is attached. */
     MESH_EVENT_MAX,
 } mesh_event_id_t;
 
@@ -310,6 +315,14 @@ typedef struct {
     mesh_addr_t rc_addr;    /**< root address specified by users via API esp_mesh_waive_root() */
 } mesh_event_vote_started_t;
 
+/**
+ * @brief find a mesh network that this device can join
+ */
+typedef struct {
+    uint8_t channel;            /**< channel number of the new found network */
+    uint8_t router_bssid[6];    /**< router BSSID */
+} mesh_event_find_network_t;
+
 /**
  * @brief IP settings from LwIP stack
  */
@@ -381,6 +394,11 @@ typedef struct {
     bool is_rootless;     /**< whether current mesh network has a root */
 } mesh_event_network_state_t;
 
+/**
+ * @brief New router information
+ */
+typedef system_event_sta_connected_t mesh_event_router_switch_t;
+
 /**
  * @brief Mesh event information
  */
@@ -405,6 +423,8 @@ typedef union {
     mesh_event_root_fixed_t root_fixed;                    /**< fixed root */
     mesh_event_scan_done_t scan_done;                      /**< scan done */
     mesh_event_network_state_t network_state;              /**< network state, such as whether current mesh network has a root. */
+    mesh_event_find_network_t find_network;                /**< network found that can join */
+    mesh_event_router_switch_t router_switch;              /**< new router information */
 } mesh_event_info_t;
 
 /**
@@ -445,10 +465,16 @@ typedef struct {
  * @brief Router configuration
  */
 typedef struct {
-    uint8_t ssid[32];        /**< SSID */
-    uint8_t ssid_len;        /**< length of SSID */
-    uint8_t bssid[6];        /**< BSSID, if router is hidden, this value is mandatory */
-    uint8_t password[64];    /**< password */
+    uint8_t ssid[32];             /**< SSID */
+    uint8_t ssid_len;             /**< length of SSID */
+    uint8_t bssid[6];             /**< BSSID, if this value is specified, users should also specify "allow_router_switch". */
+    uint8_t password[64];         /**< password */
+    bool allow_router_switch;     /**< if the BSSID is specified and this value is also set, when the router of this specified BSSID
+                                       fails to be found after "fail" (mesh_attempts_t) times, the whole network is allowed to switch
+                                       to another router with the same SSID. The new router might also be on a different channel.
+                                       The default value is false.
+                                       There is a risk that if the password is different between the new switched router and the previous
+                                       one, the mesh network could be established but the root will never connect to the new switched router. */
 } mesh_router_t;
 
 /**
@@ -464,6 +490,8 @@ typedef struct {
  */
 typedef struct {
     uint8_t channel;                            /**< channel, the mesh network on */
+    bool allow_channel_switch;                  /**< if this value is set, when "fail" (mesh_attempts_t) times is reached, device will change to
+                                                     a full channel scan for a network that could join. The default value is false. */
     mesh_event_cb_t event_cb;                   /**< mesh event callback */
     mesh_addr_t mesh_id;                        /**< mesh network identification */
     mesh_router_t router;                       /**< router configuration */
@@ -1412,6 +1440,23 @@ esp_err_t esp_mesh_disconnect(void);
  */
 esp_err_t esp_mesh_connect(void);
 
+/**
+ * @brief      Cause the root device to add Channel Switch Announcement Element (CSA IE) to beacon
+ *             - Set the new channel
+ *             - Set how many beacons with CSA IE will be sent before changing a new channel
+ *             - Enable the channel switch function
+ *
+ * @attention  This API is only called by the root.
+ *
+ * @param[in]  new_bssid  the new router BSSID if the router changes
+ * @param[in]  csa_newchan  the new channel number to which the whole network is moving
+ * @param[in]  csa_count  channel switch period(beacon count), unit is based on beacon interval of its softAP, the default value is 15.
+ *
+ * @return
+ *    - ESP_OK
+ */
+esp_err_t esp_mesh_switch_channel(const uint8_t *new_bssid, int csa_newchan, int csa_count);
+
 #ifdef __cplusplus
 }
 #endif
index 892a63089b5ab74114a86c2a3202bfa755bfd320..b16383705d7844e125f5063cb642f5964f2d8ff4 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 892a63089b5ab74114a86c2a3202bfa755bfd320
+Subproject commit b16383705d7844e125f5063cb642f5964f2d8ff4
index 87488be1206e011e87de0943ecf5333ae7c090d2..20d35d68b19a89fe264683587027f01037d7a771 100644 (file)
@@ -774,6 +774,37 @@ a shallower parent node. Due to parent node switching, a self-organized ESP-MESH
 network can dynamically adjust its network layout to ensure each connection has a good 
 RSSI and that the number of layers in the network is minimized.
 
+Network Channel Switching
+-------------------------
+
+The list shows network changes allowed by different combinations of four parameters channel, allow_channel_switch,
+router BSSID and allow_router_switch. More information will be added soon.
+
++-------------------------------------------------------------------------+------------------------------+
+|                          Mesh Configuration                             |        Network Changes       |
++===========+======================+================+=====================+==============================+
+|  channel  | allow_channel_switch |  router BSSID  | allow_router_switch |       when no root appears   |
++-----------+----------------------+----------------+---------------------+------------------------------+
+|  not set  |           X          |    not set     |          X          |   channel and router BSSID   |
++-----------+----------------------+----------------+---------------------+------------------------------+
+|  not set  |           X          |      set       |          0          |           channel            |
++-----------+----------------------+----------------+---------------------+------------------------------+
+|  not set  |           X          |      set       |          1          |   channel and router BSSID   |
++-----------+----------------------+----------------+---------------------+------------------------------+
+|    set    |           1          |    not set     |          X          |   channel and router BSSID   |
++-----------+----------------------+----------------+---------------------+------------------------------+
+|    set    |           0          |    not set     |          X          |        router BSSID          |
++-----------+----------------------+----------------+---------------------+------------------------------+
+|    set    |           1          |      set       |          0          |           channel            |
++-----------+----------------------+----------------+---------------------+------------------------------+
+|    set    |           0          |      set       |          0          |                              |
++-----------+----------------------+----------------+---------------------+------------------------------+
+|    set    |           1          |      set       |          1          |   channel and router BSSID   |
++-----------+----------------------+----------------+---------------------+------------------------------+
+|    set    |           0          |      set       |          1          |        router BSSID          |
++-----------+----------------------+----------------+---------------------+------------------------------+
+
+
 .. --------------------------- Data Transmission ------------------------------
 
 .. _mesh-data-transmission:
@@ -1010,4 +1041,4 @@ Further Notes
 - Mesh networking IE uses AES encryption
 
 
-Router and internet icon made by `Smashicons <https://smashicons.com>`_ from `www.flaticon.com <https://smashicons.com>`_
\ No newline at end of file
+Router and internet icon made by `Smashicons <https://smashicons.com>`_ from `www.flaticon.com <https://smashicons.com>`_
index d8de07e5bcbd5184dd52ac7d96b99624b299c572..e7f46ada30c6e44aac7482b7ba5ea0011b493a15 100644 (file)
@@ -2,8 +2,8 @@ menu "Example Configuration"
 
 config MESH_CHANNEL
     int "channel"
-    range 1 14
-    default 1
+    range 0 14
+    default 0
     help
         mesh network channel.
 
index fae5fa27998a17b597129ff06c2ecc2a0ca8b10b..e6ce6255c2bde10d69da7a927ad7acd743e828c4 100644 (file)
@@ -85,7 +85,6 @@ void esp_mesh_p2p_tx_main(void *arg)
             vTaskDelay(10 * 1000 / portTICK_RATE_MS);
             continue;
         }
-
         esp_mesh_get_routing_table((mesh_addr_t *) &route_table,
                                    CONFIG_MESH_ROUTE_TABLE_SIZE * 6, &route_table_size);
         if (send_count && !(send_count % 100)) {
@@ -309,12 +308,27 @@ void mesh_event_handler(mesh_event_t event)
                  event.info.root_conflict.capacity);
         break;
     case MESH_EVENT_CHANNEL_SWITCH:
-        ESP_LOGI(MESH_TAG, "<MESH_EVENT_CHANNEL_SWITCH>");
+        ESP_LOGI(MESH_TAG, "<MESH_EVENT_CHANNEL_SWITCH>new channel:%d", event.info.channel_switch.channel);
         break;
     case MESH_EVENT_SCAN_DONE:
         ESP_LOGI(MESH_TAG, "<MESH_EVENT_SCAN_DONE>number:%d",
                  event.info.scan_done.number);
         break;
+    case MESH_EVENT_NETWORK_STATE:
+        ESP_LOGI(MESH_TAG, "<MESH_EVENT_NETWORK_STATE>is_rootless:%d",
+                 event.info.network_state.is_rootless);
+        break;
+    case MESH_EVENT_STOP_RECONNECTION:
+        ESP_LOGI(MESH_TAG, "<MESH_EVENT_STOP_RECONNECTION>");
+        break;
+    case MESH_EVENT_FIND_NETWORK:
+        ESP_LOGI(MESH_TAG, "<MESH_EVENT_FIND_NETWORK>new channel:%d, router BSSID:"MACSTR"",
+                 event.info.find_network.channel, MAC2STR(event.info.find_network.router_bssid));
+        break;
+    case MESH_EVENT_ROUTER_SWITCH:
+        ESP_LOGI(MESH_TAG, "<MESH_EVENT_ROUTER_SWITCH>new router:%s, channel:%d, "MACSTR"",
+                 event.info.router_switch.ssid, event.info.router_switch.channel, MAC2STR(event.info.router_switch.bssid));
+        break;
     default:
         ESP_LOGI(MESH_TAG, "unknown id:%d", event.id);
         break;