mesh: bugfix

1. suppport mesh type, mesh ID, router and IE crypt func&key at any time after mesh is initalized.
2. support modify parent at any time after mesh is configured.
3. modify manual networking example.
4. update header file.
5. fix issues in root conflicts handling.
6. add max length of beacon to menuconfig.
7. fix issue when received a beacon without DSSS.
This commit is contained in:
qiyueixa 2018-09-23 21:09:59 +08:00
parent 623641f26c
commit 9c4cc55012
7 changed files with 142 additions and 101 deletions

View file

@ -1059,6 +1059,25 @@ config ESP32_WIFI_TASK_PINNED_TO_CORE_1
bool "Core 1"
endchoice
config ESP32_WIFI_SOFTAP_BEACON_MAX_LEN
int "Max length of WiFi SoftAP Beacon"
range 752 1256
default 752
help
ESP-MESH utilizes beacon frames to detect and resolve root node conflicts (see documentation). However the default
length of a beacon frame can simultaneously hold only five root node identifier structures, meaning that a root node
conflict of up to five nodes can be detected at one time. In the occurence of more root nodes conflict involving more
than five root nodes, the conflict resolution process will detect five of the root nodes, resolve the conflict, and
re-detect more root nodes. This process will repeat until all root node conflicts are resolved. However this process
can generally take a very long time.
To counter this situation, the beacon frame length can be increased such that more root nodes can be detected simultaneously.
Each additional root node will require 36 bytes and should be added ontop of the default beacon frame length of
752 bytes. For example, if you want to detect 10 root nodes simultaneously, you need to set the beacon frame length as
932 (752+36*5).
Setting a longer beacon length also assists with debugging as the conflicting root nodes can be identified more quickly.
endmenu # Wi-Fi
menu PHY

View file

@ -541,7 +541,7 @@ esp_err_t esp_mesh_deinit(void);
* - Create TX and RX queues according to the configuration.
* - Register mesh packets receive callback.
*
* @attention This API shall be called after esp_mesh_init() and esp_mesh_set_config().
* @attention  This API shall be called after mesh initialization and configuration.
*
* @return
* - ESP_OK
@ -711,10 +711,10 @@ esp_err_t esp_mesh_recv_toDS(mesh_addr_t *from, mesh_addr_t *to,
* Root conflict function could eliminate redundant roots connected with the same BSSID, but couldn't handle roots
* connected with different BSSID. Because users might have such requirements of setting up routers with same SSID
* for the future replacement. But in that case, if the above situations happen, please make sure applications
* implement forward functions on the root to guarantee devices in different mesh network can communicate with each other.
* implement forward functions on the root to guarantee devices in different mesh networks can communicate with each other.
* max_connection of mesh softAP is limited by the max number of Wi-Fi softAP supported (max:10).
*
* @attention This API shall be called between esp_mesh_init() and esp_mesh_start().
* @attention This API shall be called before mesh is started after mesh is initialized.
*
* @param[in] config pointer to mesh stack configuration
*
@ -739,7 +739,7 @@ esp_err_t esp_mesh_get_config(mesh_cfg_t *config);
/**
* @brief Get router configuration
*
* @attention This API shall be called between esp_mesh_init() and esp_mesh_start().
* @attention This API is used to dynamically modify the router configuration after mesh is configured.
*
* @param[in] router pointer to router configuration
*
@ -763,7 +763,7 @@ esp_err_t esp_mesh_get_router(mesh_router_t *router);
/**
* @brief Set mesh network ID
*
* @attention This API could be called either before esp_mesh_start() or after esp_mesh_start().
* @attention This API is used to dynamically modify the mesh network ID.
*
* @param[in] id pointer to mesh network ID
*
@ -786,6 +786,8 @@ esp_err_t esp_mesh_get_id(mesh_addr_t *id);
/**
* @brief Designate device type over the mesh network
* - MESH_ROOT: designates the root node for a mesh network
* - MESH_LEAF: designates a device as a standalone Wi-Fi station
*
* @param[in] type device type
*
@ -806,10 +808,10 @@ esp_err_t esp_mesh_set_type(mesh_type_t type);
mesh_type_t esp_mesh_get_type(void);
/**
* @brief Set network max layer value (max:25, default:15)
* @brief Set network max layer value (max:25, default:25)
* - Network max layer limits the max hop count.
*
* @attention This API shall be called before esp_mesh_start().
* @attention This API shall be called before mesh is started.
*
* @param[in] max_layer max layer value
*
@ -830,7 +832,7 @@ int esp_mesh_get_max_layer(void);
/**
* @brief Set mesh softAP password
*
* @attention This API shall be called before esp_mesh_start().
* @attention This API shall be called before mesh is started.
*
* @param[in] pwd pointer to the password
* @param[in] len password length
@ -845,7 +847,7 @@ esp_err_t esp_mesh_set_ap_password(const uint8_t *pwd, int len);
/**
* @brief Set mesh softAP authentication mode
*
* @attention This API shall be called before esp_mesh_start().
* @attention This API shall be called before mesh is started.
*
* @param[in] authmode authentication mode
*
@ -866,7 +868,7 @@ wifi_auth_mode_t esp_mesh_get_ap_authmode(void);
/**
* @brief Set mesh softAP max connection value
*
* @attention This API shall be called before esp_mesh_start().
* @attention This API shall be called before mesh is started.
*
* @param[in] connections the number of max connections
*
@ -914,11 +916,15 @@ esp_err_t esp_mesh_get_parent_bssid(mesh_addr_t *bssid);
bool esp_mesh_is_root(void);
/**
* @brief Enable/disable mesh networking self-organized, self-organized by default
* - If self-organized is disabled, users shall set a parent for the device via
* esp_mesh_set_parent();
* @brief Enable/disable self-organized networking
* - Self-organized networking has three main functions:
* select the root node;
* find a preferred parent;
* initiate reconnection if a disconnection is detected.
* - Self-organized networking is enabled by default.
* - If self-organized is disabled, users should set a parent for the device via esp_mesh_set_parent().
*
* @attention This API could be called either before esp_mesh_start() or after esp_mesh_start().
* @attention This API is used to dynamically modify whether to enable the self organizing.
*
* @param[in] enable enable or disable self-organized networking
* @param[in] select_parent
@ -976,7 +982,7 @@ esp_err_t esp_mesh_waive_root(const mesh_vote_t *vote, int reason);
* - During the networking, only obtaining vote percentage reaches this threshold,
* the device could be a root.
*
* @attention This API shall be called before esp_mesh_start().
* @attention This API shall be called before mesh is started.
*
* @param[in] percentage vote percentage threshold
*
@ -1090,7 +1096,7 @@ int esp_mesh_available_txupQ_num(const mesh_addr_t *addr, uint32_t *xseqno_in);
/**
* @brief Set the number of queue
*
* @attention This API shall be called before esp_mesh_start().
* @attention This API shall be called before mesh is started.
*
* @param[in] qsize default:32 (min:16)
*
@ -1179,7 +1185,7 @@ bool esp_mesh_is_my_group(const mesh_addr_t *addr);
/**
* @brief Set mesh network capacity
*
* @attention This API shall be called before esp_mesh_start().
* @attention This API shall be called before mesh is started.
*
* @param[in] num mesh network capacity
*
@ -1191,17 +1197,19 @@ bool esp_mesh_is_my_group(const mesh_addr_t *addr);
esp_err_t esp_mesh_set_capacity_num(int num);
/**
* @brief Get mesh network capacity
* @brief Get mesh network capacity
*
* @return mesh network capacity
* @return mesh network capacity
*/
int esp_mesh_get_capacity_num(void);
/**
* @brief Set mesh IE crypto functions
* @brief Set mesh IE crypto functions
*
* @param[in] crypto_funcs crypto functions for mesh IE
* @attention This API can be called at any time after mesh is initialized.
*
* @param[in] crypto_funcs crypto functions for mesh IE
* - If crypto_funcs is set to NULL, mesh IE is no longer encrypted.
* @return
* - ESP_OK
*/
@ -1210,15 +1218,13 @@ esp_err_t esp_mesh_set_ie_crypto_funcs(const mesh_crypto_funcs_t *crypto_funcs);
/**
* @brief Set mesh IE crypto key
*
* @attention This API shall be called after esp_mesh_set_config() and before esp_mesh_start().
* @attention This API can be called at any time after mesh is initialized.
*
* @param[in] key ASCII crypto key
* @param[in] len length in bytes, range:8~64
*
* @return
* - ESP_OK
* - ESP_ERR_MESH_NOT_ALLOWED
* - ESP_ERR_MESH_NOT_CONFIG
* - ESP_MESH_ERR_ARGUMENT
*/
esp_err_t esp_mesh_set_ie_crypto_key(const char *key, int len);
@ -1236,9 +1242,9 @@ esp_err_t esp_mesh_set_ie_crypto_key(const char *key, int len);
esp_err_t esp_mesh_get_ie_crypto_key(char *key, int len);
/**
* @brief Set delay time before network starts root healing
* @brief Set delay time before starting root healing
*
* @param[in] delay_ms delay time in milliseconds
* @param[in] delay_ms delay time in milliseconds
*
* @return
* - ESP_OK
@ -1253,9 +1259,9 @@ esp_err_t esp_mesh_set_root_healing_delay(int delay_ms);
int esp_mesh_get_root_healing_delay(void);
/**
* @brief Set mesh event callback
* @brief Set mesh event callback
*
* @param[in] event_cb mesh event call back
* @param[in] event_cb mesh event call back
*
* @return
* - ESP_OK
@ -1285,12 +1291,23 @@ esp_err_t esp_mesh_fix_root(bool enable);
bool esp_mesh_is_root_fixed(void);
/**
* @brief Specify a parent for the device
* @brief Set a specified parent for the device
*
* @attention This API can be called at any time after mesh is configured.
*
* @param[in] parent parent configuration, the SSID and the channel of the parent are mandatory.
* @param[in] parent_mesh_id parent mesh ID, if not set, use the device default one.
* @param[in] my_type my mesh type
* @param[in] my_layer my mesh layer
* - If the BSSID is set, make sure that the SSID and BSSID represent the same parent,
* otherwise the device will never find this specified parent.
* @param[in] parent_mesh_id parent mesh ID,
* - If this value is not set, the original mesh ID is used.
* @param[in] my_type mesh type
* - If the parent set for the device is the same as the router in the network configuration,
* then my_type shall set MESH_ROOT and my_layer shall set MESH_ROOT_LAYER.
* @param[in] my_layer mesh layer
* - my_layer of the device may change after joining the network.
* - If my_type is set MESH_NODE, my_layer shall be greater than MESH_ROOT_LAYER.
* - If my_type is set MESH_LEAF, the device becomes a standalone Wi-Fi station and no longer
* has the ability to extend the network.
*
* @return
* - ESP_OK
@ -1330,7 +1347,7 @@ esp_err_t esp_mesh_scan_get_ap_ie_len(int *len);
esp_err_t esp_mesh_scan_get_ap_record(wifi_ap_record_t *ap_record, void *buffer);
/**
* @brief flush upstream packets pending in to_parent queue and to_parent_p2p queue
* @brief Flush upstream packets pending in to_parent queue and to_parent_p2p queue
*
* @return
* - ESP_OK
@ -1338,10 +1355,10 @@ esp_err_t esp_mesh_scan_get_ap_record(wifi_ap_record_t *ap_record, void *buffer)
esp_err_t esp_mesh_flush_upstream_packets(void);
/**
* @brief get the number of nodes in the subnet of a specific child
* @brief Get the number of nodes in the subnet of a specific child
*
* @param child_mac an associated child address of this device
* @param nodes_num pointer to the number of nodes in the subnet of a specific child
* @param[in] child_mac an associated child address of this device
* @param[out] nodes_num pointer to the number of nodes in the subnet of a specific child
*
* @return
* - ESP_OK
@ -1351,11 +1368,11 @@ esp_err_t esp_mesh_flush_upstream_packets(void);
esp_err_t esp_mesh_get_subnet_nodes_num(const mesh_addr_t *child_mac, int *nodes_num);
/**
* @brief get nodes in the subnet of a specific child
* @brief Get nodes in the subnet of a specific child
*
* @param child_mac an associated child address of this device
* @param nodes pointer to nodes in the subnet of a specific child
* @param nodes_num the number of nodes in the subnet of a specific child
* @param[in] child_mac an associated child address of this device
* @param[out] nodes pointer to nodes in the subnet of a specific child
* @param[in] nodes_num the number of nodes in the subnet of a specific child
*
* @return
* - ESP_OK

View file

@ -66,7 +66,7 @@ typedef struct {
uint8_t oui[3]; /**< organization identifier */
/**< mesh networking IE content */
uint8_t type; /** ESP defined IE type */
uint8_t encryped : 1; /**< whether mesh networking IE is encrypted */
uint8_t encrypted : 1; /**< whether mesh networking IE is encrypted */
uint8_t version : 7; /**< mesh networking IE version */
/**< content */
uint8_t mesh_type; /**< mesh device type */

View file

@ -109,6 +109,7 @@ typedef struct {
int tx_ba_win; /**< WiFi Block Ack TX window size */
int rx_ba_win; /**< WiFi Block Ack RX window size */
int wifi_task_core_id; /**< WiFi Task Core ID */
int beacon_max_len; /**< WiFi softAP maximum length of the beacon */
int magic; /**< WiFi init magic number, it should be the last field */
} wifi_init_config_t;
@ -176,6 +177,12 @@ extern const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs;
#define WIFI_TASK_CORE_ID 0
#endif
#ifdef CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN
#define WIFI_SOFTAP_BEACON_MAX_LEN CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN
#else
#define WIFI_SOFTAP_BEACON_MAX_LEN 752
#endif
#define WIFI_INIT_CONFIG_DEFAULT() { \
.event_handler = &esp_event_send, \
.osi_funcs = &g_wifi_osi_funcs, \
@ -193,6 +200,7 @@ extern const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs;
.tx_ba_win = WIFI_DEFAULT_TX_BA_WIN,\
.rx_ba_win = WIFI_DEFAULT_RX_BA_WIN,\
.wifi_task_core_id = WIFI_TASK_CORE_ID,\
.beacon_max_len = WIFI_SOFTAP_BEACON_MAX_LEN, \
.magic = WIFI_INIT_CONFIG_MAGIC\
};

@ -1 +1 @@
Subproject commit 05aa0f411d710a515db6f617b5f413cb3aa14ed1
Subproject commit 2f74d17a63cf40c7c7e63772d0b931617c94d771

View file

@ -59,22 +59,35 @@ config MESH_AP_CONNECTIONS
config MESH_MAX_LAYER
int "Mesh Max Layer"
range 1 15
range 1 25
default 6
help
Max layer allowed in mesh network.
config MESH_ROUTE_TABLE_SIZE
int "Mesh Routing Table Size"
range 1 300
default 50
config MESH_IE_CRYPTO_KEY
string "Mesh IE Crypto Key"
default "hello, esp-mesh."
help
The number of devices over the network(max: 300).
Mesh IE ASCII crypto key, length in bytes, range:8~64.
config MESH_PARENT_SSID
string "Parent SSID"
default "PARENT_SSID"
choice
bool "Mesh IE Crypto Funcs"
default IE_CRYPTO_ENABLE
help
Parent SSID.
Mesh IE crypto funcs.
config IE_CRYPTO_ENABLE
bool "IE_CRYPTO_ENABLE"
config IE_CRYPTO_DISABLE
bool "IE_CRYPTO_DISABLE"
endchoice
config MESH_IE_CRYPTO_FUNCS
int
default 1 if IE_CRYPTO_ENABLE
default 0 if IE_CRYPTO_DISABLE
help
Mesh IE crypto enable/disable.
endmenu

View file

@ -57,16 +57,18 @@ void mesh_scan_done_handler(int num)
bool parent_found = false;
mesh_type_t my_type = MESH_IDLE;
int my_layer = -1;
wifi_config_t parent = { 0, };
wifi_scan_config_t scan_config = { 0 };
for (i = 0; i < num; i++) {
esp_mesh_scan_get_ap_ie_len(&ie_len);
esp_mesh_scan_get_ap_record(&record, &assoc);
if (ie_len == sizeof(assoc)) {
ESP_LOGW(MESH_TAG,
"<MESH>[%d]%s, layer:%d/%d, assoc:%d/%d, %d, "MACSTR", channel:%u, rssi:%d, ID<"MACSTR">",
"<MESH>[%d]%s, layer:%d/%d, assoc:%d/%d, %d, "MACSTR", channel:%u, rssi:%d, ID<"MACSTR"><%s>",
i, record.ssid, assoc.layer, assoc.layer_cap, assoc.assoc,
assoc.assoc_cap, assoc.layer2_cap, MAC2STR(record.bssid),
record.primary, record.rssi, MAC2STR(assoc.mesh_id));
record.primary, record.rssi, MAC2STR(assoc.mesh_id), assoc.encrypted ? "IE Encrypted" : "IE Unencrypted");
#ifdef MESH_SET_NODE
if (assoc.mesh_type != MESH_IDLE && assoc.layer_cap
&& assoc.assoc < assoc.assoc_cap && record.rssi > -70) {
@ -101,9 +103,8 @@ void mesh_scan_done_handler(int num)
if (parent_found) {
/*
* parent
* Both channel and ssid of the parent are mandatory.
* Both channel and SSID of the parent are mandatory.
*/
wifi_config_t parent = { 0, };
parent.sta.channel = parent_record.primary;
memcpy(&parent.sta.ssid, &parent_record.ssid,
sizeof(parent_record.ssid));
@ -122,24 +123,36 @@ void mesh_scan_done_handler(int num)
MAC2STR(parent_record.bssid), parent_record.primary,
parent_record.rssi);
}
ESP_ERROR_CHECK(esp_mesh_set_parent(&parent, (mesh_addr_t*)&parent_assoc.mesh_id, my_type, my_layer));
ESP_ERROR_CHECK(esp_mesh_set_parent(&parent, (mesh_addr_t *)&parent_assoc.mesh_id, my_type, my_layer));
} else {
ESP_LOGW(MESH_TAG,
"no parent found, enable self-organized networking.");
ESP_ERROR_CHECK(esp_mesh_set_self_organized(1, 1));
"<Warning>no parent found, modify IE crypto configuration and scan");
if (CONFIG_MESH_IE_CRYPTO_FUNCS) {
/* modify IE crypto key */
ESP_LOGW(MESH_TAG, "<Config>modify IE crypto key to %s", CONFIG_MESH_IE_CRYPTO_KEY);
ESP_ERROR_CHECK(esp_mesh_set_ie_crypto_key(CONFIG_MESH_IE_CRYPTO_KEY, strlen(CONFIG_MESH_IE_CRYPTO_KEY)));
} else {
/* disable IE crypto */
ESP_LOGW(MESH_TAG, "<Config>disable IE crypto");
ESP_ERROR_CHECK(esp_mesh_set_ie_crypto_funcs(NULL));
}
ESP_ERROR_CHECK(esp_wifi_scan_stop());
scan_config.show_hidden = 1;
scan_config.scan_type = WIFI_SCAN_TYPE_PASSIVE;
ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, 0));
}
}
void mesh_event_handler(mesh_event_t event)
{
mesh_addr_t id = {0,};
mesh_addr_t id = {0,};
static uint8_t last_layer = 0;
ESP_LOGD(MESH_TAG, "esp_event_handler:%d", event.id);
switch (event.id) {
case MESH_EVENT_STARTED:
esp_mesh_get_id(&id);
esp_mesh_get_id(&id);
ESP_LOGI(MESH_TAG, "<MESH_EVENT_STARTED>ID:"MACSTR"", MAC2STR(id.addr));
mesh_layer = esp_mesh_get_layer();
ESP_ERROR_CHECK(esp_mesh_set_self_organized(0, 0));
@ -147,6 +160,7 @@ void mesh_event_handler(mesh_event_t event)
wifi_scan_config_t scan_config = { 0 };
/* mesh softAP is hidden */
scan_config.show_hidden = 1;
scan_config.scan_type = WIFI_SCAN_TYPE_PASSIVE;
ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, 0));
break;
case MESH_EVENT_STOPPED:
@ -179,7 +193,7 @@ void mesh_event_handler(mesh_event_t event)
/* TODO handler for the failure */
break;
case MESH_EVENT_PARENT_CONNECTED:
esp_mesh_get_id(&id);
esp_mesh_get_id(&id);
mesh_layer = event.info.connected.self_layer;
memcpy(&mesh_parent_addr.addr, event.info.connected.connected.bssid, 6);
ESP_LOGI(MESH_TAG,
@ -199,6 +213,12 @@ void mesh_event_handler(mesh_event_t event)
event.info.disconnected.reason);
mesh_disconnected_indicator();
mesh_layer = esp_mesh_get_layer();
if (event.info.disconnected.reason == WIFI_REASON_ASSOC_TOOMANY) {
ESP_ERROR_CHECK(esp_wifi_scan_stop());
scan_config.show_hidden = 1;
scan_config.scan_type = WIFI_SCAN_TYPE_PASSIVE;
ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, 0));
}
break;
case MESH_EVENT_LAYER_CHANGE:
mesh_layer = event.info.layer_change.new_layer;
@ -224,46 +244,10 @@ void mesh_event_handler(mesh_event_t event)
case MESH_EVENT_ROOT_LOST_IP:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_ROOT_LOST_IP>");
break;
case MESH_EVENT_VOTE_STARTED:
ESP_LOGI(MESH_TAG,
"<MESH_EVENT_VOTE_STARTED>attempts:%d, reason:%d, rc_addr:"MACSTR"",
event.info.vote_started.attempts,
event.info.vote_started.reason,
MAC2STR(event.info.vote_started.rc_addr.addr));
break;
case MESH_EVENT_VOTE_STOPPED:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_VOTE_STOPPED>");
break;
case MESH_EVENT_ROOT_SWITCH_REQ:
ESP_LOGI(MESH_TAG,
"<MESH_EVENT_ROOT_SWITCH_REQ>reason:%d, rc_addr:"MACSTR"",
event.info.switch_req.reason,
MAC2STR( event.info.switch_req.rc_addr.addr));
break;
case MESH_EVENT_ROOT_SWITCH_ACK:
/* new root */
mesh_layer = esp_mesh_get_layer();
esp_mesh_get_parent_bssid(&mesh_parent_addr);
ESP_LOGI(MESH_TAG, "<MESH_EVENT_ROOT_SWITCH_ACK>layer:%d, parent:"MACSTR"", mesh_layer, MAC2STR(mesh_parent_addr.addr));
break;
case MESH_EVENT_TODS_STATE:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_TODS_REACHABLE>state:%d",
event.info.toDS_state);
break;
case MESH_EVENT_ROOT_FIXED:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_ROOT_FIXED>%s",
event.info.root_fixed.is_fixed ? "fixed" : "not fixed");
break;
case MESH_EVENT_ROOT_ASKED_YIELD:
ESP_LOGI(MESH_TAG,
"<MESH_EVENT_ROOT_ASKED_YIELD>"MACSTR", rssi:%d, capacity:%d",
MAC2STR(event.info.root_conflict.addr),
event.info.root_conflict.rssi,
event.info.root_conflict.capacity);
break;
case MESH_EVENT_CHANNEL_SWITCH:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_CHANNEL_SWITCH>");
break;
case MESH_EVENT_SCAN_DONE:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_SCAN_DONE>number:%d",
event.info.scan_done.number);
@ -303,7 +287,7 @@ void app_main(void)
ESP_ERROR_CHECK(esp_wifi_start());
/* mesh initialization */
ESP_ERROR_CHECK(esp_mesh_init());
ESP_ERROR_CHECK(esp_mesh_set_ap_authmode(WIFI_AUTH_OPEN));
/* mesh enable IE crypto */
mesh_cfg_t cfg = MESH_INIT_CONFIG_DEFAULT();
/* mesh ID */
memcpy((uint8_t *) &cfg.mesh_id, MESH_ID, 6);
@ -316,12 +300,12 @@ void app_main(void)
memcpy((uint8_t *) &cfg.router.password, CONFIG_MESH_ROUTER_PASSWD,
strlen(CONFIG_MESH_ROUTER_PASSWD));
/* mesh softAP */
ESP_ERROR_CHECK(esp_mesh_set_ap_authmode(CONFIG_MESH_AP_AUTHMODE));
cfg.mesh_ap.max_connection = CONFIG_MESH_AP_CONNECTIONS;
memcpy((uint8_t *) &cfg.mesh_ap.password, CONFIG_MESH_AP_PASSWD,
strlen(CONFIG_MESH_AP_PASSWD));
ESP_ERROR_CHECK(esp_mesh_set_config(&cfg));
/* mesh start */
ESP_ERROR_CHECK(esp_mesh_start());
ESP_LOGI(MESH_TAG, "mesh starts successfully, heap:%d, %s\n", esp_get_free_heap_size(),
esp_mesh_is_root_fixed() ? "root fixed" : "root not fixed");
ESP_LOGI(MESH_TAG, "mesh starts successfully, heap:%d\n", esp_get_free_heap_size());
}