Hi, On Tue, Aug 19, 2025 at 3:41 AM Ye He <ye.he@xxxxxxxxxxx> wrote: > > Hi Luiz, > > Hi, > > On Fri, Aug 15, 2025 at 6:04 AM Ye He <ye.he@xxxxxxxxxxx> wrote: > > Hi Luiz, > > Hi, > > On Wed, Aug 13, 2025 at 3:12 AM Ye He via B4 Relay > <devnull+ye.he.amlogic.com@xxxxxxxxxx> wrote: > > From: Ye He <ye.he@xxxxxxxxxxx> > > This patch introduces a new SyncBroadcast method to the device1 interface, > allowing users to explicitly choose which broadcast source device to > synchronize with. > > Hold on, why do you think we don't have a explicit way to select the > broadcast to synchronize? Have you read Transport.Select > documentation: > > https://github.com/bluez/bluez/blob/master/doc/org.bluez.MediaTransport.rst#void-select > > Also if the plan is to introduce another method to enumerate > MediaTransport for Broadcaster I don't think it is a good idea since > it affect scan state anyway and then we have the problem that the > device needs to be discovered first in order to have an object. > > > As far as I understand, the Transport.Select method is intended > for selecting a BIS to synchronize with when there are multiple > BISes within a broadcast device. > > However, if there are multiple broadcast devices, BlueZ currently > defaults to synchronizing with the first one it encounters during > the LE discovery procedure, which may not what the user expects. > > By introducing a new SyncBroadcast method in device1, the application > layer could choose the target one to synchronize with from cached > broadcast devices based on their own criteria — for example, choosing > the device with the strongest RSSI or device with custom UUIDs. > > You are confusing PA Sync with BIG Sync, during the general discovery > what BlueZ does is a short lived PA Sync to discover the streams > configuration (BASE), it _doesn't_ do a BIG sync, then the user can > use Transport.Select to select which stream(s) to synchronize. > > > I'm sorry for previously confusing PA sync with BIG sync. After reviewing the > BIS synchronization process, I believe the actual issue I encountered is that > when multiple BIS source devices are present, BlueZ currently establishes PA > sync with the first device it discovers by default. That is not the entire explanation, the PA sync is done for every Broadcast found, not just the first: https://github.com/bluez/bluez/blob/master/profiles/audio/bap.c#L3651 > In this case, the application layer has no way to select the target broadcast > device — it can only accept the one that BlueZ chooses by default for creating > PA sync. To address this limitation, I suggest introducing a new method > (e.g., Device1.SyncPA) that would allow applications to explicitly select the > desired device for PA synchronization. > > Signed-off-by: Ye He <ye.he@xxxxxxxxxxx> > --- > doc/org.bluez.Device.rst | 15 +++++++++++++++ > plugins/neard.c | 2 +- > src/adapter.c | 4 ++-- > src/device.c | 39 ++++++++++++++++++++++++++++++++++++--- > src/device.h | 3 ++- > 5 files changed, 56 insertions(+), 7 deletions(-) > > diff --git a/doc/org.bluez.Device.rst b/doc/org.bluez.Device.rst > index 61c394dd2d0b371fe10508b8e64087ed87a2e6e0..44d929e8850659cdfbcafa81f18dd44e4aa53d03 100644 > --- a/doc/org.bluez.Device.rst > +++ b/doc/org.bluez.Device.rst > @@ -155,6 +155,21 @@ Possible errors: > :org.bluez.Error.NotConnected: > :org.bluez.Error.DoesNotExist: > > +void SyncBroadcast() [experimental] > +``````````````````````````````````` > + > +Initiates synchronization with a broadcast source device that contains Broadcast > +Announcements UUID. This method can be used on devices that are capable of > +broadcast synchronization. > > +If the device is not capable of broadcast synchronization, this method will > +fail with `org.bluez.Error.NotSupported`. > + > +Possible errors: > + > +:org.bluez.Error.Failed: > +:org.bluez.Error.NotSupported: > + > Signals > ------- > > diff --git a/plugins/neard.c b/plugins/neard.c > index c84934025cd8541bf604efe9520c1c3e9c83068f..8c231a8e84b0090b450f3b61e75cc4d4c6e4a14f 100644 > --- a/plugins/neard.c > +++ b/plugins/neard.c > @@ -633,7 +633,7 @@ static void store_params(struct btd_adapter *adapter, struct btd_device *device, > } > > if (params->services) > - device_add_eir_uuids(device, params->services); > + device_add_eir_uuids(device, params->services, true); > > if (params->hash) { > btd_adapter_add_remote_oob_data(adapter, ¶ms->address, > diff --git a/src/adapter.c b/src/adapter.c > index b771cf66ade30dcfe0a6fa41cd28f1ba46bed5a4..b12d75c815ee936aeaf3210f97831eee8ee945a2 100644 > --- a/src/adapter.c > +++ b/src/adapter.c > @@ -1740,7 +1740,7 @@ static void discovery_cleanup(struct btd_adapter *adapter, int timeout) > next = g_slist_next(l); > > if (device_is_temporary(dev) && !device_is_connectable(dev) > - && !btd_device_is_connected(dev)) > + && !btd_device_is_connected(dev) && !btd_device_is_bcast_syncable(dev)) > btd_adapter_remove_device(adapter, dev); > } > } > @@ -7452,7 +7452,7 @@ void btd_adapter_device_found(struct btd_adapter *adapter, > eir_data.did_product, > eir_data.did_version); > > - device_add_eir_uuids(dev, eir_data.services); > + device_add_eir_uuids(dev, eir_data.services, false); > > if (adapter->discovery_list) > g_slist_foreach(adapter->discovery_list, filter_duplicate_data, > diff --git a/src/device.c b/src/device.c > index 0179c3dab603ece0faedfd122c87b99f35a2ca6e..410a051391529799d83102d3e8b041a264fd415a 100644 > --- a/src/device.c > +++ b/src/device.c > @@ -78,6 +78,8 @@ > > #define RSSI_THRESHOLD 8 > > +#define BCAAS_UUID_STR "00001852-0000-1000-8000-00805f9b34fb" > + > static DBusConnection *dbus_conn = NULL; > static unsigned service_state_cb_id; > > @@ -2356,7 +2358,7 @@ done: > dev->connect = NULL; > } > > -void device_add_eir_uuids(struct btd_device *dev, GSList *uuids) > +void device_add_eir_uuids(struct btd_device *dev, GSList *uuids, bool probe) > { > GSList *l; > GSList *added = NULL; > @@ -2372,7 +2374,8 @@ void device_add_eir_uuids(struct btd_device *dev, GSList *uuids) > dev->eir_uuids = g_slist_append(dev->eir_uuids, g_strdup(str)); > } > > - device_probe_profiles(dev, added); > + if (probe) > + device_probe_profiles(dev, added); > } > > static void add_manufacturer_data(void *data, void *user_data) > @@ -2411,7 +2414,7 @@ static void add_service_data(void *data, void *user_data) > return; > > l = g_slist_append(NULL, sd->uuid); > - device_add_eir_uuids(dev, l); > + device_add_eir_uuids(dev, l, false); > g_slist_free(l); > > g_dbus_emit_property_changed(dbus_conn, dev->path, > @@ -3488,6 +3491,21 @@ static DBusMessage *get_service_records(DBusConnection *conn, DBusMessage *msg, > return reply; > } > > +static DBusMessage *sync_broadcast_device(DBusConnection *conn, DBusMessage *msg, > + void *user_data) > +{ > + struct btd_device *dev = user_data; > + > + DBG("Sync with broadcast device %s", batostr(&dev->bdaddr)); > + > + if (!btd_device_is_bcast_syncable(dev)) > + return btd_error_not_supported(msg); > + > + btd_device_add_uuid(dev, BCAAS_UUID_STR); > + > + return dbus_message_new_method_return(msg); > +} > + > static const GDBusMethodTable device_methods[] = { > { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, dev_disconnect) }, > { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, dev_connect) }, > @@ -3500,6 +3518,7 @@ static const GDBusMethodTable device_methods[] = { > { GDBUS_EXPERIMENTAL_METHOD("GetServiceRecords", NULL, > GDBUS_ARGS({ "Records", "aay" }), > get_service_records) }, > + { GDBUS_EXPERIMENTAL_ASYNC_METHOD("SyncBroadcast", NULL, NULL, sync_broadcast_device) }, > { } > }; > > @@ -3654,6 +3673,20 @@ bool btd_device_bdaddr_type_connected(struct btd_device *dev, uint8_t type) > return dev->le_state.connected; > } > > +bool btd_device_is_bcast_syncable(struct btd_device *dev) > +{ > + if (dev->bredr_state.connected || dev->le_state.connected) > + return false; > + > + for (GSList *l = dev->eir_uuids; l != NULL; l = l->next) { > + const char *str = l->data; > + if (bt_uuid_strcmp(str, BCAAS_UUID_STR) == 0) > + return true; > + } > + > + return false; > +} > + > static void clear_temporary_timer(struct btd_device *dev) > { > if (dev->temporary_timer) { > diff --git a/src/device.h b/src/device.h > index 9e7c30ad71864932d3da2211f30e3c7ffc4b02f7..70f4dc1a11a12bce4514fcfa362c713d4d2a5235 100644 > --- a/src/device.h > +++ b/src/device.h > @@ -76,7 +76,7 @@ void btd_device_gatt_set_service_changed(struct btd_device *device, > uint16_t start, uint16_t end); > bool device_attach_att(struct btd_device *dev, GIOChannel *io); > void btd_device_add_uuid(struct btd_device *device, const char *uuid); > -void device_add_eir_uuids(struct btd_device *dev, GSList *uuids); > +void device_add_eir_uuids(struct btd_device *dev, GSList *uuids, bool probe); > void device_set_manufacturer_data(struct btd_device *dev, GSList *list, > bool duplicate); > void device_set_service_data(struct btd_device *dev, GSList *list, > @@ -110,6 +110,7 @@ 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); > bool btd_device_bearer_is_connected(struct btd_device *dev); > +bool btd_device_is_bcast_syncable(struct btd_device *dev); > bool btd_device_bdaddr_type_connected(struct btd_device *dev, uint8_t type); > uint8_t btd_device_get_bdaddr_type(struct btd_device *dev); > bool device_is_retrying(struct btd_device *device); > > --- > base-commit: 9cdbad590b7476b83e2ef240a486fd5159251be8 > change-id: 20250813-adapter-sync-bcast-871fb45c702a > > Best regards, > -- > Ye He <ye.he@xxxxxxxxxxx> > > > > > -- > Luiz Augusto von Dentz > > > -- > Luiz Augusto von Dentz -- Luiz Augusto von Dentz