* [PATCH BlueZ bluez 1/2] adapter: add MGMT_EV_EXT_ADV_SID_CHANGED mgmt event
2026-01-07 8:51 [PATCH BlueZ bluez 0/2] Optimize the PA sync flow Yang Li via B4 Relay
@ 2026-01-07 8:51 ` Yang Li via B4 Relay
2026-01-07 9:47 ` Optimize the PA sync flow bluez.test.bot
2026-01-07 8:51 ` [PATCH BlueZ bluez 2/2] bap: add timer to wait for SID update before PA sync Yang Li via B4 Relay
1 sibling, 1 reply; 4+ messages in thread
From: Yang Li via B4 Relay @ 2026-01-07 8:51 UTC (permalink / raw)
To: Linux Bluetooth; +Cc: Yang Li
From: Yang Li <yang.li@amlogic.com>
Add the MGMT_EV_EXT_ADV_SID_CHANGED mgmt event to notify userspace
of SID updates for extended advertising.
Signed-off-by: Yang Li <yang.li@amlogic.com>
---
lib/bluetooth/mgmt.h | 7 +++++++
src/adapter.c | 39 +++++++++++++++++++++++++++++++++++++--
src/device.c | 22 ++++++++++++++++++++++
src/device.h | 2 ++
4 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/lib/bluetooth/mgmt.h b/lib/bluetooth/mgmt.h
index 1ad52529f..338d2a732 100644
--- a/lib/bluetooth/mgmt.h
+++ b/lib/bluetooth/mgmt.h
@@ -1107,6 +1107,12 @@ struct mgmt_ev_mesh_pkt_cmplt {
uint8_t handle;
} __packed;
+#define MGMT_EV_EXT_ADV_SID_CHANGED 0x0033
+struct mgmt_ev_ext_adv_sid_changed {
+ struct mgmt_addr_info addr;
+ uint8_t sid;
+} __packed;
+
static const char *mgmt_op[] = {
"<0x0000>",
"Read Version",
@@ -1253,6 +1259,7 @@ static const char *mgmt_ev[] = {
"Advertisement Monitor Device Lost",
"Mesh Packet Found",
"Mesh Packet Complete",
+ "Extended Advertising SID Changed",
"PA Sync Established",
"BIG Sync Established",
"BIG Sync Lost",
diff --git a/src/adapter.c b/src/adapter.c
index a5de7cee1..ee6a1e711 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -84,6 +84,7 @@
#define SCAN_TYPE_DUAL (SCAN_TYPE_BREDR | SCAN_TYPE_LE)
#define HCI_RSSI_INVALID 127
+#define HCI_SID_INVALID 0xff
#define DISTANCE_VAL_INVALID 0x7FFF
#define PATHLOSS_MAX 137
@@ -7446,6 +7447,7 @@ void btd_adapter_device_found(struct btd_adapter *adapter,
}
device_set_legacy(dev, legacy);
+ device_set_sid(dev, HCI_SID_INVALID);
if (name_resolve_failed)
device_name_resolve_fail(dev);
@@ -7601,14 +7603,42 @@ static void device_found_callback(uint16_t index, uint16_t length,
flags = le32_to_cpu(ev->flags);
ba2str(&ev->addr.bdaddr, addr);
- DBG("hci%u addr %s, rssi %d flags 0x%04x eir_len %u",
- index, addr, ev->rssi, flags, eir_len);
+ DBG("hci%u addr %s type %u, rssi %d flags 0x%04x eir_len %u",
+ index, addr, ev->addr.type, ev->rssi, flags, eir_len);
btd_adapter_device_found(adapter, &ev->addr.bdaddr,
ev->addr.type, ev->rssi, flags,
eir, eir_len, false);
}
+static void device_ext_adv_sid_changed_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_ev_ext_adv_sid_changed *ev = param;
+ struct btd_adapter *adapter = user_data;
+ struct btd_device *dev;
+ char addr[18];
+
+ if (length < sizeof(*ev)) {
+ btd_error(adapter->dev_id,
+ "Too short ext adv sid changed event (%u bytes)",
+ length);
+ return;
+ }
+
+ ba2str(&ev->addr.bdaddr, addr);
+ DBG("hci%u addr %s type %u, sid %u", index, addr, ev->addr.type, ev->sid);
+
+ dev = btd_adapter_find_device(adapter, &ev->addr.bdaddr,
+ ev->addr.type);
+ if (!dev) {
+ DBG("No device found for ext adv sid change event");
+ return;
+ }
+
+ device_set_sid(dev, ev->sid);
+}
+
struct agent *adapter_get_agent(struct btd_adapter *adapter)
{
return agent_get(NULL);
@@ -10424,6 +10454,11 @@ static void read_info_complete(uint8_t status, uint16_t length,
device_found_callback,
adapter, NULL);
+ mgmt_register(adapter->mgmt, MGMT_EV_EXT_ADV_SID_CHANGED,
+ adapter->dev_id,
+ device_ext_adv_sid_changed_callback,
+ adapter, NULL);
+
mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_DISCONNECTED,
adapter->dev_id,
disconnected_callback,
diff --git a/src/device.c b/src/device.c
index c8aaf042f..827b897ab 100644
--- a/src/device.c
+++ b/src/device.c
@@ -298,6 +298,7 @@ struct btd_device {
gboolean general_connect;
bool legacy;
+ uint8_t sid;
int8_t rssi;
int8_t tx_power;
@@ -7106,6 +7107,27 @@ void device_set_rssi(struct btd_device *device, int8_t rssi)
device_set_rssi_with_delta(device, rssi, RSSI_THRESHOLD);
}
+void device_set_sid(struct btd_device *device, uint8_t sid)
+{
+ if (!device)
+ return;
+
+ if (device->sid == sid)
+ return;
+
+ DBG("sid %d", sid);
+
+ device->sid = sid;
+}
+
+uint8_t device_get_sid(struct btd_device *device)
+{
+ if (!device)
+ return 0xFF;
+
+ return device->sid;
+}
+
void device_set_tx_power(struct btd_device *device, int8_t tx_power)
{
if (!device)
diff --git a/src/device.h b/src/device.h
index c7b8b2a16..82332001e 100644
--- a/src/device.h
+++ b/src/device.h
@@ -108,6 +108,8 @@ void device_set_cable_pairing(struct btd_device *device, bool cable_pairing);
void device_set_rssi_with_delta(struct btd_device *device, int8_t rssi,
int8_t delta_threshold);
void device_set_rssi(struct btd_device *device, int8_t rssi);
+void device_set_sid(struct btd_device *device, uint8_t sid);
+uint8_t device_get_sid(struct btd_device *device);
void device_set_tx_power(struct btd_device *device, int8_t tx_power);
void device_set_flags(struct btd_device *device, uint8_t flags);
bool btd_device_is_connected(struct btd_device *dev);
--
2.42.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH BlueZ bluez 2/2] bap: add timer to wait for SID update before PA sync
2026-01-07 8:51 [PATCH BlueZ bluez 0/2] Optimize the PA sync flow Yang Li via B4 Relay
2026-01-07 8:51 ` [PATCH BlueZ bluez 1/2] adapter: add MGMT_EV_EXT_ADV_SID_CHANGED mgmt event Yang Li via B4 Relay
@ 2026-01-07 8:51 ` Yang Li via B4 Relay
1 sibling, 0 replies; 4+ messages in thread
From: Yang Li via B4 Relay @ 2026-01-07 8:51 UTC (permalink / raw)
To: Linux Bluetooth; +Cc: Yang Li
From: Yang Li <yang.li@amlogic.com>
Add a timer to wait for the SID to become valid before triggering
PA sync. Once the SID is available, PA sync is initiated accordingly.
Fixes: https://github.com/bluez/bluez/issues/1758
Signed-off-by: Yang Li <yang.li@amlogic.com>
---
profiles/audio/bap.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index b6eb91ab3..360e0a309 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -48,6 +48,7 @@
#include "src/shared/bap.h"
#include "src/shared/tmap.h"
#include "src/shared/gmap.h"
+#include "src/shared/timeout.h"
#include "btio/btio.h"
#include "src/plugin.h"
@@ -140,6 +141,8 @@ struct bap_data {
struct queue *server_streams;
GIOChannel *listen_io;
unsigned int io_id;
+ unsigned int listen_retry_id;
+ int listen_retry_tries;
unsigned int cig_update_id;
bool services_ready;
bool bap_ready;
@@ -176,6 +179,9 @@ static void bap_data_free(struct bap_data *data)
{
struct queue *bcast_snks = data->bcast_snks;
+ if (data->listen_retry_id)
+ timeout_remove(data->listen_retry_id);
+
if (data->listen_io) {
g_io_channel_shutdown(data->listen_io, TRUE, NULL);
g_io_channel_unref(data->listen_io);
@@ -3573,16 +3579,55 @@ static void bap_detached(struct bt_bap *bap, void *user_data)
bap_data_remove(data);
}
+static bool pa_sync_retry_cb(gpointer user_data)
+{
+ struct bap_data *data = user_data;
+ uint8_t sid = device_get_sid(data->device);
+
+ if (!data)
+ return FALSE;
+
+ data->listen_retry_tries++;
+ if (data->listen_retry_tries >= 2) {
+ data->listen_retry_id = 0;
+ data->listen_retry_tries = 0;
+ btd_adapter_remove_device(data->adapter, data->device);
+ return FALSE;
+ }
+
+ if (sid != 0xFF) {
+ data->listen_retry_id = 0;
+ data->listen_retry_tries = 0;
+ pa_sync(data);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static int pa_sync(struct bap_data *data)
{
GError *err = NULL;
- uint8_t sid = 0xff;
+ uint8_t sid = device_get_sid(data->device);
if (data->listen_io) {
DBG("Already probed");
return -1;
}
+ /*
+ * If SID is not yet available, wait MGMT_EV_EXT_ADV_SID_CHANGED event
+ * to update it and retry PA sync creation.
+ */
+ if (sid == 0xFF) {
+ DBG("SID not available, scheduling retry for PA sync");
+ if (data->listen_retry_id == 0)
+ data->listen_retry_id =
+ timeout_add(5, pa_sync_retry_cb, data, NULL);
+
+ return -1;
+ }
+
DBG("Create PA sync with this source");
data->listen_io = bt_io_listen(NULL, iso_pa_sync_confirm_cb, data,
--
2.42.0
^ permalink raw reply related [flat|nested] 4+ messages in thread