傳統藍牙搜索流程分析

傳統藍牙搜索流程分析

本期承接上篇分享《傳統藍牙BR/EDR的搜索Inquiry》來聊聊安卓系統中傳統藍牙搜索是如何實現的。
在這裏插入圖片描述

安卓系統中應用Application通過藍牙適配器接口BluetoothAdapter.startDiscovery() 的調用觸發搜索流程的開始,我們的分析也就從這裏開啓。

安卓源碼版本:Android 9,P(Pie餡餅)版本

在分析之前對第三方應用有如下幾個要求:

  1. 確保藍牙狀態打開
  2. 確保應用的清單文件 AndroidManifest.xml 中具有如下幾個權限(也可動態申請)
    在這裏插入圖片描述
  3. 註冊了設備發現的廣播接收處理,這樣才能接收掃描到的藍牙設備信息
    在這裏插入圖片描述

Application通過滿足上述三個條件後,只要觸發搜索流程開啓就可以等待設備信息的上報再做進一步處理,先讓我們整體看下搜索流程的時序圖:
在這裏插入圖片描述

以上就是傳統藍牙查詢的完整流程,其實在開始傳統藍牙查詢的同時,安卓系統也會開啓低功耗藍牙BLE的scan流程,時序圖中將這部分內容去掉了,留待以後分析BLE掃描時再做分析(挖個坑…)。

從時序圖中可以看出應用Application調用完BluetoothAdapter.startDiscovery() 後不需要其他操作了,只需耐心等待相關的系統廣播即可。

指令一直被下發到協議棧bluedroid後,開始封裝數據,並且中間的處理過程都是在協議棧中進行的,所以接下來重點分析下協議棧內部是如何玩轉掃描流程的。

1、 首先指令到達協議棧btif_dm_start_discovery()處理函數中,設置了查詢必要的相關參數
在這裏插入圖片描述
filter_type設置爲0,傳統藍牙的查詢Inquiry過濾關閉。

2、 指令進一步被下發到協議棧的stack層中的 BTM_StartInquiry() 繼續處理,在這裏判斷查詢模式參數如果包含ble,則發起ble的scan掃描。

3、 首先通過HCI指令 HCI_SET_EVENT_FILTER 設置Inquiry的過濾器

4、 設置過濾器的完成事件處理中調用 btm_initiate_inquiry() 開啓真正的查詢

5、 btm_acl_update_busy_level()中 event= BTM_BLI_INQ_EVT 更新當前協議棧的繁忙等級,並且通過JNI層的回調上報藍牙服務層傳統藍牙查詢開始。

6、 通過設置的查詢模式確定Inquiry指令中的查詢訪問代碼LAP值
在這裏插入圖片描述

7、 安卓系統藍牙協議棧bluedroid中默認採用One-Time Inquiry查詢方式,且該方式的查詢結果上報的數量限制默認爲 0 ,也就是不限制上報的數量。
在這裏插入圖片描述

8、 藍牙控制器Controller通過(Inquiry Result、Inquiry Result with RSSI或者Extended Inquiry Result)三種上報事件中的一種依次上報查詢到的設備結果到協議棧

9、 協議棧解析出設備信息後最後在btif_dm_search_devices_evt()函數中通過 event= BTA_DM_INQ_RES_EVT 將查詢到的設備信息上報到藍牙服務層

10、 服務層的RemoteDevices遠端藍牙設備管理類通過廣播 “android.bluetooth.device.action.FOUND” 將設備信息廣播出去

11、 查詢時間12.8s觸發,控制器Controller通過Inquiry Complete事件通知協議棧查詢Inquiry流程完成。但協議棧在收到該完成事件時,不會立即上報服務層查詢結束。

12、 協議棧會先通過查詢記錄對每一個設備發起Discovery流程(主要通過請求遠端名)。

13、 最後所有查詢記錄中的設備都Discovery完成後,纔會上報傳統藍牙查詢結束。

經過以上這些步驟,安卓系統中的搜索流程成功完成。流程對應的HCI交互如下:
在這裏插入圖片描述

本篇流程的分析主要看上述的那幅時序圖就可以了,其他細枝末節的問題可以參照安卓源碼或協議再分析,這裏就不做分析了。感興趣的小夥伴歡迎私信留言一起討論。

更多互聯互通技術,歡迎關注微信公衆號:Connectivity
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章