summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudia Draghicescu <claudia.rosu@nxp.com>2023-08-08 14:50:34 +0300
committerAyush Garg <ayush.garg@samsung.com>2024-01-05 19:04:03 +0530
commit2718c8752f0b011212fff7db620858ca2c6d4671 (patch)
treedd239abfeb511f6caed33ec5bdc69362278f4e9a
parentea1fbbf9dc60bd11e04e24a1dd21ada22df2f279 (diff)
downloadbluez-2718c8752f0b011212fff7db620858ca2c6d4671.tar.gz
bluez-2718c8752f0b011212fff7db620858ca2c6d4671.tar.bz2
bluez-2718c8752f0b011212fff7db620858ca2c6d4671.zip
client/player: Add broadcast sink endpoint
Added support for broadcast sink registration using the 0x1851 UUID. Added support for remote endpoint creation when a broadcast source is discovered. Added support for creating a local endpoint when the broadcast sink endpoint was registered from an external application (Pipewire). To test this feature use the following commands: [bluetooth]# endpoint.register 00001851-0000-1000-8000-00805f9b34fb 0x06 [bluetooth]# scan on [NEW] Endpoint /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/pac_bcast0 [bluetooth]# endpoint.config /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/pac_bcast0 /local/endpoint/ep0 16_2_1
-rw-r--r--client/player.c61
1 files changed, 53 insertions, 8 deletions
diff --git a/client/player.c b/client/player.c
index 136ef303..092348c6 100644
--- a/client/player.c
+++ b/client/player.c
@@ -1182,6 +1182,17 @@ static const struct capabilities {
CODEC_CAPABILITIES(BCAA_SERVICE_UUID, LC3_ID,
LC3_DATA(LC3_FREQ_ANY, LC3_DURATION_ANY,
3u, 30, 240)),
+
+ /* Broadcast LC3 Sink:
+ *
+ * Frequencies: 8Khz 11Khz 16Khz 22Khz 24Khz 32Khz 44.1Khz 48Khz
+ * Duration: 7.5 ms 10 ms
+ * Channel count: 3
+ * Frame length: 30-240
+ */
+ CODEC_CAPABILITIES(BAA_SERVICE_UUID, LC3_ID,
+ LC3_DATA(LC3_FREQ_ANY, LC3_DURATION_ANY,
+ 3u, 30, 240)),
};
struct codec_qos {
@@ -1464,6 +1475,7 @@ static struct preset {
PRESET(PAC_SINK_UUID, LC3_ID, lc3_presets, 3),
PRESET(PAC_SOURCE_UUID, LC3_ID, lc3_presets, 3),
PRESET(BCAA_SERVICE_UUID, LC3_ID, lc3_presets, 3),
+ PRESET(BAA_SERVICE_UUID, LC3_ID, lc3_presets, 3),
};
static void parse_vendor_codec(const char *codec, uint16_t *vid, uint16_t *cid)
@@ -2284,6 +2296,9 @@ static void register_endpoint_setup(DBusMessageIter *iter, void *user_data)
bt_shell_hexdump(ep->meta->iov_base, ep->meta->iov_len);
}
+ g_dbus_dict_append_entry(&dict, "Broadcast", DBUS_TYPE_BOOLEAN,
+ &ep->broadcast);
+
dbus_message_iter_close_container(iter, &dict);
}
@@ -2454,7 +2469,8 @@ static void endpoint_auto_accept(const char *input, void *user_data)
{
struct endpoint *ep = user_data;
- if (!strcmp(ep->uuid, BCAA_SERVICE_UUID)) {
+ if (!strcmp(ep->uuid, BCAA_SERVICE_UUID) ||
+ !strcmp(ep->uuid, BAA_SERVICE_UUID)) {
ep->broadcast = true;
} else {
ep->broadcast = false;
@@ -2727,13 +2743,20 @@ static void endpoint_config(const char *input, void *user_data)
endpoint_set_config(cfg);
}
+static struct endpoint *endpoint_new(const struct capabilities *cap);
+
static void cmd_config_endpoint(int argc, char *argv[])
{
struct endpoint_config *cfg;
const struct codec_preset *preset;
+ const struct capabilities *cap;
+ char *uuid;
+ uint8_t codec_id;
+ bool broadcast = false;
cfg = new0(struct endpoint_config, 1);
+ /* Search for the remote endpoint name on DBUS */
cfg->proxy = g_dbus_proxy_lookup(endpoints, NULL, argv[1],
BLUEZ_MEDIA_ENDPOINT_INTERFACE);
if (!cfg->proxy) {
@@ -2741,16 +2764,36 @@ static void cmd_config_endpoint(int argc, char *argv[])
goto fail;
}
+ /* Search for the local endpoint */
cfg->ep = endpoint_find(argv[2]);
if (!cfg->ep) {
- bt_shell_printf("Local Endpoint %s not found\n", argv[2]);
- goto fail;
+
+ /* When the local endpoint was not found either we received
+ * UUID, or the provided local endpoint is not available
+ */
+ uuid = argv[2];
+ codec_id = strtol(argv[3], NULL, 0);
+ cap = find_capabilities(uuid, codec_id);
+ if (cap) {
+ broadcast = true;
+ cfg->ep = endpoint_new(cap);
+ cfg->ep->preset = find_presets_name(uuid, argv[3]);
+ if (!cfg->ep->preset)
+ bt_shell_printf("Preset not found\n");
+ } else {
+ bt_shell_printf("Local Endpoint %s,"
+ "or capabilities not found\n", uuid);
+ goto fail;
+ }
}
- if (argc > 3) {
- preset = preset_find_name(cfg->ep->preset, argv[3]);
+ if (((broadcast == false) && (argc > 3)) ||
+ ((broadcast == true) && (argc > 4))) {
+ char *preset_name = (broadcast == false)?argv[3]:argv[4];
+
+ preset = preset_find_name(cfg->ep->preset, preset_name);
if (!preset) {
- bt_shell_printf("Preset %s not found\n", argv[3]);
+ bt_shell_printf("Preset %s not found\n", preset_name);
goto fail;
}
@@ -3171,7 +3214,8 @@ static const struct bt_shell_menu endpoint_menu = {
{ "unregister", "<UUID/object>", cmd_unregister_endpoint,
"Register Endpoint",
local_endpoint_generator },
- { "config", "<endpoint> <local endpoint> [preset]",
+ { "config",
+ "<endpoint> [local endpoint/UUID] [preset/codec id] [preset]",
cmd_config_endpoint,
"Configure Endpoint",
endpoint_generator },
@@ -3188,7 +3232,8 @@ static struct endpoint *endpoint_new(const struct capabilities *cap)
ep = new0(struct endpoint, 1);
ep->uuid = g_strdup(cap->uuid);
- ep->broadcast = strcmp(cap->uuid, BCAA_SERVICE_UUID) ? false : true;
+ ep->broadcast = (strcmp(cap->uuid, BCAA_SERVICE_UUID) &&
+ strcmp(cap->uuid, BAA_SERVICE_UUID)) ? false : true;
ep->codec = cap->codec_id;
ep->path = g_strdup_printf("%s/ep%u", BLUEZ_MEDIA_ENDPOINT_PATH,
g_list_length(local_endpoints));