Hi,
After a lot of trial and error, I have a workaround but think there is an underlying bug. I am using the smart config example code as a template.
If I call the function to do the smart config in the mesh event handler (when no parent found) either as a function call or by creating a new task, the smart config appears to get the details (fires SC_STATUS_LINK) but calling esp_mesh_set_router doesn't seem to work - there is no activity on serial output. Also, it never fires event SC_STATUS_LINK_OVER. I also tried switching the router config using the wifi calls (surrounded by switching self organising off before it and then back on after it) that are in the example and this fails too sometimes core dumping
My workaround is to create a task in the mesh event handler to start the smart config process and waits for this task to set a bit to say it has got the data. The smart config task then stores the SSID and password in global variables when SC_STATUS_LINK is fired and then stops the smart config process, deletes the task, and sets the bit to say it has done it. On detecting the bit has been set, the mesh event handler reads the global variables and calls esp_mesh_set_router. This seems to work fine but adds unnecessary complexity to the code design. Any ideas why the switching in the smart config event handler as in the example doesn't work with mesh?
Code in the mesh event handler is...
Code: Select all
EventBits_t uxBits;
bool bSmartConfigDone = false;
ESP_LOGI(HOMEIOT_TAG, "OnMeshNoParent: No parent found starting Smart Config");
xTaskCreate(DoSmartConfig, "DoSmartConfig", 4096, NULL, 3, NULL);
while (!bSmartConfigDone)
{
// Wait for the Smart Config to set the get data bit to indicate it has got router info
uxBits = xEventGroupWaitBits(s_wifi_event_group, SMARTCONFIG_GOT_DATA_BIT, true, false, portMAX_DELAY);
if(uxBits & SMARTCONFIG_GOT_DATA_BIT)
{
ESP_LOGI(HOMEIOT_TAG, "OnMeshNoParent: Received notification Smart Config has set data");
mesh_router_t newinfo = {0};
strcpy((char*)newinfo.ssid, sSmartConfigSSID);
strcpy((char*)newinfo.password,sSmartConfigPassword );
newinfo.ssid_len = strlen((char*) newinfo.ssid);
memset(newinfo.bssid, '\0', 6);
newinfo.allow_router_switch = true;
ESP_LOGI(HOMEIOT_TAG, "OnMeshNoParent: Setting mesh router info to ssid[%s] password[%s] len[%d]", newinfo.ssid, newinfo.password, newinfo.ssid_len);
esp_err_t err = esp_mesh_set_router(&newinfo);
ESP_LOGI(HOMEIOT_TAG, "Finished set router err [%d = %s]", err, esp_err_to_name(err));
bSmartConfigDone = true;
}
}
Smart config code is
Code: Select all
void DoSmartConfig (void *parm)
{
EventBits_t uxBits;
ESP_LOGI(HOMEIOT_TAG, "DoSmartConfig: Starting Smart Config");
ESP_ERROR_CHECK( esp_smartconfig_set_type(SC_TYPE_ESPTOUCH) );
ESP_ERROR_CHECK( esp_smartconfig_start(cbOnSmartConfigEvent, 1) );
ESP_LOGI(HOMEIOT_TAG, "DoSmartConfig: Smart Config Started");
while (1)
{
uxBits = xEventGroupWaitBits(s_wifi_event_group, ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
if(uxBits & ESPTOUCH_DONE_BIT)
{
ESP_LOGI(HOMEIOT_TAG, "DoSmartConfig: Stopping Smart Config");
esp_smartconfig_stop();
// Notify task which initiated the smart config process that we have got the data
xEventGroupSetBits(s_wifi_event_group, SMARTCONFIG_GOT_DATA_BIT);
vTaskDelete(NULL);
ESP_LOGI(HOMEIOT_TAG, "DoSmartConfig: Smart Config task deleted");
}
}
}
Code for the event handler
Code: Select all
static void cbOnSmartConfigEvent(smartconfig_status_t status, void *pdata)
{
switch (status) {
case SC_STATUS_WAIT:
ESP_LOGI(HOMEIOT_TAG, "cbOnSmartConfigEvent: SC_STATUS_WAIT");
break;
case SC_STATUS_FIND_CHANNEL:
ESP_LOGI(HOMEIOT_TAG, "cbOnSmartConfigEvent: SC_STATUS_FINDING_CHANNEL");
break;
case SC_STATUS_GETTING_SSID_PSWD:
ESP_LOGI(HOMEIOT_TAG, "cbOnSmartConfigEvent: SC_STATUS_GETTING_SSID_PSWD");
break;
case SC_STATUS_LINK:
ESP_LOGI(HOMEIOT_TAG, "cbOnSmartConfigEvent: SC_STATUS_LINK");
wifi_config_t *wifi_config = pdata;
// Store the SSID and Password in the global variables to pass to the Mesh thread
strcpy(sSmartConfigSSID, (char*)wifi_config->sta.ssid);
strcpy(sSmartConfigPassword,(char*)wifi_config->sta.password );
// Notify function that created the Smart config task that we are done
// Switching router config is done in the mesh task as doing it here fails.
ESP_LOGI(HOMEIOT_TAG, "cbOnSmartConfigEvent: Notifying Smart Config has data");
xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
break;
case SC_STATUS_LINK_OVER: // This will never be executed as connection done in mesh thread after this is killed.
ESP_LOGI(HOMEIOT_TAG, "cbOnSmartConfigEvent: SC_STATUS_LINK_OVER");
xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
break;
default:
break;
}
}