Re: [PATCH bluez] As a BIS sink role, BlueZ currently defaults to synchronizing with the first broadcast source device discovered by the le discovery procedure. This behavior may not align with user expectations, as it removes control over the target device selection.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

>
> 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, &params->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





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux