#include #include #include "esp_log.h" #include "nvs_flash.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_event.h" #include #include "esp_wifi.h" #include "esp_http_client.h" #include "esp_tls.h" #include "esp_https_ota.h" #include "esp_ota_ops.h" #include "esp_crt_bundle.h" #include "USB.h" #include "Key_Value.h" static const char *TAG = "WiFi"; static EventGroupHandle_t s_wifi_event_group; #define WIFI_CONNECTED_BIT BIT0 #define WIFI_FAIL_BIT BIT1 #define KTAG_WIFI_TASK_PRIORITY 2 static TaskHandle_t xWiFiTask = NULL; static StaticTask_t xWiFiTaskBuffer; static StackType_t xWiFiTaskStack[4096]; static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { KLOG_INFO(TAG, "Connecting to the WiFi Access Point..."); esp_wifi_connect(); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) { KLOG_INFO(TAG, "Connected to the WiFi Access Point!"); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { KLOG_WARN(TAG, "Failed to connect to the WiFi Access Point!"); xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); } 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; KLOG_INFO(TAG, "Got an IP address:" IPSTR, IP2STR(&event->ip_info.ip)); xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } else { KLOG_WARN(TAG, "Unhandled event: %s %ld", event_base, event_id); } } esp_err_t _http_event_handler(esp_http_client_event_t *evt) { switch (evt->event_id) { case HTTP_EVENT_ERROR: KLOG_DEBUG(TAG, "HTTP_EVENT_ERROR"); break; case HTTP_EVENT_ON_CONNECTED: KLOG_DEBUG(TAG, "HTTP_EVENT_ON_CONNECTED"); break; case HTTP_EVENT_HEADER_SENT: KLOG_DEBUG(TAG, "HTTP_EVENT_HEADER_SENT"); break; case HTTP_EVENT_ON_HEADER: KLOG_DEBUG(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value); break; case HTTP_EVENT_ON_DATA: KLOG_DEBUG(TAG, "HTTP_EVENT_ON_DATA, %.*s", evt->data_len, (char *)evt->data); break; case HTTP_EVENT_ON_FINISH: KLOG_DEBUG(TAG, "HTTP_EVENT_ON_FINISH"); break; case HTTP_EVENT_DISCONNECTED: KLOG_DEBUG(TAG, "HTTP_EVENT_DISCONNECTED"); break; case HTTP_EVENT_REDIRECT: KLOG_DEBUG(TAG, "HTTP_EVENT_REDIRECT"); break; } return ESP_OK; } bool wifi_init_sta(void) { s_wifi_event_group = xEventGroupCreate(); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); esp_netif_create_default_wifi_sta(); 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, &event_handler, NULL, &instance_any_id)); ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip)); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); wifi_config_t wifi_config = { .sta = { .failure_retry_cnt = 3, }, }; char STA_SSID[32]; char STA_Password[64]; KV_Get_Value_string(CONFIG_FILE, "STA_SSID", STA_SSID); KV_Get_Value_string(CONFIG_FILE, "STA_Password", STA_Password); strlcpy((char *)wifi_config.sta.ssid, STA_SSID, sizeof(wifi_config.sta.ssid)); strlcpy((char *)wifi_config.sta.password, STA_Password, sizeof(wifi_config.sta.password)); ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_start()); // Wait 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); if (bits & WIFI_CONNECTED_BIT) { KLOG_INFO(TAG, "Connected to AP with SSID: %s", wifi_config.sta.ssid); return true; } else if (bits & WIFI_FAIL_BIT) { KLOG_WARN(TAG, "Failed to connect to SSID \"%s\"!", wifi_config.sta.ssid); return false; } else { KLOG_ERROR(TAG, "Unexpected event!"); return false; } } void download_test_file(void) { esp_http_client_config_t config = { .url = "https://ktag.clubk.club/2024A.txt", .crt_bundle_attach = esp_crt_bundle_attach, .event_handler = _http_event_handler}; esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { KLOG_INFO(TAG, "HTTPS Status = %d, content_length = %lld", esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { KLOG_ERROR(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } esp_http_client_config_t ota_http_config = { .crt_bundle_attach = esp_crt_bundle_attach, .event_handler = _http_event_handler, .buffer_size = 8192, .keep_alive_enable = true, .timeout_ms = 30 * 1000}; esp_https_ota_config_t ota_config = { .http_config = &ota_http_config, .bulk_flash_erase = false, }; static void WiFi_Task(void *pvParameters) { if (wifi_init_sta()) { download_test_file(); vTaskDelay(5000 / portTICK_PERIOD_MS); const esp_partition_t *running = esp_ota_get_running_partition(); esp_app_desc_t running_app_info; if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) { KLOG_INFO(TAG, "Running firmware version: %s", running_app_info.version); } ota_http_config.url = Get_OTA_Image_URL(); KLOG_INFO(TAG, "Attempting OTA reprogramming from %s", ota_http_config.url); esp_log_level_set("wifi", ESP_LOG_VERBOSE); esp_err_t err = esp_https_ota(&ota_config); if (err == ESP_OK) { Erase_OTA_File(); KLOG_INFO(TAG, "OTA Succeed, Rebooting...\n"); vTaskDelay(5000 / portTICK_PERIOD_MS); esp_restart(); } else { KLOG_ERROR(TAG, "OTA Failed!\n"); } } vTaskDelete(NULL); } void Initialize_WiFi(void) { if (xWiFiTask == NULL) { KLOG_INFO(TAG, "Initializing WiFi..."); xWiFiTask = xTaskCreateStaticPinnedToCore( WiFi_Task, "KTag WiFI", sizeof(xWiFiTaskStack) / sizeof(StackType_t), NULL, KTAG_WIFI_TASK_PRIORITY, xWiFiTaskStack, &xWiFiTaskBuffer, APP_CPU_NUM); } else { KLOG_WARN(TAG, "WiFi already running."); } }