* [PATCH BlueZ 1/1] bass: Register bap attached/detached callbacks
2025-02-11 14:19 [PATCH BlueZ 0/1] bass: Register bap attached/detached callbacks Iulia Tanasescu
@ 2025-02-11 14:19 ` Iulia Tanasescu
2025-02-11 17:39 ` bluez.test.bot
2025-02-12 21:40 ` [PATCH BlueZ 0/1] " patchwork-bot+bluetooth
1 sibling, 1 reply; 4+ messages in thread
From: Iulia Tanasescu @ 2025-02-11 14:19 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, andrei.istodorescu,
luiz.dentz, Iulia Tanasescu
This removes the bass_bcast_probe and bass_bcast_remove APIs, in order to
decouple the BASS and BAP plugins.
Instead, since the BASS Server (BAP Scan Delegator) implementation needs
to reference the bap session, BASS registers bap attached/detached
callbacks with shared/bap.
- After receiving a request from a Broadcast Assistant, the BASS Server
creates a device for the Broadcaster and adds the UUID to probe.
- The service is probed inside the BAP plugin, where a new bt_bap session
is attached. The service is set as user data beforehand.
- The bt_bap session is notified in the BASS bap_attached callback. The
reference to the service is accessible from the user data.
- The BASS Server takes ownership for the service by setting its user
data. This way, short-lived PA sync will be skipped inside BAP, and the
BASS Server will handle long-lived PA sync and stream configuration.
- When the bt_bap session is removed, it will be notified in the
bap_detached callback.
---
profiles/audio/bap.c | 53 ++++++++++++++++++++++++++++++-------------
profiles/audio/bass.c | 46 +++++++++++++++++++++----------------
profiles/audio/bass.h | 5 +---
3 files changed, 64 insertions(+), 40 deletions(-)
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 77df9455a..c503f250c 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -4,7 +4,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2022 Intel Corporation. All rights reserved.
- * Copyright 2023-2024 NXP
+ * Copyright 2023-2025 NXP
*
*
*/
@@ -192,7 +192,7 @@ static void bap_data_free(struct bap_data *data)
if (data->io_id)
g_source_remove(data->io_id);
- if (data->service) {
+ if (data->service && btd_service_get_user_data(data->service) == data) {
btd_service_set_user_data(data->service, NULL);
bt_bap_set_user_data(data->bap, NULL);
}
@@ -2751,7 +2751,7 @@ static void bap_data_add(struct bap_data *data)
queue_push_tail(sessions, data);
- if (data->service)
+ if (data->service && !btd_service_get_user_data(data->service))
btd_service_set_user_data(data->service, data);
}
@@ -3064,7 +3064,6 @@ static int bap_bcast_probe(struct btd_service *service)
struct btd_adapter *adapter = device_get_adapter(device);
struct btd_gatt_database *database = btd_adapter_get_database(adapter);
struct bap_data *data;
- int ret = 0;
if (!btd_adapter_has_exp_feature(adapter, EXP_FEAT_ISO_SOCKET)) {
error("BAP requires ISO Socket which is not enabled");
@@ -3084,6 +3083,8 @@ static int bap_bcast_probe(struct btd_service *service)
}
data->bcast_snks = queue_new();
+ bt_bap_set_user_data(data->bap, service);
+
if (!bt_bap_attach(data->bap, NULL)) {
error("BAP unable to attach");
return -EINVAL;
@@ -3098,13 +3099,18 @@ static int bap_bcast_probe(struct btd_service *service)
data->pac_id = bt_bap_pac_register(data->bap, pac_added_broadcast,
pac_removed_broadcast, data, NULL);
- bt_bap_set_user_data(data->bap, service);
-
- if (bass_bcast_probe(service, &ret))
- /* Return if probed device was handled inside BASS. */
- return ret;
-
- pa_sync(data);
+ if (btd_service_get_user_data(service) == data)
+ /* If the reference to the bap session has been set as service
+ * user data, it means the broadcaster was autonomously probed.
+ * Thus, the Broadcast Sink needs to create short lived PA sync
+ * to discover streams.
+ *
+ * If the service user data does not match the bap session, it
+ * means that the broadcaster was probed via a Broadcast
+ * Assistant from the BASS plugin, where stream discovery and
+ * configuration will also be handled.
+ */
+ pa_sync(data);
return 0;
}
@@ -3118,15 +3124,12 @@ static void bap_bcast_remove(struct btd_service *service)
ba2str(device_get_address(device), addr);
DBG("%s", addr);
- data = btd_service_get_user_data(service);
+ data = queue_find(sessions, match_device, device);
if (!data) {
error("BAP service not handled by profile");
return;
}
- /* Notify the BASS plugin about the removed session. */
- bass_bcast_remove(device);
-
bap_data_remove(data);
bass_remove_stream(device);
@@ -3225,6 +3228,24 @@ static int bap_disconnect(struct btd_service *service)
return 0;
}
+static int bap_bcast_disconnect(struct btd_service *service)
+{
+ struct btd_device *device = btd_service_get_device(service);
+ struct bap_data *data;
+
+ data = queue_find(sessions, match_device, device);
+ if (!data) {
+ error("BAP service not handled by profile");
+ return -EINVAL;
+ }
+
+ bt_bap_detach(data->bap);
+
+ btd_service_disconnecting_complete(service, 0);
+
+ return 0;
+}
+
static int bap_adapter_probe(struct btd_profile *p, struct btd_adapter *adapter)
{
struct btd_gatt_database *database = btd_adapter_get_database(adapter);
@@ -3307,7 +3328,7 @@ static struct btd_profile bap_bcast_profile = {
.remote_uuid = BCAAS_UUID_STR,
.device_probe = bap_bcast_probe,
.device_remove = bap_bcast_remove,
- .disconnect = bap_disconnect,
+ .disconnect = bap_bcast_disconnect,
.auto_connect = false,
.experimental = true,
};
diff --git a/profiles/audio/bass.c b/profiles/audio/bass.c
index 3a37d6711..6c84fa1c3 100644
--- a/profiles/audio/bass.c
+++ b/profiles/audio/bass.c
@@ -3,7 +3,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright 2023-2024 NXP
+ * Copyright 2023-2025 NXP
*
*/
@@ -557,26 +557,27 @@ static void confirm_cb(GIOChannel *io, void *user_data)
dg->io_id = g_io_add_watch(io, G_IO_OUT, big_info_cb, dg);
}
-bool bass_bcast_probe(struct btd_service *service, int *ret)
+static void bap_attached(struct bt_bap *bap, void *user_data)
{
+ struct btd_service *service = bt_bap_get_user_data(bap);
struct btd_device *device = btd_service_get_device(service);
struct btd_adapter *adapter = device_get_adapter(device);
struct bass_delegator *dg;
GError *err = NULL;
+ DBG("%p", bap);
+
dg = queue_find(delegators, delegator_match_device, device);
if (!dg)
/* Only probe devices added via Broadcast Assistants */
- return false;
+ return;
- if (dg->service) {
+ if (dg->service)
/* Service has already been probed */
- *ret = -EINVAL;
- return true;
- }
+ return;
dg->service = service;
- dg->bap = bap_get_session(device);
+ dg->bap = bap;
dg->io = bt_io_listen(NULL, confirm_cb, dg,
NULL, &err,
@@ -593,11 +594,12 @@ bool bass_bcast_probe(struct btd_service *service, int *ret)
BT_IO_OPT_INVALID);
if (!dg->io) {
error("%s", err->message);
- *ret = -err->code;
g_error_free(err);
+ return;
}
- return true;
+ /* Take ownership for the service by setting the user data. */
+ btd_service_set_user_data(service, dg);
}
static void setup_free(void *data)
@@ -610,22 +612,23 @@ static void setup_free(void *data)
util_iov_free(setup->meta, 1);
util_iov_free(setup->config, 1);
- if (setup->stream) {
- uint8_t state = bt_bap_stream_get_state(setup->stream);
-
- if (state == BT_BAP_STREAM_STATE_STREAMING)
- bt_bass_clear_bis_sync(setup->dg->src,
- stream_get_bis(setup->stream));
- }
+ /* Clear bis index from the bis sync bitmask, if it
+ * has been previously set.
+ */
+ bt_bass_clear_bis_sync(setup->dg->src, setup->bis);
}
-bool bass_bcast_remove(struct btd_device *device)
+static void bap_detached(struct bt_bap *bap, void *user_data)
{
+ struct btd_service *service = bt_bap_get_user_data(bap);
+ struct btd_device *device = btd_service_get_device(service);
struct bass_delegator *dg;
+ DBG("%p", bap);
+
dg = queue_remove_if(delegators, delegator_match_device, device);
if (!dg)
- return false;
+ return;
DBG("%p", dg);
@@ -657,7 +660,7 @@ bool bass_bcast_remove(struct btd_device *device)
free(dg);
- return true;
+ btd_service_set_user_data(service, NULL);
}
static void assistant_set_state(struct bass_assistant *assistant,
@@ -1649,6 +1652,7 @@ static struct btd_profile bass_service = {
};
static unsigned int bass_id;
+static unsigned int bap_id;
static int bass_init(void)
{
@@ -1659,6 +1663,7 @@ static int bass_init(void)
return err;
bass_id = bt_bass_register(bass_attached, bass_detached, NULL);
+ bap_id = bt_bap_register(bap_attached, bap_detached, NULL);
return 0;
}
@@ -1667,6 +1672,7 @@ static void bass_exit(void)
{
btd_profile_unregister(&bass_service);
bt_bass_unregister(bass_id);
+ bt_bap_unregister(bap_id);
}
BLUETOOTH_PLUGIN_DEFINE(bass, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
diff --git a/profiles/audio/bass.h b/profiles/audio/bass.h
index 678532168..99b755259 100644
--- a/profiles/audio/bass.h
+++ b/profiles/audio/bass.h
@@ -3,7 +3,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright 2024 NXP
+ * Copyright 2024-2025 NXP
*
*/
@@ -12,9 +12,6 @@ void bass_add_stream(struct btd_device *device, struct iovec *meta,
uint8_t sgrp, uint8_t bis);
void bass_remove_stream(struct btd_device *device);
-bool bass_bcast_probe(struct btd_service *service, int *ret);
-bool bass_bcast_remove(struct btd_device *device);
-
typedef void (*bt_bass_bcode_func_t)(void *user_data, int err);
void bass_req_bcode(struct bt_bap_stream *stream,
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread