#include "esp_event.h" #include "esp_log.h" #include "esp_system.h" #include "esp_timer.h" #include "nvs_flash.h" #include "mqtt.h" #include "wifi.h" #include static const char *TAG = "app"; /** * @brief Initialize NVS (Non-Volatile Storage) flash storage, handling full or * incompatible pages. * * This function checks the NVS flash storage to ensure that there is enough * space and that the version of NVS is compatible. If the partition is full or * incompatible, it will erase the NVS partition and attempt initialization * again. * * @return esp_err_t * - ESP_OK: Initialization successful. * - Other error codes if initialization or erasure fails. */ static esp_err_t nvs_flash_init_check(void) { esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_LOGW(TAG, "NVS partition is full or incompatible, erasing..."); ret = nvs_flash_erase(); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to erase NVS partition (%s)", esp_err_to_name(ret)); return ret; } ret = nvs_flash_init(); } if (ret != ESP_OK) ESP_LOGE(TAG, "Failed to initialize NVS (%s)", esp_err_to_name(ret)); return ret; } /** * @brief General helper function to initialize a given component and log * errors. * * This function takes an initialization function and a component name, attempts * to initialize the component, and logs an error if initialization fails. * * @param init_func A function pointer to the initialization function of the * component. * @param component_name A string describing the name of the component being * initialized. * * @return esp_err_t * - ESP_OK: If initialization is successful. * - Other error codes if initialization fails. */ static esp_err_t init_component(esp_err_t (*init_func)(void), const char *component_name) { esp_err_t ret = init_func(); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to initialize %s (%s)", component_name, esp_err_to_name(ret)); return ret; } return ESP_OK; } /** * @brief Initializes all the essential components for the application. * * This function initializes the NVS storage, network interface, and event loop * in sequence. If any of these components fail to initialize, the function * returns an error, and the application will stop early. * * @return esp_err_t * - ESP_OK: If all components are successfully initialized. * - ESP_FAIL: If any component fails to initialize. */ esp_err_t init_app_components(void) { if (init_component(nvs_flash_init_check, "NVS") != ESP_OK) { ESP_LOGE(TAG, "NVS initialization failed, aborting app start."); return ESP_FAIL; } if (init_component(esp_netif_init, "network interface") != ESP_OK) return ESP_FAIL; if (init_component(esp_event_loop_create_default, "event loop") != ESP_OK) return ESP_FAIL; return ESP_OK; } /** * @brief Main entry point of the application. * * This function is responsible for initializing the core components of the * application, including the NVS storage, network interface, and event loop. If * any initialization step fails, the application will log the error and stop. * * After initialization, this function will configure the WiFi station and start * the MQTT client. */ void app_main(void) { if (init_app_components() != ESP_OK) { ESP_LOGE(TAG, "App initialization failed, aborting."); return; } ESP_LOGI(TAG, "Initializing WiFi in station mode"); wifi_init_sta(); ESP_LOGI(TAG, "Starting MQTT client"); mqtt_app_start(); }