From 25df447e3118ab09cf53a67800f6758741560a11 Mon Sep 17 00:00:00 2001 From: FalconCode-Ux Date: Tue, 27 Jul 2021 03:16:26 +0100 Subject: [PATCH] Example "camera_web_server" updated to be compatible with ESP-IDF v4.2.1-dirty Updated "app_wifi" to be compatible with both "esp_event" library and "ESP-NETIF" library. Updated "app_mdns" to be compatible with "esp_event" library. Tested the program successfully on the ESP-AI-Thinker with the OV2640 camera. --- .../camera_web_server/main/app_mdns.c | 11 +- .../camera_web_server/main/app_wifi.c | 238 ++++++++++++------ .../camera_web_server/main/include/app_mdns.h | 2 +- .../camera_web_server/main/include/app_wifi.h | 7 +- 4 files changed, 174 insertions(+), 84 deletions(-) diff --git a/examples/single_chip/camera_web_server/main/app_mdns.c b/examples/single_chip/camera_web_server/main/app_mdns.c index 17449aa..26c02cc 100644 --- a/examples/single_chip/camera_web_server/main/app_mdns.c +++ b/examples/single_chip/camera_web_server/main/app_mdns.c @@ -31,6 +31,7 @@ #include "esp_camera.h" #include "mdns.h" #include "app_camera.h" +#include "app_wifi.h" static const char *TAG = "camera mdns"; @@ -82,11 +83,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 +136,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; @@ -166,7 +167,7 @@ void app_mdns_update_framesize(int size) } } -void app_mdns_main() +void app_mdns_main(void) { uint8_t mac[6]; 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 df65f85..9804e37 100644 --- a/examples/single_chip/camera_web_server/main/app_wifi.c +++ b/examples/single_chip/camera_web_server/main/app_wifi.c @@ -25,7 +25,7 @@ #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,8 +33,6 @@ #include "lwip/err.h" #include "lwip/sys.h" -#include "mdns.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 @@ -49,111 +47,185 @@ #define EXAMPLE_IP_ADDR CONFIG_SERVER_IP #define EXAMPLE_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 = "camera wifi"; static int s_retry_num = 0; -static esp_err_t event_handler(void *ctx, system_event_t *event) +esp_netif_t *AP_netif, *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_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(); + 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(void) { + /* 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(EXAMPLE_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)); + 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); 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; wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK; + if (strlen(EXAMPLE_ESP_WIFI_AP_PASS) == 0) { wifi_config.ap.authmode = WIFI_AUTH_OPEN; } + if (strlen(EXAMPLE_ESP_WIFI_AP_CHANNEL)) { int channel; sscanf(EXAMPLE_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(WIFI_MODE_AP)); + // "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_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", + EXAMPLE_ESP_WIFI_AP_SSID, EXAMPLE_ESP_WIFI_AP_PASS, EXAMPLE_ESP_WIFI_AP_CHANNEL); } -void wifi_init_sta() +void wifi_init_sta(void) { - wifi_config_t wifi_config; - memset(&wifi_config, 0, sizeof(wifi_config_t)); + 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_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_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_WPA_WPA2_PSK, + .pmf_cfg = { + .capable = true, + .required = false + }, + }, + }; + snprintf((char*)wifi_config.sta.ssid, 32, "%s", EXAMPLE_ESP_WIFI_SSID); snprintf((char*)wifi_config.sta.password, 64, "%s", EXAMPLE_ESP_WIFI_PASS); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); 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); -} -void app_wifi_main() -{ - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - wifi_mode_t mode = WIFI_MODE_NULL; + /* 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 (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; + if (bits & WIFI_CONNECTED_BIT) { + ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", + EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); + } 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); + } 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 +233,35 @@ 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_ERROR_CHECK(esp_wifi_init(&cfg)); + + wifi_mode_t mode = WIFI_MODE_NULL; + + if (strlen(EXAMPLE_ESP_WIFI_AP_SSID) && strlen(EXAMPLE_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)) { + mode = WIFI_MODE_AP; + ESP_LOGI(TAG, "WIFI_MODE_AP"); + wifi_init_softap(); + } else if (strlen(EXAMPLE_ESP_WIFI_SSID)) { + mode = WIFI_MODE_STA; + ESP_LOGI(TAG, "WIFI_MODE_STA"); + wifi_init_sta(); + } + 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/camera_web_server/main/include/app_mdns.h b/examples/single_chip/camera_web_server/main/include/app_mdns.h index 90769d1..4ce059a 100644 --- a/examples/single_chip/camera_web_server/main/include/app_mdns.h +++ b/examples/single_chip/camera_web_server/main/include/app_mdns.h @@ -20,7 +20,7 @@ extern "C" { #include -void app_mdns_main(); +void app_mdns_main(void); void app_mdns_update_framesize(int size); const char * app_mdns_query(size_t * out_len); diff --git a/examples/single_chip/camera_web_server/main/include/app_wifi.h b/examples/single_chip/camera_web_server/main/include/app_wifi.h index dc164e9..0b61464 100644 --- a/examples/single_chip/camera_web_server/main/include/app_wifi.h +++ b/examples/single_chip/camera_web_server/main/include/app_wifi.h @@ -28,7 +28,12 @@ extern "C" { #endif -void app_wifi_main(); +#include "esp_netif.h" + +extern esp_netif_t *AP_netif; +extern esp_netif_t *STA_netif; + +void app_wifi_main(void); #ifdef __cplusplus }