253 lines
6.8 KiB
C
253 lines
6.8 KiB
C
/*******************************************************************************
|
|
* @file app_nvs.c
|
|
* @brief Application persistent settings stored through Zephyr NVS/settings
|
|
******************************************************************************/
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/sys/util.h>
|
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
|
#include <zephyr/settings/settings.h>
|
|
#endif
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
|
|
#include "app_nvs.h"
|
|
#include "main.h"
|
|
#include "debug_print.h"
|
|
|
|
#define APP_NVS_SETTINGS_NAME "vesiscan"
|
|
#define APP_NVS_KEY_PIEZO "piezo"
|
|
#define APP_NVS_KEY_HW_NO "hw"
|
|
#define APP_NVS_KEY_SERIAL_NO "serial"
|
|
#define APP_NVS_KEY_PASSKEY "passkey"
|
|
#define APP_NVS_KEY_PASSKEY_CHANGED "passkey_changed" /* 패스키 1회 변경 완료 플래그 */
|
|
|
|
#define APP_NVS_FULL_KEY_PIEZO "vesiscan/piezo"
|
|
#define APP_NVS_FULL_KEY_HW_NO "vesiscan/hw"
|
|
#define APP_NVS_FULL_KEY_SERIAL_NO "vesiscan/serial"
|
|
#define APP_NVS_FULL_KEY_PASSKEY "vesiscan/passkey"
|
|
#define APP_NVS_FULL_KEY_PASSKEY_CHANGED "vesiscan/passkey_changed" /* 값 0은 변경 가능, 값 1은 변경 차단 */
|
|
|
|
static piezo_config_t *m_piezo_cfg;
|
|
static app_nvs_piezo_validate_fn m_piezo_validate;
|
|
static app_nvs_piezo_log_fn m_piezo_log;
|
|
|
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
|
static int read_exact(settings_read_cb read_cb, void *cb_arg,
|
|
void *dst, size_t expected_len, const char *key)
|
|
{
|
|
int rc = read_cb(cb_arg, dst, expected_len);
|
|
|
|
if (rc < 0)
|
|
{
|
|
DBG_ERR("[NVS] %s read failed err=%d\r\n", key, rc);
|
|
return rc;
|
|
}
|
|
if (rc != expected_len)
|
|
{
|
|
DBG_ERR("[NVS] %s short read (%d)\r\n", key, rc);
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int app_nvs_settings_set(const char *name, size_t len,
|
|
settings_read_cb read_cb, void *cb_arg)
|
|
{
|
|
const char *next;
|
|
|
|
if (settings_name_steq(name, APP_NVS_KEY_PIEZO, &next) && (next == NULL))
|
|
{
|
|
piezo_config_t loaded;
|
|
int err;
|
|
|
|
if (len != sizeof(loaded))
|
|
{
|
|
DBG_ERR("[NVS] piezo size mismatch (%u)\r\n", (uint32_t)len);
|
|
return -EINVAL;
|
|
}
|
|
|
|
err = read_exact(read_cb, cb_arg, &loaded, sizeof(loaded), APP_NVS_KEY_PIEZO);
|
|
if (err)
|
|
{
|
|
return err;
|
|
}
|
|
|
|
if ((m_piezo_cfg == NULL) ||
|
|
((m_piezo_validate != NULL) && !m_piezo_validate(&loaded)))
|
|
{
|
|
DBG_ERR("[NVS] piezo invalid, keep defaults\r\n");
|
|
return 0;
|
|
}
|
|
|
|
*m_piezo_cfg = loaded;
|
|
if (m_piezo_log != NULL)
|
|
{
|
|
m_piezo_log("[NVS] piezo restored", m_piezo_cfg);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
if (settings_name_steq(name, APP_NVS_KEY_HW_NO, &next) && (next == NULL))
|
|
{
|
|
if (len != HW_NO_LENGTH)
|
|
{
|
|
DBG_ERR("[NVS] hw size mismatch (%u)\r\n", (uint32_t)len);
|
|
return -EINVAL;
|
|
}
|
|
|
|
memset(HW_NO, 0, sizeof(HW_NO));
|
|
return read_exact(read_cb, cb_arg, HW_NO, HW_NO_LENGTH, APP_NVS_KEY_HW_NO);
|
|
}
|
|
|
|
if (settings_name_steq(name, APP_NVS_KEY_SERIAL_NO, &next) && (next == NULL))
|
|
{
|
|
if (len != SERIAL_NO_LENGTH)
|
|
{
|
|
DBG_ERR("[NVS] serial size mismatch (%u)\r\n", (uint32_t)len);
|
|
return -EINVAL;
|
|
}
|
|
|
|
memset(SERIAL_NO, 0, sizeof(SERIAL_NO));
|
|
return read_exact(read_cb, cb_arg, SERIAL_NO, SERIAL_NO_LENGTH, APP_NVS_KEY_SERIAL_NO);
|
|
}
|
|
|
|
if (settings_name_steq(name, APP_NVS_KEY_PASSKEY, &next) && (next == NULL))
|
|
{
|
|
if (len != PASSKEY_LENGTH)
|
|
{
|
|
DBG_ERR("[NVS] passkey size mismatch (%u)\r\n", (uint32_t)len);
|
|
return -EINVAL;
|
|
}
|
|
|
|
memset(m_static_passkey, 0, sizeof(m_static_passkey));
|
|
return read_exact(read_cb, cb_arg, m_static_passkey, PASSKEY_LENGTH, APP_NVS_KEY_PASSKEY);
|
|
}
|
|
|
|
if (settings_name_steq(name, APP_NVS_KEY_PASSKEY_CHANGED, &next) && (next == NULL))
|
|
{
|
|
/* 저장된 변경 완료 플래그 복원 */
|
|
if (len != sizeof(m_passkey_changed))
|
|
{
|
|
DBG_ERR("[NVS] passkey_changed size mismatch (%u)\r\n", (uint32_t)len);
|
|
return -EINVAL;
|
|
}
|
|
|
|
return read_exact(read_cb, cb_arg, &m_passkey_changed, sizeof(m_passkey_changed), APP_NVS_KEY_PASSKEY_CHANGED);
|
|
}
|
|
|
|
return -ENOENT;
|
|
}
|
|
|
|
SETTINGS_STATIC_HANDLER_DEFINE(app_nvs_settings,
|
|
APP_NVS_SETTINGS_NAME,
|
|
NULL,
|
|
app_nvs_settings_set,
|
|
NULL,
|
|
NULL);
|
|
#endif
|
|
|
|
int app_nvs_init(piezo_config_t *piezo_cfg,
|
|
app_nvs_piezo_validate_fn piezo_validate,
|
|
app_nvs_piezo_log_fn piezo_log)
|
|
{
|
|
m_piezo_cfg = piezo_cfg;
|
|
m_piezo_validate = piezo_validate;
|
|
m_piezo_log = piezo_log;
|
|
|
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
|
int err = settings_subsys_init();
|
|
|
|
if (err && (err != -EALREADY))
|
|
{
|
|
DBG_ERR("[NVS] settings init failed err=%d\r\n", err);
|
|
return err;
|
|
}
|
|
|
|
err = settings_load_subtree(APP_NVS_SETTINGS_NAME);
|
|
if (err)
|
|
{
|
|
DBG_ERR("[NVS] settings load failed err=%d\r\n", err);
|
|
return err;
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
int app_nvs_save_piezo(const piezo_config_t *cfg)
|
|
{
|
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
|
int err = settings_save_one(APP_NVS_FULL_KEY_PIEZO, cfg, sizeof(*cfg));
|
|
if (err)
|
|
{
|
|
DBG_ERR("[NVS] piezo save failed err=%d\r\n", err);
|
|
}
|
|
return err;
|
|
#else
|
|
ARG_UNUSED(cfg);
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
int app_nvs_save_hw_no(const char *hw_no)
|
|
{
|
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
|
int err = settings_save_one(APP_NVS_FULL_KEY_HW_NO, hw_no, HW_NO_LENGTH);
|
|
if (err)
|
|
{
|
|
DBG_ERR("[NVS] hw save failed err=%d\r\n", err);
|
|
}
|
|
return err;
|
|
#else
|
|
ARG_UNUSED(hw_no);
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
int app_nvs_save_serial_no(const char *serial_no)
|
|
{
|
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
|
int err = settings_save_one(APP_NVS_FULL_KEY_SERIAL_NO, serial_no, SERIAL_NO_LENGTH);
|
|
if (err)
|
|
{
|
|
DBG_ERR("[NVS] serial save failed err=%d\r\n", err);
|
|
}
|
|
return err;
|
|
#else
|
|
ARG_UNUSED(serial_no);
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
int app_nvs_save_passkey(const char *passkey)
|
|
{
|
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
|
int err = settings_save_one(APP_NVS_FULL_KEY_PASSKEY, passkey, PASSKEY_LENGTH);
|
|
if (err)
|
|
{
|
|
DBG_ERR("[NVS] passkey save failed err=%d\r\n", err);
|
|
}
|
|
return err;
|
|
#else
|
|
ARG_UNUSED(passkey);
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
int app_nvs_save_passkey_changed(uint8_t changed)
|
|
{
|
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
|
/* 패스키 변경 성공 후 재부팅해도 재변경 차단 */
|
|
int err = settings_save_one(APP_NVS_FULL_KEY_PASSKEY_CHANGED, &changed, sizeof(changed));
|
|
if (err)
|
|
{
|
|
DBG_ERR("[NVS] passkey_changed save failed err=%d\r\n", err);
|
|
}
|
|
return err;
|
|
#else
|
|
ARG_UNUSED(changed);
|
|
return 0;
|
|
#endif
|
|
}
|