This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Errors after unpairing devices and further attempts to bond them

I built and run Bluetooth: Peripheral HIDS keyboard example on nRF52840 DK using nRF Connect SDK 1.3.0. I connected and bonded with it from an Android phone. Then I deleted bond information from the Android phone. After it, I wanted to connect and bond again. And it worked properly. Great! It was BT_SECURITY_L4. You can see UART logs below.

*** Booting Zephyr OS build v2.3.0-rc1-ncs1  ***
Starting Bluetooth Peripheral HIDS keyboard example
I: 8 Sectors of 4096 bytes
I: alloc wra: 0, fa0
I: data wra: 0, f4
I: HW Platform: Nordic Semiconductor (0x0002)
I: HW Variant: nRF52x (0x0002)
I: Firmware: Standard Bluetooth controller (0x00) Version 2.3 Build 0
I: No ID address. App must call settings_load()
Bluetooth initialized
E: set-value failure. key: bt/name error(-2)
I: Identity: d6:c4:f9:a2:02:ad (random)
I: HCI: version 5.2 (0x0b) revision 0x0000, manufacturer 0x05f1
I: LMP: version 5.2 (0x0b) subver 0xffff
NFC configuration start
NFC configuration done
Advertising successfully started
Advertising continued
Connected 20:47:da:12:f4:e8 (public)
Passkey for 20:47:da:12:f4:e8 (public): 800540
Press Button 1 to confirm, Button 2 to reject.
Numeric Match, conn 0x2000177c
Key report send error: -13
Security changed: 20:47:da:12:f4:e8 (public) level 4
Pairing completed: 20:47:da:12:f4:e8 (public), bonded: 1
Disconnected from 20:47:da:12:f4:e8 (public) (reason 19)
Advertising successfully started
Advertising continued
Connected 20:47:da:12:f4:e8 (public)
Passkey for 20:47:da:12:f4:e8 (public): 379671
Press Button 1 to confirm, Button 2 to reject.
Numeric Match, conn 0x2000177c
Security changed: 20:47:da:12:f4:e8 (public) level 4
Pairing completed: 20:47:da:12:f4:e8 (public), bonded: 1
Disconnected from 20:47:da:12:f4:e8 (public) (reason 19)


Now I want to do the same with BT_SECURITY_L2 without any numeric comparison. What should I do? I set passkey_display and passkey_confirm callbacks to NULL:

static struct bt_conn_auth_cb conn_auth_callbacks = {
	.passkey_display = NULL,
	.passkey_confirm = NULL,
	.cancel = auth_cancel,
	.pairing_confirm = pairing_confirm,
#if CONFIG_NFC_OOB_PAIRING
	.oob_data_request = auth_oob_data_request,
#endif
	.pairing_complete = pairing_complete,
	.pairing_failed = pairing_failed
};


Is it right?

And I built and run the program. And I did the same steps of connecting/disconnecting and bonding/deleting bond information twice. And you can see in below UART logs that I couldn't bond the second time:

Security failed: 20:47:da:12:f4:e8 (public) level 1 err 4
Pairing failed conn: 20:47:da:12:f4:e8 (public), reason 4

*** Booting Zephyr OS build v2.3.0-rc1-ncs1  ***
Starting Bluetooth Peripheral HIDS keyboard example
I: 8 Sectors of 4096 bytes
I: alloc wra: 0, ff0
I: data wra: 0, 0
I: HW Platform: Nordic Semiconductor (0x0002)
I: HW Variant: nRF52x (0x0002)
I: Firmware: Standard Bluetooth controller (0x00) Version 2.3 Build 0
I: No ID address. App must call settings_load()
Bluetooth initialized
I: Identity: d6:c4:f9:a2:02:ad (random)
I: HCI: version 5.2 (0x0b) revision 0x0000, manufacturer 0x05f1
I: LMP: version 5.2 (0x0b) subver 0xffff
NFC configuration start
NFC configuration done
Advertising successfully started
Advertising continued
Connected 48:ef:30:6f:b3:db (random)
Pairing confirmed: 48:ef:30:6f:b3:db (random)
Security changed: 48:ef:30:6f:b3:db (random) level 2
Pairing completed: 20:47:da:12:f4:e8 (public), bonded: 1
Disconnected from 20:47:da:12:f4:e8 (public) (reason 19)
Advertising successfully started
Advertising continued
Connected 20:47:da:12:f4:e8 (public)
Security failed: 20:47:da:12:f4:e8 (public) level 1 err 4
Pairing failed conn: 20:47:da:12:f4:e8 (public), reason 4
Disconnected from 20:47:da:12:f4:e8 (public) (reason 19)

Logs from nRF Connect SDK:

nRF Connect, 2020-08-07
Nordic_HIDS_keyboard (D6:C4:F9:A2:02:AD)
V	02:32:15.042	Connecting to D6:C4:F9:A2:02:AD...
D	02:32:15.042	gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)
D	02:32:15.922	[Callback] Connection state changed with status: 0 and new state: CONNECTED (2)
I	02:32:15.922	Connected to D6:C4:F9:A2:02:AD
D	02:32:15.922	[Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED
V	02:32:15.946	Discovering services...
D	02:32:15.946	gatt.discoverServices()
D	02:32:15.954	[Callback] Services discovered with status: 0
I	02:32:15.954	Services discovered
V	02:32:15.991	Generic Attribute (0x1801)
- Service Changed [I] (0x2A05)
   Client Characteristic Configuration (0x2902)
- Client Supported Features [R W] (0x2B29)
- Database Hash [R] (0x2B2A)
Generic Access (0x1800)
- Device Name [R] (0x2A00)
- Appearance [R] (0x2A01)
- Peripheral Preferred Connection Parameters [R] (0x2A04)
Battery Service (0x180F)
- Battery Level [N R] (0x2A19)
   Client Characteristic Configuration (0x2902)
Device Information (0x180A)
- Model Number String [R] (0x2A24)
- Manufacturer Name String [R] (0x2A29)
- PnP ID [R] (0x2A50)
Human Interface Device (0x1812)
- Protocol Mode [R WNR] (0x2A4E)
- Report [N R] (0x2A4D)
   Client Characteristic Configuration (0x2902)
   Report Reference (0x2908)
- Report [R W WNR] (0x2A4D)
   Report Reference (0x2908)
- Report Map [R] (0x2A4B)
- Boot Keyboard Input Report [N R] (0x2A22)
   Client Characteristic Configuration (0x2902)
- Boot Keyboard Output Report [R W WNR] (0x2A32)
- HID Information [R] (0x2A4A)
- HID Control Point [WNR] (0x2A4C)
D	02:32:15.991	gatt.setCharacteristicNotification(00002a05-0000-1000-8000-00805f9b34fb, true)
D	02:32:15.993	gatt.setCharacteristicNotification(00002a19-0000-1000-8000-00805f9b34fb, true)
D	02:32:15.994	gatt.setCharacteristicNotification(00002a4d-0000-1000-8000-00805f9b34fb, true)
D	02:32:15.995	gatt.setCharacteristicNotification(00002a22-0000-1000-8000-00805f9b34fb, true)
V	02:32:17.786	Starting pairing...
D	02:32:17.786	device.createBond()
D	02:32:17.809	[Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_BONDING (11)
I	02:32:18.619	Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)
D	02:32:19.158	[Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_BONDED (12)
I	02:32:19.158	Device bonded
I	02:32:19.696	Connection parameters updated (interval: 45.0ms, latency: 0, timeout: 5000ms)
I	02:32:21.226	Connection parameters updated (interval: 45.0ms, latency: 0, timeout: 420ms)
V	02:32:28.559	Removing bond information...
D	02:32:28.559	device.removeBond() (hidden)
D	02:32:28.608	[Callback] Connection state changed with status: 22 and new state: DISCONNECTED (0)
E	02:32:28.609	Error 22 (0x16): GATT CONN TERMINATE LOCAL HOST
I	02:32:28.609	Disconnected
D	02:32:28.628	[Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED
D	02:32:29.218	[Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_NONE (10)
I	02:32:29.218	Bond information deleted
D	02:32:36.404	gatt.close()
D	02:32:36.406	wait(200)
V	02:32:36.608	Connecting to D6:C4:F9:A2:02:AD...
D	02:32:36.608	gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)
D	02:32:37.564	[Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED
D	02:32:37.569	[Callback] Connection state changed with status: 0 and new state: CONNECTED (2)
I	02:32:37.569	Connected to D6:C4:F9:A2:02:AD
V	02:32:37.594	Discovering services...
D	02:32:37.594	gatt.discoverServices()
D	02:32:37.601	[Callback] Services discovered with status: 0
I	02:32:37.601	Services discovered
V	02:32:37.617	Generic Attribute (0x1801)
- Service Changed [I] (0x2A05)
   Client Characteristic Configuration (0x2902)
- Client Supported Features [R W] (0x2B29)
- Database Hash [R] (0x2B2A)
Generic Access (0x1800)
- Device Name [R] (0x2A00)
- Appearance [R] (0x2A01)
- Peripheral Preferred Connection Parameters [R] (0x2A04)
Battery Service (0x180F)
- Battery Level [N R] (0x2A19)
   Client Characteristic Configuration (0x2902)
Device Information (0x180A)
- Model Number String [R] (0x2A24)
- Manufacturer Name String [R] (0x2A29)
- PnP ID [R] (0x2A50)
Human Interface Device (0x1812)
- Protocol Mode [R WNR] (0x2A4E)
- Report [N R] (0x2A4D)
   Client Characteristic Configuration (0x2902)
   Report Reference (0x2908)
- Report [R W WNR] (0x2A4D)
   Report Reference (0x2908)
- Report Map [R] (0x2A4B)
- Boot Keyboard Input Report [N R] (0x2A22)
   Client Characteristic Configuration (0x2902)
- Boot Keyboard Output Report [R W WNR] (0x2A32)
- HID Information [R] (0x2A4A)
- HID Control Point [WNR] (0x2A4C)
D	02:32:37.617	gatt.setCharacteristicNotification(00002a05-0000-1000-8000-00805f9b34fb, true)
D	02:32:37.619	gatt.setCharacteristicNotification(00002a19-0000-1000-8000-00805f9b34fb, true)
D	02:32:37.621	gatt.setCharacteristicNotification(00002a4d-0000-1000-8000-00805f9b34fb, true)
D	02:32:37.624	gatt.setCharacteristicNotification(00002a22-0000-1000-8000-00805f9b34fb, true)
V	02:32:40.512	Starting pairing...
D	02:32:40.512	device.createBond()
D	02:32:40.541	[Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_BONDING (11)
D	02:32:40.589	[Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_NONE (10)
I	02:32:40.589	Bonding failed
I	02:32:41.072	Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)
D	02:32:43.644	[Callback] Connection state changed with status: 22 and new state: DISCONNECTED (0)
E	02:32:43.644	Error 22 (0x16): GATT CONN TERMINATE LOCAL HOST
I	02:32:43.644	Disconnected
D	02:32:43.708	[Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED

As I understood, I had to add unpairing on the side of peripherals. And I added bt_unpair(BT_ID_DEFAULT, BT_ADDR_LE_ANY) call in a disconnected callback. Then I built and run the program again and I tried the same steps of connecting/disconnecting and bonding/deleting bond information twice. And everything worked fine!

So, I want to ask you about the unpairing stage. In which callback should I call bt_unpair function?

Is there a way to distinguish ordinary disconnection from deleting bond information on a remote device? I think that no. So, I want to ask how to properly avoid the error with the second attempt to bond, when there's not a numeric comparison. It's an ordinary case when the bond information was deleted on the remote device and it tries to connect the second time. So I have to handle such bonding properly. Please, explain to me, how to cope with it.

Why don't provided examples have such unpairing functions?

And why did a security level changed to 1 during the second bonding without calling bt_unpair function, although it was 2 after the first attempt?

Thank you in advance for any assistance!

Related