Subject: [PATCH BlueZ 0/3] 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:
" This is a BIS Reconfiguration? (yes/no)"
Yes or y if a BIS reconfiguration is required
No or n if it is a new BIS configuration
"The BIS index is assigned in the order of the configuration
starting with 1"
"BIS Index (value):" a value representing the BIS index if this is a
BIS reconfiguration.
endpoint.register 00001852-0000-1000-8000-00805f9b34fb 0x06
endpoint.config /org/bluez/hci0/pac_bcast0 /local/endpoint/ep0 48_4_1
This is a BIS Reconfiguration? (yes/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
endpoint.config /org/bluez/hci0/pac_bcast0 /local/endpoint/ep0 48_4_1
[/local/endpoint/ep0] This is a BIS Reconfiguration? (yes/no): y
The BIS index is assigned in the order of the configuration
starting with 1
[/local/endpoint/ep0] BIS Index (value): 1
[/local/endpoint/ep0] BIG (auto/value): 0
[/local/endpoint/ep0] Enter channel location (value/no): 2
[/local/endpoint/ep0] Enter Metadata (value/no): n
transport.show /org/bluez/hci0/pac_bcast0/fd0 to view the update
Transport /org/bluez/hci0/pac_bcast0/fd0

Configuration.Location: 0x00000002
Configuration.Location: Front Right (0x00000002)


Silviu Florian Barbulescu (3):
player: Add reconfiguration prompt for broadcast source
transport: Add support to update the transport configuration
bap: Broadcast source reconfiguration support added

client/player.c | 46 ++++++++++++++++++++-
profiles/audio/bap.c | 85 ++++++++++++++++++++++++++++++++++++++
profiles/audio/media.c | 3 +-
profiles/audio/transport.c | 23 +++++++++++
profiles/audio/transport.h | 1 +
src/shared/bap.c | 9 +++-
6 files changed, 163 insertions(+), 4 deletions(-)


base-commit: 19f8fcdc2084048bebe5bd9ea4fb97f7ece16df0
--
2.39.2



Subject: [PATCH BlueZ 2/3] transport: Add support to update the transport configuration

Add support to update the transport configuration

---
profiles/audio/transport.c | 23 +++++++++++++++++++++++
profiles/audio/transport.h | 1 +
2 files changed, 24 insertions(+)

diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 159fbd575..c8492d4a1 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -1483,6 +1483,29 @@ static void bap_update_bcast_qos(const struct media_transport *transport)
"Configuration");
}

+void bap_update_bcast_config(struct media_transport *transport)
+{
+ struct bap_transport *bap = transport->data;
+ struct iovec *cc;
+
+ cc = bt_bap_stream_get_config(bap->stream);
+
+ if (((int)cc->iov_len != transport->size) ||
+ (memcmp(cc->iov_base, transport->configuration,
+ transport->size) != 0)) {
+ free(transport->configuration);
+ transport->configuration = util_memdup(cc->iov_base,
+ cc->iov_len);
+ transport->size = cc->iov_len;
+
+ g_dbus_emit_property_changed(btd_get_dbus_connection(),
+ transport->path, MEDIA_TRANSPORT_INTERFACE,
+ "Configuration");
+ }
+
+ bap_update_bcast_qos(transport);
+}
+
static guint transport_bap_resume(struct media_transport *transport,
struct media_owner *owner)
{
diff --git a/profiles/audio/transport.h b/profiles/audio/transport.h
index b46bc8025..6df419a67 100644
--- a/profiles/audio/transport.h
+++ b/profiles/audio/transport.h
@@ -16,6 +16,7 @@ struct media_transport *media_transport_create(struct btd_device *device,
uint8_t *configuration,
size_t size, void *data,
void *stream);
+void bap_update_bcast_config(struct media_transport *transport);

void media_transport_destroy(struct media_transport *transport);
const char *media_transport_get_path(struct media_transport *transport);
--
2.39.2


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

endpoint.config /org/bluez/hci0/pac_bcast0 /local/endpoint/ep0 48_4_1
[/local/endpoint/ep0] This is a BIS Reconfiguration? (yes/no): y
The BIS index is assigned in the order of the configuration
starting with 1
[/local/endpoint/ep0] BIS Index (value): 1
[/local/endpoint/ep0] BIG (auto/value): 0
[/local/endpoint/ep0] Enter channel location (value/no): 2
[/local/endpoint/ep0] Enter Metadata (value/no): n

---
client/player.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/client/player.c b/client/player.c
index a40bf66e3..35143115a 100644
--- a/client/player.c
+++ b/client/player.c
@@ -3809,6 +3809,48 @@ static void config_endpoint_iso_group(const char *input, void *user_data)
}
}

+static void endpoint_set_reconfigure_cfg(const char *input, void *user_data)
+{
+ char *endptr = NULL;
+ int value;
+ struct endpoint_config *cfg = user_data;
+
+ 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);
+ }
+
+ cfg->ep->iso_stream = value;
+
+ bt_shell_prompt_input(cfg->ep->path,
+ "BIG (auto/value):",
+ config_endpoint_iso_group, cfg);
+}
+
+static void endpoint_is_reconfigure_cfg(const char *input, void *user_data)
+{
+ struct endpoint_config *cfg = user_data;
+
+ if (!strcasecmp(input, "n") || !strcasecmp(input, "no")) {
+ cfg->ep->iso_stream = BT_ISO_QOS_STREAM_UNSET;
+ goto done;
+ } else {
+ bt_shell_printf("The BIS index is assigned in the order of "
+ "the configuration starting with 1\n");
+ bt_shell_prompt_input(cfg->ep->path,
+ "BIS Index (value):",
+ endpoint_set_reconfigure_cfg, cfg);
+ return;
+ }
+
+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);
@@ -3835,8 +3877,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);
+ "This is a BIS reconfiguration? (yes/no):",
+ endpoint_is_reconfigure_cfg, cfg);
}

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


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

---
profiles/audio/bap.c | 85 ++++++++++++++++++++++++++++++++++++++++++
profiles/audio/media.c | 3 +-
src/shared/bap.c | 9 ++++-
3 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 1b8a47c52..c07506c45 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;
@@ -881,6 +886,62 @@ 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(setup->base, 1);
+ setup->base = NULL;
+
+ if (setup->qos.bcast.bis == bis_cnt) {
+ util_iov_free(ent_setup->caps, 1);
+ ent_setup->caps = util_iov_dup(setup->caps, 1);
+ util_iov_free(ent_setup->metadata, 1);
+ ent_setup->metadata = util_iov_dup(setup->metadata, 1);
+ memcpy(&ent_setup->qos, &setup->qos,
+ sizeof(struct bt_bap_bcast_qos));
+ ent_setup->qos.bcast.bcode = util_iov_dup(
+ setup->qos.bcast.bcode, 1);
+
+ 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)
{
@@ -922,6 +983,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 updated 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/media.c b/profiles/audio/media.c
index edaff7867..084c09fc7 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -1154,7 +1154,8 @@ static int pac_config(struct bt_bap_stream *stream, struct iovec *cfg,

endpoint->transports = g_slist_append(endpoint->transports,
transport);
- }
+ } else if (bt_bap_stream_get_dir(stream) == BT_BAP_BCAST_SINK)
+ bap_update_bcast_config(transport);

msg = dbus_message_new_method_call(endpoint->sender, endpoint->path,
MEDIA_ENDPOINT_INTERFACE,
diff --git a/src/shared/bap.c b/src/shared/bap.c
index 37fc1de4e..07f5671e4 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -1701,7 +1701,14 @@ 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;
+
+ 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


2024-03-08 17:37:48

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH BlueZ 1/3] player: Add reconfiguration prompt for broadcast source

Hi Silviu,

On Fri, Mar 8, 2024 at 11:52 AM Silviu Florian Barbulescu
<[email protected]> wrote:
>
> endpoint.config /org/bluez/hci0/pac_bcast0 /local/endpoint/ep0 48_4_1
> [/local/endpoint/ep0] This is a BIS Reconfiguration? (yes/no): y
> The BIS index is assigned in the order of the configuration
> starting with 1
> [/local/endpoint/ep0] BIS Index (value): 1
> [/local/endpoint/ep0] BIG (auto/value): 0
> [/local/endpoint/ep0] Enter channel location (value/no): 2
> [/local/endpoint/ep0] Enter Metadata (value/no): n
>
> ---
> client/player.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 44 insertions(+), 2 deletions(-)
>
> diff --git a/client/player.c b/client/player.c
> index a40bf66e3..35143115a 100644
> --- a/client/player.c
> +++ b/client/player.c
> @@ -3809,6 +3809,48 @@ static void config_endpoint_iso_group(const char *input, void *user_data)
> }
> }
>
> +static void endpoint_set_reconfigure_cfg(const char *input, void *user_data)
> +{
> + char *endptr = NULL;
> + int value;
> + struct endpoint_config *cfg = user_data;
> +
> + 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);
> + }
> +
> + cfg->ep->iso_stream = value;
> +
> + bt_shell_prompt_input(cfg->ep->path,
> + "BIG (auto/value):",
> + config_endpoint_iso_group, cfg);
> +}
> +
> +static void endpoint_is_reconfigure_cfg(const char *input, void *user_data)
> +{
> + struct endpoint_config *cfg = user_data;
> +
> + if (!strcasecmp(input, "n") || !strcasecmp(input, "no")) {
> + cfg->ep->iso_stream = BT_ISO_QOS_STREAM_UNSET;
> + goto done;
> + } else {
> + bt_shell_printf("The BIS index is assigned in the order of "
> + "the configuration starting with 1\n");
> + bt_shell_prompt_input(cfg->ep->path,
> + "BIS Index (value):",
> + endpoint_set_reconfigure_cfg, cfg);
> + return;
> + }
> +
> +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);
> @@ -3835,8 +3877,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);
> + "This is a BIS reconfiguration? (yes/no):",
> + endpoint_is_reconfigure_cfg, cfg);
> }
>
> static void cmd_config_endpoint(int argc, char *argv[])
> --
> 2.39.2

Instead of having a 2 step process we could ask the BIS index right
away and if the user answers no/0 it means it doesn't want to
reconfigure an existing index.

--
Luiz Augusto von Dentz

2024-03-08 17:42:11

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH BlueZ 2/3] transport: Add support to update the transport configuration

Hi Silviu,

On Fri, Mar 8, 2024 at 11:52 AM Silviu Florian Barbulescu
<[email protected]> wrote:
>
> Add support to update the transport configuration
>
> ---
> profiles/audio/transport.c | 23 +++++++++++++++++++++++
> profiles/audio/transport.h | 1 +
> 2 files changed, 24 insertions(+)
>
> diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
> index 159fbd575..c8492d4a1 100644
> --- a/profiles/audio/transport.c
> +++ b/profiles/audio/transport.c
> @@ -1483,6 +1483,29 @@ static void bap_update_bcast_qos(const struct media_transport *transport)
> "Configuration");
> }
>
> +void bap_update_bcast_config(struct media_transport *transport)
> +{
> + struct bap_transport *bap = transport->data;
> + struct iovec *cc;
> +
> + cc = bt_bap_stream_get_config(bap->stream);
> +
> + if (((int)cc->iov_len != transport->size) ||
> + (memcmp(cc->iov_base, transport->configuration,
> + transport->size) != 0)) {
> + free(transport->configuration);
> + transport->configuration = util_memdup(cc->iov_base,
> + cc->iov_len);
> + transport->size = cc->iov_len;
> +
> + g_dbus_emit_property_changed(btd_get_dbus_connection(),
> + transport->path, MEDIA_TRANSPORT_INTERFACE,
> + "Configuration");
> + }
> +
> + bap_update_bcast_qos(transport);
> +}
> +
> static guint transport_bap_resume(struct media_transport *transport,
> struct media_owner *owner)
> {
> diff --git a/profiles/audio/transport.h b/profiles/audio/transport.h
> index b46bc8025..6df419a67 100644
> --- a/profiles/audio/transport.h
> +++ b/profiles/audio/transport.h
> @@ -16,6 +16,7 @@ struct media_transport *media_transport_create(struct btd_device *device,
> uint8_t *configuration,
> size_t size, void *data,
> void *stream);
> +void bap_update_bcast_config(struct media_transport *transport);

Lets not bypass layers here, so the config updates probably need to be
pushed thru bt_bap_stream somehow, perhaps via a new callback or a
state change where the transport.c can query the new configuration and
update its D-Bus property.

> void media_transport_destroy(struct media_transport *transport);
> const char *media_transport_get_path(struct media_transport *transport);
> --
> 2.39.2
>


--
Luiz Augusto von Dentz

2024-03-08 19:33:58

by bluez.test.bot

[permalink] [raw]
Subject: RE: Broadcast source reconfiguration support

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=833849

---Test result---

Test Summary:
CheckPatch PASS 1.53 seconds
GitLint PASS 1.00 seconds
BuildEll PASS 24.54 seconds
BluezMake PASS 1713.73 seconds
MakeCheck PASS 13.65 seconds
MakeDistcheck PASS 179.10 seconds
CheckValgrind PASS 249.57 seconds
CheckSmatch PASS 352.54 seconds
bluezmakeextell PASS 119.87 seconds
IncrementalBuild PASS 4739.05 seconds
ScanBuild PASS 1075.86 seconds



---
Regards,
Linux Bluetooth