diff --git a/example/a2dp_sink_demo.c b/example/a2dp_sink_demo.c index 9d959f885..1f6fdf0c8 100644 --- a/example/a2dp_sink_demo.c +++ b/example/a2dp_sink_demo.c @@ -744,7 +744,13 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe a2dp_subevent_stream_established_get_bd_addr(packet, address); status = a2dp_subevent_stream_established_get_status(packet); cid = a2dp_subevent_stream_established_get_a2dp_cid(packet); - if (cid != a2dp_cid) break; + printf("A2DP_SUBEVENT_STREAM_ESTABLISHED %d, %d \n", cid, a2dp_cid); + if (!a2dp_cid){ + // incoming connection + a2dp_cid = cid; + } else if (cid != a2dp_cid) { + break; + } if (status){ app_state = AVDTP_APPLICATION_IDLE; printf(" -- a2dp sink demo: streaming connection failed, status 0x%02x\n", status); @@ -855,8 +861,8 @@ static void stdin_process(char cmd){ uint8_t status = ERROR_CODE_SUCCESS; switch (cmd){ case 'b': - printf(" - Create AVDTP connection to addr %s, and local seid %d.\n", bd_addr_to_str(device_addr), local_seid); status = a2dp_sink_establish_stream(device_addr, local_seid, &a2dp_cid); + printf(" - Create AVDTP connection to addr %s, and local seid %d, expected cid 0x%02x.\n", bd_addr_to_str(device_addr), local_seid, a2dp_cid); break; case 'B': printf(" - AVDTP disconnect from addr %s.\n", bd_addr_to_str(device_addr)); diff --git a/src/classic/a2dp_sink.c b/src/classic/a2dp_sink.c index 5f9e7a80a..308ce08a4 100644 --- a/src/classic/a2dp_sink.c +++ b/src/classic/a2dp_sink.c @@ -291,7 +291,8 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe cid = avdtp_subevent_streaming_connection_established_get_avdtp_cid(packet); loc_seid = avdtp_subevent_streaming_connection_established_get_local_seid(packet); rem_seid = avdtp_subevent_streaming_connection_established_get_remote_seid(packet); - + log_info("AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED, avdtp cid 0x%02x, status %d ---", cid, status); + if (status != 0){ a2dp_streaming_emit_connection_established(a2dp_sink_context.a2dp_callback, cid, address, loc_seid, rem_seid, status); break; diff --git a/src/classic/avdtp.c b/src/classic/avdtp.c index beca921b3..6a86b4a3b 100644 --- a/src/classic/avdtp.c +++ b/src/classic/avdtp.c @@ -132,7 +132,7 @@ uint8_t avdtp_connect(bd_addr_t remote, avdtp_sep_type_t query_role, avdtp_conte avdtp_streaming_emit_connection_established(avdtp_context->avdtp_callback, connection->avdtp_cid, remote, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), 0); break; } - avdtp_signaling_emit_connection_established(avdtp_context->avdtp_callback, avdtp_context->avdtp_cid, connection->remote_addr, ERROR_CODE_SUCCESS); + avdtp_signaling_emit_connection_established(avdtp_context->avdtp_callback, connection->avdtp_cid, connection->remote_addr, ERROR_CODE_SUCCESS); break; } default: @@ -508,7 +508,7 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet if (!connection || connection->state == AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED){ connection = avdtp_create_connection(event_addr, context); connection->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED; - log_info("L2CAP_EVENT_INCOMING_CONNECTION, connection %p, state connection %d", connection, connection->state); + log_info("L2CAP_EVENT_INCOMING_CONNECTION, connection %p, state connection %d, avdtp cid 0x%02x", connection, connection->state, connection->avdtp_cid); l2cap_accept_connection(local_cid); break; } @@ -562,7 +562,7 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet connection->l2cap_signaling_cid = local_cid; connection->local_seid = 0; connection->state = AVDTP_SIGNALING_CONNECTION_OPENED; - log_info(" -> AVDTP_SIGNALING_CONNECTION_OPENED, connection %p, avdtp_cid 0x%02x", connection, local_cid); + log_info(" -> AVDTP_SIGNALING_CONNECTION_OPENED, connection %p, l2cap_signaling_cid 0x%02x, avdtp_cid 0x%02x", connection, local_cid, connection->avdtp_cid); avdtp_signaling_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, event_addr, 0); break; } @@ -576,14 +576,14 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet if (stream_endpoint->l2cap_media_cid == 0){ status = l2cap_event_channel_opened_get_status(packet); if (status){ - log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED failed with status %d, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d", status, context->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint)); + log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED failed with status %d, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d", status, connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint)); stream_endpoint->state = AVDTP_STREAM_ENDPOINT_IDLE; - avdtp_streaming_emit_connection_established(context->avdtp_callback, context->avdtp_cid, event_addr, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), status); + avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, event_addr, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), status); break; } if (stream_endpoint->state != AVDTP_STREAM_ENDPOINT_W4_L2CAP_FOR_MEDIA_CONNECTED){ log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED failed - stream endpoint in wrong state %d, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d", stream_endpoint->state, connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint)); - avdtp_streaming_emit_connection_established(context->avdtp_callback, context->avdtp_cid, event_addr, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), AVDTP_STREAM_ENDPOINT_IN_WRONG_STATE); + avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, event_addr, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), AVDTP_STREAM_ENDPOINT_IN_WRONG_STATE); break; } @@ -592,8 +592,8 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet stream_endpoint->l2cap_media_cid = l2cap_event_channel_opened_get_local_cid(packet); stream_endpoint->media_con_handle = l2cap_event_channel_opened_get_handle(packet); - log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d", context->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint)); - avdtp_streaming_emit_connection_established(context->avdtp_callback, context->avdtp_cid, event_addr, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), 0); + log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d", connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint)); + avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, event_addr, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), 0); return; } break; @@ -603,27 +603,13 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet connection = avdtp_connection_for_l2cap_signaling_cid(local_cid, context); stream_endpoint = avdtp_stream_endpoint_for_l2cap_cid(local_cid, context); log_info("received L2CAP_EVENT_CHANNEL_CLOSED, cid 0x%2x, connection %p, stream_endpoint %p", local_cid, connection, stream_endpoint); - - if (connection){ - avdtp_signaling_emit_connection_released(context->avdtp_callback, connection->avdtp_cid); - btstack_linked_list_remove(avdtp_connections, (btstack_linked_item_t*) connection); - btstack_linked_list_iterator_t it; - btstack_linked_list_iterator_init(&it, stream_endpoints); - while (btstack_linked_list_iterator_has_next(&it)){ - avdtp_stream_endpoint_t * _stream_endpoint = (avdtp_stream_endpoint_t *)btstack_linked_list_iterator_next(&it); - - if (_stream_endpoint->connection == connection){ - avdtp_initialize_stream_endpoint(_stream_endpoint); - } - } - btstack_memory_avdtp_connection_free(connection); - break; - } if (stream_endpoint){ if (stream_endpoint->l2cap_media_cid == local_cid){ connection = stream_endpoint->connection; - avdtp_streaming_emit_connection_released(context->avdtp_callback, context->avdtp_cid, avdtp_local_seid(stream_endpoint)); + if (connection) { + avdtp_streaming_emit_connection_released(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint)); + } stream_endpoint->l2cap_media_cid = 0; stream_endpoint->state = AVDTP_STREAM_ENDPOINT_IDLE; stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE; @@ -646,6 +632,23 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet break; } } + + if (connection){ + avdtp_signaling_emit_connection_released(context->avdtp_callback, connection->avdtp_cid); + btstack_linked_list_remove(avdtp_connections, (btstack_linked_item_t*) connection); + btstack_linked_list_iterator_t it; + btstack_linked_list_iterator_init(&it, stream_endpoints); + while (btstack_linked_list_iterator_has_next(&it)){ + avdtp_stream_endpoint_t * _stream_endpoint = (avdtp_stream_endpoint_t *)btstack_linked_list_iterator_next(&it); + + if (_stream_endpoint->connection == connection){ + avdtp_initialize_stream_endpoint(_stream_endpoint); + } + } + btstack_memory_avdtp_connection_free(connection); + break; + } + break; case HCI_EVENT_DISCONNECTION_COMPLETE: