Bonded Bluetooth Pairing in Zephyr
Mar, 05 2022
In the previous post, we discussed the difference between connecting with your device and pairing with your device. In this tutorial, we'll cover how to implement "just works" Bluetooth Low Energy pairing in Zephyr on an nRF52.
I'll assume that you have already implemented a custom peripheral as described in this post.
If not, you can clone the git repo and start from there.
First, we'll need to add some additional lines in our
prj.conf file. Add the following lines:
prj.conf file should match with this one.
Next, head over to your custom service (
src/services/led_service.c) and change some of the characteristic's configuration settings. Replace the BT_GATT_SERVICE_DEFINE macro with the following:
You'll notice that the only thing that changed from the previous service definition is the
BT_GATT_PERM_WRITE flags. They are now set to
BT_GATT_PERM_WRITE_ENCRYPT. Changing this flag prompts iOS to initiate system pairing when trying to write an encrypted characteristic.
led_service.c file should now match mine.
Head on over to
src/main.c and find the
bt_conn_cb structure defined as
conn_callbacks. Replace its definition with the following:
Now we'll need to define the
security_changed callback. Let's do that now, just above the
Next we'll need to add a few pairing specific callbacks. Just underneath the
conn_callbacks definition, add the following code:
Similar to the
conn_callbacks, we now have a
bt_conn_auth_cb struct which takes a number of callbacks related to Bluetooth pairing state changes.
Take note of the
.passkey_confirm properties. Setting these to
NULL is what makes the pairing scheme "just works" rather than something more strict. If your peripheral device has a keypad or display available during pairing, here is where you would interface with them.
Next, in the
bt_ready function, just underneath the
bt_conn_cb_register(&conn_callbacks) call, let's register our
Just beneath the register call we now need to load our settings:
To make this call, we'll need to pull in the settings library. Add the following header to the top of your
Finally, there's a helpful debugging call to make in your
main function after you initialize your Bluetooth stack:
This deletes pairing information from your peripheral device after each re-boot. This will help us avoid any errors when you choose "forget device" on your central (iOS or Android device), thus preventing our peripheral from referencing the outdated encryption information.
Double check that your
main.c looks like mine.
You can check out the finished git repo here.