Android Bluetooth HCI log 詳解

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

5. 參考

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 姓名:于川皓 學號:16140210089 轉載自:http://blog.csdn.net/xubin34171...
    道無涯_cc76閱讀 8,225評論 0 11
  • 背景 藍牙歷史說到藍牙,就不得不說下藍牙技術聯盟(Bluetooth SIG),它負責藍牙規范制定和推廣的國際組織...
    徐正峰閱讀 12,523評論 6 33
  • 自己封裝的BLE庫(5.0以上) 這里不記錄具體代碼規則,后面會給出參考文章,別人已經寫很詳細了,我就單純記錄下踩...
    冰川孤辰js閱讀 4,829評論 1 11
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,869評論 18 139
  • 前言 最近在做Android藍牙這部分內容,所以查閱了很多相關資料,在此總結一下。 基本概念 Bluetooth是...
    貓疏閱讀 14,723評論 7 113