android bt 代码栈

android bt 代码栈

参考文档

蓝牙的总体流程

0003_bluetooth_flow.png

enable bluetooth

* packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothAdapter.java 
  └── public boolean enable()
      └── return mManagerService.enable(mAttributionSource);
          └── packages/modules/Bluetooth/service/java/com/android/server/bluetooth/BluetoothManagerService.java
              └── sendEnableMsg(false, BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName); 
                  └── mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0));
                      ├── handleEnable(mQuietEnable);
                      │   └── if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT)) 
                      │       └── public void onServiceConnected(ComponentName componentName, IBinder service)
                      │           └── Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
                      │               ├── mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));//获取的是 IBluetooth 对象, 而AdapterService.java 内部类 AdapterServiceBinder  实现了 IBluetooth 
                      │               ├── mBluetooth.registerCallback(mBluetoothCallback, mContext.getAttributionSource()); 
                      │               └── if (!mBluetooth.enable(mQuietEnable, mContext.getAttributionSource()))
                      │                   └── packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java
                      │                       └── service.enable(quietMode)
                      │                           └── mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
                      │                               └── transitionTo(mTurningBleOnState);
                      │                                   ├── sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY);
                      │                                   └── mAdapterService.startProfileServices();
                      │                                       ├── Class[] supportedProfileServices = Config.getSupportedProfiles();
                      │                                       └── setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON); 
                      │                                           └── setProfileServiceState(service, state);
                      │                                               ├── intent.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED);
                      │                                               ├── intent.putExtra(BluetoothAdapter.EXTRA_STATE, state);
                      │                                               └── startService(intent);
                      │                                                   └── packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/ProfileService.java 
                      │                                                       └── public int onStartCommand(Intent intent, int flags, int startId)
                      │                                                           ├── if (state == BluetoothAdapter.STATE_OFF)
                      │                                                           │   └── doStop(); 
                      │                                                           └── else if (state == BluetoothAdapter.STATE_ON)
                      │                                                               └── doStart();
                      │                                                                   └── mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON);
                      │                                                                       ├── Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
                      │                                                                       └── mHandler.sendMessage(m);
                      │                                                                           └── processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1);
                      │                                                                               └── enableNative();
                      │                                                                                   └── packages/modules/Bluetooth/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp 
                      │                                                                                       └── int ret = sBluetoothInterface->enable();
                      │                                                                                           └── packages/modules/Bluetooth/system/btif/src/bluetooth.cc
                      │                                                                                               └── stack_manager_get_interface()->start_up_stack_async();
                      │                                                                                                   └── packages/modules/Bluetooth/system/btif/src/stack_manager.cc
                      │                                                                                                       └── management_thread.DoInThread(FROM_HERE, base::Bind(event_start_up_stack, nullptr)); 
                      │                                                                                                           └── static void event_start_up_stack(UNUSED_ATTR void* context)
                      │                                                                                                               ├── ensure_stack_is_initialized();
                      │                                                                                                               │   └── static void event_init_stack(void* context) 
                      │                                                                                                               │       ├── btif_init_bluetooth();
                      │                                                                                                               │       └── bte_main_init();
                      │                                                                                                               │           ├── hci = bluetooth::shim::hci_layer_get_interface()
                      │                                                                                                               │           └── hci->set_data_cb(base::Bind(&post_to_main_message_loop));
                      │                                                                                                               ├── module_start_up(get_local_module(BTIF_CONFIG_MODULE));
                      │                                                                                                               ├── BTA_dm_init()  //搜索事件回调
                      │                                                                                                               │   └── bta_sys_register(BTA_ID_DM_SEARCH, &bta_dm_search_reg);
                      │                                                                                                               │       └── static const tBTA_SYS_REG bta_dm_search_reg = {bta_dm_search_sm_execute, bta_dm_search_sm_disable};
                      │                                                                                                               │           └── bool bta_dm_search_sm_execute(BT_HDR_RIGID* p_msg) 
                      │                                                                                                               │               └── void bta_dm_search_start(tBTA_DM_MSG* p_data) 
                      │                                                                                                               │                   └── result.status = BTM_StartInquiry(bta_dm_inq_results_cb, bta_dm_inq_cmpl_cb);
                      │                                                                                                               │                       └── static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir,uint16_t eir_len)
                      │                                                                                                               │                           └── bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result);
                      │                                                                                                               ├── bta_dm_enable(bte_dm_evt);
                      │                                                                                                               └── BTA_dm_on_hw_on();
                      ├── Message enableDelayedMsg = mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED);
                      └── mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS);

蓝牙扫描

* packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothAdapter.java
  └── public boolean startDiscovery()
      └── mService.startDiscovery(mAttributionSource, recv);
          └── public void startDiscovery(AttributionSource source, SynchronousResultReceiver receiver)  
              └── receiver.send(startDiscovery(source));
                  └── private boolean startDiscovery(AttributionSource attributionSource) 
                      └── return service.startDiscovery(attributionSource);
                          └── boolean startDiscovery(AttributionSource attributionSource) 
                              └── return startDiscoveryNative();
                                  └── int ret = sBluetoothInterface->start_discovery();
                                      └── do_in_main_thread(FROM_HERE, base::BindOnce(btif_dm_start_discovery));
                                          └── packages/modules/Bluetooth/system/btif/src/btif_dm.cc
                                              └── void btif_dm_start_discovery(void) 
                                                  ├── if (bta_dm_is_search_request_queued())
                                                  │   └──  return bta_dm_search_cb.p_pending_search != NULL;
                                                  └──  BTA_DmSearch(btif_dm_search_devices_evt, is_bonding_or_sdp());
                                                      ├── void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback, bool is_bonding_or_sdp)
                                                      └── static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_search_data)
                                                          └── invoke_device_found_cb(num_properties, properties);
                                                              └── void invoke_device_found_cb(int num_properties, bt_property_t* properties)  

app 获取搜索到的设备

* packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java 
  └── public void onCreate()
      └── initNative(mUserManager.isGuestUser(), isCommonCriteriaMode(), configCompareResult, getInitFlags(), isAtvDevice, getApplicationInfo().dataDir);
          └── packages/modules/Bluetooth/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp 
              └── int ret = sBluetoothInterface->init(&sBluetoothCallbacks, isGuest == JNI_TRUE ? 1 : 0,isCommonCriteriaMode == JNI_TRUE ? 1 : 0, configCompareResult, flags, isAtvDevice == JNI_TRUE ? 1 : 0, user_data_directory);
                  ├── static int init(bt_callbacks_t* callbacks, bool start_restricted
                  │   └── set_hal_cbacks(callbacks);
                  │       └── void set_hal_cbacks(bt_callbacks_t* callbacks) { bt_hal_cbacks = callbacks; }
                  │           └── 
                  └── static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks),adapter_state_change_callback,adapter_properties_callback,remote_device_properties_callback,device_found_callback,discovery_state_changed_callback,pin_request_callback,ssp_request_callback,bond_state_changed_callback,address_consolidate_callback,acl_state_changed_callback,callback_thread_event,dut_mode_recv_callback,le_test_mode_recv_callback,energy_info_recv_callback,link_quality_report_callback,generate_local_oob_data_callback,switch_buffer_size_callback,switch_codec_callback};
                      └── sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback,addr.get());
                          └── method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
                              └── packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java
                                  └── mRemoteDevices.deviceFoundCallback(address);
                                      └── packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java 
                                          └── void deviceFoundCallback(byte[] address) 
                                              ├── Intent intent = new Intent(BluetoothDevice.ACTION_FOUND);
                                              └── sAdapterService.sendBroadcastMultiplePermissions
                                            

蓝牙配对

* frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
  └── public boolean startPairing()  
      └── if (!mDevice.createBond())
          └── packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothDevice.java 
              └── return createBond(TRANSPORT_AUTO);
                  ├── return createBondInternal(transport, null, null);
                  │   └── service.createBond(this, transport, remoteP192Data, remoteP256Data,mAttributionSource, recv);
                  │       └── packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java 
                  │           └── receiver.send(createBond(device, transport, remoteP192Data, remoteP256Data, source));
                  │               └── private boolean createBond(BluetoothDevice device, int transport, OobData remoteP192Data, OobData remoteP256Data, AttributionSource attributionSource) 
                  │                   └── Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
                  │                       └── packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java
                  │                           └── result = createBond(dev, msg.arg1, p192Data, p256Data, false);
                  │                               └── result = mAdapterService.createBondNative(addr, transport);
                  │                                   └── packages/modules/Bluetooth/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp 
                  │                                       └── int ret = sBluetoothInterface->create_bond((RawAddress*)addr, transport);
                  │                                           └── do_in_main_thread(FROM_HERE, base::BindOnce(btif_dm_create_bond, *bd_addr, transport));
                  │                                               └── void btif_dm_create_bond(const RawAddress bd_addr, int transport) 
                  │                                                   ├── btif_stats_add_bond_event(bd_addr, BTIF_DM_FUNC_CREATE_BOND,pairing_cb.state);
                  │                                                   └── btif_dm_cb_create_bond(bd_addr, transport);
                  │                                                       └── static void btif_dm_cb_create_bond(const RawAddress bd_addr,tBT_TRANSPORT transport)
                  │                                                           └── bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);  ///这里进行蓝牙状态变化的上报
                  │                                                               ├── invoke_bond_state_changed_cb(status, bd_addr, state, pairing_cb.fail_reason);
                  │                                                               │   └── HAL_CBACK(bt_hal_cbacks,bond_state_changed_cb, status,&bd_addr, state, fail_reason);
                  │                                                               │       └── typedef struct {... bond_state_changed_callback bond_state_changed_cb;...}
                  │                                                               │           └── static void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr,bt_bond_state_t state, int fail_reason)
                  │                                                               │               └── void bondStateChangeCallback(int status, byte[] address, int newState, int hciReason) 
                  │                                                               │                   └── mBondStateMachine.bondStateChangeCallback(status, address, newState, hciReason);// 
                  │                                                               └── BTA_DmBond(bd_addr, addr_type, transport, device_type);
                  │                                                                   └── do_in_main_thread(FROM_HERE, base::Bind(bta_dm_bond, bd_addr, addr_type, transport, device_type));
                  │                                                                       ├── BTM_SecBond(bd_addr, addr_type, transport, device_type, 0, NULL);
                  │                                                                       │   └── btm_sec_bond_by_transport(bd_addr, addr_type, transport, pin_len, p_pin);
                  │                                                                       │       ├── if (!controller_get_interface()->supports_simple_pairing()) 
                  │                                                                       │       └── btsnd_hcic_write_pin_type(HCI_PIN_TYPE_FIXED);
                  │                                                                       └── bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
                  ├── mRemoteDevices.setBondingInitiatedLocally(Utils.getByteAddress(device));
                  ├── cancelDiscoveryNative();
                  └── mBondStateMachine.sendMessage(msg);

开始配对后,确认是否进行配对

* packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothPairingController.java
  └── private void onPair(String passkey)
      ├── mDevice.setPin(passkey);
      └── mDevice.setPairingConfirmation(true);
          └── packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothDevice.java
              ├── final IBluetooth service = getService();
              └── service.setPairingConfirmation(this, confirm, mAttributionSource, recv);
                  └── packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java
                      └── public void setPairingConfirmation(BluetoothDevice device, boolean accept, AttributionSource source, SynchronousResultReceiver receiver) 
                          └── receiver.send(setPairingConfirmation(device, accept, source));
                              └── AdapterService service = getService();
                                  └── service.sspReplyNative(getBytesFromAddress(device.getAddress()),AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION, accept,0);
                                      └── packages/modules/Bluetooth/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
                                          └── int ret = sBluetoothInterface->ssp_reply((RawAddress*)addr, (bt_ssp_variant_t)type, accept, passkey);
                                              └── packages/modules/Bluetooth/system/btif/src/bluetooth.cc
                                                  └── do_in_main_thread(FROM_HERE, base::BindOnce(btif_dm_ssp_reply, *bd_addr, variant, accept))
                                                      └── packages/modules/Bluetooth/system/btif/src/btif_dm.cc
                                                          └── void btif_dm_ssp_reply(const RawAddress bd_addr, bt_ssp_variant_t variant, uint8_t accept) 

蓝牙状态变更上报

这里以BondStateMachine为例进行代码跟踪,其他的回调也是类似

* packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AdapterService.java 
  ├── classInitNative();
  │   └── packages/modules/Bluetooth/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
  │       ├── method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
  │       ├── method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
  │       ├── method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback", "([B[BIZ)V");
  │       ├── method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback", "([B[BIII)V");
  │       └── method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BII)V");
  └── public void onCreate()
      ├── mJniCallbacks = new JniCallbacks(this, mAdapterProperties);
      └── initNative(mUserManager.isGuestUser(), isCommonCriteriaMode(), configCompareResult, getInitFlags(), isAtvDevice, getApplicationInfo().dataDir);
          └── int ret = sBluetoothInterface->init(&sBluetoothCallbacks, isGuest == JNI_TRUE ? 1 : 0,isCommonCriteriaMode == JNI_TRUE ? 1 : 0, configCompareResult, flags,isAtvDevice == JNI_TRUE ? 1 : 0, user_data_directory);//这里将回调函数传入
              └── static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks),adapter_state_change_callback,adapter_properties_callback,remote_device_properties_callback,device_found_callback,discovery_state_changed_callback,pin_request_callback,ssp_request_callback,bond_state_changed_callback,address_consolidate_callback,acl_state_changed_callback,callback_thread_event,dut_mode_recv_callback,le_test_mode_recv_callback,energy_info_recv_callback,link_quality_report_callback,generate_local_oob_data_callback,switch_buffer_size_callback,switch_codec_callback};
                  └── static void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr, bt_bond_state_t state,int fail_reason) 
                      └── sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback,(jint)status, addr.get(), (jint)state,(jint)fail_reason);
                          └── packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java
                              └── void bondStateChangeCallback(int status, byte[] address, int newState, int hciReason)
                                  └── mBondStateMachine.bondStateChangeCallback(status, address, newState, hciReason);
                                      └── packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java
                                          └── void bondStateChangeCallback(int status, byte[] address, int newState, int hciReason) 
                                              ├── Message msg = obtainMessage(BONDING_STATE_CHANGE);
                                              └── sendMessage(msg);
                                                  └── sendIntent(dev, newState, reason, false);
                                                      └── packages/modules/Bluetooth/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
                                                          └── private class BondStateChangedReceiver extends BroadcastReceiver 
                                                              └── bondStateChanged(device, state)
                                                                  └── void bondStateChanged(BluetoothDevice device, int bondState)
                                                                      └──  if (bondState != BluetoothDevice.BOND_NONE) return; //到这里最终好像也没处理什么

蓝牙配对状态改变

在userdebug版本下可以看到日志,蓝牙配对过程中状态的切换 IDLE => WAIT_PIN_REQ => WAIT_NUM_CONFIRM => WAIT_AUTH_COMPLETE => IDLE

03-23 17:56:52.593652  9439  9489 I bt_btm_sec: btm_sec_change_pairing_state: Pairing state changed IDLE => WAIT_PIN_REQ pairing_flags:0x5
03-23 17:56:54.060246  9439  9489 I bt_btm_sec: btm_sec_change_pairing_state: Pairing state changed WAIT_PIN_REQ => WAIT_LOCAL_IOCAPS pairing_flags:0x5
03-23 17:56:54.311093  9439  9489 I bt_btm_sec: btm_sec_change_pairing_state: Pairing state changed WAIT_LOCAL_IOCAPS => WAIT_NUM_CONFIRM pairing_flags:0x5
03-23 17:56:55.985548  9439  9489 I bt_btm_sec: btm_sec_change_pairing_state: Pairing state changed WAIT_NUM_CONFIRM => WAIT_AUTH_COMPLETE pairing_flags:0x5
03-23 17:56:56.057715  9439  9489 I bt_btm_sec: btm_sec_change_pairing_state: Pairing state changed WAIT_AUTH_COMPLETE => IDLE pairing_flags:0x5