IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 11 BT配对流程[4] - 配对状态上报流程 -> 正文阅读

[移动开发]Android 11 BT配对流程[4] - 配对状态上报流程

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消息,处理相应的逻辑

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:40:29  更:2021-11-09 19:41:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:03:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码