<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/105551/forget-about-connection-after-disconnection</link><description>I have the peripheral_hids_mouse as starting point. I work on nRF52 DK with latest v2.5.0 toolchain. 
 
 The peripheral is supposed to maintains several connections to different centrals. I want to be able to &amp;#39;remove&amp;#39; connections from the peripheral to</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 04 Dec 2023 09:06:16 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/105551/forget-about-connection-after-disconnection" /><item><title>RE: Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/thread/458679?ContentTypeID=1</link><pubDate>Mon, 04 Dec 2023 09:06:16 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6db7be61-ac3b-48bb-8f1b-99017ec39ea4</guid><dc:creator>Susheel Nuguru</dc:creator><description>[quote user="mirmit"]However, I would expect the nRF to not allows such connection, as I unpair it from the central.[/quote]
&lt;p&gt;Any BLE connectable advertiser&amp;nbsp;cannot stop any scanner to send a connect request. Even unpaired devices can connect on the non encrypted link to the advertiser. In the peripheral after the connection is made, the peripheral can chose to disconnect from the central on other conditions.&lt;/p&gt;
&lt;p&gt;Advertisers wont accept connect requests from central only of they do directed advertising meant for some other centrals.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/thread/458404?ContentTypeID=1</link><pubDate>Thu, 30 Nov 2023 20:38:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:eb3541c4-feca-47d5-b661-37c5605f01cf</guid><dc:creator>mirmit</dc:creator><description>&lt;p&gt;Hi Susheel,&lt;/p&gt;
&lt;p&gt;thanks for getting back. I&amp;#39;m not commenting right now, as I&amp;#39;m still struggling with setting up the BLS Sniffer on my setup (I cannot see the nRF Sniffer in Wireshark...).&lt;/p&gt;
&lt;p&gt;The nRF strat advertising, as I just freed one connection slot with the unpairing from the central initiated by the peripheral. It is in a configuration wher I could decide to connect to a different Central.&lt;/p&gt;
&lt;p&gt;the Central is, in this case a PC on Windows 11, but could be an Android device. I understand the Central&amp;nbsp; want to reconnect to the peripheral and it still&amp;nbsp; knows all the info to revive the connection, as if the periferal went away and then come back in reachable zone.&lt;/p&gt;
&lt;p&gt;However, I would expect the nRF to not allows such connection, as I unpair it from the central.&lt;/p&gt;
&lt;p&gt;Hope this clarifies a bit the use case.&lt;/p&gt;
&lt;p&gt;Thanks,&lt;br /&gt;Alexandre&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/thread/457679?ContentTypeID=1</link><pubDate>Mon, 27 Nov 2023 18:36:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:af5afd6f-a2f2-4ff8-97c8-17d759628e77</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;Hi Alexandre,&lt;/p&gt;
&lt;p&gt;It looks like it is the central that is trying to connect to this advertiser because your device seems to be doing normal advertising. From the log, I see this&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;Disconnected from 38:68:93:65:7B:73 (public) (reason 19)
Regular advertising started&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;When your peripheral device is doing undirected advertising with connectable packets, then you cannot stop central from connecting and the central can initiate to pairing again. It is best to understand what your central is doing aswell. Do you have a sniffer log of the air packet transactions to see what is happening after the disconnect and which side of the devices are initiating what procedure?&lt;/p&gt;
[quote user="mirmit"]Is there a way to clean up the persistent connection list? [/quote]
&lt;p&gt;I do not think that there is any additional persistent list&amp;nbsp; maintained within the peripheral after you do bt_unpair successfully for the correct connection.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/thread/457166?ContentTypeID=1</link><pubDate>Thu, 23 Nov 2023 12:59:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:69cdec71-7817-4b0e-bc6e-9fb3a91a6e14</guid><dc:creator>mirmit</dc:creator><description>&lt;p&gt;Hi Simon,&lt;/p&gt;
&lt;p&gt;Attached the code with the log. You will notice some changes from Nordic hids mouse sample to handle the disconnection.&lt;/p&gt;
&lt;p&gt;I notice the regular advertising is not looping anymore when the Central explicitly disconnect.&lt;/p&gt;
&lt;p&gt;On a side note, I had hard time restarting from a clean state, where the nRF doesn&amp;#39;t know any connection. Is there a way to clean up the persistent connection list? Is there any docs on the topic of handling this, and potentially how to extend it to also store application data?&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Alexandre&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#include &amp;lt;zephyr/types.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;zephyr/sys/printk.h&amp;gt;
#include &amp;lt;zephyr/sys/byteorder.h&amp;gt;
#include &amp;lt;zephyr/kernel.h&amp;gt;
#include &amp;lt;zephyr/drivers/gpio.h&amp;gt;
#include &amp;lt;soc.h&amp;gt;
#include &amp;lt;assert.h&amp;gt;

#include &amp;lt;zephyr/settings/settings.h&amp;gt;

#include &amp;lt;zephyr/bluetooth/bluetooth.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/hci.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/conn.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/uuid.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/gatt.h&amp;gt;

#include &amp;lt;zephyr/bluetooth/services/bas.h&amp;gt;
#include &amp;lt;bluetooth/services/hids.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/services/dis.h&amp;gt;
#include &amp;lt;dk_buttons_and_leds.h&amp;gt;

#define DEVICE_NAME     CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)

#define BASE_USB_HID_SPEC_VERSION   0x0101

/* Number of pixels by which the cursor is moved when a button is pushed. */
#define MOVEMENT_SPEED              5
/* Number of input reports in this application. */
#define INPUT_REPORT_COUNT          3
/* Length of Mouse Input Report containing button data. */
#define INPUT_REP_BUTTONS_LEN       3
/* Length of Mouse Input Report containing movement data. */
#define INPUT_REP_MOVEMENT_LEN      3
/* Length of Mouse Input Report containing media player data. */
#define INPUT_REP_MEDIA_PLAYER_LEN  1
/* Index of Mouse Input Report containing button data. */
#define INPUT_REP_BUTTONS_INDEX     0
/* Index of Mouse Input Report containing movement data. */
#define INPUT_REP_MOVEMENT_INDEX    1
/* Index of Mouse Input Report containing media player data. */
#define INPUT_REP_MPLAYER_INDEX     2
/* Id of reference to Mouse Input Report containing button data. */
#define INPUT_REP_REF_BUTTONS_ID    1
/* Id of reference to Mouse Input Report containing movement data. */
#define INPUT_REP_REF_MOVEMENT_ID   2
/* Id of reference to Mouse Input Report containing media player data. */
#define INPUT_REP_REF_MPLAYER_ID    3

/* HIDs queue size. */
#define HIDS_QUEUE_SIZE 10

/* Key used to move cursor left */
#define KEY_LEFT_MASK   DK_BTN1_MSK
/* Key used to move cursor right */
#define KEY_RIGHT_MASK  DK_BTN2_MSK
/* Key used to move change client up */
#define KEY_NEXT_MASK     DK_BTN3_MSK
/* Key used to disconnect curent client */
#define KEY_DISCONNECT_MASK   DK_BTN4_MSK

/* Key used to accept or reject passkey value */
#define KEY_PAIRING_ACCEPT DK_BTN1_MSK
#define KEY_PAIRING_REJECT DK_BTN2_MSK

/* HIDS instance. */
BT_HIDS_DEF(hids_obj,
	    INPUT_REP_BUTTONS_LEN,
	    INPUT_REP_MOVEMENT_LEN,
	    INPUT_REP_MEDIA_PLAYER_LEN);

static struct k_work hids_work;
struct mouse_pos {
	int16_t x_val;
	int16_t y_val;
};

/* Mouse movement queue. */
K_MSGQ_DEFINE(hids_queue,
	      sizeof(struct mouse_pos),
	      HIDS_QUEUE_SIZE,
	      4);

#if CONFIG_BT_DIRECTED_ADVERTISING
/* Bonded address queue. */
K_MSGQ_DEFINE(bonds_queue,
	      sizeof(bt_addr_le_t),
	      CONFIG_BT_MAX_PAIRED,
	      4);
#endif

static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_GAP_APPEARANCE,
		      (CONFIG_BT_DEVICE_APPEARANCE &amp;gt;&amp;gt; 0) &amp;amp; 0xff,
		      (CONFIG_BT_DEVICE_APPEARANCE &amp;gt;&amp;gt; 8) &amp;amp; 0xff),
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
	BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_HIDS_VAL),
					  BT_UUID_16_ENCODE(BT_UUID_BAS_VAL)),
};

static const struct bt_data sd[] = {
	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};

static struct conn_mode {
	struct bt_conn *conn;
	bool in_boot_mode;
} conn_mode[CONFIG_BT_HIDS_MAX_CLIENT_COUNT];

static struct k_work adv_work;

static struct k_work pairing_work;
struct pairing_data_mitm {
	struct bt_conn *conn;
	unsigned int passkey;
};

K_MSGQ_DEFINE(mitm_queue,
	      sizeof(struct pairing_data_mitm),
	      CONFIG_BT_HIDS_MAX_CLIENT_COUNT,
	      4);

static size_t current_client = -1;
size_t next_client(size_t current);

#if CONFIG_BT_DIRECTED_ADVERTISING
static void bond_find(const struct bt_bond_info *info, void *user_data)
{
	int err;

	/* Filter already connected peers. */
	for (size_t i = 0; i &amp;lt; CONFIG_BT_HIDS_MAX_CLIENT_COUNT; i++) {
		if (conn_mode[i].conn) {
			const bt_addr_le_t *dst =
				bt_conn_get_dst(conn_mode[i].conn);

			if (!bt_addr_le_cmp(&amp;amp;info-&amp;gt;addr, dst)) {
				return;
			}
		}
	}

	err = k_msgq_put(&amp;amp;bonds_queue, (void *) &amp;amp;info-&amp;gt;addr, K_NO_WAIT);
	if (err) {
		printk(&amp;quot;No space in the queue for the bond.\n&amp;quot;);
	}
}
#endif

static void advertising_continue(void)
{
	struct bt_le_adv_param adv_param;

#if CONFIG_BT_DIRECTED_ADVERTISING
	bt_addr_le_t addr;

	if (!k_msgq_get(&amp;amp;bonds_queue, &amp;amp;addr, K_NO_WAIT)) {
		char addr_buf[BT_ADDR_LE_STR_LEN];

		adv_param = *BT_LE_ADV_CONN_DIR(&amp;amp;addr);
		adv_param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA;

		int err = bt_le_adv_start(&amp;amp;adv_param, NULL, 0, NULL, 0);

		if (err) {
			printk(&amp;quot;Directed advertising failed to start\n&amp;quot;);
			return;
		}

		bt_addr_le_to_str(&amp;amp;addr, addr_buf, BT_ADDR_LE_STR_LEN);
		printk(&amp;quot;Direct advertising to %s started\n&amp;quot;, addr_buf);
	} else
#endif
	{
		int err;

		adv_param = *BT_LE_ADV_CONN;
		adv_param.options |= BT_LE_ADV_OPT_ONE_TIME;
		err = bt_le_adv_start(&amp;amp;adv_param, ad, ARRAY_SIZE(ad),
				  sd, ARRAY_SIZE(sd));
		if (err) {
			printk(&amp;quot;Advertising failed to start (err %d)\n&amp;quot;, err);
			return;
		}

		printk(&amp;quot;Regular advertising started\n&amp;quot;);
	}
}

static void advertising_start(void)
{
#if CONFIG_BT_DIRECTED_ADVERTISING
	k_msgq_purge(&amp;amp;bonds_queue);
	bt_foreach_bond(BT_ID_DEFAULT, bond_find, NULL);
#endif

	k_work_submit(&amp;amp;adv_work);
}

static void advertising_process(struct k_work *work)
{
	advertising_continue();
}

static void pairing_process(struct k_work *work)
{
	int err;
	struct pairing_data_mitm pairing_data;

	char addr[BT_ADDR_LE_STR_LEN];

	err = k_msgq_peek(&amp;amp;mitm_queue, &amp;amp;pairing_data);
	if (err) {
		return;
	}

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

	printk(&amp;quot;Passkey for %s: %06u\n&amp;quot;, addr, pairing_data.passkey);
	printk(&amp;quot;Press Button 1 to confirm, Button 2 to reject.\n&amp;quot;);
}


static void insert_conn_object(struct bt_conn *conn)
{
	for (size_t i = 0; i &amp;lt; CONFIG_BT_HIDS_MAX_CLIENT_COUNT; i++) {
		if (!conn_mode[i].conn) {
			conn_mode[i].conn = conn;
			conn_mode[i].in_boot_mode = false;

			return;
		}
	}

	printk(&amp;quot;Connection object could not be inserted %p\n&amp;quot;, conn);
}


static bool is_conn_slot_free(void)
{
	for (size_t i = 0; i &amp;lt; CONFIG_BT_HIDS_MAX_CLIENT_COUNT; i++) {
		printk(&amp;quot;%s: conn_mode[%d].conn %d\n&amp;quot;, __func__, i, conn_mode[i].conn);
	}

	for (size_t i = 0; i &amp;lt; CONFIG_BT_HIDS_MAX_CLIENT_COUNT; i++) {
		if (!conn_mode[i].conn) {
			return true;
		}
	}
	printk(&amp;quot;%s: all slots used\n&amp;quot;, __func__);

	return false;
}


static void connected(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) {
		if (err == BT_HCI_ERR_ADV_TIMEOUT) {
			printk(&amp;quot;Direct advertising to %s timed out\n&amp;quot;, addr);
			k_work_submit(&amp;amp;adv_work);
		} else {
			printk(&amp;quot;Failed to connect to %s (%u)\n&amp;quot;, addr, err);
		}
		return;
	}

	printk(&amp;quot;Connected %s\n&amp;quot;, addr);

	err = bt_hids_connected(&amp;amp;hids_obj, conn);

	if (err) {
		printk(&amp;quot;Failed to notify HID service about connection\n&amp;quot;);
		return;
	}

	insert_conn_object(conn);

	if (is_conn_slot_free()) {
		advertising_start();
	}
}


static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	int err;
	char addr[BT_ADDR_LE_STR_LEN];

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

	printk(&amp;quot;Disconnected from %s (reason %u)\n&amp;quot;, addr, reason);

	err = bt_hids_disconnected(&amp;amp;hids_obj, conn);

	if (err) {
		printk(&amp;quot;Failed to notify HID service about disconnection\n&amp;quot;);
	}

	for (size_t i = 0; i &amp;lt; CONFIG_BT_HIDS_MAX_CLIENT_COUNT; i++) {
		if (conn_mode[i].conn == conn) {
			conn_mode[i].conn = NULL;
			break;
		}
	}

	advertising_start();
}


#ifdef CONFIG_BT_HIDS_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) {
		printk(&amp;quot;Security changed: %s level %u\n&amp;quot;, addr, level);
	} else {
		printk(&amp;quot;Security failed: %s level %u err %d\n&amp;quot;, addr, level,
			err);
	}
}
#endif


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


static void hids_pm_evt_handler(enum bt_hids_pm_evt evt,
				struct bt_conn *conn)
{
	char addr[BT_ADDR_LE_STR_LEN];
	size_t i;

	for (i = 0; i &amp;lt; CONFIG_BT_HIDS_MAX_CLIENT_COUNT; i++) {
		if (conn_mode[i].conn == conn) {
			break;
		}
	}

	if (i &amp;gt;= CONFIG_BT_HIDS_MAX_CLIENT_COUNT) {
		return;
	}

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

	switch (evt) {
	case BT_HIDS_PM_EVT_BOOT_MODE_ENTERED:
		printk(&amp;quot;Boot mode entered %s\n&amp;quot;, addr);
		conn_mode[i].in_boot_mode = true;
		break;

	case BT_HIDS_PM_EVT_REPORT_MODE_ENTERED:
		printk(&amp;quot;Report mode entered %s\n&amp;quot;, addr);
		conn_mode[i].in_boot_mode = false;
		break;

	default:
		break;
	}
}


static void hid_init(void)
{
	int err;
	struct bt_hids_init_param hids_init_param = { 0 };
	struct bt_hids_inp_rep *hids_inp_rep;
	static const uint8_t mouse_movement_mask[DIV_ROUND_UP(INPUT_REP_MOVEMENT_LEN, 8)] = {0};

	static const uint8_t report_map[] = {
		0x05, 0x01,     /* Usage Page (Generic Desktop) */
		0x09, 0x02,     /* Usage (Mouse) */

		0xA1, 0x01,     /* Collection (Application) */

		/* Report ID 1: Mouse buttons + scroll/pan */
		0x85, 0x01,       /* Report Id 1 */
		0x09, 0x01,       /* Usage (Pointer) */
		0xA1, 0x00,       /* Collection (Physical) */
		0x95, 0x05,       /* Report Count (3) */
		0x75, 0x01,       /* Report Size (1) */
		0x05, 0x09,       /* Usage Page (Buttons) */
		0x19, 0x01,       /* Usage Minimum (01) */
		0x29, 0x05,       /* Usage Maximum (05) */
		0x15, 0x00,       /* Logical Minimum (0) */
		0x25, 0x01,       /* Logical Maximum (1) */
		0x81, 0x02,       /* Input (Data, Variable, Absolute) */
		0x95, 0x01,       /* Report Count (1) */
		0x75, 0x03,       /* Report Size (3) */
		0x81, 0x01,       /* Input (Constant) for padding */
		0x75, 0x08,       /* Report Size (8) */
		0x95, 0x01,       /* Report Count (1) */
		0x05, 0x01,       /* Usage Page (Generic Desktop) */
		0x09, 0x38,       /* Usage (Wheel) */
		0x15, 0x81,       /* Logical Minimum (-127) */
		0x25, 0x7F,       /* Logical Maximum (127) */
		0x81, 0x06,       /* Input (Data, Variable, Relative) */
		0x05, 0x0C,       /* Usage Page (Consumer) */
		0x0A, 0x38, 0x02, /* Usage (AC Pan) */
		0x95, 0x01,       /* Report Count (1) */
		0x81, 0x06,       /* Input (Data,Value,Relative,Bit Field) */
		0xC0,             /* End Collection (Physical) */

		/* Report ID 2: Mouse motion */
		0x85, 0x02,       /* Report Id 2 */
		0x09, 0x01,       /* Usage (Pointer) */
		0xA1, 0x00,       /* Collection (Physical) */
		0x75, 0x0C,       /* Report Size (12) */
		0x95, 0x02,       /* Report Count (2) */
		0x05, 0x01,       /* Usage Page (Generic Desktop) */
		0x09, 0x30,       /* Usage (X) */
		0x09, 0x31,       /* Usage (Y) */
		0x16, 0x01, 0xF8, /* Logical maximum (2047) */
		0x26, 0xFF, 0x07, /* Logical minimum (-2047) */
		0x81, 0x06,       /* Input (Data, Variable, Relative) */
		0xC0,             /* End Collection (Physical) */
		0xC0,             /* End Collection (Application) */

		/* Report ID 3: Advanced buttons */
		0x05, 0x0C,       /* Usage Page (Consumer) */
		0x09, 0x01,       /* Usage (Consumer Control) */
		0xA1, 0x01,       /* Collection (Application) */
		0x85, 0x03,       /* Report Id (3) */
		0x15, 0x00,       /* Logical minimum (0) */
		0x25, 0x01,       /* Logical maximum (1) */
		0x75, 0x01,       /* Report Size (1) */
		0x95, 0x01,       /* Report Count (1) */

		0x09, 0xCD,       /* Usage (Play/Pause) */
		0x81, 0x06,       /* Input (Data,Value,Relative,Bit Field) */
		0x0A, 0x83, 0x01, /* Usage (Consumer Control Configuration) */
		0x81, 0x06,       /* Input (Data,Value,Relative,Bit Field) */
		0x09, 0xB5,       /* Usage (Scan Next Track) */
		0x81, 0x06,       /* Input (Data,Value,Relative,Bit Field) */
		0x09, 0xB6,       /* Usage (Scan Previous Track) */
		0x81, 0x06,       /* Input (Data,Value,Relative,Bit Field) */

		0x09, 0xEA,       /* Usage (Volume Down) */
		0x81, 0x06,       /* Input (Data,Value,Relative,Bit Field) */
		0x09, 0xE9,       /* Usage (Volume Up) */
		0x81, 0x06,       /* Input (Data,Value,Relative,Bit Field) */
		0x0A, 0x25, 0x02, /* Usage (AC Forward) */
		0x81, 0x06,       /* Input (Data,Value,Relative,Bit Field) */
		0x0A, 0x24, 0x02, /* Usage (AC Back) */
		0x81, 0x06,       /* Input (Data,Value,Relative,Bit Field) */
		0xC0              /* End Collection */
	};

	hids_init_param.rep_map.data = report_map;
	hids_init_param.rep_map.size = sizeof(report_map);

	hids_init_param.info.bcd_hid = BASE_USB_HID_SPEC_VERSION;
	hids_init_param.info.b_country_code = 0x00;
	hids_init_param.info.flags = (BT_HIDS_REMOTE_WAKE |
				      BT_HIDS_NORMALLY_CONNECTABLE);

	hids_inp_rep = &amp;amp;hids_init_param.inp_rep_group_init.reports[0];
	hids_inp_rep-&amp;gt;size = INPUT_REP_BUTTONS_LEN;
	hids_inp_rep-&amp;gt;id = INPUT_REP_REF_BUTTONS_ID;
	hids_init_param.inp_rep_group_init.cnt++;

	hids_inp_rep++;
	hids_inp_rep-&amp;gt;size = INPUT_REP_MOVEMENT_LEN;
	hids_inp_rep-&amp;gt;id = INPUT_REP_REF_MOVEMENT_ID;
	hids_inp_rep-&amp;gt;rep_mask = mouse_movement_mask;
	hids_init_param.inp_rep_group_init.cnt++;

	hids_inp_rep++;
	hids_inp_rep-&amp;gt;size = INPUT_REP_MEDIA_PLAYER_LEN;
	hids_inp_rep-&amp;gt;id = INPUT_REP_REF_MPLAYER_ID;
	hids_init_param.inp_rep_group_init.cnt++;

	hids_init_param.is_mouse = true;
	hids_init_param.pm_evt_handler = hids_pm_evt_handler;

	err = bt_hids_init(&amp;amp;hids_obj, &amp;amp;hids_init_param);
	__ASSERT(err == 0, &amp;quot;HIDS initialization failed\n&amp;quot;);
}


static void mouse_movement_send(int16_t x_delta, int16_t y_delta)
{
//	for (size_t i = 0; i &amp;lt; CONFIG_BT_HIDS_MAX_CLIENT_COUNT; i++) {
	size_t i = current_client;
	{

		if (!conn_mode[i].conn) {
//			continue;
			return;
		}

		if (conn_mode[i].in_boot_mode) {
			x_delta = MAX(MIN(x_delta, SCHAR_MAX), SCHAR_MIN);
			y_delta = MAX(MIN(y_delta, SCHAR_MAX), SCHAR_MIN);

			bt_hids_boot_mouse_inp_rep_send(&amp;amp;hids_obj,
							     conn_mode[i].conn,
							     NULL,
							     (int8_t) x_delta,
							     (int8_t) y_delta,
							     NULL);
		} else {
			uint8_t x_buff[2];
			uint8_t y_buff[2];
			uint8_t buffer[INPUT_REP_MOVEMENT_LEN];

			int16_t x = MAX(MIN(x_delta, 0x07ff), -0x07ff);
			int16_t y = MAX(MIN(y_delta, 0x07ff), -0x07ff);

			/* Convert to little-endian. */
			sys_put_le16(x, x_buff);
			sys_put_le16(y, y_buff);

			/* Encode report. */
			BUILD_ASSERT(sizeof(buffer) == 3,
					 &amp;quot;Only 2 axis, 12-bit each, are supported&amp;quot;);

			buffer[0] = x_buff[0];
			buffer[1] = (y_buff[0] &amp;lt;&amp;lt; 4) | (x_buff[1] &amp;amp; 0x0f);
			buffer[2] = (y_buff[1] &amp;lt;&amp;lt; 4) | (y_buff[0] &amp;gt;&amp;gt; 4);


			bt_hids_inp_rep_send(&amp;amp;hids_obj, conn_mode[i].conn,
						  INPUT_REP_MOVEMENT_INDEX,
						  buffer, sizeof(buffer), NULL);
		}
	}
}


static void mouse_handler(struct k_work *work)
{
	struct mouse_pos pos;

	while (!k_msgq_get(&amp;amp;hids_queue, &amp;amp;pos, K_NO_WAIT)) {
		mouse_movement_send(pos.x_val, pos.y_val);
	}
}

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

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


static void auth_passkey_confirm(struct bt_conn *conn, unsigned int passkey)
{
	int err;

	struct pairing_data_mitm pairing_data;

	pairing_data.conn    = bt_conn_ref(conn);
	pairing_data.passkey = passkey;

	err = k_msgq_put(&amp;amp;mitm_queue, &amp;amp;pairing_data, K_NO_WAIT);
	if (err) {
		printk(&amp;quot;Pairing queue is full. Purge previous data.\n&amp;quot;);
	}

	/* In the case of multiple pairing requests, trigger
	 * pairing confirmation which needed user interaction only
	 * once to avoid display information about all devices at
	 * the same time. Passkey confirmation for next devices will
	 * be proccess from queue after handling the earlier ones.
	 */
	if (k_msgq_num_used_get(&amp;amp;mitm_queue) == 1) {
		k_work_submit(&amp;amp;pairing_work);
	}
}


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(&amp;quot;Pairing cancelled: %s\n&amp;quot;, 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(&amp;quot;Pairing completed: %s, bonded: %d\n&amp;quot;, addr, bonded);

	if (current_client == -1) {
		// no client currently connected, connect to the first
		current_client = next_client(current_client);
	}

}


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

	if (k_msgq_peek(&amp;amp;mitm_queue, &amp;amp;pairing_data) != 0) {
		return;
	}

	if (pairing_data.conn == conn) {
		bt_conn_unref(pairing_data.conn);
		k_msgq_get(&amp;amp;mitm_queue, &amp;amp;pairing_data, K_NO_WAIT);
	}

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

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


static struct bt_conn_auth_cb conn_auth_callbacks = {
	.passkey_display = auth_passkey_display,
	.passkey_confirm = auth_passkey_confirm,
	.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 /* defined(CONFIG_BT_HIDS_SECURITY_ENABLED) */


static void num_comp_reply(bool accept)
{
	struct pairing_data_mitm pairing_data;
	struct bt_conn *conn;

	if (k_msgq_get(&amp;amp;mitm_queue, &amp;amp;pairing_data, K_NO_WAIT) != 0) {
		return;
	}

	conn = pairing_data.conn;

	if (accept) {
		bt_conn_auth_passkey_confirm(conn);
		printk(&amp;quot;Numeric Match, conn %p\n&amp;quot;, conn);
	} else {
		bt_conn_auth_cancel(conn);
		printk(&amp;quot;Numeric Reject, conn %p\n&amp;quot;, conn);
	}

	bt_conn_unref(pairing_data.conn);

	if (k_msgq_num_used_get(&amp;amp;mitm_queue)) {
		k_work_submit(&amp;amp;pairing_work);
	}
}


size_t next_client(size_t current)
{
	size_t client = current;
	while (++client &amp;lt; CONFIG_BT_HIDS_MAX_CLIENT_COUNT) {
		if (conn_mode[client].conn) {
			break;
		}
	}

	if (client == CONFIG_BT_HIDS_MAX_CLIENT_COUNT) {
		client = 0;
		while (client &amp;lt; current) {
			if (conn_mode[client].conn) {
				break;
			}
			client ++;
		}
	}
	if (! conn_mode[client].conn) {
		client = -1;
	}

	printk(&amp;quot;%s(): changed connected client from %d to %d\n&amp;quot;, __func__, current, client);
	return client;
}

void button_changed(uint32_t button_state, uint32_t has_changed)
{
	bool data_to_send = false;
	struct mouse_pos pos;
	uint32_t buttons = button_state &amp;amp; has_changed;

	memset(&amp;amp;pos, 0, sizeof(struct mouse_pos));

	if (IS_ENABLED(CONFIG_BT_HIDS_SECURITY_ENABLED)) {
		if (k_msgq_num_used_get(&amp;amp;mitm_queue)) {
			if (buttons &amp;amp; KEY_PAIRING_ACCEPT) {
				num_comp_reply(true);
				printk(&amp;quot;%s(): current client %d\n&amp;quot;, __func__, current_client);
				return;
			}

			if (buttons &amp;amp; KEY_PAIRING_REJECT) {
				num_comp_reply(false);

				return;
			}
		}
	}

	if (buttons &amp;amp; KEY_LEFT_MASK) {
		pos.x_val -= MOVEMENT_SPEED;
		printk(&amp;quot;%s(): left\n&amp;quot;, __func__);
		data_to_send = true;
	}
/*	if (buttons &amp;amp; KEY_UP_MASK) {
		pos.y_val -= MOVEMENT_SPEED;
		printk(&amp;quot;%s(): up\n&amp;quot;, __func__);
		data_to_send = true;
	}
*/	if (buttons &amp;amp; KEY_RIGHT_MASK) {
		pos.x_val += MOVEMENT_SPEED;
		printk(&amp;quot;%s(): right\n&amp;quot;, __func__);
		data_to_send = true;
	}
/*	if (buttons &amp;amp; KEY_DOWN_MASK) {
		pos.y_val += MOVEMENT_SPEED;
		printk(&amp;quot;%s(): down\n&amp;quot;, __func__);
		data_to_send = true;
	}
*/
	if (buttons &amp;amp; KEY_NEXT_MASK) {
		printk(&amp;quot;%s(): next\n&amp;quot;, __func__);
		// switch to next client
		current_client = next_client(current_client);
		char addr[BT_ADDR_LE_STR_LEN];
		bt_addr_le_to_str(bt_conn_get_dst(conn_mode[current_client].conn), addr, sizeof(addr));
		printk(&amp;quot;Changed to : %s\n&amp;quot;, addr);

		return;
	}

	if (buttons &amp;amp; KEY_DISCONNECT_MASK) {
		// discard the current client connection
		printk(&amp;quot;%s(): disconnect\n&amp;quot;, __func__);
		char addr[BT_ADDR_LE_STR_LEN];
		int ret;
		bt_addr_le_to_str(bt_conn_get_dst(conn_mode[current_client].conn), addr, sizeof(addr));
		printk(&amp;quot;Disconnect from : %s\n&amp;quot;, addr);
		ret = bt_conn_disconnect(conn_mode[current_client].conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
		printk(&amp;quot;%s disconnect ret: %d\n&amp;quot;, __func__, ret);
		ret = bt_unpair(BT_ID_DEFAULT, bt_conn_get_dst(conn_mode[current_client].conn));
		printk(&amp;quot;%s unpair ret: %d\n&amp;quot;, __func__, ret);
		current_client = next_client(current_client);
		return;
	}

	if (data_to_send &amp;amp;&amp;amp; current_client != -1) {
		int err;

		err = k_msgq_put(&amp;amp;hids_queue, &amp;amp;pos, K_NO_WAIT);
		if (err) {
			printk(&amp;quot;No space in the queue for button pressed\n&amp;quot;);
			return;
		}
		if (k_msgq_num_used_get(&amp;amp;hids_queue) == 1) {
			k_work_submit(&amp;amp;hids_work);
		}
	}
}


void configure_buttons(void)
{
	int err;

	err = dk_buttons_init(button_changed);
	if (err) {
		printk(&amp;quot;Cannot init buttons (err: %d)\n&amp;quot;, err);
	}
}


static void bas_notify(void)
{
	uint8_t battery_level = bt_bas_get_battery_level();

	battery_level--;

	if (!battery_level) {
		battery_level = 100U;
	}

	bt_bas_set_battery_level(battery_level);
}


int main(void)
{
	int err;

	printk(&amp;quot;Starting Bluetooth Peripheral HIDS mouse example\n&amp;quot;);

	if (IS_ENABLED(CONFIG_BT_HIDS_SECURITY_ENABLED)) {
		err = bt_conn_auth_cb_register(&amp;amp;conn_auth_callbacks);
		if (err) {
			printk(&amp;quot;Failed to register authorization callbacks.\n&amp;quot;);
			return 0;
		}

		err = bt_conn_auth_info_cb_register(&amp;amp;conn_auth_info_callbacks);
		if (err) {
			printk(&amp;quot;Failed to register authorization info callbacks.\n&amp;quot;);
			return 0;
		}
	}

	/* DIS initialized at system boot with SYS_INIT macro. */
	hid_init();

	err = bt_enable(NULL);
	if (err) {
		printk(&amp;quot;Bluetooth init failed (err %d)\n&amp;quot;, err);
		return 0;
	}

	printk(&amp;quot;Bluetooth initialized\n&amp;quot;);

	k_work_init(&amp;amp;hids_work, mouse_handler);
	k_work_init(&amp;amp;adv_work, advertising_process);
	if (IS_ENABLED(CONFIG_BT_HIDS_SECURITY_ENABLED)) {
		k_work_init(&amp;amp;pairing_work, pairing_process);
	}

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

	advertising_start();

	configure_buttons();

	while (1) {
		k_sleep(K_SECONDS(1));
		/* Battery level simulation */
		bas_notify();
	}
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;*** Booting nRF Connect SDK v2.5.0 ***
Starting Bluetooth Peripheral HIDS mouse example
I: 6 Sectors of 4096 bytes
I: alloc wra: 0, f50
I: data wra: 0, 168
I: SoftDevice Controller build revision:
I: c5 93 ba a9 14 4d 8d 05 |.....M..
I: 30 4e 9b 92 d7 71 1e e8 |0N...q..
I: aa 02 50 3c             |..P&amp;lt;
I: HW Platform: Nordic Semiconductor (0x0002)
I: HW Variant: nRF52x (0x0002)
I: Firmware: Standard Bluetooth controller (0x00) Version 197.47763 Build 2370639017
I: No ID address. App must call settings_load()
Bluetooth initialized
I: Identity: EE:67:A1:B1:28:1D (random)
I: HCI: version 5.4 (0x0d) revision 0x1102, manufacturer 0x0059
I: LMP: version 5.4 (0x0d) subver 0x1102
Direct advertising to 38:68:93:65:7B:73 (public) started
Direct advertising to 38:68:93:65:7B:73 (public) timed out
Direct advertising to 00:1D:29:E0:3E:D1 (public) started
Connected 00:1D:29:E0:3E:D1 (public)
is_conn_slot_free: conn_mode[0].conn 536877752
is_conn_slot_free: conn_mode[1].conn 0
Direct advertising to 38:68:93:65:7B:73 (public) started
Direct advertising to 38:68:93:65:7B:73 (public) timed out
Regular advertising started
Security changed: 00:1D:29:E0:3E:D1 (public) level 4
I: BAS Notifications enabled
Connected 38:68:93:65:7B:73 (public)
is_conn_slot_free: conn_mode[0].conn 536877752
is_conn_slot_free: conn_mode[1].conn 536877952
is_conn_slot_free: all slots used
Security changed: 38:68:93:65:7B:73 (public) level 4
button_changed(): next
next_client(): changed connected client from -1 to 0
Changed to : 00:1D:29:E0:3E:D1 (public)
button_changed(): right
button_changed(): next
next_client(): changed connected client from 0 to 1
Changed to : 38:68:93:65:7B:73 (public)
button_changed(): next
next_client(): changed connected client from 1 to 0
Changed to : 00:1D:29:E0:3E:D1 (public)
button_changed(): right
button_changed(): next
next_client(): changed connected client from 0 to 1
Changed to : 38:68:93:65:7B:73 (public)
button_changed(): right
button_changed(): disconnect
Disconnect from : 38:68:93:65:7B:73 (public)
button_changed disconnect ret: 0
button_changed unpair ret: 0
next_client(): changed connected client from 1 to 0
I: BAS Notifications disabled
Disconnected from 38:68:93:65:7B:73 (public) (reason 22)
Regular advertising started
Connected 38:68:93:65:7B:73 (public)
is_conn_slot_free: conn_mode[0].conn 536877752
is_conn_slot_free: conn_mode[1].conn 536877952
is_conn_slot_free: all slots used
Disconnected from 38:68:93:65:7B:73 (public) (reason 19)
Regular advertising started
Connected 38:68:93:65:7B:73 (public)
is_conn_slot_free: conn_mode[0].conn 536877752
is_conn_slot_free: conn_mode[1].conn 536877952
is_conn_slot_free: all slots used
Disconnected from 38:68:93:65:7B:73 (public) (reason 19)
Regular advertising started
Connected 38:68:93:65:7B:73 (public)
is_conn_slot_free: conn_mode[0].conn 536877752
is_conn_slot_free: conn_mode[1].conn 536877952
is_conn_slot_free: all slots used
Disconnected from 38:68:93:65:7B:73 (public) (reason 19)
Regular advertising started
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/thread/456658?ContentTypeID=1</link><pubDate>Tue, 21 Nov 2023 12:03:25 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dd4dac88-abf7-4e1c-949d-5403c9c8f671</guid><dc:creator>Simonr</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;I think we need the full log here to see what is going on properly, as it seems it disconnects twice in a row without connecting at all. Do you also have a log of the connected central device so we can see what happens on that end?&lt;/p&gt;
&lt;p&gt;Also, it does seem to unpair correctly, but there won&amp;#39;t be anything stopping it from reconnecting if the connection doesn&amp;#39;t require pairing, so you would need to make the central require pairing or a bond in order to connect for it to not instantly reconnect (or stop scanning with the initial device for a period I assume).&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Simon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/thread/456268?ContentTypeID=1</link><pubDate>Sat, 18 Nov 2023 12:45:48 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:249522ca-558a-4a13-853f-d62a0d227bb5</guid><dc:creator>mirmit</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I disconnect then unpair the connection both functions return 0&lt;/p&gt;
&lt;div style="background-color:#1f1f1f;color:#cccccc;font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;font-size:14px;font-weight:normal;line-height:19px;white-space:pre;"&gt;
&lt;div&gt;&lt;span style="color:#dcdcaa;"&gt;bt_addr_le_to_str&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;(&lt;/span&gt;&lt;span style="color:#dcdcaa;"&gt;bt_conn_get_dst&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;(&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;conn_mode&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;[&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;current_client&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;].&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;conn&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;), &lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;addr&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;, &lt;/span&gt;&lt;span style="color:#569cd6;"&gt;sizeof&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;(&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;addr&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;));&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color:#dcdcaa;"&gt;printk&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;(&lt;/span&gt;&lt;span style="color:#ce9178;"&gt;&amp;quot;Disconnect from : &lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;%s&lt;/span&gt;&lt;span style="color:#d7ba7d;"&gt;\n&lt;/span&gt;&lt;span style="color:#ce9178;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;, &lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;addr&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color:#9cdcfe;"&gt;ret&lt;/span&gt;&lt;span style="color:#cccccc;"&gt; &lt;/span&gt;&lt;span style="color:#d4d4d4;"&gt;=&lt;/span&gt;&lt;span style="color:#cccccc;"&gt; &lt;/span&gt;&lt;span style="color:#dcdcaa;"&gt;bt_conn_disconnect&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;(&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;conn_mode&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;[&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;current_client&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;].&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;conn&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;, &lt;/span&gt;&lt;span style="color:#569cd6;"&gt;BT_HCI_ERR_REMOTE_USER_TERM_CONN&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color:#dcdcaa;"&gt;printk&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;(&lt;/span&gt;&lt;span style="color:#ce9178;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;%s&lt;/span&gt;&lt;span style="color:#ce9178;"&gt; disconnect ret: &lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;%d&lt;/span&gt;&lt;span style="color:#d7ba7d;"&gt;\n&lt;/span&gt;&lt;span style="color:#ce9178;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;, __func__, &lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;ret&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color:#9cdcfe;"&gt;ret&lt;/span&gt;&lt;span style="color:#cccccc;"&gt; &lt;/span&gt;&lt;span style="color:#d4d4d4;"&gt;=&lt;/span&gt;&lt;span style="color:#cccccc;"&gt; &lt;/span&gt;&lt;span style="color:#dcdcaa;"&gt;bt_unpair&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;(&lt;/span&gt;&lt;span style="color:#569cd6;"&gt;BT_ID_DEFAULT&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;, &lt;/span&gt;&lt;span style="color:#dcdcaa;"&gt;bt_conn_get_dst&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;(&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;conn_mode&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;[&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;current_client&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;].&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;conn&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;));&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color:#dcdcaa;"&gt;printk&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;(&lt;/span&gt;&lt;span style="color:#ce9178;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;%s&lt;/span&gt;&lt;span style="color:#ce9178;"&gt; unpair ret: &lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;%d&lt;/span&gt;&lt;span style="color:#d7ba7d;"&gt;\n&lt;/span&gt;&lt;span style="color:#ce9178;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;, __func__, &lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;ret&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color:#9cdcfe;"&gt;current_client&lt;/span&gt;&lt;span style="color:#cccccc;"&gt; &lt;/span&gt;&lt;span style="color:#d4d4d4;"&gt;=&lt;/span&gt;&lt;span style="color:#cccccc;"&gt; &lt;/span&gt;&lt;span style="color:#dcdcaa;"&gt;next_client&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;(&lt;/span&gt;&lt;span style="color:#9cdcfe;"&gt;current_client&lt;/span&gt;&lt;span style="color:#cccccc;"&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;as seen in the output:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new, courier;"&gt;button_changed(): disconnect&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;Disconnect from : 38:68:93:65:7B:73 (public)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;button_changed disconnect ret: 0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;button_changed unpair ret: 0&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Then the advertising/connection loop goes:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new, courier;"&gt;Regular advertising started&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;Disconnected from 38:68:93:65:7B:73 (public) (reason 19)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;Advertising failed to start (err -120)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;Connected 38:68:93:65:7B:73 (public)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;Regular advertising started&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;...&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Not sure where to look next.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Alexandre&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/thread/455934?ContentTypeID=1</link><pubDate>Thu, 16 Nov 2023 10:24:42 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:13b2579f-c60d-46ff-841a-a2c58c2dadfc</guid><dc:creator>Simonr</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;Did you disconnect from the device before calling this bt_unpair() function? I&amp;#39;d recommend checking the return value of bt_unpair() here to see if it returns successfully (with 0) or with a negative error code.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Simon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/thread/455634?ContentTypeID=1</link><pubDate>Tue, 14 Nov 2023 20:15:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7c0d246c-03c7-416a-871b-e696b87c0939</guid><dc:creator>mirmit</dc:creator><description>&lt;p&gt;Hi Simon,&lt;/p&gt;
&lt;p&gt;I unbound with a call to:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new, courier;"&gt;bt_addr_le_to_str(bt_conn_get_dst(conn_mode[current_client].conn), addr, sizeof(addr));&lt;br /&gt;bt_unpair(BT_ID_DEFAULT, bt_conn_get_dst(conn_mode[current_client].conn);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new, courier;"&gt;current_client&lt;/span&gt; being the index to the connection I&amp;#39;m looking to unbound.&lt;/p&gt;
&lt;p&gt;However, the unbounded device remains known to the nrf and it keep connect to it with log as:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new, courier;"&gt;Regular advertising started&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;Disconnected from 38:68:93:65:7B:73 (public) (reason 19)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;Advertising failed to start (err -120)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;Connected 38:68:93:65:7B:73 (public)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new, courier;"&gt;Regular advertising started&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;On the previously bonded central, I keep seeing the device status toggling between couples to connected, with the update of the battery status.&lt;/p&gt;
&lt;p&gt;Is there an additional step to be sure the nRF completely forget about this previous bond?&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Alexandre&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/thread/455287?ContentTypeID=1</link><pubDate>Mon, 13 Nov 2023 12:35:58 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:68689529-e6db-4697-9848-e2fdd6445bd2</guid><dc:creator>Simonr</dc:creator><description>&lt;p&gt;Hi again&lt;/p&gt;
&lt;p&gt;Thank you for the description, I understand.&lt;/p&gt;
&lt;p&gt;In the nRF Connect SDK, the correct way to erase bond information from devices would be to use the &lt;strong&gt;unpair&lt;/strong&gt;() or &lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/connectivity/bluetooth/api/gap.html#c.bt_unpair"&gt;&lt;strong&gt;bt_unpair&lt;/strong&gt;&lt;/a&gt;() functions from ...&lt;strong&gt;\&amp;lt;YOUR NCS FOLDER&amp;gt;\v2.5.0\zephyr\subsys\bluetooth\host\hci_core.c&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;How you decide which device to delete will be up to you. If you choose the one that was stored first or last&amp;nbsp;would be logical choices perhaps.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Simon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/thread/455159?ContentTypeID=1</link><pubDate>Fri, 10 Nov 2023 15:41:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:89f3c4c3-a52a-4712-8d26-75cac5863619</guid><dc:creator>mirmit</dc:creator><description>&lt;p&gt;I&amp;#39;m planning to have a peripheral which can be connected to different PC/Phone. At some point the capacity of potential bound will be exhausted. I want to be able to free up one past connection and connect to a new device.&lt;/p&gt;
&lt;p&gt;There are plenty od code about establishing the connection, but the resources seem scare on the &amp;#39;disconnect&amp;#39;.&lt;/p&gt;
&lt;p&gt;As I understand the sample code, once I have the two connections set up, the device will stop advertise anymore. How should I proceed to discard one connection and accept pairing with a third device.&lt;/p&gt;
&lt;p&gt;I mention 2 connections because this is the limit on the sample code, but I would have the same question if CONFIG_BT_MAX_PAIRED were defined with 32.&lt;/p&gt;
&lt;p&gt;Thanks,&lt;br /&gt;Aleandre&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Forget about connection after disconnection</title><link>https://devzone.nordicsemi.com/thread/455116?ContentTypeID=1</link><pubDate>Fri, 10 Nov 2023 13:03:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:af564143-e9ff-4da9-bdaa-7160f1963fd5</guid><dc:creator>Simonr</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;Are you sure you want to erase the bond entirely, and not just avoid automatically reconnecting to the central after it has been disconnected? Most mouse/headset/keyboard devices and the likes keeps bonds upon disconnects but just avoid to immediately reconnect to the device they were disconnected from, and from your description is what you&amp;#39;re looking for too.&lt;/p&gt;
&lt;p&gt;From the log it seems like the device starts&amp;nbsp;&lt;strong&gt;direct advertising&lt;/strong&gt; that means it only will connect to the device it&amp;#39;s advertising too. I&amp;#39;d assume advertising either openly or directly to the other device upon a disconnection would be a better solution to what you&amp;#39;re trying to do when it is the central that initiates disconnection.&lt;/p&gt;
&lt;p&gt;If you do in fact want to delete bonds, I recommend perhaps using a button to trigger bond deletion either of all devices, or of specific one(s).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Simon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>