在android4.2中,Google更换了android的蓝牙协议栈,从Bluez换成Bluedroid,我也是初涉这个方面,顺便记录一下。 http://source.android.com/d...

在android4.2中,Google更换了android的蓝牙协议栈,从Bluez换成Bluedroid,我也是初涉这个方面,顺便记录一下。
http://source.android.com/devices/bluetooth.html
android4.2蓝牙结构

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模块并且指定这些组件

转载于:https://www.cnblogs.com/yuzaipiaofei/p/4124113.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
蓝牙协议栈Bluez是Linux系统的官方蓝牙协议栈,它是一个开源项目,从Linux 2.4.6版本开始成为Linux内核的一部分。Bluez协议栈支持蓝牙技术,可以实现多种电子设备之间的短距离无线通信,无需任何线缆和用户手工干涉。它由底层硬件模块、间层和高端应用层三部分组成。Bluez协议栈的功能包括自动同步和建立无线网络,实现设备之间的资源共享。蓝牙Mesh功能在Bluez协议栈的Release 5.47版本开始逐步支持,但目前的最新版本是Release 5.66。需要注意的是,截至目前,蓝牙Mesh的单元测试尚未全部实现。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* [BlueTooth: 蓝牙Bluz协议栈概述](https://blog.csdn.net/Augusdi/article/details/25899123)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [(一)深入理解Bluez协议栈之蓝牙Mesh的支持(1/5)](https://blog.csdn.net/wanguofeng8023/article/details/129213237)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值