From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH v5 2/4] Bluetooth: HCI: Fix tracking of instances sharing handle 0x00
Date: Tue, 6 Oct 2026 10:15:00 -0400 [thread overview]
Message-ID: <20261006141502.3789138-2-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20261006141502.3789138-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
When the controller supports a single advertising set, instance 1 uses
handle 0x00 which is the same handle used by instance 0 (Global
Advertising), but hci_cc_le_set_ext_adv_enable would lookup the instance
using the handle as instance identifier, marking instance 0 as
enabled/disabled instead of instance 1, leaving its state out of sync.
Fix this by matching instances by handle and, for handle 0x00, using
hdev->cur_adv_instance, now set when enabling an instance, to determine
which instance owns the set. Also disable the instance sharing the
advertising set of instance 0 before overriding it.
Fixes: e77f43d531af ("Bluetooth: hci_core: Fix not handling hdev->le_num_of_adv_sets=1")
Assisted-by: OpenCode:claude-opus-5.5
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
net/bluetooth/hci_event.c | 47 ++++++++++++++++++++++++++++++---------
net/bluetooth/hci_sync.c | 35 ++++++++++++++++++++++++++++-
2 files changed, 70 insertions(+), 12 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 2c8f6f22a4ee..9ec6c3c22fbd 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1639,6 +1639,39 @@ static u8 hci_cc_le_set_adv_enable(struct hci_dev *hdev, void *data,
return rp->status;
}
+/* Update the enabled state of the instance(s) using the advertising set
+ * identified by handle.
+ *
+ * Instances may share handle 0x00 with instance 0 (Global Advertising), e.g.
+ * when the controller supports a single advertising set, in which case the
+ * set is owned by the instance last enabled (hdev->cur_adv_instance) and any
+ * other instance sharing it shall be considered disabled.
+ */
+static void hci_le_ext_adv_set_enabled(struct hci_dev *hdev, u8 handle,
+ bool enable)
+{
+ struct adv_info *adv;
+ bool owned = false;
+
+ list_for_each_entry(adv, &hdev->adv_instances, list) {
+ if (adv->handle != handle)
+ continue;
+
+ adv->enabled = enable &&
+ (handle ||
+ adv->instance == hdev->cur_adv_instance);
+ owned |= adv->enabled;
+ }
+
+ if (handle)
+ return;
+
+ if (enable && !owned)
+ hci_dev_set_flag(hdev, HCI_LE_ADV_0);
+ else
+ hci_dev_clear_flag(hdev, HCI_LE_ADV_0);
+}
+
static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
struct sk_buff *skb)
{
@@ -1660,18 +1693,13 @@ static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
hci_dev_lock(hdev);
- if (cp->num_of_sets)
- adv = hci_find_adv_instance(hdev, set->handle);
-
if (cp->enable) {
struct hci_conn *conn;
hci_dev_set_flag(hdev, HCI_LE_ADV);
- if (adv)
- adv->enabled = true;
- else if (!set->handle)
- hci_dev_set_flag(hdev, HCI_LE_ADV_0);
+ if (cp->num_of_sets)
+ hci_le_ext_adv_set_enabled(hdev, set->handle, true);
conn = hci_lookup_le_connect(hdev);
if (conn)
@@ -1680,10 +1708,7 @@ static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
conn->conn_timeout);
} else {
if (cp->num_of_sets) {
- if (adv)
- adv->enabled = false;
- else if (!set->handle)
- hci_dev_clear_flag(hdev, HCI_LE_ADV_0);
+ hci_le_ext_adv_set_enabled(hdev, set->handle, false);
/* If just one instance was disabled check if there are
* any other instance enabled, including instance 0,
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 19917aa49cb2..c5768069ee39 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -1156,6 +1156,30 @@ int hci_update_random_address_sync(struct hci_dev *hdev, bool require_privacy,
return 0;
}
+/* Check if the advertising set with handle 0x00 is in use, either by instance
+ * 0 or by an instance sharing its advertising set.
+ */
+static bool hci_ext_adv_handle_0_enabled(struct hci_dev *hdev)
+{
+ struct adv_info *adv;
+ bool enabled;
+
+ hci_dev_lock(hdev);
+
+ enabled = hci_dev_test_flag(hdev, HCI_LE_ADV_0);
+
+ list_for_each_entry(adv, &hdev->adv_instances, list) {
+ if (!adv->handle && adv->enabled) {
+ enabled = true;
+ break;
+ }
+ }
+
+ hci_dev_unlock(hdev);
+
+ return enabled;
+}
+
int hci_disable_ext_adv_legacy_instance_sync(struct hci_dev *hdev)
{
struct hci_cp_le_set_ext_adv_enable *cp;
@@ -1163,7 +1187,7 @@ int hci_disable_ext_adv_legacy_instance_sync(struct hci_dev *hdev)
u8 data[sizeof(*cp) + sizeof(*set) * 1];
u8 size;
- if (!hci_dev_test_flag(hdev, HCI_LE_ADV_0))
+ if (!hci_ext_adv_handle_0_enabled(hdev))
return 0;
memset(data, 0, sizeof(data));
@@ -1409,6 +1433,9 @@ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
return -EINVAL;
}
} else {
+ /* Disable the advertising set with handle 0x00, including any
+ * instance sharing it, since it is going to be overridden.
+ */
err = hci_disable_ext_adv_legacy_instance_sync(hdev);
if (err)
return err;
@@ -1676,6 +1703,12 @@ int hci_enable_ext_advertising_sync(struct hci_dev *hdev, u8 instance)
set->duration = cpu_to_le16(duration / 10);
}
+ /* Track which instance owns the advertising set since the handle
+ * alone is ambiguous when instances share handle 0x00, see
+ * hci_cc_le_set_ext_adv_enable.
+ */
+ hdev->cur_adv_instance = instance;
+
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE,
sizeof(*cp) +
sizeof(*set) * cp->num_of_sets,
--
2.55.0
next prev parent reply other threads:[~2026-10-06 14:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-06 14:14 [PATCH v5 1/4] Bluetooth: MGMT: Fix advertising instances with Global Advertising Luiz Augusto von Dentz
2026-10-06 14:15 ` Luiz Augusto von Dentz [this message]
2026-10-06 14:15 ` [PATCH v5 3/4] Bluetooth: MGMT: Fix pending state of instances added without HCI traffic Luiz Augusto von Dentz
2026-10-06 14:15 ` [PATCH v5 4/4] Bluetooth: MGMT: Fix leaking instance on Add Extended Advertising Parameters Luiz Augusto von Dentz
2026-10-06 15:10 ` [PATCH v5 1/4] Bluetooth: MGMT: Fix advertising instances with Global Advertising patchwork-bot+bluetooth
2026-10-06 15:24 ` [v5,1/4] " bluez.test.bot
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=20261006141502.3789138-2-luiz.dentz@gmail.com \
--to=luiz.dentz@gmail.com \
--cc=linux-bluetooth@vger.kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.