* [PATCH BlueZ] shared/bap: Fix endpoint configuration
@ 2026-02-20 15:55 Frédéric Danis
2026-02-20 17:06 ` [BlueZ] " bluez.test.bot
2026-02-20 17:30 ` [PATCH BlueZ] " Luiz Augusto von Dentz
0 siblings, 2 replies; 3+ messages in thread
From: Frédéric Danis @ 2026-02-20 15:55 UTC (permalink / raw)
To: linux-bluetooth
When a first local endpoint is created after connection to a remote
device this doesn't trigger the SelectProperties request because
bt_bap_bac ops are not yet set when bt_bap_select() is called.
Creating a second local endpoint allows to trigger SelectProperties
request for the first endpoint.
This commit fixes this behavior by setting the ops during bt_bap_pac
creation.
---
profiles/audio/media.c | 4 +---
src/shared/bap.c | 11 ++++++++---
src/shared/bap.h | 30 +++++++++++++++++-------------
unit/test-bap.c | 34 ++++++++++++++++------------------
4 files changed, 42 insertions(+), 37 deletions(-)
diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index 772af1014..0b88c46f1 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -1363,7 +1363,7 @@ static bool endpoint_init_pac(struct media_endpoint *endpoint, uint8_t type,
endpoint->pac = bt_bap_add_vendor_pac(db, name, type, endpoint->codec,
endpoint->cid, endpoint->vid, &endpoint->qos,
- &data, metadata);
+ &data, metadata, &pac_ops, endpoint);
if (!endpoint->pac) {
error("Unable to create PAC");
free(name);
@@ -1371,8 +1371,6 @@ static bool endpoint_init_pac(struct media_endpoint *endpoint, uint8_t type,
return false;
}
- bt_bap_pac_set_ops(endpoint->pac, &pac_ops, endpoint);
-
DBG("PAC %s registered", name);
free(name);
diff --git a/src/shared/bap.c b/src/shared/bap.c
index 37b04c5c1..549c43c34 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -4129,7 +4129,9 @@ struct bt_bap_pac *bt_bap_add_vendor_pac(struct gatt_db *db,
uint8_t id, uint16_t cid, uint16_t vid,
struct bt_bap_pac_qos *qos,
struct iovec *data,
- struct iovec *metadata)
+ struct iovec *metadata,
+ struct bt_bap_pac_ops *ops,
+ void *ops_user_data)
{
struct bt_bap_db *bdb;
struct bt_bap_pac *pac;
@@ -4150,6 +4152,7 @@ struct bt_bap_pac *bt_bap_add_vendor_pac(struct gatt_db *db,
codec.vid = vid;
pac = bap_pac_new(bdb, name, type, &codec, qos, data, metadata);
+ bt_bap_pac_set_ops(pac, ops, ops_user_data);
switch (type) {
case BT_BAP_SINK:
@@ -4178,10 +4181,12 @@ struct bt_bap_pac *bt_bap_add_pac(struct gatt_db *db, const char *name,
uint8_t type, uint8_t id,
struct bt_bap_pac_qos *qos,
struct iovec *data,
- struct iovec *metadata)
+ struct iovec *metadata,
+ struct bt_bap_pac_ops *ops,
+ void *ops_user_data)
{
return bt_bap_add_vendor_pac(db, name, type, id, 0x0000, 0x0000, qos,
- data, metadata);
+ data, metadata, ops, ops_user_data);
}
uint8_t bt_bap_pac_get_type(struct bt_bap_pac *pac)
diff --git a/src/shared/bap.h b/src/shared/bap.h
index c1b75949f..f7e25a93c 100644
--- a/src/shared/bap.h
+++ b/src/shared/bap.h
@@ -67,19 +67,6 @@ struct bt_bap_pac_qos {
uint16_t context;
};
-struct bt_bap_pac *bt_bap_add_vendor_pac(struct gatt_db *db,
- const char *name, uint8_t type,
- uint8_t id, uint16_t cid, uint16_t vid,
- struct bt_bap_pac_qos *qos,
- struct iovec *data,
- struct iovec *metadata);
-
-struct bt_bap_pac *bt_bap_add_pac(struct gatt_db *db, const char *name,
- uint8_t type, uint8_t id,
- struct bt_bap_pac_qos *qos,
- struct iovec *data,
- struct iovec *metadata);
-
struct bt_bap_pac_ops {
int (*select)(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac,
uint32_t chan_alloc, struct bt_bap_pac_qos *qos,
@@ -92,6 +79,23 @@ struct bt_bap_pac_ops {
void (*clear)(struct bt_bap_stream *stream, void *user_data);
};
+struct bt_bap_pac *bt_bap_add_vendor_pac(struct gatt_db *db,
+ const char *name, uint8_t type,
+ uint8_t id, uint16_t cid, uint16_t vid,
+ struct bt_bap_pac_qos *qos,
+ struct iovec *data,
+ struct iovec *metadata,
+ struct bt_bap_pac_ops *ops,
+ void *ops_user_data);
+
+struct bt_bap_pac *bt_bap_add_pac(struct gatt_db *db, const char *name,
+ uint8_t type, uint8_t id,
+ struct bt_bap_pac_qos *qos,
+ struct iovec *data,
+ struct iovec *metadata,
+ struct bt_bap_pac_ops *ops,
+ void *ops_user_data);
+
bool bt_bap_pac_set_ops(struct bt_bap_pac *pac, struct bt_bap_pac_ops *ops,
void *user_data);
diff --git a/unit/test-bap.c b/unit/test-bap.c
index 3a67e7016..ab3996e22 100644
--- a/unit/test-bap.c
+++ b/unit/test-bap.c
@@ -686,12 +686,12 @@ static void test_setup_pacs(struct test_data *data)
BT_BAP_SINK, 0x0ff,
0x0001, 0x0001,
data->qos, data->caps,
- NULL);
+ NULL, NULL, NULL);
else
data->snk = bt_bap_add_pac(data->db, "test-bap-snk",
BT_BAP_SINK, LC3_ID,
data->qos, data->caps,
- NULL);
+ NULL, NULL, NULL);
g_assert(data->snk);
}
@@ -702,12 +702,12 @@ static void test_setup_pacs(struct test_data *data)
BT_BAP_SOURCE, 0x0ff,
0x0001, 0x0001,
data->qos, data->caps,
- NULL);
+ NULL, NULL, NULL);
else
data->src = bt_bap_add_pac(data->db, "test-bap-src",
BT_BAP_SOURCE, LC3_ID,
data->qos, data->caps,
- NULL);
+ NULL, NULL, NULL);
g_assert(data->src);
}
}
@@ -753,30 +753,28 @@ static void test_setup_server(const void *user_data)
data->snk = bt_bap_add_vendor_pac(db, "test-bap-snk",
BT_BAP_SINK, 0x0ff,
0x0001, 0x0001,
- data->qos, NULL,
- NULL);
+ data->qos, NULL, NULL,
+ &ucast_pac_ops, NULL);
else
data->snk = bt_bap_add_pac(db, "test-bap-snk", BT_BAP_SINK,
LC3_ID, data->qos,
- data->caps, NULL);
+ data->caps, NULL,
+ &ucast_pac_ops, NULL);
g_assert(data->snk);
- bt_bap_pac_set_ops(data->snk, &ucast_pac_ops, NULL);
-
if (data->cfg && data->cfg->vs)
data->src = bt_bap_add_vendor_pac(db, "test-bap-snk",
BT_BAP_SOURCE, 0x0ff,
0x0001, 0x0001,
- data->qos, NULL,
- NULL);
+ data->qos, NULL, NULL,
+ &ucast_pac_ops, NULL);
else
data->src = bt_bap_add_pac(db, "test-bap-src", BT_BAP_SOURCE,
LC3_ID, data->qos,
- data->caps, NULL);
+ data->caps, NULL,
+ &ucast_pac_ops, NULL);
g_assert(data->src);
- bt_bap_pac_set_ops(data->src, &ucast_pac_ops, NULL);
-
att = bt_att_new(io_get_fd(io), false);
g_assert(att);
@@ -1052,13 +1050,13 @@ static void test_bcast_config(struct test_data *data)
BT_BAP_BCAST_SOURCE,
0x0ff, 0x0000, 0x0000,
NULL, data->caps,
- NULL);
+ NULL, NULL, NULL);
else
data->bsrc = bt_bap_add_pac(data->db, "test-bap-bsrc",
BT_BAP_BCAST_SOURCE,
LC3_ID,
NULL, data->caps,
- NULL);
+ NULL, NULL, NULL);
g_assert(data->bsrc);
}
@@ -1073,13 +1071,13 @@ static void test_bcast_config(struct test_data *data)
BT_BAP_BCAST_SINK,
0xff, 0x0000, 0x0000,
NULL, data->caps,
- NULL);
+ NULL, NULL, NULL);
else
data->bsnk = bt_bap_add_pac(data->db, "test-bap-bsnk",
BT_BAP_BCAST_SINK,
LC3_ID,
NULL, data->caps,
- NULL);
+ NULL, NULL, NULL);
g_assert(data->bsnk);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* RE: [BlueZ] shared/bap: Fix endpoint configuration
2026-02-20 15:55 [PATCH BlueZ] shared/bap: Fix endpoint configuration Frédéric Danis
@ 2026-02-20 17:06 ` bluez.test.bot
2026-02-20 17:30 ` [PATCH BlueZ] " Luiz Augusto von Dentz
1 sibling, 0 replies; 3+ messages in thread
From: bluez.test.bot @ 2026-02-20 17:06 UTC (permalink / raw)
To: linux-bluetooth, frederic.danis
[-- Attachment #1: Type: text/plain, Size: 1865 bytes --]
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=1055952
---Test result---
Test Summary:
CheckPatch PENDING 0.39 seconds
GitLint PENDING 0.30 seconds
BuildEll PASS 20.93 seconds
BluezMake PASS 634.77 seconds
MakeCheck PASS 18.72 seconds
MakeDistcheck PASS 243.74 seconds
CheckValgrind PASS 293.63 seconds
CheckSmatch WARNING 348.56 seconds
bluezmakeextell PASS 181.35 seconds
IncrementalBuild PENDING 0.41 seconds
ScanBuild PASS 1012.39 seconds
Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:
##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
src/shared/bap.c:312:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:312:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:312:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structures
##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH BlueZ] shared/bap: Fix endpoint configuration
2026-02-20 15:55 [PATCH BlueZ] shared/bap: Fix endpoint configuration Frédéric Danis
2026-02-20 17:06 ` [BlueZ] " bluez.test.bot
@ 2026-02-20 17:30 ` Luiz Augusto von Dentz
1 sibling, 0 replies; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2026-02-20 17:30 UTC (permalink / raw)
To: Frédéric Danis; +Cc: linux-bluetooth
Hi Frederic,
On Fri, Feb 20, 2026 at 10:56 AM Frédéric Danis
<frederic.danis@collabora.com> wrote:
>
> When a first local endpoint is created after connection to a remote
> device this doesn't trigger the SelectProperties request because
> bt_bap_bac ops are not yet set when bt_bap_select() is called.
> Creating a second local endpoint allows to trigger SelectProperties
> request for the first endpoint.
>
> This commit fixes this behavior by setting the ops during bt_bap_pac
> creation.
> ---
> profiles/audio/media.c | 4 +---
> src/shared/bap.c | 11 ++++++++---
> src/shared/bap.h | 30 +++++++++++++++++-------------
> unit/test-bap.c | 34 ++++++++++++++++------------------
> 4 files changed, 42 insertions(+), 37 deletions(-)
>
> diff --git a/profiles/audio/media.c b/profiles/audio/media.c
> index 772af1014..0b88c46f1 100644
> --- a/profiles/audio/media.c
> +++ b/profiles/audio/media.c
> @@ -1363,7 +1363,7 @@ static bool endpoint_init_pac(struct media_endpoint *endpoint, uint8_t type,
>
> endpoint->pac = bt_bap_add_vendor_pac(db, name, type, endpoint->codec,
> endpoint->cid, endpoint->vid, &endpoint->qos,
> - &data, metadata);
> + &data, metadata, &pac_ops, endpoint);
> if (!endpoint->pac) {
> error("Unable to create PAC");
> free(name);
> @@ -1371,8 +1371,6 @@ static bool endpoint_init_pac(struct media_endpoint *endpoint, uint8_t type,
> return false;
> }
>
> - bt_bap_pac_set_ops(endpoint->pac, &pac_ops, endpoint);
> -
> DBG("PAC %s registered", name);
>
> free(name);
> diff --git a/src/shared/bap.c b/src/shared/bap.c
> index 37b04c5c1..549c43c34 100644
> --- a/src/shared/bap.c
> +++ b/src/shared/bap.c
> @@ -4129,7 +4129,9 @@ struct bt_bap_pac *bt_bap_add_vendor_pac(struct gatt_db *db,
> uint8_t id, uint16_t cid, uint16_t vid,
> struct bt_bap_pac_qos *qos,
> struct iovec *data,
> - struct iovec *metadata)
> + struct iovec *metadata,
> + struct bt_bap_pac_ops *ops,
> + void *ops_user_data)
> {
> struct bt_bap_db *bdb;
> struct bt_bap_pac *pac;
> @@ -4150,6 +4152,7 @@ struct bt_bap_pac *bt_bap_add_vendor_pac(struct gatt_db *db,
> codec.vid = vid;
>
> pac = bap_pac_new(bdb, name, type, &codec, qos, data, metadata);
> + bt_bap_pac_set_ops(pac, ops, ops_user_data);
>
> switch (type) {
> case BT_BAP_SINK:
> @@ -4178,10 +4181,12 @@ struct bt_bap_pac *bt_bap_add_pac(struct gatt_db *db, const char *name,
> uint8_t type, uint8_t id,
> struct bt_bap_pac_qos *qos,
> struct iovec *data,
> - struct iovec *metadata)
> + struct iovec *metadata,
> + struct bt_bap_pac_ops *ops,
> + void *ops_user_data)
> {
> return bt_bap_add_vendor_pac(db, name, type, id, 0x0000, 0x0000, qos,
> - data, metadata);
> + data, metadata, ops, ops_user_data);
> }
>
> uint8_t bt_bap_pac_get_type(struct bt_bap_pac *pac)
> diff --git a/src/shared/bap.h b/src/shared/bap.h
> index c1b75949f..f7e25a93c 100644
> --- a/src/shared/bap.h
> +++ b/src/shared/bap.h
> @@ -67,19 +67,6 @@ struct bt_bap_pac_qos {
> uint16_t context;
> };
>
> -struct bt_bap_pac *bt_bap_add_vendor_pac(struct gatt_db *db,
> - const char *name, uint8_t type,
> - uint8_t id, uint16_t cid, uint16_t vid,
> - struct bt_bap_pac_qos *qos,
> - struct iovec *data,
> - struct iovec *metadata);
> -
> -struct bt_bap_pac *bt_bap_add_pac(struct gatt_db *db, const char *name,
> - uint8_t type, uint8_t id,
> - struct bt_bap_pac_qos *qos,
> - struct iovec *data,
> - struct iovec *metadata);
> -
> struct bt_bap_pac_ops {
> int (*select)(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac,
> uint32_t chan_alloc, struct bt_bap_pac_qos *qos,
> @@ -92,6 +79,23 @@ struct bt_bap_pac_ops {
> void (*clear)(struct bt_bap_stream *stream, void *user_data);
> };
>
> +struct bt_bap_pac *bt_bap_add_vendor_pac(struct gatt_db *db,
> + const char *name, uint8_t type,
> + uint8_t id, uint16_t cid, uint16_t vid,
> + struct bt_bap_pac_qos *qos,
> + struct iovec *data,
> + struct iovec *metadata,
> + struct bt_bap_pac_ops *ops,
> + void *ops_user_data);
> +
> +struct bt_bap_pac *bt_bap_add_pac(struct gatt_db *db, const char *name,
> + uint8_t type, uint8_t id,
> + struct bt_bap_pac_qos *qos,
> + struct iovec *data,
> + struct iovec *metadata,
> + struct bt_bap_pac_ops *ops,
> + void *ops_user_data);
Id keep these and only add a variant where we set the ops inline that
way we don't have to rework pacs without ops, etc.
> bool bt_bap_pac_set_ops(struct bt_bap_pac *pac, struct bt_bap_pac_ops *ops,
> void *user_data);
>
> diff --git a/unit/test-bap.c b/unit/test-bap.c
> index 3a67e7016..ab3996e22 100644
> --- a/unit/test-bap.c
> +++ b/unit/test-bap.c
> @@ -686,12 +686,12 @@ static void test_setup_pacs(struct test_data *data)
> BT_BAP_SINK, 0x0ff,
> 0x0001, 0x0001,
> data->qos, data->caps,
> - NULL);
> + NULL, NULL, NULL);
> else
> data->snk = bt_bap_add_pac(data->db, "test-bap-snk",
> BT_BAP_SINK, LC3_ID,
> data->qos, data->caps,
> - NULL);
> + NULL, NULL, NULL);
> g_assert(data->snk);
> }
>
> @@ -702,12 +702,12 @@ static void test_setup_pacs(struct test_data *data)
> BT_BAP_SOURCE, 0x0ff,
> 0x0001, 0x0001,
> data->qos, data->caps,
> - NULL);
> + NULL, NULL, NULL);
> else
> data->src = bt_bap_add_pac(data->db, "test-bap-src",
> BT_BAP_SOURCE, LC3_ID,
> data->qos, data->caps,
> - NULL);
> + NULL, NULL, NULL);
> g_assert(data->src);
> }
> }
> @@ -753,30 +753,28 @@ static void test_setup_server(const void *user_data)
> data->snk = bt_bap_add_vendor_pac(db, "test-bap-snk",
> BT_BAP_SINK, 0x0ff,
> 0x0001, 0x0001,
> - data->qos, NULL,
> - NULL);
> + data->qos, NULL, NULL,
> + &ucast_pac_ops, NULL);
> else
> data->snk = bt_bap_add_pac(db, "test-bap-snk", BT_BAP_SINK,
> LC3_ID, data->qos,
> - data->caps, NULL);
> + data->caps, NULL,
> + &ucast_pac_ops, NULL);
> g_assert(data->snk);
>
> - bt_bap_pac_set_ops(data->snk, &ucast_pac_ops, NULL);
> -
> if (data->cfg && data->cfg->vs)
> data->src = bt_bap_add_vendor_pac(db, "test-bap-snk",
> BT_BAP_SOURCE, 0x0ff,
> 0x0001, 0x0001,
> - data->qos, NULL,
> - NULL);
> + data->qos, NULL, NULL,
> + &ucast_pac_ops, NULL);
> else
> data->src = bt_bap_add_pac(db, "test-bap-src", BT_BAP_SOURCE,
> LC3_ID, data->qos,
> - data->caps, NULL);
> + data->caps, NULL,
> + &ucast_pac_ops, NULL);
> g_assert(data->src);
>
> - bt_bap_pac_set_ops(data->src, &ucast_pac_ops, NULL);
> -
> att = bt_att_new(io_get_fd(io), false);
> g_assert(att);
>
> @@ -1052,13 +1050,13 @@ static void test_bcast_config(struct test_data *data)
> BT_BAP_BCAST_SOURCE,
> 0x0ff, 0x0000, 0x0000,
> NULL, data->caps,
> - NULL);
> + NULL, NULL, NULL);
> else
> data->bsrc = bt_bap_add_pac(data->db, "test-bap-bsrc",
> BT_BAP_BCAST_SOURCE,
> LC3_ID,
> NULL, data->caps,
> - NULL);
> + NULL, NULL, NULL);
>
> g_assert(data->bsrc);
> }
> @@ -1073,13 +1071,13 @@ static void test_bcast_config(struct test_data *data)
> BT_BAP_BCAST_SINK,
> 0xff, 0x0000, 0x0000,
> NULL, data->caps,
> - NULL);
> + NULL, NULL, NULL);
> else
> data->bsnk = bt_bap_add_pac(data->db, "test-bap-bsnk",
> BT_BAP_BCAST_SINK,
> LC3_ID,
> NULL, data->caps,
> - NULL);
> + NULL, NULL, NULL);
>
> g_assert(data->bsnk);
> }
> --
> 2.43.0
>
>
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-02-20 17:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-20 15:55 [PATCH BlueZ] shared/bap: Fix endpoint configuration Frédéric Danis
2026-02-20 17:06 ` [BlueZ] " bluez.test.bot
2026-02-20 17:30 ` [PATCH BlueZ] " Luiz Augusto von Dentz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox