From 04885661ef021d67a361ce8c30d1fb3fe8ba3bbc Mon Sep 17 00:00:00 2001 From: JarmouniA Date: Sun, 26 Sep 2021 17:15:48 +0100 Subject: [PATCH] STA_connexion fixes in all wifi_app.c --- .../camera_web_server/main/app_wifi.c | 127 ++++--- .../detection_with_web/main/app_wifi.c | 291 ++++++++++----- .../face_recognition_solution/main/app_wifi.c | 342 +++++++++++------- .../handpose_estimation_web/main/app_wifi.c | 293 ++++++++++----- 4 files changed, 682 insertions(+), 371 deletions(-) diff --git a/examples/single_chip/camera_web_server/main/app_wifi.c b/examples/single_chip/camera_web_server/main/app_wifi.c index 9804e37..f6fd75a 100644 --- a/examples/single_chip/camera_web_server/main/app_wifi.c +++ b/examples/single_chip/camera_web_server/main/app_wifi.c @@ -19,7 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + #include + #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" @@ -33,19 +35,23 @@ #include "lwip/err.h" #include "lwip/sys.h" +#include "app_wifi.h" + /* The examples use WiFi configuration that you can set via 'make menuconfig'. If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" + the config you want - ie #define ESP_WIFI_SSID "mywifissid" */ -#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID -#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD -#define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY -#define EXAMPLE_ESP_WIFI_AP_SSID CONFIG_ESP_WIFI_AP_SSID -#define EXAMPLE_ESP_WIFI_AP_PASS CONFIG_ESP_WIFI_AP_PASSWORD -#define EXAMPLE_MAX_STA_CONN CONFIG_MAX_STA_CONN -#define EXAMPLE_IP_ADDR CONFIG_SERVER_IP -#define EXAMPLE_ESP_WIFI_AP_CHANNEL CONFIG_ESP_WIFI_AP_CHANNEL + +#define ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID +#define ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD +#define ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY + +#define ESP_WIFI_AP_SSID CONFIG_ESP_WIFI_AP_SSID +#define ESP_WIFI_AP_PASS CONFIG_ESP_WIFI_AP_PASSWORD +#define MAX_STA_CONN CONFIG_MAX_STA_CONN +#define SERVER_IP_ADDR CONFIG_SERVER_IP +#define ESP_WIFI_AP_CHANNEL CONFIG_ESP_WIFI_AP_CHANNEL /* FreeRTOS event group to signal when we are connected*/ static EventGroupHandle_t s_wifi_event_group; @@ -57,11 +63,12 @@ static EventGroupHandle_t s_wifi_event_group; #define WIFI_CONNECTED_BIT BIT0 #define WIFI_FAIL_BIT BIT1 -static const char *TAG = "camera wifi"; +static const char *TAG = "App_Wifi"; static int s_retry_num = 0; -esp_netif_t *AP_netif, *STA_netif; +esp_netif_t *AP_netif; +esp_netif_t *STA_netif; static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) @@ -79,10 +86,10 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base, } if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - esp_wifi_connect(); + ESP_ERROR_CHECK(esp_wifi_connect()); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { - esp_wifi_connect(); + if (s_retry_num < ESP_MAXIMUM_RETRY) { + ESP_ERROR_CHECK(esp_wifi_connect()); s_retry_num++; ESP_LOGI(TAG, "retry to connect to the AP"); } else { @@ -91,13 +98,13 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base, ESP_LOGI(TAG,"connect to the AP fail"); } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; - ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + ESP_LOGI(TAG, "Got IP:" IPSTR, IP2STR(&event->ip_info.ip)); s_retry_num = 0; xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } } -void wifi_init_softap(void) +void wifi_init_softap(wifi_mode_t mode) { /* default event loop from esp_event library */ ESP_ERROR_CHECK(esp_netif_init()); @@ -112,10 +119,10 @@ void wifi_init_softap(void) NULL, NULL)); - if (strcmp(EXAMPLE_IP_ADDR, "192.168.4.1")) + if (strcmp(SERVER_IP_ADDR, "192.168.4.1")) { int a, b, c, d; - sscanf(EXAMPLE_IP_ADDR, "%d.%d.%d.%d", &a, &b, &c, &d); + sscanf(SERVER_IP_ADDR, "%d.%d.%d.%d", &a, &b, &c, &d); esp_netif_ip_info_t ip_info; esp_netif_set_ip4_addr(&ip_info.ip, a, b, c, d); esp_netif_set_ip4_addr(&ip_info.gw, a, b, c, d); @@ -128,32 +135,33 @@ void wifi_init_softap(void) wifi_config_t wifi_config; memset(&wifi_config, 0, sizeof(wifi_config_t)); - snprintf((char*)wifi_config.ap.ssid, 32, "%s", EXAMPLE_ESP_WIFI_AP_SSID); + snprintf((char*)wifi_config.ap.ssid, 32, "%s", ESP_WIFI_AP_SSID); wifi_config.ap.ssid_len = strlen((char*)wifi_config.ap.ssid); - snprintf((char*)wifi_config.ap.password, 64, "%s", EXAMPLE_ESP_WIFI_AP_PASS); + snprintf((char*)wifi_config.ap.password, 64, "%s", ESP_WIFI_AP_PASS); - wifi_config.ap.max_connection = EXAMPLE_MAX_STA_CONN; + wifi_config.ap.max_connection = MAX_STA_CONN; wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK; - if (strlen(EXAMPLE_ESP_WIFI_AP_PASS) == 0) { + if (strlen(ESP_WIFI_AP_PASS) == 0) { wifi_config.ap.authmode = WIFI_AUTH_OPEN; } - if (strlen(EXAMPLE_ESP_WIFI_AP_CHANNEL)) { + if (strlen(ESP_WIFI_AP_CHANNEL)) { int channel; - sscanf(EXAMPLE_ESP_WIFI_AP_CHANNEL, "%d", &channel); + sscanf(ESP_WIFI_AP_CHANNEL, "%d", &channel); wifi_config.ap.channel = channel; } - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + ESP_ERROR_CHECK(esp_wifi_set_mode(mode)); // "esp_wifi_set_config" can be called only when specified interface is enabled, otherwise, API fail ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%s", - EXAMPLE_ESP_WIFI_AP_SSID, EXAMPLE_ESP_WIFI_AP_PASS, EXAMPLE_ESP_WIFI_AP_CHANNEL); + ESP_LOGI(TAG, "wifi_init_softap finished. SSID : %s password : %s channel : %s", + ESP_WIFI_AP_SSID, ESP_WIFI_AP_PASS, ESP_WIFI_AP_CHANNEL); } -void wifi_init_sta(void) +void wifi_init_sta(wifi_mode_t mode) { s_wifi_event_group = xEventGroupCreate(); @@ -165,12 +173,13 @@ void wifi_init_sta(void) assert(STA_netif); esp_event_handler_instance_t instance_any_id; - esp_event_handler_instance_t instance_got_ip; ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, &instance_any_id)); + + esp_event_handler_instance_t instance_got_ip; ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, @@ -179,7 +188,7 @@ void wifi_init_sta(void) wifi_config_t wifi_config = { .sta = { - .threshold.authmode = WIFI_AUTH_WPA_WPA2_PSK, + .threshold.authmode = WIFI_AUTH_WPA2_PSK, .pmf_cfg = { .capable = true, .required = false @@ -187,36 +196,40 @@ void wifi_init_sta(void) }, }; - snprintf((char*)wifi_config.sta.ssid, 32, "%s", EXAMPLE_ESP_WIFI_SSID); - snprintf((char*)wifi_config.sta.password, 64, "%s", EXAMPLE_ESP_WIFI_PASS); + snprintf((char*)wifi_config.sta.ssid, 32, "%s", ESP_WIFI_SSID); + snprintf((char*)wifi_config.sta.password, 64, "%s", ESP_WIFI_PASS); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_mode(mode)); + // "esp_wifi_set_config" can be called only when specified interface is enabled, otherwise, API fail ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(TAG, "wifi_init_sta finished."); + ESP_LOGI(TAG, "wifi_init_STA finished."); - /* 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) */ + // 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, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); - /* xEventGroupWaitBits() returns the bits before the call returned, - * hence we can test which event actually happened. */ + // xEventGroupWaitBits() returns the bits before the call returned, + // hence we can test which event actually happened. if (bits & WIFI_CONNECTED_BIT) { - ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); + wifi_ap_record_t AP_info; + ESP_ERROR_CHECK(esp_wifi_sta_get_ap_info(&AP_info)); + ESP_LOGI(TAG, "connected to AP, SSID : %s Channel : %d Strength : %d Authmode : %d", + AP_info.ssid, AP_info.primary, AP_info.rssi, AP_info.authmode); } else if (bits & WIFI_FAIL_BIT) { - ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); + ESP_LOGI(TAG, "Failed to connect to SSID : %s, password : %s", + ESP_WIFI_SSID, ESP_WIFI_PASS); } else { ESP_LOGE(TAG, "UNEXPECTED EVENT"); } - /* The event will not be processed after unregister */ + // The event will not be processed after unregister ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip)); ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id)); @@ -237,23 +250,27 @@ void app_wifi_main(void) * this can guarantee all the fields got correct value when more fields are added * into wifi_init_config_t in future release. */ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + /* esp_wifi_init API must be called before all other WiFi API can be called */ + ESP_LOGI(TAG, "Initializing ESP Wifi"); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - wifi_mode_t mode = WIFI_MODE_NULL; + wifi_mode_t mode; + mode = WIFI_MODE_NULL; - if (strlen(EXAMPLE_ESP_WIFI_AP_SSID) && strlen(EXAMPLE_ESP_WIFI_SSID)) { + if (strlen(ESP_WIFI_AP_SSID) && strlen(ESP_WIFI_SSID)) { mode = WIFI_MODE_APSTA; - ESP_LOGI(TAG, "WIFI_MODE_APSTA"); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA)); - } else if (strlen(EXAMPLE_ESP_WIFI_AP_SSID)) { + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_APSTA"); + wifi_init_softap(mode); + wifi_init_sta(mode); + } else if (strlen(ESP_WIFI_AP_SSID)) { mode = WIFI_MODE_AP; - ESP_LOGI(TAG, "WIFI_MODE_AP"); - wifi_init_softap(); - } else if (strlen(EXAMPLE_ESP_WIFI_SSID)) { + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_AP"); + wifi_init_softap(mode); + } else if (strlen(ESP_WIFI_SSID)) { mode = WIFI_MODE_STA; - ESP_LOGI(TAG, "WIFI_MODE_STA"); - wifi_init_sta(); + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_STA"); + wifi_init_sta(mode); } if (mode == WIFI_MODE_NULL) { @@ -261,7 +278,5 @@ void app_wifi_main(void) return; } - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); // Set current WiFi power save type. -} +} \ No newline at end of file diff --git a/examples/single_chip/detection_with_web/main/app_wifi.c b/examples/single_chip/detection_with_web/main/app_wifi.c index df65f85..2384eda 100644 --- a/examples/single_chip/detection_with_web/main/app_wifi.c +++ b/examples/single_chip/detection_with_web/main/app_wifi.c @@ -19,13 +19,15 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + #include + #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" #include "sdkconfig.h" @@ -34,126 +36,211 @@ #include "lwip/sys.h" #include "mdns.h" +#include "app_wifi.h" /* The examples use WiFi configuration that you can set via 'make menuconfig'. If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" + the config you want - ie #define ESP_WIFI_SSID "mywifissid" */ -#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID -#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD -#define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY -#define EXAMPLE_ESP_WIFI_AP_SSID CONFIG_ESP_WIFI_AP_SSID -#define EXAMPLE_ESP_WIFI_AP_PASS CONFIG_ESP_WIFI_AP_PASSWORD -#define EXAMPLE_MAX_STA_CONN CONFIG_MAX_STA_CONN -#define EXAMPLE_IP_ADDR CONFIG_SERVER_IP -#define EXAMPLE_ESP_WIFI_AP_CHANNEL CONFIG_ESP_WIFI_AP_CHANNEL -static const char *TAG = "camera wifi"; +#define ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID +#define ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD +#define ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY + +#define ESP_WIFI_AP_SSID CONFIG_ESP_WIFI_AP_SSID +#define ESP_WIFI_AP_PASS CONFIG_ESP_WIFI_AP_PASSWORD +#define MAX_STA_CONN CONFIG_MAX_STA_CONN +#define SERVER_IP_ADDR CONFIG_SERVER_IP +#define ESP_WIFI_AP_CHANNEL CONFIG_ESP_WIFI_AP_CHANNEL + +/* FreeRTOS event group to signal when we are connected*/ +static EventGroupHandle_t s_wifi_event_group; + +/* The event group allows multiple bits for each event, + * For STA events handling, we only care about two events: + * - we are connected to the AP with an IP + * - we failed to connect after the maximum amount of retries */ +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +static const char *TAG = "App_Wifi"; static int s_retry_num = 0; -static esp_err_t event_handler(void *ctx, system_event_t *event) +esp_netif_t *AP_netif; +esp_netif_t *STA_netif; + +static void wifi_event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { - switch(event->event_id) { - case SYSTEM_EVENT_AP_STACONNECTED: - ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d", - MAC2STR(event->event_info.sta_connected.mac), - event->event_info.sta_connected.aid); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED: + if (event_id == WIFI_EVENT_AP_STACONNECTED) { + wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; + ESP_LOGI(TAG, "station: " MACSTR "join, AID=%d", + MAC2STR(event->mac), + event->aid); + } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { + wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; ESP_LOGI(TAG, "station:" MACSTR "leave, AID=%d", - MAC2STR(event->event_info.sta_disconnected.mac), - event->event_info.sta_disconnected.aid); - break; - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "got ip:%s", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - s_retry_num = 0; - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - { - if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { - esp_wifi_connect(); - s_retry_num++; - ESP_LOGI(TAG,"retry to connect to the AP"); - } - ESP_LOGI(TAG,"connect to the AP fail"); - break; + MAC2STR(event->mac), + event->aid); + } + + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + ESP_ERROR_CHECK(esp_wifi_connect()); + } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + if (s_retry_num < ESP_MAXIMUM_RETRY) { + ESP_ERROR_CHECK(esp_wifi_connect()); + s_retry_num++; + ESP_LOGI(TAG, "retry to connect to the AP"); + } else { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); } - default: - break; + ESP_LOGI(TAG,"connect to the AP fail"); + } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + ESP_LOGI(TAG, "Got IP:" IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } mdns_handle_system_event(ctx, event); - return ESP_OK; } -void wifi_init_softap() +void wifi_init_softap(wifi_mode_t mode) { - if (strcmp(EXAMPLE_IP_ADDR, "192.168.4.1")) + /* default event loop from esp_event library */ + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + AP_netif = esp_netif_create_default_wifi_ap(); + assert(AP_netif); + + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &wifi_event_handler, + NULL, + NULL)); + + if (strcmp(SERVER_IP_ADDR, "192.168.4.1")) { int a, b, c, d; - sscanf(EXAMPLE_IP_ADDR, "%d.%d.%d.%d", &a, &b, &c, &d); - tcpip_adapter_ip_info_t ip_info; - IP4_ADDR(&ip_info.ip, a, b, c, d); - IP4_ADDR(&ip_info.gw, a, b, c, d); - IP4_ADDR(&ip_info.netmask, 255, 255, 255, 0); - ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(WIFI_IF_AP)); - ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(WIFI_IF_AP, &ip_info)); - ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(WIFI_IF_AP)); + sscanf(SERVER_IP_ADDR, "%d.%d.%d.%d", &a, &b, &c, &d); + esp_netif_ip_info_t ip_info; + esp_netif_set_ip4_addr(&ip_info.ip, a, b, c, d); + esp_netif_set_ip4_addr(&ip_info.gw, a, b, c, d); + esp_netif_set_ip4_addr(&ip_info.netmask, 255, 255, 255, 0); + ESP_ERROR_CHECK(esp_netif_dhcps_stop(AP_netif)); + ESP_ERROR_CHECK(esp_netif_set_ip_info(AP_netif, &ip_info)); + ESP_ERROR_CHECK(esp_netif_dhcps_start(AP_netif)); } + wifi_config_t wifi_config; memset(&wifi_config, 0, sizeof(wifi_config_t)); - snprintf((char*)wifi_config.ap.ssid, 32, "%s", EXAMPLE_ESP_WIFI_AP_SSID); + + snprintf((char*)wifi_config.ap.ssid, 32, "%s", ESP_WIFI_AP_SSID); wifi_config.ap.ssid_len = strlen((char*)wifi_config.ap.ssid); - snprintf((char*)wifi_config.ap.password, 64, "%s", EXAMPLE_ESP_WIFI_AP_PASS); - wifi_config.ap.max_connection = EXAMPLE_MAX_STA_CONN; + snprintf((char*)wifi_config.ap.password, 64, "%s", ESP_WIFI_AP_PASS); + + wifi_config.ap.max_connection = MAX_STA_CONN; wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK; - if (strlen(EXAMPLE_ESP_WIFI_AP_PASS) == 0) { + + if (strlen(ESP_WIFI_AP_PASS) == 0) { wifi_config.ap.authmode = WIFI_AUTH_OPEN; } - if (strlen(EXAMPLE_ESP_WIFI_AP_CHANNEL)) { + + if (strlen(ESP_WIFI_AP_CHANNEL)) { int channel; - sscanf(EXAMPLE_ESP_WIFI_AP_CHANNEL, "%d", &channel); + sscanf(ESP_WIFI_AP_CHANNEL, "%d", &channel); wifi_config.ap.channel = channel; } - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_set_mode(mode)); + // "esp_wifi_set_config" can be called only when specified interface is enabled, otherwise, API fail + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(TAG, "wifi_init_softap finished.SSID:%s password:%s", - EXAMPLE_ESP_WIFI_AP_SSID, EXAMPLE_ESP_WIFI_AP_PASS); + ESP_LOGI(TAG, "wifi_init_softap finished. SSID : %s password : %s channel : %s", + ESP_WIFI_AP_SSID, ESP_WIFI_AP_PASS, ESP_WIFI_AP_CHANNEL); } -void wifi_init_sta() +void wifi_init_sta(wifi_mode_t mode) { - wifi_config_t wifi_config; - memset(&wifi_config, 0, sizeof(wifi_config_t)); - snprintf((char*)wifi_config.sta.ssid, 32, "%s", EXAMPLE_ESP_WIFI_SSID); - snprintf((char*)wifi_config.sta.password, 64, "%s", EXAMPLE_ESP_WIFI_PASS); + s_wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_netif_init()); - ESP_LOGI(TAG, "wifi_init_sta finished."); - ESP_LOGI(TAG, "connect to ap SSID:%s password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); -} + ESP_ERROR_CHECK(esp_event_loop_create_default()); -void app_wifi_main() -{ - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - wifi_mode_t mode = WIFI_MODE_NULL; + STA_netif = esp_netif_create_default_wifi_sta(); + assert(STA_netif); - if (strlen(EXAMPLE_ESP_WIFI_AP_SSID) && strlen(EXAMPLE_ESP_WIFI_SSID)) { - mode = WIFI_MODE_APSTA; - } else if (strlen(EXAMPLE_ESP_WIFI_AP_SSID)) { - mode = WIFI_MODE_AP; - } else if (strlen(EXAMPLE_ESP_WIFI_SSID)) { - mode = WIFI_MODE_STA; + esp_event_handler_instance_t instance_any_id; + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &wifi_event_handler, + NULL, + &instance_any_id)); + + esp_event_handler_instance_t instance_got_ip; + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &wifi_event_handler, + NULL, + &instance_got_ip)); + + wifi_config_t wifi_config = { + .sta = { + .threshold.authmode = WIFI_AUTH_WPA2_PSK, + .pmf_cfg = { + .capable = true, + .required = false + }, + }, + }; + + snprintf((char*)wifi_config.sta.ssid, 32, "%s", ESP_WIFI_SSID); + snprintf((char*)wifi_config.sta.password, 64, "%s", ESP_WIFI_PASS); + + ESP_ERROR_CHECK(esp_wifi_set_mode(mode)); + // "esp_wifi_set_config" can be called only when specified interface is enabled, otherwise, API fail + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_wifi_start()); + + ESP_LOGI(TAG, "wifi_init_STA finished."); + + // 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, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + // xEventGroupWaitBits() returns the bits before the call returned, + // hence we can test which event actually happened. + + if (bits & WIFI_CONNECTED_BIT) { + wifi_ap_record_t AP_info; + ESP_ERROR_CHECK(esp_wifi_sta_get_ap_info(&AP_info)); + ESP_LOGI(TAG, "connected to AP, SSID : %s Channel : %d Strength : %d Authmode : %d", + AP_info.ssid, AP_info.primary, AP_info.rssi, AP_info.authmode); + } else if (bits & WIFI_FAIL_BIT) { + ESP_LOGI(TAG, "Failed to connect to SSID : %s, password : %s", + ESP_WIFI_SSID, ESP_WIFI_PASS); + } else { + ESP_LOGE(TAG, "UNEXPECTED EVENT"); } + // The event will not be processed after unregister + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip)); + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id)); + + vEventGroupDelete(s_wifi_event_group); +} + +void app_wifi_main(void) +{ + //Initialize NVS esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); @@ -161,23 +248,37 @@ void app_wifi_main() } ESP_ERROR_CHECK(ret); + /* Always use WIFI_INIT_CONFIG_DEFAULT macro to init the config to default values, + * this can guarantee all the fields got correct value when more fields are added + * into wifi_init_config_t in future release. */ + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + + /* esp_wifi_init API must be called before all other WiFi API can be called */ + ESP_LOGI(TAG, "Initializing ESP Wifi"); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + wifi_mode_t mode; + mode = WIFI_MODE_NULL; + + if (strlen(ESP_WIFI_AP_SSID) && strlen(ESP_WIFI_SSID)) { + mode = WIFI_MODE_APSTA; + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_APSTA"); + wifi_init_softap(mode); + wifi_init_sta(mode); + } else if (strlen(ESP_WIFI_AP_SSID)) { + mode = WIFI_MODE_AP; + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_AP"); + wifi_init_softap(mode); + } else if (strlen(ESP_WIFI_SSID)) { + mode = WIFI_MODE_STA; + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_STA"); + wifi_init_sta(mode); + } + if (mode == WIFI_MODE_NULL) { ESP_LOGW(TAG,"Neither AP or STA have been configured. WiFi will be off."); return; } - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_mode(mode)); - - if (mode & WIFI_MODE_AP) { - wifi_init_softap(); - } - - if (mode & WIFI_MODE_STA) { - wifi_init_sta(); - } - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); + ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); // Set current WiFi power save type. } diff --git a/examples/single_chip/face_recognition_solution/main/app_wifi.c b/examples/single_chip/face_recognition_solution/main/app_wifi.c index 58b4d1a..cc68300 100644 --- a/examples/single_chip/face_recognition_solution/main/app_wifi.c +++ b/examples/single_chip/face_recognition_solution/main/app_wifi.c @@ -19,170 +19,264 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + #include + #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" #include "sdkconfig.h" #include "lwip/err.h" #include "lwip/sys.h" + #include "app_wifi.h" -static const char *TAG = "app_wifi"; +/* The examples use WiFi configuration that you can set via 'make menuconfig'. -#define EXAMPLE_ESP_WIFI_MODE_AP 1 //TRUE:AP FALSE:STA -#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID -#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD -#define EXAMPLE_MAX_STA_CONN CONFIG_MAX_STA_CONN -#define EXAMPLE_IP_ADDR CONFIG_SERVER_IP -#define EXAMPLE_ESP_WIFI_AP_CHANNEL CONFIG_ESP_WIFI_AP_CHANNEL + If you'd rather not, just change the below entries to strings with + the config you want - ie #define ESP_WIFI_SSID "mywifissid" +*/ -static esp_err_t event_handler(void *ctx, system_event_t *event) -{/*{{{*/ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "got ip:%s", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - break; - case SYSTEM_EVENT_AP_STACONNECTED: - ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d", - MAC2STR(event->event_info.sta_connected.mac), - event->event_info.sta_connected.aid); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED: - ESP_LOGI(TAG, "station:" MACSTR " leave, AID=%d", - MAC2STR(event->event_info.sta_disconnected.mac), - event->event_info.sta_disconnected.aid); +#define ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID +#define ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD +#define ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - break; - default: - break; - } - return ESP_OK; -}/*}}}*/ +#define ESP_WIFI_AP_SSID CONFIG_ESP_WIFI_AP_SSID +#define ESP_WIFI_AP_PASS CONFIG_ESP_WIFI_AP_PASSWORD +#define MAX_STA_CONN CONFIG_MAX_STA_CONN +#define SERVER_IP_ADDR CONFIG_SERVER_IP +#define ESP_WIFI_AP_CHANNEL CONFIG_ESP_WIFI_AP_CHANNEL -#if EXAMPLE_ESP_WIFI_MODE_AP -static void wifi_init_softap() +/* FreeRTOS event group to signal when we are connected*/ +static EventGroupHandle_t s_wifi_event_group; + +/* The event group allows multiple bits for each event, + * For STA events handling, we only care about two events: + * - we are connected to the AP with an IP + * - we failed to connect after the maximum amount of retries */ +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +static const char *TAG = "App_Wifi"; + +static int s_retry_num = 0; + +esp_netif_t *AP_netif; +esp_netif_t *STA_netif; + +static void wifi_event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { - tcpip_adapter_init(); + if (event_id == WIFI_EVENT_AP_STACONNECTED) { + wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; + ESP_LOGI(TAG, "station: " MACSTR "join, AID=%d", + MAC2STR(event->mac), + event->aid); + } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { + wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; + ESP_LOGI(TAG, "station:" MACSTR "leave, AID=%d", + MAC2STR(event->mac), + event->aid); + } - if (strcmp(EXAMPLE_IP_ADDR, "192.168.4.1")) + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + ESP_ERROR_CHECK(esp_wifi_connect()); + } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + if (s_retry_num < ESP_MAXIMUM_RETRY) { + ESP_ERROR_CHECK(esp_wifi_connect()); + s_retry_num++; + ESP_LOGI(TAG, "retry to connect to the AP"); + } else { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + ESP_LOGI(TAG,"connect to the AP fail"); + } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + ESP_LOGI(TAG, "Got IP:" IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } +} + +void wifi_init_softap(wifi_mode_t mode) +{ + /* default event loop from esp_event library */ + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + AP_netif = esp_netif_create_default_wifi_ap(); + assert(AP_netif); + + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &wifi_event_handler, + NULL, + NULL)); + + if (strcmp(SERVER_IP_ADDR, "192.168.4.1")) { int a, b, c, d; - sscanf(EXAMPLE_IP_ADDR, "%d.%d.%d.%d", &a, &b, &c, &d); - tcpip_adapter_ip_info_t ip_info; - IP4_ADDR(&ip_info.ip, a, b, c, d); - IP4_ADDR(&ip_info.gw, a, b, c, d); - IP4_ADDR(&ip_info.netmask, 255, 255, 255, 0); - ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(WIFI_IF_AP)); - ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(WIFI_IF_AP, &ip_info)); - ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(WIFI_IF_AP)); + sscanf(SERVER_IP_ADDR, "%d.%d.%d.%d", &a, &b, &c, &d); + esp_netif_ip_info_t ip_info; + esp_netif_set_ip4_addr(&ip_info.ip, a, b, c, d); + esp_netif_set_ip4_addr(&ip_info.gw, a, b, c, d); + esp_netif_set_ip4_addr(&ip_info.netmask, 255, 255, 255, 0); + ESP_ERROR_CHECK(esp_netif_dhcps_stop(AP_netif)); + ESP_ERROR_CHECK(esp_netif_set_ip_info(AP_netif, &ip_info)); + ESP_ERROR_CHECK(esp_netif_dhcps_start(AP_netif)); } - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - - uint8_t mac[6]; - ESP_ERROR_CHECK(esp_wifi_get_mac(ESP_IF_WIFI_AP, mac)); - wifi_config_t wifi_config; memset(&wifi_config, 0, sizeof(wifi_config_t)); - if (strlen(EXAMPLE_ESP_WIFI_SSID) == 0) - { - snprintf((char *)wifi_config.ap.ssid, 32, "esp-eye-%x%x", mac[4], mac[5]); - } - else - { - memcpy(wifi_config.ap.ssid, EXAMPLE_ESP_WIFI_SSID, sizeof(EXAMPLE_ESP_WIFI_SSID)); - } - memcpy(wifi_config.ap.password, EXAMPLE_ESP_WIFI_PASS, sizeof(EXAMPLE_ESP_WIFI_PASS)); - wifi_config.ap.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID); - wifi_config.ap.max_connection = EXAMPLE_MAX_STA_CONN; + + snprintf((char*)wifi_config.ap.ssid, 32, "%s", ESP_WIFI_AP_SSID); + wifi_config.ap.ssid_len = strlen((char*)wifi_config.ap.ssid); + snprintf((char*)wifi_config.ap.password, 64, "%s", ESP_WIFI_AP_PASS); + + wifi_config.ap.max_connection = MAX_STA_CONN; wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK; - if (strlen(EXAMPLE_ESP_WIFI_AP_CHANNEL)) { - int channel; - sscanf(EXAMPLE_ESP_WIFI_AP_CHANNEL, "%d", &channel); - wifi_config.ap.channel = channel; - } - if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) { + + if (strlen(ESP_WIFI_AP_PASS) == 0) { wifi_config.ap.authmode = WIFI_AUTH_OPEN; } - - esp_wifi_set_ps(WIFI_PS_NONE); - 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_init_softap finished.SSID:%s password:%s", - wifi_config.ap.ssid, EXAMPLE_ESP_WIFI_PASS); - - char buf[80]; - sprintf(buf, "SSID:%s", wifi_config.ap.ssid); - sprintf(buf, "PASSWORD:%s", wifi_config.ap.password); - -} - -#else - -static void wifi_init_sta() -{ - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - - wifi_config_t wifi_config = {0}; - memset(&wifi_config, 0, sizeof(wifi_config_t)); - memcpy(wifi_config.sta.ssid, EXAMPLE_ESP_WIFI_SSID, sizeof(EXAMPLE_ESP_WIFI_SSID)); - memcpy(wifi_config.sta.password, EXAMPLE_ESP_WIFI_PASS, sizeof(EXAMPLE_ESP_WIFI_PASS)); - - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - - ESP_ERROR_CHECK(esp_wifi_start()); - - ESP_LOGI(TAG, "connect to ap SSID:%s password:%s", wifi_config.sta.ssid, wifi_config.sta.password); - char buf[80]; - sprintf(buf, "SSID:%s", wifi_config.sta.ssid); - sprintf(buf, "PASSWORD:%s", wifi_config.sta.password); + if (strlen(ESP_WIFI_AP_CHANNEL)) { + int channel; + sscanf(ESP_WIFI_AP_CHANNEL, "%d", &channel); + wifi_config.ap.channel = channel; + } + ESP_ERROR_CHECK(esp_wifi_set_mode(mode)); + // "esp_wifi_set_config" can be called only when specified interface is enabled, otherwise, API fail + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + + ESP_LOGI(TAG, "wifi_init_softap finished. SSID : %s password : %s channel : %s", + ESP_WIFI_AP_SSID, ESP_WIFI_AP_PASS, ESP_WIFI_AP_CHANNEL); } -#endif -void app_wifi_init () +void wifi_init_sta(wifi_mode_t mode) +{ + s_wifi_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_netif_init()); + + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + STA_netif = esp_netif_create_default_wifi_sta(); + assert(STA_netif); + + esp_event_handler_instance_t instance_any_id; + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &wifi_event_handler, + NULL, + &instance_any_id)); + + esp_event_handler_instance_t instance_got_ip; + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &wifi_event_handler, + NULL, + &instance_got_ip)); + + wifi_config_t wifi_config = { + .sta = { + .threshold.authmode = WIFI_AUTH_WPA2_PSK, + .pmf_cfg = { + .capable = true, + .required = false + }, + }, + }; + + snprintf((char*)wifi_config.sta.ssid, 32, "%s", ESP_WIFI_SSID); + snprintf((char*)wifi_config.sta.password, 64, "%s", ESP_WIFI_PASS); + + ESP_ERROR_CHECK(esp_wifi_set_mode(mode)); + // "esp_wifi_set_config" can be called only when specified interface is enabled, otherwise, API fail + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_wifi_start()); + + ESP_LOGI(TAG, "wifi_init_STA finished."); + + // 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, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + // xEventGroupWaitBits() returns the bits before the call returned, + // hence we can test which event actually happened. + + if (bits & WIFI_CONNECTED_BIT) { + wifi_ap_record_t AP_info; + ESP_ERROR_CHECK(esp_wifi_sta_get_ap_info(&AP_info)); + ESP_LOGI(TAG, "connected to AP, SSID : %s Channel : %d Strength : %d Authmode : %d", + AP_info.ssid, AP_info.primary, AP_info.rssi, AP_info.authmode); + } else if (bits & WIFI_FAIL_BIT) { + ESP_LOGI(TAG, "Failed to connect to SSID : %s, password : %s", + ESP_WIFI_SSID, ESP_WIFI_PASS); + } else { + ESP_LOGE(TAG, "UNEXPECTED EVENT"); + } + + // The event will not be processed after unregister + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip)); + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id)); + + vEventGroupDelete(s_wifi_event_group); +} + +void app_wifi_main(void) { //Initialize NVS esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); + + /* Always use WIFI_INIT_CONFIG_DEFAULT macro to init the config to default values, + * this can guarantee all the fields got correct value when more fields are added + * into wifi_init_config_t in future release. */ + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + + /* esp_wifi_init API must be called before all other WiFi API can be called */ + ESP_LOGI(TAG, "Initializing ESP Wifi"); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); -#if EXAMPLE_ESP_WIFI_MODE_AP - ESP_LOGI(TAG, "ESP_WIFI_MODE_AP"); - wifi_init_softap(); -#else - ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); - wifi_init_sta(); -#endif /*EXAMPLE_ESP_WIFI_MODE_AP*/ + wifi_mode_t mode; + mode = WIFI_MODE_NULL; + if (strlen(ESP_WIFI_AP_SSID) && strlen(ESP_WIFI_SSID)) { + mode = WIFI_MODE_APSTA; + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_APSTA"); + wifi_init_softap(mode); + wifi_init_sta(mode); + } else if (strlen(ESP_WIFI_AP_SSID)) { + mode = WIFI_MODE_AP; + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_AP"); + wifi_init_softap(mode); + } else if (strlen(ESP_WIFI_SSID)) { + mode = WIFI_MODE_STA; + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_STA"); + wifi_init_sta(mode); + } + + if (mode == WIFI_MODE_NULL) { + ESP_LOGW(TAG,"Neither AP or STA have been configured. WiFi will be off."); + return; + } + + ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); // Set current WiFi power save type. } - diff --git a/examples/single_chip/handpose_estimation_web/main/app_wifi.c b/examples/single_chip/handpose_estimation_web/main/app_wifi.c index df65f85..c743782 100644 --- a/examples/single_chip/handpose_estimation_web/main/app_wifi.c +++ b/examples/single_chip/handpose_estimation_web/main/app_wifi.c @@ -19,13 +19,15 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + #include + #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" #include "sdkconfig.h" @@ -34,126 +36,211 @@ #include "lwip/sys.h" #include "mdns.h" +#include "app_wifi.h" /* The examples use WiFi configuration that you can set via 'make menuconfig'. If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" + the config you want - ie #define ESP_WIFI_SSID "mywifissid" */ -#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID -#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD -#define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY -#define EXAMPLE_ESP_WIFI_AP_SSID CONFIG_ESP_WIFI_AP_SSID -#define EXAMPLE_ESP_WIFI_AP_PASS CONFIG_ESP_WIFI_AP_PASSWORD -#define EXAMPLE_MAX_STA_CONN CONFIG_MAX_STA_CONN -#define EXAMPLE_IP_ADDR CONFIG_SERVER_IP -#define EXAMPLE_ESP_WIFI_AP_CHANNEL CONFIG_ESP_WIFI_AP_CHANNEL -static const char *TAG = "camera wifi"; +#define ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID +#define ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD +#define ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY + +#define ESP_WIFI_AP_SSID CONFIG_ESP_WIFI_AP_SSID +#define ESP_WIFI_AP_PASS CONFIG_ESP_WIFI_AP_PASSWORD +#define MAX_STA_CONN CONFIG_MAX_STA_CONN +#define SERVER_IP_ADDR CONFIG_SERVER_IP +#define ESP_WIFI_AP_CHANNEL CONFIG_ESP_WIFI_AP_CHANNEL + +/* FreeRTOS event group to signal when we are connected*/ +static EventGroupHandle_t s_wifi_event_group; + +/* The event group allows multiple bits for each event, + * For STA events handling, we only care about two events: + * - we are connected to the AP with an IP + * - we failed to connect after the maximum amount of retries */ +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +static const char *TAG = "App_Wifi"; static int s_retry_num = 0; -static esp_err_t event_handler(void *ctx, system_event_t *event) +esp_netif_t *AP_netif; +esp_netif_t *STA_netif; + +static void wifi_event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { - switch(event->event_id) { - case SYSTEM_EVENT_AP_STACONNECTED: - ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d", - MAC2STR(event->event_info.sta_connected.mac), - event->event_info.sta_connected.aid); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED: + if (event_id == WIFI_EVENT_AP_STACONNECTED) { + wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; + ESP_LOGI(TAG, "station: " MACSTR "join, AID=%d", + MAC2STR(event->mac), + event->aid); + } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { + wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; ESP_LOGI(TAG, "station:" MACSTR "leave, AID=%d", - MAC2STR(event->event_info.sta_disconnected.mac), - event->event_info.sta_disconnected.aid); - break; - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "got ip:%s", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - s_retry_num = 0; - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - { - if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { - esp_wifi_connect(); - s_retry_num++; - ESP_LOGI(TAG,"retry to connect to the AP"); - } - ESP_LOGI(TAG,"connect to the AP fail"); - break; + MAC2STR(event->mac), + event->aid); + } + + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + ESP_ERROR_CHECK(esp_wifi_connect()); + } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + if (s_retry_num < ESP_MAXIMUM_RETRY) { + ESP_ERROR_CHECK(esp_wifi_connect()); + s_retry_num++; + ESP_LOGI(TAG, "retry to connect to the AP"); + } else { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); } - default: - break; + ESP_LOGI(TAG,"connect to the AP fail"); + } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + ESP_LOGI(TAG, "Got IP:" IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } mdns_handle_system_event(ctx, event); - return ESP_OK; } -void wifi_init_softap() +void wifi_init_softap(wifi_mode_t mode) { - if (strcmp(EXAMPLE_IP_ADDR, "192.168.4.1")) + /* default event loop from esp_event library */ + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + AP_netif = esp_netif_create_default_wifi_ap(); + assert(AP_netif); + + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &wifi_event_handler, + NULL, + NULL)); + + if (strcmp(SERVER_IP_ADDR, "192.168.4.1")) { int a, b, c, d; - sscanf(EXAMPLE_IP_ADDR, "%d.%d.%d.%d", &a, &b, &c, &d); - tcpip_adapter_ip_info_t ip_info; - IP4_ADDR(&ip_info.ip, a, b, c, d); - IP4_ADDR(&ip_info.gw, a, b, c, d); - IP4_ADDR(&ip_info.netmask, 255, 255, 255, 0); - ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(WIFI_IF_AP)); - ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(WIFI_IF_AP, &ip_info)); - ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(WIFI_IF_AP)); + sscanf(SERVER_IP_ADDR, "%d.%d.%d.%d", &a, &b, &c, &d); + esp_netif_ip_info_t ip_info; + esp_netif_set_ip4_addr(&ip_info.ip, a, b, c, d); + esp_netif_set_ip4_addr(&ip_info.gw, a, b, c, d); + esp_netif_set_ip4_addr(&ip_info.netmask, 255, 255, 255, 0); + ESP_ERROR_CHECK(esp_netif_dhcps_stop(AP_netif)); + ESP_ERROR_CHECK(esp_netif_set_ip_info(AP_netif, &ip_info)); + ESP_ERROR_CHECK(esp_netif_dhcps_start(AP_netif)); } + wifi_config_t wifi_config; memset(&wifi_config, 0, sizeof(wifi_config_t)); - snprintf((char*)wifi_config.ap.ssid, 32, "%s", EXAMPLE_ESP_WIFI_AP_SSID); + + snprintf((char*)wifi_config.ap.ssid, 32, "%s", ESP_WIFI_AP_SSID); wifi_config.ap.ssid_len = strlen((char*)wifi_config.ap.ssid); - snprintf((char*)wifi_config.ap.password, 64, "%s", EXAMPLE_ESP_WIFI_AP_PASS); - wifi_config.ap.max_connection = EXAMPLE_MAX_STA_CONN; + snprintf((char*)wifi_config.ap.password, 64, "%s", ESP_WIFI_AP_PASS); + + wifi_config.ap.max_connection = MAX_STA_CONN; wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK; - if (strlen(EXAMPLE_ESP_WIFI_AP_PASS) == 0) { + + if (strlen(ESP_WIFI_AP_PASS) == 0) { wifi_config.ap.authmode = WIFI_AUTH_OPEN; } - if (strlen(EXAMPLE_ESP_WIFI_AP_CHANNEL)) { + + if (strlen(ESP_WIFI_AP_CHANNEL)) { int channel; - sscanf(EXAMPLE_ESP_WIFI_AP_CHANNEL, "%d", &channel); + sscanf(ESP_WIFI_AP_CHANNEL, "%d", &channel); wifi_config.ap.channel = channel; } - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_set_mode(mode)); + // "esp_wifi_set_config" can be called only when specified interface is enabled, otherwise, API fail + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(TAG, "wifi_init_softap finished.SSID:%s password:%s", - EXAMPLE_ESP_WIFI_AP_SSID, EXAMPLE_ESP_WIFI_AP_PASS); + ESP_LOGI(TAG, "wifi_init_softap finished. SSID : %s password : %s channel : %s", + ESP_WIFI_AP_SSID, ESP_WIFI_AP_PASS, ESP_WIFI_AP_CHANNEL); } -void wifi_init_sta() +void wifi_init_sta(wifi_mode_t mode) { - wifi_config_t wifi_config; - memset(&wifi_config, 0, sizeof(wifi_config_t)); - snprintf((char*)wifi_config.sta.ssid, 32, "%s", EXAMPLE_ESP_WIFI_SSID); - snprintf((char*)wifi_config.sta.password, 64, "%s", EXAMPLE_ESP_WIFI_PASS); + s_wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_netif_init()); - ESP_LOGI(TAG, "wifi_init_sta finished."); - ESP_LOGI(TAG, "connect to ap SSID:%s password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); -} + ESP_ERROR_CHECK(esp_event_loop_create_default()); -void app_wifi_main() -{ - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - wifi_mode_t mode = WIFI_MODE_NULL; + STA_netif = esp_netif_create_default_wifi_sta(); + assert(STA_netif); - if (strlen(EXAMPLE_ESP_WIFI_AP_SSID) && strlen(EXAMPLE_ESP_WIFI_SSID)) { - mode = WIFI_MODE_APSTA; - } else if (strlen(EXAMPLE_ESP_WIFI_AP_SSID)) { - mode = WIFI_MODE_AP; - } else if (strlen(EXAMPLE_ESP_WIFI_SSID)) { - mode = WIFI_MODE_STA; + esp_event_handler_instance_t instance_any_id; + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &wifi_event_handler, + NULL, + &instance_any_id)); + + esp_event_handler_instance_t instance_got_ip; + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &wifi_event_handler, + NULL, + &instance_got_ip)); + + wifi_config_t wifi_config = { + .sta = { + .threshold.authmode = WIFI_AUTH_WPA2_PSK, + .pmf_cfg = { + .capable = true, + .required = false + }, + }, + }; + + snprintf((char*)wifi_config.sta.ssid, 32, "%s", ESP_WIFI_SSID); + snprintf((char*)wifi_config.sta.password, 64, "%s", ESP_WIFI_PASS); + + ESP_ERROR_CHECK(esp_wifi_set_mode(mode)); + // "esp_wifi_set_config" can be called only when specified interface is enabled, otherwise, API fail + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_wifi_start()); + + ESP_LOGI(TAG, "wifi_init_STA finished."); + + // 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, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + // xEventGroupWaitBits() returns the bits before the call returned, + // hence we can test which event actually happened. + + if (bits & WIFI_CONNECTED_BIT) { + wifi_ap_record_t AP_info; + ESP_ERROR_CHECK(esp_wifi_sta_get_ap_info(&AP_info)); + ESP_LOGI(TAG, "connected to AP, SSID : %s Channel : %d Strength : %d Authmode : %d", + AP_info.ssid, AP_info.primary, AP_info.rssi, AP_info.authmode); + } else if (bits & WIFI_FAIL_BIT) { + ESP_LOGI(TAG, "Failed to connect to SSID : %s, password : %s", + ESP_WIFI_SSID, ESP_WIFI_PASS); + } else { + ESP_LOGE(TAG, "UNEXPECTED EVENT"); } + // The event will not be processed after unregister + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip)); + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id)); + + vEventGroupDelete(s_wifi_event_group); +} + +void app_wifi_main(void) +{ + //Initialize NVS esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); @@ -161,23 +248,37 @@ void app_wifi_main() } ESP_ERROR_CHECK(ret); + /* Always use WIFI_INIT_CONFIG_DEFAULT macro to init the config to default values, + * this can guarantee all the fields got correct value when more fields are added + * into wifi_init_config_t in future release. */ + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + + /* esp_wifi_init API must be called before all other WiFi API can be called */ + ESP_LOGI(TAG, "Initializing ESP Wifi"); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + wifi_mode_t mode; + mode = WIFI_MODE_NULL; + + if (strlen(ESP_WIFI_AP_SSID) && strlen(ESP_WIFI_SSID)) { + mode = WIFI_MODE_APSTA; + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_APSTA"); + wifi_init_softap(mode); + wifi_init_sta(mode); + } else if (strlen(ESP_WIFI_AP_SSID)) { + mode = WIFI_MODE_AP; + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_AP"); + wifi_init_softap(mode); + } else if (strlen(ESP_WIFI_SSID)) { + mode = WIFI_MODE_STA; + ESP_LOGI(TAG, "Wifi mode is set to WIFI_MODE_STA"); + wifi_init_sta(mode); + } + if (mode == WIFI_MODE_NULL) { ESP_LOGW(TAG,"Neither AP or STA have been configured. WiFi will be off."); return; } - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_mode(mode)); - - if (mode & WIFI_MODE_AP) { - wifi_init_softap(); - } - - if (mode & WIFI_MODE_STA) { - wifi_init_sta(); - } - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); -} + ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); // Set current WiFi power save type. +} \ No newline at end of file