avdtp: allow call to avdtp_disconnect before connection was established

This commit is contained in:
Matthias Ringwald 2024-04-02 12:03:23 +02:00
parent 041b66c55d
commit 95fdf9791c
2 changed files with 27 additions and 12 deletions

View File

@ -22,6 +22,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- HFP AG: send OK after SLC for HF that does not support 3-way-calling or HF Indicators - HFP AG: send OK after SLC for HF that does not support 3-way-calling or HF Indicators
- HSP HS: use EV3 and 2EV3 packets for 7.5 ms voice interval - HSP HS: use EV3 and 2EV3 packets for 7.5 ms voice interval
- AVDTP: use round robin for outgoing connections - AVDTP: use round robin for outgoing connections
- AVDTP: allow call to avdtp_disconnect before connection was established
- A2DP: allow call to avdtp_disconnect before connection was established
- AVRCP: use round robin for outgoing connections - AVRCP: use round robin for outgoing connections
- GOEP Client: use round robin for outgoing connections - GOEP Client: use round robin for outgoing connections
- HID Host: use round robin for outgoing connections - HID Host: use round robin for outgoing connections

View File

@ -1084,15 +1084,9 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
} }
} }
uint8_t avdtp_disconnect(uint16_t avdtp_cid){ void avdtp_disconenct_streamendpoints(const avdtp_connection_t *connection) {
avdtp_connection_t * connection = avdtp_get_connection_for_avdtp_cid(avdtp_cid);
if (!connection) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
if (connection->state == AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED) return ERROR_CODE_SUCCESS;
btstack_linked_list_iterator_t it; btstack_linked_list_iterator_t it;
btstack_linked_list_iterator_init(&it, avdtp_get_stream_endpoints()); btstack_linked_list_iterator_init(&it, avdtp_get_stream_endpoints());
while (btstack_linked_list_iterator_has_next(&it)){ while (btstack_linked_list_iterator_has_next(&it)){
avdtp_stream_endpoint_t * stream_endpoint = (avdtp_stream_endpoint_t *)btstack_linked_list_iterator_next(&it); avdtp_stream_endpoint_t * stream_endpoint = (avdtp_stream_endpoint_t *)btstack_linked_list_iterator_next(&it);
if (stream_endpoint->connection != connection) continue; if (stream_endpoint->connection != connection) continue;
@ -1107,9 +1101,28 @@ uint8_t avdtp_disconnect(uint16_t avdtp_cid){
break; break;
} }
} }
}
uint8_t avdtp_disconnect(uint16_t avdtp_cid){
avdtp_connection_t * connection = avdtp_get_connection_for_avdtp_cid(avdtp_cid);
if (!connection) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
switch (connection->state){
case AVDTP_SIGNALING_CONNECTION_OPENED:
avdtp_disconenct_streamendpoints(connection);
connection->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED; connection->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED;
l2cap_disconnect(connection->l2cap_signaling_cid); l2cap_disconnect(connection->l2cap_signaling_cid);
break;
case AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED:
// stream endpoints closed, wait for disconnected
break;
default:
// connection has not been reported as established yet, report open failed
avdtp_signaling_emit_connection_established(connection->avdtp_cid, connection->remote_addr,
connection->con_handle, ERROR_CODE_UNSPECIFIED_ERROR);
avdtp_finalize_connection(connection);
break;
}
return ERROR_CODE_SUCCESS; return ERROR_CODE_SUCCESS;
} }