a2dp sink: fix avdtp cid propagation

This commit is contained in:
Milanka Ringwald 2017-10-17 12:50:33 +02:00
parent 42133918ad
commit 596b7fdcf4
3 changed files with 38 additions and 28 deletions

View File

@ -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));

View File

@ -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;

View File

@ -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: