Android Bluetooth HCI log 詳解

飯小粒發表於2020-10-22

0. 引子

對於藍芽開發者來說,通過HCI log可以幫助我們更好地分析問題,理解藍芽協議,就好像網路開發一定要會使用Wireshark分析網路協議一樣。

本篇主要介紹HCI log的作用如何抓取一份HCI log,並結合一個實際的例子來說明如何分析HCI log

1. HCI log 介紹

1.1 HCI log 作用

HCI log是用來分析藍芽裝置之間的互動行為是否符合預期是否符合藍芽規範。在日常的開發中,通常使用HCI log來做這樣幾件事:

  • 分析Bug:藍芽開啟後搜尋不到裝置,或者搜尋到的裝置沒有名稱只有藍芽地址;Android手機不能向蘋果手機傳輸檔案 ... ...

  • 需求分析:手機需要適配一款藍芽自拍杆來控制拍照,通過HCI log可以觀察競品在實現這個功能時,使用的是什麼Bluetooth Profile?只要知道了使用的Bluetooth Profile,我們就有了實現這個功能的思路。

  • 藍芽協議學習:通過HCI log輔助學習藍芽協議,就好像學習TCP/IP時,通過wireshark抓包來學習TCP協議

1.2 藍芽核心系統架構

說了這麼多HCI log的用處,要想更好地理解HCI log,我們需要先來看下HCI在整個藍芽核心系統架構中所處的位置。為了理解起來更簡單,我這邊將藍芽核心系統架構抽象為3層

  • User Application(Host):User Application即應用層,也被稱為Host,我們呼叫Bluetooth API就屬於應用層,例如,BluetoothAdapter中提供的介面。

  • HCI (Host controller Interface):上層在呼叫藍芽API時,不會直接操作藍芽底層(Controller)相關介面,而是通過HCI下發對應操作的Command給Controller,然後底層執行命令後返回執行結果,即Controller傳送Event給HCI,HCI再通知給應用層,HCI起到了一個中間層的作用。

  • Controller:Controller是在最底層,可以理解為我們手機上的藍芽晶片。

抽象後的藍芽架構

完整的藍芽核心系統架構比較複雜,這裡我們就不再深入,感興趣的同學可以參考藍芽規範Core_v4.2.pdf,裡面有詳細的定義和介紹。我們後面在分析HCI log時,也會參考這個規範中定義的內容。

完整的藍芽架構

2. 如何抓取HCI log

在開發者選項中開啟啟用藍芽HCI資訊收集日誌開關,Android系統就開始自動地收集HCI log並儲存到手機上。

啟用藍芽HCI資訊收集日誌

不同的平臺存放HCI log的路徑會不一樣,MTK存放HCI log的路徑為/sdcard/mtklog/btlog/btsnoop_hci.log高通的存放路徑為/sdcard/btsnoop_hci.log

 

MTK:/ $ ls -l /sdcard/mtklog/btlog/
total 816
-rw-rw---- 1 root sdcard_rw 412258 2016-02-28 00:39 btsnoop_hci.log

shell@Qualcomm:/ $ ls -l /sdcard/btsnoop_hci.log
-rw-rw---- root     sdcard_rw    12744 2017-06-16 15:43 btsnoop_hci.log

如果上面提到的路徑下都沒有HCI log,我們還可以通過手機上的藍芽配置檔案bt_stack.conf來檢視路徑,bt_stack.conf位於/etc/bluetooth/路徑下。HCI log路徑通過BtSnoopFileName=/sdcard/btsnoop_hci.log來進行設定的。

HCI log在手機上的路徑

而bt_stack.conf是通過Android原始碼中的/system/bt/conf/bt_stack.conf來配置的。

 

// /system/bt/conf/bt_stack.conf
# BtSnoop log output file
BtSnoopFileName=/sdcard/btsnoop_hci.log

將抓取到的HCI log pull出來,直接用記事本開啟,看到的都是亂碼。我們還需要一個HCI log分析工具:Frontline ComProbe Protocol Analysis System

 

C:\Windows\System32>adb pull /sdcard/mtklog/btlog/btsnoop_hci.log C:\Users\admin\Desktop\hci
501 KB/s (4880 bytes in 0.009s)

3. HCI log分析工具

Frontline ComProbe Protocol Analysis System是Frontline提供的一款藍芽協議log分析工具,Frontine這家公司主要是做抓取藍芽Air sniff log裝置的,我們後面再來說下什麼是Air sniff log。購買他們的抓包工具就會附帶log分析工具,也可以在Frontine官網上下載,下載的時候需要填一些資訊,覺得麻煩的同學可以去其他非官網途徑進行下載。

安裝完成後,在開始選單中找到Frontline ComProbe Protocol Analysis System,使用Capture File Viewer可以開啟HCI log

 

ComProbe Protocol Analysis System

Step 1. 首先,選擇要開啟的HCI log,並選擇log型別為BtSnoop Files,即以*.log結尾的檔案。
還有一種方式是將btsnoop_hci.log的字尾修改為btsnoop_hci.cfa,就可以直接用Capture File Viewer開啟。

Step 1. 開啟的HCI log

 

選擇log型別

Step 2. 開啟log檔案後,選擇Frame Display就可以看到我們抓取的HCI log了

Step 2 . 選擇Frame Display

Frame Display主介面

Step 3. Frame Display視窗中有很多Tab,將協議棧中各類協議分類顯示,例如:HCI相關的log放在HCI的Tab中,Hands-Free(HFP)屬於應用層的Bluetooth Profile,和HFP相關操作的log都放在Hands-Free這個Tab中。

Frame Display

  • Air sniff log
    Android裝置上抓取的HCI log只能分析Host和Control之間的問題,當Host和Control之間互動是正常的,那就可能就是傳輸的過程中(Air Interface)出了問題,此時就需要分析Air sniff log。Air sniff log能夠抓取的兩個藍芽裝置在資料傳輸過程中的空中包,抓取Air sniff log需要專門的裝置。

Air sniff log

4. HCI log 案例 - 藍芽掃描裝置過程分析

應用層在呼叫startDiscovery()進行裝置掃描時,Host會通過HCI傳送一個Inquiry HCI CommandController。接下來我們會通過分析HCI log,來學習Inquiry 的流程。在分析HCI log前,我們先來學習下HCI Command資料包的結構。

4.1 HCI Command 資料包結構

HCI Command資料包結構定義在藍芽核心協議規範Core_v4.2.pdf中。

HCI Command資料包格式如下,開頭的Opcode是區分不同型別的命令的唯一標識,Opcode由OpCode Group Field (OGF)OpCode Command Field (OCF)組成。根據OGF的值,可以將HCI commands進行分類。OpCode 的計算公式為:** OpCode = OGF << 6 + OCF 。有了OpCode計算的方式,我們就可以通過OpCode過濾**HCI log裡面的指定型別的HCI Command。

HCI Command Packet

OpCode計算方法

4.2 過濾Inquiry Command

Inquiry CommandLink Control command型別的command,通過查詢Bluetooth Core Specification的中Vol 2->Part E->7.1 LINK CONTROL COMMANDS小節,可知Link Control command的OCF值為0x0001

Bluetooth Core Specification目錄

For the Link Control commands, the OGF is defined as 0x01

因此,Inquiry Command的Opcode為 0x0001 << 6 + 0x01 = 0x0401通過0x0401就確定某條command為Inquiry Command,該命令的名稱為HCI_Inquiry

Inquiry Command

ComProbe Protocol Analysis System支援過濾功能,通過設定filter可以過濾出Opcode為0x0401的log,設定方法如下圖:

 

過濾HCI_Inquiry

4.3 掃描過程分析

1. 傳送Inquiry請求

  • Host傳送HCI_Inquiry Command
    應用層要進行藍芽裝置掃描啦,Host先發一條HCI_Inquiry的Command通知Controller

Host: HCI_Inquiry

  • Controller回覆HCI Event
    Controller在收到HCI_Inquiry這條Command後,會回覆一條Command Status的HCI Event,來表示Controller執行HCI_Inquiry後的狀態,即Status:Success。仔細觀察可以發現這兩條HCI log的Frame標號是挨著的,HCI_Inquiry的幀號是196,Command Status的幀號是197。

Controller:Command_status、

2. 掃描結果

掃描完成後,Controller會傳送Event:HCI Extended Inquiry Result。以列表中搜尋到的Jabra Classic v0.5.3為例,它的HCI Extended Inquiry Result資料包中會包含它的裝置名稱、它所支援的Service的UUID,和裝置型別Wearable Headset device,因此,Jabra Classic v0.5.3的Icon是一個耳機的圖示

掃描結果

Jabra Classic v0.5.3的HCI Extended Inquiry Result



作者:傷口不該結疤
連結:https://www.jianshu.com/p/73f7366161d1
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

相關文章