Linux bluetooth development
 help / color / mirror / Atom feed
From: Weihong Guan <weihong.guan@gmail.com>
To: linux-bluetooth@vger.kernel.org
Cc: Marcel Holtmann <marcel@holtmann.org>,
	Luiz Augusto von Dentz <luiz.dentz@gmail.com>,
	Weihong Guan <weihong.guan@gmail.com>
Subject: [PATCH v2 3/3] Bluetooth: hci_event: Find the instance owning a terminated advertising set
Date: Wed, 11 Nov 2026 01:09:40 +0000	[thread overview]
Message-ID: <20261111010940.728149-4-weihong.guan@gmail.com> (raw)
In-Reply-To: <20261111010940.728149-1-weihong.guan@gmail.com>

hci_le_ext_adv_term_evt() looks the instance up by the event's handle,
but when the controller supports a single advertising set,
hci_add_adv_instance() gives instance 1 handle 0x00, which is also the
handle of Global Advertising. For instance 1 the event then finds no
instance, and:

 - a connection from it gets hdev->random_addr as its responder
   address, rather than the instance's random address, which SMP then
   checks against;
 - the connection stores handle 0x00 in conn->adv_instance, which is
   later restored as hdev->cur_adv_instance, so after the disconnection
   instance 0 is re-enabled rather than instance 1;
 - when the set terminates with an error, instance 0 is removed rather
   than instance 1, so instance 1 stays with no
   MGMT_EV_ADVERTISING_REMOVED.

Find the instance owning the set: for handle 0x00 the instance enabled
on it, as hci_le_ext_adv_set_enabled() tracks, and use its instance
number and random address. Global Advertising, and any other handle,
are handled as before.

Fixes: e77f43d531af ("Bluetooth: hci_core: Fix not handling hdev->le_num_of_adv_sets=1")
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Weihong Guan <weihong.guan@gmail.com>
---
 net/bluetooth/hci_event.c | 42 +++++++++++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index f0ce124bb..33ff6cd80 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -6179,6 +6179,26 @@ static void hci_le_pa_sync_lost_evt(struct hci_dev *hdev, void *data,
 	hci_dev_unlock(hdev);
 }
 
+/* The instance advertising on the set identified by handle. Handle 0x00 may
+ * be shared by Global Advertising and an instance, e.g. instance 1 when the
+ * controller supports a single advertising set, in which case the instance
+ * enabled on it, if any, owns the set (see hci_le_ext_adv_set_enabled()).
+ */
+static struct adv_info *hci_le_ext_adv_owner(struct hci_dev *hdev, u8 handle)
+{
+	struct adv_info *adv;
+
+	if (handle)
+		return hci_find_adv_instance(hdev, handle);
+
+	list_for_each_entry(adv, &hdev->adv_instances, list) {
+		if (!adv->handle && adv->enabled)
+			return adv;
+	}
+
+	return NULL;
+}
+
 static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
 				    struct sk_buff *skb)
 {
@@ -6202,15 +6222,18 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
 
 	hci_dev_lock(hdev);
 
-	adv = hci_find_adv_instance(hdev, ev->handle);
+	adv = hci_le_ext_adv_owner(hdev, ev->handle);
 
 	if (ev->status) {
+		u8 instance;
+
 		if (!adv)
 			goto unlock;
 
 		/* Remove advertising as it has been terminated */
-		hci_remove_adv_instance(hdev, ev->handle);
-		mgmt_advertising_removed(NULL, hdev, ev->handle);
+		instance = adv->instance;
+		hci_remove_adv_instance(hdev, instance);
+		mgmt_advertising_removed(NULL, hdev, instance);
 
 		list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
 			if (adv->enabled)
@@ -6227,22 +6250,19 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
 
 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle));
 	if (conn) {
-		/* Store handle in the connection so the correct advertising
-		 * instance can be re-enabled when disconnected.
+		/* Store the instance in the connection so the correct
+		 * advertising instance can be re-enabled when disconnected.
 		 */
-		conn->adv_instance = ev->handle;
+		conn->adv_instance = adv ? adv->instance : ev->handle;
 
 		if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM ||
 		    bacmp(&conn->resp_addr, BDADDR_ANY))
 			goto unlock;
 
-		if (!ev->handle) {
-			bacpy(&conn->resp_addr, &hdev->random_addr);
-			goto unlock;
-		}
-
 		if (adv)
 			bacpy(&conn->resp_addr, &adv->random_addr);
+		else if (!ev->handle)
+			bacpy(&conn->resp_addr, &hdev->random_addr);
 	}
 
 unlock:
-- 
2.47.3


  parent reply	other threads:[~2026-11-11  1:09 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11  1:09 [PATCH v2 0/3] Bluetooth: Advertising sets on a single-set controller Weihong Guan
2026-11-11  1:09 ` [PATCH v2 1/3] Bluetooth: hci_sync: Set an advertising set's random address on its handle Weihong Guan
2026-11-11  3:38   ` Bluetooth: Advertising sets on a single-set controller bluez.test.bot
2026-11-11  1:09 ` [PATCH v2 2/3] Bluetooth: hci_sync: Remove an advertising set by its handle Weihong Guan
2026-11-11  1:09 ` Weihong Guan [this message]
2026-11-11 15:47   ` [PATCH v2 3/3] Bluetooth: hci_event: Find the instance owning a terminated advertising set Luiz Augusto von Dentz
2026-11-11 16:58     ` Weihong Guan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261111010940.728149-4-weihong.guan@gmail.com \
    --to=weihong.guan@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=luiz.dentz@gmail.com \
    --cc=marcel@holtmann.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox