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 安全连接,建议您使用这个更新的配对协议,因为它消除了旧协议的安全问题。 (但是我会假设在这种情况下,无论如何都会自动使用较新的协议。)
我在 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 安全连接,建议您使用这个更新的配对协议,因为它消除了旧协议的安全问题。 (但是我会假设在这种情况下,无论如何都会自动使用较新的协议。)