最近在使用NRf52832芯片开发项目时候,发现总是在1分30秒的时候,蓝牙断开,
打印log是:
Peripheral disconnected. conn_handle: 0x2, reason: 0x16:
经过查找ble_hci.h的状态,发现是0x16状态是因为芯片端主动断开的,
#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */
#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */
#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/
#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */
#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */
于是,在每个断开的api( 函数:sd_ble_gap_disconnect())处打印log,发现问题出现在下方地方:
if (m_conn_params_config.disconnect_on_fail)
{
ret_code_t err_code;
NRF_LOG_INFO(" disconnect 3333 ....");
err_code = sd_ble_gap_disconnect(conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) // NRF_ERROR_INVALID_STATE means disconnect is already in progress.
{
send_error_evt(err_code);
}
}
// Notify the application that the procedure has failed
if (m_conn_params_config.evt_handler != NULL)
{
ble_conn_params_evt_t evt;
evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
evt.conn_handle = conn_handle;
m_conn_params_config.evt_handler(&evt);
}
正因为这个 :m_conn_params_config.disconnect_on_fail 参数,导致断开,
于是反向查找这个参数,发现是在conn_params_init()函数里面
static void conn_params_init(void)
{
ret_code_t err_code;
ble_conn_params_init_t cp_init;
memset(&cp_init, 0, sizeof(cp_init));
cp_init.p_conn_params = NULL;
cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
cp_init.start_on_notify_cccd_handle = BLE_CONN_HANDLE_INVALID; // Start upon connection.
cp_init.disconnect_on_fail = true;
cp_init.evt_handler = NULL; // Ignore events.
cp_init.error_handler = conn_params_error_handler;
err_code = ble_conn_params_init(&cp_init);
APP_ERROR_CHECK(err_code);
}
解决方式:
第一种、
将 cp_init.disconnect_on_fail=false;
第二种:
将 conn_params_init()放在广播初始化 :advertising_init()之后
如下:
int main(void)
{
bool erase_bonds;
// Initialize.
log_init();
timer_init();
#if NRF52832_SDK_DEMO_DSIABLE==0
buttons_leds_init(&erase_bonds);
#endif
power_management_init();
ble_stack_init();
peer_manager_init();
scan_init();
db_discovery_init();
liv_BAT_C_Init();
liv_Char_C_Init();
#if NRF52832_SDK_DEMO_DSIABLE==0
hrs_c_init();
rscs_c_init();
#else
// NRF_UICR->NFCPINS = 0;
liv_SystemService_init();
liv_SystemGpio_init();
#endif
gap_params_init();
gatt_init();
services_init();
advertising_init();
conn_params_init();
// Start execution.
NRF_LOG_INFO("Relay example started.");
}
个人推荐