Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: hci_sync: Use the advertising set handle, not the instance
@ 2026-10-23 13:24 Weihong Guan
  2026-10-23 17:54 ` bluez.test.bot
  2026-11-10 15:16 ` [PATCH] " Weihong Guan
  0 siblings, 2 replies; 5+ messages in thread
From: Weihong Guan @ 2026-10-23 13:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcel Holtmann, Luiz Augusto von Dentz

When the controller supports a single advertising set,
hci_add_adv_instance() gives instance 1 handle 0x00. The parameters,
data and enable commands for an instance use adv->handle, but two
commands still send the instance number as the advertising handle:

 - LE Set Advertising Set Random Address, from
   hci_set_adv_set_random_addr_sync(). The random address goes to
   handle 0x01, a set the controller doesn't have, and 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

 - LE Remove Advertising Set, from hci_remove_ext_adv_instance_sync(),
   so removing instance 1 fails with Unknown Advertising Identifier:

     $ 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)

Look the instance up and use its handle, as the other set commands do.
In hci_set_adv_set_random_addr_sync() the instance stays the function's
argument, so instance 0 still updates hdev->random_addr, which is shared
with scanning.

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>
---
Notes, outside the commit:

Tested on a Raspberry Pi 5 with its 6.18.50 kernel, with this change and
a local equivalent of 1bfecdbd03 ("Bluetooth: HCI: Fix tracking of
instances sharing handle 0x00"), which depends on changes 6.18 doesn't
have. The controller is an open link layer on a WCH CH583 behind HCI
over USB, reporting one advertising set. Non-connectable and connectable
instances are added and removed with btmgmt, every advertising command
on handle 0x00 and answered Success. That kernel has also run our BLE test
suite through BlueZ since. Build-tested on bluetooth-next with W=1, no
new warnings.

Two related spots I've left alone, as the ownership of handle 0x00 is
better judged by you:

 - hci_cc_le_set_adv_set_random_addr() returns early for handle 0x00
   and otherwise looks the set up by instance number, so a single-set
   controller's instance 1 never gets adv->random_addr recorded. A
   by-handle lookup there may meet hdev->cur_adv_instance before it is
   updated for the instance being set up.
 - hci_le_ext_adv_term_evt() looks up ev->handle as an instance and
   stores it as conn->adv_instance.

Also, removing a single-set controller's instance 1 now removes set
0x00, which Global Advertising also uses; if you'd rather disable than
remove there, I'm happy to rework it.

 net/bluetooth/hci_sync.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index c9e80b957..cdd175fe5 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -1248,6 +1248,7 @@ 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 = NULL;
 	int err;
 
 	if (!instance) {
@@ -1261,9 +1262,12 @@ static int hci_set_adv_set_random_addr_sync(struct hci_dev *hdev, u8 instance,
 			return err;
 	}
 
+	if (instance)
+		adv = hci_find_adv_instance(hdev, instance);
+
 	memset(&cp, 0, sizeof(cp));
 
-	cp.handle = instance;
+	cp.handle = adv ? adv->handle : instance;
 	bacpy(&cp.bdaddr, random_addr);
 
 	return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
@@ -2067,6 +2071,8 @@ 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;
 	int err;
 
 	if (!ext_adv_capable(hdev))
@@ -2077,11 +2083,16 @@ int hci_remove_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance,
 		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 > 0) {
+		adv = hci_find_adv_instance(hdev, instance);
+		if (!adv)
+			return -EINVAL;
+	}
+
+	handle = adv ? adv->handle : instance;
 
 	return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_REMOVE_ADV_SET,
-					sizeof(instance), &instance, 0,
+					sizeof(handle), &handle, 0,
 					HCI_CMD_TIMEOUT, sk);
 }
 
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-11-11  1:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-23 13:24 [PATCH] Bluetooth: hci_sync: Use the advertising set handle, not the instance Weihong Guan
2026-10-23 17:54 ` bluez.test.bot
2026-11-10 15:16 ` [PATCH] " Weihong Guan
2026-11-10 16:02   ` Luiz Augusto von Dentz
2026-11-11  1:13     ` Weihong Guan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox