1
votes

I implemented a GATT Server and Client App on Android. The connection is working and I forced pairing by adding PERMISSION_READ/WRITE_ENCRYPTED_MITM to all of the GattCharacteristics.

But the pairing behavior differs on different clients:

1) Pin is shown on the client/central (Android 5 on Samsung Galaxy S3) and should be insert on the server/peripheral (Android 7 on Nexus 5).

2) Passkey is shown on both devices client/central (Android 5 on Samsung Galaxy S3) and server/peripheral (Android 6 on Nexus 7)

3) Pairing with Windows or iOS fails with server/peripheral expecing a pin for input.

What I expected and want to happen is:

Pin is shown on the server/peripheral and has to be insert on client/central

Is there any way to configure that behavior?

Thanks in advance!

EDIT

Here is my setup:

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);
1
For 2), are you sure you run BLE and not Bluetooth Classic? According to Bluetooth 4.1 specification, the case when both roles have a display and a keyboard, the initiator should display and the responder input.Emil
Yes, I am using BluetoothLeAdvertiser and BluetoothGattServer class. I'll add some code.Myon
Is it really possible to force pairing by adding MITM requirement to all characteristics? I would expect that this only leads to an "insufficient encryption" error if pairing is not done. Normally, the necessity of pairing and the type of pairing is determined from authentication requirements (where a flag for MITM protection must be set if you want MITM-safe encryption) and IO capabilities of both devices.Thern
Solved the problem on Windows. There is a default code "000000" that has to be entered.Myon
Were you able to change the I/O capabilities on an Android? I have a similar problem and want to know how to make my phone "Keyboard Only"Tyler

1 Answers

3
votes

Summary: Set the I/O Capabilites of your client to "Keyboard Only".

Explanation:

I am not fully sure what happens "under the hood" of your system. But I can tell you what should be happening according to the BLE CoreSpec. First see CoreSpec V4.2, Vol. 3, Part H, chap. 2.3.5.1, table 2.7 & 2.8. There it is defined which pairing is used, depending on the authentication requirements and the I/O capabilities of the devices.

What you want is described as "Passkey Entry: responder displays, initiator inputs". This is the case if legacy pairing (pairing according to Bluetooth V4.0) is used, and if:

  • the server (responder) has a display AND
  • the client (initiator) has a keyboard AND
  • server and client do NOT both have display AND keyboard.

(And if OOB data is not used and MITM is enforced, but I assume this as given.) Note that if both client and server have display and keyboard, the default case is that the client displays and the server inputs. It would seem that if your protocol automatically handles pairing, it will also automatically chose the pairing method as defined in the CoreSpec.

So what you see is corresponding to different I/O capabilities of different servers. It seems that your client has display and keyboard, so if you use a server with display and keyboard, the client will display the passkey and the responder will wait for input (which fits to your case 1). For case 2, we have Numeric Comparison; this is only possible if LE Secure Connections (pairing according to Bluetooth V4.2) is supported by both client and server.

For case 3, I don't know what is going on, but it may be a problem between an Android system and an iOS system not operating well together (but I have no idea why).

Since pairing seems to be fully automized here, the only possibility to change things is to change the I/O capabilities. There should be a function to change these capabilities, check your manual. If you do not want to use a display on the client, set its I/O capabilities to "Keyboard Only" and it will exhibit the behavior you expect.(*)

(*) This holds only if you use legacy pairing. If both devices support LE Secure Connections, it is recommended that you use this newer pairing protocol, since it removes security issues with the old protocol. (I would however assume that in this case, the newer protocol is used automatically anyway.)