蓝牙之六-A2dp代码调用流程

来源:互联网 发布:查找淘宝用户购买记录 编辑:程序博客网 时间:2024/05/19 12:28

这里写图片描述 
上图描述的是蓝牙协议栈,通过该图,查看A2dp的代码在协议栈的调用流程。其分层架构如下: 
这里写图片描述 
1.蓝牙的系统服务service通过JNI与bluedroid协议栈进行通信。协议栈分为两层,Bluetooth Embedded System(BTE)和Bluetooth Application Layer(BTA)。这两层和framework层应用进行通信。 
2.蓝牙服务通过Binder IPC通信与应用程序交互。 
3.系统服务给开发者提供了获取各种profile的接口。

Application framework

该层使用android.bluetooth APIs和Bluetooth hardware进行通信。通过Binder IPC机制和Bluetooth进程进行通信。该层代码位于frameworks/base/core/java/android/bluetooth/目录下。 
如A2DP连接frameworks/base/core/java/android/bluetooth/BluetoothA2dp.java

    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;    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

该方法通过Binder IPC通信机制,调用packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java下的内部私有类。通过aidl机制实现。

<packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java>private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub {        public boolean connect(BluetoothDevice device) {            A2dpService service = getService();            if (service == null) return false;            return service.connect(device);        }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

然后调用到A2dpService的connect的方法。

<packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java>public class A2dpService extends ProfileService {        ...        public boolean connect(BluetoothDevice device) {        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,                                       "Need BLUETOOTH ADMIN permission");        if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) {            return false;        }        ParcelUuid[] featureUuids = device.getUuids();        if ((BluetoothUuid.containsAnyUuid(featureUuids, A2DP_SOURCE_UUID)) &&            !(BluetoothUuid.containsAllUuids(featureUuids ,A2DP_SOURCE_SINK_UUIDS))) {            Log.e(TAG,"Remote does not have A2dp Sink UUID");            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;    }    ....        private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub {            public boolean connect(BluetoothDevice device) {                A2dpService service = getService();                if (service == null) return false;                return service.connect(device);           }       }  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

上述过程就是Bluetooth application framework与Bluetooth process的调用过程。

Bluetooth System service

这部分代码位于packages/apps/Bluetooth下,在framework层实现蓝牙服务和各种profile,以apps形式存在。该层通过JNI调用HAL层代码。 
A2dpService的connect方法会发送状态机改变消息, 
mStateMachine.sendMessage(A2dpStateMachine.CONNECT, device); 
这个消息会被A2dpStateMachine对象的processMessage(Message)方法接收:

            switch(message.what) {                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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

上述的connectA2dpNative(getByteAddress(device))会通过JNI调用Native方法。

<packages/apps/Bluetooth/jni/com_android_bluetooth_a2dp.cpp>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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

JNI

和JNI相关的代码在package/apps/Bluetooth/jni目录下,上一节的connectA2dpNative方法就是这个目录的代码。JNI层代码调用到HAL代码并且从HAL接收到回调。 
A2dp连接中,会调用sBluetoothA2dpInterface->connect实现。

<packages/apps/Bluetooth/jni/com_android_bluetooth_a2dp.cpp>static void initNative(JNIEnv *env, jobject object) {    const bt_interface_t* btInf;    bt_status_t status;...    if ( (sBluetoothA2dpInterface = (btav_interface_t *)          btInf->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID)) == NULL) {        ALOGE("Failed to get Bluetooth A2DP Interface");        return;    }    if ( (status = sBluetoothA2dpInterface->init(&sBluetoothA2dpCallbacks)) != BT_STATUS_SUCCESS) {        ALOGE("Failed to initialize Bluetooth A2DP, status: %d", status);        sBluetoothA2dpInterface = NULL;        return;    }    mCallbacksObj = env->NewGlobalRef(object);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在initNative中获得sBluetoothA2dpInterface对象。

HAL

硬件抽象层定义了android.bluetooth APIs和Bluetooth process调用的接口。Bluetooth 的HAL层代码在: 
hardware/libhardware/include/hardware/bluetooth.h,HAL层的以下代码也要重视:

hardware/libhardware/include/hardware/bt_common_types.h  //A2DP profile定义hardware/libhardware/include/hardware/bt_av.h   //GATT profile 定义         hardware/libhardware/include/hardware/bt_gatt_types.h  hardware/libhardware/include/hardware/bt_gatt_client.h hardware/libhardware/include/hardware/bt_gatt_server.h hardware/libhardware/include/hardware/bt_gatt.h  //HFP profile定义hardware/libhardware/include/hardware/bt_hf.h  //HDP profile 定义hardware/libhardware/include/hardware/bt_hl.h //MAP profilehardware/libhardware/include/hardware/bt_mce.h//HFP client profilehardware/libhardware/include/hardware/bt_hf_client.h //pan profile  hardware/libhardware/include/hardware/bt_pan.h//AVRCP profile     hardware/libhardware/include/hardware/bt_rc.h     hardware/libhardware/include/hardware/bt_hh.h //SDP profile         hardware/libhardware/include/hardware/bt_sdp.h//RFCOMM sockets         hardware/libhardware/include/hardware/bt_sock.h
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

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

typedef struct {    /** set to sizeof(btav_interface_t) */    size_t          size;    /**     * Register the BtAv callbacks     */    bt_status_t (*init)( btav_callbacks_t* callbacks );    /** connect to headset */    bt_status_t (*connect)( bt_bdaddr_t *bd_addr );    /** dis-connect from headset */    bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr );    /** Closes the interface. */    void  (*cleanup)( void );} btav_interface_t;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

BT stack

协议栈在/system/bt下,实现了HAL层和扩展配置等。包括BTA和BTE量大组件,BTA实现了蓝牙设备管理、状态管理及一些应用规范。而BTE则通过HCI与厂商蓝牙芯片交互以实现了蓝牙协议栈的通用功能和相关协议。另外,BTE还包括一个统一内核接口(GKI),蓝牙芯片厂商可借助GKI快速轻松得移植蓝牙协议栈到其他操作系统或手机平台上。 
A2dp的连接将调用

<system/bt/btif/src/btif_av.c>static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid){    btif_av_connect_req_t connect_req;    connect_req.target_bda = bd_addr;    connect_req.uuid = uuid;    BTIF_TRACE_EVENT("%s", __FUNCTION__);    btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);    return BT_STATUS_SUCCESS;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Vendor extensions

增加自定义扩展或者HCI层追踪,可以创建libbt-vendor模块并指定这些组件。


原创粉丝点击