diff mbox series

[BlueZ,v5,6/7] media: Add broadcast sink media endpoint

Message ID 20230808115040.4403-7-claudia.rosu@nxp.com
State New
Headers show
Series Add support for BAP broadcast sink | expand

Commit Message

Claudia Draghicescu Aug. 8, 2023, 11:50 a.m. UTC
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(-)

Comments

Luiz Augusto von Dentz Aug. 9, 2023, 6:01 p.m. UTC | #1
Hi Claudia,

On Tue, Aug 8, 2023 at 9:46 AM Claudia Draghicescu <claudia.rosu@nxp.com> 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
>
diff mbox series

Patch

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);