You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
4.7 KiB
176 lines
4.7 KiB
//
|
|
// Created by MightyPork on 2018/11/18.
|
|
//
|
|
|
|
#include <nvs.h>
|
|
#include <string.h>
|
|
#include <esp_log.h>
|
|
#include "settings.h"
|
|
#include "utils.h"
|
|
|
|
static const char * TAG = "settings.c";
|
|
|
|
static uint16_t app_boot_count = 0;
|
|
|
|
#undef X
|
|
#define X(pre,name,post,def,gen_nvs,nvs_format,save_prefix) .name = def,
|
|
const struct cspemu_settings defaults = {
|
|
SETTINGS_XTABLE()
|
|
};
|
|
|
|
|
|
struct cspemu_settings g_Settings;
|
|
struct cspemu_globals g_State = {
|
|
.wifi_inited = false,
|
|
};
|
|
|
|
static nvs_handle storage = 0;
|
|
extern nvs_handle g_nvs_storage __attribute__((alias("storage")));
|
|
|
|
void settings_init(void)
|
|
{
|
|
ESP_ERROR_CHECK(nvs_open("cspemu", NVS_READWRITE, &storage));
|
|
}
|
|
|
|
union fu {
|
|
float f;
|
|
uint32_t u;
|
|
};
|
|
|
|
/** Read float from NVS. See `nvs_get_u32` for more info. */
|
|
static esp_err_t nvs_get_f32 (nvs_handle_t handle, const char* key, float* out_value) {
|
|
uint32_t u = 0;
|
|
esp_err_t rv = nvs_get_u32(handle, key, &u);
|
|
if (rv != ESP_OK) {
|
|
return rv;
|
|
}
|
|
|
|
union fu reinterpret = {
|
|
.u = u,
|
|
};
|
|
|
|
*out_value = reinterpret.f;
|
|
return ESP_OK;
|
|
}
|
|
|
|
/** Write float to NVS. See `nvs_set_u32` for more info. */
|
|
static esp_err_t nvs_set_f32 (nvs_handle_t handle, const char* key, float value) {
|
|
union fu reinterpret = {
|
|
.f = value,
|
|
};
|
|
return nvs_set_u32(handle, key, reinterpret.u);
|
|
}
|
|
|
|
/** Dummy read from NVS; placeholder for XTABLE entries with manually implemented getters */
|
|
static esp_err_t nvs_get_none(nvs_handle handle, const char* key, void* out_value) {
|
|
return ESP_OK;
|
|
}
|
|
|
|
/** Dummy write to NVS; placeholder for XTABLE entries with manually implemented setters */
|
|
static esp_err_t nvs_set_none(nvs_handle handle, const char* key, void* value) {
|
|
return ESP_OK;
|
|
}
|
|
|
|
void settings_load(void)
|
|
{
|
|
esp_err_t rv;
|
|
memcpy(&g_Settings, &defaults, sizeof(struct cspemu_settings));
|
|
|
|
// abort on failure other than "not found"
|
|
#define NVSCHECK(callback) \
|
|
do { \
|
|
rv = callback; \
|
|
if (rv != ESP_OK && rv != ESP_ERR_NVS_NOT_FOUND) { \
|
|
ESP_LOGE(TAG, "NVS ERR %d", rv); \
|
|
abort(); \
|
|
} \
|
|
} while(0)
|
|
|
|
NVSCHECK(nvs_get_u16(storage, "bootcount", &app_boot_count));
|
|
ESP_LOGI(TAG, "NVS restored bootcount %d", app_boot_count);
|
|
app_boot_count++;
|
|
NVSCHECK(nvs_set_u16(storage, "bootcount", app_boot_count));
|
|
|
|
|
|
// version will be used for settings format upgrades
|
|
uint8_t version = 0;
|
|
NVSCHECK(nvs_get_u8(storage, "version", &version));
|
|
|
|
#undef X
|
|
#define X(pre, name, post, def, gen_nvs, nvs_format, save_prefix) \
|
|
if (gen_nvs) { \
|
|
NVSCHECK(nvs_get_##nvs_format(storage, STR(name), save_prefix g_Settings. name)); \
|
|
}
|
|
|
|
SETTINGS_XTABLE()
|
|
|
|
// custom values
|
|
|
|
#define ensure_str_terminated(str, len) if (strnlen((str), (len)) >= (len)) { (str)[(len)-1] = 0; }
|
|
|
|
{
|
|
size_t capacity = CONSOLE_PW_LEN;
|
|
NVSCHECK(nvs_get_str(storage, "tcpp_pw", g_Settings.console_pw, &capacity));
|
|
ensure_str_terminated(g_Settings.console_pw, CONSOLE_PW_LEN);
|
|
}
|
|
{
|
|
size_t capacity = NTP_SRV_LEN;
|
|
NVSCHECK(nvs_get_str(storage, "ntp_srv", g_Settings.ntp_srv, &capacity));
|
|
ensure_str_terminated(g_Settings.ntp_srv, NTP_SRV_LEN);
|
|
}
|
|
{
|
|
size_t capacity = 10;
|
|
NVSCHECK(nvs_get_blob(storage, "co2_calib", g_Settings.co2_calib, &capacity));
|
|
}
|
|
{
|
|
size_t capacity = BSEC_MAX_STATE_BLOB_SIZE;
|
|
NVSCHECK(nvs_get_blob(storage, "bsec_state", g_Settings.bsec_state, &capacity));
|
|
}
|
|
}
|
|
|
|
void settings_persist(enum settings_key_enum what)
|
|
{
|
|
esp_err_t rv;
|
|
// char name[24];
|
|
|
|
#undef NVSCHECK
|
|
#define NVSCHECK(callback) \
|
|
do { \
|
|
rv = (callback); \
|
|
if (rv != ESP_OK) { \
|
|
ESP_LOGE(TAG, "NVS ERR %d", rv); \
|
|
abort(); \
|
|
} \
|
|
} while(0)
|
|
|
|
|
|
#undef X
|
|
#define X(pre,name,post,def,gen_nvs,nvs_format,save_prefix) \
|
|
if ((gen_nvs) && ((what)==SETTINGS_ALL || (what)==SETTINGS_## name)) { \
|
|
NVSCHECK(nvs_set_##nvs_format(storage, STR(name), g_Settings. name)); \
|
|
}
|
|
|
|
SETTINGS_XTABLE()
|
|
|
|
// custom values
|
|
if (what==SETTINGS_ALL || what==SETTINGS_console_pw) {
|
|
NVSCHECK(nvs_set_str(storage, "tcpp_pw", g_Settings.console_pw));
|
|
}
|
|
|
|
if (what==SETTINGS_ALL || what==SETTINGS_ntp_srv) {
|
|
NVSCHECK(nvs_set_str(storage, "ntp_srv", g_Settings.ntp_srv));
|
|
}
|
|
|
|
if (what==SETTINGS_ALL || what==SETTINGS_co2_calib) {
|
|
NVSCHECK(nvs_set_blob(storage, "co2_calib", (void*) g_Settings.co2_calib, 5*sizeof(uint16_t)));
|
|
}
|
|
|
|
if (what==SETTINGS_ALL || what==SETTINGS_bsec_state) {
|
|
NVSCHECK(nvs_set_blob(storage, "bsec_state", (void*) g_Settings.bsec_state, BSEC_MAX_STATE_BLOB_SIZE));
|
|
}
|
|
}
|
|
|
|
uint16_t app_get_bootcount()
|
|
{
|
|
return app_boot_count;
|
|
}
|
|
|