espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.44k stars 7.25k forks source link

[esp_mesh_wifi] Intermediate node does not connect to new fixed root node via esp_mesh_set_type (IDFGH-13117) #14063

Closed dnlmsr closed 1 month ago

dnlmsr commented 3 months ago

Answers checklist.

IDF version.

v5.2.2

Espressif SoC revision.

ESP32-D0WDQ6 (revision v1.0)

Operating System used.

Linux

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

https://www.az-delivery.de/it/products/esp32-developmentboard

Power Supply used.

USB

What is the expected behavior?

Conditions:

When designated node runs esp_mesh_set_type(MESH_ROOT) all the intermediate nodes should connect to the new fixed root node of the mesh

What is the actual behavior?

Intermediate node does not connect to the new fixed root node

Steps to reproduce.

  1. Use the example mesh/internal_communication
  2. Build and flash the firmware for the intermediate node with the code in mesh_main.c slightly changed as follows:

    
    /* Mesh Internal Communication Example
    
    This example code is in the Public Domain (or CC0 licensed, at your option.)
    
    Unless required by applicable law or agreed to in writing, this
    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    CONDITIONS OF ANY KIND, either express or implied.
    */
    #include "esp_event.h"
    #include "esp_log.h"
    #include "esp_mac.h"
    #include "esp_mesh.h"
    #include "esp_mesh_internal.h"
    #include "esp_wifi.h"
    #include "mesh_light.h"
    #include "nvs_flash.h"
    #include <inttypes.h>
    #include <string.h>

/***

/***

/***

mesh_light_ctl_t light_on = { .cmd = MESH_CONTROL_CMD, .on = 1, .token_id = MESH_TOKEN_ID, .token_value = MESH_TOKEN_VALUE, };

mesh_light_ctl_t light_off = { .cmd = MESH_CONTROL_CMD, .on = 0, .token_id = MESH_TOKEN_ID, .token_value = MESH_TOKEN_VALUE, };

/***

/***

void esp_mesh_p2p_rx_main(void *arg) { int recv_count = 0; esp_err_t err; mesh_addr_t from; int send_count = 0; mesh_data_t data; int flag = 0; data.data = rx_buf; data.size = RX_SIZE; is_running = true;

while (is_running) { data.size = RX_SIZE; err = esp_mesh_recv(&from, &data, portMAX_DELAY, &flag, NULL, 0); if (err != ESP_OK || !data.size) { ESP_LOGE(MESH_TAG, "err:0x%x, size:%d", err, data.size); continue; } / extract send count / if (data.size >= sizeof(send_count)) { send_count = (data.data[25] << 24) | (data.data[24] << 16) | (data.data[23] << 8) | data.data[22]; } recv_count++; / process light control / mesh_light_process(&from, data.data, data.size); if (!(recv_count % 1)) { ESP_LOGW( MESH_TAG, "[#RX:%d/%d][L:%d] parent:" MACSTR ", receive from " MACSTR ", size:%d, heap:%" PRId32 ", flag:%d[err:0x%x, proto:%d, tos:%d]", recv_count, send_count, mesh_layer, MAC2STR(mesh_parent_addr.addr), MAC2STR(from.addr), data.size, esp_get_minimum_free_heap_size(), flag, err, data.proto, data.tos); } } vTaskDelete(NULL); }

esp_err_t esp_mesh_comm_p2p_start(void) { static bool is_comm_p2p_started = false; if (!is_comm_p2p_started) { is_comm_p2p_started = true; xTaskCreate(esp_mesh_p2p_tx_main, "MPTX", 3072, NULL, 5, NULL); xTaskCreate(esp_mesh_p2p_rx_main, "MPRX", 3072, NULL, 5, NULL); } return ESP_OK; }

void mesh_event_handler(void arg, esp_event_base_t event_base, int32_t event_id, void event_data) { mesh_addr_t id = { 0, }; static uint16_t last_layer = 0;

switch (event_id) { case MESH_EVENT_STARTED: { esp_mesh_get_id(&id); ESP_LOGI(MESH_TAG, "ID:" MACSTR "", MAC2STR(id.addr)); is_mesh_connected = false; mesh_layer = esp_mesh_get_layer(); } break; case MESH_EVENT_STOPPED: { ESP_LOGI(MESH_TAG, ""); is_mesh_connected = false; mesh_layer = esp_mesh_get_layer(); } break; case MESH_EVENT_CHILD_CONNECTED: { mesh_event_child_connected_t child_connected = (mesh_event_child_connected_t )event_data; ESP_LOGI(MESH_TAG, "aid:%d, " MACSTR "", child_connected->aid, MAC2STR(child_connected->mac)); } break; case MESH_EVENT_CHILD_DISCONNECTED: { mesh_event_child_disconnected_t child_disconnected = (mesh_event_child_disconnected_t )event_data; ESP_LOGI(MESH_TAG, "aid:%d, " MACSTR "", child_disconnected->aid, MAC2STR(child_disconnected->mac)); } break; case MESH_EVENT_ROUTING_TABLE_ADD: { mesh_event_routing_table_change_t routing_table = (mesh_event_routing_table_change_t )event_data; ESP_LOGW(MESH_TAG, "add %d, new:%d, layer:%d", routing_table->rt_size_change, routing_table->rt_size_new, mesh_layer); } break; case MESH_EVENT_ROUTING_TABLE_REMOVE: { mesh_event_routing_table_change_t routing_table = (mesh_event_routing_table_change_t )event_data; ESP_LOGW(MESH_TAG, "remove %d, new:%d, layer:%d", routing_table->rt_size_change, routing_table->rt_size_new, mesh_layer); } break; case MESH_EVENT_NO_PARENT_FOUND: { mesh_event_no_parent_found_t no_parent = (mesh_event_no_parent_found_t )event_data; ESP_LOGI(MESH_TAG, "scan times:%d", no_parent->scan_times); } / TODO handler for the failure / break; case MESH_EVENT_PARENT_CONNECTED: { mesh_event_connected_t connected = (mesh_event_connected_t )event_data; esp_mesh_get_id(&id); mesh_layer = connected->self_layer; memcpy(&mesh_parent_addr.addr, connected->connected.bssid, 6); ESP_LOGI(MESH_TAG, "layer:%d-->%d, parent:" MACSTR "%s, ID:" MACSTR ", duty:%d", last_layer, mesh_layer, MAC2STR(mesh_parent_addr.addr), esp_mesh_is_root() ? "" : (mesh_layer == 2) ? "" : "", MAC2STR(id.addr), connected->duty); last_layer = mesh_layer; mesh_connected_indicator(mesh_layer); is_mesh_connected = true; if (esp_mesh_is_root()) { esp_netif_dhcpc_stop(netif_sta); esp_netif_dhcpc_start(netif_sta); } esp_mesh_comm_p2p_start(); } break; case MESH_EVENT_PARENT_DISCONNECTED: { mesh_event_disconnected_t disconnected = (mesh_event_disconnected_t )event_data; ESP_LOGI(MESH_TAG, "reason:%d", disconnected->reason); is_mesh_connected = false; mesh_disconnected_indicator(); mesh_layer = esp_mesh_get_layer(); } break; case MESH_EVENT_LAYER_CHANGE: { mesh_event_layer_change_t layer_change = (mesh_event_layer_change_t )event_data; mesh_layer = layer_change->new_layer; ESP_LOGI(MESH_TAG, "layer:%d-->%d%s", last_layer, mesh_layer, esp_mesh_is_root() ? "" : (mesh_layer == 2) ? "" : ""); last_layer = mesh_layer; mesh_connected_indicator(mesh_layer); } break; case MESH_EVENT_ROOT_ADDRESS: { mesh_event_root_address_t root_addr = (mesh_event_root_address_t )event_data; ESP_LOGI(MESH_TAG, "root address:" MACSTR "", MAC2STR(root_addr->addr)); } break; case MESH_EVENT_VOTE_STARTED: { mesh_event_vote_started_t vote_started = (mesh_event_vote_started_t )event_data; ESP_LOGI(MESH_TAG, "attempts:%d, reason:%d, rc_addr:" MACSTR "", vote_started->attempts, vote_started->reason, MAC2STR(vote_started->rc_addr.addr)); } break; case MESH_EVENT_VOTE_STOPPED: { ESP_LOGI(MESH_TAG, ""); break; } case MESH_EVENT_ROOT_SWITCH_REQ: { mesh_event_root_switch_req_t switch_req = (mesh_event_root_switch_req_t )event_data; ESP_LOGI(MESH_TAG, "reason:%d, rc_addr:" MACSTR "", switch_req->reason, MAC2STR(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, "layer:%d, parent:" MACSTR "", mesh_layer, MAC2STR(mesh_parent_addr.addr)); } break; case MESH_EVENT_TODS_STATE: { mesh_event_toDS_state_t toDs_state = (mesh_event_toDS_state_t )event_data; ESP_LOGI(MESH_TAG, "state:%d", toDs_state); } break; case MESH_EVENT_ROOT_FIXED: { mesh_event_root_fixed_t root_fixed = (mesh_event_root_fixed_t )event_data; ESP_LOGI(MESH_TAG, "%s", root_fixed->is_fixed ? "fixed" : "not fixed"); } break; case MESH_EVENT_ROOT_ASKED_YIELD: { mesh_event_root_conflict_t root_conflict = (mesh_event_root_conflict_t )event_data; ESP_LOGI(MESH_TAG, "" MACSTR ", rssi:%d, capacity:%d", MAC2STR(root_conflict->addr), root_conflict->rssi, root_conflict->capacity); } break; case MESH_EVENT_CHANNEL_SWITCH: { mesh_event_channel_switch_t channel_switch = (mesh_event_channel_switch_t )event_data; ESP_LOGI(MESH_TAG, "new channel:%d", channel_switch->channel); } break; case MESH_EVENT_SCAN_DONE: { mesh_event_scan_done_t scan_done = (mesh_event_scan_done_t )event_data; ESP_LOGI(MESH_TAG, "number:%d", scan_done->number); } break; case MESH_EVENT_NETWORK_STATE: { mesh_event_network_state_t network_state = (mesh_event_network_state_t )event_data; ESP_LOGI(MESH_TAG, "is_rootless:%d", network_state->is_rootless); } break; case MESH_EVENT_STOP_RECONNECTION: { ESP_LOGI(MESH_TAG, ""); } break; case MESH_EVENT_FIND_NETWORK: { mesh_event_find_network_t find_network = (mesh_event_find_network_t )event_data; ESP_LOGI(MESH_TAG, "new channel:%d, router BSSID:" MACSTR "", find_network->channel, MAC2STR(find_network->router_bssid)); } break; case MESH_EVENT_ROUTER_SWITCH: { mesh_event_router_switch_t router_switch = (mesh_event_router_switch_t )event_data; ESP_LOGI(MESH_TAG, "new router:%s, channel:%d, " MACSTR "", router_switch->ssid, router_switch->channel, MAC2STR(router_switch->bssid)); } break; case MESH_EVENT_PS_PARENT_DUTY: { mesh_event_ps_duty_t ps_duty = (mesh_event_ps_duty_t )event_data; ESP_LOGI(MESH_TAG, "duty:%d", ps_duty->duty); } break; case MESH_EVENT_PS_CHILD_DUTY: { mesh_event_ps_duty_t ps_duty = (mesh_event_ps_duty_t *)event_data; ESP_LOGI(MESH_TAG, "cidx:%d, " MACSTR ", duty:%d", ps_duty->child_connected.aid - 1, MAC2STR(ps_duty->child_connected.mac), ps_duty->duty); } break; default: ESP_LOGI(MESH_TAG, "unknown id:%" PRId32 "", event_id); break; } }

void ip_event_handler(void arg, esp_event_base_t event_base, int32_t event_id, void event_data) { ip_event_got_ip_t event = (ip_event_got_ip_t )event_data; ESP_LOGI(MESH_TAG, "IP:" IPSTR, IP2STR(&event->ip_info.ip)); }

void app_main(void) { ESP_ERROR_CHECK(mesh_light_init()); ESP_ERROR_CHECK(nvs_flash_init()); / tcpip initialization / ESP_ERROR_CHECK(esp_netif_init()); / event initialization / ESP_ERROR_CHECK(esp_event_loop_create_default()); /* create network interfaces for mesh (only station instance saved for

  1. Build and flash the firmware for the designated root node with the following code in mesh_main.c (node starts as MESH_LEAF, then after 30s turns to MESH_ROOT):

    
    /* Mesh Internal Communication Example
    
    This example code is in the Public Domain (or CC0 licensed, at your option.)
    
    Unless required by applicable law or agreed to in writing, this
    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    CONDITIONS OF ANY KIND, either express or implied.
    */
    #include "esp_event.h"
    #include "esp_log.h"
    #include "esp_mac.h"
    #include "esp_mesh.h"
    #include "esp_mesh_internal.h"
    #include "esp_wifi.h"
    #include "mesh_light.h"
    #include "nvs_flash.h"
    #include <inttypes.h>
    #include <string.h>

/***

/***

/***

mesh_light_ctl_t light_on = { .cmd = MESH_CONTROL_CMD, .on = 1, .token_id = MESH_TOKEN_ID, .token_value = MESH_TOKEN_VALUE, };

mesh_light_ctl_t light_off = { .cmd = MESH_CONTROL_CMD, .on = 0, .token_id = MESH_TOKEN_ID, .token_value = MESH_TOKEN_VALUE, };

/***

/***

void esp_mesh_p2p_rx_main(void *arg) { int recv_count = 0; esp_err_t err; mesh_addr_t from; int send_count = 0; mesh_data_t data; int flag = 0; data.data = rx_buf; data.size = RX_SIZE; is_running = true;

while (is_running) { data.size = RX_SIZE; err = esp_mesh_recv(&from, &data, portMAX_DELAY, &flag, NULL, 0); if (err != ESP_OK || !data.size) { ESP_LOGE(MESH_TAG, "err:0x%x, size:%d", err, data.size); continue; } / extract send count / if (data.size >= sizeof(send_count)) { send_count = (data.data[25] << 24) | (data.data[24] << 16) | (data.data[23] << 8) | data.data[22]; } recv_count++; / process light control / mesh_light_process(&from, data.data, data.size); if (!(recv_count % 1)) { ESP_LOGW( MESH_TAG, "[#RX:%d/%d][L:%d] parent:" MACSTR ", receive from " MACSTR ", size:%d, heap:%" PRId32 ", flag:%d[err:0x%x, proto:%d, tos:%d]", recv_count, send_count, mesh_layer, MAC2STR(mesh_parent_addr.addr), MAC2STR(from.addr), data.size, esp_get_minimum_free_heap_size(), flag, err, data.proto, data.tos); } } vTaskDelete(NULL); }

esp_err_t esp_mesh_comm_p2p_start(void) { static bool is_comm_p2p_started = false; if (!is_comm_p2p_started) { is_comm_p2p_started = true; xTaskCreate(esp_mesh_p2p_tx_main, "MPTX", 3072, NULL, 5, NULL); xTaskCreate(esp_mesh_p2p_rx_main, "MPRX", 3072, NULL, 5, NULL); } return ESP_OK; }

void mesh_event_handler(void arg, esp_event_base_t event_base, int32_t event_id, void event_data) { mesh_addr_t id = { 0, }; static uint16_t last_layer = 0;

switch (event_id) { case MESH_EVENT_STARTED: { esp_mesh_get_id(&id); ESP_LOGI(MESH_TAG, "ID:" MACSTR "", MAC2STR(id.addr)); is_mesh_connected = false; mesh_layer = esp_mesh_get_layer(); } break; case MESH_EVENT_STOPPED: { ESP_LOGI(MESH_TAG, ""); is_mesh_connected = false; mesh_layer = esp_mesh_get_layer(); } break; case MESH_EVENT_CHILD_CONNECTED: { mesh_event_child_connected_t child_connected = (mesh_event_child_connected_t )event_data; ESP_LOGI(MESH_TAG, "aid:%d, " MACSTR "", child_connected->aid, MAC2STR(child_connected->mac)); } break; case MESH_EVENT_CHILD_DISCONNECTED: { mesh_event_child_disconnected_t child_disconnected = (mesh_event_child_disconnected_t )event_data; ESP_LOGI(MESH_TAG, "aid:%d, " MACSTR "", child_disconnected->aid, MAC2STR(child_disconnected->mac)); } break; case MESH_EVENT_ROUTING_TABLE_ADD: { mesh_event_routing_table_change_t routing_table = (mesh_event_routing_table_change_t )event_data; ESP_LOGW(MESH_TAG, "add %d, new:%d, layer:%d", routing_table->rt_size_change, routing_table->rt_size_new, mesh_layer); } break; case MESH_EVENT_ROUTING_TABLE_REMOVE: { mesh_event_routing_table_change_t routing_table = (mesh_event_routing_table_change_t )event_data; ESP_LOGW(MESH_TAG, "remove %d, new:%d, layer:%d", routing_table->rt_size_change, routing_table->rt_size_new, mesh_layer); } break; case MESH_EVENT_NO_PARENT_FOUND: { mesh_event_no_parent_found_t no_parent = (mesh_event_no_parent_found_t )event_data; ESP_LOGI(MESH_TAG, "scan times:%d", no_parent->scan_times); } / TODO handler for the failure / break; case MESH_EVENT_PARENT_CONNECTED: { mesh_event_connected_t connected = (mesh_event_connected_t )event_data; esp_mesh_get_id(&id); mesh_layer = connected->self_layer; memcpy(&mesh_parent_addr.addr, connected->connected.bssid, 6); ESP_LOGI(MESH_TAG, "layer:%d-->%d, parent:" MACSTR "%s, ID:" MACSTR ", duty:%d", last_layer, mesh_layer, MAC2STR(mesh_parent_addr.addr), esp_mesh_is_root() ? "" : (mesh_layer == 2) ? "" : "", MAC2STR(id.addr), connected->duty); last_layer = mesh_layer; mesh_connected_indicator(mesh_layer); is_mesh_connected = true; if (esp_mesh_is_root()) { esp_netif_dhcpc_stop(netif_sta); esp_netif_dhcpc_start(netif_sta); } esp_mesh_comm_p2p_start(); } break; case MESH_EVENT_PARENT_DISCONNECTED: { mesh_event_disconnected_t disconnected = (mesh_event_disconnected_t )event_data; ESP_LOGI(MESH_TAG, "reason:%d", disconnected->reason); is_mesh_connected = false; mesh_disconnected_indicator(); mesh_layer = esp_mesh_get_layer(); } break; case MESH_EVENT_LAYER_CHANGE: { mesh_event_layer_change_t layer_change = (mesh_event_layer_change_t )event_data; mesh_layer = layer_change->new_layer; ESP_LOGI(MESH_TAG, "layer:%d-->%d%s", last_layer, mesh_layer, esp_mesh_is_root() ? "" : (mesh_layer == 2) ? "" : ""); last_layer = mesh_layer; mesh_connected_indicator(mesh_layer); } break; case MESH_EVENT_ROOT_ADDRESS: { mesh_event_root_address_t root_addr = (mesh_event_root_address_t )event_data; ESP_LOGI(MESH_TAG, "root address:" MACSTR "", MAC2STR(root_addr->addr)); } break; case MESH_EVENT_VOTE_STARTED: { mesh_event_vote_started_t vote_started = (mesh_event_vote_started_t )event_data; ESP_LOGI(MESH_TAG, "attempts:%d, reason:%d, rc_addr:" MACSTR "", vote_started->attempts, vote_started->reason, MAC2STR(vote_started->rc_addr.addr)); } break; case MESH_EVENT_VOTE_STOPPED: { ESP_LOGI(MESH_TAG, ""); break; } case MESH_EVENT_ROOT_SWITCH_REQ: { mesh_event_root_switch_req_t switch_req = (mesh_event_root_switch_req_t )event_data; ESP_LOGI(MESH_TAG, "reason:%d, rc_addr:" MACSTR "", switch_req->reason, MAC2STR(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, "layer:%d, parent:" MACSTR "", mesh_layer, MAC2STR(mesh_parent_addr.addr)); } break; case MESH_EVENT_TODS_STATE: { mesh_event_toDS_state_t toDs_state = (mesh_event_toDS_state_t )event_data; ESP_LOGI(MESH_TAG, "state:%d", toDs_state); } break; case MESH_EVENT_ROOT_FIXED: { mesh_event_root_fixed_t root_fixed = (mesh_event_root_fixed_t )event_data; ESP_LOGI(MESH_TAG, "%s", root_fixed->is_fixed ? "fixed" : "not fixed"); } break; case MESH_EVENT_ROOT_ASKED_YIELD: { mesh_event_root_conflict_t root_conflict = (mesh_event_root_conflict_t )event_data; ESP_LOGI(MESH_TAG, "" MACSTR ", rssi:%d, capacity:%d", MAC2STR(root_conflict->addr), root_conflict->rssi, root_conflict->capacity); } break; case MESH_EVENT_CHANNEL_SWITCH: { mesh_event_channel_switch_t channel_switch = (mesh_event_channel_switch_t )event_data; ESP_LOGI(MESH_TAG, "new channel:%d", channel_switch->channel); } break; case MESH_EVENT_SCAN_DONE: { mesh_event_scan_done_t scan_done = (mesh_event_scan_done_t )event_data; ESP_LOGI(MESH_TAG, "number:%d", scan_done->number); } break; case MESH_EVENT_NETWORK_STATE: { mesh_event_network_state_t network_state = (mesh_event_network_state_t )event_data; ESP_LOGI(MESH_TAG, "is_rootless:%d", network_state->is_rootless); } break; case MESH_EVENT_STOP_RECONNECTION: { ESP_LOGI(MESH_TAG, ""); } break; case MESH_EVENT_FIND_NETWORK: { mesh_event_find_network_t find_network = (mesh_event_find_network_t )event_data; ESP_LOGI(MESH_TAG, "new channel:%d, router BSSID:" MACSTR "", find_network->channel, MAC2STR(find_network->router_bssid)); } break; case MESH_EVENT_ROUTER_SWITCH: { mesh_event_router_switch_t router_switch = (mesh_event_router_switch_t )event_data; ESP_LOGI(MESH_TAG, "new router:%s, channel:%d, " MACSTR "", router_switch->ssid, router_switch->channel, MAC2STR(router_switch->bssid)); } break; case MESH_EVENT_PS_PARENT_DUTY: { mesh_event_ps_duty_t ps_duty = (mesh_event_ps_duty_t )event_data; ESP_LOGI(MESH_TAG, "duty:%d", ps_duty->duty); } break; case MESH_EVENT_PS_CHILD_DUTY: { mesh_event_ps_duty_t ps_duty = (mesh_event_ps_duty_t *)event_data; ESP_LOGI(MESH_TAG, "cidx:%d, " MACSTR ", duty:%d", ps_duty->child_connected.aid - 1, MAC2STR(ps_duty->child_connected.mac), ps_duty->duty); } break; default: ESP_LOGI(MESH_TAG, "unknown id:%" PRId32 "", event_id); break; } }

void ip_event_handler(void arg, esp_event_base_t event_base, int32_t event_id, void event_data) { ip_event_got_ip_t event = (ip_event_got_ip_t )event_data; ESP_LOGI(MESH_TAG, "IP:" IPSTR, IP2STR(&event->ip_info.ip)); }

void app_main(void) { ESP_ERROR_CHECK(mesh_light_init()); ESP_ERROR_CHECK(nvs_flash_init()); / tcpip initialization / ESP_ERROR_CHECK(esp_netif_init()); / event initialization / ESP_ERROR_CHECK(esp_event_loop_create_default()); /* create network interfaces for mesh (only station instance saved for

Debug Logs.

Logs for the intermediate node

I (614428) mesh_main: <MESH_EVENT_FIND_NETWORK>new channel:1, router BSSID:00:00:00:00:00:00
I (614438) wifi:mode : sta (ec:62:60:9c:a0:74) + softAP (ec:62:60:9c:a0:75)
W (614448) wifi:<MESH AP>adjust channel:1, secondary channel offset:1(40U)
I (614458) wifi:Total power save buffer number: 16
I (614458) wifi:Init max length of beacon: 752/752
I (614468) wifi:Init max length of beacon: 752/752
W (614478) wifi:<MESH AP>adjust channel:1, secondary channel offset:1(40U)
I (614488) wifi:Total power save buffer number: 16
I (614788) mesh: [SCAN][ch:1]AP:21, other(ID:0, RD:0), MAP:0, idle:0, candidate:0, root:0, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (614788) mesh: [FAIL][2161]root:0, fail:113, normal:0

I (615098) mesh: [SCAN][ch:1]AP:17, other(ID:0, RD:0), MAP:0, idle:0, candidate:0, root:0, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (615098) mesh: [FAIL][2162]root:0, fail:114, normal:0

I (615408) mesh: [SCAN][ch:1]AP:18, other(ID:0, RD:0), MAP:0, idle:0, candidate:0, root:0, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (615408) mesh: [FAIL][2163]root:0, fail:115, normal:0

I (615538) mesh: [SCAN][ch:1]AP:12, other(ID:0, RD:0), MAP:0, idle:0, candidate:0, root:0, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (615538) mesh: [FAIL][2164]root:0, fail:116, normal:0

I (615848) mesh: [SCAN][ch:1]AP:21, other(ID:0, RD:0), MAP:0, idle:0, candidate:0, root:0, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (615848) mesh: [FAIL][2165]root:0, fail:117, normal:0

I (616158) mesh: [SCAN][ch:1]AP:24, other(ID:0, RD:0), MAP:1, idle:0, candidate:1, root:1, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (616158) mesh: [FAIL][2166]root:0, fail:118, normal:0

I (616288) mesh: [SCAN][ch:1]AP:12, other(ID:0, RD:0), MAP:0, idle:0, candidate:0, root:0, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (616288) mesh: [FAIL][2167]root:0, fail:119, normal:0

I (616598) mesh: [SCAN][ch:1]AP:21, other(ID:0, RD:0), MAP:0, idle:0, candidate:0, root:0, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (616598) mesh: [FAIL][2168]root:0, fail:120, normal:0

I (616908) mesh: [SCAN][ch:1]AP:21, other(ID:0, RD:0), MAP:0, idle:0, candidate:0, root:0, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (616908) mesh: [FAIL][2169]root:0, fail:121, normal:0

I (617038) mesh: [SCAN][ch:1]AP:13, other(ID:0, RD:0), MAP:1, idle:0, candidate:1, root:1, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (617038) mesh: [FAIL][2170]root:0, fail:122, normal:0

I (617348) mesh: [SCAN][ch:1]AP:20, other(ID:0, RD:0), MAP:1, idle:0, candidate:1, root:1, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (617348) mesh: [FAIL][2171]root:0, fail:123, normal:0

....

I (613308) mesh: [SCAN][ch:1]AP:24, other(ID:0, RD:0), MAP:1, idle:0, candidate:1, root:1, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (613308) mesh: [FAIL][2159]root:0, fail:111, normal:0

I (613618) mesh: [SCAN][ch:1]AP:24, other(ID:0, RD:0), MAP:1, idle:0, candidate:1, root:1, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (613618) mesh: [FAIL][2160]root:0, fail:112, normal:0

I (613618) mesh: <MESH_NWK_PARENT_SELECTION>no parent found, set ROOTLESS, scan times:60, heap:176508
I (613628) wifi:mode : sta (ec:62:60:9c:a0:74)
I (613628) mesh_main: <MESH_EVENT_NO_PARENT_FOUND>scan times:60
I (613648) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:1
I (613958) mesh: [FIND][ch:1]AP:25, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]
I (613958) mesh: [FIND:1]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (613958) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:2
I (614098) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>
I (614098) mesh: [FIND:2]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (614108) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:3
I (614418) mesh: find root:ESPM_B243C0, root_cap:1(max:300), new channel:1, old channel:0
I (614418) mesh: [FIND][ch:1]AP:18, otherID:0, MAP:1, idle:0, candidate:0, root:1[00:00:00:00:00:00][FIXED-ROOT]
I (614418) mesh: [FIND:3]find a network, channel:1, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

Logs for the fixed root node after 15s from the boot:

I (15018) mesh: [SCAN][ch:1]AP:19, other(ID:0, RD:0), MAP:0, idle:0, candidate:0, root:0, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (15018) mesh: [FAIL][57]root:0, fail:57, normal:0

I (15328) mesh: [SCAN][ch:1]AP:27, other(ID:0, RD:0), MAP:0, idle:0, candidate:0, root:0, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (15328) mesh: [FAIL][58]root:0, fail:58, normal:0

I (15638) mesh: [SCAN][ch:1]AP:28, other(ID:0, RD:0), MAP:0, idle:0, candidate:0, root:0, topMAP:0[c:0,i:0][00:00:00:00:00:00][FIXED-ROOT]<>
I (15638) mesh: [FAIL][59]root:0, fail:59, normal:0

I (15638) mesh: <MESH_NWK_PARENT_SELECTION>no parent found, set ROOTLESS, scan times:60, heap:177888
I (15648) mesh_main: <MESH_EVENT_NO_PARENT_FOUND>scan times:60
I (15648) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:2
I (15658) mesh_main: <MESH_EVENT_NETWORK_STATE>is_rootless:1
I (15788) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>
I (15788) mesh: [FIND:1]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (15798) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:3
I (16108) mesh: [FIND][ch:1]AP:25, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]
I (16108) mesh: [FIND:2]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (16118) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:4
I (16248) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>
I (16248) mesh: [FIND:3]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (16258) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:5
I (16568) mesh: [FIND][ch:1]AP:26, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]
I (16568) mesh: [FIND:4]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (16578) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:6
I (16708) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>
I (16708) mesh: [FIND:5]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (16718) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:7
I (17028) mesh: [FIND][ch:1]AP:22, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]
I (17028) mesh: [FIND:6]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (17038) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:8
I (17168) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>
I (17168) mesh: [FIND:7]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (17178) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:9
I (17488) mesh: [FIND][ch:1]AP:27, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]
I (17488) mesh: [FIND:8]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (17498) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:10
I (17628) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>
I (17628) mesh: [FIND:9]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (17638) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:11
I (17948) mesh: [FIND][ch:1]AP:27, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]
I (17948) mesh: [FIND:10]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (17958) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:12
I (18088) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>
I (18088) mesh: [FIND:11]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (18098) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:13
I (18408) mesh: [FIND][ch:1]AP:26, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]
I (18408) mesh: [FIND:12]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (18418) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:14
I (18548) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>
I (18548) mesh: [FIND:13]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (18558) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:15
I (18868) mesh: [FIND][ch:1]AP:17, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]
I (18868) mesh: [FIND:14]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (18878) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:16
I (19008) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>
I (19008) mesh: [FIND:15]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (19018) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:17
I (19328) mesh: [FIND][ch:1]AP:26, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]
I (19328) mesh: [FIND:16]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (19338) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:18
I (19468) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>
I (19468) mesh: [FIND:17]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (19478) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:19
I (19788) mesh: [FIND][ch:1]AP:26, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]
I (19788) mesh: [FIND:18]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (19798) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:20
I (19928) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>
I (19928) mesh: [FIND:19]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (19938) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x0, look_for_nwk_count:21
I (20248) mesh: [FIND][ch:1]AP:28, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]
I (20248) mesh: [FIND:20]fail to find a network, channel:0, cfg<channel:1, router:ROUTER_SSID, 00:00:00:00:00:00>

I (20258) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:22
I (20388) mesh: [FIND][ch:1]AP:0, otherID:0, MAP:0, idle:0, candidate:0, root:0[00:00:00:00:00:00][FIXED-ROOT]<scan router>

More Information.

Provided code is mostly equal as the already existing example. Notable changes start after esp_mesh_start

As a result I would like to provision an "offline mesh" without a Wi-Fi router. Since we need a way to elect a fixed root in order to form the mesh, a designated node after some time automatically promotes itself to root node.

Everything works if the switch with esp_set_mesh_type(MESH_ROOT) happens before 15s after boot. A longer wait time will cause the following log lines:

I (15648) mesh_main: <MESH_EVENT_NO_PARENT_FOUND>scan times:60
I (15648) mesh: <MESH_NWK_LOOK_FOR_NETWORK>need_scan:0x3, need_scan_router:0x1, look_for_nwk_count:2
I (15658) mesh_main: <MESH_EVENT_NETWORK_STATE>is_rootless:1

Which is why I suspect that after the switch to root node, it notifies the nodes around that the mesh does not have a root node.

zhangyanjiaoesp commented 2 months ago

@dnlmsr do not call esp_mesh_set_type(MESH_LEAF) can solve your problem.

dnlmsr commented 2 months ago

@dnlmsr do not call esp_mesh_set_type(MESH_LEAF) can solve your problem.

This will not solve my implementation. I will try to rephrase:

In my application I want the device to always start as leaf node, thus if a mesh is already present, it will successfully connect to that mesh. However, when the device does not connect to an existing mesh, I want the device to become a root node, either via a delay or by a user action.

In the sample code I attached the 15/30s delay before calling the esp_mesh_set_type(MESH_ROOT) is just a "simulation" of an external command calling this function.

zhangyanjiaoesp commented 2 months ago

@dnlmsr what about the channel? When I setting the cfg.channel = 0, it can also connects to the root node.