diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 77df945..c503f25 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2022 Intel Corporation. All rights reserved.
- * Copyright 2023-2024 NXP
+ * Copyright 2023-2025 NXP
*
*
*/
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);
}
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);
}
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");
}
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;
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;
}
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);
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);
.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 3a37d67..6c84fa1 100644
--- a/profiles/audio/bass.c
+++ b/profiles/audio/bass.c
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright 2023-2024 NXP
+ * Copyright 2023-2025 NXP
*
*/
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,
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)
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);
free(dg);
- return true;
+ btd_service_set_user_data(service, NULL);
}
static void assistant_set_state(struct bass_assistant *assistant,
};
static unsigned int bass_id;
+static unsigned int bap_id;
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;
}
{
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 6785321..99b7552 100644
--- a/profiles/audio/bass.h
+++ b/profiles/audio/bass.h
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright 2024 NXP
+ * Copyright 2024-2025 NXP
*
*/
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,