android bluetooth stack-scan

AdapterService.java
在这里插入图片描述
在这里插入图片描述
上层一点搜索的button就开始走到底层so的JNI调用

start_discovery
btif_dm_start_discovery
	BTA_DmBleScanFilterSetup设置扫描过滤->bta_dm_scan_filter_param_setup, /* BTA_DM_API_SCAN_FILTER_SETUP_EVT */

BTA_DmBleScanFilterSetup

BTA_DmBleScanFilterSetup为扫描参数设置,接下来走到
bta_dm_scan_filter_param_setup,先清除扫描参数,再设置默认的扫描参数

搜索周边设备
 BTA_DmSearch(&inq_params, services, bte_search_devices_evt);
执行到
bta_dm_search_sm_execute-》bta_dm_search_start中先清醒扫描缓存,设置扫描参数,再进行扫描BTM_StartInquiry->btm_ble_start_inquiry->
btm_ble_start_scan->btsnd_hcic_ble_set_scan_enable发送命令到主控开始扫描
设置定时器,时间到了停止扫描
 static void btm_ble_inquiry_timer_timeout(UNUSED_ATTR void *data)
 {           
     btm_ble_stop_inquiry();
 } 并调用完成扫描函数btm_process_inq_complete  
``

当有事件响应时,即有广播包来时,触发事件读取函数
btu_hci_msg_process-》BT_EVT_TO_BTU_HCI_EVT-》 btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
case HCI_BLE_EVENT:(BLE事件)
case HCI_BLE_ADV_PKT_RPT_EVT: /* result of inquiry */
btu_ble_process_adv_pkt§;处理扫描到的广播包-》btm_ble_process_adv_pkt_cont
btm_ble_update_inq_result 更新扫描到的数据库
btm_ble_is_discoverable找出可被扫描的设备
//执行回调 BTA_DmSearch(&inq_params, services, bte_search_devices_evt);
bte_search_devices_evt->
btif_dm_search_devices_evt

case BTA_DM_INQ_RES_EVT:
{
/* inquiry result */
UINT32 cod;
bt_bdname_t bdname;
bt_bdaddr_t bdaddr;
UINT8 remote_name_len;
tBTA_SERVICE_MASK services = 0;
bdstr_t bdstr;

p_search_data = (tBTA_DM_SEARCH *)p_param;
bdcpy(bdaddr.address, p_search_data->inq_res.bd_addr);

BTIF_TRACE_DEBUG("%s() %s device_type = 0x%x\n", __FUNCTION__, bdaddr_to_string(&bdaddr, bdstr, sizeof(bdstr)),
#if (BLE_INCLUDED == TRUE)
p_search_data->inq_res.device_type);
#else
BT_DEVICE_TYPE_BREDR);
#endif
bdname.name[0] = 0;

cod = devclass2uint (p_search_data->inq_res.dev_class);

if (cod == 0) {
LOG_DEBUG("%s cod is 0, set as unclassified", __func__);
cod = COD_UNCLASSIFIED;
}

if (!check_eir_remote_name(p_search_data, bdname.name, &remote_name_len))
check_cached_remote_name(p_search_data, bdname.name, &remote_name_len);

/* Check EIR for remote name and services */
if (p_search_data->inq_res.p_eir)
{
BTA_GetEirService(p_search_data->inq_res.p_eir, &services);
BTIF_TRACE_DEBUG("%s()EIR BTA services = %08X", __FUNCTION__, (UINT32)services);
/* TODO:  Get the service list and check to see which uuids we got and send it back to the client. */
}


{
bt_property_t properties[5];
bt_device_type_t dev_type;
uint32_t num_properties = 0;
bt_status_t status;
int addr_type = 0;

memset(properties, 0, sizeof(properties));
/* BD_ADDR */
BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
BT_PROPERTY_BDADDR, sizeof(bdaddr), &bdaddr);
num_properties++;
/* BD_NAME */
/* Don't send BDNAME if it is empty */
if (bdname.name[0])
{
BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
BT_PROPERTY_BDNAME,
strlen((char *)bdname.name), &bdname);
num_properties++;
}

/* DEV_CLASS */
BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
BT_PROPERTY_CLASS_OF_DEVICE, sizeof(cod), &cod);
num_properties++;
/* DEV_TYPE */
#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
/* FixMe: Assumption is that bluetooth.h and BTE enums match */

/* Verify if the device is dual mode in NVRAM */
int stored_device_type = 0;
if (btif_get_device_type(bdaddr.address, &stored_device_type) &&
((stored_device_type == BT_DEVICE_TYPE_BLE &&
p_search_data->inq_res.device_type == BT_DEVICE_TYPE_BREDR) ||
(stored_device_type == BT_DEVICE_TYPE_BREDR &&
p_search_data->inq_res.device_type == BT_DEVICE_TYPE_BLE))) {
dev_type = BT_DEVICE_TYPE_DUMO;
} else {
dev_type = p_search_data->inq_res.device_type;
}

if (p_search_data->inq_res.device_type == BT_DEVICE_TYPE_BLE)
addr_type = p_search_data->inq_res.ble_addr_type;
#else
dev_type = BT_DEVICE_TYPE_BREDR;
#endif
BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
BT_PROPERTY_TYPE_OF_DEVICE, sizeof(dev_type), &dev_type);
num_properties++;
/* RSSI */
BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
BT_PROPERTY_REMOTE_RSSI, sizeof(int8_t),
&(p_search_data->inq_res.rssi));
num_properties++;

status = btif_storage_add_remote_device(&bdaddr, num_properties, properties);
ASSERTC(status == BT_STATUS_SUCCESS, "failed to save remote device (inquiry)", status);
#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
status = btif_storage_set_remote_addr_type(&bdaddr, addr_type);
ASSERTC(status == BT_STATUS_SUCCESS, "failed to save remote addr type (inquiry)", status);
#endif
/* Callback to notify upper layer of device */
HAL_CBACK(bt_hal_cbacks, device_found_cb,
num_properties, properties);
}
}

最后通过回调上报给安卓的framework

/* Callback to notify upper layer of device */
HAL_CBACK(bt_hal_cbacks, device_found_cb,
num_properties, properties);

ble扫描参数:
在scanmanager.java里配置
在这里插入图片描述
以上参数通过jni传到bt stack的接口进而设置到协议栈
在这里插入图片描述
然后通过gattClientScanNative进行扫描
在这里插入图片描述
这里为android O/mtk6580为对应的代码流程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下发到协议栈去执行
在这里插入图片描述
有时需要通过周围的枚举来找到当前的处理函数如:
在这里插入图片描述
在这里插入图片描述
bta_dm_ble_observe

btm_cb.ble_ctr_cb.p_obs_results_cb = p_results_cb;
btm_cb.ble_ctr_cb.p_obs_cmpl_cb = p_cmpl_cb;

bta_dm_search_cb.p_scan_cback ==
p_data->ble_observe.p_cback==
bta_scan_results_cb
在这里插入图片描述
采用上层给的扫描参数,如果上层有设置的话,否则采用协议栈默认的参数
设置扫描结果返回函数p_obs_results_cb   bta_dm_observe_results_cb,
扫描完成返回函数p_obs_cmpl_cb  bta_dm_observe_cmpl_cb
在这里插入图片描述
设置参数,使能扫描
在这里插入图片描述
下发到hci层
在这里插入图片描述
在这里插入图片描述

BTM_BleObserve超时后扫描结束
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
并掉用扫描完成函数
bta_dm_observe_cmpl_cb
在这里插入图片描述
返回扫描结果从hci返回

BTU                           btu_hcif_process_event/HCI_BLE_ADV_PKT_RPT_EVT
 
                              btu_ble_process_adv_pkt
 
BTM                           btm_ble_process_adv_pkt
 
                              btm_ble_process_adv_pkt_cont
 
BTA                           bta_scan_results_cb
 
BTIF                          BTIF_GATT_OBSERVE_EVT

返回扫描结果
btm_ble_process_adv_pkt_cont
在这里插入图片描述

  tBTM_INQ_RESULTS_CB* p_obs_results_cb = btm_cb.ble_ctr_cb.p_obs_results_cb;
  if (p_obs_results_cb && (result & BTM_BLE_OBS_RESULT)) {
    (p_obs_results_cb)((tBTM_INQ_RESULTS*)&p_i->inq_info.results,
                       const_cast<uint8_t*>(adv_data.data()), adv_data.size());
  }
  

調用到bta_dm_observe_results_cb
在这里插入图片描述

 if (bta_dm_search_cb.p_scan_cback)
    bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result);

调用到bta_scan_results_cb
在这里插入图片描述
在这里插入图片描述
通过callback上传到jni层,再上传到应用层
在这里插入图片描述

  HAL_CBACK(bt_gatt_callbacks, scanner->scan_result_cb, ble_evt_type, addr_type,
            &bd_addr, ble_primary_phy, ble_secondary_phy, ble_advertising_sid,
            ble_tx_power, rssi, ble_periodic_adv_int, std::move(value));
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值