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
手机扫一扫
移动阅读更方便
你可能感兴趣的文章