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
next prev 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