mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-23 04:04:36 +08:00
bap: Remove PA idle timer logic
This removes BAP support for long-lived PA sync (added for Scan Delegator support), since it is now handled inside the BASS plugin. This also removes the PA idle timer logic, since PA/BIG sync requests are now ordered inside the kernel.
This commit is contained in:
parent
e618932b96
commit
e59a915db9
@ -65,15 +65,9 @@
|
||||
#define MEDIA_ENDPOINT_INTERFACE "org.bluez.MediaEndpoint1"
|
||||
#define MEDIA_INTERFACE "org.bluez.Media1"
|
||||
|
||||
/* Periodic advertisments are performed by an idle timer, which,
|
||||
* at every tick, checks a queue for pending PA requests.
|
||||
* When there is no pending requests, an item is popped from the
|
||||
* queue, marked as pending and then it gets processed.
|
||||
*/
|
||||
#define PA_IDLE_TIMEOUT 2
|
||||
|
||||
struct bap_setup {
|
||||
struct bap_ep *ep;
|
||||
struct bap_data *data;
|
||||
struct bt_bap_stream *stream;
|
||||
struct bt_bap_qos qos;
|
||||
int (*qos_parser)(struct bap_setup *setup, const char *key, int var,
|
||||
@ -101,15 +95,9 @@ 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 bap_adapter *adapter;
|
||||
struct btd_adapter *adapter;
|
||||
struct btd_service *service;
|
||||
struct bt_bap *bap;
|
||||
unsigned int ready_id;
|
||||
@ -121,30 +109,12 @@ struct bap_data {
|
||||
struct queue *bcast_snks;
|
||||
struct queue *streams;
|
||||
GIOChannel *listen_io;
|
||||
unsigned int io_id;
|
||||
int selecting;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
enum {
|
||||
BAP_PA_SHORT_REQ = 0, /* Request for short PA sync */
|
||||
BAP_PA_LONG_REQ, /* Request for long PA sync */
|
||||
BAP_PA_BIG_SYNC_REQ, /* Request for PA Sync and BIG Sync */
|
||||
};
|
||||
|
||||
struct bap_bcast_pa_req {
|
||||
uint8_t type;
|
||||
bool in_progress;
|
||||
struct bap_data *bap_data;
|
||||
union {
|
||||
struct btd_service *service;
|
||||
struct queue *setups;
|
||||
} data;
|
||||
unsigned int io_id; /* io_id for BIG Info watch */
|
||||
GIOChannel *io;
|
||||
};
|
||||
|
||||
static struct queue *sessions;
|
||||
static struct queue *adapters;
|
||||
|
||||
/* Structure holding the parameters for Periodic Advertisement create sync.
|
||||
* The full QOS is populated at the time the user selects and endpoint and
|
||||
@ -219,6 +189,9 @@ static void bap_data_free(struct bap_data *data)
|
||||
g_io_channel_unref(data->listen_io);
|
||||
}
|
||||
|
||||
if (data->io_id)
|
||||
g_source_remove(data->io_id);
|
||||
|
||||
if (data->service) {
|
||||
btd_service_set_user_data(data->service, NULL);
|
||||
bt_bap_set_user_data(data->bap, NULL);
|
||||
@ -382,7 +355,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->adapter);
|
||||
path = adapter_get_path(ep->data->adapter);
|
||||
else
|
||||
path = device_get_path(ep->data->device);
|
||||
|
||||
@ -996,12 +969,19 @@ static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool stream_io_unset(const void *data, const void *user_data)
|
||||
{
|
||||
struct bt_bap_stream *stream = (struct bt_bap_stream *)data;
|
||||
|
||||
return !bt_bap_stream_get_io(stream);
|
||||
}
|
||||
|
||||
static void iso_bcast_confirm_cb(GIOChannel *io, GError *err, void *user_data)
|
||||
{
|
||||
struct bap_bcast_pa_req *req = user_data;
|
||||
struct bap_setup *setup;
|
||||
struct bap_setup *setup = user_data;
|
||||
struct bt_bap_stream *stream = setup->stream;
|
||||
int fd;
|
||||
struct bap_data *bap_data = req->bap_data;
|
||||
struct bap_data *bap_data = setup->data;
|
||||
|
||||
DBG("BIG Sync completed");
|
||||
|
||||
@ -1009,28 +989,23 @@ static void iso_bcast_confirm_cb(GIOChannel *io, GError *err, void *user_data)
|
||||
* to the order of the BISes that were enqueued before
|
||||
* calling bt_io_bcast_accept.
|
||||
*/
|
||||
setup = queue_pop_head(req->data.setups);
|
||||
|
||||
if (queue_isempty(req->data.setups)) {
|
||||
/* All fds have been notified. Mark service as connected. */
|
||||
btd_service_connecting_complete(bap_data->service, 0);
|
||||
|
||||
if (req->io) {
|
||||
g_io_channel_unref(req->io);
|
||||
g_io_channel_shutdown(req->io, TRUE, NULL);
|
||||
req->io = NULL;
|
||||
}
|
||||
|
||||
queue_remove(bap_data->adapter->bcast_pa_requests, req);
|
||||
queue_destroy(req->data.setups, NULL);
|
||||
free(req);
|
||||
}
|
||||
if (bt_bap_stream_get_io(stream))
|
||||
stream = queue_find(bt_bap_stream_io_get_links(stream),
|
||||
stream_io_unset, NULL);
|
||||
|
||||
fd = g_io_channel_unix_get_fd(io);
|
||||
|
||||
if (bt_bap_stream_set_io(setup->stream, fd)) {
|
||||
if (bt_bap_stream_set_io(stream, fd))
|
||||
g_io_channel_set_close_on_unref(io, FALSE);
|
||||
return;
|
||||
|
||||
if (!queue_find(bt_bap_stream_io_get_links(stream),
|
||||
stream_io_unset, NULL)) {
|
||||
/* All fds have been notified. Mark service as connected. */
|
||||
btd_service_connecting_complete(bap_data->service, 0);
|
||||
|
||||
g_io_channel_unref(bap_data->listen_io);
|
||||
g_io_channel_shutdown(bap_data->listen_io, TRUE, NULL);
|
||||
bap_data->listen_io = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1097,6 +1072,8 @@ static void create_stream_for_bis(struct bap_data *bap_data,
|
||||
/* Create an internal copy for bcode */
|
||||
setup->qos.bcast.bcode = util_iov_dup(qos->bcast.bcode, 1);
|
||||
|
||||
setup->data = bap_data;
|
||||
|
||||
queue_push_tail(bap_data->bcast_snks, setup);
|
||||
|
||||
/* Create and configure stream */
|
||||
@ -1139,8 +1116,7 @@ static gboolean big_info_report_cb(GIOChannel *io, GIOCondition cond,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *err = NULL;
|
||||
struct bap_bcast_pa_req *req = user_data;
|
||||
struct bap_data *data = btd_service_get_user_data(req->data.service);
|
||||
struct bap_data *data = user_data;
|
||||
struct bt_iso_base base;
|
||||
struct bt_iso_qos qos;
|
||||
struct iovec iov;
|
||||
@ -1156,7 +1132,7 @@ static gboolean big_info_report_cb(GIOChannel *io, GIOCondition cond,
|
||||
error("%s", err->message);
|
||||
g_error_free(err);
|
||||
g_io_channel_shutdown(io, TRUE, NULL);
|
||||
req->io_id = 0;
|
||||
data->io_id = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1165,18 +1141,10 @@ static gboolean big_info_report_cb(GIOChannel *io, GIOCondition cond,
|
||||
g_io_channel_unref(data->listen_io);
|
||||
data->listen_io = NULL;
|
||||
|
||||
if (req->type == BAP_PA_LONG_REQ) {
|
||||
/* If long-lived PA sync was requested, keep a reference
|
||||
* to the PA sync io to keep the sync active.
|
||||
*/
|
||||
data->listen_io = io;
|
||||
g_io_channel_ref(io);
|
||||
} else {
|
||||
/* For short-lived PA, the sync is no longer needed at
|
||||
* this point, so the io can be closed.
|
||||
*/
|
||||
g_io_channel_shutdown(io, TRUE, NULL);
|
||||
}
|
||||
/* For short-lived PA, the sync is no longer needed at
|
||||
* this point, so the io can be closed.
|
||||
*/
|
||||
g_io_channel_shutdown(io, TRUE, NULL);
|
||||
|
||||
/* Analyze received BASE data and create remote media endpoints for each
|
||||
* BIS matching our capabilities
|
||||
@ -1191,23 +1159,21 @@ static gboolean big_info_report_cb(GIOChannel *io, GIOCondition cond,
|
||||
|
||||
util_iov_free(bap_qos.bcast.bcode, 1);
|
||||
|
||||
service_set_connecting(req->data.service);
|
||||
service_set_connecting(data->service);
|
||||
|
||||
queue_remove(data->adapter->bcast_pa_requests, req);
|
||||
req->io_id = 0;
|
||||
free(req);
|
||||
data->io_id = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void iso_pa_sync_confirm_cb(GIOChannel *io, void *user_data)
|
||||
{
|
||||
struct bap_bcast_pa_req *req = user_data;
|
||||
struct bap_data *data = user_data;
|
||||
/* PA Sync was established, wait for BIG Info report so that the
|
||||
* encryption flag is also available.
|
||||
*/
|
||||
DBG("PA Sync done");
|
||||
req->io_id = g_io_add_watch(io, G_IO_OUT, big_info_report_cb,
|
||||
data->io_id = g_io_add_watch(io, G_IO_OUT, big_info_report_cb,
|
||||
user_data);
|
||||
}
|
||||
|
||||
@ -1262,7 +1228,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->adapter;
|
||||
struct btd_adapter *adapter = data->adapter;
|
||||
struct btd_device *device = data->device;
|
||||
struct bap_ep *ep;
|
||||
struct queue *queue;
|
||||
@ -2109,95 +2075,13 @@ static void setup_listen_io(struct bap_data *data, struct bt_bap_stream *stream,
|
||||
data->listen_io = io;
|
||||
}
|
||||
|
||||
static void check_pa_req_in_progress(void *data, void *user_data)
|
||||
{
|
||||
struct bap_bcast_pa_req *req = data;
|
||||
|
||||
if (req->in_progress == TRUE)
|
||||
*((bool *)user_data) = TRUE;
|
||||
}
|
||||
|
||||
static int pa_sync(struct bap_bcast_pa_req *req);
|
||||
static void pa_and_big_sync(struct bap_bcast_pa_req *req);
|
||||
|
||||
static gboolean pa_idle_timer(gpointer user_data)
|
||||
{
|
||||
struct bap_adapter *adapter = user_data;
|
||||
struct bap_bcast_pa_req *req;
|
||||
bool in_progress = FALSE;
|
||||
|
||||
/* Handle timer if no request is in progress */
|
||||
queue_foreach(adapter->bcast_pa_requests, check_pa_req_in_progress,
|
||||
&in_progress);
|
||||
if (in_progress == FALSE) {
|
||||
req = queue_peek_head(adapter->bcast_pa_requests);
|
||||
if (req != NULL)
|
||||
switch (req->type) {
|
||||
case BAP_PA_SHORT_REQ:
|
||||
DBG("do short lived PA Sync");
|
||||
pa_sync(req);
|
||||
break;
|
||||
case BAP_PA_LONG_REQ:
|
||||
DBG("do long lived PA Sync");
|
||||
pa_sync(req);
|
||||
break;
|
||||
case BAP_PA_BIG_SYNC_REQ:
|
||||
DBG("do PA Sync and BIG Sync");
|
||||
pa_and_big_sync(req);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* pa_req queue is empty, stop the timer by returning
|
||||
* FALSE and set the pa_timer_id to 0. This will later
|
||||
* be used to check if the timer is active.
|
||||
*/
|
||||
adapter->pa_timer_id = 0;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
static int pa_sync(struct bap_data *data);
|
||||
static void pa_and_big_sync(struct bap_setup *setup);
|
||||
|
||||
static void setup_accept_io_broadcast(struct bap_data *data,
|
||||
struct bap_setup *setup)
|
||||
{
|
||||
struct bap_bcast_pa_req *req = new0(struct bap_bcast_pa_req, 1);
|
||||
struct bap_adapter *adapter = data->adapter;
|
||||
struct queue *links = bt_bap_stream_io_get_links(setup->stream);
|
||||
const struct queue_entry *entry;
|
||||
|
||||
/* Timer could be stopped if all other requests were treated.
|
||||
* Check the state of the timer and turn it on so that this request
|
||||
* can also be treated.
|
||||
*/
|
||||
if (adapter->pa_timer_id == 0)
|
||||
adapter->pa_timer_id = g_timeout_add_seconds(PA_IDLE_TIMEOUT,
|
||||
pa_idle_timer,
|
||||
adapter);
|
||||
|
||||
/* Add this request to the PA queue.
|
||||
* We don't need to check the queue here, as we cannot have
|
||||
* BAP_PA_BIG_SYNC_REQ before a short PA (BAP_PA_SHORT_REQ)
|
||||
*/
|
||||
req->type = BAP_PA_BIG_SYNC_REQ;
|
||||
req->in_progress = FALSE;
|
||||
req->bap_data = data;
|
||||
|
||||
req->data.setups = queue_new();
|
||||
|
||||
/* Enqueue all linked setups to the request */
|
||||
queue_push_tail(req->data.setups, setup);
|
||||
|
||||
for (entry = queue_get_entries(links); entry;
|
||||
entry = entry->next) {
|
||||
struct bt_bap_stream *stream = entry->data;
|
||||
|
||||
queue_push_tail(req->data.setups,
|
||||
bap_find_setup_by_stream(data, stream));
|
||||
}
|
||||
|
||||
queue_push_tail(adapter->bcast_pa_requests, req);
|
||||
pa_and_big_sync(setup);
|
||||
}
|
||||
|
||||
static void setup_create_ucast_io(struct bap_data *data,
|
||||
@ -2952,10 +2836,8 @@ static void bap_detached(struct bt_bap *bap, void *user_data)
|
||||
bap_data_remove(data);
|
||||
}
|
||||
|
||||
static int pa_sync(struct bap_bcast_pa_req *req)
|
||||
static int pa_sync(struct bap_data *data)
|
||||
{
|
||||
struct btd_service *service = req->data.service;
|
||||
struct bap_data *data = btd_service_get_user_data(service);
|
||||
GError *err = NULL;
|
||||
|
||||
if (data->listen_io) {
|
||||
@ -2964,13 +2846,13 @@ static int 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,
|
||||
|
||||
data->listen_io = bt_io_listen(NULL, iso_pa_sync_confirm_cb, data,
|
||||
NULL, &err,
|
||||
BT_IO_OPT_SOURCE_BDADDR,
|
||||
btd_adapter_get_address(data->adapter->adapter),
|
||||
btd_adapter_get_address(data->adapter),
|
||||
BT_IO_OPT_SOURCE_TYPE,
|
||||
btd_adapter_get_address_type(data->adapter->adapter),
|
||||
btd_adapter_get_address_type(data->adapter),
|
||||
BT_IO_OPT_DEST_BDADDR,
|
||||
device_get_address(data->device),
|
||||
BT_IO_OPT_DEST_TYPE,
|
||||
@ -2988,9 +2870,9 @@ static int pa_sync(struct bap_bcast_pa_req *req)
|
||||
|
||||
static void append_setup(void *data, void *user_data)
|
||||
{
|
||||
struct bap_setup *setup = data;
|
||||
struct bt_bap_stream *stream = data;
|
||||
struct sockaddr_iso_bc *addr = user_data;
|
||||
char *path = bt_bap_stream_get_user_data(setup->stream);
|
||||
char *path = bt_bap_stream_get_user_data(stream);
|
||||
int bis = 1;
|
||||
int s_err;
|
||||
const char *strbis = NULL;
|
||||
@ -3015,39 +2897,36 @@ static void append_setup(void *data, void *user_data)
|
||||
|
||||
static void setup_refresh_qos(void *data, void *user_data)
|
||||
{
|
||||
struct bap_setup *setup = data;
|
||||
struct bt_bap_stream *stream = data;
|
||||
struct bap_data *bap_data = user_data;
|
||||
struct bap_setup *setup = bap_find_setup_by_stream(bap_data, stream);
|
||||
|
||||
setup->qos = *bt_bap_stream_get_qos(setup->stream);
|
||||
setup->qos = *bt_bap_stream_get_qos(stream);
|
||||
}
|
||||
|
||||
static void iso_do_big_sync(GIOChannel *io, void *user_data)
|
||||
{
|
||||
GError *err = NULL;
|
||||
struct bap_bcast_pa_req *req = user_data;
|
||||
struct queue *setups = req->data.setups;
|
||||
struct bap_setup *setup = queue_peek_head(setups);
|
||||
struct bap_data *data = req->bap_data;
|
||||
struct bap_setup *setup = user_data;
|
||||
struct bap_data *data = setup->data;
|
||||
struct sockaddr_iso_bc iso_bc_addr = {0};
|
||||
struct bt_iso_qos qos;
|
||||
struct queue *links = bt_bap_stream_io_get_links(setup->stream);
|
||||
|
||||
DBG("PA Sync done");
|
||||
|
||||
if (req->io) {
|
||||
g_io_channel_unref(req->io);
|
||||
g_io_channel_shutdown(req->io, TRUE, NULL);
|
||||
req->io = io;
|
||||
g_io_channel_ref(req->io);
|
||||
}
|
||||
|
||||
iso_bc_addr.bc_bdaddr_type = btd_device_get_bdaddr_type(data->device);
|
||||
memcpy(&iso_bc_addr.bc_bdaddr, device_get_address(data->device),
|
||||
sizeof(bdaddr_t));
|
||||
g_io_channel_unref(data->listen_io);
|
||||
g_io_channel_shutdown(data->listen_io, TRUE, NULL);
|
||||
data->listen_io = io;
|
||||
g_io_channel_ref(data->listen_io);
|
||||
|
||||
/* Append each linked BIS to the BIG sync request */
|
||||
queue_foreach(setups, append_setup, &iso_bc_addr);
|
||||
append_setup(setup->stream, &iso_bc_addr);
|
||||
queue_foreach(links, append_setup, &iso_bc_addr);
|
||||
|
||||
/* Refresh qos stored in setups */
|
||||
queue_foreach(setups, setup_refresh_qos, NULL);
|
||||
setup->qos = *bt_bap_stream_get_qos(setup->stream);
|
||||
queue_foreach(links, setup_refresh_qos, data);
|
||||
|
||||
/* Set the user requested QOS */
|
||||
bap_qos_to_iso_qos(&setup->qos, &qos);
|
||||
@ -3061,7 +2940,7 @@ static void iso_do_big_sync(GIOChannel *io, void *user_data)
|
||||
|
||||
if (!bt_io_bcast_accept(io,
|
||||
iso_bcast_confirm_cb,
|
||||
req, NULL, &err,
|
||||
setup, NULL, &err,
|
||||
BT_IO_OPT_ISO_BC_NUM_BIS,
|
||||
iso_bc_addr.bc_num_bis, BT_IO_OPT_ISO_BC_BIS,
|
||||
iso_bc_addr.bc_bis, BT_IO_OPT_INVALID)) {
|
||||
@ -3070,28 +2949,16 @@ static void iso_do_big_sync(GIOChannel *io, void *user_data)
|
||||
}
|
||||
}
|
||||
|
||||
static void pa_and_big_sync(struct bap_bcast_pa_req *req)
|
||||
static void pa_and_big_sync(struct bap_setup *setup)
|
||||
{
|
||||
GError *err = NULL;
|
||||
struct bap_data *bap_data = req->bap_data;
|
||||
|
||||
req->in_progress = TRUE;
|
||||
|
||||
if (bap_data->listen_io) {
|
||||
/* If there is an active listen io for the BAP session
|
||||
* with the Broadcast Source, it means that PA sync is
|
||||
* already established. Go straight to establishing BIG
|
||||
* sync.
|
||||
*/
|
||||
iso_do_big_sync(bap_data->listen_io, req);
|
||||
return;
|
||||
}
|
||||
struct bap_data *bap_data = setup->data;
|
||||
|
||||
DBG("Create PA sync with this source");
|
||||
req->io = bt_io_listen(NULL, iso_do_big_sync, req,
|
||||
bap_data->listen_io = bt_io_listen(NULL, iso_do_big_sync, setup,
|
||||
NULL, &err,
|
||||
BT_IO_OPT_SOURCE_BDADDR,
|
||||
btd_adapter_get_address(bap_data->adapter->adapter),
|
||||
btd_adapter_get_address(bap_data->adapter),
|
||||
BT_IO_OPT_DEST_BDADDR,
|
||||
device_get_address(bap_data->device),
|
||||
BT_IO_OPT_DEST_TYPE,
|
||||
@ -3099,26 +2966,17 @@ static void pa_and_big_sync(struct bap_bcast_pa_req *req)
|
||||
BT_IO_OPT_MODE, BT_IO_MODE_ISO,
|
||||
BT_IO_OPT_QOS, &bap_sink_pa_qos,
|
||||
BT_IO_OPT_INVALID);
|
||||
if (!req->io) {
|
||||
if (!bap_data->listen_io) {
|
||||
error("%s", err->message);
|
||||
g_error_free(err);
|
||||
}
|
||||
}
|
||||
|
||||
static bool match_bap_adapter(const void *data, const void *match_data)
|
||||
{
|
||||
struct bap_adapter *adapter = (struct bap_adapter *)data;
|
||||
|
||||
return 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_bcast_pa_req *req;
|
||||
uint8_t type = BAP_PA_LONG_REQ;
|
||||
struct bap_data *data;
|
||||
int ret = 0;
|
||||
|
||||
@ -3127,27 +2985,10 @@ static int bap_bcast_probe(struct btd_service *service)
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
data = queue_find(sessions, match_device, device);
|
||||
if (data && data->service) {
|
||||
error("Profile probed twice for the same device!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
data = bap_data_new(device);
|
||||
data->device = device;
|
||||
bap_data_add(data);
|
||||
|
||||
/* The Broadcaster was scanned autonomously,
|
||||
* so it should be probed short-lived.
|
||||
*/
|
||||
type = BAP_PA_SHORT_REQ;
|
||||
}
|
||||
|
||||
data = bap_data_new(device);
|
||||
data->service = service;
|
||||
btd_service_set_user_data(service, data);
|
||||
|
||||
data->adapter = queue_find(adapters, match_bap_adapter, adapter);
|
||||
data->adapter = adapter;
|
||||
data->device = device;
|
||||
data->bap = bt_bap_new(btd_gatt_database_get_db(database),
|
||||
btd_gatt_database_get_db(database));
|
||||
if (!data->bap) {
|
||||
@ -3155,9 +2996,6 @@ static int bap_bcast_probe(struct btd_service *service)
|
||||
free(data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bt_bap_set_debug(data->bap, bap_debug, NULL, NULL);
|
||||
|
||||
data->bcast_snks = queue_new();
|
||||
|
||||
if (!bt_bap_attach(data->bap, NULL)) {
|
||||
@ -3165,6 +3003,8 @@ static int bap_bcast_probe(struct btd_service *service)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bap_data_add(data);
|
||||
|
||||
data->ready_id = bt_bap_ready_register(data->bap, bap_ready, service,
|
||||
NULL);
|
||||
data->state_id = bt_bap_state_register(data->bap, bap_state_bcast_sink,
|
||||
@ -3178,36 +3018,15 @@ static int bap_bcast_probe(struct btd_service *service)
|
||||
/* Return if probed device was handled inside BASS. */
|
||||
return ret;
|
||||
|
||||
/* Start the PA timer if it hasn't been started yet */
|
||||
if (data->adapter->pa_timer_id == 0)
|
||||
data->adapter->pa_timer_id = g_timeout_add_seconds(
|
||||
PA_IDLE_TIMEOUT,
|
||||
pa_idle_timer,
|
||||
data->adapter);
|
||||
|
||||
/* Enqueue this device advertisement so that we can create PA sync. */
|
||||
DBG("enqueue service: %p", service);
|
||||
req = new0(struct bap_bcast_pa_req, 1);
|
||||
req->type = type;
|
||||
req->in_progress = FALSE;
|
||||
req->data.service = service;
|
||||
queue_push_tail(data->adapter->bcast_pa_requests, req);
|
||||
pa_sync(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool match_service(const void *data, const void *match_data)
|
||||
{
|
||||
struct bap_bcast_pa_req *req = (struct bap_bcast_pa_req *)data;
|
||||
|
||||
return req->data.service == match_data;
|
||||
}
|
||||
|
||||
static void bap_bcast_remove(struct btd_service *service)
|
||||
{
|
||||
struct btd_device *device = btd_service_get_device(service);
|
||||
struct bap_data *data;
|
||||
struct bap_bcast_pa_req *req;
|
||||
char addr[18];
|
||||
|
||||
ba2str(device_get_address(device), addr);
|
||||
@ -3218,17 +3037,6 @@ static void bap_bcast_remove(struct btd_service *service)
|
||||
error("BAP service not handled by profile");
|
||||
return;
|
||||
}
|
||||
/* Remove the corresponding entry from the pa_req queue. Any pa_req that
|
||||
* are in progress will be stopped by bap_data_remove which calls
|
||||
* bap_data_free.
|
||||
*/
|
||||
req = queue_remove_if(data->adapter->bcast_pa_requests,
|
||||
match_service, service);
|
||||
if (req && req->io_id) {
|
||||
g_source_remove(req->io_id);
|
||||
req->io_id = 0;
|
||||
}
|
||||
free(req);
|
||||
|
||||
/* Notify the BASS plugin about the removed session. */
|
||||
bass_bcast_remove(device);
|
||||
@ -3370,13 +3178,7 @@ static int bap_adapter_probe(struct btd_profile *p, struct btd_adapter *adapter)
|
||||
bt_bap_set_user_data(data->bap, adapter);
|
||||
bap_data_set_user_data(data, adapter);
|
||||
|
||||
data->adapter = new0(struct bap_adapter, 1);
|
||||
data->adapter->adapter = adapter;
|
||||
|
||||
if (adapters == NULL)
|
||||
adapters = queue_new();
|
||||
data->adapter->bcast_pa_requests = queue_new();
|
||||
queue_push_tail(adapters, data->adapter);
|
||||
data->adapter = adapter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3391,15 +3193,6 @@ static void bap_adapter_remove(struct btd_profile *p,
|
||||
ba2str(btd_adapter_get_address(adapter), addr);
|
||||
DBG("%s", addr);
|
||||
|
||||
queue_destroy(data->adapter->bcast_pa_requests, free);
|
||||
queue_remove(adapters, data->adapter);
|
||||
free(data->adapter);
|
||||
|
||||
if (queue_isempty(adapters)) {
|
||||
queue_destroy(adapters, NULL);
|
||||
adapters = NULL;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
error("BAP service not handled by profile");
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user