Hi Claudia, On Tue, Aug 8, 2023 at 10:35 AM Claudia Draghicescu <claudia.rosu@xxxxxxx> wrote: > > This patch gets the QOS broadcast stream parameters and passes them > to upper layers. > --- > profiles/audio/transport.c | 245 ++++++++++++++++++++++++++++++++++++- > 1 file changed, 243 insertions(+), 2 deletions(-) > > diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c > index cf5662d1d..107339520 100644 > --- a/profiles/audio/transport.c > +++ b/profiles/audio/transport.c > @@ -552,6 +552,8 @@ static DBusMessage *acquire(DBusConnection *conn, DBusMessage *msg, > owner = media_owner_create(msg); > > if (!strcmp(media_endpoint_get_uuid(transport->endpoint), > + BAA_SERVICE_UUID) > + || !strcmp(media_endpoint_get_uuid(transport->endpoint), > BCAA_SERVICE_UUID)) { This code above is probably what media_endpoint_is_broadcast should be doing, so it matches by uuid. > req = media_request_create(msg, 0x00); > media_owner_add(owner, req); > @@ -853,6 +855,9 @@ static gboolean qos_exists(const GDBusPropertyTable *property, void *data) > struct media_transport *transport = data; > struct bap_transport *bap = transport->data; > > + if (media_endpoint_is_broadcast(transport->endpoint)) > + return bap->qos.bcast.io_qos.sdu != 0x00; > + > return bap->qos.ucast.io_qos.phy != 0x00; > } > > @@ -868,6 +873,18 @@ static gboolean get_cig(const GDBusPropertyTable *property, > return TRUE; > } > > +static gboolean get_big(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_transport *transport = data; > + struct bap_transport *bap = transport->data; > + > + dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, > + &bap->qos.bcast.big); > + > + return TRUE; > +} > + > static gboolean get_cis(const GDBusPropertyTable *property, > DBusMessageIter *iter, void *data) > { > @@ -880,6 +897,18 @@ static gboolean get_cis(const GDBusPropertyTable *property, > return TRUE; > } > > +static gboolean get_bis(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_transport *transport = data; > + struct bap_transport *bap = transport->data; > + > + dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, > + &bap->qos.bcast.bis); > + > + return TRUE; > +} > + > static gboolean get_interval(const GDBusPropertyTable *property, > DBusMessageIter *iter, void *data) > { > @@ -899,6 +928,9 @@ static gboolean get_framing(const GDBusPropertyTable *property, > struct bap_transport *bap = transport->data; > dbus_bool_t val = bap->qos.ucast.framing; > > + if (media_endpoint_is_broadcast(transport->endpoint)) > + val = bap->qos.bcast.framing; > + > dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val); > > return TRUE; > @@ -910,6 +942,12 @@ static gboolean get_phy(const GDBusPropertyTable *property, > struct media_transport *transport = data; > struct bap_transport *bap = transport->data; > > + if (media_endpoint_is_broadcast(transport->endpoint)) { > + dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, > + &bap->qos.bcast.io_qos.phy); > + return TRUE; > + } > + > dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, > &bap->qos.ucast.io_qos.phy); > > @@ -922,6 +960,12 @@ static gboolean get_sdu(const GDBusPropertyTable *property, > struct media_transport *transport = data; > struct bap_transport *bap = transport->data; > > + if (media_endpoint_is_broadcast(transport->endpoint)) { > + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, > + &bap->qos.bcast.io_qos.sdu); > + return TRUE; > + } > + > dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, > &bap->qos.ucast.io_qos.sdu); > > @@ -1040,6 +1084,121 @@ static gboolean get_links(const GDBusPropertyTable *property, > return TRUE; > } > > +static gboolean get_sync_interval(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_transport *transport = data; > + struct bap_transport *bap = transport->data; > + > + dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, > + &bap->qos.bcast.sync_interval); > + > + return TRUE; > +} > + > +static gboolean get_packing(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_transport *transport = data; > + struct bap_transport *bap = transport->data; > + > + dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, > + &bap->qos.bcast.packing); > + > + return TRUE; > +} > + > +static gboolean get_bcode(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_transport *transport = data; > + struct bap_transport *bap = transport->data; > + DBusMessageIter array; > + > + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, > + DBUS_TYPE_BYTE_AS_STRING, &array); > + > + if (bap->qos.bcast.bcode && bap->qos.bcast.bcode->iov_len) > + dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE, > + &bap->qos.bcast.bcode->iov_base, > + bap->qos.bcast.bcode->iov_len); > + > + dbus_message_iter_close_container(iter, &array); > + return TRUE; > +} > + > +static gboolean get_options(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_transport *transport = data; > + struct bap_transport *bap = transport->data; > + > + dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, > + &bap->qos.bcast.options); > + > + return TRUE; > +} > + > +static gboolean get_skip(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_transport *transport = data; > + struct bap_transport *bap = transport->data; > + > + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, > + &bap->qos.bcast.skip); > + > + return TRUE; > +} > + > +static gboolean get_sync_timeout(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_transport *transport = data; > + struct bap_transport *bap = transport->data; > + > + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, > + &bap->qos.bcast.sync_timeout); > + > + return TRUE; > +} > + > +static gboolean get_sync_cte_type(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_transport *transport = data; > + struct bap_transport *bap = transport->data; > + > + dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, > + &bap->qos.bcast.sync_cte_type); > + > + return TRUE; > +} > + > +static gboolean get_mse(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_transport *transport = data; > + struct bap_transport *bap = transport->data; > + > + dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, > + &bap->qos.bcast.mse); > + > + return TRUE; > +} > + > +static gboolean get_timeout(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct media_transport *transport = data; > + struct bap_transport *bap = transport->data; > + > + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, > + &bap->qos.bcast.timeout); > + > + return TRUE; > +} > + > static const GDBusPropertyTable bap_properties[] = { > { "Device", "o", get_device }, > { "UUID", "s", get_uuid }, > @@ -1059,6 +1218,17 @@ static const GDBusPropertyTable bap_properties[] = { > { "Location", "u", get_location }, > { "Metadata", "ay", get_metadata }, > { "Links", "ao", get_links, NULL, links_exists }, > + { "BIG", "y", get_big, NULL, qos_exists }, > + { "BIS", "y", get_bis, NULL, qos_exists }, > + { "SyncInterval", "y", get_sync_interval, NULL, qos_exists }, > + { "Packing", "y", get_packing, NULL, qos_exists }, > + { "BCode", "ay", get_bcode, NULL, qos_exists }, > + { "Options", "y", get_options, NULL, qos_exists }, > + { "Skip", "q", get_skip, NULL, qos_exists }, > + { "SyncTimeout", "q", get_sync_timeout, NULL, qos_exists }, > + { "SyncCteType", "y", get_sync_cte_type, NULL, qos_exists }, > + { "MSE", "y", get_mse, NULL, qos_exists }, > + { "Timeout", "q", get_timeout, NULL, qos_exists }, > { } > }; > > @@ -1341,6 +1511,71 @@ static gboolean bap_resume_wait_cb(void *data) > return FALSE; > } > > +static void bap_update_bcast_qos(const struct media_transport *transport) > +{ > + struct bap_transport *bap = transport->data; > + struct bt_bap_qos *qos; > + > + qos = bt_bap_stream_get_qos(bap->stream); > + > + if (!memcmp(qos, &bap->qos, sizeof(struct bt_bap_qos))) > + return; > + > + bap->qos = *qos; > + > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "BIG"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "BIS"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "SyncInterval"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "Packing"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "Framing"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "BCode"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "Options"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "Skip"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "SyncTimeout"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "SyncCteType"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "MSE"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "Timeout"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "Interval"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "Latency"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "PHY"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "SDU"); > + g_dbus_emit_property_changed(btd_get_dbus_connection(), > + transport->path, MEDIA_TRANSPORT_INTERFACE, > + "RTN"); > +} > + > static guint resume_bap(struct media_transport *transport, > struct media_owner *owner) > { > @@ -1493,7 +1728,10 @@ static void bap_state_changed(struct bt_bap_stream *stream, uint8_t old_state, > if (owner && owner->pending) > return; > bap_update_links(transport); > - bap_update_qos(transport); > + if (!media_endpoint_is_broadcast(transport->endpoint)) > + bap_update_qos(transport); > + else if (bt_bap_stream_io_dir(stream) != BT_BAP_BCAST_SOURCE) > + bap_update_bcast_qos(transport); > transport_update_playing(transport, FALSE); > return; > case BT_BAP_STREAM_STATE_DISABLING: > @@ -1503,6 +1741,8 @@ static void bap_state_changed(struct bt_bap_stream *stream, uint8_t old_state, > return; > break; > case BT_BAP_STREAM_STATE_STREAMING: > + if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE) > + bap_update_bcast_qos(transport); > break; > } > > @@ -1631,7 +1871,8 @@ struct media_transport *media_transport_create(struct btd_device *device, > properties = a2dp_properties; > } else if (!strcasecmp(uuid, PAC_SINK_UUID) || > !strcasecmp(uuid, PAC_SOURCE_UUID) || > - !strcasecmp(uuid, BCAA_SERVICE_UUID)) { > + !strcasecmp(uuid, BCAA_SERVICE_UUID) || > + !strcasecmp(uuid, BAA_SERVICE_UUID)) { > if (media_transport_init_bap(transport, stream) < 0) > goto fail; > properties = bap_properties; > -- > 2.34.1 > -- Luiz Augusto von Dentz