2023-08-08 16:46:04

by Claudia Draghicescu

[permalink] [raw]
Subject: [PATCH BlueZ v5 6/7] media: Add broadcast sink media endpoint

This patch adds the possibility to register a broadcast
media endpoint if the controller has support for ISO Sync Receiver.
---
profiles/audio/media.c | 82 +++++++++++++++++++++++++++++++++---------
profiles/audio/media.h | 3 +-
2 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index 15c64c8d6..59143060b 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -105,6 +105,7 @@ struct media_endpoint {
GSList *requests;
struct media_adapter *adapter;
GSList *transports;
+ bool broadcast;
};

struct media_player {
@@ -1058,7 +1059,9 @@ static struct media_transport *pac_bcast_config(struct bt_bap_stream *stream,
struct media_endpoint *endpoint)
{
struct bt_bap *bap = bt_bap_stream_get_session(stream);
- struct btd_adapter *adapter = bt_bap_get_user_data(bap);
+ struct btd_adapter *adapter = endpoint->adapter->btd_adapter;
+ struct btd_device *device =
+ btd_service_get_device(bt_bap_get_user_data(bap));
const char *path;

if (!adapter) {
@@ -1066,9 +1069,17 @@ static struct media_transport *pac_bcast_config(struct bt_bap_stream *stream,
return NULL;
}

+ if (!device) {
+ DBG("no device found");
+ } else {
+ char name[30];
+
+ device_get_name(device, name, 30);
+ DBG("device found name %s", name);
+ }
path = bt_bap_stream_get_user_data(stream);

- return media_transport_create(NULL, path, cfg->iov_base, cfg->iov_len,
+ return media_transport_create(device, path, cfg->iov_base, cfg->iov_len,
endpoint, stream);
}

@@ -1238,6 +1249,12 @@ static bool endpoint_init_broadcast_source(struct media_endpoint *endpoint,
return endpoint_init_pac(endpoint, BT_BAP_BCAST_SOURCE, err);
}

+static bool endpoint_init_broadcast_sink(struct media_endpoint *endpoint,
+ int *err)
+{
+ return endpoint_init_pac(endpoint, BT_BAP_BCAST_SINK, err);
+}
+
static bool endpoint_properties_exists(const char *uuid,
struct btd_device *dev,
void *user_data)
@@ -1351,6 +1368,17 @@ static bool experimental_broadcaster_ep_supported(struct btd_adapter *adapter)
return g_dbus_get_flags() & G_DBUS_FLAG_ENABLE_EXPERIMENTAL;
}

+static bool experimental_bcast_sink_ep_supported(struct btd_adapter *adapter)
+{
+ if (!btd_adapter_has_exp_feature(adapter, EXP_FEAT_ISO_SOCKET))
+ return false;
+
+ if (!btd_adapter_has_settings(adapter, MGMT_SETTING_ISO_SYNC_RECEIVER))
+ return false;
+
+ return g_dbus_get_flags() & G_DBUS_FLAG_ENABLE_EXPERIMENTAL;
+}
+
static struct media_endpoint_init {
const char *uuid;
bool (*func)(struct media_endpoint *endpoint, int *err);
@@ -1366,6 +1394,8 @@ static struct media_endpoint_init {
experimental_endpoint_supported },
{ BCAA_SERVICE_UUID, endpoint_init_broadcast_source,
experimental_broadcaster_ep_supported },
+ { BAA_SERVICE_UUID, endpoint_init_broadcast_sink,
+ experimental_bcast_sink_ep_supported },
};

static struct media_endpoint *
@@ -1382,6 +1412,7 @@ media_endpoint_create(struct media_adapter *adapter,
int size,
uint8_t *metadata,
int metadata_size,
+ bool broadcast,
int *err)
{
struct media_endpoint *endpoint;
@@ -1397,6 +1428,7 @@ media_endpoint_create(struct media_adapter *adapter,
endpoint->cid = cid;
endpoint->vid = vid;
endpoint->delay_reporting = delay_reporting;
+ endpoint->broadcast = broadcast;

if (qos)
endpoint->qos = *qos;
@@ -1458,11 +1490,11 @@ struct vendor {
} __packed;

static int parse_properties(DBusMessageIter *props, const char **uuid,
- gboolean *delay_reporting, uint8_t *codec,
- uint16_t *cid, uint16_t *vid,
- struct bt_bap_pac_qos *qos,
- uint8_t **capabilities, int *size,
- uint8_t **metadata, int *metadata_size)
+ gboolean *delay_reporting, uint8_t *codec,
+ uint16_t *cid, uint16_t *vid,
+ struct bt_bap_pac_qos *qos,
+ uint8_t **capabilities, int *size,
+ uint8_t **metadata, int *metadata_size, bool *broadcast)
{
gboolean has_uuid = FALSE;
gboolean has_codec = FALSE;
@@ -1546,6 +1578,10 @@ static int parse_properties(DBusMessageIter *props, const char **uuid,
if (var != DBUS_TYPE_UINT16)
return -EINVAL;
dbus_message_iter_get_basic(&value, &qos->ppd_max);
+ } else if (strcasecmp(key, "Broadcast") == 0) {
+ if (var != DBUS_TYPE_BOOLEAN)
+ return -EINVAL;
+ dbus_message_iter_get_basic(&value, broadcast);
}

dbus_message_iter_next(props);
@@ -1569,6 +1605,7 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
uint8_t *metadata = NULL;
int size = 0;
int metadata_size = 0;
+ bool broadcast = false;
int err;

sender = dbus_message_get_sender(msg);
@@ -1587,13 +1624,13 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,

if (parse_properties(&props, &uuid, &delay_reporting, &codec, &cid,
&vid, &qos, &capabilities, &size, &metadata,
- &metadata_size) < 0)
+ &metadata_size, &broadcast) < 0)
return btd_error_invalid_args(msg);

if (media_endpoint_create(adapter, sender, path, uuid, delay_reporting,
- codec, cid, vid, &qos, capabilities,
- size, metadata, metadata_size,
- &err) == NULL) {
+ codec, cid, vid, &qos, capabilities,
+ size, metadata, metadata_size, broadcast,
+ &err) == NULL) {
if (err == -EPROTONOSUPPORT)
return btd_error_not_supported(msg);
else
@@ -2627,6 +2664,7 @@ static void app_register_endpoint(void *data, void *user_data)
int metadata_size = 0;
DBusMessageIter iter, array;
struct media_endpoint *endpoint;
+ bool broadcast = false;

if (app->err)
return;
@@ -2736,12 +2774,18 @@ static void app_register_endpoint(void *data, void *user_data)
dbus_message_iter_get_basic(&iter, &qos.ppd_min);
}

+ if (g_dbus_proxy_get_property(proxy, "Broadcast", &iter)) {
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
+ goto fail;
+ dbus_message_iter_get_basic(&iter, &broadcast);
+ }
+
endpoint = media_endpoint_create(app->adapter, app->sender, path, uuid,
- delay_reporting, codec,
- vendor.cid, vendor.vid, &qos,
- capabilities, size,
- metadata, metadata_size,
- &app->err);
+ delay_reporting, codec,
+ vendor.cid, vendor.vid, &qos,
+ capabilities, size,
+ metadata, metadata_size, broadcast,
+ &app->err);
if (!endpoint) {
error("Unable to register endpoint %s:%s: %s", app->sender,
path, strerror(-app->err));
@@ -3245,3 +3289,9 @@ struct btd_adapter *media_endpoint_get_btd_adapter(
{
return endpoint->adapter->btd_adapter;
}
+
+bool media_endpoint_is_broadcast(
+ struct media_endpoint *endpoint)
+{
+ return endpoint->broadcast;
+}
diff --git a/profiles/audio/media.h b/profiles/audio/media.h
index 1de84a8ff..0eeb5746a 100644
--- a/profiles/audio/media.h
+++ b/profiles/audio/media.h
@@ -22,5 +22,6 @@ const char *media_endpoint_get_uuid(struct media_endpoint *endpoint);
uint8_t media_endpoint_get_codec(struct media_endpoint *endpoint);
struct btd_adapter *media_endpoint_get_btd_adapter(
struct media_endpoint *endpoint);
-
+bool media_endpoint_is_broadcast(
+ struct media_endpoint *endpoint);
int8_t media_player_get_device_volume(struct btd_device *device);
--
2.34.1



2023-08-09 18:34:29

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH BlueZ v5 6/7] media: Add broadcast sink media endpoint

Hi Claudia,

On Tue, Aug 8, 2023 at 9:46 AM Claudia Draghicescu <[email protected]> wrote:
>
> This patch adds the possibility to register a broadcast
> media endpoint if the controller has support for ISO Sync Receiver.
> ---
> profiles/audio/media.c | 82 +++++++++++++++++++++++++++++++++---------
> profiles/audio/media.h | 3 +-
> 2 files changed, 68 insertions(+), 17 deletions(-)
>
> diff --git a/profiles/audio/media.c b/profiles/audio/media.c
> index 15c64c8d6..59143060b 100644
> --- a/profiles/audio/media.c
> +++ b/profiles/audio/media.c
> @@ -105,6 +105,7 @@ struct media_endpoint {
> GSList *requests;
> struct media_adapter *adapter;
> GSList *transports;
> + bool broadcast;

Can't we use the uuid to determine if it is a broadcast or not?

> };
>
> struct media_player {
> @@ -1058,7 +1059,9 @@ static struct media_transport *pac_bcast_config(struct bt_bap_stream *stream,
> struct media_endpoint *endpoint)
> {
> struct bt_bap *bap = bt_bap_stream_get_session(stream);
> - struct btd_adapter *adapter = bt_bap_get_user_data(bap);
> + struct btd_adapter *adapter = endpoint->adapter->btd_adapter;
> + struct btd_device *device =
> + btd_service_get_device(bt_bap_get_user_data(bap));
> const char *path;
>
> if (!adapter) {
> @@ -1066,9 +1069,17 @@ static struct media_transport *pac_bcast_config(struct bt_bap_stream *stream,
> return NULL;
> }
>
> + if (!device) {
> + DBG("no device found");
> + } else {
> + char name[30];
> +
> + device_get_name(device, name, 30);
> + DBG("device found name %s", name);
> + }

Seems like a leftover to debug if the code is working properly, on the
final version this is probably not needed.

> path = bt_bap_stream_get_user_data(stream);
>
> - return media_transport_create(NULL, path, cfg->iov_base, cfg->iov_len,
> + return media_transport_create(device, path, cfg->iov_base, cfg->iov_len,
> endpoint, stream);
> }
>
> @@ -1238,6 +1249,12 @@ static bool endpoint_init_broadcast_source(struct media_endpoint *endpoint,
> return endpoint_init_pac(endpoint, BT_BAP_BCAST_SOURCE, err);
> }
>
> +static bool endpoint_init_broadcast_sink(struct media_endpoint *endpoint,
> + int *err)
> +{
> + return endpoint_init_pac(endpoint, BT_BAP_BCAST_SINK, err);
> +}
> +
> static bool endpoint_properties_exists(const char *uuid,
> struct btd_device *dev,
> void *user_data)
> @@ -1351,6 +1368,17 @@ static bool experimental_broadcaster_ep_supported(struct btd_adapter *adapter)
> return g_dbus_get_flags() & G_DBUS_FLAG_ENABLE_EXPERIMENTAL;
> }
>
> +static bool experimental_bcast_sink_ep_supported(struct btd_adapter *adapter)
> +{
> + if (!btd_adapter_has_exp_feature(adapter, EXP_FEAT_ISO_SOCKET))
> + return false;
> +
> + if (!btd_adapter_has_settings(adapter, MGMT_SETTING_ISO_SYNC_RECEIVER))
> + return false;
> +
> + return g_dbus_get_flags() & G_DBUS_FLAG_ENABLE_EXPERIMENTAL;
> +}
> +
> static struct media_endpoint_init {
> const char *uuid;
> bool (*func)(struct media_endpoint *endpoint, int *err);
> @@ -1366,6 +1394,8 @@ static struct media_endpoint_init {
> experimental_endpoint_supported },
> { BCAA_SERVICE_UUID, endpoint_init_broadcast_source,
> experimental_broadcaster_ep_supported },
> + { BAA_SERVICE_UUID, endpoint_init_broadcast_sink,
> + experimental_bcast_sink_ep_supported },
> };
>
> static struct media_endpoint *
> @@ -1382,6 +1412,7 @@ media_endpoint_create(struct media_adapter *adapter,
> int size,
> uint8_t *metadata,
> int metadata_size,
> + bool broadcast,
> int *err)
> {
> struct media_endpoint *endpoint;
> @@ -1397,6 +1428,7 @@ media_endpoint_create(struct media_adapter *adapter,
> endpoint->cid = cid;
> endpoint->vid = vid;
> endpoint->delay_reporting = delay_reporting;
> + endpoint->broadcast = broadcast;
>
> if (qos)
> endpoint->qos = *qos;
> @@ -1458,11 +1490,11 @@ struct vendor {
> } __packed;
>
> static int parse_properties(DBusMessageIter *props, const char **uuid,
> - gboolean *delay_reporting, uint8_t *codec,
> - uint16_t *cid, uint16_t *vid,
> - struct bt_bap_pac_qos *qos,
> - uint8_t **capabilities, int *size,
> - uint8_t **metadata, int *metadata_size)
> + gboolean *delay_reporting, uint8_t *codec,
> + uint16_t *cid, uint16_t *vid,
> + struct bt_bap_pac_qos *qos,
> + uint8_t **capabilities, int *size,
> + uint8_t **metadata, int *metadata_size, bool *broadcast)
> {
> gboolean has_uuid = FALSE;
> gboolean has_codec = FALSE;
> @@ -1546,6 +1578,10 @@ static int parse_properties(DBusMessageIter *props, const char **uuid,
> if (var != DBUS_TYPE_UINT16)
> return -EINVAL;
> dbus_message_iter_get_basic(&value, &qos->ppd_max);
> + } else if (strcasecmp(key, "Broadcast") == 0) {
> + if (var != DBUS_TYPE_BOOLEAN)
> + return -EINVAL;
> + dbus_message_iter_get_basic(&value, broadcast);

I'm not in favor of adding yet another if we can distinct the endpoint
based on their uuid.

> }
>
> dbus_message_iter_next(props);
> @@ -1569,6 +1605,7 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
> uint8_t *metadata = NULL;
> int size = 0;
> int metadata_size = 0;
> + bool broadcast = false;
> int err;
>
> sender = dbus_message_get_sender(msg);
> @@ -1587,13 +1624,13 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
>
> if (parse_properties(&props, &uuid, &delay_reporting, &codec, &cid,
> &vid, &qos, &capabilities, &size, &metadata,
> - &metadata_size) < 0)
> + &metadata_size, &broadcast) < 0)
> return btd_error_invalid_args(msg);
>
> if (media_endpoint_create(adapter, sender, path, uuid, delay_reporting,
> - codec, cid, vid, &qos, capabilities,
> - size, metadata, metadata_size,
> - &err) == NULL) {
> + codec, cid, vid, &qos, capabilities,
> + size, metadata, metadata_size, broadcast,
> + &err) == NULL) {
> if (err == -EPROTONOSUPPORT)
> return btd_error_not_supported(msg);
> else
> @@ -2627,6 +2664,7 @@ static void app_register_endpoint(void *data, void *user_data)
> int metadata_size = 0;
> DBusMessageIter iter, array;
> struct media_endpoint *endpoint;
> + bool broadcast = false;
>
> if (app->err)
> return;
> @@ -2736,12 +2774,18 @@ static void app_register_endpoint(void *data, void *user_data)
> dbus_message_iter_get_basic(&iter, &qos.ppd_min);
> }
>
> + if (g_dbus_proxy_get_property(proxy, "Broadcast", &iter)) {
> + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
> + goto fail;
> + dbus_message_iter_get_basic(&iter, &broadcast);
> + }
> +
> endpoint = media_endpoint_create(app->adapter, app->sender, path, uuid,
> - delay_reporting, codec,
> - vendor.cid, vendor.vid, &qos,
> - capabilities, size,
> - metadata, metadata_size,
> - &app->err);
> + delay_reporting, codec,
> + vendor.cid, vendor.vid, &qos,
> + capabilities, size,
> + metadata, metadata_size, broadcast,
> + &app->err);
> if (!endpoint) {
> error("Unable to register endpoint %s:%s: %s", app->sender,
> path, strerror(-app->err));
> @@ -3245,3 +3289,9 @@ struct btd_adapter *media_endpoint_get_btd_adapter(
> {
> return endpoint->adapter->btd_adapter;
> }
> +
> +bool media_endpoint_is_broadcast(
> + struct media_endpoint *endpoint)
> +{
> + return endpoint->broadcast;
> +}
> diff --git a/profiles/audio/media.h b/profiles/audio/media.h
> index 1de84a8ff..0eeb5746a 100644
> --- a/profiles/audio/media.h
> +++ b/profiles/audio/media.h
> @@ -22,5 +22,6 @@ const char *media_endpoint_get_uuid(struct media_endpoint *endpoint);
> uint8_t media_endpoint_get_codec(struct media_endpoint *endpoint);
> struct btd_adapter *media_endpoint_get_btd_adapter(
> struct media_endpoint *endpoint);
> -
> +bool media_endpoint_is_broadcast(
> + struct media_endpoint *endpoint);
> int8_t media_player_get_device_volume(struct btd_device *device);
> --
> 2.34.1
>


--
Luiz Augusto von Dentz