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 Command給Controller。接下來我們會通過分析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 Command是Link 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
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
相關文章
- Android Bluetooth hciReason(HCI_ / HCI_ERR_)定義Android
- linux下bluetooth程式設計(三)HCI層程式設計Linux程式設計
- Android Bluetooth 入門Android
- 深入瞭解Android藍芽Bluetooth——《基礎篇》Android藍芽
- Dialogment詳解
- LogMiner詳解
- Android藍芽那點事——深入瞭解Android藍芽Bluetooth《進階篇》Android藍芽
- Android中級教程之----Log圖文詳解(Log.v,Log.d,Log.i,Log.w,Log.e)!Android
- Logstash使用詳解
- MongoDB oplog詳解MongoDB
- BLE藍芽那些事—深入瞭解Android藍芽Bluetooth基礎篇藍芽Android
- Android——最全的系統對話方塊(AlertDialog)詳解Android
- Android AlterDialog 常用對話方塊使用方法詳解Android
- showModalDialog()、showModelessDialog()方法使用詳解
- log4j 詳解
- Android AsyncTask 詳解Android
- Android:動畫詳解Android動畫
- Android拖拽詳解Android
- Android:Service詳解Android
- Android Notification 詳解Android
- Android WebView 詳解AndroidWebView
- Android – Drawable 詳解Android
- Android RecyclerView詳解AndroidView
- Android Proguard 詳解Android
- android service詳解Android
- log4net使用詳解
- git log提交歷史詳解Git
- Logstash詳解之——output模組
- LOG_ARCHIVE_DEST_n詳解Hive
- Logstash詳解之——input模組
- Logstash詳解之——filter模組Filter
- log4j配置詳解
- C:/inetpub/logs/logfile/路徑詳解
- linux下bluetooth程式設計(五)bluetooth與socketLinux程式設計
- MySQL Binlog 解析工具 Maxwell 詳解MySql
- Log4J.xml配置詳解XML
- log4j.properties配置詳解
- Android SecureRandom漏洞詳解Androidrandom