Bonding Troubles

I've been working for months to try and figure out exactly how to get my application to bond the way I want it to.

I'm using nrf connect sdk 2.4.2 on an nrf52832.  I used the nordic uart service peripheral project as a base.  The uart service works great but I'm having a great amount of difficulty adding any measure of security to the project.

I would like the device to behave like this:

  1. Only permit usage of application characteristics (TX and RX) when bonded with the connected phone
  2. Only permit bonding when a user presses a button on the device
  3. When bonding is started do not present a passcode dialog to the user on the phone

I gather the best way to do this is something like the following though i've tried many permutations:

prj.conf:

CONFIG_BT_NUS_SECURITY_ENABLED=y
CONFIG_BT_NUS_AUTHEN=y
CONFIG_BT_SMP_APP_PAIRING_ACCEPT=n
CONFIG_BT_SMP=y
CONFIG_BT_FIXED_PASSKEY=n
CONFIG_BT_BONDABLE=y
CONFIG_BT_KEYS_OVERWRITE_OLDEST=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_DEBUG_SMP=y
CONFIG_BT_SMP_ENFORCE_MITM=n
CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE=y
main.c:
{
static void connected(struct bt_conn *conn, uint8_t err)

    char addr[BT_ADDR_LE_STR_LEN];

    if (err) {
        LOG_ERR("Connection failed (err %u)", err);
        return;
    }

    connection_status = TRUE;
    current_conn = bt_conn_ref(conn);

    bt_conn_set_security(current_conn, BT_SECURITY_L2);
    if (err) {
        LOG_ERR("Failed to set security: %d", err);
    }
   
    exchange_mtu(conn);

    bt_conn_le_param_update(conn, &conn_params);
}
struct bt_conn_auth_cb conn_auth_callbacks = {
#if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
    .pairing_accept = NULL,
#endif
    .passkey_display = NULL,
#if defined(CONFIG_BT_PASSKEY_KEYPRESS)
    .passkey_display_keypress = NULL,
#endif
    .passkey_entry = NULL,
    .passkey_confirm = NULL,
    .oob_data_request = NULL,
    .cancel = auth_cancel,
    .pairing_confirm = auth_pairing_confirm,
#if defined(CONFIG_BT_BREDR)
    .pincode_entry = NULL,
#endif
};
 
static void auth_pairing_confirm(struct bt_conn *conn)
{
    LOG_ERR("Pairing confirmation requested");
    auth_conn = bt_conn_ref(conn);
    awaiting_pairing_confirm = true;
    pair_timeout = PAIR_TIMEOUT_INIT;
}
Then I've implemented a button press I'm sure is working:
void gpio_callback_function(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    if(auth_conn)
    {
        if (awaiting_pairing_confirm) {
            bt_conn_auth_pairing_confirm(auth_conn);
            bt_conn_unref(auth_conn);
            auth_conn = NULL;
            awaiting_pairing_confirm = false;
            pair_timeout = PAIR_TIMEOUT_INIT;
            // Stop LED indication if any
        }
    }
}

Results:
When using this setup the phone still shows a passcode on it that is meant to be entered on the device and I see that upon entering security level 2 the device immediately disconnects.  I believe the security level change is necessary to protect the tx and rx characteristics and to match the settings I already made in the prj.conf though I've tried disabling that as well and it doesn't improve bonding.   Here is a log I have taken:

00> [00:00:08.972,015] <inf> bt_hci_core: hci_vs_init: HW Variant: nRF52x (0x0002)
00> [00:00:08.972,045] <inf> bt_hci_core: hci_vs_init: Firmware: Standard Bluetooth controller (0x00) Version 224.11902 Build 2231721665
00> [00:00:08.972,503] <dbg> bt_smp: bt_smp_init: LE SC enabled
00> [00:00:08.972,900] <inf> bt_hci_core: bt_init: No ID address. App must call settings_load()
00> [00:00:08.972,930] <inf> peripheral_uart: sys_init: Bluetooth initialized
00> [00:00:08.976,593] <inf> bt_hci_core: bt_dev_show_info: Identity: D9:9D:3A:4F:B5:5D (random)
00> [00:00:08.976,654] <inf> bt_hci_core: bt_dev_show_info: HCI: version 5.4 (0x0d) revision 0x1077, manufacturer 0x0059
00> [00:00:08.976,684] <inf> bt_hci_core: bt_dev_show_info: LMP: version 5.4 (0x0d) subver 0x1077
00> [00:00:09.009,796] <dbg> bt_smp: bt_smp_pkey_ready:
00> [00:00:22.874,633] <dbg> bt_smp: bt_smp_accept: conn 0x20002460 handle 0
00> [00:00:22.874,664] <dbg> bt_smp: bt_smp_connected: chan 0x20002828 cid 0x0006
00> [00:00:22.877,380] <dbg> bt_smp: smp_send_security_req:
00> [00:00:22.877,868] <dbg> bt_smp: smp_init: prnd 60b6727878064e85c9b81dcdd5327006
00> [00:00:22.878,173] <inf> peripheral_uart: connected: Connected 74:74:46:D6:E9:45 (public)
00> [00:00:23.068,756] <dbg> bt_smp: bt_smp_recv: Received SMP code 0x01 len 6
00> [00:00:23.068,786] <dbg> bt_smp: smp_pairing_req: req: io_capability 0x04, oob_flag 0x00, auth_req 0x2D, max_key_size 0x10, init_key_dist 0x0F, resp_key_dist 0x0F
00> [00:00:23.068,817] <dbg> bt_smp: smp_pairing_complete: got status 0x3
00> [00:00:23.068,847] <dbg> bt_smp: bt_smp_encrypt_change: chan 0x20002828 conn 0x20002460 handle 0 encrypt 0x00 hci status 0x1f
00> [00:00:23.069,061] <wrn> peripheral_uart: security_changed: Security failed: 74:74:46:D6:E9:45 (public) level 1 err 4
00> [00:00:23.069,244] <inf> peripheral_uart: pairing_failed: Pairing failed conn: 74:74:46:D6:E9:45 (public), reason 4
00> [00:00:23.113,555] <inf> peripheral_uart: exchange_func: MTU exchange done 498
00> [00:00:35.813,995] <dbg> bt_smp: bt_smp_disconnected: chan 0x20002828 cid 0x0006
00> [00:00:35.814,392] <inf> peripheral_uart: disconnected: Disconnected: 74:74:46:D6:E9:45 (public) (reason 19)
00> [00:00:37.795,745] <dbg> bt_smp: bt_smp_accept: conn 0x20002460 handle 0
00> [00:00:37.795,776] <dbg> bt_smp: bt_smp_connected: chan 0x20002828 cid 0x0006
00> [00:00:37.798,461] <dbg> bt_smp: smp_send_security_req:
00> [00:00:37.798,980] <dbg> bt_smp: smp_init: prnd fa720263f0156e232722fea23591b8cd
Any help would be much appreciated.  I feel like I've looked everywhere to try and find a solution but I'm just not finding the information I need.
Thanks in advance!
Related