Android4.4 Bluetooth enble

本文深入解析了Android4.4上蓝牙协议栈的实现细节,从源码分布、常用类及相关profile到EnableBluetooth的过程,全面揭示了Android蓝牙服务的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值