藍牙電話顧名思義就是使用藍牙技術實現電話撥打相關功能,當前市面上一般運用到藍牙音箱、藍牙手環和藍牙車載等設備上,由於車載藍牙涉及到的知識點更全面,所以主要以車載為第一視角講解藍牙電話相關的內容。
藍牙電話總體上涉及到藍牙的HFP和PBAP這兩種協議,本篇分享先介紹HFP,PBAP留待下一篇文章繼續。
Hands-Free Profile簡稱HFP,協議規定了免提設備控制電話相關操作,這裡的免提設備指的就是相關的藍牙設備(如車載藍牙、藍牙音箱等)。詳細描述請參考協議文檔HFP_v1.7.1.pdf。
先來大致瞭解下藍牙電話在安卓系統中的架構,然後逐層分析各部分的作用:
藍牙電話應用:下發用戶指令、接收藍牙服務上報的數據,並將數據處理後顯示在相關界面上。由於是以車載藍牙為分析視角,所以使用的相關協議都是Client端的,手機藍牙作為Server端。
藍牙API:安卓系統對外提供的API,這裡主要用到BluetoothHeadsetClient.java、BluetoothPbapClient.java。
由於安卓源碼中關於藍牙協議的client部分或相關接口都被@hide給隱藏掉了,這樣 android.jar 滿足不了安卓源碼framework層開發人員的需求。
解決方法:安卓源碼全編後會在路徑:out\\target\\common\\obj\\JAVA_LIBRARIES\\framework_intermediates下生成包含所有接口的classes.jar文件,該jar包可以替換android.jar使用。
藍牙服務:實現所有的上層服務以及與藍牙協議棧bluedroid交互,這裡主要依賴於hfpclient和pbapclient這兩個模塊。
JNI:實現JAVA層調用C語言模塊,路徑:packages\\apps\\Bluetooth\\jni。
藍牙協議棧:也被稱為藍牙核心協議棧Host部分(android4.2開始主要採用博通開源藍牙協議棧bluedroid),大部分的藍牙協議的實現都是在這一模塊內完成的,通過HCI和底層藍牙芯片進行消息交互。
藍牙芯片:藍牙核心協議棧Controller部分,完成藍牙協議裡偏底層的相關定義,主要由各藍牙芯片廠商開發實現功能。
以上就是藍牙電話架構各部分在安卓系統中具體的作用,接下來會從HFP的連接、通話、AT命令集、語音音頻這四個方面做進一步分析。因為HFP的連接和通話都和上層應用有關聯,所以先對這兩部分作出分析。
一、連接
手機音頻profile的連接具體分為AG和HF這兩個角色,
AG:Audio Gate,音頻網關,音頻設備輸入輸出設備——手機
HF:Hands Free,免提設備,作為音頻網關遠程輸入輸出機制,並可以提供控制功能——車載藍牙
連接的具體流程如下圖:
手機音頻的連接AG和HF側都可以發起,連接過程中的消息交互及流程大體相同。本篇文章沒有特殊聲明,第一視角都是車載藍牙(HF側)作為分析起點。上層應用調用API觸發HFP協議的連接,則底層各模塊相互合作直到連接成功上報HFP的連接狀態,應用層監測到連接狀態後則整個過程完成,詳細流程見如下時序圖:
從上面完整的HFP連接時序圖可以看出藍牙電話應用的操作只需要調用HFP協議的連接API後監聽系統中對應的廣播就行,大部分工作都在bluedroid內完成,各層分工明確高效。
連接過程中唯一需要注意的是藍牙服務層只有在在Service Level Connection連接完成後(對應於相關AT命令依次交互完成)才會對外廣播連接狀態改變到Connected的廣播。
這樣在操作連接HFP協議失敗時,我們就可以從以下六個方面分析原因:
1、 應用層是否正確調用連接的相關API
2、 應用層是否正確設置監聽廣播
3、 當前藍牙的ACL鏈路是否建立成功
4、 SDP服務搜索HFP協議是否正常完成
5、 RFCOMM是否連接成功
6、 AT命令是否依次交互完成
AT命令依次交互的順序為:BRSF -> BAC(AG、HF都支持codec協商) -> CIND=? -> CIND? -> CMER -> CHLD=?(AG、HF都支持三方通話) -> ……
下圖為HFP連接在HCI層的完整流程(PS:RFCOMM連接前應該會有l2cap鏈路的連接,由於這份log中前面已經連接成功,所以截圖中沒有RFCOMM的l2cap鏈路連接)
HFP連接的流程大體就是上面這些要點,後面三部分的內容我們在接下來的文章中再做分析。
閱讀更多 Connectivity 的文章