Android4.4 之Bluetooth整理

Android 4.4上蓝牙协议栈采用的是BRCM和Google共同开发的bluedroid,代替了之前的Bluez.

一、 Bluetooth 源码分布 (基于Android 4.4 )

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

bluetooth Settings 代码

2. packages/apps/Bluetooth

BT 应用层代码,及BT profile(如:A2dp,gatt,hdp,hfp,hid,map,opp,pan,pbap ...) 上层代码

packages/apps/Bluetooth/jni

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

framework 层相关 java 代码与aidl

4. external/bluetooth/bluedroid

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固件

二、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 电话号码簿访问协议

三、Enable Bluetooth

1. 服务启动:

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

系统启动时在SystemServer中注册蓝牙服务管理BluetoothManagerService服务:

Android4.4 之Bluetooth整理 Bt 服务

其它进程通过binder机制调用该服务,该服务属于综合服务管理类,包括AdapterService的启动、蓝牙适配器Adapter的管理等。

2. BluetoothAdapter

Android的蓝牙Enable是由BluetoothAdapter提供的。只需要调用BluetoothAdapter.enable()即可启动蓝牙。下面我就分析这一个过程

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

Android4.4 之Bluetooth整理 mManagerService.enable()

mManagerService其实就是bluetoothAdapter的一个proxy,

Android4.4 之Bluetooth整理 getDefaultAdapter

Android4.4 之Bluetooth整理 BluetoothAdapter

3. BluetoothManagerService

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

Android4.4 之Bluetooth整理 BluetoothManagerService:enable()

Android4.4 之Bluetooth整理 sendEnableMsg

sendEnableMsg 交给handleMessage 处理,可以看到case MESSAGE_ENABLE: 里调用了handleEnable

Android4.4 之Bluetooth整理 handleEnable

可以看到是调用了mBluetooth.enable()

4. AdapterService,AdapterState

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

Android4.4 之Bluetooth整理 AdapterService:enable()

此处用了用了StateMachine,它会在AdapterState 里processMessage 处理(StateMachine就是状态机,在不同的状态下,收到相同的Event,做不同的事情),直接搜索UER_TURN_ON 可以看到下面:

Android4.4 之Bluetooth整理 USER_TURN_ON

接下来是调用了adapterService.processStart()

Android4.4 之Bluetooth整理 processStart

setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON); 是用来开启Bluetooth Profile 的,log 中可以看到:

Android4.4 之Bluetooth整理 BT Profile log

然后可以看到:mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED));

交给了PendingCommandState下的processMessage处理

Android4.4 之Bluetooth整理 case STARTED

由mAdapterService.enableNative(); 可以看到 /*package*/ native boolean enableNative();

此时就进入了JNI了

5. JNI 调用

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

Android4.4 之Bluetooth整理 enableNative

static const bt_interface_t *sBluetoothInterface = NULL;

Android4.4 之Bluetooth整理 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(); 会调到下方

Android4.4 之Bluetooth整理 bluetooth:enable()

接下来调用:external/bluetooth/bluedroid/btif/src/Btif_core.c

Android4.4 之Bluetooth整理 btif_enable_bluetooth

external/bluetooth/bluedroid/main/Bte_main.c

Android4.4 之Bluetooth整理 bte_main_enable

Android4.4 之Bluetooth整理 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 的初始化

Android4.4 之Bluetooth整理 bte_main_in_hw_init

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

Android4.4 之Bluetooth整理 bt_hc_get_interface

Android4.4 之Bluetooth整理 bluetoothHCLibInterface

由以上可以看到set_power

Android4.4 之Bluetooth整理 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 初始化:

Android4.4 之Bluetooth整理 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

Android4.4 之Bluetooth整理 op

Android4.4 之Bluetooth整理 upio_set_bluetooth_power

static char *rfkill_state_path = NULL;

rfkill_state_path 是在下面初始化的。

Android4.4 之Bluetooth整理 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 如下:

Android4.4 之Bluetooth整理 log

下面为minicom 里开启蓝牙的logcat 的log

Android4.4 之Bluetooth整理 logcat