Linux bluetooth development
 help / color / mirror / Atom feed
* [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 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

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