diff --git a/examples/single_chip/handpose_estimation_web/main/app_mdns.c b/examples/single_chip/handpose_estimation_web/main/app_mdns.c index 4cdc825..d4c173f 100644 --- a/examples/single_chip/handpose_estimation_web/main/app_mdns.c +++ b/examples/single_chip/handpose_estimation_web/main/app_mdns.c @@ -22,15 +22,18 @@ * */ #include -#include "sdkconfig.h" + #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "esp_log.h" #include "esp_wifi.h" #include "esp_camera.h" +#include "sdkconfig.h" + #include "mdns.h" #include "app_camera.h" +#include "app_wifi.h" static const char *TAG = "camera mdns"; @@ -82,11 +85,11 @@ const char * app_mdns_query(size_t * out_len) *p++ = '['; //add own data first - tcpip_adapter_ip_info_t ip; + esp_netif_ip_info_t ip; if (strlen(CONFIG_ESP_WIFI_SSID)) { - tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip); + esp_netif_get_ip_info(STA_netif, &ip); } else { - tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip); + esp_netif_get_ip_info(AP_netif, &ip); } *p++ = '{'; p += sprintf(p, "\"instance\":\"%s\",", iname); @@ -135,7 +138,7 @@ const char * app_mdns_query(size_t * out_len) } a = r->addr; while(a){ - if(a->addr.type != IPADDR_TYPE_V6){ + if(a->addr.type != ESP_IPADDR_TYPE_V6){ p += sprintf(p, "\"ip\":\"" IPSTR "\",", IP2STR(&(a->addr.u_addr.ip4))); p += sprintf(p, "\"id\":\"" IPSTR ":%u\",", IP2STR(&(a->addr.u_addr.ip4)), r->port); break; 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..3514e09 100644 --- a/examples/single_chip/handpose_estimation_web/main/app_wifi.c +++ b/examples/single_chip/handpose_estimation_web/main/app_wifi.c @@ -20,12 +20,13 @@ * 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" @@ -33,127 +34,210 @@ #include "lwip/err.h" #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; - } - default: - 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); + } + 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 +245,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 diff --git a/examples/single_chip/handpose_estimation_web/main/include/app_wifi.h b/examples/single_chip/handpose_estimation_web/main/include/app_wifi.h index dc164e9..ea4a610 100644 --- a/examples/single_chip/handpose_estimation_web/main/include/app_wifi.h +++ b/examples/single_chip/handpose_estimation_web/main/include/app_wifi.h @@ -24,6 +24,11 @@ #ifndef _APP_WIFI_H_ #define _APP_WIFI_H_ +#include "esp_netif.h" + +extern esp_netif_t *AP_netif; +extern esp_netif_t *STA_netif; + #ifdef __cplusplus extern "C" { #endif @@ -34,4 +39,4 @@ void app_wifi_main(); } #endif -#endif +#endif \ No newline at end of file