Android 11 BT配对流程[4] - 配对状态上报流程

wuchangjian2021-11-08 17:34:36编程学习

Android 蓝牙学习汇总

11-08 08:39:08.131  2483  2802 I BluetoothBondStateMachine: Bond State Change Intent:C0:B4:7D:3C:98:87 BOND_BONDED => BOND_NONE
11-08 08:39:48.024  2483  2840 I bt_btm  : btm_sec_change_pairing_state()  New: GET_REM_NAME pairing_flags:0x1
11-08 08:39:48.034  2483  2802 I BluetoothBondStateMachine: Bond State Change Intent:C0:B4:7D:3C:98:87 BOND_NONE => BOND_BONDING
11-08 08:39:48.421  2483  2840 I bt_btm  : btm_sec_change_pairing_state()  New: WAIT_PIN_REQ pairing_flags:0x5
11-08 08:39:49.030  2483  2840 I bt_btm  : btm_sec_change_pairing_state()  New: WAIT_LOCAL_IOCAPS pairing_flags:0x5
11-08 08:39:49.343  2483  2840 I bt_btm  : btm_sec_change_pairing_state()  New: WAIT_NUM_CONFIRM pairing_flags:0x5
11-08 08:39:52.094  2483  2840 I bt_btm  : btm_sec_change_pairing_state()  New: WAIT_AUTH_COMPLETE pairing_flags:0x5
11-08 08:39:52.187  2483  2840 I bt_btm  : btm_sec_change_pairing_state()  New: IDLE pairing_flags:0x5
11-08 08:39:52.697  2483  2802 I BluetoothBondStateMachine: Bond State Change Intent:C0:B4:7D:3C:98:87 BOND_BONDING => BOND_BONDED

蓝牙配对从BOND_NONE->BOND_BONDING->BOND_BONDED

android-11/system/bt/btif/src/btif_dm.cc
-----------------------------------------------

# 通过bond_state_changed 上报配对状态

static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr,
                               bt_bond_state_t state) {
  btif_stats_add_bond_event(bd_addr, BTIF_DM_FUNC_BOND_STATE_CHANGED, state);

  if ((pairing_cb.state == state) && (state == BT_BOND_STATE_BONDING)) {
    // Cross key pairing so send callback for static address
    if (!pairing_cb.static_bdaddr.IsEmpty()) {
      auto tmp = bd_addr;
      HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, &tmp, state);
    }
    return;
  }

  if (pairing_cb.bond_type == BOND_TYPE_TEMPORARY) state = BT_BOND_STATE_NONE;

  BTIF_TRACE_DEBUG("%s: state=%d, prev_state=%d, sdp_attempts = %d", __func__,
                   state, pairing_cb.state, pairing_cb.sdp_attempts);

  if (state == BT_BOND_STATE_NONE) {
    MetricIdAllocator::GetInstance().ForgetDevice(bd_addr);
  } else if (state == BT_BOND_STATE_BONDED) {
    MetricIdAllocator::GetInstance().AllocateId(bd_addr);
    if (!MetricIdAllocator::GetInstance().SaveDevice(bd_addr)) {
      LOG(FATAL) << __func__ << ": Fail to save metric id for device "
                 << bd_addr;
    }
  }
  auto tmp = bd_addr;
----------------------------------------------------------------------------
# bt_hal_cbacks是JNI Init操作的时候传下来的函数指针,用于bluedroid回调JNI的接口
# 这里通过JNI实现的bond_state_changed_cb传递到上层
----------------------------------------------------------------------------
  HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, &tmp, state);

  int dev_type;
  if (!btif_get_device_type(bd_addr, &dev_type)) {
    dev_type = BT_DEVICE_TYPE_BREDR;
  }

  if (state == BT_BOND_STATE_BONDING ||
      (state == BT_BOND_STATE_BONDED && pairing_cb.sdp_attempts > 0)) {
    // Save state for the device is bonding or SDP.
    pairing_cb.state = state;
    pairing_cb.bd_addr = bd_addr;
  } else {
    pairing_cb = {};
  }
}

继续看看JNI的实现

android-11/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
-----------------------------------------------------------------------------------------

static bool initNative(JNIEnv* env, jobject obj, jboolean isGuest,
                       jboolean isNiapMode, int configCompareResult) {
  ALOGV("%s", __func__);

  android_bluetooth_UidTraffic.clazz =
      (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic"));

  sJniAdapterServiceObj = env->NewGlobalRef(obj);
  sJniCallbacksObj =
      env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));

  if (!sBluetoothInterface) {
    return JNI_FALSE;
  }
--------------------------------------------
# sBluetoothCallbacks 定义见下面
--------------------------------------------
  int ret = sBluetoothInterface->init(
      &sBluetoothCallbacks, isGuest == JNI_TRUE ? 1 : 0,
      isNiapMode == JNI_TRUE ? 1 : 0, configCompareResult);
  if (ret != BT_STATUS_SUCCESS) {
    ALOGE("Error while setting the callbacks: %d\n", ret);
    sBluetoothInterface = NULL;
    return JNI_FALSE;
  }
  ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
  if (ret != BT_STATUS_SUCCESS) {
    ALOGE("Error while setting Bluetooth callouts: %d\n", ret);
    sBluetoothInterface->cleanup();
    sBluetoothInterface = NULL;
    return JNI_FALSE;
  }

  sBluetoothSocketInterface =
      (btsock_interface_t*)sBluetoothInterface->get_profile_interface(
          BT_PROFILE_SOCKETS_ID);
  if (sBluetoothSocketInterface == NULL) {
    ALOGE("Error getting socket interface");
  }

  return JNI_TRUE;
}
-----------------------------------------------------------------------------------------
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, acl_state_changed_callback,
    callback_thread_event,       dut_mode_recv_callback,
    le_test_mode_recv_callback,  energy_info_recv_callback};

-----------------------------------------------------------------------------------------
static void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
                                        bt_bond_state_t state) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (!bd_addr) {
    ALOGE("Address is null in %s", __func__);
    return;
  }

  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
  if (!addr.get()) {
    ALOGE("Address allocation failed in %s", __func__);
    return;
  }
  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
                                   (jbyte*)bd_addr);
-------------------------------------------
# 通过JNI回调Java ,通知到java层
-------------------------------------------
  sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback,
                               (jint)status, addr.get(), (jint)state);
}

-----------------------------------------------------------------------------------------
method_bondStateChangeCallback 定义如下:
  method_bondStateChangeCallback =
      env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V");

  jclass jniCallbackClass =
      env->FindClass("com/android/bluetooth/btservice/JniCallbacks");

# JNI-> 调用JniCallbacks.bondStateChangeCallback
-----------------------------------------------------------------------------------------

上面完成了JNI-> Java层的调用

android-11/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/JniCallbacks.java
-----------------------------------------------------------------------------------------


    void bondStateChangeCallback(int status, byte[] address, int newState) {
        mBondStateMachine.bondStateChangeCallback(status, address, newState);
    }


-----------------------------------------------------------------------------------------
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
-----------------------------------------------------------------------------------------
    void bondStateChangeCallback(int status, byte[] address, int newState) {
        BluetoothDevice device = mRemoteDevices.getDevice(address);

        if (device == null) {
            infoLog("No record of the device:" + device);
            // This device will be added as part of the BONDING_STATE_CHANGE intent processing
            // in sendIntent above
            device = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
        }

        infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device + " newState: "
                + newState);

        Message msg = obtainMessage(BONDING_STATE_CHANGE);
        msg.obj = device;

        if (newState == BOND_STATE_BONDED) {
            msg.arg1 = BluetoothDevice.BOND_BONDED;
        } else if (newState == BOND_STATE_BONDING) {
            msg.arg1 = BluetoothDevice.BOND_BONDING;
        } else {
            msg.arg1 = BluetoothDevice.BOND_NONE;
        }
        msg.arg2 = status;

        sendMessage(msg);
    }

-----------------------------------------------------------------------------------------
上面把协议栈的配对状态发送到了蓝牙APP,这里就不继续看了,大概就是根据状态机不同的状态处理BluetoothDevice.BOND_NONE,BOND_STATE_BONDING,BOND_BONDED消息,处理相应的逻辑

相关文章

HCIP 2

HCIP 2

实验拓扑图如上所示   要求: 1.R4为运营商,...

数据结构与算法自学8

2021/11/11 大话数据结构 赫夫曼树定义及原理 赫夫曼编码 图 无...

7-165 圆形体体积计算器 (20 分)

7-165 圆形体体积计算器 (20 分) 本题要求实现一个常用圆形体体积的计算器。计...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。