Hello,
It is generally recommended to let the central initiate the pairing request, or at least, give it a chance to send it first. From the "Accessory Design
Guidelines for Apple Devices" document:
40.10 Pairing
The accessory should not request pairing until an ATT request is rejected using the Insufficient
Authentication error code. See the Bluetooth 4.0 specification, Volume 3, Part F, Section 4 for details.
If, for security reasons, the accessory requires a bonded relationship with the Central, the Peripheral
should reject the ATT request using the Insufficient Authentication error code, as appropriate. As a
result, the device may proceed with the necessary security procedures.
Similarly, if the device acts as a Central and a GATT server, it may reject an ATT request using the
Insufficient Authentication error code. The accessory should initiate the security procedure for pairing
in response.
Pairing may require user authorization depending on device. Once an accessory is paired with a device,
it shall retain the distributed keys of both central and peripheral for future use. If the pairing is no longer
required, the accessory shall delete both sets of keys.
The Insufficient Authentication error code is returned when the GATT client tries to read a characteristic that has the security level set to a level that requires authentication. The user will automatically get a pairing popup if they use iOS.
Characteristic read and write permissions (i.e. security level) is configured when you initialize the service. Like here for the HIDS service: https://github.com/nrfconnect/sdk-nrf/blob/35f91d3151abfaddf60d826ed87c91cfa81773a5/subsys/bluetooth/services/hids.c#L751
But to answer your question, it should be possible to issue a security request from the peripheral by calling the bt_conn_set_security() function, or by enabling the CONFIG_BT_GATT_AUTO_SEC_REQ option.
Best regards,
Vidar
Hello,
It is generally recommended to let the central initiate the pairing request, or at least, give it a chance to send it first. From the "Accessory Design
Guidelines for Apple Devices" document:
40.10 Pairing
The accessory should not request pairing until an ATT request is rejected using the Insufficient
Authentication error code. See the Bluetooth 4.0 specification, Volume 3, Part F, Section 4 for details.
If, for security reasons, the accessory requires a bonded relationship with the Central, the Peripheral
should reject the ATT request using the Insufficient Authentication error code, as appropriate. As a
result, the device may proceed with the necessary security procedures.
Similarly, if the device acts as a Central and a GATT server, it may reject an ATT request using the
Insufficient Authentication error code. The accessory should initiate the security procedure for pairing
in response.
Pairing may require user authorization depending on device. Once an accessory is paired with a device,
it shall retain the distributed keys of both central and peripheral for future use. If the pairing is no longer
required, the accessory shall delete both sets of keys.
The Insufficient Authentication error code is returned when the GATT client tries to read a characteristic that has the security level set to a level that requires authentication. The user will automatically get a pairing popup if they use iOS.
Characteristic read and write permissions (i.e. security level) is configured when you initialize the service. Like here for the HIDS service: https://github.com/nrfconnect/sdk-nrf/blob/35f91d3151abfaddf60d826ed87c91cfa81773a5/subsys/bluetooth/services/hids.c#L751
But to answer your question, it should be possible to issue a security request from the peripheral by calling the bt_conn_set_security() function, or by enabling the CONFIG_BT_GATT_AUTO_SEC_REQ option.
Best regards,
Vidar
Thank you, Vidar, just one clarification, I initiate pairing from Central to Peripheral. By using bt_conn_set_security() I can upgrade the security level and that causes pairing_complete callback to be called. So, that's good, thank you.
But I have a new issue. I have a test suite that I'm running in a loop : Central connects to a Peripheral, Central initiates pairing, pairing successfully completes, Central does some characteristics read/write and then disconnects. This process is run in a loop. My problem is, after the first run, pairing never completes, ie I never see pairing_complete callback being called. So I'm guessing that I need to do something else to clear old pairing info. Any idea how I can do that ?
Many thanks,
E.
Thanks for the clarification and sorry for delayed response. The reason you are not getting the pairing_complete callback on the subsequent connections is that the pairing procedure is only performed in the first connection. The other connections will be secured with the encryption key that was exchanged during pairing.
You can register the "security changed" callback if you want to monitor when the link becomes secured in both cases (i.e. after pairing or encryption with existing keys):
Here is how the callback is used in our central uart sample for reference: https://github.com/nrfconnect/sdk-nrf/blob/7848293244a0904cb401f13f420bf610d7aa8e91/samples/bluetooth/central_uart/src/main.c#L425
The other connections will be secured with the encryption key that was exchanged during pairing.
Is that because these two devices are bonded ? I don't want them to be bonded, I want to trigger and restart pairing process every time . Is there a way of doing this ?
I see. In that case you can add CONFIG_BT_BONDABLE=n to your project, or call bt_set_bondable('false') on startup.
Thank you, I did that, but overall pairing seems to be very unreliable. Many times it fails with unspecified reason.
But before that getting into details with pairing, connections have been pretty undeterministic, too. I have a Central which issues a connect to a Peripheral, many times Central comes back with disconnected callback with reason BT_HCI_ERR_CONN_FAIL_TO_ESTAB. So, do you have any recommendations to make connections more reliable ? Any parameters to tweak ? Why would it keep disconnecting with BT_HCI_ERR_CONN_FAIL_TO_ESTAB reason ?