作者:王石
藍牙功能是無線短距的重要能力,在工作、生活中有很多藍牙設備,比如車載藍牙設備,藍牙耳機,藍牙鍵盤。
1994 年由電信商愛立信發展出這個技術,最初藍牙的設計是系統創建出一個 RS-232 數據線的無線通信技術替代版,能夠連結多個設備並克服同步問題。
目前藍牙技術由藍牙技術聯盟(SIG Special Interest Group)來負責維護其技術標準,IEEE 曾經將藍牙技術標準化為 IEEE 802.15.1,但是這個標準已經不再繼續使用。
接下來我們就深入分析下開源鴻蒙的藍牙結構和各層作用及工作內容。
概述
在開源鴻蒙的源碼里和系統功能相關的部分大多都放在 foundation 這個文件夾里,而通訊相關的部分則是在 communication 這個文件夾內。
我們本篇要分析的藍牙功能就是在 foundation/communication/Bluetooth 路徑下。
具體目錄結構如下:
.
├── bundle.json
├── frameworks //框架層
│ ├── inner
│ └── js
├── hisysevent.yaml
├── interfaces //接口層
│ ├── inner_api
│ └── kits
├── LICENSE
├── README.md
├── README_zh.md
├── sa_profile //系統能力配置
│ ├── 1130.xml
│ └── BUILD.gn
├── services //服務層
│ ├── bluetooth
│ └── bluetooth_lite
└── test 測試代碼
├── example
├── fuzztest
├── moduletest
└── unittest
架構簡析
根據目錄結構和內部文件及編譯框架總結架構如下:
接口層:對外提供 js 接口,採用 d.ts 定義,藍牙文件夾內位置 interfaces/kits/js 具體存放路徑在
interface/sdk-js/api/@ohos.bluetooth.d.ts
對內提供 c 接口,可以供 softbus,netmanager,audioframework 三個子系統調用,藍牙文件夾內位置 interfaces/inner_api/include。
框架層:分兩個子層,NAPI 框架實現層,藍牙文件夾內位置
foundation/communication/bluetooth/frameworks/js/napi
實現所有 js 層代碼接口適配並調用 innerapi 的實現;藍牙接口實現層,使用 IPC 架構同藍牙服務層通信,將從 NAPI 收到的命令,或者別的子系統收到的命令經由 IPC 架構發送給服務層,並註冊服務層 observer,收聽由服務層上報的事件。
服務層:分三個子層。
系統能力層,藍牙文件夾內位置:
foundation/communication/bluetooth/services/bluetooth/server
實現藍牙系統能力服務,接收從框架層經由 IPC 發送下來的命令,並收聽藍牙 service 傳上來的消息並回傳給藍牙框架層。
藍牙服務層,藍牙文件夾內位置:
foundation/communication/bluetooth/services/bluetooth/service
實現不同藍牙能力的 adapter(包括 classic_adapter 和 BLE_adapter),通過調用藍牙協議棧實現藍牙業務的邏輯能力。
藍牙協議棧,藍牙文件夾內位置:
foundation/communication/bluetooth/services/bluetooth/stack
實現藍牙協議包解析,打包以及藍牙協議流程的處理,實現藍牙 host,藍牙 profile 以及藍牙鏈路和 hci 接口,最後通過使用藍牙硬體驅動收發藍牙原始數據。
硬體驅動:預編譯包,通過 dlopen 提供 hci 的底層接口,註冊回調以及發送數據。
功能簡析
①NAPI 功能
HAP 應用層通過 @ohos.bluetooth.d.ts 引用調用藍牙接口,藍牙接口包括 bluetooth 接口,BLE 接口,profile 接口。
bluetooth 接口包括經典藍牙接口,BLE 接口接口,和 profile 接口;目前支持的 profile 有 A2dpSourceProfile,HandsFreeAudioGatewayProfile,HidHostProfile 和 PanProfile。
NAPI 框架接口均通過 DECLARE_NAPI_FUNCTION,js 的回調也通過此接口經由傳入回調函數指針實現。
NAPI 層通過調用藍牙框架層的 BluetoothHost 實現功能,通過將 g_bluetoothHostObserver 註冊到框架層內部實現來獲得消息回調。
同時 NAPI 層提供 g_Observer 存儲 js 層的回調函數,在收到框架層的回調後在 g_Observer 里查找對應的回調函數來實現應用通知;此對象因為是 map 結構體,所以一個應用只能註冊一個並在應用內部自己處理。
②藍牙框架功能
藍牙框架提供 cadapter 接口和藍牙框架具體實現(藍牙 NAPI 層調用的 BluetoothHost 即在具體實現層)。
cadapter 實現 c 接口,通過 BluetoothHost 實現功能,其他外部模塊均通過 cadapter 提供的 c 接口調用藍牙能力。
藍牙框架內部實現層提供接口一一對應 cadapter 和 NAPI 接口。
BluettoothHost 內部通過:
SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager()
接口得到 samgr,然後通過 BLUETOOTH_HOST_SYS_ABILITY_ID 標識獲取藍牙服務對象,然後通過藍牙服務對象通過 IPC 接口調用藍牙服務功能。
藍牙框架內部提供 RegisterObserver 方式,允許其他層應用(比如軟總線層通過調用 cadapter 接口 GapRegisterCallbacks 收聽藍牙的回調事件)收聽藍牙回調事件。
藍牙框架因為是動態庫實現,所以如果有多處依賴則會生成多份實例,如 NAPI 和軟總線都依賴藍牙框架庫,所以在系統里會有兩份實例同時若產生藍牙通知也會有兩個進程同時收到消息。
③藍牙系統能力
藍牙系統能力通過繼承 SystemAbility,BluetoothHoststub 兩個類實現藍牙服務能力並實現 IPC 進行通信。
IPC 通信部分的代碼在藍牙文件夾 foundation/communication/bluetooth/services/bluetooth/ipc 內,提供 proxy 和 stub 實現,即 btipc_static.a 靜態庫。
藍牙系統能力可視作藍牙服務進程,提供包括藍牙狀態機,藍牙 adapter(classic,ble),藍牙 profile 服務實例。
藍牙系統配置在 foundation/communication/bluetooth/services/bluetooth/etc/init 目錄內,此部分內容會在製作鏡像包時打包到系統文件內去。
在藍牙服務啟動的時候會讀取藍牙配置(AdapterConfig::GetInstance()->Load(),ProfileConfig::GetInstance()->Load())並確定藍牙的 snooplog(協議棧輸出文件)。
藍牙系統能力內部使用 Dispatcher 模型執行任務事務,在 Dispatcher 對象內部它通過線程加任務隊列的方式處理多條任務命令,目前實現方法為但線程依次處理隊列內的事務。
藍牙系統能力層通過 permission_utils 提供應用權限保護能力,服務調用功能時首先調用 PermissionUtils::VerifyXXXBluetoothPermission(XXX包括,Use,Discover,Manage,Location)。
然後調用 AuthCenter 對應功能,最後調用 PermissionHelper 對應接口確認權限;在 AuthCenter 里內部定義了 g_permissionAlwaysGrant 全局變量,可以方便調試時擁有所有權限。
④藍牙協議棧
藍牙協議棧通過 c 接口對藍牙服務層提供接口;
藍牙協議棧內部他提供任務隊列方式處理藍牙命令(GapRunTaskBlockProcess,GapRunTaskUnBlockProcess),分別對於藍牙協議棧同步接口和異步接口。
藍牙協議棧內部也有層級,對上的是 gap,中間是 btm,對下的是 hci,中間部分和其他藍牙協議站定義的內容一致,如:att,avctp,avdtp,l2cap,rfcomm,sdp,smp。
HCI 層它通過 g_hdiLib 加載藍牙驅動庫 libbluetooth_hdi_adapter.so,並通過加載藍牙驅動接口(HdiInit,HdiSendHciPacket,HdiClose)實現藍牙數據發送,藍牙數據接收(g_hdiCallacks)。
總結
藍牙服務的結構也是所有開源鴻蒙的結構能力,大致流程均為:NAPI 框架,系統服務框架,IPC 框架,Observer 框架,原生 driver 框架(其實可以採用 HDF 框架)。
目前開源鴻蒙用的藍牙協議站不是 android,bluez,btstack 這三種主流藍牙協議棧,根據注釋可得其參考《BLUETOOTH SPECIFICATION Version 5.0》實現。
目前官方最新的協議棧是 v5.3,參考連結如下:
https://www.bluetooth.com/specifications/specs/core-specification-5-3/