从 AdapterService# startDiscovery,往下梳理:
http://aospxref.com/android-13.0.0_r3/xref/packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/
AdapterService.java#3808
继续往下调用:
http://aospxref.com/android-13.0.0_r3/xref/packages/modules/Bluetooth/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp#startDiscoveryNative
对应的调用的位置:
http://aospxref.com/android-13.0.0_r3/xref/packages/modules/Bluetooth/system/btif/src/bluetooth.cc#start_discovery
static int start_discovery(void) {
if (!interface_ready()) return BT_STATUS_NOT_READY;
do_in_main_thread(FROM_HERE, base::BindOnce(btif_dm_start_discovery)); ---> 这个函数比较熟悉了吧
return BT_STATUS_SUCCESS;
}
http://aospxref.com/android-13.0.0_r3/xref/packages/modules/Bluetooth/system/btif/src/btif_dm.cc#btif_dm_start_discovery
void btif_dm_start_discovery(void) {
BTIF_TRACE_EVENT("%s", __func__);
if (bta_dm_is_search_request_queued()) {
LOG_INFO("%s skipping start discovery because a request is queued", __func__);
return;
}
/* Will be enabled to true once inquiry busy level has been received */
btif_dm_inquiry_in_progress = false;
/* find nearby devices */
BTA_DmSearch(btif_dm_search_devices_evt, is_bonding_or_sdp()); ---> 和Android R参数大差不差,第一个是回调,第二个往下看
}
我们继续看下:也就是说这个 is_bonding_or_sdp 当前是否有命令在执行
那是首次的话就是: p_msg->hdr.event = BTA_DM_API_SEARCH_EVT;
bta_sys_sendmsg(p_msg) 这个还是和之前一样,最终调到 bta_sys_event 里面,执行(*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
就是对应的 tBTA_SYS_REG 结构体初始化函数,具体是哪个类里面的初始化,这个是由 event 事件决定的,比如我们现在是搜索那初始化就是:static const tBTA_SYS_REG bta_dm_search_reg = {bta_dm_search_sm_execute, bta_dm_search_sm_disable};
执行的就是:bta_dm_search_sm_execute 方法;
http://aospxref.com/android-13.0.0_r3/xref/packages/modules/Bluetooth/system/bta/dm/bta_dm_main.cc#bta_dm_search_sm_execute
// 这里代码有点多,我们只看和流程相关的,此时 p_msg->hdr.event = BTA_DM_API_SEARCH_EVT,上面讲过
bool bta_dm_search_sm_execute(BT_HDR_RIGID* p_msg) {
APPL_TRACE_EVENT("bta_dm_search_sm_execute state:%d, event:0x%x", bta_dm_search_cb.state, p_msg->event);
tBTA_DM_MSG* message = (tBTA_DM_MSG*)p_msg;
switch (bta_dm_search_cb.state) {
case BTA_DM_SEARCH_IDLE:
switch (p_msg->event) {
case BTA_DM_API_SEARCH_EVT:
bta_dm_search_set_state(BTA_DM_SEARCH_ACTIVE); ---> 更新状态
bta_dm_search_start(message); ---> 执行这个方法
break;
case BTA_DM_API_DISCOVER_EVT:
bta_dm_search_set_state(BTA_DM_DISCOVER_ACTIVE);
bta_dm_discover(message);
break;
继续看流程 bta_dm_search_start 方法里面的 BTM_StartInquiry,这个就比较熟悉了吧
http://aospxref.com/android-13.0.0_r3/xref/packages/modules/Bluetooth/system/stack/btm/btm_inq.cc#BTM_StartInquiry
tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, tBTM_CMPL_CB* p_cmpl_cb) {
tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
if (bluetooth::shim::is_gd_shim_enabled()) {
return bluetooth::shim::BTM_StartInquiry(p_results_cb, p_cmpl_cb);
}
/* Only one active inquiry is allowed in this implementation.
Also do not allow an inquiry if the inquiry filter is being updated */
if (p_inq->inq_active) {
LOG(ERROR) << __func__ << ": BTM_BUSY";
return (BTM_BUSY);
}
/*** Make sure the device is ready ***/
if (!BTM_IsDeviceUp()) {
LOG(ERROR) << __func__ << ": adapter is not up";
return BTM_WRONG_MODE;
}
BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Classic inquiry started");
/* Save the inquiry parameters to be used upon the completion of
* setting/clearing the inquiry filter */
p_inq->inqparms = {};
p_inq->inqparms.mode = BTM_GENERAL_INQUIRY | BTM_BLE_GENERAL_INQUIRY; ---> 经典蓝牙和BLE
p_inq->inqparms.duration = BTIF_DM_DEFAULT_INQ_MAX_DURATION; ---> 设置超时时间
/* Initialize the inquiry variables */
p_inq->state = BTM_INQ_ACTIVE_STATE; ---> 状态设置
p_inq->p_inq_cmpl_cb = p_cmpl_cb;
p_inq->p_inq_results_cb = p_results_cb;
p_inq->inq_cmpl_info.num_resp = 0; /* Clear the results counter */
p_inq->inq_active = p_inq->inqparms.mode;
BTM_TRACE_DEBUG("BTM_StartInquiry: p_inq->inq_active = 0x%02x", p_inq->inq_active);
if (controller_get_interface()->supports_ble()) {
btm_ble_start_inquiry(p_inq->inqparms.duration); ---> BLE 扫描发起
} else {
LOG_WARN("Trying to do LE scan on a non-LE adapter");
p_inq->inqparms.mode &= ~BTM_BLE_INQUIRY_MASK;
}
btm_acl_update_inquiry_status(BTM_INQUIRY_STARTED);
if (p_inq->inq_active & BTM_SSP_INQUIRY_ACTIVE) {
btm_process_inq_complete(HCI_ERR_MAX_NUM_OF_CONNECTIONS, BTM_GENERAL_INQUIRY);
return BTM_CMD_STARTED;
}
btm_clr_inq_result_flt();
/* Allocate memory to hold bd_addrs responding */
p_inq->p_bd_db = (tINQ_BDADDR*)osi_calloc(BT_DEFAULT_BUFFER_SIZE);
p_inq->max_bd_entries =
(uint16_t)(BT_DEFAULT_BUFFER_SIZE / sizeof(tINQ_BDADDR));
bluetooth::legacy::hci::GetInterface().StartInquiry( ---> BR/EDR扫描接口
general_inq_lap, p_inq->inqparms.duration, 0);
return BTM_CMD_STARTED;
}
在BTM_StartInquiry会区分BLE扫描和BR/EDR扫描,而且BLE在前面发起!
以BLE的为例子,大致看下BLE 的扫描:http://aospxref.com/android-13.0.0_r3/xref/packages/modules/Bluetooth/system/stack/btm/
btm_ble_gap.cc#btm_ble_start_inquiry
tBTM_STATUS btm_ble_start_inquiry(uint8_t duration) {
tBTM_STATUS status = BTM_CMD_STARTED;
tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb;
tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
BTM_TRACE_DEBUG("btm_ble_start_inquiry: inq_active = 0x%02x", btm_cb.btm_inq_vars.inq_active);
/* if selective connection is active, or inquiry is already active, reject it
*/
if (p_ble_cb->is_ble_inquiry_active()) {
BTM_TRACE_ERROR("LE Inquiry is active, can not start inquiry");
return (BTM_BUSY);
}
/* Cleanup anything remaining on index 0 */
BTM_BleAdvFilterParamSetup(BTM_BLE_SCAN_COND_DELETE,
static_cast<tBTM_BLE_PF_FILT_INDEX>(0), nullptr,
base::Bind(btm_ble_scan_filt_param_cfg_evt));
auto adv_filt_param = std::make_unique<btgatt_filt_param_setup_t>();
/* Add an allow-all filter on index 0*/
adv_filt_param->dely_mode = IMMEDIATE_DELY_MODE;
adv_filt_param->feat_seln = ALLOW_ALL_FILTER;
adv_filt_param->filt_logic_type = BTA_DM_BLE_PF_FILT_LOGIC_OR;
adv_filt_param->list_logic_type = BTA_DM_BLE_PF_LIST_LOGIC_OR;
adv_filt_param->rssi_low_thres = LOWEST_RSSI_VALUE;
adv_filt_param->rssi_high_thres = LOWEST_RSSI_VALUE;
BTM_BleAdvFilterParamSetup(BTM_BLE_SCAN_COND_ADD, static_cast<tBTM_BLE_PF_FILT_INDEX>(0),
std::move(adv_filt_param), base::Bind(btm_ble_scan_filt_param_cfg_evt));
if (!p_ble_cb->is_ble_scan_active()) { ---> 当前没有在执行的
cache.ClearAll();
btm_send_hci_set_scan_params(
BTM_BLE_SCAN_MODE_ACTI, BTM_BLE_LOW_LATENCY_SCAN_INT,
BTM_BLE_LOW_LATENCY_SCAN_WIN,
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, SP_ADV_ALL);
p_ble_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_ACTI;
btm_ble_start_scan(); ---> 开始
} else if ((p_ble_cb->inq_var.scan_interval !=
BTM_BLE_LOW_LATENCY_SCAN_INT) ||
(p_ble_cb->inq_var.scan_window != BTM_BLE_LOW_LATENCY_SCAN_WIN)) {
BTM_TRACE_DEBUG("%s, restart LE scan with low latency scan params",
__func__);
btm_send_hci_scan_enable(BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
btm_send_hci_set_scan_params(
BTM_BLE_SCAN_MODE_ACTI, BTM_BLE_LOW_LATENCY_SCAN_INT,
BTM_BLE_LOW_LATENCY_SCAN_WIN,
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, SP_ADV_ALL);
btm_send_hci_scan_enable(BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE);
}
if (status == BTM_CMD_STARTED) {
p_inq->inq_active |= BTM_BLE_GENERAL_INQUIRY;
p_ble_cb->set_ble_inquiry_active();
BTM_TRACE_DEBUG("btm_ble_start_inquiry inq_active = 0x%02x",
p_inq->inq_active);
if (duration != 0) {
/* start inquiry timer */
uint64_t duration_ms = duration * 1000;
alarm_set_on_mloop(p_ble_cb->inq_var.inquiry_timer, duration_ms,
btm_ble_inquiry_timer_timeout, NULL);
}
}
return status;
}
void btm_ble_start_scan() {
tBTM_BLE_INQ_CB* p_inq = &btm_cb.ble_ctr_cb.inq_var;
/* start scan, disable duplicate filtering */
btm_send_hci_scan_enable(BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE);
if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI)
btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT);
else
btm_ble_set_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT);
}
static void btm_send_hci_scan_enable(uint8_t enable, uint8_t filter_duplicates) {
if (controller_get_interface()->supports_ble_extended_advertising()) {
btsnd_hcic_ble_set_extended_scan_enable(enable, filter_duplicates, 0x0000, 0x0000);
} else {
btsnd_hcic_ble_set_scan_enable(enable, filter_duplicates); ---> 就会掉到stack里面去
}
}
http://aospxref.com/android-13.0.0_r3/xref/packages/modules/Bluetooth/system/stack/hcic/
hciblecmds.cc#btsnd_hcic_ble_set_scan_enable
void btsnd_hcic_ble_set_scan_enable(uint8_t scan_enable, uint8_t duplicate) {
BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
uint8_t* pp = (uint8_t*)(p + 1);
p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE;
p->offset = 0;
UINT16_TO_STREAM(pp, HCI_BLE_WRITE_SCAN_ENABLE);
UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE);
UINT8_TO_STREAM(pp, scan_enable);
UINT8_TO_STREAM(pp, duplicate);
btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); ---> HCI 向 controller 端发送了
}
到此,差不多就大致理了下流程,有兴趣的可以继续追下 btu_hcif_send_cmd 方法往下的流程。