avdtp: streamlinw avdtp_handle_sdp_client_query_result, only register new query if connection is waiting

This commit is contained in:
Matthias Ringwald 2024-11-06 10:32:38 +01:00
parent 371c8f0ee5
commit 89f10e1d72
2 changed files with 46 additions and 63 deletions

View File

@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- SM: fix CTKD key distribution over BR/EDR
- SM: fix CTKD after BR/EDR Role Change
- A2DP: emit stream established if peer set-up configuration
- AVDTP: fix SDP Client registration bug that could block other SDP queries
- HIOS Client: emit disconnected event on HCI disconnect and free connection struct
- Scan Parameter Service Client: emit disconnected event on HCI disconnect and free connection struct
- PBAP Client: fix PBAP_SUBEVENT_OPERATION_COMPLETED with OBEX_DISCONNECTED for pbap_disconnect

View File

@ -734,78 +734,60 @@ static void avdtp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t c
log_error("SDP query, connection with 0x%02x cid not found", avdtp_sdp_query_context_avdtp_cid);
return;
}
uint8_t status = ERROR_CODE_SUCCESS;
switch (connection->state){
case AVDTP_SIGNALING_W4_SDP_QUERY_FOR_REMOTE_SINK_COMPLETE:
switch (hci_event_packet_get_type(packet)){
case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
avdtp_handle_sdp_client_query_attribute_value(connection, packet);
return;
case SDP_EVENT_QUERY_COMPLETE:
status = sdp_event_query_complete_get_status(packet);
if (status != ERROR_CODE_SUCCESS) break;
if (!connection->sink_supported || (connection->avdtp_l2cap_psm == 0)) {
status = SDP_SERVICE_NOT_FOUND;
break;
}
break;
default:
btstack_assert(false);
return;
}
switch (hci_event_packet_get_type(packet)){
case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
avdtp_handle_sdp_client_query_attribute_value(connection, packet);
return;
case SDP_EVENT_QUERY_COMPLETE:
status = sdp_event_query_complete_get_status(packet);
break;
case AVDTP_SIGNALING_W4_SDP_QUERY_FOR_REMOTE_SOURCE_COMPLETE:
switch (hci_event_packet_get_type(packet)){
case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
avdtp_handle_sdp_client_query_attribute_value(connection, packet);
return;
case SDP_EVENT_QUERY_COMPLETE:
status = sdp_event_query_complete_get_status(packet);
if (status != ERROR_CODE_SUCCESS) break;
if (!connection->source_supported || (connection->avdtp_l2cap_psm == 0)) {
status = SDP_SERVICE_NOT_FOUND;
break;
}
break;
default:
btstack_assert(false);
return;
}
break;
case AVDTP_SIGNALING_CONNECTION_OPENED:
switch (hci_event_packet_get_type(packet)){
case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
avdtp_handle_sdp_client_query_attribute_value(connection, packet);
return;
case SDP_EVENT_QUERY_COMPLETE:
// without suitable SDP Record, avdtp version v0.0 is assumed
status = sdp_event_query_complete_get_status(packet);
break;
default:
btstack_assert(false);
return;
}
break;
default:
// bail out, we must have had an incoming connection in the meantime; just trigger next sdp query on complete
if (hci_event_packet_get_type(packet) == SDP_EVENT_QUERY_COMPLETE){
(void) sdp_client_register_query_callback(&avdtp_handle_sdp_client_query_request);
}
btstack_assert(false);
return;
}
if (status == ERROR_CODE_SUCCESS){
avdtp_handle_sdp_query_succeeded(connection);
} else {
avdtp_handle_sdp_query_failed(connection, status);
// query completed with status, validate received information
bool handle_query_complete = true;
switch (connection->state){
case AVDTP_SIGNALING_W4_SDP_QUERY_FOR_REMOTE_SINK_COMPLETE:
if (status == ERROR_CODE_SUCCESS) {
if (!connection->sink_supported || (connection->avdtp_l2cap_psm == 0)) {
status = SDP_SERVICE_NOT_FOUND;
}
}
break;
case AVDTP_SIGNALING_W4_SDP_QUERY_FOR_REMOTE_SOURCE_COMPLETE:
if (status == ERROR_CODE_SUCCESS) {
if (!connection->source_supported || (connection->avdtp_l2cap_psm == 0)) {
status = SDP_SERVICE_NOT_FOUND;
}
}
break;
case AVDTP_SIGNALING_CONNECTION_OPENED:
// without suitable SDP Record, avdtp version v0.0 is assumed
break;
default:
// we must have had an incoming connection in the meantime -> bail out
// just trigger next sdp query on complete
handle_query_complete = false;
break;
}
if (handle_query_complete){
if (status == ERROR_CODE_SUCCESS){
avdtp_handle_sdp_query_succeeded(connection);
} else {
avdtp_handle_sdp_query_failed(connection, status);
}
}
// register the SDP Query request to check if there is another connection waiting for the query
// ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
(void) sdp_client_register_query_callback(&avdtp_handle_sdp_client_query_request);
if (avdtp_get_next_connection_ready_for_sdp_query() != NULL){
// ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
(void) sdp_client_register_query_callback(&avdtp_handle_sdp_client_query_request);
}
}
static avdtp_connection_t * avdtp_handle_incoming_connection(avdtp_connection_t * connection, bd_addr_t event_addr, hci_con_handle_t con_handle, uint16_t local_cid){