Add native Wi-Fi management and persistence

This commit is contained in:
2026-08-23 14:57:53 +02:00
parent aa5fa207b6
commit c5f3595173
11 changed files with 2869 additions and 2 deletions
+113
View File
@@ -0,0 +1,113 @@
/* 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 <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#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;
/* Seed the credential DRBG before Wi-Fi, Bluetooth, or ADC use. */
esp_err_t wifi_config_entropy_init(void);
/* 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);
/* Volatile writes prevent ordinary optimization from eliding secret cleanup. */
void wifi_config_secure_wipe(void *data, size_t size);