2023-07-12 12:31:14

by Claudia Draghicescu

[permalink] [raw]
Subject: [PATCH BlueZ v2 2/6] client/main: Add broadcast source discovery

This checks if the scanned device advertises the
Broadcast Audio Announcement service.
If it does, the device will be added to a list of broadcast sources
to which the adapter can synchronize.

To test this feature use the following commands:

[bluetooth]# endpoint.register 00002bc9-0000-1000-8000-00805f9b34fb 0x06
[/local/endpoint/ep0] Auto Accept (yes/no): y
[/local/endpoint/ep0] Max Transports (auto/value): a
[/local/endpoint/ep0] unicast/broadcast (u/b): b
[/local/endpoint/ep0] BIG (auto/value): a
[/local/endpoint/ep0] BIS (auto/value): a

[bluetooth]# scan on

[bluetooth]# endpoint.config /org/bluez/hci0/pac_bcast0
/local/endpoint/ep0 16_2_1 <source_address>

---
client/main.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)

diff --git a/client/main.c b/client/main.c
index b433a2200..8fe537f34 100644
--- a/client/main.c
+++ b/client/main.c
@@ -198,7 +198,7 @@ static void print_device(GDBusProxy *proxy, const char *description)
if (filter.discoverable)
return;

- bt_shell_printf("%s%s%s" COLOR_BOLDGRAY "Device %s %s"
+ bt_shell_printf("%s%s%s" COLOR_GREEN "Device %s %s"
COLOR_OFF "\n",
description ? "[" : "",
description ? : "",
@@ -304,6 +304,57 @@ static gboolean proxy_is_child(GDBusProxy *device, GDBusProxy *parent)
return FALSE;
}

+static bool parse_service_data(GDBusProxy *proxy)
+{
+ DBusMessageIter iter, entries;
+
+ if (!g_dbus_proxy_get_property(proxy, "ServiceData", &iter))
+ return false;
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+ return false;
+
+ dbus_message_iter_recurse(&iter, &entries);
+
+ while (dbus_message_iter_get_arg_type(&entries)
+ == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter value, entry, array;
+ const char *uuid_str;
+ uint8_t *service_data;
+ int len;
+
+ dbus_message_iter_recurse(&entries, &entry);
+ dbus_message_iter_get_basic(&entry, &uuid_str);
+
+ dbus_message_iter_next(&entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+ goto fail;
+
+ dbus_message_iter_recurse(&entry, &value);
+
+ if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_ARRAY)
+ goto fail;
+
+ dbus_message_iter_recurse(&value, &array);
+
+ if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_BYTE)
+ goto fail;
+
+ dbus_message_iter_get_fixed_array(&array, &service_data, &len);
+
+ if (!strcmp(uuid_str, BAA_SERVICE_UUID)) {
+ player_add_bcast_source(proxy, service_data, len);
+ return true;
+ }
+
+ dbus_message_iter_next(&entries);
+ }
+
+fail:
+ return false;
+}
+
static gboolean service_is_child(GDBusProxy *service)
{
DBusMessageIter iter;
@@ -399,6 +450,8 @@ static void device_added(GDBusProxy *proxy)
if (connected)
set_default_device(proxy, NULL);
}
+
+ parse_service_data(proxy);
}

static struct adapter *find_ctrl(GList *source, const char *path);
@@ -531,6 +584,8 @@ static void device_removed(GDBusProxy *proxy)
/* TODO: Error */
return;
}
+ /* Check if it was a broadcast source and remove it */
+ player_remove_bcast_source(proxy);

adapter->devices = g_list_remove(adapter->devices, proxy);

--
2.34.1