码迷,mamicode.com
首页 > 移动开发 > 详细

Android4.4 之Bluetooth整理

时间:2014-08-12 19:13:57      阅读:336      评论:0      收藏:0      [点我收藏+]

标签:android   style   blog   http   java   使用   os   io   

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服务: 

bubuko.com,布布扣Bt 服务

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

 2.  BluetoothAdapter 

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

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

bubuko.com,布布扣mManagerService.enable()

mManagerService其实就是bluetoothAdapter的一个proxy, 

bubuko.com,布布扣getDefaultAdapter

bubuko.com,布布扣BluetoothAdapter

 3. BluetoothManagerService

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

bubuko.com,布布扣BluetoothManagerService:enable()

bubuko.com,布布扣sendEnableMsg

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

bubuko.com,布布扣handleEnable

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

 4. AdapterService,AdapterState

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

bubuko.com,布布扣AdapterService:enable()

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

bubuko.com,布布扣USER_TURN_ON

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

bubuko.com,布布扣processStart

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

bubuko.com,布布扣BT Profile log

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

交给了PendingCommandState下的processMessage处理

bubuko.com,布布扣case STARTED

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

 此时就进入了JNI了

 5. JNI 调用

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

bubuko.com,布布扣enableNative

static const bt_interface_t *sBluetoothInterface = NULL;

bubuko.com,布布扣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(); 会调到下方

bubuko.com,布布扣bluetooth:enable()

 

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

bubuko.com,布布扣btif_enable_bluetooth

 

 external/bluetooth/bluedroid/main/Bte_main.c

bubuko.com,布布扣bte_main_enable

 

bubuko.com,布布扣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 的初始化

bubuko.com,布布扣bte_main_in_hw_init

 

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

bubuko.com,布布扣bt_hc_get_interface

 

bubuko.com,布布扣bluetoothHCLibInterface

 

由以上可以看到set_power

bubuko.com,布布扣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 初始化:

bubuko.com,布布扣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

bubuko.com,布布扣op

bubuko.com,布布扣upio_set_bluetooth_power

static char *rfkill_state_path = NULL;

 rfkill_state_path 是在下面初始化的。

bubuko.com,布布扣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 如下:

bubuko.com,布布扣log

 

 

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

bubuko.com,布布扣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


Android4.4 之Bluetooth整理,布布扣,bubuko.com

Android4.4 之Bluetooth整理

标签:android   style   blog   http   java   使用   os   io   

原文地址:http://my.oschina.net/u/994235/blog/300439

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!