2024-04-24 14:08:23

by Vlad Pruteanu

[permalink] [raw]
Subject: [PATCH BlueZ v2 2/4] bap: Replace adapter in bap_data with bap_adapter

This patch introduces the bap_adapter structure. In addition to btd_adapter
it also holds the pa_timer_id and the bcast_pa_requests queue associated
with that adapter. This enables convenient access to these variables since
the functions that need them already utilize bap_data.

For each adapter a new instance of bap_adapter is created and inserted into
the global queue, bap_adapters.

For each scanned source bap_bcast_probe searches the bap_adapters queue
based on the adapter and stores the result in the bap_data associated
with the source. Operations made on the old global queue are now made
on bap_data->bap_adapter->bcast_pa_requests queue.

While this commit sought to utilize the already existing bap_data in order
to avoid searching in queues, a lookup was still necessary in
bap_bcast_probe. Here, the bap_data for the scanned devices is created and
the bap_adapter field must be set to the appropriate value. There is no way
of getting the correct bap_adapter refference without searching the
bap_adapters queue.
---
profiles/audio/bap.c | 100 ++++++++++++++++++++++++++++---------------
1 file changed, 66 insertions(+), 34 deletions(-)

diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 9e93906ca..d8cd05f26 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -98,9 +98,15 @@ struct bap_ep {
struct queue *setups;
};

+struct bap_adapter {
+ struct btd_adapter *adapter;
+ unsigned int pa_timer_id;
+ struct queue *bcast_pa_requests;
+};
+
struct bap_data {
struct btd_device *device;
- struct btd_adapter *adapter;
+ struct bap_adapter *bap_adapter;
struct btd_service *service;
struct bt_bap *bap;
unsigned int ready_id;
@@ -130,8 +136,7 @@ struct bap_bcast_pa_req {
};

static struct queue *sessions;
-static struct queue *bcast_pa_requests;
-static unsigned int pa_timer_id;
+static struct queue *bap_adapters;

/* Structure holding the parameters for Periodic Advertisement create sync.
* The full QOS is populated at the time the user selects and endpoint and
@@ -366,7 +371,7 @@ static gboolean get_device(const GDBusPropertyTable *property,
const char *path;

if (bt_bap_pac_get_type(ep->lpac) == BT_BAP_BCAST_SOURCE)
- path = adapter_get_path(ep->data->adapter);
+ path = adapter_get_path(ep->data->bap_adapter->adapter);
else
path = device_get_path(ep->data->device);

@@ -993,7 +998,7 @@ static void iso_bcast_confirm_cb(GIOChannel *io, GError *err, void *user_data)

DBG("BIG Sync completed");

- queue_remove(bcast_pa_requests, req);
+ queue_remove(setup->ep->data->bap_adapter->bcast_pa_requests, req);

/* This device is no longer needed */
btd_service_connecting_complete(setup->ep->data->service, 0);
@@ -1150,8 +1155,8 @@ static void iso_pa_sync_confirm_cb(GIOChannel *io, void *user_data)
g_io_channel_unref(data->listen_io);
g_io_channel_shutdown(io, TRUE, NULL);
data->listen_io = NULL;
- queue_remove(bcast_pa_requests, pa_req);
-
+ queue_remove(data->bap_adapter->bcast_pa_requests, pa_req);
+ free(pa_req);
/* Analyze received BASE data and create remote media endpoints for each
* BIS matching our capabilities
*/
@@ -1209,7 +1214,7 @@ static struct bap_ep *ep_register_bcast(struct bap_data *data,
struct bt_bap_pac *lpac,
struct bt_bap_pac *rpac)
{
- struct btd_adapter *adapter = data->adapter;
+ struct btd_adapter *adapter = data->bap_adapter->adapter;
struct btd_device *device = data->device;
struct bap_ep *ep;
struct queue *queue;
@@ -2062,14 +2067,15 @@ static void pa_and_big_sync(struct bap_bcast_pa_req *req);

static gboolean pa_idle_timer(gpointer user_data)
{
- struct bap_bcast_pa_req *req = user_data;
+ struct bap_adapter *bap_adapter = user_data;
+ struct bap_bcast_pa_req *req;
bool in_progress = FALSE;

/* Handle timer if no request is in progress */
- queue_foreach(bcast_pa_requests, check_pa_req_in_progress,
+ queue_foreach(bap_adapter->bcast_pa_requests, check_pa_req_in_progress,
&in_progress);
if (in_progress == FALSE) {
- req = queue_peek_head(bcast_pa_requests);
+ req = queue_peek_head(bap_adapter->bcast_pa_requests);
if (req != NULL)
switch (req->type) {
case BAP_PA_SHORT_REQ:
@@ -2090,6 +2096,7 @@ static void setup_accept_io_broadcast(struct bap_data *data,
struct bap_setup *setup)
{
struct bap_bcast_pa_req *pa_req = new0(struct bap_bcast_pa_req, 1);
+ struct bap_adapter *bap_adapter = data->bap_adapter;

/* Add this request to the PA queue.
* We don't need to check the queue here and the timer, as we cannot
@@ -2098,7 +2105,7 @@ static void setup_accept_io_broadcast(struct bap_data *data,
pa_req->type = BAP_PA_BIG_SYNC_REQ;
pa_req->in_progress = FALSE;
pa_req->data.setup = setup;
- queue_push_tail(bcast_pa_requests, pa_req);
+ queue_push_tail(bap_adapter->bcast_pa_requests, pa_req);
}

static void setup_create_ucast_io(struct bap_data *data,
@@ -2779,18 +2786,18 @@ static int short_lived_pa_sync(struct bap_bcast_pa_req *req)
DBG("Create PA sync with this source");
req->in_progress = TRUE;
data->listen_io = bt_io_listen(NULL, iso_pa_sync_confirm_cb, req,
- NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR,
- btd_adapter_get_address(data->adapter),
- BT_IO_OPT_SOURCE_TYPE,
- btd_adapter_get_address_type(data->adapter),
- BT_IO_OPT_DEST_BDADDR,
- device_get_address(data->device),
- BT_IO_OPT_DEST_TYPE,
- btd_device_get_bdaddr_type(data->device),
- BT_IO_OPT_MODE, BT_IO_MODE_ISO,
- BT_IO_OPT_QOS, &bap_sink_pa_qos,
- BT_IO_OPT_INVALID);
+ NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR,
+ btd_adapter_get_address(data->bap_adapter->adapter),
+ BT_IO_OPT_SOURCE_TYPE,
+ btd_adapter_get_address_type(data->bap_adapter->adapter),
+ BT_IO_OPT_DEST_BDADDR,
+ device_get_address(data->device),
+ BT_IO_OPT_DEST_TYPE,
+ btd_device_get_bdaddr_type(data->device),
+ BT_IO_OPT_MODE, BT_IO_MODE_ISO,
+ BT_IO_OPT_QOS, &bap_sink_pa_qos,
+ BT_IO_OPT_INVALID);
if (!data->listen_io) {
error("%s", err->message);
g_error_free(err);
@@ -2877,7 +2884,7 @@ static void pa_and_big_sync(struct bap_bcast_pa_req *req)
setup->io = bt_io_listen(NULL, iso_do_big_sync, req,
NULL, &err,
BT_IO_OPT_SOURCE_BDADDR,
- btd_adapter_get_address(data->adapter),
+ btd_adapter_get_address(data->bap_adapter->adapter),
BT_IO_OPT_DEST_BDADDR,
device_get_address(data->device),
BT_IO_OPT_DEST_TYPE,
@@ -2891,11 +2898,20 @@ static void pa_and_big_sync(struct bap_bcast_pa_req *req)
}
}

+static bool match_bap_adapter(const void *data, const void *match_data)
+{
+ struct bap_adapter *bap_adapter = (struct bap_adapter *)data;
+
+ return bap_adapter->adapter == match_data;
+}
+
static int bap_bcast_probe(struct btd_service *service)
{
struct btd_device *device = btd_service_get_device(service);
struct btd_adapter *adapter = device_get_adapter(device);
struct btd_gatt_database *database = btd_adapter_get_database(adapter);
+ struct bap_adapter *bap_adapter = queue_find(bap_adapters,
+ match_bap_adapter, adapter);
struct bap_bcast_pa_req *pa_req =
new0(struct bap_bcast_pa_req, 1);
struct bap_data *data;
@@ -2907,7 +2923,7 @@ static int bap_bcast_probe(struct btd_service *service)

data = bap_data_new(device);
data->service = service;
- data->adapter = adapter;
+ data->bap_adapter = bap_adapter;
data->device = device;
data->bap = bt_bap_new(btd_gatt_database_get_db(database),
btd_gatt_database_get_db(database));
@@ -2933,12 +2949,10 @@ static int bap_bcast_probe(struct btd_service *service)

bt_bap_set_user_data(data->bap, service);

- /* First time initialize the queue and start the idle timer */
- if (bcast_pa_requests == NULL) {
- bcast_pa_requests = queue_new();
- pa_timer_id = g_timeout_add_seconds(PA_IDLE_TIMEOUT,
- pa_idle_timer, NULL);
- }
+ /* Start the PA timer if it hasn't been started yet */
+ if (bap_adapter->pa_timer_id == 0)
+ bap_adapter->pa_timer_id = g_timeout_add_seconds(
+ PA_IDLE_TIMEOUT, pa_idle_timer, bap_adapter);

/* Enqueue this device advertisement so that we can do short-lived
*/
@@ -2946,7 +2960,7 @@ static int bap_bcast_probe(struct btd_service *service)
pa_req->type = BAP_PA_SHORT_REQ;
pa_req->in_progress = FALSE;
pa_req->data.service = service;
- queue_push_tail(bcast_pa_requests, pa_req);
+ queue_push_tail(bap_adapter->bcast_pa_requests, pa_req);

return 0;
}
@@ -3067,6 +3081,7 @@ static int bap_adapter_probe(struct btd_profile *p,
{
struct btd_gatt_database *database = btd_adapter_get_database(adapter);
struct bap_data *data;
+ struct bap_adapter *bap_adapter;
char addr[18];

ba2str(btd_adapter_get_address(adapter), addr);
@@ -3078,7 +3093,6 @@ static int bap_adapter_probe(struct btd_profile *p,
}

data = bap_data_new(NULL);
- data->adapter = adapter;

data->bap = bt_bap_new(btd_gatt_database_get_db(database),
btd_gatt_database_get_db(database));
@@ -3102,6 +3116,15 @@ static int bap_adapter_probe(struct btd_profile *p,

bt_bap_set_user_data(data->bap, adapter);
bap_data_set_user_data(data, adapter);
+
+ bap_adapter = new0(struct bap_adapter, 1);
+ bap_adapter->adapter = adapter;
+ data->bap_adapter = bap_adapter;
+
+ if (bap_adapters == NULL)
+ bap_adapters = queue_new();
+ bap_adapter->bcast_pa_requests = queue_new();
+ queue_push_tail(bap_adapters, bap_adapter);
return 0;
}

@@ -3115,6 +3138,15 @@ static void bap_adapter_remove(struct btd_profile *p,
ba2str(btd_adapter_get_address(adapter), addr);
DBG("%s", addr);

+ queue_destroy(data->bap_adapter->bcast_pa_requests, free);
+ queue_remove(bap_adapters, data->bap_adapter);
+ free(data->bap_adapter);
+
+ if (queue_isempty(bap_adapters)) {
+ queue_destroy(bap_adapters, NULL);
+ bap_adapters = NULL;
+ }
+
if (!data) {
error("BAP service not handled by profile");
return;
--
2.40.1