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 Reply
  • 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

Children
Related