如何将蓝牙低功耗(BLE)设备与Android配对以读取加密数据。
使用Android BLE page中的信息,我能够发现设备,连接设备,发现服务并读取未加密的特征。
当我尝试读取加密特征(一个会导致iOS显示要求配对然后完成阅读的弹出窗口)时,我得到错误代码5 ,这对应于{{ 3}}。
我不确定如何使设备配对或如何为读取完成提供身份验证信息。
我通过尝试添加描述符来玩弄BluetoothGattCharacteristics,但这也不起作用 任何帮助表示赞赏!
答案 0 :(得分:24)
当您收到GATT_INSUFFICIENT_AUTHENTICATION错误时,系统会为您启动绑定过程。在下面的例子中,我试图在葡萄糖监测器上启用通知和指示。首先,我启用葡萄糖测量特征的通知,这可能导致错误出现。
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
if (GM_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid())) {
mCallbacks.onGlucoseMeasurementNotificationEnabled();
if (mGlucoseMeasurementContextCharacteristic != null) {
enableGlucoseMeasurementContextNotification(gatt);
} else {
enableRecordAccessControlPointIndication(gatt);
}
}
if (GM_CONTEXT_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid())) {
mCallbacks.onGlucoseMeasurementContextNotificationEnabled();
enableRecordAccessControlPointIndication(gatt);
}
if (RACP_CHARACTERISTIC.equals(descriptor.getCharacteristic().getUuid())) {
mCallbacks.onRecordAccessControlPointIndicationsEnabled();
}
} else if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
// this is where the tricky part comes
if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
mCallbacks.onBondingRequired();
// I'm starting the Broadcast Receiver that will listen for bonding process changes
final IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
mContext.registerReceiver(mBondingBroadcastReceiver, filter);
} else {
// this situation happens when you try to connect for the second time to already bonded device
// it should never happen, in my opinion
Logger.e(TAG, "The phone is trying to read from paired device without encryption. Android Bug?");
// I don't know what to do here
// This error was found on Nexus 7 with KRT16S build of Andorid 4.4. It does not appear on Samsung S4 with Andorid 4.3.
}
} else {
mCallbacks.onError(ERROR_WRITE_DESCRIPTOR, status);
}
};
mBondingBroadcastReceiver是:
private BroadcastReceiver mBondingBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
final int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
final int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1);
Logger.d(TAG, "Bond state changed for: " + device.getAddress() + " new state: " + bondState + " previous: " + previousBondState);
// skip other devices
if (!device.getAddress().equals(mBluetoothGatt.getDevice().getAddress()))
return;
if (bondState == BluetoothDevice.BOND_BONDED) {
// Continue to do what you've started before
enableGlucoseMeasurementNotification(mBluetoothGatt);
mContext.unregisterReceiver(this);
mCallbacks.onBonded();
}
}
};
请记住在退出活动时取消注册广播接收器。它可能没有被接收者本身注销。
答案 1 :(得分:1)
我认为新的android 4.4提供了配对方法。同样的问题我已经面临所以等待更新和希望解决问题解决了createBond()方法。
答案 2 :(得分:0)
您可能需要检查内核smp.c文件,哪种方法可以调用它来进行配对。 1)密钥2)正常工作等。我想如果它能够调用MIMT和密钥安全级别,就不会有任何身份验证问题。确保将所有标志设置为调用SMP密钥方法。通过在smp.c文件中放置一些打印来跟踪。
在ICS中运行的解决方案:在android中使用btmgmt工具并将其挂钩在加密API中。使用密钥或任何其他方法。有用。您可能需要从最新的bluez代码中添加btmgmt中的密钥API。