/******************************************************************************* * @file app_nvs.c * @brief Application persistent settings stored through Zephyr NVS/settings ******************************************************************************/ #include #include #if IS_ENABLED(CONFIG_SETTINGS) #include #endif #include #include #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 }