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