android 上的 BLE 外设配对引脚

BLE peripheral pairing pin on android

我在 Android 上实现了 GATT 服务器和客户端应用程序。连接正常,我通过向所有 GattCharacteristics 添加 PERMISSION_READ/WRITE_ENCRYPTED_MITM 来强制配对。

但不同客户端的配对行为不同:

1) Pin 显示在 client/central(Android 5 on Samsung Galaxy S3)上,应插入 server/peripheral(Android 7 on Nexus 5 ).

2) 密钥显示在两个设备上 client/central(Android 5 on Samsung Galaxy S3)和 server/peripheral(Android 6 on Nexus 7)

3) 与 Windows 或 iOS 配对失败,server/peripheral 需要输入引脚。

我期望并希望发生的是:

Pin 显示在 server/peripheral 上,必须插入 client/central

有什么方法可以配置该行为吗?

提前致谢!

编辑

这是我的设置:

BluetoothGattService gattService = new BluetoothGattService(
    serviceUUID, BluetoothGattService.SERVICE_TYPE_PRIMARY);
gattService.addCharacteristic(new BluetoothGattCharacteristic(
    charReadUUID,
    BluetoothGattCharacteristic.PROPERTY_READ,
    BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED_MITM
));
gattService.addCharacteristic(new BluetoothGattCharacteristic(
    charWriteUUID,
    BluetoothGattCharacteristic.PROPERTY_WRITE,
    BluetoothGattCharacteristic.PERMISSION_WRITE_ENCRYPTED_MITM
));
gattServer.addService(gattService);

...

AdvertiseSettings settings = new AdvertiseSettings.Builder()
    .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED)
    .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
    .setConnectable(true)
    .build();

AdvertiseData data = new AdvertiseData.Builder()
    .setIncludeTxPowerLevel(false)
    .addServiceUuid(serviceUUID)
    .build();

BluetoothLeAdvertiser advertiser = adaper.getBluetoothLeAdvertiser()
advertiser.startAdvertising(settings, data, callback);

总结:将客户端的 I/O 能力设置为 "Keyboard Only"。

解释:

我不完全确定你的系统 "under the hood" 发生了什么。但我可以告诉您根据 BLE CoreSpec 应该发生什么。首先参见 CoreSpec V4.2,Vol。 3,H 部分,第一章。 2.3.5.1,table 2.7 和 2.8。根据身份验证要求和设备的 I/O 功能,定义了使用哪种配对。

你想要的描述为"Passkey Entry: responder displays, initiator inputs"。如果使用传统配对(根据蓝牙 V4.0 配对),并且如果:

  • 服务器(响应者)有一个显示 AND
  • 客户端(发起者)有键盘并且
  • 服务器和客户端并非都具有显示器和键盘。

(并且如果不使用OOB数据并且强制执行MITM,但我假设这是给定的。)请注意,如果客户端和服务器都有显示器和键盘,则默认情况是客户端显示和服务器输入.似乎如果您的协议自动处理配对,它也会自动选择 CoreSpec 中定义的配对方法。

所以你看到的是对应不同服务器不同的I/O能力。看起来你的客户端有显示器和键盘,所以如果你使用带有显示器和键盘的服务器,客户端将显示密码,响应者将等待输入(适合你的情况 1)。对于案例 2,我们有数值比较;这只有在客户端和服务器都支持 LE 安全连接(根据蓝牙 V4.2 配对)时才有可能。

对于情况3,我不知道是怎么回事,但可能是Android系统和iOS系统之间的问题不能很好地协同工作(但我没有知道为什么)。

由于这里的配对似乎是完全自动化的,唯一可能改变的是改变 I/O 功能。应该有一个功能来更改这些功能,请查看您的手册。如果您不想在客户端上使用显示,请将其 I/O 功能设置为 "Keyboard Only",它将表现出您期望的行为。(*)

(*) 这仅在您使用传统配对时成立。如果两个设备都支持 LE 安全连接,建议您使用这个更新的配对协议,因为它消除了旧协议的安全问题。 (但是我会假设在这种情况下,无论如何都会自动使用较新的协议。)