패스키 최초 1회 변경 가능 제한
This commit is contained in:
@@ -19,11 +19,13 @@
|
||||
#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;
|
||||
@@ -122,6 +124,18 @@ static int app_nvs_settings_set(const char *name, size_t len,
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -220,3 +234,19 @@ int app_nvs_save_passkey(const char *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
|
||||
}
|
||||
|
||||
@@ -20,5 +20,6 @@ int app_nvs_save_piezo(const piezo_config_t *cfg);
|
||||
int app_nvs_save_hw_no(const char *hw_no);
|
||||
int app_nvs_save_serial_no(const char *serial_no);
|
||||
int app_nvs_save_passkey(const char *passkey);
|
||||
int app_nvs_save_passkey_changed(uint8_t changed);
|
||||
|
||||
#endif /* APP_NVS_H__ */
|
||||
|
||||
@@ -67,6 +67,7 @@ uint8_t m_reset_status = 1; /* 리셋 상태 코드 */
|
||||
char SERIAL_NO[SERIAL_NO_BUF_SIZE]; /* 시리얼 번호 */
|
||||
char HW_NO[HW_NO_BUF_SIZE]; /* 하드웨어 번호 */
|
||||
char m_static_passkey[PASSKEY_BUF_SIZE]; /* BLE 정적 패스키 */
|
||||
uint8_t m_passkey_changed; /* 패스키 변경은 출고 후 1회만 허용 */
|
||||
|
||||
static uint16_t cnt_s; /* 전원 버튼 폴링 카운터 (5ms 단위) */
|
||||
static bool device_on = false; /* 디바이스 전원 상태 (래치 완료 여부) */
|
||||
@@ -310,6 +311,9 @@ static void load_default_config(void)
|
||||
memset(m_static_passkey, 0, sizeof(m_static_passkey));
|
||||
memcpy(m_static_passkey, DEFAULT_PASSKEY, passkey_len);
|
||||
|
||||
/* NVS 로드 전 기본값은 변경 가능 상태 */
|
||||
m_passkey_changed = 0U;
|
||||
|
||||
/* 기본 상태값 */
|
||||
m_reset_status = 1;
|
||||
bond_data_delete = true;
|
||||
|
||||
@@ -74,6 +74,7 @@ extern volatile bool processing;
|
||||
extern char SERIAL_NO[SERIAL_NO_BUF_SIZE];
|
||||
extern char HW_NO[HW_NO_BUF_SIZE];
|
||||
extern char m_static_passkey[PASSKEY_BUF_SIZE];
|
||||
extern uint8_t m_passkey_changed;
|
||||
extern bool bond_data_delete;
|
||||
extern uint32_t m_life_cycle;
|
||||
extern uint8_t m_reset_status;
|
||||
|
||||
+111
-3
@@ -9,6 +9,11 @@
|
||||
******************************************************************************/
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/sys/reboot.h>
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
@@ -131,6 +136,12 @@ int piezo_config_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void reboot_after_response(void)
|
||||
{
|
||||
k_msleep(100);
|
||||
sys_reboot(SYS_REBOOT_COLD);
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* CRC16 (CRC-CCITT, Nordic SDK 호환)
|
||||
*============================================================================*/
|
||||
@@ -697,6 +708,77 @@ static int cmd_msn(const uint8_t *data, uint8_t data_len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_msq(const uint8_t *data, uint8_t data_len)
|
||||
{
|
||||
ARG_UNUSED(data);
|
||||
ARG_UNUSED(data_len);
|
||||
|
||||
int err = send_response_u16("rsq:", 0x0000);
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[CMD] msq tx failed err=%d\r\n", err);
|
||||
}
|
||||
|
||||
DBG_PRINTF("[CMD] msq -> power off\r\n");
|
||||
sleep_mode_enter();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_mss(const uint8_t *data, uint8_t data_len)
|
||||
{
|
||||
ARG_UNUSED(data);
|
||||
ARG_UNUSED(data_len);
|
||||
|
||||
int err = send_response_u16("rss:", 0x0000);
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[CMD] mss tx failed err=%d\r\n", err);
|
||||
}
|
||||
|
||||
DBG_PRINTF("[CMD] mss -> reboot\r\n");
|
||||
reboot_after_response();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_msr(const uint8_t *data, uint8_t data_len)
|
||||
{
|
||||
uint16_t status = 0x0000;
|
||||
|
||||
ARG_UNUSED(data);
|
||||
ARG_UNUSED(data_len);
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
int err = bt_unpair(BT_ID_DEFAULT, NULL);
|
||||
if (err)
|
||||
{
|
||||
status = (uint16_t)(-err);
|
||||
DBG_ERR("[CMD] msr bt_unpair failed err=%d\r\n", err);
|
||||
}
|
||||
else
|
||||
{
|
||||
bond_data_delete = true;
|
||||
DBG_PRINTF("[CMD] msr bond data deleted\r\n");
|
||||
}
|
||||
#else
|
||||
bond_data_delete = true;
|
||||
DBG_PRINTF("[CMD] msr bond delete skipped (BT_SMP disabled)\r\n");
|
||||
#endif
|
||||
|
||||
int tx_err = send_response_u16("rsr:", status);
|
||||
if (tx_err)
|
||||
{
|
||||
DBG_ERR("[CMD] msr tx failed err=%d\r\n", tx_err);
|
||||
}
|
||||
|
||||
if (status == 0x0000)
|
||||
{
|
||||
DBG_PRINTF("[CMD] msr -> reboot\r\n");
|
||||
reboot_after_response();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* msp? → IMU 1회 측정 → rsp: + accel XYZ + gyro XYZ (각 int16 빅엔디안) */
|
||||
static int cmd_msp(const uint8_t *data, uint8_t data_len)
|
||||
{
|
||||
@@ -1328,15 +1410,38 @@ static int cmd_mpz(const uint8_t *data, uint8_t data_len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(m_static_passkey, 0, sizeof(m_static_passkey));
|
||||
memcpy(m_static_passkey, data, PASSKEY_LENGTH);
|
||||
int err = app_nvs_save_passkey(m_static_passkey);
|
||||
if (m_passkey_changed != 0U)
|
||||
{
|
||||
/* 패스키가 변경된 경우 다시 바꿀 수 없음(FFFF 반환) */
|
||||
send_response_u16("rpz:", 0xFFFF);
|
||||
DBG_PRINTF("[CMD] mpz: passkey already changed\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* NVS 저장이 모두 성공한 뒤 RAM 값 확정 */
|
||||
char new_passkey[PASSKEY_BUF_SIZE];
|
||||
memset(new_passkey, 0, sizeof(new_passkey));
|
||||
memcpy(new_passkey, data, PASSKEY_LENGTH);
|
||||
|
||||
int err = app_nvs_save_passkey(new_passkey);
|
||||
if (err)
|
||||
{
|
||||
send_response_u16("rpz:", 0xFFFD);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 변경 완료 플래그 세트 : 다음 mpz? 명령 차단 */
|
||||
err = app_nvs_save_passkey_changed(1U);
|
||||
if (err)
|
||||
{
|
||||
send_response_u16("rpz:", 0xFFFD);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(m_static_passkey, 0, sizeof(m_static_passkey));
|
||||
memcpy(m_static_passkey, new_passkey, PASSKEY_LENGTH);
|
||||
m_passkey_changed = 1U;
|
||||
|
||||
send_response_ascii("rpz:", m_static_passkey, PASSKEY_LENGTH);
|
||||
DBG_PRINTF("[CMD] mpz updated\r\n");
|
||||
return 1;
|
||||
@@ -1396,6 +1501,9 @@ typedef struct
|
||||
|
||||
static const cmd_entry_t cmd_table[] =
|
||||
{
|
||||
{ "msq?", cmd_msq },
|
||||
{ "mss?", cmd_mss },
|
||||
{ "msr?", cmd_msr },
|
||||
{ "msn?", cmd_msn },
|
||||
{ "mls?", cmd_mls },
|
||||
{ "msp?", cmd_msp },
|
||||
|
||||
Reference in New Issue
Block a user