Initial Commit
This commit is contained in:
+34
-75
@@ -31,9 +31,7 @@
|
||||
|
||||
LOG_MODULE_REGISTER(ble_svc, LOG_LEVEL_INF);
|
||||
|
||||
/*==============================================================================
|
||||
* Module variables
|
||||
*============================================================================*/
|
||||
/* Module variables */
|
||||
static struct bt_conn *current_conn;
|
||||
static ble_data_rx_cb_t rx_callback;
|
||||
static bool dfu_advertising_mode;
|
||||
@@ -43,6 +41,7 @@ static int64_t last_rx_conn_param_update_ms;
|
||||
|
||||
#define BLE_TX_POWER_NORMAL_DBM 4
|
||||
#define BLE_TX_POWER_STRESS_DBM 8
|
||||
#define BLE_RSSI_MONITOR_ENABLED 0
|
||||
#define BLE_RSSI_STRESS_DBM (-80)
|
||||
#define BLE_RSSI_STRESS_COUNT 3
|
||||
#define BLE_RSSI_MONITOR_INTERVAL_MS 500
|
||||
@@ -68,7 +67,7 @@ static uint32_t pairing_passkey = BT_PASSKEY_RAND;
|
||||
|
||||
/*
|
||||
* - mutex: 여러 곳에서 동시에 NUS 전송을 시작하지 못하게 막음
|
||||
* - sem : "직전 전송이 정말 끝났는지" 기다리는 신호
|
||||
* - sem : 직전 전송이 정말 끝났는지 기다리는 신호
|
||||
*/
|
||||
static struct k_mutex nus_tx_lock;
|
||||
static struct k_sem nus_tx_done_sem;
|
||||
@@ -195,6 +194,11 @@ static void tx_power_monitor_handler(struct k_work *work)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!BLE_RSSI_MONITOR_ENABLED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
err = ble_read_conn_rssi(&rssi);
|
||||
if (err)
|
||||
{
|
||||
@@ -221,23 +225,6 @@ static void tx_power_monitor_handler(struct k_work *work)
|
||||
K_MSEC(BLE_RSSI_MONITOR_INTERVAL_MS));
|
||||
}
|
||||
|
||||
static const char *ble_addr_type_str(uint8_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case BT_ADDR_LE_PUBLIC:
|
||||
return "public";
|
||||
case BT_ADDR_LE_RANDOM:
|
||||
return "random";
|
||||
case BT_ADDR_LE_PUBLIC_ID:
|
||||
return "public-id";
|
||||
case BT_ADDR_LE_RANDOM_ID:
|
||||
return "random-id";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_log_local_identity(void)
|
||||
{
|
||||
bt_addr_le_t addr = {0};
|
||||
@@ -463,8 +450,7 @@ static int ble_request_preferred_conn_params(bool count_attempt)
|
||||
err = bt_conn_le_param_update(current_conn, &conn_param);
|
||||
if (err)
|
||||
{
|
||||
DBG_ERR("[BLE] Param update failed err=%d -> disconnect\r\n", err);
|
||||
(void)bt_conn_disconnect(current_conn, BT_HCI_ERR_UNACCEPT_CONN_PARAM);
|
||||
DBG_ERR("[BLE] Param update failed err=%d\r\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -493,25 +479,21 @@ static void conn_param_update_handler(struct k_work *work)
|
||||
}
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Advertising data
|
||||
*============================================================================*/
|
||||
/* Advertising data */
|
||||
|
||||
static const struct bt_data sd[] =
|
||||
{
|
||||
/* 평상시 Web Bluetooth 앱이 찾을 수 있도록 NUS UUID 광고 */
|
||||
BT_DATA_BYTES(BT_DATA_UUID128_SOME, BT_UUID_NUS_VAL),
|
||||
// 평상시 Web Bluetooth 앱이 찾을 수 있도록 NUS UUID 광고
|
||||
BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_NUS_VAL),
|
||||
};
|
||||
|
||||
static const struct bt_data sd_dfu[] =
|
||||
{
|
||||
/* DFU 진입 후 mcumgr 앱이 찾을 수 있도록 SMP UUID 광고 */
|
||||
// DFU 진입 후 mcumgr 앱이 찾을 수 있도록 SMP UUID 광고
|
||||
BT_DATA_BYTES(BT_DATA_UUID128_SOME, SMP_BT_SVC_UUID_VAL),
|
||||
};
|
||||
|
||||
/*==============================================================================
|
||||
* Connection callbacks
|
||||
*============================================================================*/
|
||||
/* Connection callbacks */
|
||||
static void connected(struct bt_conn *conn, uint8_t err)
|
||||
{
|
||||
if (err)
|
||||
@@ -528,7 +510,10 @@ static void connected(struct bt_conn *conn, uint8_t err)
|
||||
low_rssi_count = 0U;
|
||||
slow_tx_count = 0U;
|
||||
(void)ble_set_conn_tx_power(BLE_TX_POWER_NORMAL_DBM, "connected");
|
||||
k_work_schedule(&tx_power_monitor_work, K_MSEC(BLE_RSSI_MONITOR_INTERVAL_MS));
|
||||
if (BLE_RSSI_MONITOR_ENABLED)
|
||||
{
|
||||
k_work_schedule(&tx_power_monitor_work, K_MSEC(BLE_RSSI_MONITOR_INTERVAL_MS));
|
||||
}
|
||||
|
||||
/* 연결 정보 출력 */
|
||||
char addr_str[BT_ADDR_LE_STR_LEN];
|
||||
@@ -537,8 +522,6 @@ static void connected(struct bt_conn *conn, uint8_t err)
|
||||
|
||||
conn_param_update_attempts = 0U;
|
||||
last_rx_conn_param_update_ms = 0;
|
||||
k_work_schedule(&conn_param_update_work,
|
||||
K_MSEC(BLE_CONN_PARAM_FIRST_DELAY_MS));
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
err = bt_conn_set_security(conn, BLE_REQUIRED_SECURITY_LEVEL);
|
||||
@@ -578,29 +561,14 @@ static void disconnected(struct bt_conn *conn, uint8_t reason)
|
||||
reason,
|
||||
advertising_unlimited ? "unlimited" : "10min");
|
||||
|
||||
/* 워크큐에서 advertising 재시작 */
|
||||
// 워크큐에서 advertising 재시작
|
||||
k_work_submit(&adv_restart_work);
|
||||
}
|
||||
|
||||
static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param)
|
||||
{
|
||||
ARG_UNUSED(conn);
|
||||
|
||||
if (!ble_conn_param_is_preferred(param->interval_min,
|
||||
param->latency,
|
||||
param->timeout) ||
|
||||
(param->interval_max != BLE_MAX_CONN_INTERVAL))
|
||||
{
|
||||
DBG_PRINTF("[BLE] Override requested params: min=%u max=%u latency=%u timeout=%u\r\n",
|
||||
param->interval_min,
|
||||
param->interval_max,
|
||||
param->latency,
|
||||
param->timeout);
|
||||
param->interval_min = BLE_MIN_CONN_INTERVAL;
|
||||
param->interval_max = BLE_MAX_CONN_INTERVAL;
|
||||
param->latency = BLE_SLAVE_LATENCY;
|
||||
param->timeout = BLE_CONN_SUP_TIMEOUT;
|
||||
}
|
||||
ARG_UNUSED(param);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -646,9 +614,7 @@ BT_CONN_CB_DEFINE(conn_callbacks) =
|
||||
#endif
|
||||
};
|
||||
|
||||
/*==============================================================================
|
||||
* NUS callbacks
|
||||
*============================================================================*/
|
||||
/* NUS callbacks */
|
||||
static void nus_received(struct bt_conn *conn, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_BT_SMP)
|
||||
@@ -661,18 +627,13 @@ static void nus_received(struct bt_conn *conn, const uint8_t *data, uint16_t len
|
||||
ARG_UNUSED(conn);
|
||||
#endif
|
||||
|
||||
DBG_CORE("[NUS RX] len=%u\r\n", len);
|
||||
//DBG_CORE("[NUS RX] len=%u\r\n", len);
|
||||
|
||||
if (current_conn == conn)
|
||||
{
|
||||
int64_t now_ms = k_uptime_get();
|
||||
|
||||
if ((last_rx_conn_param_update_ms == 0) ||
|
||||
((now_ms - last_rx_conn_param_update_ms) >= BLE_CONN_PARAM_RETRY_INTERVAL_MS))
|
||||
{
|
||||
last_rx_conn_param_update_ms = now_ms;
|
||||
(void)ble_request_preferred_conn_params(false);
|
||||
}
|
||||
ARG_UNUSED(now_ms);
|
||||
}
|
||||
|
||||
if (rx_callback)
|
||||
@@ -684,7 +645,7 @@ static void nus_received(struct bt_conn *conn, const uint8_t *data, uint16_t len
|
||||
static void nus_sent(struct bt_conn *conn)
|
||||
{
|
||||
ARG_UNUSED(conn);
|
||||
/* 직전 NUS 패킷 전송 완료 */
|
||||
// 직전 NUS 패킷 전송 완료
|
||||
k_sem_give(&nus_tx_done_sem);
|
||||
//DBG_CORE("[NUS TX] complete\r\n");
|
||||
}
|
||||
@@ -695,9 +656,7 @@ static struct bt_nus_cb nus_cb =
|
||||
.sent = nus_sent,
|
||||
};
|
||||
|
||||
/*==============================================================================
|
||||
* Public functions
|
||||
*============================================================================*/
|
||||
/* Public functions */
|
||||
int ble_service_init(ble_data_rx_cb_t rx_cb)
|
||||
{
|
||||
int err;
|
||||
@@ -711,7 +670,7 @@ int ble_service_init(ble_data_rx_cb_t rx_cb)
|
||||
k_work_init_delayable(&conn_param_update_work, conn_param_update_handler);
|
||||
|
||||
k_work_init_delayable(&tx_power_monitor_work, tx_power_monitor_handler);
|
||||
/* Enable BLE stack */
|
||||
// Enable BLE stack
|
||||
err = bt_enable(NULL);
|
||||
if (err)
|
||||
{
|
||||
@@ -740,7 +699,7 @@ int ble_service_init(ble_data_rx_cb_t rx_cb)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize NUS */
|
||||
// Initialize NUS
|
||||
err = bt_nus_init(&nus_cb);
|
||||
if (err)
|
||||
{
|
||||
@@ -766,9 +725,9 @@ int ble_advertising_start(void)
|
||||
|
||||
struct bt_le_adv_param adv_param = BT_LE_ADV_PARAM_INIT(
|
||||
BT_LE_ADV_OPT_CONN,
|
||||
APP_ADV_INTERVAL, /* min interval */
|
||||
APP_ADV_INTERVAL, /* max interval */
|
||||
NULL /* undirected */
|
||||
APP_ADV_INTERVAL, // min interval
|
||||
APP_ADV_INTERVAL, // max interval
|
||||
NULL // undirected
|
||||
);
|
||||
|
||||
err = bt_set_name(SERIAL_NO);
|
||||
@@ -817,7 +776,7 @@ int ble_dfu_advertising_enable(void)
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
/* mdf? 응답 전송 후 현재 연결을 끊고 SMP UUID 광고로 재시작 */
|
||||
// mdf? 응답 전송 후 현재 연결을 끊고 SMP UUID 광고로 재시작
|
||||
dfu_advertising_mode = true;
|
||||
DBG_PRINTF("[BLE] DFU advertising mode enabled\r\n");
|
||||
|
||||
@@ -860,10 +819,10 @@ int ble_data_send(const uint8_t *data, uint16_t len)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 먼저 들어온 전송이 끝나기 전 다음 전송이 겹치지 않게 잠금 (NUS는 한 번에 한 패킷씩 보내는 것이 안전) */
|
||||
// 먼저 들어온 전송이 끝나기 전 다음 전송이 겹치지 않게 잠금 (NUS는 한 번에 한 패킷씩 보내는 것이 안전)
|
||||
k_mutex_lock(&nus_tx_lock, K_FOREVER);
|
||||
|
||||
/* 혹시 남아 있는 완료 신호가 있으면 비우고 이번 전송 전용 상태로 만듦 */
|
||||
// 혹시 남아 있는 완료 신호가 있으면 비우고 이번 전송 전용 상태로 만듦
|
||||
while (k_sem_take(&nus_tx_done_sem, K_NO_WAIT) == 0) {
|
||||
}
|
||||
|
||||
@@ -895,7 +854,7 @@ int ble_data_send(const uint8_t *data, uint16_t len)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* bt_nus_send() 성공 후 sent 콜백이 올 때까지 기다림 (다음 패킷을 보내도 되는 시점) */
|
||||
// bt_nus_send() 성공 후 sent 콜백이 올 때까지 기다림 (다음 패킷을 보내도 되는 시점)
|
||||
err = k_sem_take(&nus_tx_done_sem, K_MSEC(BLE_TX_STUCK_MS));
|
||||
if (err)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user