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 }
BluetoothAdapter3. 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 }
sendEnableMsgsendEnableMsg 交给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 gattBT 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