您的位置:首页 > 编程语言

蓝牙代码基本结构分析

2015-05-30 11:48 323 查看

蓝牙代码总体结构分析

在Android框架代码中,有两个重要接口
IBluetooth
IBluetoothManager


这两个接口之间的类图关系如下:



总体来讲,对于应用程序通过
BluetoothManager
BluetoothAdapter
来操作蓝牙相关接口。

其中
IBluetoothManager
定义了如下一些接口:

interface IBluetoothManager
{
IBluetooth registerAdapter(in IBluetoothManagerCallback callback);
void unregisterAdapter(in IBluetoothManagerCallback callback);
void registerStateChangeCallback(in IBluetoothStateChangeCallback callback);
void unregisterStateChangeCallback(in IBluetoothStateChangeCallback callback);
boolean isEnabled();
boolean enable();
boolean enableNoAutoConnect();
boolean disable(boolean persist);
IBluetoothGatt getBluetoothGatt();

String getAddress();
String getName();
}


上述接口主要跟蓝牙设备的管理有关,其中一些接口如
enable
实际会还是要依赖
IBluetooth
接口

提供的方法。

BluetoothManager

用于获取BluetoothAdapter的一个实例,以及执行一些全局性的蓝牙管理行为。

获取BluetoothAdapter的方式如下:

public TestActivity extends Activity {

...
private BluetoothManager bluetoothManager = null;
private BluetoothAdapter BluetoothAdapter = null;

protected void onCreate(Bundle savedInstances) {
...
bluetoothManager = this.getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
...
}
...
}


BluetoothAdapter

该类代表本地端的一个蓝牙适配器,提供了一系列操作蓝牙设备的接口,如初始化蓝牙设备,

扫描蓝牙设备以及获取已配对蓝牙设备列表等等操作。除上通过
BluetoothManager
类获取该类的

一个实例引用外,还可以使用该类本身提供的一个静态成员方法获取该类的一个实例引用:

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();


此类的大部分方法都会通过
IBluetoothManager
IBluetooth
操作提供的方法调用到底层。

上述三个类代码位于:frameworks\base\core\java\android\bluetooth目录下。

BluetoothManagerService

此类是接口
IBluetoothManager
的具体实现类,它从
IBluetoothManager.Stub
抽象类中继承而来。

它的大部分方法都通过
IBluetooth
往底层传递,此外,通过它还可以访问
IBluetoothGatt
接口。

该类的代码位于:frameworks\base\services\java\com\android\server目录下。

AdapterServiceBinder

该类实现了
IBluetooth
接口,它从
IBluetooth.Stub
抽象类中继承而来。它是AdapterService的一个私有静态

内部类。为什么要实现为一个静态内部类呢?

实际上,它的一些接口实现最终调用的是它的外部类
AdapterService
的方法,并通过这些方法调用到JNI层。

该类的代码位于:packages\apps\Bluetooth\src\com\android\bluetooth\btservice目录下。

JNI层

在JNI层,一个重要的数据结构是
bt_interface_t
,对应了一个此类型的全局变量,在JNI代码中,可以通过

接口
getBluetoothInterface
来获取该变量的引用。

下面是AdapterService类对应的JNI层的代码,我们看下如何通过HAL来初始化该全局变量。

static void classInitNative(JNIEnv* env, jclass clazz) {
int err;
hw_module_t* module;
...
char value[PROPERTY_VALUE_MAX];
property_get("bluetooth.mock_stack", value, "");

const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);

err = hw_get_module(id, (hw_module_t const**)&module);

if (err == 0) {
hw_device_t* abstraction;
err = module->methods->open(module, id, &abstraction);
if (err == 0) {
bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
sBluetoothInterface = btStack->get_bluetooth_interface();
} else {
ALOGE("Error while opening Bluetooth library");
}
} else {
ALOGE("No Bluetooth Library found");
}
}


从上述代码可以看到,通过HAL的接口,我们得到了bt_interface_t类型的全局变量的引用,并通过该变量,

将上层的一些操作通过HAL层传递到底层。

相关代码位于:packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp

HAL层

基本数据结构定义在如下路径:hardware\libhardware\include\bluetooth.h.

typedef struct {
struct hw_device_t common;
const bt_interface_t* (*get_bluetooth_interface)();
} bluetooth_device_t;

typedef bluetooth_device_t bluetooth_module_t;


可以看到,定义了一个
bluetooth_device_t
的结构体,它提供了一个
get_bluetooth_interface
函数指针。

那实际注册HAL的代码位于如下路径:

external\bluetooth\bluedroid\btif\src\bluetooth.c

HAL层注册了蓝牙协议栈,它作为一个HAL层的“设备”为上层服务,其定义如下:

static struct hw_module_methods_t bt_stack_module_methods = {
.open = open_bluetooth_stack,
};

struct hw_module_t HAL_MODULE_INFO_SYM = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = BT_HARDWARE_MODULE_ID,
.name = "Bluetooth Stack",
.author = "The Android Open Source Project",
.methods = &bt_stack_module_methods
};


在open方法中,初始化了
bluetooth_device_t
结构体成员,特别地,它初始化了
get_bluetooth_interface
,

这样framework层就可以间接通过这个接口来操作蓝牙设备了。

总结

最后,我们再次看一下蓝牙模块功能的调用过程。

获取蓝牙模块的接口

通过
hw_get_module
获取蓝牙模块的接口,并调用它的open标准接口

获得
hw_device_t
的设备指针,再通过其
get_bluetooth_interface
获取

蓝牙接口
bt_interface_t


获取Profile接口

通过
bt_interface_t
接口的方法
get_profile_interface
获取对应Profile的接口指针。

如下是一些初始化过程:

Created with Raphaël 2.1.2AdapterServiceAdapterServicecom_android_bluetooth_btservice_AdapterService.cppcom_android_bluetooth_btservice_AdapterService.cppbt_interface_tbt_interface_tbluetooth.cbluetooth.conCreateinitNativeinitNativeinitinit

Created with Raphaël 2.1.2com_android_bluetooth_btservice_AdapterService.cppcom_android_bluetooth_btservice_AdapterService.cppbluetooth.cbluetooth.cbt_utils.cbt_utils.cbtif_core.cbtif_core.cbtif_config.cbtif_config.cbte_main.cbte_main.cgki_ulinux.cgki_ulinux.cinitbt_utils_initbtif_init_bluetoothbtif_config_initbte_main_boot_entrybtif_fetch_local_bdaddrGKI_create_task
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: