Hello Nordic Team,
I am working with the nRF5340 Audio DK as a central device, trying to establish a secure connection using Security Level 4 (128-bit encryption with LE Secure Connections).
My goal is to ensure the central device enforces LESC (LE Secure Connections) with 128-bit encryption, but I am facing two major issues when connecting to different peripherals:
Issue 1: Security Level 4 Fails on Connection with Another nRF5340 board
When using another nRF5340 board as a peripheral, running the inbuilt nRF Audio Server code, the connection is established successfully. However, when I attempt to set Security Level 4, it fails with error .
[00:00:12.813,354] <inf> main: Received Command: connect 73:08:D0:98:FC:BD [00:00:12.813,446] <inf> main: Attempting to connect to 73:08:D0:98:FC:BD... [00:00:12.916,320] <inf> main: Connection initiated index : 0 [00:00:12.994,049] <inf> main: MTU exchanged: 23/23 [00:00:12.994,171] <inf> main: Connected: 73:08:D0:98:FC:BD (random) (index 0) Security level: 1 [00:00:13.196,289] <err> main: Security failed: 73:08:D0:98:FC:BD (random) level 1 err (4) [00:00:13.196,319] <inf> main: Pairing Failed (4). Disconnecting. [00:00:13.296,417] <inf> main: disconnect index : 0 [00:00:13.296,508] <inf> main: Disconnected: 73:08:D0:98:FC:BD (random), reason 0x16 (BT_HCI_ERR_LOCALHOST_TERM_CONN) Disconnected: (err 22 BT_HCI_ERR_LOCALHOST_TERM_CONN)
in nrf340_audio code i have change prj.conf file and add following config.
CONFIG_BT=y CONFIG_BT_SMP=y CONFIG_BT_BONDABLE=y CONFIG_BT_SMP_SC_PAIR_ONLY=y CONFIG_BT_PRIVACY=y
- Why does Security Level 4 fail with error 234?
- Are there additional configurations needed for enforcing LE Secure Connections (128-bit encryption with LTK)?
- Is there a way to debug or confirm why the encryption upgrade fails?
Issue 2: Connection Fails with Headset (Peripheral) - BT_HCI_ERR_UNKNOWN_CONN_ID
When attempting to connect to a headset as a peripheral, the connection fails with error 2 (BT_HCI_ERR_UNKNOWN_CONN_ID
):
[00:00:36.785,827] <inf> main: Received Command: connect 7E:32:87:8B:18:4F [00:00:36.785,919] <inf> main: Attempting to connect to 7E:32:87:8B:18:4F... [00:00:36.886,810] <inf> main: Connection initiated index : 0 [00:00:37.846,679] <wrn> bt_hci_core: Connection creation timeout triggered [00:00:37.846,832] <err> main: Failed to connect to 7E:32:87:8B:18:4F (random) (err 2: BT_HCI_ERR_UNKNOWN_CONN_ID) ERROR: Failed to connect (err 2 BT_HCI_ERR_UNKNOWN_CONN_ID)
- Why does the connection timeout and fail with
BT_HCI_ERR_UNKNOWN_CONN_ID
? - Do I need to manually set pairing parameters for headset support?
- Is this issue related to Security Level 4 enforcement, or is it purely a connection establishment issue?
and also security level is not work .
Central-Side Configuration & Code
prj.conf (Security Settings for Central)
CONFIG_BT=y CONFIG_LOG=y CONFIG_BT_CENTRAL=y CONFIG_BT_AUDIO=y CONFIG_BT_ISO_TX_BUF_COUNT=4 # Support an ISO channel per ASE CONFIG_BT_ISO_MAX_CHAN=4 CONFIG_BT_KEYS_OVERWRITE_OLDEST=y CONFIG_BT_HCI=y CONFIG_BT_EXT_ADV=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y CONFIG_UART_ASYNC_API=y # Security Connection(Level 4 - Authenticated Secure Connections and 128-bit key ) CONFIG_BT=y CONFIG_BT_SMP=y CONFIG_BT_BONDABLE=y CONFIG_BT_SMP_SC_PAIR_ONLY=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP_APP_PAIRING_ACCEPT=y #Converts a HCI error to string CONFIG_BT_HCI_ERR_TO_STR=y CONFIG_NRFX_UARTE1=y CONFIG_BT_MAX_CONN=5 CONFIG_BT_DEVICE_NAME="NRF5340_AUDIO_CLIENT" CONFIG_MAIN_STACK_SIZE=8192 CONFIG_IDLE_STACK_SIZE=1024 CONFIG_ISR_STACK_SIZE=4096 CONFIG_LOG_BUFFER_SIZE=2048 CONFIG_BT_SCAN_WITH_IDENTITY=y CONFIG_BT_CONN_CHECK_NULL_BEFORE_CREATE=y CONFIG_GPIO=y CONFIG_PWM=y
Central-Side Connection Code
static struct bt_conn *default_conn; /* Callback function when connection is established */ static void connected_cb(struct bt_conn *conn, uint8_t err) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); if (err) { LOG_ERR("Failed to connect to %s (err %d: %s)\n", addr, err, bt_hci_err_to_str(err)); return; } default_conn = bt_conn_ref(conn); LOG_INF("Connected: %s\n", addr); /* Get current security level */ uint8_t sec_level = bt_conn_get_security(conn); printk("Security level: %d\n", sec_level); /* Attempt to set security level to 4 */ err = bt_conn_set_security(conn, BT_SECURITY_L4); if (err) { LOG_ERR("Security Level 4 failed, error code: %d", err); } } /* Callback function when connection is disconnected */ static void disconnected_cb(struct bt_conn *conn, uint8_t reason) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); if (default_conn) { bt_conn_unref(default_conn); default_conn = NULL; } LOG_INF("Disconnected: %s, reason 0x%02x (%s)\n", addr, reason, bt_hci_err_to_str(reason)); } /* Callback function when identity is resolved */ static void identity_resolved_cb(struct bt_conn *conn, const bt_addr_le_t *rpa, const bt_addr_le_t *identity) { char addr_identity[BT_ADDR_LE_STR_LEN]; char addr_rpa[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(identity, addr_identity, sizeof(addr_identity)); bt_addr_le_to_str(rpa, addr_rpa, sizeof(addr_rpa)); LOG_INF("Identity resolved %s -> %s\n", addr_rpa, addr_identity); } /* Callback function when security level changes */ static void security_changed_cb(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_ERR("Security failed: %s level %u err %s(%d)\n", addr, level, bt_security_err_to_str(err), err); } else { LOG_INF("Security changed: %s level %u\n", addr, level); } } /* Connection callbacks */ static struct bt_conn_cb conn_callbacks = { .connected = connected_cb, .disconnected = disconnected_cb, .identity_resolved = identity_resolved_cb, .security_changed = security_changed_cb, }; /* Handle pairing success */ static void auth_pairing_complete_cb(struct bt_conn *conn, bool bonded) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); LOG_INF("Pairing complete with %s (Bonded: %s)\n", addr, bonded ? "Yes" : "No"); uint8_t sec_level = bt_conn_get_security(conn); if (sec_level == 4) { printk("Secure Connections (Level 4) established\n"); } else { printk("Security level: %d\n", sec_level); } } /* Handle pairing failure */ static void auth_pairing_failed_cb(struct bt_conn *conn, enum bt_security_err reason) { LOG_INF("Pairing Failed (%d). Disconnecting.\n", reason); bt_conn_disconnect(conn, BT_HCI_ERR_AUTH_FAIL); } /* Callback function for bond deletion */ static void auth_bond_deleted_cb(uint8_t id, const bt_addr_le_t *peer) { LOG_INF("Bond Information Deleted\n"); } /* Bluetooth authentication info callback structure */ static struct bt_conn_auth_info_cb auth_info_callbacks = { .pairing_complete = auth_pairing_complete_cb, .pairing_failed = auth_pairing_failed_cb, .bond_deleted = auth_bond_deleted_cb, }; /* Callback when ATT MTU is updated */ static void att_mtu_updated(struct bt_conn *conn, uint16_t tx, uint16_t rx) { LOG_INF("MTU exchanged: %u/%u\n", tx, rx); } /* GATT callbacks */ static struct bt_gatt_cb gatt_callbacks = { .att_mtu_updated = att_mtu_updated, }; /* Function to handle pairing accept */ static enum bt_security_err auth_pairing_accept_cb(struct bt_conn *conn, const struct bt_conn_pairing_feat *const feat) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); printk("Pairing accept for %s\n", addr); /* Accept pairing */ return BT_SECURITY_ERR_SUCCESS; } /* Function to handle pairing confirmation */ static void auth_pairing_confirm_cb(struct bt_conn *conn) { LOG_INF("Pairing Confirm\n"); bt_conn_auth_pairing_confirm(conn); } /* Function to handle passkey confirmation */ static void auth_passkey_confirm_cb(struct bt_conn *conn, uint32_t passkey) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); printk("Passkey confirmation for %s with passkey %u\n", addr, passkey); /* Confirm passkey */ bt_conn_auth_passkey_confirm(conn); } /* Function to display passkey */ static void auth_passkey_display_cb(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: %06u\n", addr, passkey); } /* Function to handle pairing cancellation */ static void auth_cancel_cb(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: %s\n", addr); } /* Define the authentication callbacks structure */ static struct bt_conn_auth_cb auth_cb_callbacks = { .pairing_accept = auth_pairing_accept_cb, .pairing_confirm = auth_pairing_confirm_cb, .passkey_confirm = auth_passkey_confirm_cb, .passkey_display = auth_passkey_display_cb, .cancel = auth_cancel_cb, };
My ultimate aim is to ensure that my central device always connects using Security Level 4, which requires:
LE Secure Connections (LESC)
128-bit encryption using Long-Term Key (LTK)
MITM protection enabled
My Key Questions:
- Are my configurations correct for enforcing Security Level 4?
- What additional steps or configurations are needed to make it work with both peripherals?
- How can I debug or ensure that both devices negotiate LE Secure Connections properly?
I would greatly appreciate any insights, recommendations, or debugging steps to resolve these issues.
Thank you for your time and support!