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!