Android4.4 Bluetooth enble
阅读原文时间:2021年04月25日阅读:1

Android Bluetooth

Android 4.4上蓝牙协议栈采用的是BRCM和Google共同开发的bluedroid,代替了之前的Bluez.

一、 Bluetooth 源码分布 (基于Android 4.4 )

1.  packages/apps/Settings/src/com/android/settings/bluetooth

 bluetooth Settings 代码

2.  packages/apps/Bluetooth

     BT 应用层代码,及BT profile(如:A2dp,gatt,hdp,hfp,hid,map,opp,pan,pbap …) 上层代码

      packages/apps/Bluetooth/jni

3.  frameworks/base/core/java/android/bluetooth

     framework 层相关 java 代码与aidl

4.  external/bluetooth/bluedroid      

     BRCM和Google共同开发的 官方蓝牙协议栈

5.  linux/kernel/drivers/bluetooth

6.  linux/kernel/net/bluetooth

7. 以下是近期项目intel 平台

hardware/broadcom/libbt

hardware/libhardware

vendor/intel/fw/PRIVATE/bt    厂商bt固件

二、Bluetooth 常用类及相关profile

A2dp :  Advanced Audio Distribution Profile 蓝牙 音频传输模型协定

  蓝牙立体声,和蓝牙耳机听歌有关那些,另还有个AVRCP--( Audio/Video Remote Control Profile) 音频/视频远程控制配置文件, 是用来听歌时暂停,上下歌曲选择的

GATT:  Generic Attribute Profile   通用属性配置文件

        GATT是基于ATT Protocol的, ATT针对BLE设备做了专门的优化,具体就是在传输过程中使用尽量少的数据。每个属性都有一个唯一的UUID,属性将以characteristics and services的形式传输

       https://developer.bluetooth.org/TechnologyOverview/Pages/GATT.aspx

HDP : Bluetooth Health Device Profile 蓝牙关于医疗方面的应用 

HFP : Hands-free Profile   和电话相关,蓝牙接听、挂断电话 

HID :  Human Interface Device  

         定义了蓝牙在人机接口设备中的协议、特征和使用规程。典型的应用包括蓝牙鼠标、蓝牙键盘、蓝牙游戏手柄等。该协议改编自USB HID Protocol

MAP :  Message Access Profile

OPP : Object Push Profile

PAN : Personal Area Network Profile

描述了两个或更多个 Bluetooth 设备如何构成一个即时网络,和网络有关的还有串行端口功能(SPP),拨号网络功能(DUN)

PBAP : Phonebook Access Profile  电话号码簿访问协议 

三、Enable Bluetooth

1. 服务启动:

frameworks/base/services/java/com/android/server/SystemServer.java

系统启动时在SystemServer中注册蓝牙服务管理BluetoothManagerService服务:  

1 // Skip Bluetooth if we have an emulator kernel 2 // TODO: Use a more reliable check to see if this product should 3 // support Bluetooth - see bug 988521
4 if (SystemProperties.get("ro.kernel.qemu").equals("1")) {
5 Slog.i(TAG, "No Bluetooh Service (emulator)");
6 } else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7 Slog.i(TAG, "No Bluetooth Service (factory test)");
8 } else if (!context.getPackageManager().hasSystemFeature
9 (PackageManager.FEATURE_BLUETOOTH)) { 10 Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)"); 11 } else if (disableBluetooth) { 12 Slog.i(TAG, "Bluetooth Service disabled by config"); 13 } else { 14 Slog.i(TAG, "Bluetooth Manager Service"); 15 bluetooth = new BluetoothManagerService(context); 16 ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth); 17 }

Bt 服务

  其它进程通过binder机制调用该服务,该服务属于综合服务管理类,包括AdapterService的启动、蓝牙适配器Adapter的管理等。

 2.   BluetoothAdapter 

Android的蓝牙Enable是由BluetoothAdapter提供的。只需要调用BluetoothAdapter.enable()即可启动蓝牙。下面我就分析这一个过程

 frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java

 1     /**
 2      * Turn on the local Bluetooth adapter—do not use without explicit
 3      * user action to turn on Bluetooth.
 4      * <p>This powers on the underlying Bluetooth hardware, and starts all
 5      * Bluetooth system services.
 6      * <p class="caution"><strong>Bluetooth should never be enabled without
 7      * direct user consent</strong>. If you want to turn on Bluetooth in order
 8      * to create a wireless connection, you should use the {@link
 9      * #ACTION_REQUEST_ENABLE} Intent, which will raise a dialog that requests
10      * user permission to turn on Bluetooth. The {@link #enable()} method is
11      * provided only for applications that include a user interface for changing
12      * system settings, such as a "power manager" app.</p>
13      * <p>This is an asynchronous call: it will return immediately, and
14      * clients should listen for {@link #ACTION_STATE_CHANGED}
15      * to be notified of subsequent adapter state changes. If this call returns
16      * true, then the adapter state will immediately transition from {@link
17      * #STATE_OFF} to {@link #STATE_TURNING_ON}, and some time
18      * later transition to either {@link #STATE_OFF} or {@link
19      * #STATE_ON}. If this call returns false then there was an
20      * immediate problem that will prevent the adapter from being turned on -
21      * such as Airplane mode, or the adapter is already turned on.
22      * <p>Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
23      * permission
24      *
25      * @return true to indicate adapter startup has begun, or false on
26      *         immediate error
27      */
28     public boolean enable() {
29         if (isEnabled() == true){
30             if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");
31             return true;
32         }
33         try {
34             return mManagerService.enable(); // 
35         } catch (RemoteException e) {Log.e(TAG, "", e);}
36         return false;
37     }

mManagerService.enable()

mManagerService其实就是bluetoothAdapter的一个proxy,  

 1     /**
 2      * Get a handle to the default local Bluetooth adapter.
 3      * <p>Currently Android only supports one Bluetooth adapter, but the API
 4      * could be extended to support more. This will always return the default
 5      * adapter.
 6      * @return the default local adapter, or null if Bluetooth is not supported
 7      *         on this hardware platform
 8      */
 9     public static synchronized BluetoothAdapter getDefaultAdapter() {
10         if (sAdapter == null) {
11             IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
12             if (b != null) {
13                 IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
14                 sAdapter = new BluetoothAdapter(managerService);
15             } else {
16                 Log.e(TAG, "Bluetooth binder is null");
17             }
18         }
19         return sAdapter;
20     }

getDefaultAdapter

 1     /**
 2      * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance.
 3      */
 4     BluetoothAdapter(IBluetoothManager managerService) {
 5 
 6         if (managerService == null) {
 7             throw new IllegalArgumentException("bluetooth manager service is null");
 8         }
 9         try {
10             mService = managerService.registerAdapter(mManagerCallback);
11         } catch (RemoteException e) {Log.e(TAG, "", e);}
12         mManagerService = managerService;
13         mLeScanClients = new HashMap<LeScanCallback, GattCallbackWrapper>();
14     }

BluetoothAdapter

 3.  BluetoothManagerService

frameworks/base/services/java/com/android/server/BluetoothManagerService.java

 1     public boolean enable() {
 2         if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
 3             (!checkIfCallerIsForegroundUser())) {
 4             Log.w(TAG,"enable(): not allowed for non-active and non system user");
 5             return false;
 6         }
 7 
 8         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
 9                                                 "Need BLUETOOTH ADMIN permission");
10         if (DBG) {
11             Log.d(TAG,"enable():  mBluetooth =" + mBluetooth +
12                     " mBinding = " + mBinding);
13         }
14 
15         synchronized(mReceiver) {
16             mQuietEnableExternal = false;
17             mEnableExternal = true;
18             // waive WRITE_SECURE_SETTINGS permission check
19             long callingIdentity = Binder.clearCallingIdentity();
20             persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
21             Binder.restoreCallingIdentity(callingIdentity);
22             sendEnableMsg(false);
23         }
24         return true;
25     }

BluetoothManagerService:enable()

1     private void sendEnableMsg(boolean quietMode) {
2         mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
3                              quietMode ? 1 : 0, 0));
4     }

sendEnableMsg

sendEnableMsg 交给handleMessage 处理,可以看到case MESSAGE_ENABLE: 里调用了handleEnable

 1     private void handleEnable(boolean quietMode) {
 2         mQuietEnable = quietMode;
 3 
 4         synchronized(mConnection) {
 5             if ((mBluetooth == null) && (!mBinding)) {
 6                 //Start bind timeout and bind
 7                 Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
 8                 mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
 9                 mConnection.setGetNameAddressOnly(false);
10                 Intent i = new Intent(IBluetooth.class.getName());
11                 if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {
12                     mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
13                 } else {
14                     mBinding = true;
15                 }
16             } else if (mBluetooth != null) {
17                 if (mConnection.isGetNameAddressOnly()) {
18                     // if GetNameAddressOnly is set, we can clear this flag,
19                     // so the service won't be unbind
20                     // after name and address are saved
21                     mConnection.setGetNameAddressOnly(false);
22                     //Register callback object
23                     try {
24                         mBluetooth.registerCallback(mBluetoothCallback);
25                     } catch (RemoteException re) {
26                         Log.e(TAG, "Unable to register BluetoothCallback",re);
27                     }
28                     //Inform BluetoothAdapter instances that service is up
29                     sendBluetoothServiceUpCallback();
30                 }
31 
32                 //Enable bluetooth
33                 try {
34                     if (!mQuietEnable) {
35                         if(!mBluetooth.enable()) {
36                             Log.e(TAG,"IBluetooth.enable() returned false");
37                         }
38                     }
39                     else {
40                         if(!mBluetooth.enableNoAutoConnect()) {
41                             Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
42                         }
43                     }
44                 } catch (RemoteException e) {
45                     Log.e(TAG,"Unable to call enable()",e);
46                 }
47             }
48 
49             // Inform AudioRouteManager that bluetooth is enabled
50             mAudioManager.setParameters(AUDIO_PARAMETER_KEY_BLUETOOTH_STATE + "=true");
51         }
52     }

handleEnable

可以看到是调用了 mBluetooth.enable()

 4. AdapterService,AdapterState

packages/app/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

 1      public synchronized boolean enable(boolean quietMode) {
 2          enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
 3                                         "Need BLUETOOTH ADMIN permission");
 4          if (DBG)debugLog("Enable called with quiet mode status =  " + mQuietmode);
 5          mQuietmode  = quietMode;
 6          Message m =
 7                  mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON);
 8          mAdapterStateMachine.sendMessage(m);
 9          return true;
10      }

AdapterService:enable()

此处用了 用了StateMachine,它会在AdapterState 里processMessage 处理(StateMachine就是状态机,在不同的状态下,收到相同的Event,做不同的事情),直接搜索UER_TURN_ON 可以看到下面:

 1     private class OffState extends State {
 2         @Override
 3         public void enter() {
 4             infoLog("Entering OffState");
 5         }
 6 
 7         @Override
 8         public boolean processMessage(Message msg) {
 9             AdapterService adapterService = mAdapterService;
10             if (adapterService == null) {
11                 Log.e(TAG,"receive message at OffState after cleanup:" +
12                           msg.what);
13                 return false;
14             }
15             switch(msg.what) {
16                case USER_TURN_ON:
17                    if (DBG) Log.d(TAG,"CURRENT_STATE=OFF, MESSAGE = USER_TURN_ON");
18                    sendCrashToolInfo("ON");
19                    notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_ON);
20                    mPendingCommandState.setTurningOn(true);
21                    transitionTo(mPendingCommandState);
22                    sendMessageDelayed(START_TIMEOUT, START_TIMEOUT_DELAY);
23                    adapterService.processStart();
24                    break;
25                case USER_TURN_OFF:
26                    if (DBG) Log.d(TAG,"CURRENT_STATE=OFF, MESSAGE = USER_TURN_OFF");
27                    sendCrashToolInfo("OFF");
28                    //TODO: Handle case of service started and stopped without enable
29                    break;
30                default:
31                    if (DBG) Log.d(TAG,"ERROR: UNEXPECTED MESSAGE: CURRENT_STATE=OFF, MESSAGE = " + msg.what );
32                    return false;
33             }
34             return true;
35         }
36     }

USER_TURN_ON

接下来是调用了adapterService.processStart()

1 void processStart() { 2 if (DBG) debugLog("processStart()");
3 Class[] supportedProfileServices = Config.getSupportedProfiles(); 4 //Initialize data objects
5 for (int i=0; i < supportedProfileServices.length;i++) { 6 mProfileServicesState.put(supportedProfileServices[i].getName(),BluetoothAdapter.STATE_OFF); 7 } 8 mRemoteDevices = new RemoteDevices(this); 9 mAdapterProperties.init(mRemoteDevices); 10 11 if(mBondStateMachine != null) //Avoid resource leakage 12 { 13 mBondStateMachine.doQuit(); 14 mBondStateMachine.cleanup(); 15 } 16 17 if (DBG) {debugLog("processStart(): Make Bond State Machine");} 18 mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices); 19 20 mJniCallbacks.init(mBondStateMachine,mRemoteDevices); 21 22 //FIXME: Set static instance here??? 23 setAdapterService(this); 24 25 //Start profile services 26 if (!mProfilesStarted && supportedProfileServices.length >0) { 27 //Startup all profile services
28 setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON); 29 }else { 30 if (DBG) {debugLog("processStart(): Profile Services alreay started");} 31 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED)); 32 } 33 }

processStart

setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON); 是用来开启Bluetooth Profile 的,log 中可以看到:         

1 BluetoothAdapterService( 1789): Starting service com.android.bluetooth.hfp.HeadsetService
2 BluetoothAdapterService( 1789): Starting service com.android.bluetooth.a2dp.A2dpService
3 BluetoothAdapterService( 1789): Starting service com.android.bluetooth.hid.HidService
4 BluetoothAdapterService( 1789): Starting service com.android.bluetooth.hdp.HealthService
5 BluetoothAdapterService( 1789): Starting service com.android.bluetooth.pan.PanService
6 BluetoothAdapterService( 1789): Starting service com.android.bluetooth.gatt.GattService
7 BluetoothAdapterService( 1789): Starting service com.android.bluetooth.map.BluetoothMapService
8     bluedroid( 1789): get_profile_interface handsfree
9     bluedroid( 1789): get_profile_interface a2dp 10     bluedroid( 1789): get_profile_interface avrcp 11     bluedroid( 1789): get_profile_interface hidhost 12     bluedroid( 1789): get_profile_interface health 13     bluedroid( 1789): get_profile_interface pan 14     bluedroid( 1789): get_profile_interface gatt​

BT Profile log

然后可以看到:mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED)); 

交给了PendingCommandState下的processMessage处理

 1                 case STARTED:   {
 2                     if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STARTED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);
 3                     //Remove start timeout
 4                     removeMessages(START_TIMEOUT);
 5 
 6                     //Enable
 7                     boolean ret = adapterService.enableNative();
 8                     if (!ret) {
 9                         errorLog("Error while turning Bluetooth On");
10                         notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
11                         transitionTo(mOffState);
12                     } else {
13                         sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);
14                     }
15                 }

case STARTED

由mAdapterService.enableNative(); 可以看到  /*package*/ native boolean enableNative();

 此时就进入了JNI了

 5. JNI 调用

enableNative() 是在 packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

1 static jboolean enableNative(JNIEnv* env, jobject obj) { 2 ALOGV("%s:",__FUNCTION__);
3
4 jboolean result = JNI_FALSE; 5 if (!sBluetoothInterface) return result; 6
7 int ret = sBluetoothInterface->enable();
8 result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 9 return result; 10 }

enableNative

static const bt_interface_t *sBluetoothInterface = NULL;

  1 /** NOTE: By default, no profiles are initialized at the time of init/enable.
  2  *  Whenever the application invokes the 'init' API of a profile, then one of
  3  *  the following shall occur:
  4  *
  5  *    1.) If Bluetooth is not enabled, then the Bluetooth core shall mark the
  6  *        profile as enabled. Subsequently, when the application invokes the
  7  *        Bluetooth 'enable', as part of the enable sequence the profile that were
  8  *        marked shall be enabled by calling appropriate stack APIs. The
  9  *        'adapter_properties_cb' shall return the list of UUIDs of the
 10  *        enabled profiles.
 11  *
 12  *    2.) If Bluetooth is enabled, then the Bluetooth core shall invoke the stack
 13  *        profile API to initialize the profile and trigger a
 14  *        'adapter_properties_cb' with the current list of UUIDs including the
 15  *        newly added profile's UUID.
 16  *
 17  *   The reverse shall occur whenever the profile 'cleanup' APIs are invoked
 18  */
 19 
 20 /** Represents the standard Bluetooth DM interface. */
 21 typedef struct {
 22     /** set to sizeof(bt_interface_t) */
 23     size_t size;
 24     /**
 25      * Opens the interface and provides the callback routines
 26      * to the implemenation of this interface.
 27      */
 28     int (*init)(bt_callbacks_t* callbacks );
 29 
 30     /** Enable Bluetooth. */
 31     int (*enable)(void);
 32 
 33     /** Disable Bluetooth. */
 34     int (*disable)(void);
 35 
 36     /** This ensures the chip is Powered ON  to support other radios in the combo chip.
 37      * If the chip is OFF it set the chip to ON, if it is already ON it just increases the radio ref count
 38      * to keep track when to Power OFF */
 39     int (*enableRadio)(void);
 40 
 41     /** This decreases radio ref count  and ensures that chip is Powered OFF
 42      * when the radio ref count becomes zero. */
 43     int (*disableRadio)(void);
 44 
 45     /** Closes the interface. */
 46     void (*cleanup)(void);
 47 
 48     /** Get all Bluetooth Adapter properties at init */
 49     int (*get_adapter_properties)(void);
 50 
 51     /** Get Bluetooth Adapter property of 'type' */
 52     int (*get_adapter_property)(bt_property_type_t type);
 53 
 54     /** Set Bluetooth Adapter property of 'type' */
 55     /* Based on the type, val shall be one of
 56      * bt_bdaddr_t or bt_bdname_t or bt_scanmode_t etc
 57      */
 58     int (*set_adapter_property)(const bt_property_t *property);
 59 
 60     /** Get all Remote Device properties */
 61     int (*get_remote_device_properties)(bt_bdaddr_t *remote_addr);
 62 
 63     /** Get Remote Device property of 'type' */
 64     int (*get_remote_device_property)(bt_bdaddr_t *remote_addr,
 65                                       bt_property_type_t type);
 66 
 67     /** Set Remote Device property of 'type' */
 68     int (*set_remote_device_property)(bt_bdaddr_t *remote_addr,
 69                                       const bt_property_t *property);
 70 
 71     /** Get Remote Device's service record  for the given UUID */
 72     int (*get_remote_service_record)(bt_bdaddr_t *remote_addr,
 73                                      bt_uuid_t *uuid);
 74 
 75     /** Start SDP to get remote services */
 76     int (*get_remote_services)(bt_bdaddr_t *remote_addr);
 77 
 78     /** Start Discovery */
 79     int (*start_discovery)(void);
 80 
 81     /** Cancel Discovery */
 82     int (*cancel_discovery)(void);
 83 
 84     /** Create Bluetooth Bonding */
 85     int (*create_bond)(const bt_bdaddr_t *bd_addr);
 86 
 87     /** Remove Bond */
 88     int (*remove_bond)(const bt_bdaddr_t *bd_addr);
 89 
 90     /** Cancel Bond */
 91     int (*cancel_bond)(const bt_bdaddr_t *bd_addr);
 92 
 93     /** BT Legacy PinKey Reply */
 94     /** If accept==FALSE, then pin_len and pin_code shall be 0x0 */
 95     int (*pin_reply)(const bt_bdaddr_t *bd_addr, uint8_t accept,
 96                      uint8_t pin_len, bt_pin_code_t *pin_code);
 97 
 98     /** BT SSP Reply - Just Works, Numeric Comparison and Passkey
 99      * passkey shall be zero for BT_SSP_VARIANT_PASSKEY_COMPARISON &
100      * BT_SSP_VARIANT_CONSENT
101      * For BT_SSP_VARIANT_PASSKEY_ENTRY, if accept==FALSE, then passkey
102      * shall be zero */
103     int (*ssp_reply)(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
104                      uint8_t accept, uint32_t passkey);
105 
106     /** Get Bluetooth profile interface */
107     const void* (*get_profile_interface) (const char *profile_id);
108 
109     /** Bluetooth Test Mode APIs - Bluetooth must be enabled for these APIs */
110     /* Configure DUT Mode - Use this mode to enter/exit DUT mode */
111     int (*dut_mode_configure)(uint8_t enable);
112 
113     /* Send any test HCI (vendor-specific) command to the controller. Must be in DUT Mode */
114     int (*dut_mode_send)(uint16_t opcode, uint8_t *buf, uint8_t len);
115     /** BLE Test Mode APIs */
116     /* opcode MUST be one of: LE_Receiver_Test, LE_Transmitter_Test, LE_Test_End */
117     int (*le_test_mode)(uint16_t opcode, uint8_t *buf, uint8_t len);
118 
119     /* enable or disable bluetooth HCI snoop log */
120     int (*config_hci_snoop_log)(uint8_t enable);
121 
122     /** Get FM module interface */
123     const void* (*get_fm_interface) ();
124 } bt_interface_t;

bt_interface_t 定义

  bt_interface_t 定义 在hardware/libhardware/include/hardware/bluetooth.h

sBluetoothInterface的初始化在classInitNative(),这个函数大概做了以下的事情:

1)、注册java的回调函数(就是当下层已经打开蓝牙了,然后要通知上层,蓝牙已经打开了,java层就可以发送蓝牙打开的Broadcast了。)

2)、初始化蓝牙模块的HAL接口。

3)、得到sBluetoothInterface

6. Bluedroid -> bluetooth.c

external/bluetooth/bluedroid/btif/src/bluetooth.c

sBluetoothInterface->enable(); 会调到下方

1 static int enable( void ) 2 {
3 ALOGI("enable");
4
5 /* sanity check */
6 if (interface_ready() == FALSE) 7 return BT_STATUS_NOT_READY; 8
9 return btif_enable_bluetooth(); 10 }

bluetooth:enable()

接下来调用:external/bluetooth/bluedroid/btif/src/Btif_core.c

1 /*******************************************************************************
2 **
3 ** Function btif_enable_bluetooth
4 **
5 ** Description Performs chip power on and kickstarts OS scheduler
6 **
7 ** Returns bt_status_t
8 **
9 *******************************************************************************/
10
11 bt_status_t btif_enable_bluetooth(void) 12 { 13 BTIF_TRACE_DEBUG0("BTIF ENABLE BLUETOOTH"); 14
15 if (0 == btif_core_radio_ref_count){ 16
17 if (btif_core_state != BTIF_CORE_STATE_DISABLED) 18 { 19 ALOGD("not disabled\n"); 20 return BT_STATUS_DONE; 21 } 22
23 btif_core_state = BTIF_CORE_STATE_ENABLING; 24
25 /* Create the GKI tasks and run them */
26 bte_main_enable(); 27 btif_core_radio_ref_count++; 28 } 29 else
30 { 31 btif_core_radio_ref_count++; 32 /*btif core/chip is already enabled so just do other initialisation according to event*/
33 btif_transfer_context(btif_in_generic_evt, BTIF_CORE_BT_STATE_ON, NULL, 0, NULL); 34 } 35
36 return BT_STATUS_SUCCESS; 37 }

btif_enable_bluetooth

 external/bluetooth/bluedroid/main/Bte_main.c

1 /******************************************************************************
2 **
3 ** Function bte_main_enable
4 **
5 ** Description BTE MAIN API - Creates all the BTE tasks. Should be called
6 ** part of the Bluetooth stack enable sequence
7 **
8 ** Returns None
9 ** 10 ******************************************************************************/
11 void bte_main_enable() 12 { 13 APPL_TRACE_DEBUG1("%s", __FUNCTION__); 14
15 /* Initialize BTE control block */
16 BTE_Init(); 17
18 lpm_enabled = FALSE; 19
20 bte_hci_enable(); 21
22 GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR, 23 (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE), 24 sizeof(bte_btu_stack)); 25
26 GKI_run(0); 27 }

bte_main_enable

1 /******************************************************************************
2 **
3 ** Function bte_hci_enable
4 **
5 ** Description Enable HCI & Vendor modules
6 **
7 ** Returns None
8 **
9 ******************************************************************************/
10 static void bte_hci_enable(void) 11 { 12 APPL_TRACE_DEBUG1("%s", __FUNCTION__); 13
14 preload_start_wait_timer(); 15
16 if (bt_hc_if) 17 { 18 int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address); 19 APPL_TRACE_EVENT1("libbt-hci init returns %d", result); 20
21 assert(result == BT_HC_STATUS_SUCCESS); 22
23 if (hci_logging_enabled == TRUE || hci_logging_config == TRUE) 24 bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile); 25
26 #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)
27 APPL_TRACE_DEBUG1("%s Not Turninig Off the BT before Turninig ON", __FUNCTION__); 28
29 /* Do not power off the chip before powering on if BT_CLEAN_TURN_ON_DISABLED flag 30 is defined and set to TRUE to avoid below mentioned issue. 31
32 Wingray kernel driver maintains a combined counter to keep track of 33 BT-Wifi state. Invoking set_power(BT_HC_CHIP_PWR_OFF) when the BT is already 34 in OFF state causes this counter to be incorrectly decremented and results in undesired 35 behavior of the chip. 36
37 This is only a workaround and when the issue is fixed in the kernel this work around 38 should be removed. */
39 #else
40 /* toggle chip power to ensure we will reset chip in case 41 a previous stack shutdown wasn't completed gracefully */
42 bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF); 43 #endif
44 bt_hc_if->set_power(BT_HC_CHIP_PWR_ON); 45
46 bt_hc_if->preload(NULL); 47 } 48 }

bte_hci_enable

我们先看下bt_hc_if->set_power,前面有做一些初始化Bluedroid的动作

由 bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);可以看出:

static bt_hc_interface_t *bt_hc_if=NULL;

下面是bt_hc_if 的初始化

1 /******************************************************************************
2 **
3 ** Function bte_main_in_hw_init
4 **
5 ** Description Internal helper function for chip hardware init
6 **
7 ** Returns None
8 **
9 ******************************************************************************/
10 static void bte_main_in_hw_init(void) 11 { 12 if ( (bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface()) \ 13 == NULL) 14 { 15 APPL_TRACE_ERROR0("!!! Failed to get BtHostControllerInterface !!!"); 16 } 17
18 memset(&preload_retry_cb, 0, sizeof(bt_preload_retry_cb_t)); 19 }

bte_main_in_hw_init

 external/bluetooth/bluedroid/hci/src/Bt_hci_bdroid.c

1 /*******************************************************************************
2 **
3 ** Function bt_hc_get_interface
4 **
5 ** Description Caller calls this function to get API instance
6 **
7 ** Returns API table
8 **
9 *******************************************************************************/
10 const bt_hc_interface_t *bt_hc_get_interface(void) 11 { 12 return &bluetoothHCLibInterface; 13 }

bt_hc_get_interface

1 static const bt_hc_interface_t bluetoothHCLibInterface = { 2 sizeof(bt_hc_interface_t),
3 init,
4 set_power,
5 lpm,
6 preload,
7 postload,
8 transmit_buf,
9 set_rxflow, 10 logging, 11 cleanup 12 };

bluetoothHCLibInterface

由以上可以看到set_power

 1 /** Chip power control */
 2 static void set_power(bt_hc_chip_power_state_t state)
 3 {
 4     int pwr_state;
 5 
 6     BTHCDBG("set_power %d", state);
 7 
 8     /* Calling vendor-specific part */
 9     pwr_state = (state == BT_HC_CHIP_PWR_ON) ? BT_VND_PWR_ON : BT_VND_PWR_OFF;
10 
11     if (bt_vnd_if)
12         bt_vnd_if->op(BT_VND_OP_POWER_CTRL, &pwr_state);
13     else
14         ALOGE("vendor lib is missing!");
15 }

set_power

可以看到,bt_vnd_if->op(BT_VND_OP_POWER_CTRL, &pwr_state);

 external/bluetooth/bluedroid/hci/src/Bt_hw.c

bt_vendor_interface_t *bt_vnd_if=NULL;

 bt_vnd_if 初始化:

1 /******************************************************************************
2 **
3 ** Function init_vnd_if
4 **
5 ** Description Initialize vendor lib interface
6 **
7 ** Returns None
8 **
9 ******************************************************************************/
10 void init_vnd_if(unsigned char *local_bdaddr) 11 { 12 void *dlhandle; 13
14 dlhandle = dlopen("libbt-vendor.so", RTLD_NOW); 15 if (!dlhandle) 16 { 17 ALOGE("!!! Failed to load libbt-vendor.so !!!"); 18 return; 19 } 20
21 bt_vnd_if = (bt_vendor_interface_t *) dlsym(dlhandle, "BLUETOOTH_VENDOR_LIB_INTERFACE"); 22 if (!bt_vnd_if) 23 { 24 ALOGE("!!! Failed to get bt vendor interface !!!"); 25 return; 26 } 27
28 bt_vnd_if->init(&vnd_callbacks, local_bdaddr); 29 }

init_vnd_if

在init_vnd_if()函数可以看到其实是一个libbt-vendor.so的interface。这个是Vendor(芯片厂商)的library

Vendor就是芯片供应商的意思,在他们做好一块蓝牙芯片后,需要提供一些硬件相关的动作,比如上下电,设置波特率之类的。但是这些操作一般不会对没有许可的开放。Bluedroid提供了一个统一的接口bt_vendor_interface_t,供应商只需要实现这个接口定义的蓝牙相关的操作就可以交给bluedroid去做剩下的事情了

下面主要是broadcom 为例,我们进入/hardware/里面:

$ find . -name Android.mk |xargs grep libbt 
./broadcom/libbt/Android.mk:LOCAL_MODULE := libbt-vendor 
./broadcom/libbt/Android.mk:LOCAL_MODULE := libbt-vendor 
./broadcom/libbt/Android.mk: LOCAL_SRC_FILES := $(TI_BT_VENDOR_PATH)/libbt-vendor-ti.c 
./qcom/bt/Android.mk:include $(call all-named-subdir-makefiles,libbt-vendor) 
./qcom/bt/libbt-vendor/Android.mk:LOCAL_MODULE := libbt-vendor

或者

$ grep -nr BT_VND_OP_POWER_CTRL 
broadcom/libbt/src/bt_vendor_brcm.c:147: case BT_VND_OP_POWER_CTRL: 
broadcom/libbt/src/bt_vendor_brcm.c:149: BTVNDDBG("op: BT_VND_OP_POWER_CTRL"); 
qcom/bt/libbt-vendor/src/bt_vendor_qcom.c:105: case BT_VND_OP_POWER_CTRL:

在broadcom/libbt/src/bt_vendor_brcm.c

1 /** Requested operations */
2 static int op(bt_vendor_opcode_t opcode, void *param)
3 {
4 int retval = 0;
5
6 switch(opcode)
7 {
8 case BT_VND_OP_POWER_CTRL: 9 {
10 BTVNDDBG("op: BT_VND_OP_POWER_CTRL");
11 int *state = (int *) param; 12 if (*state == BT_VND_PWR_OFF) 13 upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
14 else if (*state == BT_VND_PWR_ON) 15 upio_set_bluetooth_power(UPIO_BT_POWER_ON);
16 BTVNDDBG("Delay for a while after BT power on");
17 usleep(200000);
18 }
19 break;
20
21 case BT_VND_OP_FW_CFG: 22 {
23 BTVNDDBG("op: BT_VND_OP_FW_CFG");
24 hw_config_start();
25 }
26 break;
27
28 case BT_VND_OP_SCO_CFG: 29 {
30 BTVNDDBG("op: BT_VND_OP_SCO_CFG");
31 #if (SCO_CFG_INCLUDED == TRUE)
32 if (is2076()) 33 {
34 ALOGD("PCM2 Settings for AP6476(BCM2076)");
35 hw_pcm2_config();
36 }
37 else
38 {
39 ALOGD("SCO config");
40 hw_sco_config();
41 }
42 #else
43 retval = -1;
44 #endif
45 }
46 break;
47
48 case BT_VND_OP_USERIAL_OPEN: 49 {
50 BTVNDDBG("op: BT_VND_OP_USERIAL_OPEN");
51 int (*fd_array)[] = (int (*)[]) param;
52 int fd, idx; 53 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
54 if (fd != -1)
55 {
56 for (idx=0; idx < CH_MAX; idx++) 57 (*fd_array)[idx] = fd; 58 59 retval = 1; 60 } 61 /* retval contains numbers of open fd of HCI channels */ 62 } 63 break; 64 65 case BT_VND_OP_USERIAL_CLOSE: 66 { 67 BTVNDDBG("op: BT_VND_OP_USERIAL_CLOSE"); 68 userial_vendor_close(); 69 } 70 break; 71 72 case BT_VND_OP_GET_LPM_IDLE_TIMEOUT: 73 { 74 BTVNDDBG("op: BT_VND_OP_GET_LPM_IDLE_TIMEOUT"); 75 uint32_t *timeout_ms = (uint32_t *) param; 76 *timeout_ms = hw_lpm_get_idle_timeout(); 77 } 78 break; 79 80 case BT_VND_OP_LPM_SET_MODE: 81 { 82 BTVNDDBG("op: BT_VND_OP_LPM_SET_MODE"); 83 uint8_t *mode = (uint8_t *) param; 84 retval = hw_lpm_enable(*mode); 85 } 86 break; 87 88 case BT_VND_OP_LPM_WAKE_SET_STATE: 89 { 90 uint8_t *state = (uint8_t *) param; 91 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ 92 TRUE : FALSE; 93 94 hw_lpm_set_wake_state(wake_assert); 95 } 96 break; 97 98 case BT_VND_OP_WBS_CFG: 99 { 100 #if (SCO_USE_I2S_INTERFACE == TRUE) 101 uint8_t *state = (uint8_t *) param; 102 hw_wbs_enable(*state); 103 #else 104 ALOGE("WBS configuration not supported without I2S"); 105 #endif // (SCO_USE_I2S_INTERFACE == TRUE) 106 } 107 break; 108 109 case BT_VND_OP_EPILOG: 110 { 111 #if (HW_END_WITH_HCI_RESET == FALSE) 112 if (bt_vendor_cbacks) 113 { 114 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 115 } 116 #else
117 hw_epilog_process(); 118 #endif
119 } 120 break; 121 } 122
123 return retval; 124 }

op

1 /*******************************************************************************
2 **
3 ** Function upio_set_bluetooth_power
4 **
5 ** Description Interact with low layer driver to set Bluetooth power
6 ** on/off.
7 **
8 ** Returns 0 : SUCCESS or Not-Applicable
9 ** <0 : ERROR 10 \*\* 11 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ 12 int upio\_set\_bluetooth\_power(int on) 13 { 14 int sz; 15 int fd = -1; 16 int ret = -1; 17 char buffer = '0'; 18 19 switch(on) 20 { 21 case UPIO\_BT\_POWER\_OFF: 22 buffer = '0'; 23 break; 24 25 case UPIO\_BT\_POWER\_ON: 26 buffer = '1'; 27 break; 28 } 29 30 if (is\_emulator\_context()) 31 { 32 /\* if new value is same as current, return -1 \*/ 33 if (bt\_emul\_enable == on) 34 return ret; 35 36 UPIODBG("set\_bluetooth\_power \[emul\] %d", on); 37 38 bt\_emul\_enable = on; 39 return 0; 40 } 41 42 /\* check if we have rfkill interface \*/ 43 if (is\_rfkill\_disabled()) 44 return 0; 45 46 if (rfkill\_id == -1) 47 { 48 if (init\_rfkill()) 49 return ret; 50 } 51 52 fd = open(rfkill\_state\_path, O\_WRONLY); 53 54 if (fd < 0) 55 { 56 ALOGE("set\_bluetooth\_power : open(%s) for write failed: %s (%d)", 57 rfkill\_state\_path, strerror(errno), errno); 58 return ret; 59 } 60 61 sz = write(fd, &buffer, 1); 62 63 if (sz < 0) { 64 ALOGE("set\_bluetooth\_power : write(%s) failed: %s (%d)", 65 rfkill\_state\_path, strerror(errno),errno); 66 } 67 else 68 ret = 0; 69 70 if (fd >= 0) 71 close(fd); 72
73 return ret; 74 }

upio_set_bluetooth_power

static char *rfkill_state_path = NULL;

 rfkill_state_path 是在下面初始化的。

1 static int init_rfkill() 2 {
3 char path[64];
4 char buf[16];
5 int fd, sz, id; 6
7 if (is_rfkill_disabled()) 8 return -1;
9
10 for (id = 0; ; id++) 11 { 12 snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id); 13 fd = open(path, O_RDONLY); 14 if (fd < 0) 15 { 16 ALOGE("init_rfkill : open(%s) failed: %s (%d)\n", \ 17 path, strerror(errno), errno); 18 return -1; 19 } 20 21 sz = read(fd, &buf, sizeof(buf)); 22 close(fd); 23 24 if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0) 25 { 26 rfkill_id = id; 27 break; 28 } 29 } 30
31 asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id); 32 return 0; 33 }

init_rfkill

原来就是在rfkill_state_path(/sys/class/rfkill/rfkill[x]/state)虚拟设备里写入了1

shell@android:/sys/class/rfkill/rfkill0 $ cat state 
0  // 表示蓝牙是关闭状态

shell@android:/sys/class/rfkill/rfkill0 $ cat state 

1   // 开启蓝牙后可以看到

rfkill是Linux下的一个标准的无线控制的虚拟设备,Linux也提供了rfkill的命令去查看以及控制所有的注册的无线设备。它们会在/dev/(PC的Linux)或者/sys/class(一般是Android)下生成相应的虚拟设备。

结合set_power 下面的log 和  bluetoothHCLibInterface  定义,可以看到接下来是调用的 bluetoothHCLibInterface 里的 proload->bthc_signal_event(HC_EVENT_PRELOAD)->bt_hc_worker_thread -》userial_open(USERIAL_PORT_1)->bt_vnd_if->op(BT_VND_OP_USERIAL_OPEN, &fd_array);->userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);

接下来是Hardware.c里

hw_config_start-》hw_config_cback

部分log 如下:

 1 01-01 00:21:02.240 I/bt_userial_vendor( 1821): userial vendor open: opening /dev/ttyMFD0
 2 01-01 00:21:02.240 I/GKI_LINUX( 1821): gki_task_entry: gki_task_entry task_id=0 [BTU] starting
 3 01-01 00:21:02.240 I/bt-btu ( 1821): btu_task pending for preload complete event
 4 01-01 00:21:02.260 I/bt_userial_vendor( 1821): device fd = 71 open
 5 01-01 00:21:02.260 E/bt_hwcfg( 1821): Hardware.c--hw_config_start
 6 01-01 00:21:02.290 D/bt_hwcfg( 1821): Chipset BCM2076B1
 7 01-01 00:21:02.290 D/bt_hwcfg( 1821): Target name = [BCM2076B1]
 8 01-01 00:21:02.290 I/bt_hwcfg( 1821): FW patchfile: /etc/firmware/bt/bcm2076b1.hcd
 9 01-01 00:21:02.300 I/bt_hwcfg( 1821): bt vendor lib: set UART baud 3000000
10 01-01 00:21:02.590 I/bt_hwcfg( 1821): bt vendor lib: set UART baud 115200
11 01-01 00:21:02.590 D/bt_hwcfg( 1821): Settlement delay -- 100 ms
12 01-01 00:21:02.690 I/bt_hwcfg( 1821): bt vendor lib: set UART baud 3000000
13 01-01 00:21:02.690 I/bt_hwcfg( 1821): Setting local bd addr to 22:22:C7:74:9F:05
14 01-01 00:21:02.720 I/bt_hwcfg( 1821): vendor lib fwcfg completed

log