From 0f76c2d70915582ff8de185ea493689134962047 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 9 Jun 2017 14:51:46 +0200 Subject: [PATCH] avrcp: emit connestion established with error code on failure --- src/classic/avrcp.c | 72 ++++++++++++++++++++--------------------- test/avrcp/avrcp_test.c | 5 +++ 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/classic/avrcp.c b/src/classic/avrcp.c index bc4bccc74..7dc2fb0c2 100644 --- a/src/classic/avrcp.c +++ b/src/classic/avrcp.c @@ -1029,9 +1029,8 @@ static avrcp_connection_t * avrcp_create_connection(bd_addr_t remote_addr){ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ bd_addr_t event_addr; - hci_con_handle_t con_handle; - uint16_t psm; uint16_t local_cid; + uint8_t status; avrcp_connection_t * connection = NULL; switch (packet_type) { @@ -1046,51 +1045,50 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe case L2CAP_EVENT_INCOMING_CONNECTION: l2cap_event_incoming_connection_get_address(packet, event_addr); local_cid = l2cap_event_incoming_connection_get_local_cid(packet); - - connection = get_avrcp_connection_for_bd_addr(event_addr); - if (!connection){ - connection = avrcp_create_connection(event_addr); - connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED; - l2cap_accept_connection(local_cid); + connection = avrcp_create_connection(event_addr); + if (!connection) { + log_error("Failed to alloc connection structure"); + l2cap_decline_connection(local_cid); break; } + connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED; + connection->l2cap_signaling_cid = local_cid; + l2cap_accept_connection(local_cid); break; case L2CAP_EVENT_CHANNEL_OPENED: l2cap_event_channel_opened_get_address(packet, event_addr); - - if (l2cap_event_channel_opened_get_status(packet)){ - log_error("L2CAP connection to connection %s failed. status code 0x%02x", - bd_addr_to_str(event_addr), l2cap_event_channel_opened_get_status(packet)); - break; - } - psm = l2cap_event_channel_opened_get_psm(packet); - if (psm != BLUETOOTH_PROTOCOL_AVCTP){ - log_error("L2CAP_EVENT_CHANNEL_OPENED avrcp: unexpected PSM"); - return; - } - + connection = get_avrcp_connection_for_bd_addr(event_addr); - if (!connection) break; - - con_handle = l2cap_event_channel_opened_get_handle(packet); + status = l2cap_event_channel_opened_get_status(packet); local_cid = l2cap_event_channel_opened_get_local_cid(packet); - - if (connection->l2cap_signaling_cid != local_cid) { - log_info("Connection is not established, expected 0x%02X l2cap cid, received 0x%02X\n", connection->l2cap_signaling_cid, local_cid); - break; + + if (connection){ + // outgoing connection + if (l2cap_event_channel_opened_get_status(packet)){ + log_error("L2CAP connection to connection %s failed. status code 0x%02x", + bd_addr_to_str(event_addr), l2cap_event_channel_opened_get_status(packet)); + if (connection->state == AVCTP_CONNECTION_W4_L2CAP_CONNECTED){ + avrcp_emit_connection_established(avrcp_callback, status, event_addr, HCI_CON_HANDLE_INVALID, local_cid); + } + // free connection + btstack_memory_avrcp_connection_free(connection); + break; + } + } else { + // incoming connection + connection = avrcp_create_connection(event_addr); + if (!connection) { + log_error("Failed to alloc connection structure"); + l2cap_disconnect(local_cid, 0); // reason isn't used + break; + } } - // printf("L2CAP_EVENT_CHANNEL_OPENED: Channel successfully opened: %s, handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n", - // bd_addr_to_str(event_addr), con_handle, psm, local_cid, l2cap_event_channel_opened_get_remote_cid(packet)); - - if (connection->con_handle == 0) { - connection->l2cap_signaling_cid = local_cid; - connection->con_handle = con_handle; - connection->state = AVCTP_CONNECTION_OPENED; - avrcp_emit_connection_established(avrcp_callback, 0, event_addr, con_handle, local_cid); - break; - } + connection->l2cap_signaling_cid = local_cid; + connection->con_handle = l2cap_event_channel_opened_get_handle(packet); + connection->state = AVCTP_CONNECTION_OPENED; + avrcp_emit_connection_established(avrcp_callback, ERROR_CODE_SUCCESS, event_addr, connection->con_handle, local_cid); break; case L2CAP_EVENT_CAN_SEND_NOW: diff --git a/test/avrcp/avrcp_test.c b/test/avrcp/avrcp_test.c index 094c21554..b5076145d 100644 --- a/test/avrcp/avrcp_test.c +++ b/test/avrcp/avrcp_test.c @@ -100,6 +100,11 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe status = avrcp_subevent_connection_established_get_status(packet); avrcp_con_handle = avrcp_subevent_connection_established_get_con_handle(packet); avrcp_subevent_connection_established_get_bd_addr(packet, event_addr); + if (status != ERROR_CODE_SUCCESS){ + printf("AVRCP Connection failed: status 0x%02x\n", status); + avrcp_cid = 0; + break; + } printf("Channel successfully opened: %s, handle 0x%02x, local cid 0x%02x\n", bd_addr_to_str(event_addr), avrcp_con_handle, local_cid); // automatically enable notifications avrcp_enable_notification(avrcp_cid, AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED);