在 文章中分析了Hogp的鏈接的流程 ,這裏分析一下回連的流程.html
在使用ble設備的過程當中,咱們發現當設備和主機配對以後,若是沒有解除配對,那麼即使設備和主機斷開,那麼也是能夠從新鏈接而不須要從新走配對的流程,這裏的分析的源代碼是Android7.0 .api
回連的大概的流程是:hogp 鏈接完成以後,會把當前的device 加入到whitelist裏面.,標記爲能夠回連的設備.當設備和主機斷開的時候,主機會根據whitelist裏面的設備來進行回連.安全
這裏咱們從hogp鏈接流程中將device加入到 whitelist的流程來開始分析.app
/******************************************************************************* ** ** Function bta_hh_le_open_cmpl ** ** Description HID over GATT connection sucessfully opened ** *******************************************************************************/ void bta_hh_le_open_cmpl(tBTA_HH_DEV_CB *p_cb) { if ( p_cb->disc_active == BTA_HH_LE_DISC_NONE) { bta_hh_le_register_input_notif(p_cb, p_cb->mode, TRUE); bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, NULL); #if (BTA_HH_LE_RECONN == TRUE) if (p_cb->status == BTA_HH_OK) { bta_hh_le_add_dev_bg_conn(p_cb, TRUE);//加入到bg connection 中 } #endif } }
繼續看bta_hh_le_add_dev_bg_conn 的實現:ide
static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB *p_cb, BOOLEAN check_bond) { UINT8 sec_flag=0; BOOLEAN to_add = TRUE; if (check_bond) { /* start reconnection if remote is a bonded device */ /* verify bond */ BTM_GetSecurityFlagsByTransport(p_cb->addr, &sec_flag, BT_TRANSPORT_LE); if ((sec_flag & BTM_SEC_FLAG_LKEY_KNOWN) == 0) to_add = FALSE;//若是沒有完成安全認證,那麼不會加入到whitelist裏面 } if (!p_cb->in_bg_conn && to_add) { /* add device into BG connection to accept remote initiated connection */ BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, FALSE, BTA_GATT_TRANSPORT_LE); p_cb->in_bg_conn = TRUE;//標記爲in_bg_conn 爲true BTA_DmBleSetBgConnType(BTA_DM_BLE_CONN_AUTO, NULL); } return; } }
這裏 分爲兩個步驟:函數
這裏的重點是第一個步驟,咱們依次分析:ui
bta_gattc_api.cthis
void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport) { tBTA_GATTC_API_OPEN *p_buf = (tBTA_GATTC_API_OPEN *) osi_malloc(sizeof(tBTA_GATTC_API_OPEN)); p_buf->hdr.event = BTA_GATTC_API_OPEN_EVT; p_buf->client_if = client_if; p_buf->is_direct = is_direct; p_buf->transport = transport; memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN); bta_sys_sendmsg(p_buf); }
這裏很少說, bta_gattc_hdl_event -->BTA_GATTC_API_OPEN_EVT ->bta_gattc_process_api_open 咱們直接看實際處理的函數 spa
bta_gattc_act.ccode
void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg) { UINT16 event = ((BT_HDR *)p_msg)->event; tBTA_GATTC_CLCB *p_clcb = NULL; tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if); UNUSED(p_cb); if (p_clreg != NULL) { if (p_msg->api_conn.is_direct)//is_direct是false { if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if, p_msg->api_conn.remote_bda, p_msg->api_conn.transport)) != NULL) { bta_gattc_sm_execute(p_clcb, event, p_msg); } else { APPL_TRACE_ERROR("No resources to open a new connection."); bta_gattc_send_open_cback(p_clreg, BTA_GATT_NO_RESOURCES, p_msg->api_conn.remote_bda, BTA_GATT_INVALID_CONN_ID, p_msg->api_conn.transport, 0); } } else { bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg);//init bg conn } } }
繼續看bta_gattc_init_bk_conn
/******************************************************************************* ** ** Function bta_gattc_init_bk_conn ** ** Description Process API Open for a background connection ** ** Returns void ** *******************************************************************************/ void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg) { tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES; UINT16 conn_id; tBTA_GATTC_CLCB *p_clcb; tBTA_GATTC_DATA gattc_data; if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE))//標記p_bg_tck->cif_mask ,暫時沒看出來用處 { /* always call open to hold a connection */ if (!GATT_Connect(p_data->client_if, p_data->remote_bda, false, p_data->transport, false))//執行gatt_connect,注意這裏的參數是no_direct { /*出錯處理*/ } else { status = BTA_GATT_OK; /* if is a connected remote device */ if (GATT_GetConnIdIfConnected(p_data->client_if, p_data->remote_bda, &conn_id, p_data->transport)) { if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) { gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id; /* open connection */ bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);//當前就是connection狀態,BTA_GATTC_IGNORE status = BTA_GATT_OK; } } } } ... }
上面的重點是 GATT_Connect,下面重點看:
/******************************************************************************* ** ** Function GATT_Connect ** ** Description This function initiate a connecttion to a remote device on GATT ** channel. ** ** Parameters gatt_if: applicaiton interface ** bd_addr: peer device address. ** is_direct: is a direct conenection or a background auto connection ** ** Returns TRUE if connection started; FALSE if connection start failure. ** *******************************************************************************/ BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct, tBT_TRANSPORT transport, BOOLEAN opportunistic) { tGATT_REG *p_reg; BOOLEAN status = FALSE; /* Make sure app is registered */ if ((p_reg = gatt_get_regcb(gatt_if)) == NULL) { GATT_TRACE_ERROR("GATT_Connect - gatt_if =%d is not registered", gatt_if); return(FALSE); } if (is_direct)//定向是直接創建鏈接,不然加入whitelist status = gatt_act_connect (p_reg, bd_addr, transport, opportunistic); else { if (transport == BT_TRANSPORT_LE) status = gatt_update_auto_connect_dev(gatt_if,TRUE, bd_addr, TRUE); else { GATT_TRACE_ERROR("Unsupported transport for background connection"); } } return status; }
咱們這裏執行的是gatt_update_auto_connect_dev
/******************************************************************************* ** ** Function gatt_update_auto_connect_dev ** ** Description This function add or remove a device for background connection ** procedure. ** ** Parameters gatt_if: Application ID. ** add: add peer device ** bd_addr: peer device address. ** ** Returns TRUE if connection started; FALSE if connection start failure. ** *******************************************************************************/ BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initator) { BOOLEAN ret = FALSE; tGATT_REG *p_reg; tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); if (add) { ret = gatt_add_bg_dev_list(p_reg, bd_addr, is_initator);//添加到whitelist if (ret && p_tcb != NULL) { /* if a connected device, update the link holding number */ gatt_update_app_use_link_flag(gatt_if, p_tcb, TRUE, TRUE); } } else { ret = gatt_remove_bg_dev_from_list(p_reg, bd_addr, is_initator);//不然移除 } return ret; }
這裏咱們先簡單分析一下 gatt_update_app_use_link_flag(gatt_if, p_tcb, TRUE, TRUE);
/******************************************************************************* ** ** Function gatt_update_app_use_link_flag ** ** Description Update the application use link flag and optional to check the acl link ** if the link is up then set the idle time out accordingly ** ** Returns void. ** *******************************************************************************/ void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add, BOOLEAN check_acl_link) { // If we make no modification, i.e. kill app that was never connected to a device, // skip updating the device state. if (!gatt_update_app_hold_link_status(gatt_if, p_tcb, is_add))//gatt_cb->p_tcb->app_hold_link[i] == gatt_if return; if (!check_acl_link || p_tcb->att_lcid != L2CAP_ATT_CID || /* only update link idle timer for fixed channel */ (BTM_GetHCIConnHandle(p_tcb->peer_bda, p_tcb->transport) == GATT_INVALID_ACL_HANDLE)) { return; } if (is_add) { /* acl link is connected disable the idle timeout */ GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport);//設置timeout爲無限長 } else { if (!gatt_num_apps_hold_link(p_tcb)) { /* acl link is connected but no application needs to use the link so set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds */ GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP, p_tcb->transport);//若是是remove,那麼設置timeout爲1s } } }
下面繼續看gatt_add_bg_dev_list 的實現:
/******************************************************************************* ** ** Function gatt_add_bg_dev_list ** ** Description add/remove device from the back ground connection device list ** ** Returns TRUE if device added to the list; FALSE failed ** *******************************************************************************/ BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg, BD_ADDR bd_addr, BOOLEAN is_initator) { tGATT_IF gatt_if = p_reg->gatt_if; tGATT_BG_CONN_DEV *p_dev = NULL; UINT8 i; BOOLEAN ret = FALSE; if ((p_dev = gatt_find_bg_dev(bd_addr)) == NULL) { p_dev = gatt_alloc_bg_dev(bd_addr);//未找到則分配,此結構爲gatt_cb.bgconn_dev } if (p_dev) { for (i = 0; i < GATT_MAX_APPS; i ++) { if (is_initator)//主機端通常都是initator { if (p_dev->gatt_if[i] == gatt_if) { GATT_TRACE_ERROR("device already in iniator white list"); return TRUE; } else if (p_dev->gatt_if[i] == 0) { p_dev->gatt_if[i] = gatt_if; ret = BTM_BleUpdateBgConnDev(TRUE, bd_addr);//update background connection break; } } } } return ret; }
繼續看:
/******************************************************************************* ** ** Function BTM_BleUpdateBgConnDev ** ** Description This function is called to add or remove a device into/from ** background connection procedure. The background connection * procedure is decided by the background connection type, it can be * auto connection, or selective connection. ** ** Parameters add_remove: TRUE to add; FALSE to remove. ** remote_bda: device address to add/remove. ** ** Returns void ** *******************************************************************************/ BOOLEAN BTM_BleUpdateBgConnDev(BOOLEAN add_remove, BD_ADDR remote_bda) { BTM_TRACE_EVENT("%s() add=%d", __func__, add_remove); return btm_update_dev_to_white_list(add_remove, remote_bda); }
/******************************************************************************* ** ** Function btm_update_dev_to_white_list ** ** Description This function adds or removes a device into/from ** the white list. ** *******************************************************************************/ BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr) { tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; if (to_add && p_cb->white_list_avail_size == 0)//判斷whitelist容量 { BTM_TRACE_ERROR("%s Whitelist full, unable to add device", __func__); return FALSE; } if (to_add) background_connection_add((bt_bdaddr_t*)bd_addr);//添加到background_connections else background_connection_remove((bt_bdaddr_t*)bd_addr); btm_suspend_wl_activity(p_cb->wl_state); btm_enq_wl_dev_operation(to_add, bd_addr);//btm_cb.ble_ctr_cb.wl_op_q 更新 btm_resume_wl_activity(p_cb->wl_state); return TRUE; }
這裏簡單看下bg connection的管理:用hash map 來實現的,
static void background_connection_add(bt_bdaddr_t *address) { assert(address); background_connections_lazy_init(); background_connection_t *connection = hash_map_get(background_connections, address); if (!connection) { connection = osi_calloc(sizeof(background_connection_t)); connection->address = *address; hash_map_set(background_connections, &(connection->address), connection); } }
到這裏 已經將設備添加到bg connection裏面了,
下面繼續看
2.BTA_DmBleSetBgConnType(BTA_DM_BLE_CONN_AUTO, NULL);
void BTA_DmBleSetBgConnType(tBTA_DM_BLE_CONN_TYPE bg_conn_type, tBTA_DM_BLE_SEL_CBACK *p_select_cback) { #if BLE_INCLUDED == TRUE tBTA_DM_API_BLE_SET_BG_CONN_TYPE *p_msg = (tBTA_DM_API_BLE_SET_BG_CONN_TYPE *)osi_calloc(sizeof(tBTA_DM_API_BLE_SET_BG_CONN_TYPE)); p_msg->hdr.event = BTA_DM_API_BLE_SET_BG_CONN_TYPE; p_msg->bg_conn_type = bg_conn_type; p_msg->p_select_cback = p_select_cback; bta_sys_sendmsg(p_msg); #endif }
發出BTA_DM_API_BLE_SET_BG_CONN_TYPE 信息.
相應的處理函數:
/******************************************************************************* ** ** Function BTM_BleSetBgConnType ** ** Description This function is called to set BLE connectable mode for a ** peripheral device. ** ** Parameters bg_conn_type: it can be auto connection, or selective connection. ** p_select_cback: callback function when selective connection procedure ** is being used. ** ** Returns void ** *******************************************************************************/ BOOLEAN BTM_BleSetBgConnType(tBTM_BLE_CONN_TYPE bg_conn_type, tBTM_BLE_SEL_CBACK *p_select_cback) { BOOLEAN started = TRUE; if (btm_cb.ble_ctr_cb.bg_conn_type != bg_conn_type) { switch (bg_conn_type) { case BTM_BLE_CONN_AUTO: btm_ble_start_auto_conn(TRUE); break; ...
if (started)
btm_cb.ble_ctr_cb.bg_conn_type = bg_conn_type; //更新 bg_conn_type = BTM_BLE_CONN_AUTO = 1
咱們繼續看btm_ble_start_auto_conn 的實現:
/******************************************************************************* ** ** Function btm_ble_start_auto_conn ** ** Description This function is to start/stop auto connection procedure. ** ** Parameters start: TRUE to start; FALSE to stop. ** ** Returns void ** *******************************************************************************/ BOOLEAN btm_ble_start_auto_conn(BOOLEAN start) { tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; BD_ADDR dummy_bda = {0}; BOOLEAN exec = TRUE; UINT16 scan_int; UINT16 scan_win; UINT8 own_addr_type = p_cb->addr_mgnt_cb.own_addr_type; UINT8 peer_addr_type = BLE_ADDR_PUBLIC; if (start)//true { if ( p_cb->conn_state == BLE_CONN_IDLE )//未 正在鏈接狀態,當前狀態是 BLE_CONN_IDLE { exec = btm_execute_wl_dev_operation();//add to whitelist } /*background_connections_pending 此條件判斷不符,由於當前ble 設備和主機已經鏈接,故不會去下0x200d*/ if (p_cb->conn_state == BLE_CONN_IDLE && background_connections_pending() && btm_ble_topology_check(BTM_BLE_STATE_INIT)) { p_cb->wl_state |= BTM_BLE_WL_INIT; scan_int = (p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_SLOW_INT_1 : p_cb->scan_int; scan_win = (p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_SLOW_WIN_1 : p_cb->scan_win; if (!btsnd_hcic_ble_create_ll_conn (scan_int, /* UINT16 scan_int */ scan_win, /* UINT16 scan_win */ 0x01, /* UINT8 white_list */ peer_addr_type, /* UINT8 addr_type_peer */ dummy_bda, /* BD_ADDR bda_peer */ own_addr_type, /* UINT8 addr_type_own */ BTM_BLE_CONN_INT_MIN_DEF, /* UINT16 conn_int_min */ #ifdef BLUETOOTH_RTK BTM_BLE_CONN_INT_MIN_DEF, #else BTM_BLE_CONN_INT_MAX_DEF, /* UINT16 conn_int_max */ #endif BTM_BLE_CONN_SLAVE_LATENCY_DEF, /* UINT16 conn_latency */ BTM_BLE_CONN_TIMEOUT_DEF, /* UINT16 conn_timeout */ 0, /* UINT16 min_len */ 0)) /* UINT16 max_len */ { /* start auto connection failed */ exec = FALSE; p_cb->wl_state &= ~BTM_BLE_WL_INIT; } else { btm_ble_set_conn_st (BLE_BG_CONN); } } else { exec = FALSE; } } else //false 狀態 { if (p_cb->conn_state == BLE_BG_CONN) { btsnd_hcic_ble_create_conn_cancel(); btm_ble_set_conn_st (BLE_CONN_CANCEL); p_cb->wl_state &= ~BTM_BLE_WL_INIT; } else { exec = FALSE; } } return exec; }
在上面的 btm_execute_wl_dev_operation 流程中,會將設備加入到whitelist裏面去,對應的HCI 命令是Command: HCI_LE_Add_Device_To_White_List
到目前爲止,已經將設備加入到bg connection裏面以及contrller的 whitelist裏面了.
當設備與主機端斷開鏈接,那麼主機端應該主動發起,回連,.
下面咱們簡單看一下,當設備與主機端斷開的時候,主機端的行爲.
/******************************************************************************* ** ** Function btu_hcif_disconnection_comp_evt ** ** Description Process event HCI_DISCONNECTION_COMP_EVT ** ** Returns void ** *******************************************************************************/ static void btu_hcif_disconnection_comp_evt (UINT8 *p) { UINT16 handle; UINT8 reason; ++p; STREAM_TO_UINT16 (handle, p); STREAM_TO_UINT8 (reason, p); handle = HCID_GET_HANDLE (handle); l2c_link_hci_disc_comp (handle, reason);//L2cap 相關的連接處理 /* Notify security manager */ btm_sec_disconnected (handle, reason);//security manager的處理 }
咱們主要看一下btm_sec_disconnected的處理:
這裏挑重點;
void btm_sec_disconnected (UINT16 handle, UINT8 reason) { tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle); UINT8 old_pairing_flags = btm_cb.pairing_flags; int result = HCI_ERR_AUTH_FAILURE; tBTM_SEC_CALLBACK *p_callback = NULL; tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; btm_acl_resubmit_page();//若是有掛起的鏈接請求,那麼繼續 transport = (handle == p_dev_rec->hci_handle) ? BT_TRANSPORT_BR_EDR: BT_TRANSPORT_LE; p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */ /* clear unused flags */ p_dev_rec->sm4 &= BTM_SM4_TRUE; uint8_t *bd_addr = (uint8_t *)p_dev_rec->bd_addr; /* If we are in the process of bonding we need to tell client that auth failed */ if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) && (memcmp (btm_cb.pairing_bda, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)) { ... } #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, p_dev_rec->bd_addr, HCI_SUCCESS);//當link狀態改變時更新le設備應該作的行爲 /* see sec_flags processing in btm_acl_removed */ if (transport == BT_TRANSPORT_LE)/*清掉各類flag*/ { p_dev_rec->ble_hci_handle = BTM_SEC_INVALID_HANDLE; p_dev_rec->sec_flags &= ~(BTM_SEC_LE_AUTHENTICATED|BTM_SEC_LE_ENCRYPTED); p_dev_rec->enc_key_size = 0; } else #endif { ... } ... p_dev_rec->sec_state = BTM_SEC_STATE_IDLE; p_dev_rec->security_required = BTM_SEC_NONE; p_callback = p_dev_rec->p_callback; /* if security is pending, send callback to clean up the security state */ if(p_callback) { p_dev_rec->p_callback = NULL; /* when the peer device time out the authentication before we do, this call back must be reset here */ (*p_callback) (p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data, BTM_ERR_PROCESSING); } BTM_TRACE_EVENT("%s after update sec_flags=0x%x", __func__, p_dev_rec->sec_flags); }
這裏咱們只要專一於 btm_ble_update_mode_operation 就好.
/******************************************************************************* ** ** Function btm_ble_update_mode_operation ** ** Description This function update the GAP role operation when a link status ** is updated. ** ** Returns void ** *******************************************************************************/ void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, UINT8 status) { if (status == HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT) { ... } if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE) { ... } /* when no connection is attempted, and controller is not rejecting last request due to resource limitation, start next direct connection or background connection now in order */ if (btm_ble_get_conn_st() == BLE_CONN_IDLE && status != HCI_ERR_HOST_REJECT_RESOURCES && !btm_send_pending_direct_conn())//當沒有direct請求的時候 { btm_ble_resume_bg_conn();//開始回連 } }
/******************************************************************************* ** ** Function btm_ble_resume_bg_conn ** ** Description This function is to resume a background auto connection ** procedure. ** ** Parameters none. ** ** Returns none. ** *******************************************************************************/ BOOLEAN btm_ble_resume_bg_conn(void) { tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; BOOLEAN ret = FALSE; if (p_cb->bg_conn_type != BTM_BLE_CONN_NONE) { if (p_cb->bg_conn_type == BTM_BLE_CONN_AUTO)//BTM_BLE_CONN_AUTO前面已經設置過了 ret = btm_ble_start_auto_conn(TRUE); if (p_cb->bg_conn_type == BTM_BLE_CONN_SELECTIVE) ret = btm_ble_start_select_conn(TRUE, btm_cb.ble_ctr_cb.p_select_cback); } return ret; }
接下來又來到了這個函數:btm_ble_start_auto_conn,上面分析了當設備仍然和主機有鏈接的狀況,當前設備已經斷開,是真正須要回連的時候,
BOOLEAN btm_ble_start_auto_conn(BOOLEAN start) { tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; BD_ADDR dummy_bda = {0}; BOOLEAN exec = TRUE; UINT16 scan_int; UINT16 scan_win; UINT8 own_addr_type = p_cb->addr_mgnt_cb.own_addr_type; UINT8 peer_addr_type = BLE_ADDR_PUBLIC; if (start) { if ( p_cb->conn_state == BLE_CONN_IDLE ) { exec = btm_execute_wl_dev_operation();//這裏不會重複添加whitelist, memset. } /*這裏會發現 bg connection 裏面還有 設備須要回連*/ if (p_cb->conn_state == BLE_CONN_IDLE && background_connections_pending() && btm_ble_topology_check(BTM_BLE_STATE_INIT)) { p_cb->wl_state |= BTM_BLE_WL_INIT;//設置狀態 scan_int = (p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_SLOW_INT_1 : p_cb->scan_int; scan_win = (p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_SLOW_WIN_1 : p_cb->scan_win; /*發送0x200d到controller*/ if (!btsnd_hcic_ble_create_ll_conn (scan_int, /* UINT16 scan_int */ scan_win, /* UINT16 scan_win */ 0x01, /* UINT8 white_list */ peer_addr_type, /* UINT8 addr_type_peer */ dummy_bda, /* BD_ADDR bda_peer */ own_addr_type, /* UINT8 addr_type_own */ BTM_BLE_CONN_INT_MIN_DEF, /* UINT16 conn_int_min */ BTM_BLE_CONN_INT_MIN_DEF, BTM_BLE_CONN_SLAVE_LATENCY_DEF, /* UINT16 conn_latency */ BTM_BLE_CONN_TIMEOUT_DEF, /* UINT16 conn_timeout */ 0, /* UINT16 min_len */ 0)) /* UINT16 max_len */ { /* start auto connection failed */ exec = FALSE; p_cb->wl_state &= ~BTM_BLE_WL_INIT; } else { btm_ble_set_conn_st (BLE_BG_CONN);//設置連的狀態 } } else { exec = FALSE; } } else { if (p_cb->conn_state == BLE_BG_CONN) { btsnd_hcic_ble_create_conn_cancel(); btm_ble_set_conn_st (BLE_CONN_CANCEL); p_cb->wl_state &= ~BTM_BLE_WL_INIT; } else { BTM_TRACE_DEBUG("conn_st = %d, not in auto conn state, cannot stop", p_cb->conn_state); exec = FALSE; } } return exec; }
host端向controller端發起了鏈接的請求,也即回連請求,.
對於Le 設備的回連,暫且分析到這裏.