avdtp: rework incoming l2cap connection during connection establishment

This commit is contained in:
Matthias Ringwald 2018-11-08 15:17:38 +01:00
parent f43b5c9071
commit 0d4a198ec7

View File

@ -454,6 +454,10 @@ static void avdtp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t c
break;
case SDP_EVENT_QUERY_COMPLETE:
if (connection->state != AVDTP_SIGNALING_W4_SDP_QUERY_COMPLETE){
// bail out, we must have had an incoming connection in the meantime;
break;
}
status = sdp_event_query_complete_get_status(packet);
if (status != ERROR_CODE_SUCCESS){
avdtp_signaling_emit_connection_established(sdp_query_context->avdtp_callback, sdp_query_context->avdtp_cid, connection->remote_addr, status);
@ -488,6 +492,7 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
uint16_t psm;
uint16_t local_cid;
uint8_t status;
int accept_signaling_connection;
avdtp_stream_endpoint_t * stream_endpoint = NULL;
avdtp_connection_t * connection = NULL;
btstack_linked_list_t * avdtp_connections = &context->connections;
@ -546,22 +551,56 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
local_cid = l2cap_event_incoming_connection_get_local_cid(packet);
connection = avdtp_connection_for_bd_addr(event_addr, context);
log_info("L2CAP_EVENT_INCOMING_CONNECTION, local cid 0x%02x ", local_cid);
if (connection){
log_info("Connection state %d", connection->state);
}
if (!connection || connection->state == AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED){
if (!connection){
// create connection struct for regular inconming connection request
connection = avdtp_create_connection(event_addr, context);
if (!connection){
log_error("Could not create connection, reject");
l2cap_decline_connection(local_cid);
break;
}
connection->state = AVDTP_SIGNALING_CONNECTION_IDLE;
}
// connection exists, check states
log_info("Connection state %d", connection->state);
switch (connection->state){
case AVDTP_SIGNALING_CONNECTION_IDLE:
// regular incoming connection
accept_signaling_connection = 1;
break;
case AVDTP_SIGNALING_W4_SDP_QUERY_COMPLETE:
// incoming connection during sdp query, just accept it
accept_signaling_connection = 1;
break;
case AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED:
log_info("Reject incoming connection after creating outgoing");
l2cap_decline_connection(local_cid);
return;
case AVDTP_SIGNALING_CONNECTION_OPENED:
// handled below
accept_signaling_connection = 0;
break;
case AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED:
log_info("Reject incoming connection during disconnect");
l2cap_decline_connection(local_cid);
return;
}
if (accept_signaling_connection){
connection->is_initiator = 0;
log_info("L2CAP_EVENT_INCOMING_CONNECTION: role is_initiator %d", connection->is_initiator);
connection->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED;
log_info("L2CAP_EVENT_INCOMING_CONNECTION: role is_initiator %d", connection->is_initiator);
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;
}
// now, we're only dealing with media connections
stream_endpoint = avdtp_stream_endpoint_for_seid(connection->local_seid, context);
if (!stream_endpoint) {
log_info("L2CAP_EVENT_INCOMING_CONNECTION no streamendpoint found for seid %d", connection->local_seid);
l2cap_decline_connection(local_cid);
break;
}