/* SPDX-License-Identifier: GPL-3.0-only */ /* * Native ESP-IDF Wi-Fi configuration and persistence. * * The public structures below are also the version-1 NVS wire format. Keep * every field fixed-width and introduce a new schema version for layout * changes; do not silently reinterpret an existing blob. */ #pragma once #include #include #include #include "esp_err.h" #define WIFI_CONFIG_SCHEMA_VERSION 1U #define WIFI_CONFIG_BLOB_SIZE 528U #define WIFI_CONFIG_STA_PROFILE_BLOB_SIZE 104U #define WIFI_CONFIG_NVS_NAMESPACE "wifi_app" #define WIFI_CONFIG_NVS_BLOB_KEY "config" #define WIFI_CONFIG_STA_PROFILE_COUNT 4U #define WIFI_CONFIG_SSID_MAX_LEN 32U #define WIFI_CONFIG_PSK_MIN_LEN 8U #define WIFI_CONFIG_PSK_MAX_LEN 63U #define WIFI_CONFIG_DEFAULT_AP_PSK_LEN 16U #define WIFI_CONFIG_AP_CHANNEL_MIN 1U #define WIFI_CONFIG_AP_CHANNEL_MAX 11U /* uint8_t aliases keep the persisted representation independent of enum size. */ typedef uint8_t wifi_config_ap_policy_t; enum { WIFI_CONFIG_AP_POLICY_OFF = 0U, WIFI_CONFIG_AP_POLICY_FALLBACK = 1U, WIFI_CONFIG_AP_POLICY_ALWAYS = 2U, }; typedef uint8_t wifi_config_security_t; enum { /* ESP-IDF thresholds can express WPA2-or-stronger, not WPA2-only. */ WIFI_CONFIG_SECURITY_MIXED = 0U, WIFI_CONFIG_SECURITY_WPA3 = 1U, }; typedef uint8_t wifi_config_load_source_t; enum { WIFI_CONFIG_LOAD_GENERATED_MISSING = 0U, WIFI_CONFIG_LOAD_STORED = 1U, WIFI_CONFIG_LOAD_GENERATED_INVALID = 2U, }; typedef struct { /* Persisted booleans use 0/1 bytes so the blob layout remains fixed. */ uint8_t enabled; uint8_t priority; wifi_config_security_t security; uint8_t ssid_len; uint8_t psk_len; uint8_t reserved[3]; /* Lengths are authoritative; these fixed-width byte arrays need no NUL. */ uint8_t ssid[WIFI_CONFIG_SSID_MAX_LEN]; uint8_t psk[WIFI_CONFIG_PSK_MAX_LEN]; uint8_t reserved_tail[1]; } wifi_config_sta_profile_t; typedef struct { uint32_t schema_version; uint16_t blob_size; uint8_t enabled_at_boot; wifi_config_ap_policy_t ap_policy; uint8_t ap_ssid_len; uint8_t ap_psk_len; uint8_t ap_channel; uint8_t reserved[5]; uint8_t ap_ssid[WIFI_CONFIG_SSID_MAX_LEN]; uint8_t ap_psk[WIFI_CONFIG_PSK_MAX_LEN]; uint8_t reserved_tail[1]; wifi_config_sta_profile_t profiles[WIFI_CONFIG_STA_PROFILE_COUNT]; } wifi_app_config_t; /* Generates a unique AP SSID and a fresh random AP password. */ esp_err_t wifi_config_defaults(wifi_app_config_t *config); esp_err_t wifi_config_validate(const wifi_app_config_t *config); bool wifi_config_parse_ap_policy(const char *text, wifi_config_ap_policy_t *value); const char *wifi_config_ap_policy_to_string(wifi_config_ap_policy_t value); bool wifi_config_parse_security(const char *text, wifi_config_security_t *value); const char *wifi_config_security_to_string(wifi_config_security_t value); /* * Storage uses only wifi_app/config. Invalid, stale, or absent blobs are left * untouched. source distinguishes first boot from incompatible stored data so * callers never overwrite a potentially migratable schema automatically. */ esp_err_t wifi_config_storage_init(void); esp_err_t wifi_config_load(wifi_app_config_t *config, wifi_config_load_source_t *source); esp_err_t wifi_config_save(const wifi_app_config_t *config); /* Pass NULL to generate fresh defaults, or supply validated defaults to save. */ esp_err_t wifi_config_reset_storage(const wifi_app_config_t *defaults); /* Compatibility wrapper around the shared secure_wipe() implementation. */ void wifi_config_secure_wipe(void *data, size_t size);