@@ -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)) {
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,77 @@ 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");
+ g_dbus_emit_property_changed(btd_get_dbus_connection(),
+ transport->path, MEDIA_TRANSPORT_INTERFACE,
+ "Codec");
+ g_dbus_emit_property_changed(btd_get_dbus_connection(),
+ transport->path, MEDIA_TRANSPORT_INTERFACE,
+ "Configuration");
+}
+
static guint resume_bap(struct media_transport *transport,
struct media_owner *owner)
{
@@ -1493,7 +1734,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 +1747,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 +1877,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;