BLE 보안, 패스키 등
This commit is contained in:
+28
-21
@@ -14,26 +14,31 @@
|
||||
#include "main.h"
|
||||
#include "debug_print.h"
|
||||
|
||||
/* Zephyr settings에서 사용할 저장소 이름 */
|
||||
#define APP_NVS_SETTINGS_NAME "vesiscan"
|
||||
|
||||
/* 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_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은 변경 차단 */
|
||||
/* settings_save_one에 넘기는 전체 키 */
|
||||
#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은 변경 차단 */
|
||||
|
||||
/* parser.c가 가진 피에조 설정을 NVS 로드 시 갱신하기 위한 포인터 */
|
||||
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)
|
||||
/* 고정 길이 설정값을 정확한 크기로 읽기 */
|
||||
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);
|
||||
|
||||
@@ -51,11 +56,11 @@ static int read_exact(settings_read_cb read_cb, void *cb_arg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int app_nvs_settings_set(const char *name, size_t len,
|
||||
settings_read_cb read_cb, void *cb_arg)
|
||||
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;
|
||||
@@ -88,6 +93,7 @@ static int app_nvs_settings_set(const char *name, size_t len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* HW Version은 NUL 종료 없이 고정 길이 ASCII로 저장 */
|
||||
if (settings_name_steq(name, APP_NVS_KEY_HW_NO, &next) && (next == NULL))
|
||||
{
|
||||
if (len != HW_NO_LENGTH)
|
||||
@@ -100,6 +106,7 @@ static int app_nvs_settings_set(const char *name, size_t len,
|
||||
return read_exact(read_cb, cb_arg, HW_NO, HW_NO_LENGTH, APP_NVS_KEY_HW_NO);
|
||||
}
|
||||
|
||||
/* Serial Number는 NUL 종료 없이 고정 길이 ASCII로 저장 */
|
||||
if (settings_name_steq(name, APP_NVS_KEY_SERIAL_NO, &next) && (next == NULL))
|
||||
{
|
||||
if (len != SERIAL_NO_LENGTH)
|
||||
@@ -112,6 +119,7 @@ static int app_nvs_settings_set(const char *name, size_t len,
|
||||
return read_exact(read_cb, cb_arg, SERIAL_NO, SERIAL_NO_LENGTH, APP_NVS_KEY_SERIAL_NO);
|
||||
}
|
||||
|
||||
/* 패스키는 mpz? 명령으로 최초 1회만 저장 */
|
||||
if (settings_name_steq(name, APP_NVS_KEY_PASSKEY, &next) && (next == NULL))
|
||||
{
|
||||
if (len != PASSKEY_LENGTH)
|
||||
@@ -126,7 +134,7 @@ static int app_nvs_settings_set(const char *name, size_t len,
|
||||
|
||||
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);
|
||||
@@ -139,18 +147,13 @@ static int app_nvs_settings_set(const char *name, size_t len,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
SETTINGS_STATIC_HANDLER_DEFINE(app_nvs_settings,
|
||||
APP_NVS_SETTINGS_NAME,
|
||||
NULL,
|
||||
app_nvs_settings_set,
|
||||
NULL,
|
||||
NULL);
|
||||
/* Zephyr settings에 vesiscan 저장소만 등록 */
|
||||
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)
|
||||
int app_nvs_init(piezo_config_t *piezo_cfg, app_nvs_piezo_validate_fn piezo_validate, app_nvs_piezo_log_fn piezo_log)
|
||||
{
|
||||
/* settings_load_subtree가 호출되기 전에 복원용 포인터와 콜백 저장 */
|
||||
m_piezo_cfg = piezo_cfg;
|
||||
m_piezo_validate = piezo_validate;
|
||||
m_piezo_log = piezo_log;
|
||||
@@ -178,6 +181,7 @@ int app_nvs_init(piezo_config_t *piezo_cfg,
|
||||
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)
|
||||
{
|
||||
@@ -193,6 +197,7 @@ int app_nvs_save_piezo(const piezo_config_t *cfg)
|
||||
int app_nvs_save_hw_no(const char *hw_no)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||
/* 고정 길이 HW Version 저장 */
|
||||
int err = settings_save_one(APP_NVS_FULL_KEY_HW_NO, hw_no, HW_NO_LENGTH);
|
||||
if (err)
|
||||
{
|
||||
@@ -208,6 +213,7 @@ int app_nvs_save_hw_no(const char *hw_no)
|
||||
int app_nvs_save_serial_no(const char *serial_no)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||
/* 고정 길이 Serial Number 저장 */
|
||||
int err = settings_save_one(APP_NVS_FULL_KEY_SERIAL_NO, serial_no, SERIAL_NO_LENGTH);
|
||||
if (err)
|
||||
{
|
||||
@@ -223,6 +229,7 @@ int app_nvs_save_serial_no(const char *serial_no)
|
||||
int app_nvs_save_passkey(const char *passkey)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||
/* mpz? 명령이 허용된 뒤 고정 길이 패스키 저장 */
|
||||
int err = settings_save_one(APP_NVS_FULL_KEY_PASSKEY, passkey, PASSKEY_LENGTH);
|
||||
if (err)
|
||||
{
|
||||
@@ -238,7 +245,7 @@ int app_nvs_save_passkey(const char *passkey)
|
||||
int app_nvs_save_passkey_changed(uint8_t changed)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||
/* 패스키 변경 성공 후 재부팅해도 재변경 차단 */
|
||||
/* 재부팅 후에도 mpz?(패스키 변경) 재실행을 막기 위한 플래그 저장(NVS) */
|
||||
int err = settings_save_one(APP_NVS_FULL_KEY_PASSKEY_CHANGED, &changed, sizeof(changed));
|
||||
if (err)
|
||||
{
|
||||
|
||||
+254
-9
@@ -15,8 +15,12 @@
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||
#include <zephyr/settings/settings.h>
|
||||
#endif
|
||||
#include <zephyr/mgmt/mcumgr/transport/smp_bt.h>
|
||||
#include <bluetooth/services/nus.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "ble_service.h"
|
||||
#include "main.h"
|
||||
@@ -30,6 +34,12 @@ LOG_MODULE_REGISTER(ble_svc, LOG_LEVEL_INF);
|
||||
*============================================================================*/
|
||||
static struct bt_conn *current_conn;
|
||||
static ble_data_rx_cb_t rx_callback;
|
||||
static bool dfu_advertising_mode;
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
#define BLE_REQUIRED_SECURITY_LEVEL BT_SECURITY_L4
|
||||
static uint32_t pairing_passkey = BT_PASSKEY_RAND;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NUS 전송은 "보냈다" 호출만 한다고 바로 끝나는 게 아니다.
|
||||
@@ -118,6 +128,142 @@ static int ble_configure_fixed_identity(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
static bool ble_conn_is_secure(const struct bt_conn *conn)
|
||||
{
|
||||
return (conn != NULL) && (bt_conn_get_security(conn) >= BLE_REQUIRED_SECURITY_LEVEL);
|
||||
}
|
||||
|
||||
static int ble_passkey_to_uint(const char *passkey, unsigned int *value)
|
||||
{
|
||||
unsigned int parsed = 0U;
|
||||
|
||||
if ((passkey == NULL) || (value == NULL))
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < PASSKEY_LENGTH; i++)
|
||||
{
|
||||
if ((passkey[i] < '0') || (passkey[i] > '9'))
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
parsed = (parsed * 10U) + (unsigned int)(passkey[i] - '0');
|
||||
}
|
||||
|
||||
*value = parsed;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ble_security_configure(void)
|
||||
{
|
||||
unsigned int passkey;
|
||||
int err = ble_passkey_to_uint(m_static_passkey, &passkey);
|
||||
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[BLE] Invalid stored passkey, using default\r\n");
|
||||
memset(m_static_passkey, 0, sizeof(m_static_passkey));
|
||||
memcpy(m_static_passkey, DEFAULT_PASSKEY, PASSKEY_LENGTH);
|
||||
|
||||
err = ble_passkey_to_uint(m_static_passkey, &passkey);
|
||||
if (err)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
pairing_passkey = passkey;
|
||||
DBG_CORE("[BLE] Fixed passkey configured\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void auth_pairing_confirm(struct bt_conn *conn)
|
||||
{
|
||||
int err = bt_conn_auth_pairing_confirm(conn);
|
||||
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[BLE] Pairing confirm failed err=%d\r\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
DBG_CORE("[BLE] Pairing confirmed\r\n");
|
||||
}
|
||||
|
||||
static void auth_cancel(struct bt_conn *conn)
|
||||
{
|
||||
ARG_UNUSED(conn);
|
||||
DBG_ERR("[BLE] Pairing cancelled\r\n");
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_APP_PASSKEY)
|
||||
static uint32_t auth_app_passkey(struct bt_conn *conn)
|
||||
{
|
||||
unsigned int passkey;
|
||||
|
||||
ARG_UNUSED(conn);
|
||||
|
||||
if (ble_passkey_to_uint(m_static_passkey, &passkey) == 0)
|
||||
{
|
||||
return passkey;
|
||||
}
|
||||
|
||||
DBG_ERR("[BLE] Invalid runtime passkey, using configured fallback\r\n");
|
||||
return pairing_passkey;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct bt_conn_auth_cb auth_cb =
|
||||
{
|
||||
.pairing_confirm = auth_pairing_confirm,
|
||||
.cancel = auth_cancel,
|
||||
#if IS_ENABLED(CONFIG_BT_APP_PASSKEY)
|
||||
.app_passkey = auth_app_passkey,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void auth_pairing_complete(struct bt_conn *conn, bool bonded)
|
||||
{
|
||||
ARG_UNUSED(conn);
|
||||
DBG_CORE("[BLE] Pairing complete bonded=%u\r\n", bonded ? 1U : 0U);
|
||||
}
|
||||
|
||||
static void auth_pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
|
||||
{
|
||||
DBG_ERR("[BLE] Pairing failed reason=%u\r\n", reason);
|
||||
(void)bt_conn_disconnect(conn, BT_HCI_ERR_AUTH_FAIL);
|
||||
}
|
||||
|
||||
static struct bt_conn_auth_info_cb auth_info_cb =
|
||||
{
|
||||
.pairing_complete = auth_pairing_complete,
|
||||
.pairing_failed = auth_pairing_failed,
|
||||
};
|
||||
|
||||
static int ble_security_init(void)
|
||||
{
|
||||
int err = bt_conn_auth_cb_register(&auth_cb);
|
||||
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[BLE] auth cb register failed err=%d\r\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = bt_conn_auth_info_cb_register(&auth_info_cb);
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[BLE] auth info cb register failed err=%d\r\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return ble_security_configure();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void adv_restart_handler(struct k_work *work)
|
||||
{
|
||||
ARG_UNUSED(work);
|
||||
@@ -136,13 +282,14 @@ static const struct bt_data ad[] =
|
||||
|
||||
static const struct bt_data sd[] =
|
||||
{
|
||||
/*
|
||||
* Legacy NUS + DFU(SMP) UUIDs together exceed the 31-byte scan response
|
||||
* limit for legacy advertising. Keep the device name in the advertising
|
||||
* packet and expose only SMP here so DFU remains discoverable.
|
||||
|
||||
BT_DATA_BYTES(BT_DATA_UUID128_SOME, SMP_BT_SVC_UUID_VAL), // BLE DFU 동작을 위한 SMP UUDI 광고 */
|
||||
BT_DATA_BYTES(BT_DATA_UUID128_SOME, BT_UUID_NUS_VAL), // UUID에 NUS 안 넣으면 Web bluetooth 앱에서 안 보임
|
||||
/* 평상시 Web Bluetooth 앱이 찾을 수 있도록 NUS UUID 광고 */
|
||||
BT_DATA_BYTES(BT_DATA_UUID128_SOME, BT_UUID_NUS_VAL),
|
||||
};
|
||||
|
||||
static const struct bt_data sd_dfu[] =
|
||||
{
|
||||
/* DFU 진입 후 mcumgr 앱이 찾을 수 있도록 SMP UUID 광고 */
|
||||
BT_DATA_BYTES(BT_DATA_UUID128_SOME, SMP_BT_SVC_UUID_VAL),
|
||||
};
|
||||
|
||||
/*==============================================================================
|
||||
@@ -175,6 +322,17 @@ static void connected(struct bt_conn *conn, uint8_t err)
|
||||
};
|
||||
bt_conn_le_param_update(conn, &conn_param);
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
err = bt_conn_set_security(conn, BLE_REQUIRED_SECURITY_LEVEL);
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[BLE] Security request failed err=%d\r\n", err);
|
||||
(void)bt_conn_disconnect(conn, BT_HCI_ERR_AUTH_FAIL);
|
||||
return;
|
||||
}
|
||||
DBG_CORE("[BLE] Security requested level=%u\r\n", BLE_REQUIRED_SECURITY_LEVEL);
|
||||
#endif
|
||||
|
||||
led_set_state(LED_STATE_OFF);
|
||||
DBG_CORE("[BLE] Connected\r\n");
|
||||
}
|
||||
@@ -201,11 +359,30 @@ static void le_param_updated(struct bt_conn *conn, uint16_t interval,
|
||||
interval, latency, timeout);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
static void security_changed(struct bt_conn *conn, bt_security_t level,
|
||||
enum bt_security_err err)
|
||||
{
|
||||
ARG_UNUSED(conn);
|
||||
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[BLE] Security failed level=%u err=%u\r\n", level, err);
|
||||
return;
|
||||
}
|
||||
|
||||
DBG_CORE("[BLE] Security ready level=%u\r\n", level);
|
||||
}
|
||||
#endif
|
||||
|
||||
BT_CONN_CB_DEFINE(conn_callbacks) =
|
||||
{
|
||||
.connected = connected,
|
||||
.disconnected = disconnected,
|
||||
.le_param_updated = le_param_updated,
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
.security_changed = security_changed,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*==============================================================================
|
||||
@@ -213,7 +390,15 @@ BT_CONN_CB_DEFINE(conn_callbacks) =
|
||||
*============================================================================*/
|
||||
static void nus_received(struct bt_conn *conn, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
if (!ble_conn_is_secure(conn))
|
||||
{
|
||||
DBG_ERR("[NUS RX] blocked until BLE security is ready\r\n");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
ARG_UNUSED(conn);
|
||||
#endif
|
||||
|
||||
DBG_CORE("[NUS RX] len=%u\r\n", len);
|
||||
if (rx_callback)
|
||||
@@ -264,8 +449,26 @@ int ble_service_init(ble_data_rx_cb_t rx_cb)
|
||||
}
|
||||
DBG_CORE("[BLE] Stack enabled\r\n");
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_SETTINGS)
|
||||
err = settings_load_subtree("bt");
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[BLE] BT settings load failed err=%d\r\n", err);
|
||||
return err;
|
||||
}
|
||||
DBG_CORE("[BLE] BT settings loaded\r\n");
|
||||
#endif
|
||||
|
||||
ble_log_local_identity();
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
err = ble_security_init();
|
||||
if (err)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize NUS */
|
||||
err = bt_nus_init(&nus_cb);
|
||||
if (err)
|
||||
@@ -281,6 +484,8 @@ int ble_service_init(ble_data_rx_cb_t rx_cb)
|
||||
int ble_advertising_start(void)
|
||||
{
|
||||
int err;
|
||||
const struct bt_data *scan_data = dfu_advertising_mode ? sd_dfu : sd;
|
||||
size_t scan_data_count = dfu_advertising_mode ? ARRAY_SIZE(sd_dfu) : ARRAY_SIZE(sd);
|
||||
|
||||
struct bt_le_adv_param adv_param = BT_LE_ADV_PARAM_INIT(
|
||||
BT_LE_ADV_OPT_CONN,
|
||||
@@ -289,14 +494,14 @@ int ble_advertising_start(void)
|
||||
NULL /* undirected */
|
||||
);
|
||||
|
||||
err = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
|
||||
err = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad), scan_data, scan_data_count);
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[BLE] Adv start failed (err %d)\r\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
DBG_PRINTF("[BLE] Advertising started\r\n");
|
||||
DBG_PRINTF("[BLE] Advertising started (%s)\r\n", dfu_advertising_mode ? "SMP" : "NUS");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -313,6 +518,38 @@ int ble_advertising_stop(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_dfu_advertising_enable(void)
|
||||
{
|
||||
if (dfu_advertising_mode)
|
||||
{
|
||||
DBG_ERR("[BLE] DFU advertising already enabled\r\n");
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
/* mdf? 응답 전송 후 현재 연결을 끊고 SMP UUID 광고로 재시작 */
|
||||
dfu_advertising_mode = true;
|
||||
DBG_PRINTF("[BLE] DFU advertising mode enabled\r\n");
|
||||
|
||||
if (current_conn)
|
||||
{
|
||||
int err = bt_conn_disconnect(current_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[BLE] DFU disconnect failed err=%d\r\n", err);
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void)ble_advertising_stop();
|
||||
return ble_advertising_start();
|
||||
}
|
||||
|
||||
bool ble_dfu_advertising_is_enabled(void)
|
||||
{
|
||||
return dfu_advertising_mode;
|
||||
}
|
||||
|
||||
int ble_data_send(const uint8_t *data, uint16_t len)
|
||||
{
|
||||
int err;
|
||||
@@ -323,6 +560,14 @@ int ble_data_send(const uint8_t *data, uint16_t len)
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
if (!ble_conn_is_secure(current_conn))
|
||||
{
|
||||
DBG_ERR("[NUS TX] blocked until BLE security is ready\r\n");
|
||||
return -EACCES;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NUS는 한 번에 한 패킷씩 질서 있게 보내는 편이 안전하다.
|
||||
* 특히 mbb?는 rbb + reb x6 + raa처럼 여러 응답을 연속 전송하므로
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
/*==============================================================================
|
||||
* BLE configuration
|
||||
*============================================================================*/
|
||||
#define BLE_DEV_MODE 1 /* 1: Dev (no security), 0: Production */
|
||||
#define BLE_DEV_MODE 0 /* 1: Dev (no security), 0: Production */
|
||||
|
||||
#define APP_ADV_INTERVAL 64 /* 64 x 0.625ms = 40ms */
|
||||
#define APP_ADV_DURATION 18000 /* 18000 x 10ms = 180s (3 min) */
|
||||
@@ -39,6 +39,8 @@ int ble_service_init(ble_data_rx_cb_t rx_cb);
|
||||
int ble_advertising_start(void);
|
||||
int ble_advertising_stop(void);
|
||||
int ble_data_send(const uint8_t *data, uint16_t len);
|
||||
int ble_dfu_advertising_enable(void);
|
||||
bool ble_dfu_advertising_is_enabled(void);
|
||||
bool ble_is_connected(void);
|
||||
|
||||
#endif /* BLE_SERVICE_H__ */
|
||||
|
||||
Reference in New Issue
Block a user