From b42bb7efa9f3417471422946a43e07f1844c5062 Mon Sep 17 00:00:00 2001 From: Erki Date: Sat, 10 Feb 2024 20:01:36 +0200 Subject: [PATCH] Firmware: implement connecting to configured wifi --- firmware/main/CMakeLists.txt | 2 +- firmware/main/clock_core.cpp | 131 +++++++++++++++++++++++++++++++++ firmware/main/clock_core.hpp | 12 +++ firmware/main/esp_expected.hpp | 1 + firmware/main/main.cpp | 6 ++ 5 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 firmware/main/clock_core.cpp create mode 100644 firmware/main/clock_core.hpp diff --git a/firmware/main/CMakeLists.txt b/firmware/main/CMakeLists.txt index 018080e..5f9c478 100644 --- a/firmware/main/CMakeLists.txt +++ b/firmware/main/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register( - SRCS "main.cpp" "wifi_provisioner.cpp" + SRCS "main.cpp" "wifi_provisioner.cpp" "clock_core.cpp" INCLUDE_DIRS "" REQUIRES nvs_flash esp_wifi esp_http_server etlcpp json EMBED_FILES "${CMAKE_CURRENT_LIST_DIR}/static/index.html" diff --git a/firmware/main/clock_core.cpp b/firmware/main/clock_core.cpp new file mode 100644 index 0000000..acbff47 --- /dev/null +++ b/firmware/main/clock_core.cpp @@ -0,0 +1,131 @@ +// +// Created by erki on 25/01/24. +// + +#include "clock_core.hpp" + +#include "esp_expected.hpp" + +#include + +#include +#include +#include +#include + +namespace +{ + +const char* TAG = "clock_core"; + +constexpr EventBits_t WIFI_FAIL_BIT = BIT0; +constexpr EventBits_t WIFI_CONNECTED_BIT = BIT1; +EventGroupHandle_t wifi_event_group_; + +void wifiEventHandler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + static int retry_num = 0; + + 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 (retry_num < 10) + { + esp_wifi_connect(); + retry_num++; + ESP_LOGI(TAG, "Retrying to connect to AP."); + } + else + { + xEventGroupSetBits(wifi_event_group_, WIFI_FAIL_BIT); + } + ESP_LOGW(TAG, "Connection to AP failed."); + } + else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) + { + auto* event = static_cast(event_data); + ESP_LOGI(TAG, "Connected to AP. Got IP: " IPSTR, IP2STR(&event->ip_info.ip)); + retry_num = 0; + + xEventGroupSetBits(wifi_event_group_, WIFI_CONNECTED_BIT); + } +} + +std::expected wifiInitialize(const char* wifi_ssid, const char* wifi_password) +{ + TRY_ESP(esp_netif_init()); + TRY_ESP(esp_event_loop_create_default()); + esp_netif_create_default_wifi_sta(); + + wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); + TRY_ESP(esp_wifi_init(&config)); + + esp_event_handler_instance_t instance_any_id; + esp_event_handler_instance_t instance_got_ip; + TRY_ESP(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &wifiEventHandler, + nullptr, + &instance_any_id)); + TRY_ESP(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &wifiEventHandler, + nullptr, + &instance_got_ip)); + + wifi_sta_config_t sta_config; + std::memset(&sta_config, 0, sizeof(sta_config)); + std::strncpy((char*) sta_config.ssid, wifi_ssid, 32); + std::strncpy((char*) sta_config.password, wifi_password, 64); + sta_config.threshold.authmode = WIFI_AUTH_WPA2_PSK; + + wifi_config_t wifi_config = { .sta = sta_config }; + + TRY_ESP(esp_wifi_set_mode(WIFI_MODE_STA)); + TRY_ESP(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + TRY_ESP(esp_wifi_start()); + + return {}; +} + +} + +namespace clock_core +{ + +void run(const char* wifi_ssid, const char* wifi_password) +{ + wifi_event_group_ = xEventGroupCreate(); + + if (const auto res = wifiInitialize(wifi_ssid, wifi_password); + !res.has_value()) + { + ESP_LOGI(TAG, "WiFi setup errored in clock_core::run. Error: %s", esp_err_to_name(res.error())); + abort(); + } + + const EventBits_t bits = xEventGroupWaitBits(wifi_event_group_, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + if (bits & WIFI_CONNECTED_BIT) + { + ESP_LOGI(TAG, "WiFi setup in clock_core::run successful."); + } + else if (bits & WIFI_FAIL_BIT) + { + ESP_LOGE(TAG, "WiFi setup in clock_core::run failed."); + } + else + { + ESP_LOGE(TAG, "WiFi setup encountered an unexpected set of bits. %lu", bits); + } +} + +} diff --git a/firmware/main/clock_core.hpp b/firmware/main/clock_core.hpp new file mode 100644 index 0000000..0a96d84 --- /dev/null +++ b/firmware/main/clock_core.hpp @@ -0,0 +1,12 @@ +// +// Created by erki on 25/01/24. +// + +#pragma once + +namespace clock_core +{ + +void run(const char* wifi_ssid, const char* wifi_password); + +} diff --git a/firmware/main/esp_expected.hpp b/firmware/main/esp_expected.hpp index 015f89e..0170ac8 100644 --- a/firmware/main/esp_expected.hpp +++ b/firmware/main/esp_expected.hpp @@ -11,6 +11,7 @@ #include #include +#include #define TRY(x) ({ \ const auto& _x = (x); \ diff --git a/firmware/main/main.cpp b/firmware/main/main.cpp index 2b10f7b..58aba0b 100644 --- a/firmware/main/main.cpp +++ b/firmware/main/main.cpp @@ -11,6 +11,7 @@ #include "esp_expected.hpp" #include "wifi_provisioner.hpp" +#include "clock_core.hpp" extern "C" void app_main(void) { @@ -42,6 +43,9 @@ extern "C" void app_main(void) return; } + // @todo: Remove later. + provisioner->clearSettings(); + if (!provisioner->parametersAreConfigured()) { auto result = provisioner->startProvisioning(); @@ -78,4 +82,6 @@ extern "C" void app_main(void) delete provisioner; printf("We now have a wifi with SSID: %s, password: %s\n", ssid.c_str(), password.c_str()); + + clock_core::run(ssid.c_str(), password.c_str()); }