* [PATCH BlueZ 1/1] client: add advertise broadcast-name helper
2026-03-13 10:18 [PATCH BlueZ 0/1] client: add bluetoothctl broadcast-name helper raghava447
@ 2026-03-13 10:18 ` raghava447
2026-03-13 11:17 ` client: add bluetoothctl " bluez.test.bot
0 siblings, 1 reply; 3+ messages in thread
From: raghava447 @ 2026-03-13 10:18 UTC (permalink / raw)
To: linux-bluetooth; +Cc: raghava447
Add a bluetoothctl advertise helper for staging BLE Audio Broadcast
Name as AD type 0x30 using a plain string.
The helper reuses the existing raw advertising Data field and
registration flow.
The documentation is updated with relevant details.
---
client/advertising.c | 52 ++++++++++++++++++++++++++++++++++
client/advertising.h | 1 +
client/main.c | 7 +++++
doc/bluetoothctl-advertise.rst | 18 ++++++++++++
4 files changed, 78 insertions(+)
diff --git a/client/advertising.c b/client/advertising.c
index f9df1b855..924eb69d8 100644
--- a/client/advertising.c
+++ b/client/advertising.c
@@ -27,6 +27,7 @@
#define AD_PATH "/org/bluez/advertising"
#define AD_IFACE "org.bluez.LEAdvertisement1"
+#define AD_TYPE_BROADCAST_NAME 0x30
struct ad_data {
uint8_t data[245];
@@ -1043,6 +1044,57 @@ void ad_advertise_data(DBusConnection *conn, int type, int argc, char *argv[])
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
+void ad_advertise_broadcast_name(DBusConnection *conn, int argc, char *argv[])
+{
+ GString *name;
+ size_t i;
+ size_t len;
+
+ if (argc < 2) {
+ if (ad.data[AD_TYPE_AD].valid &&
+ ad.data[AD_TYPE_AD].type == AD_TYPE_BROADCAST_NAME)
+ bt_shell_printf("Broadcast Name: %.*s\n",
+ ad.data[AD_TYPE_AD].data.len,
+ (char *) ad.data[AD_TYPE_AD].data.data);
+ else
+ bt_shell_printf("Broadcast Name not set\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+ }
+
+ name = g_string_new(NULL);
+ for (i = 1; i < (size_t) argc; i++) {
+ g_string_append(name, argv[i]);
+ if (i + 1 < (size_t) argc)
+ g_string_append_c(name, ' ');
+ }
+
+ if (!name->len) {
+ bt_shell_printf("Broadcast name cannot be empty\n");
+ g_string_free(name, TRUE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ len = name->len;
+ if (len > sizeof(ad.data[AD_TYPE_AD].data.data)) {
+ bt_shell_printf("Broadcast name is too long\n");
+ g_string_free(name, TRUE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ ad_clear_data(AD_TYPE_AD);
+ ad.data[AD_TYPE_AD].valid = true;
+ ad.data[AD_TYPE_AD].type = AD_TYPE_BROADCAST_NAME;
+ memcpy(ad.data[AD_TYPE_AD].data.data, name->str, len);
+ ad.data[AD_TYPE_AD].data.len = len;
+ g_string_free(name, TRUE);
+
+ g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE,
+ prop_names.data[AD_TYPE_AD]);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
void ad_disable_data(DBusConnection *conn, int type)
{
if (!ad.data[type].type && !ad.data[type].data.len)
diff --git a/client/advertising.h b/client/advertising.h
index 9d124c7af..d855493ed 100644
--- a/client/advertising.h
+++ b/client/advertising.h
@@ -34,6 +34,7 @@ void ad_advertise_local_appearance(DBusConnection *conn, long int *value);
void ad_advertise_duration(DBusConnection *conn, long int *value);
void ad_advertise_timeout(DBusConnection *conn, long int *value);
void ad_advertise_data(DBusConnection *conn, int type, int argc, char *argv[]);
+void ad_advertise_broadcast_name(DBusConnection *conn, int argc, char *argv[]);
void ad_disable_data(DBusConnection *conn, int type);
void ad_advertise_discoverable(DBusConnection *conn, dbus_bool_t *value);
void ad_advertise_discoverable_timeout(DBusConnection *conn, long int *value);
diff --git a/client/main.c b/client/main.c
index cb016a579..9b4e8190d 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2917,6 +2917,11 @@ static void cmd_advertise_data(int argc, char *argv[])
ad_advertise_data(dbus_conn, AD_TYPE_AD, argc, argv);
}
+static void cmd_advertise_broadcast_name(int argc, char *argv[])
+{
+ ad_advertise_broadcast_name(dbus_conn, argc, argv);
+}
+
static void cmd_advertise_sr_uuids(int argc, char *argv[])
{
ad_advertise_uuids(dbus_conn, AD_TYPE_SRD, argc, argv);
@@ -3600,6 +3605,8 @@ static const struct bt_shell_menu advertise_menu = {
"Set/Get advertise manufacturer data" },
{ "data", "[type] [data=xx xx ...]", cmd_advertise_data,
"Set/Get advertise data" },
+ { "broadcast-name", "<string>", cmd_advertise_broadcast_name,
+ "Set BLE Audio Broadcast Name (AD type 0x30)" },
{ "sr-uuids", "[uuid1 uuid2 ...]", cmd_advertise_sr_uuids,
"Set/Get scan response uuids" },
{ "sr-solicit", "[uuid1 uuid2 ...]", cmd_advertise_sr_solicit,
diff --git a/doc/bluetoothctl-advertise.rst b/doc/bluetoothctl-advertise.rst
index 0780cd9d8..a2963e4b7 100644
--- a/doc/bluetoothctl-advertise.rst
+++ b/doc/bluetoothctl-advertise.rst
@@ -171,6 +171,24 @@ To get the currently set data use the command data without any arguments.
:Example Set service data for Battery Service (UUID 0x180F, level 100):
| **> data 0x16 0F 18 64**
+broadcast-name
+--------------
+
+Set BLE Audio Broadcast Name.
+
+This is a semantic helper for raw advertising data type ``0x30``. It writes
+only the payload bytes for that AD type into the same staged advertising data
+slot used by ``data 0x30 ...``. If either command is used later, the later
+call replaces the previous value.
+
+:Usage: **> broadcast-name <string>**
+:[string]: Broadcast Name string to be staged as AD type ``0x30`` payload
+:Example Show current broadcast name:
+ | **> broadcast-name**
+ | Broadcast Name: Collabora BlueZ Auracast
+:Example Set broadcast name to "Collabora BlueZ Auracast":
+ | **> broadcast-name "Collabora BlueZ Auracast"**
+
sr-uuids
--------
--
2.52.0
^ permalink raw reply related [flat|nested] 3+ messages in thread