From cac6a5806bff05e70bcecdee700303662c13e3ee Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 5 Jun 2013 08:46:04 +0700 Subject: [PATCH] AVRCP: Fix crash when current addressed player is removed In some stacks e.g. iOS the addressed player is removed before a new player is set which leaves the session poiting to invalid player. --- profiles/audio/avrcp.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c index cc905ac27..c546283fb 100644 --- a/profiles/audio/avrcp.c +++ b/profiles/audio/avrcp.c @@ -2429,6 +2429,20 @@ static void player_destroy(gpointer data) g_free(player); } +static void player_remove(gpointer data) +{ + struct avrcp_player *player = data; + GSList *l; + + for (l = player->sessions; l; l = l->next) { + struct avrcp *session = l->data; + + session->players = g_slist_remove(session->players, player); + } + + player_destroy(player); +} + static gboolean avrcp_get_media_player_list_rsp(struct avctp *conn, uint8_t *operands, size_t operand_count, @@ -2474,7 +2488,10 @@ static gboolean avrcp_get_media_player_list_rsp(struct avctp *conn, i += len; } - g_slist_free_full(removed, player_destroy); + if (g_slist_find(removed, session->player)) + session->player = NULL; + + g_slist_free_full(removed, player_remove); return FALSE; } @@ -2575,12 +2592,15 @@ static void avrcp_addressed_player_changed(struct avrcp *session, struct avrcp_player *player = session->player; uint16_t id = bt_get_be16(&pdu->params[1]); - if (player->id == id) + if (player != NULL && player->id == id) return; player = find_ct_player(session, id); - if (player == NULL) - return; + if (player == NULL) { + player = create_ct_player(session, id); + if (player == NULL) + return; + } player->uid_counter = bt_get_be16(&pdu->params[3]); session->player = player; -- 2.47.3