Security failed level 1 err 9 connecting error with bonded device

Hi all!

I'm developing a BLE device implementing automation IO profile, peripheral role.

I can connect normally and discover all services and characteristics from nRF Connect android app, but after bonding, I never can connect again, I receive 

Security failed: 3C:CD:5D:3F:DC:50 (public) level 1 err 9
Disconnected (reason 61)

Am I missing something? Do I need to manually save bond information?

My code is the following:

#include <zephyr/zephyr.h>
#include <zephyr/logging/log.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/settings/settings.h>

#include <device.h>
#include <drivers/flash.h>
#include <storage/flash_map.h>
#include <fs/nvs.h>

#include <stdio.h>
#include <string.h>

#include "../cfg/config.h"
#include "ble.h"

#include <zephyr/kernel.h>
#include <zephyr/sys/reboot.h>
#include <zephyr/sys/printk.h>
#include <inttypes.h>

LOG_MODULE_REGISTER(ble);

static void ccc_changed(const struct bt_gatt_attr *attr, uint16_t value) {
}

static ssize_t uart_tx_chr_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) {
	return 0;
}

static ssize_t uart_rx_chr_write(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, uint16_t len, uint16_t offset, uint8_t flags){
	return 0;
}

static ssize_t device_name_chr_write(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, uint16_t len, uint16_t offset, uint8_t flags){

	char prueba[100] = {};
	memcpy(prueba, buf, len);
	printk("Nuevo nombre: %s\n", prueba);

	return 0;
}

/* Custom service variables */
#define BT_UUID_SERVER_UART BT_UUID_128_ENCODE(0x0003CDD0, 0x0000, 0x1000, 0x8000, 0x00805f9b0131)
static struct bt_uuid_128 server_uart_tx_uuid = BT_UUID_INIT_128(
	BT_UUID_128_ENCODE(0x0003CDD1, 0x0000, 0x1000, 0x8000, 0x00805f9b0131));
static struct bt_uuid_128 server_uart_rx_uuid = BT_UUID_INIT_128(
	BT_UUID_128_ENCODE(0x0003CDD2, 0x0000, 0x1000, 0x8000, 0x00805f9b0131));

static const uint8_t device_name[] = DEF_BLE_NAME;
static struct bt_uuid_16 automation_io_uuid = BT_UUID_INIT_16( 0x1815 );
static struct bt_uuid_16 device_name_uuid = BT_UUID_INIT_16( BT_UUID_GAP_DEVICE_NAME_VAL );

/* UART custom service declaration */
BT_GATT_SERVICE_DEFINE(automation_io_svc,
	BT_GATT_PRIMARY_SERVICE(&automation_io_uuid),
	BT_GATT_CHARACTERISTIC(&device_name_uuid.uuid,
			       BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY,
				   BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
				   NULL, device_name_chr_write, NULL
				   ),		   
	BT_GATT_CHARACTERISTIC(&server_uart_tx_uuid.uuid,
			       BT_GATT_CHRC_NOTIFY,
				   BT_GATT_PERM_READ,
				   uart_tx_chr_read, NULL, NULL
				   ),		   
	BT_GATT_CCC(ccc_changed,
		    BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),				   
	BT_GATT_CHARACTERISTIC(&server_uart_rx_uuid.uuid,
			       BT_GATT_CHRC_WRITE_WITHOUT_RESP,
				   BT_GATT_PERM_WRITE,
				   NULL, uart_rx_chr_write, NULL
				   ),
);

static struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
	BT_DATA(BT_DATA_NAME_COMPLETE, device_name, sizeof(device_name)-1),
    BT_DATA(BT_DATA_UUID16_ALL, &automation_io_uuid.val, sizeof(automation_io_uuid.val)),
};

static void connected(struct bt_conn *conn, uint8_t err)
{
	if (err) {
		printk("Connection failed (err %u)\n", err);
		return;
	}

	printk("Connected\n");
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	printk("Disconnected (reason %u)\n", reason);
}

static void 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) {
		printk("Security changed: %s level %u\n", addr, level);
	} else {
		printk("Security failed: %s level %u err %d\n", addr, level,
			err);
	}
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected        = connected,
	.disconnected     = disconnected,
	.security_changed = security_changed,
};

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));

	printk("Passkey for %s: %06u\n", addr, passkey);
}

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));

	printk("Pairing cancelled: %s\n", addr);
}

static void pairing_complete(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));

	printk("Pairing completed: %s, bonded: %d\n", addr, bonded);
}

static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
{
	char addr[BT_ADDR_LE_STR_LEN];

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

	printk("Pairing failed conn: %s, reason %d\n", addr, reason);
}

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

static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
	.pairing_complete = pairing_complete,
	.pairing_failed = pairing_failed
};

int ble_init(void) {
    int err;
	LOG_INF("%s", "Starting BLE");

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

	err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
	if (err) {
		printk("Failed to register authorization info callbacks.\n");
		return -1;
	}

 	err = bt_enable(NULL);
	if (err) {
		LOG_ERR("%s", "BLE enable error");
		return -1;
	}
	else {
		LOG_INF("%s", "Bluetooth initialized");
	}

	if (IS_ENABLED(CONFIG_SETTINGS)) {
		settings_load();
		LOG_INF("%s", "Settings loaded");
	}

	/* Start advertising  */
	err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
	if (err) {
		LOG_ERR("Advertising failed to start (err %d)", err);
		return -1;
	}

	return 0;
}

Thanks!

Pedro.

Parents
  • Hi Pedro,

    Are you able to upload your project so I can try to reproduce the error on my end? The pairing fails because the link is encrypted/decrypted incorrectly, which is unusual error. The bonding information should be stored to flash automatically be the Zephyr host. 

    Best regards,

    Vidar

  • Hi Vidar,

    Attached to this post you can find the project. 

    Thanks for your help!

    ble-io-bridge-periph.zip

    Edit: I'm using ncs 2.0.2

  • Hi Vidar,

    Thanks for the modified fw! I've tested it and got same error when trying to connect after bonding.

    Security failed: 3C:CD:5D:3F:DC:50 (public) level 1 err 9
    Disconnected (reason 61)

    But I discovered the problem was the mobile phone! (A Huawei P20 Pro). Even rebooting phone, reinstalling nRF Connect app, deleting bondings... didn't work. I tried with another phones (1 iphone and 2 android) and worked perfectly.

    Why can this be happening?

    Thank you very much for your help. Now I'm using another phone to do tests and all is working fine. 

  • Hi Pedro,

    It is good to know that you are not seeing this issue with other phones. But I haven't found any known interoperability issues in our database for this particular phone that should affect pairing. Do you have a nRF52 DK board to test with? It would be interesting to know if you experienced the same pairing error with other SDK samples. 

    Best regards,

    Vidar

  • Hi Vidar,

    I tested ble-io-bridge-periph-mod.zip with a nRF52 DK (nRF52832) and same problem occurs with a Huawei P20 pro. I hope this info helps you. If you need I do more test just ask me.

    Kind regards, 

    Pedro.

  • Hi Pedro,

    What I meant to suggest was that you try pairing with an entirely different application to see if it results in the same error. This might help narrow down the problem. It's possible that the issue might be timing related somehow.

    Attached is a precompiled hex for the HID keyboard example from nRF5 SDK 17.1.0 which you may try.

    1055.ble_app_hids_keyboard_pca10040_s132.hex

    You can use nrfjprog to program it:

    $ nrfjprog --program ble_app_hids_keyboard_pca10040_s132.hex --chiperase --verify -r

    Kind regards,

    Vidar

  • Hi Vidar,

    I tested your precompiled example in nRF52 DK and Huawei P20 pro and it works perfectly. After bonding I can connect and disconnect manually, and also when I reset nRF52 DK, it connects automatically to phone.

    Kind regards,

    Pedro

    Edit: I tried with HIDS Keyboard sample in NCS 2.0.2 and does not work after bonding. Same security problem occurs. It keeps trying to connect in a loop, throwing this error:

    Connected 3C:CD:5D:3F:DC:50 (public)
    Advertising successfully started
    Security failed: 3C:CD:5D:3F:DC:50 (public) level 1 err 9
    Disconnected from 3C:CD:5D:3F:DC:50 (public) (reason 61)
    Advertising continued
    Connected 3C:CD:5D:3F:DC:50 (public)
    Advertising successfully started
    Security failed: 3C:CD:5D:3F:DC:50 (public) level 1 err 9
    Disconnected from 3C:CD:5D:3F:DC:50 (public) (reason 61)
    Advertising continued
    Connected 3C:CD:5D:3F:DC:50 (public)
    Advertising successfully started
    Security failed: 3C:CD:5D:3F:DC:50 (public) level 1 err 9
    Disconnected from 3C:CD:5D:3F:DC:50 (public) (reason 61)
    Advertising continued

Reply
  • Hi Vidar,

    I tested your precompiled example in nRF52 DK and Huawei P20 pro and it works perfectly. After bonding I can connect and disconnect manually, and also when I reset nRF52 DK, it connects automatically to phone.

    Kind regards,

    Pedro

    Edit: I tried with HIDS Keyboard sample in NCS 2.0.2 and does not work after bonding. Same security problem occurs. It keeps trying to connect in a loop, throwing this error:

    Connected 3C:CD:5D:3F:DC:50 (public)
    Advertising successfully started
    Security failed: 3C:CD:5D:3F:DC:50 (public) level 1 err 9
    Disconnected from 3C:CD:5D:3F:DC:50 (public) (reason 61)
    Advertising continued
    Connected 3C:CD:5D:3F:DC:50 (public)
    Advertising successfully started
    Security failed: 3C:CD:5D:3F:DC:50 (public) level 1 err 9
    Disconnected from 3C:CD:5D:3F:DC:50 (public) (reason 61)
    Advertising continued
    Connected 3C:CD:5D:3F:DC:50 (public)
    Advertising successfully started
    Security failed: 3C:CD:5D:3F:DC:50 (public) level 1 err 9
    Disconnected from 3C:CD:5D:3F:DC:50 (public) (reason 61)
    Advertising continued

Children
Related