Exercise 1

Add pairing support to a Bluetooth LE application

In this exercise, we will start with a version of the Bluetooth Peripheral LBS sample that does not have any security support. This is similar to the application we created in Lesson 4 Exercises 1 and 2, where we created our own custom LED Button Service. All characteristics of the service are open and anyone can read and write to them without any encryption. This also means anyone with a sniffer can follow the connection and read the exchanged data.

We will start by adding the encryption requirement to a LED characteristic’s write permission. Then, we will add pairing support to the application and practice encrypting the link to be able to write to the LED characteristic.

The second part of the exercise focuses on increasing the security level to have man-in-the-middle protection, i.e security level 3 and 4. We will add a display callback to display the passkey in the log output so that we can see the passkey and enter the key to the phone. This way, the end user can ensure that they are pairing to the correct device.

Exercise steps

In the GitHub repository for this course, go to the base code for this exercise, found in lesson5/blefund_less5_exer1.

This is a slightly modified version of the Peripheral LBS sample in nRF Connect SDK. lbs.c and lbs.h have been moved from the original SDK folder into the applications src folder.

1. Add a security requirement to the LED characteristic

1.1 Change the LED characteristic permission to require encryption

In the declaration of the LED characteristic, add encryption requirement by changing BT_GATT_PERM_WRITE to BT_GATT_PERM_WRITE_ENCRYPT.

This will change the security level requirement from level 1 to level 2.

Change the following code in lbs.c

BT_GATT_CHARACTERISTIC(BT_UUID_LBS_LED,
			       BT_GATT_CHRC_WRITE,
			       BT_GATT_PERM_WRITE_ENCRYPT,
			       NULL, write_led, NULL),

2. Build and flash the application to the board.

3. Try to write to the LED characteristic.

In nRF Connect for Mobile, connect to the device Nordic_LBS. Try to write to the LED characteristic to turn it on, as we have done in previous exercises. Notice that the LED (LED3) on the board does not react. This is because the characteristic now requires encryption, but the firmware does not have pairing support. The phone may terminate the connection because of this.

Let’s add pairing support to the firmware.

4. Add the Security Management Protocol layer to the Bluetooth LE stack.

The Kconfig symbol CONFIG_BT_SMP will add the Security manager Protocol to the Bluetooth LE stack, which is the layer that makes it possible to pair devices over Bluetooth LE.

Add the following line to the prj.conf file

CONFIG_BT_SMP=y

5. Add a callback function for when the security level of the connection has changed.

Recall the connection callback structure struct bt_conn_cb that we used in the previous exercises. Let’s add a callback for the security_changed event as well.

5.1 Add the security_changed member to the callback structure

Add the following line in main.c

.security_changed = on_security_changed,

5.2 Define the callback function on_security_changed().

We want this callback function to display the current security level of the connection and inform if the link has been encrypted successfully or not.

Add the following code in main.c

static void on_security_changed(struct bt_conn *conn, bt_security_t level,
			     enum bt_security_err err)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	if (!err) {
		LOG_INF("Security changed: %s level %un", addr, level);
	} else {
		LOG_INF("Security failed: %s level %u err %dn", addr, level,
			err);
	}
}

6. Build and flash the application to the board.

Open up a terminal to see the log output from the application, which we will need to get the passkey.

Just like in previous exercises, you can go to Visual Studio Code and select the COM port for the device.

7. Try to write to the LED characteristic.

In nRF Connect for Mobile, connect to the device Nordic_LBS. Try to write to the LED characteristic to turn it on.

Now verify that a pairing pop-up Window appears after you select Write.

Android
iOS

Select Pair to accept the pairing and the LED characteristic should now be possible to control. The Bluetooth LE link is now encrypted.

In the log, you should see the security level updated to level 2 in the UART log:

8. Change the LED characteristic permission to require pairing with authentication

In the declaration of the LED characteristic, add the authentication requirement by changing BT_GATT_PERM_WRITE_ENCRYPT to BT_GATT_PERM_WRITE_AUTHEN.

Change the following code in lbs.c

BT_GATT_CHARACTERISTIC(BT_UUID_LBS_LED,
			       BT_GATT_CHRC_WRITE,
			       BT_GATT_PERM_WRITE_AUTHEN,
			       NULL, write_led, NULL),

This will increase the security level of the write permission of this characteristic from level 2 to level 3 or 4, depending in whether you are using legacy pairing or LE Secure Connections.

At this stage, even though you would still be able to pair with the board, the phone wouldn’t be able to control the LED. This is because the security level of the application doesn’t meet the requirement of the characteristic permission.

9. Define authentication callback functions

We have the authenticated pairing callback structure struct bt_conn_auth_cb with numerous members. In our case, we will only add two.

9.1 Define the callback function auth_passkey_display

Let’s define a function for the passkey_display event, which has the following signature

This will print the passkey needed for the central (your phone) to pair with the peripheral (the board).

Add the following code in main.c

static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey)
{
	char addr[BT_ADDR_LE_STR_LEN];
	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	LOG_INF("Passkey for %s: %06un", addr, passkey);
}

9.2 Define the callback function auth_cancel

Let’s define a function for the cancel event, which has the following signature

This will let us know when the pairing has been cancelled.

Add the following code in main.c

static void auth_cancel(struct bt_conn *conn)
{
	char addr[BT_ADDR_LE_STR_LEN];
	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	LOG_INF("Pairing cancelled: %sn", addr);
}

9.3 Declare the authenticated pairing callback structure struct bt_conn_auth_cb.

Let’s now declare the callback structure with the two member functions that we created in the previous steps.

Add the following code to main.c

static struct bt_conn_auth_cb conn_auth_callbacks = {
	.passkey_display = auth_passkey_display,
	.cancel = auth_cancel,
};

10. Register the authentication callbacks.

Add the following code in main.c

err = bt_conn_auth_cb_register(&conn_auth_callbacks);
if (err) {
	LOG_INF("Failed to register authorization callbacks.n");
	return;
}

The application now fulfills the requirements of pairing with MITM authetnication needed for security level 3 or level 4.

11. Build and flash the application on the board.

11.1 Make sure you select Erase And Flash To Board, to remove the previous bonding information.

11.2 Remove the bond information from your phone.

On the phone, you would need to remove the bond information of the device as well.

Android

Go to your Bluetooth settings, find the device and select the pin wheel next to it. Then select Unpair.

iOS

Go to your Bluetooth settings, find the device and select the information icon next to it. Then select Forget This Device.

12. Use your phone to connect the device and prompt the pairing request by writing to the LED characteristic.

As we have done previously, use nRF Connect for Mobile to connect to the device. Then try to write to the LED characteristic and the pairing pop-up window should appear, now with a PIN request.

Android
iOS

The passkey, a 6-digit randomly generated number, will be in the log output from the device. You will need to type this passkey to the pop-up window on the phone.

In the log output below, the passkey is 043166.

If you enter the passkey correctly, the phone and the device will pair successfully and you will be able to control the LED.

Verify in the log output that you now have security level 3 (for legacy pairing) or 4 (for LE Secure Connections).

Register an account
Already have an account? Log in
(All fields are required unless specified optional)

  • 8 or more characters
  • Upper and lower case letters
  • At least one number or special character

Forgot your password?
Enter the email associated with your account, and we will send you a link to reset your password.