Android Bluetooth

来源:互联网 发布:阿里云 ecs 是iaas 编辑:程序博客网 时间:2024/05/17 06:44

The process to connect to bluetooth:

scan -> connect -> discoverService -> get characteristic -> read or write the characteristic


Compared with Bluez, the Bluedroid has several advantages:

1.clear level structure. add HAL level, 

2. remove the DBus. Framework can get the Native code of Bluedroid directly.



These is the source code of bluetooth :


Android.bluetoothframeworks/base/core/java/android/bluetoothimplements public API for the Bluetooth adapter and profilesBluetooth system servicepackages/apps/Bluetooth/srcimplements service and profiles at the Android fraework layerBluetooth JNIpackages/apps/Bluetooth/jnidefines Bluetooth adapter and profiles service JNI: calls into HAL and receives callback from HALBluetooth HALhardware/libhardware/include/hardware/bt_*.h filesdefines the standard interface that the android.bluetooth adapter and  profiles APIsBluetooth stackexternal/bluetooth/bluedroidimplement bluetooth stack: core and profiles

  eg: Pan profie, we can see the destruct  and the class, 

android.bluetoothframeworkspublic class BluetoothPan implements BluetoothProfileBluetooth System Servicepackages/appspublic class PanService extends ProfileServiceBluetooth JNIpackages/appscom_android_bluetooth_pan.cppBluetooth HALhardware/libhardwareinclude/hardware/bt_pan.hBluetooth stackexternal/bluetoothbluedroid/btif/src/btif_pan.c(implements bt_pan.h)  bluedroid/bta/pan (Broadcom BTA)  bluedroid/stack/pan (Broadcom BTE)



AVRCP (Audio/Video Remote Control Profile)has several functions :

control the music play of mobile phone by blue tooth 

display the info of music 

scan the file of music and playlist.


There are several version of AVRCP. 

1.0—Basic remote control commands (play/pause/stop, etc.)

1.3—all of 1.0 plus metadata and media-player state support

The status of the music source (playing, stopped, etc.)

Metadata information on the track itself (artist, track name, etc.).

1.4—all of 1.0 and 1.3 plus media browsing capabilities for multiple media players

Browsing and manipulation of multiple players

Browsing of media metadata per media player, including a "Now Playing" list

Basic search capabilities

1.5—all of 1.0, 1.3 and 1.4 plus specification corrections and clarifications to absolute volume control, browsing and other features



AVRCP has two roles: Controller and Target. Bluetooth is the Controller and the phone is the Target.


These are the new characters of AVRCP 1.4


  • New Scenarios
    • Remote Control from Car Audio System
The controller(CT) is the car audio system and the mobile phone is the target(TG).
The user browsers the available media on the mobile phone via the car interface. The user may then perform actions triggering retrieval of media metadata from the phone, and perform other control operations.
  • New Feature Support
    • Connection establishment for browsing
    • Release connection for browsing
    • Absolute Volume
    • Media Player Selection
      • Supports Multiple Players
    • Browsing
      • Database Aware Players
    • Search
    • Now Playing
      • Playable Folders
  • Sections related New Features
    • 4.1.6 Procedure of AVRCP Browsing commands
    • 4.4.1 PASS THROUGH Command
    • 6.3.2 AVRCP Specific Browsing Commands
    • 6.7.2 RegisterNofitcation
      • Volume Changed 6.13.3
    • 6.9 Media Player Selection
      • SetAdressedPlayer
      • Addressed Player Changed Notification
      • SetBrowsedPlayer
      • Available Players Changed Notification
      • Notify Now Playing Content Changed
    • 6.10 Media Content Navigation
      • Scope: Media Player List, Media Player Virtual Filesystem, Search results, Now Playing
      • Browsable Items
      • UIDs
        • Database Unaware/Aware Players (Without/With UID change detection)
        • UIDs Changed Notification
      • Browsing Commands
    • 6.11 Search
    • 6.12 Item Operations
      • Play item by UID
      • Add-To Now Playing
    • 6.13 Volume Handling
      • SetAbsoluteVomume
      • Notify volume change
    • 6.15.2 Error handling for Breowsing Commands
    • 8 Service Discovery Interoperability Requirements
    • 9 L2CAP Interoperability Requirements
      • Retransmission and Flow Control
      • Configuration of the Browsing Channel
    • 25 List of defined notification events
    • 28 UID scheme

Enable Bluetooth.

Bluetooth Adapter means the local device Bluetooth adapter while BluetoothDevice means the remote Bluetooth device. And BluetoothManager is one high level manager, and be used to obtain an instance of an BluetootheAdapter and conduct overall Bluetooth Management.

The switch of Bluetooth will enable the Bluetooth of your phone.



会一层层从Bluedroid上传到UI层,Settings收到这个消息就可以更新Bluetooth开关的状态了。具体过程如下图:

  1. Settings' BluetoothEnabler class(the switch of bluetooth),get the presentation --BluetoothAdapter of local device,then get BluetoothAdapter::enable()。
  2. BluetoothAdapter is just one wrapper, it won't do anything。It will get  BluetoothManagerService::enable() directly。
  3. BluetoothManagerService use Binder to connect AdapterService,and eventually ,AdapterService::enable() been get 。BluetoothManagerService will also get AdapterService to enroll callback function,to get the message of Adapter State Change。
  4. AdapterService maintain one State Mechine -AdapterState,all the work is completed by the DriverFSM(Finite State Machine). AdapterState get the info of USER_TURN_ON from AdapterService, will run AdapterService::processStart() to  init Profie Services and Bluetooth hardware enable process. While the state of Bluetooth Adapter is BluetoothAdapter.STATE_TURNING_ON
  5. Every profile has one service. and after every profile service init, the AdapterService will be informed. When AdapterService::processProfileServiceStateChanged()  conform all profile services start, it will sendAdapterState.STARTE to AdapterState.
  6. The  AdapterState::PendingCommandState::processMessage() inFSM gets the info of AdapterState.STARTED will run AdapterService::enableNative() immediately。
  7. AdapterService::enableNative() is to enable the interface of Bluetooth JNI  to Bluetooth. enableNative() will run the enable() of Bluetooth HAL.
  8. Bluedroid use btif_enable_bluetooth()to achieve the enable() of Bluetooth HAL.
  9. When Bluedroid complete the enable Bluetooth hardware,will get the HAL_CBACK from btif_enable_bluetooth_evt() to run Bluetooth JNI's adapter_state_change_callback(),So the FSM will get the info of BT_STATE_ON.
  10. AdapterState will change the state of Bluetooth Adapter to BluetoothAdapter.STATE_ON, let the AdapterState::notifyAdapterStateChanged() to inform the AdapterService.
  11. AdapterService::updateAdapterState()will inform the BluetoothManagerService by callback that the state of  Adapter is changed.
  12. BluetoothManagerService get the conform of the changed the state will send one intent of BluetoothAdapter.ACTION_STATE_CHANGE.
  13. After the Settings' BluetoothEnabler gets the intent, the state of the Bluetooth switch will be updated.


Android Bluetooth Stack: Bluedroid: Scan remote devices.
The start scan process. The localBluetootheAdapter is one class in Settings. the define of BluetoothAdapter is in Framework. The realize of AdapterService is in package/apps/Bluetooth. startDiscoveryNative() is one interface of JNI. After start_discovery(), the process enters the Bluedroid part. start_discovery() is actually one interface of Bluetooth HAL. 



 After scan, the Bluedroid will info Android Framework: BT_DISCOVERY_STARTED by the discovery_state_change_callback in  callback() of Bluetooth HAL. and by the device_found_callback function, the Android Framework will get the Bluetooth device. The last step, discovery_state_change_callback will info Android Framework:BT_DISCOVERY_STOPPED.

The picture shows the process of Disccovery state changed.The key is callback in Bluetooth HAL, and it will pass the Discovery state from lower level Bluetooth stack  to Android Framework. 

Then AdapterProperties::discoveryStateChangeCallback() will run new intent, and the broadcast it out. Settings will get this intent by BluetoothDiscoveryReceiver. 


The picture below show the process to find the Bluetooth device of Bluedroid.  The device found  callback() will run after finding each one device.  Before device_found_callback() runs JniCallbacks::deviceFoundCallback(), it will register by JniCallbacks::devicePropertyChangedCallback() to find one Bluetooth device. RemoteDevice has one HashMap<BluetoothDevice, DeviceProperties> mDevices to store the results of Bluetooth devices which is found.



In total, Every call between Android Framework and Bluedroid will pass the Bluetooth HAL. It defines in the hardware/libhardware/include/hardware/bluetooth.h. In external/bluetooth/bluedroid/btif realized the interface (in bt_interface_t) of standard Bluetooth DM(Device Management). packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp realized the Bluetooth DM callback structure: bt_callbacks_t.So the HAL separates the Android Framework an Bluetooth stack.  Bluetooth stack just needs to realize the interface of Bluetooth HAL, an then the Android Framework can use it. So , after Android 4.2, we can use other Bluetooth stack to instead of Bluedroid. In fact, The BlueZ is developing Android Bluetooth HAL implementation, so we can use it in Android 4.2. By the way, the stable of BlueZ is better than Bluedroid. 

You can find information of BlueZ here:

http://git.kernel.org/cgit/bluetooth/bluez.git/tree/android/README


5. A2DP Introduction

The Advanced Audio Distribution Profile (A2DP) defines the protocols and procedures that realize distribution of audio content of high-quality in mono or stereo on ACL channels. As indicated in the diagram of 'Protocol Model', A2DP depends on AVDTP and SDP. 


Protocol Model

The AVDTP define procedures required to set up an audio streaming. The A2DP defines parameters and procedures that are specific foraudio streaming, including audio codec, SDP parameters. It's the pre-condition of analyzing A2DP Source implementation to familiar with the two specs: AVDTP and A2DP. The block diagrams of sending/receiving audio streaming and created packet format are shown in the diagram below. In the analysis, I only focus on MP and Media PL. AVDTP spec describes MP, while A2DP spec describes Media PL. This profile support a mandatory codec: SBC, 3 optional codecs: MPEG-1,2 Audio, MPEG-2,4 AAC and ATRAC family, and the vendor specific A2DP codecs, eg. aptX. I will only talk about the mandatory codec: SBC in the article.


Block diagram of Audio Streaming Procedures and the Packet Format

The following roles are defined for devices that implement A2DP:

Source(SRC) – A device is the SRC when it acts as a source of a digital audio stream
that is delivered to the SNK of the piconet, eg. a smartphone which sends audio stream.
Sink (SNK) – A device is the SNK when it acts as a sink of a digital audio stream
delivered from the SRC on the same piconet, eg. a Bluetooth headset which receives audio stream.

In Bluedroid, only the source role is implemented, so I analysis the implementation of A2DP source in Bluedroid.(But both of source and sink are implemented in Bluez)

2. Code Analysis

I will not list very detailed function callings(The best way to understand the code is reading the code by yourself), while just describe the process. So you will not read a lot of the boring source code.

2.1 Files Structure

I list the important files for A2DP from the upper layer to lower layger.

  • btif/src/btif_av.c                     Bluedroid AV HAL implementation which implements the interface defined in AOSP/hardware/bt_av.h.
  • btif/src/btif_media_task.c    This is the multimedia module for the BTIF system. It contains task implementations AV, HS and HF profiles' audio&video processing.
  • btif/co/bta_av_co.c               This is the advanced audio/video call-out function implementation for BTIF.
  • bta/av/bta_av_ci.c                This is the implementation for advanced audio/video call-in functions which are called from BTIF.
  • bta/av/bta_av_api.c             This is the implementation of the API for the advanced audio/video(AV) subsystem of BTA. This interface is called from btif_av.c.
  • bta/av/bta_av_mian.c          This is the main implementation file for BTA advanced audio/video.
  • bta/av/bta_av_ssm.c            This is the stream state machine for the BTA advanced audio/video.
  • bta/av/bta_av_aact.c            This file contains action functions for advanced audio/video stream.
  • bta/av/bta_av_sbc.c             This module contains utility functions for dealing with SBC data frames and codec capabilities.
  • stack/a2dp/a2d_api.c           This is the implementation of the API for the Advanced Audio Distribution Profile(A2DP)
  • stack/a2dp/a2d_sbc.c          This file contains utility functions to help build and parse SBC codec information element and media payload.
  • embdrv/sbc/sbc/encoder     This folder contains the files which implement SBC decoder.

2.2 Transfer Audio data to AVDTP via A2DP

The transferring process is handle with 'btif_media_task' which is A2DP media task for SBC encoder. The task is created when Bluetooth is enabled(see btif_enable_bluetooth_evt() in btif/src/btif_core.c). A timer drives the task to encoder and transfer audio stream. The timer is started in btif_media_task_aa_start_tx() when the 'audio_stream_out'  interface has a PCM data buffer ready to write(see hardware/libhardware/include/hardware/audio.h).  On receiving the timer event, the task handles all ready PCM data buffers. If stream is started, run the SBC encoder on each chunk of PCM samples and build an output packet consisting of one or more encoded SBC frames. 


The diagram is the flowchart of transferring audio data to AVDTP. The blue blocks are in 'btif', the red blocks are in 'bta/av', and the yellow blocks are in 'stack/avdt'.

  1. BTIF reads PCM data from audio flinger via Audio HAL.(Step 6)
  2. BTIF calls SBC encoder to encode PCM data to SBC frames which are put in a queue.(Step 7 and 8)
  3. BTIF notifies BTA that the source data is ready in the queue.(Step 9~13)
  4. BTA gets the SBC frames from the queue, then adds SBC Header. Media PL is constructed now.(Step 15~17)
  5. BTA writes Media PL to AVDTP.(Step 18)
  6. AVDTP adds Media Packet Header.(Step 19)

2.3 Implement Audio HAL for A2DP audio device

audio_stream_out  in Audio HAL defines the abstract interface for the audio output hardware. It provides information about various properties of the audio output hardware driver. We must implement audio_stream_out for A2DP audio device to output the audio from Audio Flinger to Bluetooth stack. The interface is defined in AOSP/hardware/libhardware/audio.h. Bluedroid implements the interface in AOSP/external/bluetooth/bluedroid/audio_a2dp_hw.

socket is used for IPC between Audio HAL and BTIF.  Two sockets are defined in audio_a2dp_hw.h:

#define A2DP_CTRL_PATH "/data/misc/bluedroid/.a2dp_ctrl"
#define A2DP_DATA_PATH "/data/misc/bluedroid/.a2dp_data"

A2DP_CTRL_PATH is a command socket, while A2DP_DATA_PATH is a data socket. BTIF defines two channels which are mapped to the two sockets in UIPC_Open() in udrv/ulinux/uipc.c. The channel IDs are UIPC_CH_ID_AV_CTRL and UIPC_CH_ID_AV_AUDIO. Setp 6 in the flowchart reads the PCM data from Audio HAL to BTIF with the channel ID: UIPC_CH_ID_AV_AUDIO.

3 Summary

Bluedroid in AOSP does not support all the features of A2DP. Source role is implemented, but Sink role is not implemented(Bluez implements both of them). SBC is supported in Bluedroid, while other codecs are not supported. The vendor can not add a new codec plugin easily, we have to modify the code in Bluedroid. And there are many small bugs in Bluedroid. So the improvements are needed for Bluedroid.

reference by :

http://blog.csdn.net/wendell_gong/article/details/29841967

0 0
原创粉丝点击