non-bondable pairing in nrf-connect sdk

Hello, 

I'm trying to configure the BLE stack as non-bondable pairing only so that it requires pairing by every time the smartphone tries to connect to the device (the bonding is not required). I changed the prj.config and the code, but it seems to work with iPhone but not with Android. 

My modifications 

In prj.config

CONFIG_BT_MAX_CONN=1
CONFIG_BT_MAX_PAIRED=1
CONFIG_BT_TEST_SECURITY_ENABLED=y
CONFIG_BT_TEST_AUTHEN=y
CONFIG_BT_SMP=y
CONFIG_BT_FIXED_PASSKEY=y
CONFIG_BLE_PASSKEY=123456
CONFIG_BT_BONDABLE=n

Code snapshot.

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

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	LOG_INF("Connected %s", addr);
	ble.current_conn = bt_conn_ref(conn);
	state_set(STATE_BLE_CONNECTED);
}

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

	LOG_INF("Disconnected: %s (reason %u)", addr, reason);
	bt_unpair(BT_ID_DEFAULT, NULL);

	if (ble.auth_conn) {
		bt_conn_unref(ble.auth_conn);
		ble.auth_conn = NULL;
	}
	
	if (ble.current_conn) {
		bt_conn_unref(ble.current_conn);
		ble.current_conn = NULL;
	}
	 state_set(STATE_BLE_DISCONNECTED);
	
}

static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param)
{
	//If acceptable params, return true, otherwise return false.
	return true; 
}

static void le_param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, uint16_t timeout)
{
	struct bt_conn_info info; 
	char addr[BT_ADDR_LE_STR_LEN];
	
	if(bt_conn_get_info(conn, &info))
	{
		LOG_INF("Could not parse connection info\n");
	}
	else
	{
		bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
		
		// LOG_("Connection parameters updated!	\n\
		// Connected to: %s						\n\
		// New Connection Interval: %u				\n\
		// New Slave Latency: %u					\n\
		// New Connection Supervisory Timeout: %u	\n"
		// , addr, info.le.interval, info.le.latency, info.le.timeout);
	}
}


#ifdef CONFIG_BT_TEST_SECURITY_ENABLED
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) {
		LOG_INF("Security changed: %s level %u", addr, level);
	} else {
		LOG_WRN("Security failed: %s level %u err %d", addr,
			level, err);
	}
}
#endif

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected          = connected,
	.disconnected       = disconnected,
	.le_param_req		= le_param_req,
	.le_param_updated	= le_param_updated,
#ifdef CONFIG_BT_TEST_SECURITY_ENABLED
	.security_changed = security_changed,
#endif
};

#if defined(CONFIG_BT_TEST_SECURITY_ENABLED)
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));

	LOG_INF("Passkey for %s: %06u", addr, passkey);
}

static void auth_passkey_confirm(struct bt_conn *conn, unsigned int passkey)
{
	char addr[BT_ADDR_LE_STR_LEN];

	ble.auth_conn = bt_conn_ref(conn);

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

	LOG_INF("Passkey for %s: %06u", addr, passkey);
	LOG_INF("Press Button 1 to confirm, Button 2 to reject.");
}


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

	LOG_INF("Pairing cancelled: %s", addr);
}

static void pairing_confirm(struct bt_conn *conn)
{
	bt_conn_auth_cancel(conn);
}

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

	LOG_INF("Pairing completed: %s, bonded: %d", 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));

	LOG_INF("Pairing failed conn: %s, reason %d", addr, reason);
}


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

static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
	.pairing_complete = pairing_complete,
	.pairing_failed = pairing_failed,
};
#else
static struct bt_conn_auth_cb conn_auth_callbacks;
static struct bt_conn_auth_info_cb conn_auth_info_callbacks;
#endif



#ifdef CONFIG_BT_TEST_SECURITY_ENABLED
static void num_comp_reply(bool accept)
{
	if (accept) {
		bt_conn_auth_passkey_confirm(ble.auth_conn);
		LOG_INF("Numeric Match, conn %p", (void *)ble.auth_conn);
	} else {
		bt_conn_auth_cancel(ble.auth_conn);
		LOG_INF("Numeric Reject, conn %p", (void *)ble.auth_conn);
	}

	bt_conn_unref(ble.auth_conn);
	ble.auth_conn = NULL;
}

#endif /* CONFIG_BT_TEST_SECURITY_ENABLED */


/**************************************************************************//**
 * @brief Initialize BLE.
 *****************************************************************************/
int ble_enable() {
	
	int blink_status = 0;
	int err = 0;

	if (IS_ENABLED(CONFIG_BT_TEST_SECURITY_ENABLED)) {
		err = bt_conn_auth_cb_register(&conn_auth_callbacks);
		if (err) {
			LOG_ERR("Failed to register authorization callbacks.");
			return;
		}

		err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
		if (err) {
			LOG_ERR("Failed to register authorization info callbacks.");
			return;
		}
	}

	bt_set_bondable(false);
	bt_passkey_set(CONFIG_BLE_PASSKEY);

	err = bt_enable(NULL);
	if (err) {
		error();
	}

	LOG_INF("Bluetooth initialized");

	k_sem_give(&ble_init_ok);

	if (IS_ENABLED(CONFIG_SETTINGS)) {
		settings_load();
	}

	err = bt_test_init(&test_cb);
	if (err) {
		LOG_ERR("Failed to initialize UART service (err: %d)", err);
		return;
	}

	err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd,
			      ARRAY_SIZE(sd));
	if (err) {
		LOG_ERR("Advertising failed to start (err %d)", err);
		return;
	}
	return 0;
}

Could you please tell me what else I need to modify or change to get it working on Android? 

Current behavior on Android phones.

My first connection works fine ( it requires pairing ) but the second connection doesn't require the pairing key so it fails since the hardware executes by every disconnect  (

bt_unpair) bc, I want the user enters Passkey by every time the connection is established. 

. It seems that the android phone thinks that it has the right authentication keys  (the second time) so it fails and deletes those keys after failing. Afterward, the third connection works fine and it requires again the pairing key. so result the one connection works second one does not and so on. 

Thanks in advance! 

Tools: 

SDK: 2.2
hardware: nrf53

Parents Reply Children
No Data
Related