Android4.4 之Bluetooth整理

Android 4.4上藍牙協議棧採用的是BRCM和Google共同開發的bluedroid,代替了以前的Bluez.java

1、 Bluetooth 源碼分佈 (基於Android 4.4 )linux

1.  packages/apps/Settings/src/com/android/settings/bluetoothandroid

     bluetooth Settings 代碼shell

2.  packages/apps/Bluetooth網絡

     BT 應用層代碼,及BT profile(如:A2dp,gatt,hdp,hfp,hid,map,opp,pan,pbap ...) 上層代碼app

     packages/apps/Bluetooth/jniide

3.  frameworks/base/core/java/android/bluetooth函數

     framework 層相關 java 代碼與aidl優化

4.  external/bluetooth/bluedroid      spa

     BRCM和Google共同開發的官方藍牙協議棧

5.  linux/kernel/drivers/bluetooth

6.  linux/kernel/net/bluetooth

7. 如下是近期項目intel 平臺

hardware/broadcom/libbt

hardware/libhardware

vendor/intel/fw/PRIVATE/bt    廠商bt固件

 2、Bluetooth 經常使用類及相關profile

A2dp: Advanced Audio Distribution Profile 藍牙音頻傳輸模型協定

 藍牙立體聲,和藍牙耳機聽歌有關那些,另還有個AVRCP--(Audio/Video Remote Control Profile)音頻/視頻遠程控制配置文件,是用來聽歌時暫停,上下歌曲選擇的

GATT: Generic Attribute Profile   通用屬性配置文件

       GATT是基於ATT Protocol的,ATT針對BLE設備作了專門的優化,具體就是在傳輸過程當中使用盡可能少的數據。每一個屬性都有一個惟一的UUID,屬性將以characteristics and services的形式傳輸

       https://developer.bluetooth.org/TechnologyOverview/Pages/GATT.aspx

HDP:Bluetooth Health Device Profile 藍牙關於醫療方面的應用 

HFP : Hands-free Profile  和電話相關,藍牙接聽、掛斷電話 

HID : Human Interface Device  

         定義了藍牙在人機接口設備中的協議、特徵和使用規程。典型的應用包括藍牙鼠標、藍牙鍵盤、藍牙遊戲手柄等。該協議改編自USB HID Protocol

MAP : Message Access Profile

OPP : Object Push Profile

PAN : Personal Area Network Profile

描述了兩個或更多個 Bluetooth 設備如何構成一個即時網絡,和網絡有關的還有串行端口功能(SPP),撥號網絡功能(DUN)

PBAP: Phonebook Access Profile 電話號碼簿訪問協議

 

3、Enable Bluetooth

1. 服務啓動:

frameworks/base/services/java/com/android/server/SystemServer.java

系統啓動時在SystemServer中註冊藍牙服務管理BluetoothManagerService服務: 

Bt 服務

 其它進程經過binder機制調用該服務,該服務屬於綜合服務管理類,包括AdapterService的啓動、藍牙適配器Adapter的管理等。

 2.  BluetoothAdapter 

Android的藍牙Enable是由BluetoothAdapter提供的。只須要調用BluetoothAdapter.enable()便可啓動藍牙。下面我就分析這一個過程

 frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java

mManagerService.enable()

mManagerService其實就是bluetoothAdapter的一個proxy, 

getDefaultAdapter

BluetoothAdapter

 3. BluetoothManagerService

frameworks/base/services/java/com/android/server/BluetoothManagerService.java

BluetoothManagerService:enable()

sendEnableMsg

sendEnableMsg 交給handleMessage 處理,能夠看到case MESSAGE_ENABLE: 裏調用了handleEnable

handleEnable

能夠看到是調用了mBluetooth.enable()

 4. AdapterService,AdapterState

packages/app/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

AdapterService:enable()

此處用了用了StateMachine,它會在AdapterState 裏processMessage 處理(StateMachine就是狀態機,在不一樣的狀態下,收到相同的Event,作不一樣的事情),直接搜索UER_TURN_ON 能夠看到下面:

USER_TURN_ON

接下來是調用了adapterService.processStart()

processStart

setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON); 是用來開啓Bluetooth Profile 的,log 中能夠看到:        

BT Profile log

而後能夠看到:mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED)); 

交給了PendingCommandState下的processMessage處理

case STARTED

由mAdapterService.enableNative(); 能夠看到 /*package*/ native boolean enableNative();

 此時就進入了JNI了

 5. JNI 調用

enableNative() 是在 packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

enableNative

static const bt_interface_t *sBluetoothInterface = NULL;

bt_interface_t 定義

 bt_interface_t 定義 在hardware/libhardware/include/hardware/bluetooth.h

sBluetoothInterface的初始化在classInitNative(),這個函數大概作了如下的事情:

1)、註冊java的回調函數(就是當下層已經打開藍牙了,而後要通知上層,藍牙已經打開了,java層就能夠發送藍牙打開的Broadcast了。)

2)、初始化藍牙模塊的HAL接口。

3)、獲得sBluetoothInterface

 

6. Bluedroid ->bluetooth.c

external/bluetooth/bluedroid/btif/src/bluetooth.c

sBluetoothInterface->enable(); 會調到下方

bluetooth:enable()

 

接下來調用:external/bluetooth/bluedroid/btif/src/Btif_core.c

btif_enable_bluetooth

 

 external/bluetooth/bluedroid/main/Bte_main.c

bte_main_enable

 

bte_hci_enable

咱們先看下bt_hc_if->set_power,前面有作一些初始化Bluedroid的動做

由 bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);能夠看出:

static bt_hc_interface_t *bt_hc_if=NULL;

下面是bt_hc_if 的初始化

bte_main_in_hw_init

 

 external/bluetooth/bluedroid/hci/src/Bt_hci_bdroid.c

bt_hc_get_interface

 

bluetoothHCLibInterface

 

由以上能夠看到set_power

set_power

 

能夠看到,bt_vnd_if->op(BT_VND_OP_POWER_CTRL, &pwr_state);

 external/bluetooth/bluedroid/hci/src/Bt_hw.c

bt_vendor_interface_t *bt_vnd_if=NULL;

 bt_vnd_if 初始化:

init_vnd_if

在init_vnd_if()函數能夠看到實際上是一個libbt-vendor.so的interface。這個是Vendor(芯片廠商)的library

Vendor就是芯片供應商的意思,在他們作好一塊藍牙芯片後,須要提供一些硬件相關的動做,好比上下電,設置波特率之類的。可是這些 操做通常不會對沒有許可的開放。Bluedroid提供了一個統一的接口bt_vendor_interface_t,供應商只須要實現這個接口定義的藍 牙相關的操做就能夠交給bluedroid去作剩下的事情了

 

下面主要是broadcom 爲例,咱們進入/hardware/裏面:

$ find . -name Android.mk |xargs grep libbt
./broadcom/libbt/Android.mk:LOCAL_MODULE := libbt-vendor
./broadcom/libbt/Android.mk:LOCAL_MODULE := libbt-vendor
./broadcom/libbt/Android.mk:    LOCAL_SRC_FILES := $(TI_BT_VENDOR_PATH)/libbt-vendor-ti.c
./qcom/bt/Android.mk:include $(call all-named-subdir-makefiles,libbt-vendor)
./qcom/bt/libbt-vendor/Android.mk:LOCAL_MODULE := libbt-vendor

 

或者

$ grep -nr BT_VND_OP_POWER_CTRL
broadcom/libbt/src/bt_vendor_brcm.c:147:        case BT_VND_OP_POWER_CTRL:
broadcom/libbt/src/bt_vendor_brcm.c:149:                BTVNDDBG("op: BT_VND_OP_POWER_CTRL");
qcom/bt/libbt-vendor/src/bt_vendor_qcom.c:105:        case BT_VND_OP_POWER_CTRL:

在broadcom/libbt/src/bt_vendor_brcm.c

op

upio_set_bluetooth_power

static char *rfkill_state_path = NULL;

 rfkill_state_path 是在下面初始化的。

init_rfkill

原來就是在rfkill_state_path(/sys/class/rfkill/rfkill[x]/state)虛擬設備裏寫入了1

shell@android :/sys/class/rfkill/rfkill0 $ cat state
0  // 表示藍牙是關閉狀態

shell@android :/sys/class/rfkill/rfkill0 $ cat state 

1   // 開啓藍牙後能夠看到

rfkill是Linux下的一個標準的無線控制的虛擬設備,Linux也提供了rfkill的命令去查看以及控制全部的註冊的無線設備。它們會在/dev/(PC的Linux)或者/sys/class(通常是Android)下生成相應的虛擬設備。

 

結合set_power 下面的log 和 bluetoothHCLibInterface  定義,能夠看到接下來是調用的 bluetoothHCLibInterface 裏的 proload->bthc_signal_event(HC_EVENT_PRELOAD)->bt_hc_worker_thread -》 userial_open(USERIAL_PORT_1)->bt_vnd_if->op(BT_VND_OP_USERIAL_OPEN, &fd_array);->userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);

接下來是Hardware.c裏

hw_config_start-》hw_config_cback

部分log 以下:

log

 

 

下面爲minicom 裏開啓藍牙的logcat 的log

logcat

 

 

 

Ref:

http://blog.csdn.net/baimy1985/article/details/8892410

http://my.oschina.net/u/1436933/blog/192060

http://blog.csdn.net/yutao52shi/article/details/12690353

相關文章
相關標籤/搜索