acp_
acp_

Reputation: 31

ESP-IDF wifi event loop keeps receiving SYSTEM_EVENT_STA_WPS_ER_PIN even after code rollback

I have been working on a project using the ESP32 with the ESP-IDF that will check it's NVS memory for wifi credentials before starting the network stack. If it has said credentials, it will connect to the wifi network in STA mode, if it lacks them, it will launch as it's own AP to allow the user to send it the credentials over HTTP.

After manually putting my test credentials into NVS, I started working on the AP code. Once all the AP code and logic was complete, I manually wiped the flash memory with esptool to force the board to launch in that mode. Doing so worked fine, and I was able to send it the updated credentials over HTTP.

At this point, the board attempted to connect as STA upon reset, however, the SYSTEM_EVENT_STA_WPS_ER_PIN event kept being caught by the wifi event loop. The board has since only experienced this event and has been completely unable to connect to wifi since. To make matters stranger, even after rolling back to a previous version with git, the problem still persists.

main.c

void app_main() {

    // Start NVS
    initNVS();
    // Init Wifi Controller
    initWifiController();
    // Get Credentials to send to wifi
    Creds creds = getCreds();
    // Start wifi in STA mode with gathered creds
    beginWifi(creds);

    initializePins();
    initializeTimers();
}

wifiController.c

void initWifiController(){
    // * NVS must be initialized before wifi work can be done
    // Handle when connected to the network
    connectionSemaphore = xSemaphoreCreateBinary();
    // Begin network stack
    ESP_ERROR_CHECK(esp_netif_init());
    // Create event loop for handling callbacks
    ESP_ERROR_CHECK(esp_event_loop_create_default());
}

void beginWifi(Creds creds){
    if(creds.status == ESP_OK){
        ESP_LOGI(TAG, "Connection credentials have been found, connecting to network");
        connectSTA(creds);
    }
    else if(creds.status == ESP_ERR_NVS_NOT_FOUND){
        ESP_LOGW(TAG, "Missing credentials, starting as AP");
        connectAP();
    }
    else{
        ESP_LOGE(TAG, "ESP failed with error %s, not starting wifi", esp_err_to_name(creds.status));
    }

void connectSTA(Creds creds){
    
    ESP_LOGI(TAG, "Attempting to connect to wifi with following creds: %s | %s", creds.ssid, creds.pass);
    // Set netif to sta
    esp_netif_create_default_wifi_sta();

    // Prepare and initialize wifi_init_config_t
    wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));

    // Register tracked events for event_handler
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, event_handler, NULL));

    // TODO: Check if this can be used to avoid havng to use NVS manually
    esp_wifi_set_storage(WIFI_STORAGE_RAM);

    // Config struct for wifi details
    wifi_config_t wifi_config = {};

    // Copy casted info into wifi_config
    // * https://www.esp32.com/viewtopic.php?f=13&t=14611
    // * See above link for details on this
    strcpy((char *)wifi_config.sta.ssid, creds.ssid);
    strcpy((char *)wifi_config.sta.password, creds.pass);

    esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);

    ESP_ERROR_CHECK(esp_wifi_start());

    // ? Is this required to avoid a memory leak?
    free(creds.pass);
    free(creds.ssid);
}
void connectAP(){
    // ? How important is it that these be called in this order?
    ESP_LOGI(TAG, "Starting in AP Mode");
    esp_netif_create_default_wifi_ap();
    // TODO: maybe move this creation to initWifiController to avoid making it twice
    wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));
    
    // TODO: Consider moving this to init Wifi Controller to avoid running it twice as well
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));

    // Configuration for AP
    wifi_config_t wifi_config = {
        .ap = {
            .ssid = "Grow System",
            .password = "Password",
            .ssid_len = strlen("Grow System"),
            .max_connection = 4,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK
        }
    };

    // TODO: Enable password support on AP configuration

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI(TAG, "Wifi connectAP finished");
    registerEndPoints();
}

The code essentially checks NVS for the credentials, if it finds them both it returns a struct containing both of them as well as ESP_OK. If one of them was not found, the struct instead contains ESP_ERR_NVS_NOT_FOUND. wifiController.c then receives this creds struct and calls beginWifi() which then either calls connectSTA() or connectAP() based on the status of the struct. When the credentials are present, connectSTA() is called, but for unknown reasons the event loop consistently only receives the SYSTEM_EVENT_STA_WPS_ER_PIN event. As I mentioned earlier, even after rolling my code back to a version that did not have the connectAP() function, this behavior persists.

Because of this, I have a hunch that the issue may be related to when I wiped the flash manually, as opposed to the code.

The header file contains the following line in it's typedef to define this event.

SYSTEM_EVENT_STA_WPS_ER_PIN,           /*!< ESP32 station wps pin code in enrollee mode */

I do not know what that means, as I have not intentionally included anything regarding wps in this project.

So far my research hasn't returned anything incredibly useful, so if anyone has any ideas what SYSTEM_EVENT_STA_WPS_ER_PIN is or what could be causing my issue, I would be very appreciative. If you think that anymore detail would be useful to solve this issue, please let me know and I will be more than happy to provide it.

Upvotes: 2

Views: 2119

Answers (2)

acp_
acp_

Reputation: 31

I have been digging into this issue for several days now and I have not found the root cause but have managed to discovery a workaround and some details about the issue. the SYSTEM_EVENT_STA_WPS_ER_PIN event that kept arising actually is caused by the chip trying to use WPS Enrolle Pin mode to connect to the router. Supposedly this generates an eight digit long pin that can be put into your router which should allow it to connect. I really do not know why it was doing this, but I believe it may have had something to do with how I had AP mode set up. My primary confusion now is why rolling back the code did not fix it.

For the "workaround" I found that flashing Espressif's example STA wifi connection code managed to solve it. The chip properly connected to my network once it was flashed, and I was able to reflash my own code without any issues arriving. This seems extremely strange to me, so part of me thinks that maybe the chip just couldn't connect to my network for some reason and an edge case in the code caused it to go into enrollee mode.

Here is a link to the code that I used to "fix" the issue: https://github.com/espressif/esp-idf/blob/master/examples/wifi/getting_started/station/main/station_example_main.c

I will mark this answer as correct and continue looking for the root problem. In the event that someone else know what actually could have caused this, feel free to post and I will update the correct answer. In the event that I find what the root problem is, I will update this answer as well.

EDIT: After continuing to dig, I believe that the problem was actually do to a multitude of errors in my code. Particularly, I was calling esp_netif_create_default_wifi_sta() and then not setting the WI-FI mode. I needed to add esp_wifi_set_mode(WIFI_MODE_STA), which was absent in my program. I believe setting the network stack to sta without changing the wifi mode was what caused my issue.

Upvotes: 0

Garc964
Garc964

Reputation: 11

Useful to solve the problem. I'm in the proces of learning to use the ESP32 wifi, read your message checked, the ESP-idf and esp-32 technical manual not much info there I found this URI https://www.wi-fi.org/downloads-public/Wi-Fi_Protected_Setup_Best_Practices_v2.0.2.pdf/8188

Kind regards

Update: check the sdkconfig file in your projectmap against the one in the example map for wifi config settings.

Upvotes: 1

Related Questions