Subject: [PATCH BlueZ v3 0/5] Broadcast source reconfiguration support

This patch adds support for broadcast source to reconfigure a BIS.
endpoint.config command has a new prompt for broadcast source:
BIS Index for reconfiguration? (value(1-31)/no):
Values n or 0 represent that no reconfiguration is required
Values between (1-31) specify which BIS to be reconfigured
example form client/scripts/broadcast-source.bt
endpoint.register 00001852-0000-1000-8000-00805f9b34fb 0x06
endpoint.config /org/bluez/hci0/pac_bcast0 /local/endpoint/ep0 16_2_1
BIS Index for reconfiguration? (value(1-31)/no): 0
[/local/endpoint/ep0] BIG (auto/value): 1
[/local/endpoint/ep0] Enter channel location (value/no): 1
[/local/endpoint/ep0] Enter Metadata (value/no): 0x03 0x02 0x04 0x00
transport.acquire /org/bluez/hci0/pac_bcast0/fd0
HCI Command: LE Set Periodic Ad.. (0x08|0x003f) plen 41
Handle: 1
Operation: Complete ext advertising data (0x03)
Data length: 0x26
Service Data: Basic Audio Announcement (0x1851)
Presetation Delay: 40000
Number of Subgroups: 1
Subgroup #0:
Number of BIS(s): 1
Codec: LC3 (0x06)
Codec Specific Configuration: #0: len 0x02 type 0x01
Codec Specific Configuration: Sampling Frequency: 16 Khz (0x03)
Codec Specific Configuration: #1: len 0x02 type 0x02
Codec Specific Configuration: Frame Duration: 10 ms (0x01)
Codec Specific Configuration: #2: len 0x03 type 0x04
Codec Specific Configuration: Frame Length: 40 (0x0028)
Codec Specific Configuration: #3: len 0x05 type 0x03
Codec Specific Configuration: Location: 0x00000001
Codec Specific Configuration: Location: Front Left (0x00000001)
Metadata: #0: len 0x03 type 0x02
Metadata: Context: 0x0004
Metadata: Context Media (0x0004)
BIS #0:
Index: 1
transport.release /org/bluez/hci0/pac_bcast0/fd0
endpoint.config /org/bluez/hci0/pac_bcast0 /local/endpoint/ep0 16_2_1
[/local/endpoint/ep0] BIS Index for reconfiguration? (value(1-31)/no): 1
[/local/endpoint/ep0] BIG (auto/value): 1
[/local/endpoint/ep0] Enter channel location (value/no): 2
[/local/endpoint/ep0] Enter Metadata (value/no): 0x03 0x02 0x04 0x01
transport.acquire /org/bluez/hci0/pac_bcast0/fd0
HCI Command: LE Set Periodic Ad.. (0x08|0x003f) plen 41 #47 [hci0]
Handle: 1
Operation: Complete ext advertising data (0x03)
Data length: 0x26
Service Data: Basic Audio Announcement (0x1851)
Presetation Delay: 40000
Number of Subgroups: 1
Subgroup #0:
Number of BIS(s): 1
Codec: LC3 (0x06)
Codec Specific Configuration: #0: len 0x02 type 0x01
Codec Specific Configuration: Sampling Frequency: 16 Khz (0x03)
Codec Specific Configuration: #1: len 0x02 type 0x02
Codec Specific Configuration: Frame Duration: 10 ms (0x01)
Codec Specific Configuration: #2: len 0x03 type 0x04
Codec Specific Configuration: Frame Length: 40 (0x0028)
Codec Specific Configuration: #3: len 0x05 type 0x03
Codec Specific Configuration: Location: 0x00000002
Codec Specific Configuration: Location: Front Right (0x00000002)
Metadata: #0: len 0x03 type 0x02
Metadata: Context: 0x0104
Metadata: Context Media (0x0004)
Metadata: Context Notifications (0x0100)
BIS #0:
Index: 1

Silviu Florian Barbulescu (5):
player: Add reconfiguration prompt for broadcast source
transport: Add support to update the transport configuration
bap: Broadcast source reconfiguration support added
player.c: Remove bt_shell_noninteractive_quit on acquire,release
commands
client: update broadcast source script to support the BIS
reconfiguration

client/player.c | 37 +++++++++++++--
client/scripts/broadcast-source.bt | 12 ++++-
profiles/audio/bap.c | 76 ++++++++++++++++++++++++++++++
profiles/audio/transport.c | 27 ++++++++++-
profiles/audio/transport.h | 1 +
src/shared/bap.c | 11 ++++-
6 files changed, 156 insertions(+), 8 deletions(-)


base-commit: 84628e5d109cbec0bbd515c12c4b5224380784fe
--
2.39.2



Subject: [PATCH BlueZ v3 1/5] player: Add reconfiguration prompt for broadcast source

endpoint.config /org/bluez/hci0/pac_bcast0 /local/endpoint/ep0 48_4_1
[/local/endpoint/ep0] BIS Index for reconfiguration? (value(1-31)/no): n
[/local/endpoint/ep0] BIG (auto/value): 0
[/local/endpoint/ep0] Enter channel location (value/no): 1
[/local/endpoint/ep0] Enter Metadata (value/no): n
---
client/player.c | 33 +++++++++++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/client/player.c b/client/player.c
index 8081ddc13..c754af33d 100644
--- a/client/player.c
+++ b/client/player.c
@@ -3659,6 +3659,35 @@ static void config_endpoint_iso_group(const char *input, void *user_data)
}
}

+static void endpoint_is_reconfigure_cfg(const char *input, void *user_data)
+{
+ struct endpoint_config *cfg = user_data;
+ int value;
+ char *endptr = NULL;
+
+ if (!strcasecmp(input, "n") || !strcasecmp(input, "no")) {
+ cfg->ep->iso_stream = BT_ISO_QOS_STREAM_UNSET;
+ goto done;
+ } else {
+ value = strtol(input, &endptr, 0);
+
+ if (!endptr || *endptr != '\0' || value > UINT8_MAX) {
+ bt_shell_printf("Invalid argument: %s\n", input);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ if (value == 0x0)
+ cfg->ep->iso_stream = BT_ISO_QOS_STREAM_UNSET;
+ else
+ cfg->ep->iso_stream = value;
+ }
+
+done:
+ bt_shell_prompt_input(cfg->ep->path,
+ "BIG (auto/value):",
+ config_endpoint_iso_group, cfg);
+}
+
static void endpoint_set_config_bcast(struct endpoint_config *cfg)
{
cfg->ep->bcode = g_new0(struct iovec, 1);
@@ -3674,8 +3703,8 @@ static void endpoint_set_config_bcast(struct endpoint_config *cfg)
}

bt_shell_prompt_input(cfg->ep->path,
- "BIG (auto/value):",
- config_endpoint_iso_group, cfg);
+ "BIS Index for reconfiguration? (value(1-31)/no):",
+ endpoint_is_reconfigure_cfg, cfg);
}

static void cmd_config_endpoint(int argc, char *argv[])
--
2.39.2


Subject: [PATCH BlueZ v3 3/5] bap: Broadcast source reconfiguration support added

If a BIS is reconfigured, the metadata and codec capabilities are updated.
Also, the BASE is updated to reflect the update.

---
profiles/audio/bap.c | 76 ++++++++++++++++++++++++++++++++++++++
profiles/audio/transport.c | 6 ++-
src/shared/bap.c | 11 +++++-
3 files changed, 91 insertions(+), 2 deletions(-)

diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 964ba9c21..e508e03ba 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -580,6 +580,11 @@ static int setup_parse_bcast_qos(struct bap_setup *setup, const char *key,
return -EINVAL;

dbus_message_iter_get_basic(iter, &qos->bcast.big);
+ } else if (!strcasecmp(key, "BIS")) {
+ if (var != DBUS_TYPE_BYTE)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(iter, &qos->bcast.bis);
} else if (!strcasecmp(key, "Options")) {
if (var != DBUS_TYPE_BYTE)
return -EINVAL;
@@ -884,6 +889,53 @@ static void setup_free(void *data)
free(setup);
}

+static void iterate_setups(struct bap_setup *setup)
+{
+ const struct queue_entry *entry;
+ struct bap_setup *ent_setup;
+ uint8_t bis_cnt = 1;
+
+ for (entry = queue_get_entries(setup->ep->setups);
+ entry; entry = entry->next) {
+ ent_setup = entry->data;
+
+ if (setup->qos.bcast.big != ent_setup->qos.bcast.big)
+ continue;
+
+ util_iov_free(ent_setup->base, 1);
+ ent_setup->base = NULL;
+
+ if (setup->qos.bcast.bis == bis_cnt) {
+ bt_bap_stream_config(ent_setup->stream, &setup->qos,
+ setup->caps, NULL, NULL);
+ bt_bap_stream_metadata(ent_setup->stream,
+ setup->metadata, NULL, NULL);
+ }
+
+ bis_cnt++;
+ }
+}
+
+static bool verify_state(struct bap_setup *setup)
+{
+ const struct queue_entry *entry;
+ struct bap_setup *ent_setup;
+
+ for (entry = queue_get_entries(setup->ep->setups);
+ entry; entry = entry->next) {
+ ent_setup = entry->data;
+
+ if (setup->qos.bcast.big != ent_setup->qos.bcast.big)
+ continue;
+
+ if (bt_bap_stream_get_state(ent_setup->stream) ==
+ BT_BAP_STREAM_STATE_STREAMING)
+ return false;
+ }
+
+ return true;
+}
+
static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -925,6 +977,30 @@ static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
util_iov_free(setup->metadata, 1);
setup->metadata = util_iov_dup(
bt_bap_pac_get_metadata(ep->rpac), 1);
+ } else if (bt_bap_pac_get_type(ep->lpac) == BT_BAP_BCAST_SOURCE) {
+ if (setup->qos.bcast.bis != BT_ISO_QOS_BIS_UNSET) {
+ if ((setup->qos.bcast.bis > queue_length(ep->setups)) ||
+ (setup->qos.bcast.bis == 0)) {
+ setup_free(setup);
+ return btd_error_invalid_args(msg);
+ }
+
+ /* Verify that no BIS in the BIG is in streaming state
+ */
+ if (!verify_state(setup)) {
+ setup_free(setup);
+ return btd_error_not_permitted(msg,
+ "Broadcast Audio Stream state is invalid");
+ }
+
+ /* Find and update the BIS specified in
+ * set_configuration command
+ */
+ iterate_setups(setup);
+
+ setup_free(setup);
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+ }
}

setup->stream = bt_bap_stream_new(ep->data->bap, ep->lpac, ep->rpac,
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 122c3339e..a060f8c61 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -1643,8 +1643,12 @@ static void bap_state_changed(struct bt_bap_stream *stream, uint8_t old_state,
bap_update_links(transport);
if (!media_endpoint_is_broadcast(transport->endpoint))
bap_update_qos(transport);
- else if (bt_bap_stream_io_dir(stream) != BT_BAP_BCAST_SOURCE)
+ else if (bt_bap_stream_io_dir(stream) != BT_BAP_BCAST_SOURCE) {
bap_update_bcast_qos(transport);
+ if (old_state == BT_BAP_STREAM_STATE_QOS)
+ bap_update_bcast_config(transport);
+ }
+
transport_update_playing(transport, FALSE);
return;
case BT_BAP_STREAM_STATE_DISABLING:
diff --git a/src/shared/bap.c b/src/shared/bap.c
index fd99cbbca..603d6d646 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -1701,7 +1701,16 @@ static unsigned int bap_bcast_config(struct bt_bap_stream *stream,
struct bt_bap_qos *qos, struct iovec *data,
bt_bap_stream_func_t func, void *user_data)
{
- stream->qos = *qos;
+ if (qos) {
+ stream->qos = *qos;
+ stream->qos.bcast.bcode = util_iov_dup(qos->bcast.bcode, 1);
+ }
+
+ if (data) {
+ util_iov_free(stream->cc, 1);
+ stream->cc = util_iov_dup(data, 1);
+ }
+
stream->lpac->ops->config(stream, stream->cc, &stream->qos,
ep_config_cb, stream->lpac->user_data);

--
2.39.2


Subject: Re: [PATCH BlueZ v3 1/5] player: Add reconfiguration prompt for broadcast source

I am sorry if what I say is wrong... but for me, the label done is unnecessary.

+static void endpoint_is_reconfigure_cfg(const char *input, void *user_data)
+{
+ struct endpoint_config *cfg = user_data;
+ int value;
+ char *endptr = NULL;
+
+ if (!strcasecmp(input, "n") || !strcasecmp(input, "no")) {
+ cfg->ep->iso_stream = BT_ISO_QOS_STREAM_UNSET;
/// this command "goto done" is unnecessary, because if the if()
statement is executed
///the else is not execute, and the chunk of code, that the label done
coverage, go to execute
+ goto done;
+ } else {
+ value = strtol(input, &endptr, 0);
+
+ if (!endptr || *endptr != '\0' || value > UINT8_MAX) {
+ bt_shell_printf("Invalid argument: %s\n", input);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ if (value == 0x0)
+ cfg->ep->iso_stream = BT_ISO_QOS_STREAM_UNSET;
+ else
+ cfg->ep->iso_stream = value;
+ }
+
/// this label done, is unnecessary, because if the if() executes, the
else does not execute.
/// then, the chunk that the label done is include, already execute
without "goto done;"
+done:
+ bt_shell_prompt_input(cfg->ep->path,
+ "BIG (auto/value):",
+ config_endpoint_iso_group, cfg);
+}


this chunk of code, can rrepalced for this:
+static void endpoint_is_reconfigure_cfg(const char *input, void *user_data)
+{
+ struct endpoint_config *cfg = user_data;
+ int value;
+ char *endptr = NULL;
+
+ if (!strcasecmp(input, "n") || !strcasecmp(input, "no"))
+ cfg->ep->iso_stream = BT_ISO_QOS_STREAM_UNSET;
+ else {
+ value = strtol(input, &endptr, 0);
+
+ if (!endptr || *endptr != '\0' || value > UINT8_MAX) {
+ bt_shell_printf("Invalid argument: %s\n", input);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ if (value == 0x0)
+ cfg->ep->iso_stream = BT_ISO_QOS_STREAM_UNSET;
+ else
+ cfg->ep->iso_stream = value;
+ }
+
+ bt_shell_prompt_input(cfg->ep->path,
+ "BIG (auto/value):",
+ config_endpoint_iso_group, cfg);
+}
+


Em sex., 15 de mar. de 2024 às 12:02, Silviu Florian Barbulescu
<[email protected]> escreveu:
>
> endpoint.config /org/bluez/hci0/pac_bcast0 /local/endpoint/ep0 48_4_1
> [/local/endpoint/ep0] BIS Index for reconfiguration? (value(1-31)/no): n
> [/local/endpoint/ep0] BIG (auto/value): 0
> [/local/endpoint/ep0] Enter channel location (value/no): 1
> [/local/endpoint/ep0] Enter Metadata (value/no): n
> ---
> client/player.c | 33 +++++++++++++++++++++++++++++++--
> 1 file changed, 31 insertions(+), 2 deletions(-)
>
> diff --git a/client/player.c b/client/player.c
> index 8081ddc13..c754af33d 100644
> --- a/client/player.c
> +++ b/client/player.c
> @@ -3659,6 +3659,35 @@ static void config_endpoint_iso_group(const char *input, void *user_data)
> }
> }
>
> +static void endpoint_is_reconfigure_cfg(const char *input, void *user_data)
> +{
> + struct endpoint_config *cfg = user_data;
> + int value;
> + char *endptr = NULL;
> +
> + if (!strcasecmp(input, "n") || !strcasecmp(input, "no")) {
> + cfg->ep->iso_stream = BT_ISO_QOS_STREAM_UNSET;
> + goto done;
> + } else {
> + value = strtol(input, &endptr, 0);
> +
> + if (!endptr || *endptr != '\0' || value > UINT8_MAX) {
> + bt_shell_printf("Invalid argument: %s\n", input);
> + return bt_shell_noninteractive_quit(EXIT_FAILURE);
> + }
> +
> + if (value == 0x0)
> + cfg->ep->iso_stream = BT_ISO_QOS_STREAM_UNSET;
> + else
> + cfg->ep->iso_stream = value;
> + }
> +
> +done:
> + bt_shell_prompt_input(cfg->ep->path,
> + "BIG (auto/value):",
> + config_endpoint_iso_group, cfg);
> +}
> +
> static void endpoint_set_config_bcast(struct endpoint_config *cfg)
> {
> cfg->ep->bcode = g_new0(struct iovec, 1);
> @@ -3674,8 +3703,8 @@ static void endpoint_set_config_bcast(struct endpoint_config *cfg)
> }
>
> bt_shell_prompt_input(cfg->ep->path,
> - "BIG (auto/value):",
> - config_endpoint_iso_group, cfg);
> + "BIS Index for reconfiguration? (value(1-31)/no):",
> + endpoint_is_reconfigure_cfg, cfg);
> }
>
> static void cmd_config_endpoint(int argc, char *argv[])
> --
> 2.39.2
>
>