From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> In order for states to be sent the stream cannot be freed since pending_states could be pending due to be processing a CP operation, so this attempts to grap a reference to the stream so it is not freed while states are pending. --- src/shared/bap.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/shared/bap.c b/src/shared/bap.c index 650bea2f4e8d..dbeb43fe509d 100644 --- a/src/shared/bap.c +++ b/src/shared/bap.c @@ -1130,11 +1130,9 @@ static void stream_notify_release(struct bt_bap_stream *stream) DBG(stream->bap, "stream %p", stream); - memset(&status, 0, sizeof(status)); status.id = ep->id; - ep->state = BT_BAP_STREAM_STATE_RELEASING; - status.state = ep->state; + status.state = BT_ASCS_ASE_STATE_RELEASING; gatt_db_attribute_notify(ep->attr, (void *)&status, sizeof(status), bt_bap_get_att(stream->bap)); @@ -1283,8 +1281,10 @@ static void bap_abort_stream_req(struct bt_bap *bap, queue_remove_all(bap->reqs, match_req_stream, stream, bap_req_abort); } -static void bt_bap_stream_unref(struct bt_bap_stream *stream) +static void bt_bap_stream_unref(void *data) { + struct bt_bap_stream *stream = data; + if (!stream) return; @@ -1308,7 +1308,6 @@ static void bap_ucast_detach(struct bt_bap_stream *stream) queue_remove(stream->bap->streams, stream); bap_stream_clear_cfm(stream); - stream->ep = NULL; ep->stream = NULL; bt_bap_stream_unref(stream); } @@ -1751,6 +1750,16 @@ static bool stream_notify_state(void *data) return false; } +static struct bt_bap_stream *bt_bap_stream_ref(struct bt_bap_stream *stream) +{ + if (!stream) + return NULL; + + __sync_fetch_and_add(&stream->ref_count, 1); + + return stream; +} + static void bap_ucast_set_state(struct bt_bap_stream *stream, uint8_t state) { struct bt_bap_endpoint *ep = stream->ep; @@ -1771,7 +1780,8 @@ static void bap_ucast_set_state(struct bt_bap_stream *stream, uint8_t state) else if (!stream->state_id) stream->state_id = timeout_add(BAP_PROCESS_TIMEOUT, stream_notify_state, - stream, NULL); + bt_bap_stream_ref(stream), + bt_bap_stream_unref); else /* If a state_id is already pending then queue the old one */ queue_push_tail(stream->pending_states, UINT_TO_PTR(ep->old_state)); @@ -2258,16 +2268,6 @@ static unsigned int bap_ucast_release(struct bt_bap_stream *stream, return req->id; } -static struct bt_bap_stream *bt_bap_stream_ref(struct bt_bap_stream *stream) -{ - if (!stream) - return NULL; - - __sync_fetch_and_add(&stream->ref_count, 1); - - return stream; -} - static void bap_bcast_set_state(struct bt_bap_stream *stream, uint8_t state) { struct bt_bap *bap = stream->bap; -- 2.49.0