36

如何将蓝牙低功耗 (BLE)设备与 Android 配对以读取加密数据。

使用Android BLE 页面中的信息,我能够发现设备、连接到它、发现服务并读取未加密的特征。

当我尝试读取加密特征(会导致 iOS 显示要求配对然后完成读取的弹出窗口)时,我收到错误代码 5,对应于Insufficient Authentication

我不确定如何使设备配对或如何提供身份验证信息以完成读取

我通过尝试添加描述符来玩弄 BluetoothGattCharacteristics,但这也不起作用。
任何帮助表示赞赏!

4

3 回答 3

25

When you get the GATT_INSUFFICIENT_AUTHENTICATION error, the system starts the bonding process for you. In the example below I'm trying to enable notifications and indications on glucose monitor. First I'm enabling the notifications on Glucose Measurement characteristic which can cause the error to appear.

@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);
        }
    };

Where the mBondingBroadcastReceiver is:

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();
        }
    }
};

Remember to unregister the broadcast receiver when exiting the activity. It may have not been unregistered by the receicver itself.

于 2013-11-20T10:43:59.790 回答
0

您可能需要检查 Kernel smp.c 文件,它调用了哪种配对方法进行配对。1) 密码 2) 只是工作等。我想如果它能够调用 MIMT 和密钥级别的安全性,就不会有任何身份验证问题。确保所有标志都设置为调用 SMP 密钥方法。通过在 smp.c 文件中放置一些打印来跟踪。

适用于 ICS 的解决方案:使用 android 中的 btmgmt 工具并将其挂接到加密 API 中。使用密码或任何其他方法。有用。您可能需要从最新的 bluez 代码在 btmgmt 中添加密码 API。

于 2013-10-01T07:25:18.533 回答
0

我认为新的 android 4.4 提供了配对方法。我已经面临同样的问题,所以等待更新并希望通过 createBond() 方法解决问题。

http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#setPairingConfirmation%28boolean%29

于 2013-11-03T13:51:35.517 回答