diff mbox series

[BlueZ,10/10] client: Add assistant submenu

Message ID 20240716142207.4298-11-iulia.tanasescu@nxp.com
State New
Headers show
Series Initial implementation of BAP Broadcast Assistant | expand

Commit Message

Iulia Tanasescu July 16, 2024, 2:22 p.m. UTC
This adds the initial implementation for the assistant menu in
bluetoothctl, to detect and print MediaAssistant objects.

The current BAP Broadcast Assistant implementation can be tested
by running bluetoothctl, connecting to a BASS Server, scanning
a Broadcast Source that is streaming a number of BISes with
audio capabilities matching the capabilities of the peer device,
and noticing the MediaAssistant objects being created:

client/bluetoothctl
[bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes
[bluetooth]# AdvertisementMonitor path registered
[bluetooth]# scan on
[bluetooth]# [NEW] Device 00:60:37:94:A6:A3 00-60-37-94-A6-A3
[bluetooth]# connect 00:60:37:94:A6:A3
Attempting to connect to 00:60:37:94:A6:A3
[CHG] Device 00:60:37:94:A6:A3 Connected: yes
[00-60-37-94-A6-A3]# Connection successful
[00-60-37-94-A6-A3]# [NEW] Device 15:65:78:B6:52:F6 15-65-78-B6-52-F6
[00-60-37-94-A6-A3]# [NEW] Assistant
       /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis1
[00-60-37-94-A6-A3]# [NEW] Assistant
       /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis2
[00-60-37-94-A6-A3]# scan off
[00-60-37-94-A6-A3]# Diovery stopped
[00-60-37-94-A6-A3]# disconnect
Attempting to disconnect from 00:60:37:94:A6:A3
[00-60-37-94-A6-A3]# Successful disconnected
[CHG] Device 00:60:37:94:A6:A3 Connected: no
[bluetooth]# [DEL] Assistant
       /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis1
[bluetooth]# [DEL] Assistant
       /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis2
---
 Makefile.tools     |   3 +-
 client/assistant.c | 164 +++++++++++++++++++++++++++++++++++++++++++++
 client/assistant.h |  13 ++++
 client/main.c      |   5 +-
 4 files changed, 183 insertions(+), 2 deletions(-)
 create mode 100644 client/assistant.c
 create mode 100644 client/assistant.h
diff mbox series

Patch

diff --git a/Makefile.tools b/Makefile.tools
index 679c914bf..f4f9e82dc 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -13,7 +13,8 @@  client_bluetoothctl_SOURCES = client/main.c \
 					client/gatt.h client/gatt.c \
 					client/admin.h client/admin.c \
 					client/player.h client/player.c \
-					client/mgmt.h client/mgmt.c
+					client/mgmt.h client/mgmt.c \
+					client/assistant.h client/assistant.c
 client_bluetoothctl_LDADD = lib/libbluetooth-internal.la \
 			gdbus/libgdbus-internal.la src/libshared-glib.la \
 			$(GLIB_LIBS) $(DBUS_LIBS) -lreadline
diff --git a/client/assistant.c b/client/assistant.c
new file mode 100644
index 000000000..69a955c18
--- /dev/null
+++ b/client/assistant.c
@@ -0,0 +1,164 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright 2024 NXP
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "gdbus/gdbus.h"
+
+#include "lib/bluetooth.h"
+#include "lib/uuid.h"
+
+#include "src/shared/util.h"
+#include "src/shared/shell.h"
+#include "src/shared/io.h"
+#include "src/shared/queue.h"
+#include "print.h"
+#include "assistant.h"
+
+/* String display constants */
+#define COLORED_NEW	COLOR_GREEN "NEW" COLOR_OFF
+#define COLORED_CHG	COLOR_YELLOW "CHG" COLOR_OFF
+#define COLORED_DEL	COLOR_RED "DEL" COLOR_OFF
+
+#define MEDIA_ASSISTANT_INTERFACE "org.bluez.MediaAssistant1"
+
+static DBusConnection *dbus_conn;
+
+static GList *assistants;
+
+static char *proxy_description(GDBusProxy *proxy, const char *title,
+						const char *description)
+{
+	const char *path;
+
+	path = g_dbus_proxy_get_path(proxy);
+
+	return g_strdup_printf("%s%s%s%s %s ",
+					description ? "[" : "",
+					description ? : "",
+					description ? "] " : "",
+					title, path);
+}
+
+static void print_assistant(GDBusProxy *proxy, const char *description)
+{
+	char *str;
+
+	str = proxy_description(proxy, "Assistant", description);
+
+	bt_shell_printf("%s\n", str);
+
+	g_free(str);
+}
+
+static void assistant_added(GDBusProxy *proxy)
+{
+	assistants = g_list_append(assistants, proxy);
+
+	print_assistant(proxy, COLORED_NEW);
+}
+
+static void proxy_added(GDBusProxy *proxy, void *user_data)
+{
+	const char *interface;
+
+	interface = g_dbus_proxy_get_interface(proxy);
+
+	if (!strcmp(interface, MEDIA_ASSISTANT_INTERFACE))
+		assistant_added(proxy);
+}
+
+static void assistant_removed(GDBusProxy *proxy)
+{
+	assistants = g_list_remove(assistants, proxy);
+
+	print_assistant(proxy, COLORED_DEL);
+}
+
+static void proxy_removed(GDBusProxy *proxy, void *user_data)
+{
+	const char *interface;
+
+	interface = g_dbus_proxy_get_interface(proxy);
+
+	if (!strcmp(interface, MEDIA_ASSISTANT_INTERFACE))
+		assistant_removed(proxy);
+}
+
+static void assistant_property_changed(GDBusProxy *proxy, const char *name,
+						DBusMessageIter *iter)
+{
+	char *str;
+
+	str = proxy_description(proxy, "Assistant", COLORED_CHG);
+	print_iter(str, name, iter);
+	g_free(str);
+}
+
+static void property_changed(GDBusProxy *proxy, const char *name,
+					DBusMessageIter *iter, void *user_data)
+{
+	const char *interface;
+
+	interface = g_dbus_proxy_get_interface(proxy);
+
+	if (!strcmp(interface, MEDIA_ASSISTANT_INTERFACE))
+		assistant_property_changed(proxy, name, iter);
+}
+
+static void assistant_unregister(void *data)
+{
+	GDBusProxy *proxy = data;
+
+	bt_shell_printf("Assistant %s unregistered\n",
+				g_dbus_proxy_get_path(proxy));
+}
+
+static void disconnect_handler(DBusConnection *connection, void *user_data)
+{
+	g_list_free_full(assistants, assistant_unregister);
+	assistants = NULL;
+}
+
+static GDBusClient * client;
+
+void assistant_add_submenu(void)
+{
+	dbus_conn = bt_shell_get_env("DBUS_CONNECTION");
+	if (!dbus_conn || client)
+		return;
+
+	client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
+
+	g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
+							property_changed, NULL);
+	g_dbus_client_set_disconnect_watch(client, disconnect_handler, NULL);
+}
+
+void assistant_remove_submenu(void)
+{
+	g_dbus_client_unref(client);
+	client = NULL;
+}
+
diff --git a/client/assistant.h b/client/assistant.h
new file mode 100644
index 000000000..418b0b840
--- /dev/null
+++ b/client/assistant.h
@@ -0,0 +1,13 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright 2024 NXP
+ *
+ *
+ */
+
+void assistant_add_submenu(void);
+void assistant_remove_submenu(void);
+
diff --git a/client/main.c b/client/main.c
index f012ddd43..a96a42638 100644
--- a/client/main.c
+++ b/client/main.c
@@ -4,7 +4,7 @@ 
  *  BlueZ - Bluetooth protocol stack for Linux
  *
  *  Copyright (C) 2012  Intel Corporation. All rights reserved.
- *
+ *  Copyright 2024 NXP
  *
  */
 
@@ -34,6 +34,7 @@ 
 #include "admin.h"
 #include "player.h"
 #include "mgmt.h"
+#include "assistant.h"
 
 /* String display constants */
 #define COLORED_NEW	COLOR_GREEN "NEW" COLOR_OFF
@@ -3205,6 +3206,7 @@  int main(int argc, char *argv[])
 	admin_add_submenu();
 	player_add_submenu();
 	mgmt_add_submenu();
+	assistant_add_submenu();
 
 	client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
 
@@ -3222,6 +3224,7 @@  int main(int argc, char *argv[])
 	admin_remove_submenu();
 	player_remove_submenu();
 	mgmt_remove_submenu();
+	assistant_remove_submenu();
 
 	g_dbus_client_unref(client);