From 4c8a6ba5ec7fb82e77710c69f14f774aa4c348a9 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 6 Sep 2022 12:54:36 -0700 Subject: [PATCH] shared/bap: Fix not unregistering disconnect callback bt_bap_detach shall always unregister the disconnect callback otherwise the session pointer may still be accessible. --- src/shared/bap.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/shared/bap.c b/src/shared/bap.c index 150b2116e..c5f1134d8 100644 --- a/src/shared/bap.c +++ b/src/shared/bap.c @@ -158,6 +158,7 @@ struct bt_bap { unsigned int cp_id; unsigned int process_id; + unsigned int disconn_id; struct queue *reqs; struct queue *pending; struct queue *notify; @@ -623,6 +624,8 @@ static void bap_disconnected(int err, void *user_data) { struct bt_bap *bap = user_data; + bap->disconn_id = 0; + DBG(bap, "bap %p disconnected err %d", bap, err); bt_bap_detach(bap); @@ -643,8 +646,6 @@ static struct bt_bap *bap_get_session(struct bt_att *att, struct gatt_db *db) bap = bt_bap_new(db, NULL); bap->att = att; - bt_att_register_disconnect(att, bap_disconnected, bap, NULL); - bt_bap_attach(bap, NULL); return bap; @@ -3643,6 +3644,19 @@ static void bap_endpoint_foreach(void *data, void *user_data) bap_endpoint_attach(bap, ep); } +static void bap_attach_att(struct bt_bap *bap, struct bt_att *att) +{ + if (bap->disconn_id) { + if (att == bt_bap_get_att(bap)) + return; + bt_att_unregister_disconnect(bap->att, bap->disconn_id); + } + + bap->disconn_id = bt_att_register_disconnect(bap->att, + bap_disconnected, + bap, NULL); +} + bool bt_bap_attach(struct bt_bap *bap, struct bt_gatt_client *client) { bt_uuid_t uuid; @@ -3663,8 +3677,10 @@ bool bt_bap_attach(struct bt_bap *bap, struct bt_gatt_client *client) queue_foreach(bap_cbs, bap_attached, bap); - if (!client) + if (!client) { + bap_attach_att(bap, bap->att); return true; + } if (bap->client) return false; @@ -3674,6 +3690,8 @@ clone: if (!bap->client) return false; + bap_attach_att(bap, bt_gatt_client_get_att(client)); + if (bap->rdb->pacs) { uint16_t value_handle; struct bt_pacs *pacs = bap->rdb->pacs; @@ -3733,6 +3751,9 @@ void bt_bap_detach(struct bt_bap *bap) bt_gatt_client_unref(bap->client); bap->client = NULL; + bt_att_unregister_disconnect(bap->att, bap->disconn_id); + bap->att = NULL; + queue_foreach(bap->streams, stream_foreach_detach, bap); queue_foreach(bap_cbs, bap_detached, bap); } -- 2.47.3