From 2408ec650d97a575a55a57745ae40866f4880c99 Mon Sep 17 00:00:00 2001 From: William Vallet Date: Thu, 23 May 2024 00:07:05 +0200 Subject: [PATCH] Add WiFi provisioning support --- include/wifi.h | 11 +++++ src/CMakeLists.txt | 2 +- src/main.c | 21 +++++++++ src/wifi.c | 111 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 include/wifi.h create mode 100644 src/wifi.c diff --git a/include/wifi.h b/include/wifi.h new file mode 100644 index 0000000..3ea1453 --- /dev/null +++ b/include/wifi.h @@ -0,0 +1,11 @@ +/* + * MIT License + * Copyright (c) 2024 William Vallet + */ + +#ifndef WIFI_H_ +#define WIFI_H_ + +extern void wifi_init(void); + +#endif // WIFI_H_ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9640748..609966f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register( SRCS main.c board.c led.c ir_decoder.c ir_decoder_nec.c - command.c + command.c wifi.c ) diff --git a/src/main.c b/src/main.c index b248897..f6f0b18 100644 --- a/src/main.c +++ b/src/main.c @@ -8,12 +8,15 @@ #include "command.h" #include "ir_decoder.h" #include "led.h" +#include "wifi.h" #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_chip_info.h" +#include "esp_event.h" #include "esp_flash.h" #include "esp_log.h" +#include "nvs_flash.h" #include #include @@ -45,12 +48,30 @@ static void display_chip_information(void) (chip_info.features & CHIP_FEATURE_IEEE802154) ? " IEEE-802.15.4" : ""); } +static void env_init(void) +{ + // Storage initialisation. + 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()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + // Event loop initialisation. + ESP_ERROR_CHECK(esp_event_loop_create_default()); +} + void app_main(void) { board_initialise(); esp_log_level_set("*", ESP_LOG_INFO); ESP_LOGI(LOGGER_TAG, "*** ESP UPnP remote ***"); display_chip_information(); + // Initialise WiFi (provisioning or connection). + env_init(); + wifi_init(); // Initialise command processing. command_init(); // IR decoder configuration. diff --git a/src/wifi.c b/src/wifi.c new file mode 100644 index 0000000..eedc706 --- /dev/null +++ b/src/wifi.c @@ -0,0 +1,111 @@ +/* + * MIT License + * Copyright (c) 2024 William Vallet + */ + +#include "wifi.h" +#include "esp_event.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_wifi.h" +#include "wifi_provisioning/manager.h" +#include "wifi_provisioning/scheme_softap.h" + +#define LOGGER_TAG "wifi_api" + +#define WIFI_PROV_SSID "UPnP Remote Provisioning" +#define WIFI_PROV_PASS "password" +#define WIFI_PROV_PROOF "abcd1234" +#define WIFI_PROV_SECURITY WIFI_PROV_SECURITY_1 + +static void wifi_event_handler( + void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) +{ + (void) arg; + if (event_base != WIFI_PROV_EVENT) + return; + switch (event_id) + { + case WIFI_PROV_INIT: + ESP_LOGD(LOGGER_TAG, "Provisioning initialised"); + break; + case WIFI_PROV_START: + ESP_LOGI(LOGGER_TAG, "Provisioning started"); + break; + case WIFI_PROV_CRED_RECV: + const wifi_sta_config_t * const wifi_sta_cfg = + (wifi_sta_config_t *) event_data; + ESP_LOGI(LOGGER_TAG, + "Credentials received for ssid='%s'", + wifi_sta_cfg->ssid); + break; + case WIFI_PROV_CRED_FAIL: + const wifi_prov_sta_fail_reason_t * const reason = + (wifi_prov_sta_fail_reason_t *) event_data; + ESP_LOGE(LOGGER_TAG, + "Provisioning failed reason=%s", + (*reason == WIFI_PROV_STA_AUTH_ERROR) ? + "auth_failed" : "ap_not_found"); + break; + case WIFI_PROV_CRED_SUCCESS: + ESP_LOGI(LOGGER_TAG, "Provisioning successful"); + break; + case WIFI_PROV_END: + ESP_LOGI(LOGGER_TAG, "Provisioning ended"); + wifi_prov_mgr_deinit(); + break; + case WIFI_PROV_DEINIT: + ESP_LOGD(LOGGER_TAG, "Provisioning de-initialised"); + break; + default: + // Nothing to do. + break; + } +} + +static bool wifi_is_provisioned(void) +{ + bool provisioned = false; + ESP_ERROR_CHECK(wifi_prov_mgr_is_provisioned(&provisioned)); + return provisioned; +} + +static void wifi_provisioning(void) +{ + const wifi_prov_mgr_config_t config = { + .scheme = wifi_prov_scheme_softap, + .scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE + }; + ESP_ERROR_CHECK(esp_event_handler_instance_register( + WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL)); + ESP_ERROR_CHECK(wifi_prov_mgr_init(config)); + ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning( + WIFI_PROV_SECURITY, WIFI_PROV_PROOF, WIFI_PROV_SSID, WIFI_PROV_PASS)); +} + +static void wifi_connect(void) +{ + // TODO +} + +void wifi_init(void) +{ + // Initialise WiFi component. + const wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_netif_init()); + esp_netif_create_default_wifi_ap(); + ESP_ERROR_CHECK(esp_wifi_init(&wifi_cfg)); + // Check credentials status. + if (!wifi_is_provisioned()) + { + ESP_LOGI(LOGGER_TAG, "Credentials not available"); + // No credentials, start provisioning process. + wifi_provisioning(); + } + else + { + ESP_LOGI(LOGGER_TAG, "Credentials available"); + // Credentials are present, try connection. + wifi_connect(); + } +}