Files
ESP32_Serial_Swiss_Army_Knife/src/local_ui_config.c
T

120 lines
3.3 KiB
C

/* SPDX-License-Identifier: GPL-3.0-only */
/* Versioned persistent configuration for the optional local OLED UI. */
#include "local_ui_config.h"
#include <stddef.h>
#include "nvs.h"
#include "nvs_flash.h"
void local_ui_config_defaults(local_ui_config_t *config)
{
if (config == NULL) {
return;
}
*config = (local_ui_config_t){
.version = LOCAL_UI_CONFIG_VERSION,
.dim_timeout_seconds = LOCAL_UI_CONFIG_DEFAULT_DIM_SECONDS,
.off_timeout_seconds = LOCAL_UI_CONFIG_DEFAULT_OFF_SECONDS,
};
}
esp_err_t local_ui_config_validate(const local_ui_config_t *config)
{
if (config == NULL || config->version != LOCAL_UI_CONFIG_VERSION ||
config->dim_timeout_seconds > LOCAL_UI_CONFIG_MAX_TIMEOUT_SECONDS ||
config->off_timeout_seconds > LOCAL_UI_CONFIG_MAX_TIMEOUT_SECONDS) {
return ESP_ERR_INVALID_ARG;
}
if (config->dim_timeout_seconds != 0U && config->off_timeout_seconds != 0U &&
config->off_timeout_seconds <= config->dim_timeout_seconds) {
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
esp_err_t local_ui_config_load(local_ui_config_t *config, bool *used_stored_config)
{
if (config == NULL || used_stored_config == NULL) {
return ESP_ERR_INVALID_ARG;
}
local_ui_config_defaults(config);
*used_stored_config = false;
esp_err_t error = nvs_flash_init();
if (error != ESP_OK) {
return error;
}
nvs_handle_t handle;
error = nvs_open(LOCAL_UI_CONFIG_NVS_NAMESPACE, NVS_READONLY, &handle);
if (error == ESP_ERR_NVS_NOT_FOUND) {
return ESP_OK;
}
if (error != ESP_OK) {
return error;
}
size_t stored_size = 0U;
error = nvs_get_blob(handle, LOCAL_UI_CONFIG_NVS_BLOB_KEY, NULL, &stored_size);
if (error == ESP_ERR_NVS_NOT_FOUND || error == ESP_ERR_NVS_TYPE_MISMATCH ||
(error == ESP_OK && stored_size != sizeof(local_ui_config_t))) {
nvs_close(handle);
return ESP_OK;
}
if (error != ESP_OK) {
nvs_close(handle);
return error;
}
local_ui_config_t stored;
error = nvs_get_blob(handle, LOCAL_UI_CONFIG_NVS_BLOB_KEY, &stored, &stored_size);
nvs_close(handle);
if (error == ESP_ERR_NVS_INVALID_LENGTH) {
return ESP_OK;
}
if (error != ESP_OK) {
return error;
}
if (stored_size != sizeof(stored) || local_ui_config_validate(&stored) != ESP_OK) {
return ESP_OK;
}
*config = stored;
*used_stored_config = true;
return ESP_OK;
}
esp_err_t local_ui_config_save(const local_ui_config_t *config)
{
esp_err_t error = local_ui_config_validate(config);
if (error != ESP_OK) {
return error;
}
error = nvs_flash_init();
if (error != ESP_OK) {
return error;
}
nvs_handle_t handle;
error = nvs_open(LOCAL_UI_CONFIG_NVS_NAMESPACE, NVS_READWRITE, &handle);
if (error != ESP_OK) {
return error;
}
error = nvs_set_blob(handle, LOCAL_UI_CONFIG_NVS_BLOB_KEY, config, sizeof(*config));
if (error == ESP_OK) {
error = nvs_commit(handle);
}
nvs_close(handle);
return error;
}
esp_err_t local_ui_config_reset_storage(void)
{
local_ui_config_t config;
local_ui_config_defaults(&config);
return local_ui_config_save(&config);
}