1. 程式人生 > >Android Bluetooth Stack: Bluedroid(四):Scan remote devices

Android Bluetooth Stack: Bluedroid(四):Scan remote devices

    Enable Bluetooth之後就可以掃描周圍的其他discoverable mode的Bluetooth Device。以下簡單分析以下Bluetooth BR/EDR裝置的掃描過程,然後會談一下Android 4.2引入的Bluetooth HAL。

    啟動scan的呼叫過程很簡單,返回scan結果的過程略為複雜。

    以下是start scan的流程圖,從Settings到Frameworks再到Bluedroid。LocalBluetoothAdapter是Settings裡面的一個類。BluetoothAdatper定義在frameworks中。AdapterService的實現是在packages/apps/Bluetooth裡面。startDiscoveryNative()是JNI的介面。從start_discovery()就進入到Bluedroid中了。start_discovery()實際上是Bluetooth HAL中定義的一個介面。關於BTA_DM_API_SEARCH_EVT訊息是如何傳遞的涉及到Bluedroid的架構,留到以後詳細說明。


    啟動scan之後,Bluedroid會通過Bluetooth HAL定義的callback函式discovery_state_change_callback通知Android Framework: BT_DISCOVERY_STARTED;然後會多次通過device_found_callback返回掃描到的Bluetooth device給Android Framework;最後掃描完成,會再次通過discovery_state_change_callback通知Android Framework:BT_DISCOVERY_STOPPED。

    Discovery state changed的呼叫過程如下圖所示,整個過程簡單清晰。Bluetooth HAL中定義的callback是關鍵,它把Discovery state從下層Bluetooth stack傳遞給了上層的Android Framework。AdapterProperties::discoveryStateChangeCallback()會new intent,然後廣播出去。Settings就可以通過BluetoothDiscoveryReceiver收到這個intent了。


    Bluedroid返回找到的Bluetooth device的過程如下。需要注意的是,每找到一個device就會有一次device found callback的呼叫;device_found_callback()在呼叫JniCallbacks::deviceFoundCallback()之前會通過JniCallbacks::devicePropertyChangedCallback()來註冊找到的Bluetooth device。RemoteDevices有一個HashMap<BluetoothDevice, DeviceProperties> mDevices來儲存找到過的Bluetooth devices。


    在上面的分析中,無論是從Android Framework呼叫Bluedroid還是Bluedroid返回結果到Android Framework都要通過Bluetooth HAL介面。這個Bluetooth HAL是在Andorid 4.2中引入的。Bluetooth HAL定義在hardware/libhardware/include/hardware/bluetooth.h中。external/bluetooth/bluedroid/btif實現了該HAL定義的standard Bluetooth DM(Device Management) interface(定義在bt_interface_t)。packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp實現了該HAL定義的Bluetooth DM callback structure: bt_callbacks_t。可以看到,有了Bluetooth HAL之後,Android Framework和Bluetooth stack就可以很清晰的分離開來。下層的Bluetooth stack只要實現了Bluetooth HAL的介面,就可以被Android Framework使用。所以,在Android 4.2及其後續版本中,我們完全可以用其他的Bluetooth stack來替換掉Bluedroid。事實上,已經被Android拋棄的BlueZ正在開發一個Android Bluetooth HAL implementation,這樣我們就可以在Android 4.2及其後續版本中使用BlueZ了(從穩定性和功能上來講,BlueZ目前好於Bluedroid)。有興趣的同學可以參與到BlueZ Android Bluetooth HAL implementation中,除了對bluetooth.h中定義的介面的實現,還有對bt_*.h(比如bt_av.h, bt_hl.h等)中定義的介面的實現,可以在這裡找到BlueZ for Android的介紹http://git.kernel.org/cgit/bluetooth/bluez.git/tree/android/README