Reconnecting - encountering 0x3007 ERR_WIFI_CONN && missing WIFI_EVENT_STA_START during subsequent connections

Nikostpn
Posts: 13
Joined: Mon Jan 25, 2021 5:46 pm

Reconnecting - encountering 0x3007 ERR_WIFI_CONN && missing WIFI_EVENT_STA_START during subsequent connections

Postby Nikostpn » Fri Jan 28, 2022 12:22 am

Hi all,

I'm wondering if there is a graceful way to disconnect from an AP and then reconnect to it. In my code, I use the same event handler and wifi_init_sta, but since I might have to change between APs, I have put out some of the initialization functions in the app main:

Code: Select all

 ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    assert(sta_netif);

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
My wifi_init_sta code is the following:

Code: Select all

void wifi_init_sta(uint8_t *ssid_in)
{
   s_wifi_event_group = xEventGroupCreate();

   esp_err_t error;

    esp_event_handler_instance_t instance_any_id;
    esp_event_handler_instance_t instance_any_ip;
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_ip));

    wifi_config_t wifi_config = {
        .sta = {
            .password = ESP_WIFI_PASS,
	    .threshold.authmode = WIFI_AUTH_WPA2_PSK,
            .pmf_cfg = {
                .capable = true,
                .required = false
            },
        },
    };

    memcpy(wifi_config.sta.ssid, ssid_in, sizeof(wifi_config.sta.ssid));

    ESP_LOGI(TAG, "The ssid passed in is: %s", wifi_config.sta.ssid);

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
    error = (esp_wifi_start());

    ESP_LOGI(TAG, "Error for wifi start is: %X", error);

    while(1)
	{
		/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
		 * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
		EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
				0x0f,
				//WIFI_CONNECTED_BIT | WIFI_FAIL_BIT | WIFI_DISC_BY_APP_BIT |
				//WIFI_WAIT_FOR_IP_BIT,
				pdFALSE,
				pdFALSE,
				5000/portTICK_PERIOD_MS);
				
		if((bits & WIFI_CONNECTED_BIT) != 0)
		{
			ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
					 ssid_in, ESP_WIFI_PASS);
			socket_data_tx = 0;
			ESP_LOGI(TAG, "Socket data while connecting is: %i", socket_data_tx);
			xTaskCreate(wifi_tcp_sta, "tcp_client", 4096, (void *) ssid_in, 5, NULL);
			int i = 0;
			while(socket_data_tx != 1)
			{
				vTaskDelay(1000/portTICK_PERIOD_MS);
				i++;
				if(i > 20)
				{
					ESP_LOGI(TAG, "Socket data not received!");
					break;
				}
			}
			break;
		}
		else if((bits & WIFI_FAIL_BIT) != 0)
		{
			ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s, restarting service",
					 ssid_in, ESP_WIFI_PASS);
			s_retry_num = 0;
			ESP_ERROR_CHECK(esp_wifi_stop());
			break;
		}
		else if((bits & WIFI_DISC_BY_APP_BIT) != 0)
		{
			ESP_LOGI(TAG, "Wifi Disconnected by socket!");
			break;
		}
		else if((bits & WIFI_WAIT_FOR_IP_BIT) != 0)
		{
			ESP_LOGI(TAG, "Waiting on IP connection");
			vTaskDelay(1000/portTICK_PERIOD_MS);
		}
		else
		{
			ESP_LOGE(TAG, "UNEXPECTED EVENT: No bits received, bit is: %x", bits);
			if(s_retry_num < ESP_MAXIMUM_RETRY)
			{
				s_retry_num++;
				if(s_retry_num == ESP_MAXIMUM_RETRY)
				{
					s_retry_num = 0;
					ESP_ERROR_CHECK_WITHOUT_ABORT(esp_wifi_stop());
					break;
				}
			}
		}
	}

    xEventGroupClearBits(s_wifi_event_group, 0x0f);
    									//WIFI_CONNECTED_BIT | WIFI_FAIL_BIT | WIFI_DISC_BY_APP_BIT |
    									//WIFI_WAIT_FOR_IP_BIT);
}
Usually, what happens is that after the first disconnect, the function runs again and does not proceed to receive WIFI_EVENT_STA_START and thus the wait bit function times out. That happens 3 times with "Unexpected Event" handler until the WiFi is stopped with esp_wifi_stop() and then the function is ran again, where it tries to connect and gets a 0x3007 error.

From enabling lwIP debugging, I see that dhcp server restarts often and I lose the IP address of the connection. Could that be the cause? If so, is there a manual way to restart the netif instance when the WiFi is started again? I thought that running esp_wifi_stop() should clear everything out so when I run esp_wifi_start() it should connect to an AP without any problems.

Who is online

Users browsing this forum: Majestic-12 [Bot] and 134 guests