温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Bluedroid的结构和代码分布是怎样的

发布时间:2021-10-14 14:19:48 来源:亿速云 阅读:196 作者:柒染 栏目:编程语言

本篇文章给大家分享的是有关Bluedroid的结构和代码分布是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

android development对于4.3蓝牙的介绍:

android提供BlueDroid作为默认的协议栈,BlueDroid分为两个部分:

1、Bluetooth Embedded System(BTE),它实现了BT的核心功能。

2、Bluetooth Application Layer (BTA),用于和android framework层交互。

BT 系统服务通过JNI与BT stack交互,并且通过Binder IPC通信与应用交互。这个系统服务同时也提供给RD获取不同的BT profiles;下面的图标展示BT stack的一个大体的结构:

一、application Framework

这个层的代码主要是利用android.bluetooth APIS 和 bluetooth hardware进行交互。 也就是通过Binder IPC机制调用bluetooth 进程;

代码位于framework/base/core/java/android.bluetooth/下。

比如A2DP的连接:framework/base/core/java/android.bluetooth/BluetoothA2dp.java中的connect(Bluetoothevice)方法。

 1  2  3  4  5  6  7  8  9 10 11 12 13 14
public boolean connect(BluetoothDevice device) {     if (DBG) log("connect(" + device + ")");     if (mService != null && isEnabled() &&         isValidDevice(device)) {         try {             return mService.connect(device);         } catch (RemoteException e) {             Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));             return false;         }     }     if (mService == null) Log.w(TAG, "Proxy not attached to service");     return false; }

通过Binder IPC 通信机制,调用到packages/apps/Bluetooth/src/com.android.bluetooth.a2dp/A2dpService.java下一个内部私有类

A2dpService是一个继承于ProfileService,而ProfileService是继承于Service的。

private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub{}的connect(BluetoothDevice)方法。

1 2 3 4 5
public boolean connect(BluetoothDevice device) {         A2dpService service = getService();         if (service == null) return false;         return service.connect(device);     }

然后调用到A2dpService的connect(BluetoothDevice)方法。

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17
public boolean connect(BluetoothDevice device) {     enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,                                    "Need BLUETOOTH ADMIN permission");     if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) {         return false;     }     int connectionState = mStateMachine.getConnectionState(device);     if (connectionState == BluetoothProfile.STATE_CONNECTED ||         connectionState == BluetoothProfile.STATE_CONNECTING) {         return false;     }     mStateMachine.sendMessage(A2dpStateMachine.CONNECT, device);     return true; }

这个过程就是Bluetooth Application Framework与Bluetooth Process的调用过程。

二、Bluetooth System service

Bluetooth System service位于packages/apps/Bluetooth下,它打包成一个android app包,并且在android framework 层实现BT service

和各种profile。BT app会通过JNI调用到HAL层。

A2dpService的connect方法会发送一个StateMachine.sendMessage(A2dpStateMachine.CONNECT, device)的message,这个message会被A2dpStateMachine对象的processMessage(Message)方法接收到:

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
case CONNECT:                 BluetoothDevice device = (BluetoothDevice) message.obj;                 broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,                                BluetoothProfile.STATE_DISCONNECTED);                 if (!connectA2dpNative(getByteAddress(device)) ) {                     broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,                                    BluetoothProfile.STATE_CONNECTING);                     break;                 }                 synchronized (A2dpStateMachine.this) {                     mTargetDevice = device;                     transitionTo(mPending);                 }                 // TODO(BT) remove CONNECT_TIMEOUT when the stack                 //          sends back events consistently                 sendMessageDelayed(CONNECT_TIMEOUT, 30000);                 break;

最重要的一句:connectA2dpNative(getByteAddress(device);

即会通过JNI调用到Native;

private native boolean connectA2dpNative(byte[] address);

三、JNI

与android.bluetooth有关的JNI代码位于packages/apps/bluetooth/jni下,JNI 的代码会调用到HAL层,并且在确信一些BT操作被触发时,会从HAL

获取一些回调。比如当BT设备被发现时。

再回到A2dp连接的例子中来,BT System Service通过JNI会调用到com_android_bluetooth_a2dp.cpp中:

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21
static jboolean connectA2dpNative(JNIEnv *env, jobject object, jbyteArray address) { jbyte *addr; bt_bdaddr_t * btAddr; bt_status_t status; ALOGI("%s: sBluetoothA2dpInterface: %p", __FUNCTION__, sBluetoothA2dpInterface); if (!sBluetoothA2dpInterface) return JNI_FALSE; addr = env->GetByteArrayElements(address, NULL); btAddr = (bt_bdaddr_t *) addr; if (!addr) {     jniThrowIOException(env, EINVAL);     return JNI_FALSE; } if ((status = sBluetoothA2dpInterface->connect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {     ALOGE("Failed HF connection, status: %d", status); }     env->ReleaseByteArrayElements(address, addr, 0);     return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; }

重点代码是:status = sBluetoothA2dpInterface->connect((bt_bdaddr_t *)addr);

这个sBluetoothA2dpInterface结构体对象是在initNative(JNIEnv *env, jobject object)方法时得到的。

1 2 3 4 5
if ( (sBluetoothA2dpInterface = (btav_interface_t *)       btInf->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID)) == NULL) {     ALOGE("Failed to get Bluetooth A2DP Interface");     return; }

四、HAL

硬件抽象层定义android.bluetooth APIs和BT process调用的标准接口,并且你必须实现这些接口来让你的BT hardware功能运行正常。BT HAL的

的头文件位于hardware/libhardware/include/hardware/bluetooth.h和hardware/libhardware/include/hardware/bt_*.h 文件中。

JNI中sBluetoothA2dpInterface是一个btav_interface_t结构体,位于hardware/libhardware/include/hardware/bt_av.h中,定义为:

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
typedef struct {          size_t          size;          bt_status_t (*init)( btav_callbacks_t* callbacks );          bt_status_t (*connect)( bt_bdaddr_t *bd_addr );          bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr );          void  (*cleanup)( void ); } btav_interface_t;

五、BT stack

作为默认的BT stack,(4.2之前是bluez作为协议栈的)

代码位于external/bluetooth/bluedroid下,这个stack实现了通用的BT HAL并且也可以通过扩展和改变配置来自定义。

A2dp的连接会调用到external/bluetooth/bluedroid/btif/src/btif_av.c的connect方法。

1 2 3 4 5 6 7
static bt_status_t connect(bt_bdaddr_t *bd_addr) {     BTIF_TRACE_EVENT1("%s", __FUNCTION__);     CHECK_BTAV_INIT();     return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int); }

六、Vendor extension

为了追踪添加自定义拓展和一个HCI层,你可以创建一个libbt-vendor模块并且指定这些组件。

以上就是Bluedroid的结构和代码分布是怎样的,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI