Android T 蓝牙搜索

本文详细介绍了Android系统中启动Bluetooth设备发现功能的步骤,从AdapterService的startDiscovery方法开始,深入到JNI层,然后到Bluetooth控制器的接口,包括BTM_StartInquiry函数,区分经典蓝牙和BLE扫描的过程。整个流程涉及到状态管理、回调函数、滤波器设置以及HCI命令的发送。
摘要由CSDN通过智能技术生成

从 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 方法往下的流程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值