* [PATCH BlueZ 3/5] client/player: Fix auto registration of broadcast endpoint
2023-06-19 20:30 [PATCH BlueZ 1/5] shared/bap: Add unespecified bit in audio context to PAC records Luiz Augusto von Dentz
2023-06-19 20:30 ` [PATCH BlueZ 2/5] client: Print integers decimal value Luiz Augusto von Dentz
@ 2023-06-19 20:30 ` Luiz Augusto von Dentz
2023-06-19 20:30 ` [PATCH BlueZ 4/5] client/player: Fix transport.acquire for linked transports Luiz Augusto von Dentz
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2023-06-19 20:30 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
For broadcast endpoint broadcast must be set properly.
---
client/player.c | 33 +++++++++++++++++----------------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/client/player.c b/client/player.c
index 389fc1d07..a399d82ec 100644
--- a/client/player.c
+++ b/client/player.c
@@ -1740,22 +1740,22 @@ struct endpoint_config {
0xa2, 0x65, 0xbb, 0xaf, 0xc6, 0xea, 0x03, 0xb8}
static struct bt_iso_qos bcast_qos = {
- .bcast = {
- .big = BT_ISO_QOS_BIG_UNSET,
- .bis = BT_ISO_QOS_BIS_UNSET,
- .sync_interval = 0x07,
- .packing = 0x00,
- .framing = 0x00,
- .encryption = 0x00,
- .bcode = BCODE,
- .options = 0x00,
- .skip = 0x0000,
- .sync_timeout = 0x4000,
- .sync_cte_type = 0x00,
- .mse = 0x00,
- .timeout = 0x4000,
- }
- };
+ .bcast = {
+ .big = BT_ISO_QOS_BIG_UNSET,
+ .bis = BT_ISO_QOS_BIS_UNSET,
+ .sync_interval = 24,
+ .packing = 0x00,
+ .framing = 0x00,
+ .encryption = 0x00,
+ .bcode = BCODE,
+ .options = 0x00,
+ .skip = 0x0000,
+ .sync_timeout = 0x4000,
+ .sync_cte_type = 0x00,
+ .mse = 0x00,
+ .timeout = 0x4000,
+ }
+};
static void append_properties(DBusMessageIter *iter,
struct endpoint_config *cfg)
@@ -3175,6 +3175,7 @@ static struct endpoint *endpoint_new(const struct capabilities *cap)
ep = new0(struct endpoint, 1);
ep->uuid = g_strdup(cap->uuid);
+ ep->broadcast = strcmp(cap->uuid, BAA_SERVICE_UUID) ? false : true;
ep->codec = cap->codec_id;
ep->path = g_strdup_printf("%s/ep%u", BLUEZ_MEDIA_ENDPOINT_PATH,
g_list_length(local_endpoints));
--
2.40.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH BlueZ 4/5] client/player: Fix transport.acquire for linked transports
2023-06-19 20:30 [PATCH BlueZ 1/5] shared/bap: Add unespecified bit in audio context to PAC records Luiz Augusto von Dentz
2023-06-19 20:30 ` [PATCH BlueZ 2/5] client: Print integers decimal value Luiz Augusto von Dentz
2023-06-19 20:30 ` [PATCH BlueZ 3/5] client/player: Fix auto registration of broadcast endpoint Luiz Augusto von Dentz
@ 2023-06-19 20:30 ` Luiz Augusto von Dentz
2023-06-19 20:30 ` [PATCH BlueZ 5/5] shared/bap: Pass bcode as a reference instead of value Luiz Augusto von Dentz
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2023-06-19 20:30 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Linked (bi-directional) transports can be acquired on single D-Bus
method call which was not being handled properly by the current code
causing unexpected errors.
---
client/player.c | 202 +++++++++++++++++++++++++-----------------------
1 file changed, 107 insertions(+), 95 deletions(-)
diff --git a/client/player.c b/client/player.c
index a399d82ec..d8d632f84 100644
--- a/client/player.c
+++ b/client/player.c
@@ -72,11 +72,11 @@ struct endpoint {
struct iovec *caps;
struct iovec *meta;
bool auto_accept;
- bool acquiring;
uint8_t max_transports;
uint8_t iso_group;
uint8_t iso_stream;
- char *transport;
+ struct queue *acquiring;
+ struct queue *transports;
DBusMessage *msg;
struct preset *preset;
bool broadcast;
@@ -1075,8 +1075,6 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn,
bt_shell_printf("\tTransport %s\n", path);
print_iter("\t", "Properties", &props);
- free(ep->transport);
-
if (!ep->max_transports) {
bt_shell_printf("Maximum transports reached: rejecting\n");
return g_dbus_create_error(msg,
@@ -1086,7 +1084,10 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn,
ep->max_transports--;
- ep->transport = strdup(path);
+ if (!ep->transports)
+ ep->transports = queue_new();
+
+ queue_push_tail(ep->transports, strdup(path));
if (ep->auto_accept) {
bt_shell_printf("Auto Accepting...\n");
@@ -2030,16 +2031,26 @@ static DBusMessage *endpoint_select_properties(DBusConnection *conn,
return reply;
}
+static bool match_str(const void *data, const void *user_data)
+{
+ return !strcmp(data, user_data);
+}
+
static DBusMessage *endpoint_clear_configuration(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
struct endpoint *ep = user_data;
+ DBusMessageIter args;
+ const char *path;
+
+ dbus_message_iter_init(msg, &args);
+
+ dbus_message_iter_get_basic(&args, &path);
if (ep->max_transports != UINT8_MAX)
ep->max_transports++;
- free(ep->transport);
- ep->transport = NULL;
+ queue_remove_if(ep->transports, match_str, (void *)path);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
@@ -2128,6 +2139,9 @@ static void endpoint_free(void *data)
free(ep->preset);
}
+ queue_destroy(ep->acquiring, NULL);
+ queue_destroy(ep->transports, free);
+
g_free(ep->path);
g_free(ep->uuid);
g_free(ep);
@@ -3431,14 +3445,14 @@ static struct endpoint *find_ep_by_transport(const char *path)
for (l = local_endpoints; l; l = g_list_next(l)) {
struct endpoint *ep = l->data;
- if (ep->transport && !strcmp(ep->transport, path))
+ if (queue_find(ep->transports, match_str, path))
return ep;
}
return NULL;
}
-static struct endpoint *find_link_by_proxy(GDBusProxy *proxy)
+static GDBusProxy *find_link_by_proxy(GDBusProxy *proxy)
{
DBusMessageIter iter, array;
@@ -3450,13 +3464,13 @@ static struct endpoint *find_link_by_proxy(GDBusProxy *proxy)
while (dbus_message_iter_get_arg_type(&array) ==
DBUS_TYPE_OBJECT_PATH) {
const char *transport;
- struct endpoint *link;
dbus_message_iter_get_basic(&array, &transport);
- link = find_ep_by_transport(transport);
- if (link)
- return link;
+ proxy = g_dbus_proxy_lookup(transports, NULL, transport,
+ BLUEZ_MEDIA_TRANSPORT_INTERFACE);
+ if (proxy)
+ return proxy;
}
return NULL;
@@ -3543,21 +3557,49 @@ static void transport_new(GDBusProxy *proxy, int sk, uint16_t mtu[2])
queue_push_tail(ios, transport);
}
+static void ep_set_acquiring(struct endpoint *ep, GDBusProxy *proxy, bool value)
+{
+ bt_shell_printf("Transport %s %s\n", g_dbus_proxy_get_path(proxy),
+ value ? "acquiring" : "acquiring complete");
+
+ if (value && !ep->acquiring)
+ ep->acquiring = queue_new();
+
+ if (value)
+ queue_push_tail(ep->acquiring, proxy);
+ else
+ queue_remove(ep->acquiring, proxy);
+}
+
+static void transport_set_acquiring(GDBusProxy *proxy, bool value)
+{
+ struct endpoint *ep;
+ GDBusProxy *link;
+
+ ep = find_ep_by_transport(g_dbus_proxy_get_path(proxy));
+ if (!ep)
+ return;
+
+ ep_set_acquiring(ep, proxy, value);
+
+ link = find_link_by_proxy(proxy);
+ if (link) {
+ ep = find_ep_by_transport(g_dbus_proxy_get_path(link));
+ if (!ep)
+ return;
+
+ ep_set_acquiring(ep, link, value);
+ }
+}
+
static void acquire_reply(DBusMessage *message, void *user_data)
{
GDBusProxy *proxy = user_data;
- struct endpoint *ep, *link;
DBusError error;
int sk;
uint16_t mtu[2];
- ep = find_ep_by_transport(g_dbus_proxy_get_path(proxy));
- if (ep) {
- ep->acquiring = false;
- link = find_link_by_proxy(proxy);
- if (link)
- link->acquiring = false;
- }
+ transport_set_acquiring(proxy, false);
dbus_error_init(&error);
@@ -3586,33 +3628,61 @@ static void acquire_reply(DBusMessage *message, void *user_data)
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
-static void transport_acquire(const char *input, void *user_data)
+static void prompt_acquire(const char *input, void *user_data)
{
GDBusProxy *proxy = user_data;
- struct endpoint *ep, *link;
if (!strcasecmp(input, "y") || !strcasecmp(input, "yes")) {
if (g_dbus_proxy_method_call(proxy, "Acquire", NULL,
- acquire_reply, proxy, NULL))
+ acquire_reply, proxy, NULL)) {
+ transport_set_acquiring(proxy, true);
return;
+ }
bt_shell_printf("Failed acquire transport\n");
}
+}
- /* Reset acquiring */
+static void transport_acquire(GDBusProxy *proxy, bool prompt)
+{
+ struct endpoint *ep;
+ GDBusProxy *link;
+
+ /* only attempt to acquire if transport is configured with a local
+ * endpoint.
+ */
ep = find_ep_by_transport(g_dbus_proxy_get_path(proxy));
- if (ep) {
- ep->acquiring = false;
- link = find_link_by_proxy(proxy);
- if (link)
- link->acquiring = false;
+ if (!ep || queue_find(ep->acquiring, NULL, proxy))
+ return;
+
+ link = find_link_by_proxy(proxy);
+ if (link) {
+ ep = find_ep_by_transport(g_dbus_proxy_get_path(link));
+ /* if link already acquiring wait it to be complete */
+ if (!ep && queue_find(ep->acquiring, NULL, link))
+ return;
+ }
+
+ if (ep->auto_accept || !prompt) {
+ if (!prompt)
+ bt_shell_printf("auto acquiring...\n");
+ if (!g_dbus_proxy_method_call(proxy, "Acquire", NULL,
+ acquire_reply, proxy, NULL)) {
+ bt_shell_printf("failed acquire transport\n");
+ return;
+ }
+
+ transport_set_acquiring(proxy, true);
+ return;
}
+
+ bt_shell_prompt_input(g_dbus_proxy_get_path(proxy), "acquire (yes/no):",
+ prompt_acquire, proxy);
}
static void transport_property_changed(GDBusProxy *proxy, const char *name,
DBusMessageIter *iter)
{
char *str;
- struct endpoint *ep, *link;
str = proxy_description(proxy, "Transport", COLORED_CHG);
print_iter(str, name, iter);
@@ -3626,38 +3696,7 @@ static void transport_property_changed(GDBusProxy *proxy, const char *name,
if (strcmp(str, "pending"))
return;
- /* Only attempt to acquire if transport is configured with a local
- * endpoint.
- */
- ep = find_ep_by_transport(g_dbus_proxy_get_path(proxy));
- if (!ep || ep->acquiring)
- return;
-
- ep->acquiring = true;
-
- link = find_link_by_proxy(proxy);
- if (link) {
- bt_shell_printf("Link %s found\n", link->transport);
- /* If link already acquiring wait it to be complete */
- if (link->acquiring)
- return;
- link->acquiring = true;
- }
-
- if (ep->auto_accept) {
- bt_shell_printf("Auto Acquiring...\n");
- if (!g_dbus_proxy_method_call(proxy, "Acquire", NULL,
- acquire_reply, proxy, NULL)) {
- bt_shell_printf("Failed acquire transport\n");
- ep->acquiring = false;
- if (link)
- link->acquiring = false;
- }
- return;
- }
-
- bt_shell_prompt_input(g_dbus_proxy_get_path(proxy), "Acquire (yes/no):",
- transport_acquire, proxy);
+ transport_acquire(proxy, true);
}
static void property_changed(GDBusProxy *proxy, const char *name,
@@ -3747,7 +3786,6 @@ static void cmd_acquire_transport(int argc, char *argv[])
{
GDBusProxy *proxy;
int i;
- struct endpoint *ep, *link;
for (i = 1; i < argc; i++) {
proxy = g_dbus_proxy_lookup(transports, NULL, argv[i],
@@ -3763,35 +3801,7 @@ static void cmd_acquire_transport(int argc, char *argv[])
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
- ep = find_ep_by_transport(g_dbus_proxy_get_path(proxy));
- if (!ep || ep->acquiring) {
- bt_shell_printf(
- "Transport %s already in acquiring process\n",
- argv[i]);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
-
- ep->acquiring = true;
-
- link = find_link_by_proxy(proxy);
- if (link) {
- bt_shell_printf("Link %s found\n", link->transport);
- /* If link already acquiring wait it to be complete */
- if (link->acquiring) {
- bt_shell_printf(
- "Link %s is in acquiring process\n",
- argv[i]);
- return bt_shell_noninteractive_quit(
- EXIT_FAILURE);
- }
- link->acquiring = true;
- }
-
- if (!g_dbus_proxy_method_call(proxy, "Acquire", NULL,
- acquire_reply, proxy, NULL)) {
- bt_shell_printf("Failed acquire transport\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
+ transport_acquire(proxy, false);
}
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
@@ -4076,9 +4086,11 @@ static void cmd_send_transport(int argc, char *argv[])
memset(&qos, 0, sizeof(qos));
len = sizeof(qos);
if (getsockopt(transport->sk, SOL_BLUETOOTH, BT_ISO_QOS, &qos,
- &len) < 0)
+ &len) < 0) {
+ bt_shell_printf("Unable to getsockopt(BT_ISO_QOS): %s",
+ strerror(errno));
err = transport_send(transport, fd, NULL);
- else
+ } else
err = transport_send(transport, fd, &qos);
if (err < 0) {
--
2.40.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH BlueZ 5/5] shared/bap: Pass bcode as a reference instead of value
2023-06-19 20:30 [PATCH BlueZ 1/5] shared/bap: Add unespecified bit in audio context to PAC records Luiz Augusto von Dentz
` (2 preceding siblings ...)
2023-06-19 20:30 ` [PATCH BlueZ 4/5] client/player: Fix transport.acquire for linked transports Luiz Augusto von Dentz
@ 2023-06-19 20:30 ` Luiz Augusto von Dentz
2023-06-19 22:26 ` [BlueZ,1/5] shared/bap: Add unespecified bit in audio context to PAC records bluez.test.bot
2023-06-20 20:00 ` [PATCH BlueZ 1/5] " patchwork-bot+bluetooth
5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2023-06-19 20:30 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This makes bcode field a pointer which makes it simpler to detect when
it is set and also fixes the usage of util_iov_free which expects it to
be allocated.
---
profiles/audio/bap.c | 12 +++++-------
src/shared/bap.h | 2 +-
2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index f3564c9e8..8e2fc1556 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -427,12 +427,9 @@ static int parse_properties(DBusMessageIter *props, struct iovec **caps,
dbus_message_iter_get_basic(&value,
&qos->bcast.timeout);
} else if (!strcasecmp(key, "BroadcastCode")) {
- struct iovec *iov;
-
if (var != DBUS_TYPE_ARRAY)
goto fail;
- iov = &qos->bcast.bcode;
- parse_array(&value, &iov);
+ parse_array(&value, &qos->bcast.bcode);
}
dbus_message_iter_next(props);
@@ -624,7 +621,7 @@ static void ep_free(void *data)
util_iov_free(ep->caps, 1);
util_iov_free(ep->metadata, 1);
if (bt_bap_stream_get_type(ep->stream) == BT_BAP_STREAM_TYPE_BCAST)
- util_iov_free(&ep->qos.bcast.bcode, 1);
+ util_iov_free(ep->qos.bcast.bcode, 1);
free(ep->path);
free(ep);
}
@@ -1268,7 +1265,8 @@ static void bap_create_bcast_io(struct bap_data *data, struct bap_ep *ep,
iso_qos.bcast.packing = ep->qos.bcast.packing;
iso_qos.bcast.framing = ep->qos.bcast.framing;
iso_qos.bcast.encryption = ep->qos.bcast.encryption;
- memcpy(iso_qos.bcast.bcode, ep->qos.bcast.bcode.iov_base, 16);
+ if (ep->qos.bcast.bcode)
+ memcpy(iso_qos.bcast.bcode, ep->qos.bcast.bcode->iov_base, 16);
iso_qos.bcast.options = ep->qos.bcast.options;
iso_qos.bcast.skip = ep->qos.bcast.skip;
iso_qos.bcast.sync_timeout = ep->qos.bcast.sync_timeout;
@@ -1811,7 +1809,7 @@ static struct btd_profile bap_profile = {
.disconnect = bap_disconnect,
.adapter_probe = bap_adapter_probe,
.adapter_remove = bap_adapter_remove,
- .auto_connect = true,
+ .auto_connect = false,
.experimental = true,
};
diff --git a/src/shared/bap.h b/src/shared/bap.h
index 8fc41864a..50b567663 100644
--- a/src/shared/bap.h
+++ b/src/shared/bap.h
@@ -79,7 +79,7 @@ struct bt_bap_bcast_qos {
uint8_t packing;
uint8_t framing;
uint8_t encryption;
- struct iovec bcode;
+ struct iovec *bcode;
uint8_t options;
uint16_t skip;
uint16_t sync_timeout;
--
2.40.1
^ permalink raw reply related [flat|nested] 7+ messages in thread