* [PATCH v2 0/3] Bluetooth: Advertising sets on a single-set controller
@ 2026-11-11 1:09 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
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Weihong Guan @ 2026-11-11 1:09 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, Luiz Augusto von Dentz, Weihong Guan
When the controller supports a single advertising set,
hci_add_adv_instance() gives instance 1 handle 0x00, the handle Global
Advertising uses too. The parameters, data and enable commands already
use adv->handle; these patches cover what still takes the instance
number for the handle: setting the set's random address, removing the
set, and the Advertising Set Terminated event.
Changes in v2, addressing the review at
https://sashiko.dev/#/patchset/20261023132421.1889022-1-weihong.guan%40gmail.com
(I hadn't seen it, sorry):
- The instance is looked up, and adv->handle read, with hdev->lock held.
- Patch 1: hci_cc_le_set_adv_set_random_addr() records the address of
the instance numbered as the handle and leaves handle 0x00 alone, so
instance 1's address on handle 0x00 went unrecorded. It is now
recorded in hci_set_adv_set_random_addr_sync() when the instance and
its handle differ.
- Patch 2: hci_cc_le_remove_adv_set() looked up instance 0 for handle
0x00 and left instance 1 in hdev->adv_instances. The completion can't
tell instance 1 from instance 0, which MGMT's Set Advertising also
removes on handle 0x00, so instance 1 is removed in
hci_remove_ext_adv_instance_sync() once the command succeeds.
- Patch 2: while Global Advertising is on it owns handle 0x00, and the
controller would refuse to remove an enabled set, so only the instance
is removed then.
- Patch 3 (new): the Advertising Set Terminated event finds the instance
owning handle 0x00, the one enabled on it as hci_le_ext_adv_set_enabled()
tracks, for the connection's responder address (which SMP checks), the
instance re-enabled after the disconnection, and the removal on an
error.
Tested on a Raspberry Pi 5 (rpi-7.4.y, 7.4-rc2, with net/bluetooth and
include/net/bluetooth from bluetooth-next and these patches) with a
controller reporting one advertising set (LE Read Number of Supported
Advertising Sets = 1), btmgmt and btmon:
- A non-connectable instance (a random address) starts: its address
goes to handle 0x00 and the set advertises from it.
- Removing it sends LE Remove Advertising Set for handle 0x00; the
instance leaves the list (Read Advertising Features: none) and
Advertising Removed goes out.
- With Global Advertising on, removing instance 1 sends no LE Remove
Advertising Set, the instance still leaves the list, and the set
keeps advertising for Global Advertising.
- A connectable instance from a random static address
(force_static_address) on handle 0x00: Advertising Set Terminated
for handle 0x00, LE Secure Connections pairing completes (DHKey
Check both ways, so the responder address is the one advertised),
and after the disconnection instance 1 advertises again.
Built with W=1; checkpatch clean but for the Assisted-by tag.
v1: https://lore.kernel.org/linux-bluetooth/20261023132421.1889022-1-weihong.guan@gmail.com/
Weihong Guan (3):
Bluetooth: hci_sync: Set an advertising set's random address on its
handle
Bluetooth: hci_sync: Remove an advertising set by its handle
Bluetooth: hci_event: Find the instance owning a terminated
advertising set
net/bluetooth/hci_event.c | 42 ++++++++++++-----
net/bluetooth/hci_sync.c | 94 +++++++++++++++++++++++++++++++++++----
2 files changed, 116 insertions(+), 20 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v2 1/3] Bluetooth: hci_sync: Set an advertising set's random address on its handle
2026-11-11 1:09 [PATCH v2 0/3] Bluetooth: Advertising sets on a single-set controller Weihong Guan
@ 2026-11-11 1:09 ` 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 ` [PATCH v2 3/3] Bluetooth: hci_event: Find the instance owning a terminated advertising set Weihong Guan
2 siblings, 1 reply; 8+ messages in thread
From: Weihong Guan @ 2026-11-11 1:09 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, Luiz Augusto von Dentz, Weihong Guan
When the controller supports a single advertising set,
hci_add_adv_instance() gives instance 1 handle 0x00, and the parameters,
data and enable commands for an instance use adv->handle. LE Set
Advertising Set Random Address, from hci_set_adv_set_random_addr_sync(),
still sends the instance number, 0x01, a set the controller doesn't
have, so an instance using a random address, such as a non-connectable
one, never starts:
$ btmgmt add-adv -d 0A09434841445654455354 1
Add Advertising failed with status 0x0d (Invalid Parameters)
< HCI Command: LE Set Extended Advertising Parameters Handle: 0x00
< HCI Command: LE Set Extended Advertising Data Handle: 0x00
< HCI Command: LE Set Advertising Set Random Address
Advertising handle: 0x01
Send the instance's handle, looked up with hdev->lock held.
hci_cc_le_set_adv_set_random_addr() records the address in the instance
numbered as the handle and leaves handle 0x00 alone, as that handle's
address is hdev->random_addr for instance 0. Instance 1's address on
handle 0x00 would then go unrecorded, and its RPA timer never start, so
record it in hci_set_adv_set_random_addr_sync() once the command
succeeds, as the completion does for the other handles.
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_sync.c | 39 ++++++++++++++++++++++++++++++++++++---
1 file changed, 36 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 9213e3ef9..320c5ba0d 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -1258,6 +1258,8 @@ static int hci_set_adv_set_random_addr_sync(struct hci_dev *hdev, u8 instance,
bdaddr_t *random_addr)
{
struct hci_cp_le_set_adv_set_rand_addr cp;
+ struct adv_info *adv;
+ u8 handle = instance;
int err;
if (!instance) {
@@ -1269,15 +1271,46 @@ static int hci_set_adv_set_random_addr_sync(struct hci_dev *hdev, u8 instance,
err = hci_set_random_addr_sync(hdev, random_addr);
if (err)
return err;
+ } else {
+ hci_dev_lock(hdev);
+ adv = hci_find_adv_instance(hdev, instance);
+ if (adv)
+ handle = adv->handle;
+ hci_dev_unlock(hdev);
}
memset(&cp, 0, sizeof(cp));
- cp.handle = instance;
+ cp.handle = handle;
bacpy(&cp.bdaddr, random_addr);
- return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
- sizeof(cp), &cp, HCI_CMD_TIMEOUT);
+ err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
+ sizeof(cp), &cp, HCI_CMD_TIMEOUT);
+ if (err || handle == instance)
+ return err;
+
+ /* hci_cc_le_set_adv_set_random_addr() records the address of the
+ * instance numbered as the handle, and leaves handle 0x00 to
+ * hdev->random_addr, so record it here for an instance using another
+ * handle: instance 1 on handle 0x00, on a controller supporting a
+ * single advertising set.
+ */
+ hci_dev_lock(hdev);
+
+ adv = hci_find_adv_instance(hdev, instance);
+ if (adv) {
+ bacpy(&adv->random_addr, random_addr);
+ if (!bacmp(&hdev->rpa, random_addr)) {
+ adv->rpa_expired = false;
+ queue_delayed_work(hdev->workqueue,
+ &adv->rpa_expired_cb,
+ secs_to_jiffies(hdev->rpa_timeout));
+ }
+ }
+
+ hci_dev_unlock(hdev);
+
+ return 0;
}
static int
--
2.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* RE: Bluetooth: Advertising sets on a single-set controller
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 ` bluez.test.bot
0 siblings, 0 replies; 8+ messages in thread
From: bluez.test.bot @ 2026-11-11 3:38 UTC (permalink / raw)
To: linux-bluetooth, weihong.guan
[-- Attachment #1: Type: text/plain, Size: 4684 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/series/1207749/
---Test result---
Test Summary:
CheckPatch FAIL 2.03 seconds
VerifyFixes PASS 0.09 seconds
VerifySignedoff PASS 0.09 seconds
GitLint FAIL 0.79 seconds
SubjectPrefix PASS 0.27 seconds
BuildKernel PASS 30.54 seconds
CheckAllWarning PASS 35.27 seconds
CheckSparse WARNING 38.33 seconds
BuildKernel32 PASS 31.28 seconds
CheckKernelLLVM PASS 35.13 seconds
TestRunnerSetup PASS 743.16 seconds
TestRunner_l2cap-tester PASS 12.85 seconds
TestRunner_iso-tester PASS 10.75 seconds
TestRunner_bnep-tester PASS 3.16 seconds
TestRunner_mgmt-tester PASS 88.40 seconds
TestRunner_rfcomm-tester PASS 4.49 seconds
TestRunner_sco-tester PASS 5.68 seconds
TestRunner_ioctl-tester PASS 4.71 seconds
TestRunner_mesh-tester PASS 5.54 seconds
TestRunner_smp-tester PASS 4.43 seconds
TestRunner_userchan-tester PASS 3.24 seconds
TestRunner_6lowpan-tester PASS 4.43 seconds
IncrementalBuild PASS 35.94 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[v2,1/3] Bluetooth: hci_sync: Set an advertising set's random address on its handle
WARNING: Non-standard signature: Assisted-by:
#147:
Assisted-by: Claude:claude-opus-5.5
ERROR: Unrecognized email address: 'Claude:claude-opus-5.5'
#147:
Assisted-by: Claude:claude-opus-5.5
total: 1 errors, 1 warnings, 0 checks, 57 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/home/runner/work/bluetooth-next/bluetooth-next/src/patch/14970766.patch has style problems, please review.
NOTE: Ignored message types: UNKNOWN_COMMIT_ID
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
[v2,2/3] Bluetooth: hci_sync: Remove an advertising set by its handle
WARNING: Non-standard signature: Assisted-by:
#151:
Assisted-by: Claude:claude-opus-5.5
ERROR: Unrecognized email address: 'Claude:claude-opus-5.5'
#151:
Assisted-by: Claude:claude-opus-5.5
total: 1 errors, 1 warnings, 0 checks, 68 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/home/runner/work/bluetooth-next/bluetooth-next/src/patch/14970767.patch has style problems, please review.
NOTE: Ignored message types: UNKNOWN_COMMIT_ID
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
[v2,3/3] Bluetooth: hci_event: Find the instance owning a terminated advertising set
WARNING: Non-standard signature: Assisted-by:
#143:
Assisted-by: Claude:claude-opus-5.5
ERROR: Unrecognized email address: 'Claude:claude-opus-5.5'
#143:
Assisted-by: Claude:claude-opus-5.5
total: 1 errors, 1 warnings, 0 checks, 74 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/home/runner/work/bluetooth-next/bluetooth-next/src/patch/14970768.patch has style problems, please review.
NOTE: Ignored message types: UNKNOWN_COMMIT_ID
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[v2,1/3] Bluetooth: hci_sync: Set an advertising set's random address on its handle
1: T1 Title exceeds max length (83>80): "[v2,1/3] Bluetooth: hci_sync: Set an advertising set's random address on its handle"
[v2,3/3] Bluetooth: hci_event: Find the instance owning a terminated advertising set
1: T1 Title exceeds max length (84>80): "[v2,3/3] Bluetooth: hci_event: Find the instance owning a terminated advertising set"
##############################
Test: CheckSparse - WARNING
Desc: Run sparse tool with linux kernel
Output:
net/bluetooth/hci_event.c: note: in included file (through include/net/bluetooth/hci_core.h):
https://github.com/bluez/bluetooth-next/pull/1108
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/3] Bluetooth: hci_sync: Remove an advertising set by its handle
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 1:09 ` Weihong Guan
2026-11-11 1:09 ` [PATCH v2 3/3] Bluetooth: hci_event: Find the instance owning a terminated advertising set Weihong Guan
2 siblings, 0 replies; 8+ messages in thread
From: Weihong Guan @ 2026-11-11 1:09 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, Luiz Augusto von Dentz, Weihong Guan
When the controller supports a single advertising set,
hci_add_adv_instance() gives instance 1 handle 0x00, but
hci_remove_ext_adv_instance_sync() sends the instance number as the
handle of LE Remove Advertising Set, so removing instance 1 fails:
$ btmgmt rm-adv 1
Remove Advertising failed with status 0x03 (Failed)
< HCI Command: LE Remove Advertising Set Handle: 1
> HCI Event: Command Complete
Status: Unknown Advertising Identifier (0x42)
Send the instance's handle, looked up with hdev->lock held. Two more
things follow from the instance and the handle differing:
- hci_cc_le_remove_adv_set() removes the instance numbered as the
handle it sent, which for handle 0x00 is instance 0, so instance 1
would stay in hdev->adv_instances with its RPA timer running, and no
MGMT_EV_ADVERTISING_REMOVED. The completion can't tell instance 1
from instance 0, which the MGMT Set Advertising path removes on the
same handle, so remove instance 1 in
hci_remove_ext_adv_instance_sync() once the command succeeds.
- While Global Advertising is on, it owns handle 0x00
(adv_overridden_by_global()), and the set may be enabled for it, so
the controller would refuse to remove it, with Command Disallowed.
Remove only the instance then, leaving the set to Global
Advertising.
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_sync.c | 55 +++++++++++++++++++++++++++++++++++-----
1 file changed, 49 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 320c5ba0d..d4a4f49df 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -2110,6 +2110,9 @@ int hci_enable_advertising(struct hci_dev *hdev)
int hci_remove_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance,
struct sock *sk)
{
+ struct adv_info *adv = NULL;
+ u8 handle = instance;
+ bool global = false;
int err;
if (!ext_adv_capable(hdev))
@@ -2119,13 +2122,53 @@ int hci_remove_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance,
if (err)
return err;
- /* If request specifies an instance that doesn't exist, fail */
- if (instance > 0 && !hci_find_adv_instance(hdev, instance))
- return -EINVAL;
+ if (instance) {
+ hci_dev_lock(hdev);
+
+ adv = hci_find_adv_instance(hdev, instance);
+ if (adv) {
+ handle = adv->handle;
+
+ /* An instance sharing handle 0x00 with Global
+ * Advertising doesn't own the set while Global
+ * Advertising is on, and the set may still be enabled
+ * for it, which the controller would refuse to remove.
+ */
+ global = !handle &&
+ (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
+ hci_dev_test_flag(hdev, HCI_LE_ADV_0));
+ }
+
+ hci_dev_unlock(hdev);
+
+ /* If request specifies an instance that doesn't exist, fail */
+ if (!adv)
+ return -EINVAL;
+ }
+
+ if (!global) {
+ err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_REMOVE_ADV_SET,
+ sizeof(handle), &handle, 0,
+ HCI_CMD_TIMEOUT, sk);
+ if (err)
+ return err;
+ }
+
+ /* hci_cc_le_remove_adv_set() removes the instance numbered as the
+ * handle it sent, so remove here an instance using another handle:
+ * instance 1 on handle 0x00, on a controller supporting a single
+ * advertising set. The completion can't tell it from instance 0.
+ */
+ if (handle != instance) {
+ hci_dev_lock(hdev);
+
+ if (!hci_remove_adv_instance(hdev, instance))
+ mgmt_advertising_removed(sk, hdev, instance);
- return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_REMOVE_ADV_SET,
- sizeof(instance), &instance, 0,
- HCI_CMD_TIMEOUT, sk);
+ hci_dev_unlock(hdev);
+ }
+
+ return 0;
}
int hci_le_terminate_big_sync(struct hci_dev *hdev, u8 handle, u8 reason)
--
2.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 3/3] Bluetooth: hci_event: Find the instance owning a terminated advertising set
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 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
2026-11-11 15:47 ` Luiz Augusto von Dentz
2 siblings, 1 reply; 8+ messages in thread
From: Weihong Guan @ 2026-11-11 1:09 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, Luiz Augusto von Dentz, Weihong Guan
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
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v2 3/3] Bluetooth: hci_event: Find the instance owning a terminated advertising set
2026-11-11 1:09 ` [PATCH v2 3/3] Bluetooth: hci_event: Find the instance owning a terminated advertising set Weihong Guan
@ 2026-11-11 15:47 ` Luiz Augusto von Dentz
2026-11-11 16:58 ` Weihong Guan
0 siblings, 1 reply; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2026-11-11 15:47 UTC (permalink / raw)
To: Weihong Guan; +Cc: linux-bluetooth, Marcel Holtmann
Hi Weihong,
On Tue, Nov 10, 2026 at 8:09 PM Weihong Guan <weihong.guan@gmail.com> wrote:
>
> 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);
While it seems sashiko didn't find any new problems I wonder if we can
eliminate the double lookup since hci_remove_adv_instance will attempt
to lookup again the instance, so instead of calling it perhaps we
could free the adv_info directly or via a helper shared with
hci_remove_adv_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
>
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v3 1/4] Bluetooth: hci_sync: Set random address on the set's handle
@ 2026-11-11 16:51 Weihong Guan
2026-11-11 18:21 ` Bluetooth: Advertising sets on a single-set controller bluez.test.bot
0 siblings, 1 reply; 8+ messages in thread
From: Weihong Guan @ 2026-11-11 16:51 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, Luiz Augusto von Dentz, Weihong Guan
When the controller supports a single advertising set,
hci_add_adv_instance() gives instance 1 handle 0x00, and the parameters,
data and enable commands for an instance use adv->handle. LE Set
Advertising Set Random Address, from hci_set_adv_set_random_addr_sync(),
still sends the instance number, 0x01, a set the controller doesn't
have, so an instance using a random address, such as a non-connectable
one, never starts:
$ btmgmt add-adv -d 0A09434841445654455354 1
Add Advertising failed with status 0x0d (Invalid Parameters)
< HCI Command: LE Set Extended Advertising Parameters Handle: 0x00
< HCI Command: LE Set Extended Advertising Data Handle: 0x00
< HCI Command: LE Set Advertising Set Random Address
Advertising handle: 0x01
Send the instance's handle, looked up with hdev->lock held.
hci_cc_le_set_adv_set_random_addr() records the address in the instance
numbered as the handle and leaves handle 0x00 alone, as that handle's
address is hdev->random_addr for instance 0. Instance 1's address on
handle 0x00 would then go unrecorded, and its RPA timer never start, so
record it in hci_set_adv_set_random_addr_sync() once the command
succeeds, as the completion does for the other handles.
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_sync.c | 39 ++++++++++++++++++++++++++++++++++++---
1 file changed, 36 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 9213e3ef9..320c5ba0d 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -1258,6 +1258,8 @@ static int hci_set_adv_set_random_addr_sync(struct hci_dev *hdev, u8 instance,
bdaddr_t *random_addr)
{
struct hci_cp_le_set_adv_set_rand_addr cp;
+ struct adv_info *adv;
+ u8 handle = instance;
int err;
if (!instance) {
@@ -1269,15 +1271,46 @@ static int hci_set_adv_set_random_addr_sync(struct hci_dev *hdev, u8 instance,
err = hci_set_random_addr_sync(hdev, random_addr);
if (err)
return err;
+ } else {
+ hci_dev_lock(hdev);
+ adv = hci_find_adv_instance(hdev, instance);
+ if (adv)
+ handle = adv->handle;
+ hci_dev_unlock(hdev);
}
memset(&cp, 0, sizeof(cp));
- cp.handle = instance;
+ cp.handle = handle;
bacpy(&cp.bdaddr, random_addr);
- return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
- sizeof(cp), &cp, HCI_CMD_TIMEOUT);
+ err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
+ sizeof(cp), &cp, HCI_CMD_TIMEOUT);
+ if (err || handle == instance)
+ return err;
+
+ /* hci_cc_le_set_adv_set_random_addr() records the address of the
+ * instance numbered as the handle, and leaves handle 0x00 to
+ * hdev->random_addr, so record it here for an instance using another
+ * handle: instance 1 on handle 0x00, on a controller supporting a
+ * single advertising set.
+ */
+ hci_dev_lock(hdev);
+
+ adv = hci_find_adv_instance(hdev, instance);
+ if (adv) {
+ bacpy(&adv->random_addr, random_addr);
+ if (!bacmp(&hdev->rpa, random_addr)) {
+ adv->rpa_expired = false;
+ queue_delayed_work(hdev->workqueue,
+ &adv->rpa_expired_cb,
+ secs_to_jiffies(hdev->rpa_timeout));
+ }
+ }
+
+ hci_dev_unlock(hdev);
+
+ return 0;
}
static int
--
2.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* RE: Bluetooth: Advertising sets on a single-set controller
2026-11-11 16:51 [PATCH v3 1/4] Bluetooth: hci_sync: Set random address on the set's handle Weihong Guan
@ 2026-11-11 18:21 ` bluez.test.bot
0 siblings, 0 replies; 8+ messages in thread
From: bluez.test.bot @ 2026-11-11 18:21 UTC (permalink / raw)
To: linux-bluetooth, weihong.guan
[-- Attachment #1: Type: text/plain, Size: 4889 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/series/1208570/
---Test result---
Test Summary:
CheckPatch FAIL 8.49 seconds
VerifyFixes PASS 6.43 seconds
VerifySignedoff PASS 1.36 seconds
GitLint PASS 14.44 seconds
SubjectPrefix PASS 17.47 seconds
BuildKernel PASS 23.98 seconds
CheckAllWarning PASS 27.11 seconds
CheckSparse WARNING 29.23 seconds
BuildKernel32 PASS 24.75 seconds
CheckKernelLLVM PASS 26.34 seconds
TestRunnerSetup PASS 559.69 seconds
TestRunner_l2cap-tester PASS 13.34 seconds
TestRunner_iso-tester PASS 9.70 seconds
TestRunner_bnep-tester PASS 2.91 seconds
TestRunner_mgmt-tester PASS 84.50 seconds
TestRunner_rfcomm-tester PASS 4.18 seconds
TestRunner_sco-tester PASS 5.20 seconds
TestRunner_ioctl-tester PASS 4.35 seconds
TestRunner_mesh-tester PASS 5.23 seconds
TestRunner_smp-tester PASS 4.05 seconds
TestRunner_userchan-tester PASS 3.02 seconds
TestRunner_6lowpan-tester PASS 4.19 seconds
IncrementalBuild PASS 43.26 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[v3,1/4] Bluetooth: hci_sync: Set random address on the set's handle
WARNING: Non-standard signature: Assisted-by:
#147:
Assisted-by: Claude:claude-opus-5.5
ERROR: Unrecognized email address: 'Claude:claude-opus-5.5'
#147:
Assisted-by: Claude:claude-opus-5.5
total: 1 errors, 1 warnings, 0 checks, 57 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/home/runner/work/bluetooth-next/bluetooth-next/src/patch/14973062.patch has style problems, please review.
NOTE: Ignored message types: UNKNOWN_COMMIT_ID
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
[v3,2/4] Bluetooth: hci_sync: Remove an advertising set by its handle
WARNING: Non-standard signature: Assisted-by:
#151:
Assisted-by: Claude:claude-opus-5.5
ERROR: Unrecognized email address: 'Claude:claude-opus-5.5'
#151:
Assisted-by: Claude:claude-opus-5.5
total: 1 errors, 1 warnings, 0 checks, 68 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/home/runner/work/bluetooth-next/bluetooth-next/src/patch/14973063.patch has style problems, please review.
NOTE: Ignored message types: UNKNOWN_COMMIT_ID
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
[v3,3/4] Bluetooth: hci_core: Add hci_free_adv_instance()
WARNING: Non-standard signature: Assisted-by:
#130:
Assisted-by: Claude:claude-opus-5.5
ERROR: Unrecognized email address: 'Claude:claude-opus-5.5'
#130:
Assisted-by: Claude:claude-opus-5.5
total: 1 errors, 1 warnings, 0 checks, 45 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/home/runner/work/bluetooth-next/bluetooth-next/src/patch/14973064.patch has style problems, please review.
NOTE: Ignored message types: UNKNOWN_COMMIT_ID
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
[v3,4/4] Bluetooth: hci_event: Find the owner of a terminated adv set
WARNING: Non-standard signature: Assisted-by:
#144:
Assisted-by: Claude:claude-opus-5.5
ERROR: Unrecognized email address: 'Claude:claude-opus-5.5'
#144:
Assisted-by: Claude:claude-opus-5.5
total: 1 errors, 1 warnings, 0 checks, 74 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/home/runner/work/bluetooth-next/bluetooth-next/src/patch/14973065.patch has style problems, please review.
NOTE: Ignored message types: UNKNOWN_COMMIT_ID
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
##############################
Test: CheckSparse - WARNING
Desc: Run sparse tool with linux kernel
Output:
net/bluetooth/hci_event.c: note: in included file (through include/net/bluetooth/hci_core.h):
https://github.com/bluez/bluetooth-next/pull/1113
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-11-11 18:21 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH v2 3/3] Bluetooth: hci_event: Find the instance owning a terminated advertising set Weihong Guan
2026-11-11 15:47 ` Luiz Augusto von Dentz
2026-11-11 16:58 ` Weihong Guan
-- strict thread matches above, loose matches on Subject: below --
2026-11-11 16:51 [PATCH v3 1/4] Bluetooth: hci_sync: Set random address on the set's handle Weihong Guan
2026-11-11 18:21 ` Bluetooth: Advertising sets on a single-set controller bluez.test.bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox