* [PATCH BlueZ 0/1] client: add public-broadcast advertise helper
@ 2026-03-17 5:58 raghava447
2026-03-17 5:58 ` [PATCH BlueZ 1/1] client: Add public-broadcast profile advertise command raghava447
0 siblings, 1 reply; 4+ messages in thread
From: raghava447 @ 2026-03-17 5:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: raghava447
This patch adds a bluetoothctl advertise helper for BLE Audio
public broadcast profile advertising.
This series adds a semantic helper:
public-broadcast sq
public-broadcast hq
This matches with current commands:
service 0x1856 0x02 0x00
service 0x1856 0x04 0x00
raghava447 (1):
client: Add public-broadcast profile advertise command
client/advertising.c | 70 ++++++++++++++++++++++++++++++++++++++++++++
client/advertising.h | 2 ++
client/main.c | 19 ++++++++++++
3 files changed, 91 insertions(+)
--
2.53.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH BlueZ 1/1] client: Add public-broadcast profile advertise command
2026-03-17 5:58 [PATCH BlueZ 0/1] client: add public-broadcast advertise helper raghava447
@ 2026-03-17 5:58 ` raghava447
2026-03-17 6:11 ` client: add public-broadcast advertise helper bluez.test.bot
0 siblings, 1 reply; 4+ messages in thread
From: raghava447 @ 2026-03-17 5:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: raghava447
Add an advertise submenu command for BLE Audio public broadcast profile
advertising in bluetoothctl.
The new "public-broadcast" command reuses the existing staged AD
ServiceData field for UUID 0x1856.
It supports:
- public-broadcast sq
- public-broadcast hq
- public-broadcast
The sq and hq values map to the existing raw service-data payloads:
- sq -> 0x02 0x00
- hq -> 0x04 0x00
When called without arguments, the command reports the currently staged
public-broadcast state if the staged AD service UUID is 0x1856.
Else it reports that public broadcast is not set.
---
client/advertising.c | 70 ++++++++++++++++++++++++++++++++++++++++++++
client/advertising.h | 2 ++
client/main.c | 19 ++++++++++++
3 files changed, 91 insertions(+)
diff --git a/client/advertising.c b/client/advertising.c
index 924eb69d8..27639d786 100644
--- a/client/advertising.c
+++ b/client/advertising.c
@@ -20,6 +20,8 @@
#include <string.h>
#include <errno.h>
+#include "bluetooth/bluetooth.h"
+#include "bluetooth/uuid.h"
#include "gdbus/gdbus.h"
#include "src/shared/util.h"
#include "src/shared/shell.h"
@@ -28,6 +30,7 @@
#define AD_PATH "/org/bluez/advertising"
#define AD_IFACE "org.bluez.LEAdvertisement1"
#define AD_TYPE_BROADCAST_NAME 0x30
+#define AD_PUBLIC_BROADCAST_UUID "0x1856"
struct ad_data {
uint8_t data[245];
@@ -1006,6 +1009,73 @@ static void ad_clear_data(int type)
memset(&ad.data[type], 0, sizeof(ad.data[type]));
}
+static bool ad_is_public_broadcast_uuid(const char *uuid)
+{
+ return uuid && !bt_uuid_strcmp(uuid, AD_PUBLIC_BROADCAST_UUID);
+}
+
+static const char *ad_public_broadcast_state(void)
+{
+ if (!ad_is_public_broadcast_uuid(ad.service[AD_TYPE_AD].uuid))
+ return NULL;
+
+ if (ad.service[AD_TYPE_AD].data.len != 2)
+ return NULL;
+
+ if (ad.service[AD_TYPE_AD].data.data[0] == 0x02 &&
+ ad.service[AD_TYPE_AD].data.data[1] == 0x00)
+ return "sq";
+
+ if (ad.service[AD_TYPE_AD].data.data[0] == 0x04 &&
+ ad.service[AD_TYPE_AD].data.data[1] == 0x00)
+ return "hq";
+
+ return NULL;
+}
+
+void ad_advertise_public_broadcast(DBusConnection *conn, int argc, char *argv[])
+{
+ struct ad_data data = {
+ .data = { 0x00, 0x00 },
+ .len = 2,
+ };
+ const char *state;
+
+ if (argc < 2) {
+ state = ad_public_broadcast_state();
+ if (state)
+ bt_shell_printf("Public Broadcast: %s\n", state);
+ else
+ bt_shell_printf("Public Broadcast not set\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+ }
+
+ if (!strlen(argv[1])) {
+ bt_shell_printf("Public broadcast value cannot be empty\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ if (!strcasecmp(argv[1], "sq"))
+ data.data[0] = 0x02;
+ else if (!strcasecmp(argv[1], "hq"))
+ data.data[0] = 0x04;
+ else {
+ bt_shell_printf("Invalid argument: accepted values are sq or hq\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ ad_clear_service(AD_TYPE_AD);
+
+ ad.service[AD_TYPE_AD].uuid = g_strdup(AD_PUBLIC_BROADCAST_UUID);
+ ad.service[AD_TYPE_AD].data = data;
+
+ g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE,
+ prop_names.service[AD_TYPE_AD]);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
void ad_advertise_data(DBusConnection *conn, int type, int argc, char *argv[])
{
char *endptr = NULL;
diff --git a/client/advertising.h b/client/advertising.h
index d855493ed..c08672680 100644
--- a/client/advertising.h
+++ b/client/advertising.h
@@ -35,6 +35,8 @@ 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_advertise_public_broadcast(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 9b4e8190d..93f572977 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2892,6 +2892,17 @@ static char *ad_generator(const char *text, int state)
return argument_generator(text, state, ad_arguments);
}
+static const char *public_broadcast_arguments[] = {
+ "sq",
+ "hq",
+ NULL
+};
+
+static char *public_broadcast_generator(const char *text, int state)
+{
+ return argument_generator(text, state, public_broadcast_arguments);
+}
+
static void cmd_advertise_uuids(int argc, char *argv[])
{
ad_advertise_uuids(dbus_conn, AD_TYPE_AD, argc, argv);
@@ -2922,6 +2933,11 @@ static void cmd_advertise_broadcast_name(int argc, char *argv[])
ad_advertise_broadcast_name(dbus_conn, argc, argv);
}
+static void cmd_advertise_public_broadcast(int argc, char *argv[])
+{
+ ad_advertise_public_broadcast(dbus_conn, argc, argv);
+}
+
static void cmd_advertise_sr_uuids(int argc, char *argv[])
{
ad_advertise_uuids(dbus_conn, AD_TYPE_SRD, argc, argv);
@@ -3607,6 +3623,9 @@ static const struct bt_shell_menu advertise_menu = {
"Set/Get advertise data" },
{ "broadcast-name", "<string>", cmd_advertise_broadcast_name,
"Set BLE Audio Broadcast Name (AD type 0x30)" },
+ { "public-broadcast", "[sq/hq]", cmd_advertise_public_broadcast,
+ "Set/Get BLE Audio Public Broadcast Announcement",
+ public_broadcast_generator },
{ "sr-uuids", "[uuid1 uuid2 ...]", cmd_advertise_sr_uuids,
"Set/Get scan response uuids" },
{ "sr-solicit", "[uuid1 uuid2 ...]", cmd_advertise_sr_solicit,
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH BlueZ 1/1] client: Add public-broadcast profile advertise command
@ 2026-03-17 14:26 raghava447
2026-03-17 16:21 ` client: add public-broadcast advertise helper bluez.test.bot
0 siblings, 1 reply; 4+ messages in thread
From: raghava447 @ 2026-03-17 14:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: raghava447
Add an advertise submenu command for BLE Audio public broadcast profile
advertising in bluetoothctl.
The new "public-broadcast" command reuses the existing staged AD
ServiceData field for UUID 0x1856.
It supports:
- public-broadcast sq
- public-broadcast hq
- public-broadcast
The sq and hq values map to the existing raw service-data payloads:
- sq -> 0x02 0x00
- hq -> 0x04 0x00
When called without arguments, the command reports the currently staged
public-broadcast state if the staged AD service UUID is 0x1856.
Else it reports that public broadcast is not set.
---
client/advertising.c | 70 ++++++++++++++++++++++++++++++++++++++++++++
client/advertising.h | 2 ++
client/main.c | 19 ++++++++++++
3 files changed, 91 insertions(+)
diff --git a/client/advertising.c b/client/advertising.c
index f9df1b855..30b89a404 100644
--- a/client/advertising.c
+++ b/client/advertising.c
@@ -20,6 +20,8 @@
#include <string.h>
#include <errno.h>
+#include "bluetooth/bluetooth.h"
+#include "bluetooth/uuid.h"
#include "gdbus/gdbus.h"
#include "src/shared/util.h"
#include "src/shared/shell.h"
@@ -27,6 +29,7 @@
#define AD_PATH "/org/bluez/advertising"
#define AD_IFACE "org.bluez.LEAdvertisement1"
+#define AD_PUBLIC_BROADCAST_UUID "0x1856"
struct ad_data {
uint8_t data[245];
@@ -1005,6 +1008,73 @@ static void ad_clear_data(int type)
memset(&ad.data[type], 0, sizeof(ad.data[type]));
}
+static bool ad_is_public_broadcast_uuid(const char *uuid)
+{
+ return uuid && !bt_uuid_strcmp(uuid, AD_PUBLIC_BROADCAST_UUID);
+}
+
+static const char *ad_public_broadcast_state(void)
+{
+ if (!ad_is_public_broadcast_uuid(ad.service[AD_TYPE_AD].uuid))
+ return NULL;
+
+ if (ad.service[AD_TYPE_AD].data.len != 2)
+ return NULL;
+
+ if (ad.service[AD_TYPE_AD].data.data[0] == 0x02 &&
+ ad.service[AD_TYPE_AD].data.data[1] == 0x00)
+ return "sq";
+
+ if (ad.service[AD_TYPE_AD].data.data[0] == 0x04 &&
+ ad.service[AD_TYPE_AD].data.data[1] == 0x00)
+ return "hq";
+
+ return NULL;
+}
+
+void ad_advertise_public_broadcast(DBusConnection *conn, int argc, char *argv[])
+{
+ struct ad_data data = {
+ .data = { 0x00, 0x00 },
+ .len = 2,
+ };
+ const char *state;
+
+ if (argc < 2) {
+ state = ad_public_broadcast_state();
+ if (state)
+ bt_shell_printf("Public Broadcast: %s\n", state);
+ else
+ bt_shell_printf("Public Broadcast not set\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+ }
+
+ if (!strlen(argv[1])) {
+ bt_shell_printf("Public broadcast value cannot be empty\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ if (!strcasecmp(argv[1], "sq"))
+ data.data[0] = 0x02;
+ else if (!strcasecmp(argv[1], "hq"))
+ data.data[0] = 0x04;
+ else {
+ bt_shell_printf("Invalid argument: accepted values are sq or hq\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ ad_clear_service(AD_TYPE_AD);
+
+ ad.service[AD_TYPE_AD].uuid = g_strdup(AD_PUBLIC_BROADCAST_UUID);
+ ad.service[AD_TYPE_AD].data = data;
+
+ g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE,
+ prop_names.service[AD_TYPE_AD]);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
void ad_advertise_data(DBusConnection *conn, int type, int argc, char *argv[])
{
char *endptr = NULL;
diff --git a/client/advertising.h b/client/advertising.h
index 9d124c7af..8c3fd041b 100644
--- a/client/advertising.h
+++ b/client/advertising.h
@@ -34,6 +34,8 @@ 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_public_broadcast(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..0e050b373 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2892,6 +2892,17 @@ static char *ad_generator(const char *text, int state)
return argument_generator(text, state, ad_arguments);
}
+static const char *public_broadcast_arguments[] = {
+ "sq",
+ "hq",
+ NULL
+};
+
+static char *public_broadcast_generator(const char *text, int state)
+{
+ return argument_generator(text, state, public_broadcast_arguments);
+}
+
static void cmd_advertise_uuids(int argc, char *argv[])
{
ad_advertise_uuids(dbus_conn, AD_TYPE_AD, argc, argv);
@@ -2917,6 +2928,11 @@ static void cmd_advertise_data(int argc, char *argv[])
ad_advertise_data(dbus_conn, AD_TYPE_AD, argc, argv);
}
+static void cmd_advertise_public_broadcast(int argc, char *argv[])
+{
+ ad_advertise_public_broadcast(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 +3616,9 @@ 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" },
+ { "public-broadcast", "[sq/hq]", cmd_advertise_public_broadcast,
+ "Set/Get BLE Audio Public Broadcast Announcement",
+ public_broadcast_generator },
{ "sr-uuids", "[uuid1 uuid2 ...]", cmd_advertise_sr_uuids,
"Set/Get scan response uuids" },
{ "sr-solicit", "[uuid1 uuid2 ...]", cmd_advertise_sr_solicit,
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-03-17 16:22 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-17 5:58 [PATCH BlueZ 0/1] client: add public-broadcast advertise helper raghava447
2026-03-17 5:58 ` [PATCH BlueZ 1/1] client: Add public-broadcast profile advertise command raghava447
2026-03-17 6:11 ` client: add public-broadcast advertise helper bluez.test.bot
-- strict thread matches above, loose matches on Subject: below --
2026-03-17 14:26 [PATCH BlueZ 1/1] client: Add public-broadcast profile advertise command raghava447
2026-03-17 16:21 ` client: add public-broadcast advertise helper bluez.test.bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox