BLE 연결 해제 원인에 따른 광고 지속시간 분기 적용

- 의도치 않은 연결 해제: 광고 무한 지속
- 부팅 후 첫 광고 및 그외: 10분
This commit is contained in:
2026-04-15 17:50:33 +09:00
parent c539b0c756
commit 87fbccf650
2 changed files with 36 additions and 21 deletions

View File

@@ -137,11 +137,9 @@
#define APP_BLE_OBSERVER_PRIO 3 /* BLE 이벤트 옵저버 우선순위 */
#define APP_ADV_INTERVAL 64 /* 광고 간격: 64 x 0.625ms = 40ms */
#if FEATURE_NO_SLEEP
#define APP_ADV_DURATION 0 /* 슬립 비활성화(테스트) 시: 무한 광고 */
#else
#define APP_ADV_DURATION 18000 /* 광고 지속시간: 18000 x 10ms = 3분 → 타임아웃 시 슬립 */
#endif
#define APP_ADV_DURATION_NORMAL 60000 /* 일반 disconnect 시 광고 지속시간: 60000 x 10ms = 10분 */
#define APP_ADV_DURATION_UNLIMITED 0 /* 의도치 않은 disconnect 시: 무한 광고 */
#define APP_ADV_DURATION APP_ADV_DURATION_NORMAL /* 기본 광고 지속시간 (disconnect reason에 따라 런타임 변경) */
#define MIN_CONN_INTERVAL MSEC_TO_UNITS(30, UNIT_1_25_MS) /* 최소 연결 간격: 30ms */
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(30, UNIT_1_25_MS) /* 최대 연결 간격: 30ms */
@@ -816,7 +814,8 @@ static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
* @brief BLE 광고 초기화
*
* 광고 데이터 설정: 디바이스 이름(전체), NUS UUID
* 광고 모드: Fast (40ms 간격), 지속시간 3분 (FEATURE_NO_SLEEP 시 무한)
* 광고 모드: Fast (40ms 간격), 기본 지속시간 10분
* disconnect reason에 따라 런타임에 무한 광고로 전환될 수 있음
*/
static void advertising_init(void)
{
@@ -827,12 +826,7 @@ static void advertising_init(void)
init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
init.advdata.include_appearance = true;
#if FEATURE_NO_SLEEP
init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
#else
init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
#endif
init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
init.srdata.uuids_complete.p_uuids = m_adv_uuids;
@@ -1025,8 +1019,22 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
/* BLE 연결이 끊어지는 경우 */
case BLE_GAP_EVT_DISCONNECTED:
DBG_PRINTF("[BLE] Disconnected (reason 0x%02X)\r\n",
p_ble_evt->evt.gap_evt.params.disconnected.reason);
{
uint8_t disc_reason = p_ble_evt->evt.gap_evt.params.disconnected.reason;
/* 의도치 않은 disconnect 판별:
* 0x08 supervision timeout, 0x22 LMP response timeout,
* 0x3D MIC failure, 0x3E connection failed to be established
* → 무한 광고 유지 + 슬립 진입 차단
*/
bool unintended_disc = (disc_reason == BLE_HCI_CONNECTION_TIMEOUT) ||
(disc_reason == BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT) ||
(disc_reason == BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE)||
(disc_reason == BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED);
DBG_PRINTF("[BLE] Disconnected (reason 0x%02X)%s\r\n",
disc_reason, unintended_disc ? " [UNINTENDED]" : "");
ble_connection_st = 0;
m_conn_handle = BLE_CONN_HANDLE_INVALID;
m_tx_in_progress = false;
@@ -1034,14 +1042,27 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
maa_async_abort(); // 비동기 측정 상태에 의한 먹통 현상 방지
s_tx_pending = false; // pending TX 클리어
if (device_status == true)
/* 광고 지속시간을 disconnect 원인에 따라 런타임 조정 */
(void)sd_ble_gap_adv_stop(m_advertising.adv_handle);
m_advertising.adv_modes_config.ble_adv_fast_timeout =
unintended_disc ? APP_ADV_DURATION_UNLIMITED : APP_ADV_DURATION_NORMAL;
ret_code_t adv_err = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
if (adv_err != NRF_SUCCESS && adv_err != NRF_ERROR_INVALID_STATE)
{
APP_ERROR_CHECK(adv_err);
}
/* 의도치 않은 disconnect: 슬립 진입 차단하여 지속 광고 보장 */
if (!unintended_disc && device_status == true)
{
if (device_sleep_mode() == 0)
{
device_status = false;
}
}
break;
}
break;
case BLE_GAP_EVT_CONNECTED:
DBG_PRINTF("[BLE] Connected\r\n");