From 6c5b303c0f17763e7c402388cd6a9a43529ba539 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 15 Jan 2021 14:56:37 +0100 Subject: [PATCH] avdtp: emit event for reconfigure with reconfigure field set to 1 --- src/classic/a2dp_sink.c | 36 ++++++++++++++++++++++++---------- src/classic/avdtp_acceptor.c | 5 +++-- src/classic/avdtp_initiator.c | 35 ++++++++++++--------------------- src/classic/avdtp_util.c | 37 ++++++++++++----------------------- src/classic/avdtp_util.h | 11 +++-------- 5 files changed, 57 insertions(+), 67 deletions(-) diff --git a/src/classic/a2dp_sink.c b/src/classic/a2dp_sink.c index 3243e8555..40ac39663 100644 --- a/src/classic/a2dp_sink.c +++ b/src/classic/a2dp_sink.c @@ -207,6 +207,7 @@ static void a2dp_sink_packet_handler_internal(uint8_t packet_type, uint16_t chan uint8_t status; uint8_t local_seid; uint8_t signal_identifier; + bool reconfigure; if (packet_type != HCI_EVENT_PACKET) return; if (hci_event_packet_get_type(packet) != HCI_EVENT_AVDTP_META) return; @@ -214,7 +215,7 @@ static void a2dp_sink_packet_handler_internal(uint8_t packet_type, uint16_t chan switch (packet[2]){ case AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED: if (stream_endpoint_configured) return; - + status = avdtp_subevent_signaling_connection_established_get_status(packet); if (status != ERROR_CODE_SUCCESS){ // only care for outgoing connections @@ -229,18 +230,33 @@ static void a2dp_sink_packet_handler_internal(uint8_t packet_type, uint16_t chan log_info("A2DP sink signaling connection established avdtp_cid 0x%02x", avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet)); break; - case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION: - if (stream_endpoint_configured) break; - stream_endpoint_configured = true; - a2dp_sink_cid = avdtp_subevent_signaling_media_codec_other_capability_get_avdtp_cid(packet); - a2dp_replace_subevent_id_and_emit_cmd(a2dp_sink_packet_handler_user, packet, size, A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION); - break; - case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION: - if (stream_endpoint_configured) break; + case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_MPEG_AUDIO_CONFIGURATION: + case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_MPEG_AAC_CONFIGURATION: + case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_ATRAC_CONFIGURATION: + case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION: + reconfigure = avdtp_subevent_signaling_media_codec_other_configuration_get_reconfigure(packet) != 0; + // accept configure if not configured and reconfigure if already configured + if (stream_endpoint_configured != reconfigure) break; stream_endpoint_configured = true; a2dp_sink_cid = avdtp_subevent_signaling_media_codec_other_capability_get_avdtp_cid(packet); - a2dp_replace_subevent_id_and_emit_cmd(a2dp_sink_packet_handler_user, packet, size, A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION); + switch (packet[2]){ + case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION: + a2dp_replace_subevent_id_and_emit_cmd(a2dp_sink_packet_handler_user, packet, size, A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION); + break; + case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_MPEG_AUDIO_CONFIGURATION: + a2dp_replace_subevent_id_and_emit_cmd(a2dp_sink_packet_handler_user, packet, size, A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_MPEG_AUDIO_CONFIGURATION); + break; + case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_MPEG_AAC_CONFIGURATION: + a2dp_replace_subevent_id_and_emit_cmd(a2dp_sink_packet_handler_user, packet, size, A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_MPEG_AAC_CONFIGURATION); + break; + case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_ATRAC_CONFIGURATION: + a2dp_replace_subevent_id_and_emit_cmd(a2dp_sink_packet_handler_user, packet, size, A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_ATRAC_CONFIGURATION); + break; + case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION: + a2dp_replace_subevent_id_and_emit_cmd(a2dp_sink_packet_handler_user, packet, size, A2DP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION); + break; + } break; case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED: diff --git a/src/classic/avdtp_acceptor.c b/src/classic/avdtp_acceptor.c index 077d11432..639f7a3c1 100644 --- a/src/classic/avdtp_acceptor.c +++ b/src/classic/avdtp_acceptor.c @@ -137,7 +137,8 @@ avdtp_acceptor_handle_configuration_command(avdtp_connection_t *connection, int if (stream_endpoint->media_codec_configuration_len == sep.configuration.media_codec.media_codec_information_len){ (void) memcpy(stream_endpoint->media_codec_configuration_info, sep.configuration.media_codec.media_codec_information, stream_endpoint->media_codec_configuration_len); } - avdtp_signaling_emit_configuration(stream_endpoint, connection->avdtp_cid, &sep.configuration, sep.configured_service_categories); + avdtp_signaling_emit_configuration(stream_endpoint, connection->avdtp_cid, 0, &sep.configuration, + sep.configured_service_categories); } avdtp_signaling_emit_accept(connection->avdtp_cid, avdtp_local_seid(stream_endpoint), @@ -325,7 +326,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t *connection, uint8_t if (stream_endpoint->media_codec_configuration_len == sep.configuration.media_codec.media_codec_information_len){ (void) memcpy(stream_endpoint->media_codec_configuration_info, sep.configuration.media_codec.media_codec_information, stream_endpoint->media_codec_configuration_len); } - avdtp_signaling_emit_configuration(stream_endpoint, connection->avdtp_cid, &sep.configuration, sep.configured_service_categories); + avdtp_signaling_emit_configuration(stream_endpoint, connection->avdtp_cid, 1, &sep.configuration, sep.configured_service_categories); } break; } diff --git a/src/classic/avdtp_initiator.c b/src/classic/avdtp_initiator.c index fc440cc24..bc875d05d 100644 --- a/src/classic/avdtp_initiator.c +++ b/src/classic/avdtp_initiator.c @@ -154,6 +154,8 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t *connection, uint8_t btstack_assert(stream_endpoint->remote_configuration.media_codec.media_codec_information_len == stream_endpoint->media_codec_configuration_len); (void)memcpy(stream_endpoint->media_codec_configuration_info, stream_endpoint->remote_configuration.media_codec.media_codec_information, stream_endpoint->media_codec_configuration_len); } + avdtp_signaling_emit_configuration(stream_endpoint, connection->avdtp_cid, 1, + &sep.configuration, (1 << AVDTP_MEDIA_CODEC)); break; case AVDTP_SI_SET_CONFIGURATION: @@ -175,29 +177,18 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t *connection, uint8_t log_info("configured remote seid %d", stream_endpoint->remote_sep.seid); - // copy media codec configuration if configured if ((stream_endpoint->remote_configuration_bitmap & (1 << AVDTP_MEDIA_CODEC)) != 0) { - btstack_assert(stream_endpoint->remote_configuration.media_codec.media_codec_information_len == - stream_endpoint->media_codec_configuration_len); - (void) memcpy(stream_endpoint->media_codec_configuration_info, - stream_endpoint->remote_configuration.media_codec.media_codec_information, - stream_endpoint->media_codec_configuration_len); - - switch (stream_endpoint->media_codec_type) { - case AVDTP_CODEC_SBC: - avdtp_signaling_emit_media_codec_sbc_configuration( - stream_endpoint, - connection->avdtp_cid, - stream_endpoint->media_type, - stream_endpoint->media_codec_configuration_info); - break; - default: - // TODO: we don't have codec info to emit config - avdtp_signaling_emit_media_codec_other_configuration(stream_endpoint, - connection->avdtp_cid, - &sep.configuration.media_codec); - break; - } + // copy media codec configuration for known codecs + if (stream_endpoint->media_codec_type != AVDTP_CODEC_NON_A2DP) { + btstack_assert( + stream_endpoint->remote_configuration.media_codec.media_codec_information_len == + stream_endpoint->media_codec_configuration_len); + (void) memcpy(stream_endpoint->media_codec_configuration_info, + stream_endpoint->remote_configuration.media_codec.media_codec_information, + stream_endpoint->media_codec_configuration_len); + } + avdtp_signaling_emit_configuration(stream_endpoint, connection->avdtp_cid, 0, + &sep.configuration, (1 << AVDTP_MEDIA_CODEC)); } break; diff --git a/src/classic/avdtp_util.c b/src/classic/avdtp_util.c index b778412d6..4509d0ce1 100644 --- a/src/classic/avdtp_util.c +++ b/src/classic/avdtp_util.c @@ -1210,7 +1210,7 @@ avdtp_signaling_emit_media_codec_atrac_configuration(avdtp_stream_endpoint_t *st (*packet_handler)(HCI_EVENT_PACKET, 0, event, pos); } -static void avdtp_signaling_emit_media_codec_other(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, +static void avdtp_signaling_emit_media_codec_other_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, uint8_t reconfigure, adtvp_media_codec_capabilities_t *media_codec) { btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); @@ -1253,50 +1253,37 @@ void avdtp_signaling_emit_delay(uint16_t avdtp_cid, uint8_t local_seid, uint16_t avdtp_emit_source(event, sizeof(event)); } -void avdtp_signaling_emit_media_codec_sbc_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, - avdtp_media_type_t media_type, - const uint8_t *media_codec_information) { - avdtp_signaling_emit_media_codec_sbc(stream_endpoint, avdtp_cid, 0, media_type, - media_codec_information); -} - -void avdtp_signaling_emit_media_codec_other_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, - adtvp_media_codec_capabilities_t * media_codec) { - avdtp_signaling_emit_media_codec_other(stream_endpoint, avdtp_cid, 0, media_codec); -} - -void avdtp_signaling_emit_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, - avdtp_capabilities_t *configuration, uint16_t configured_service_categories) { +void avdtp_signaling_emit_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, uint8_t reconfigure, + avdtp_capabilities_t *configuration, uint16_t configured_service_categories) { if (get_bit16(configured_service_categories, AVDTP_MEDIA_CODEC)){ switch (configuration->media_codec.media_codec_type){ - case AVDTP_CODEC_SBC: - avdtp_signaling_emit_media_codec_sbc_configuration( - stream_endpoint, avdtp_cid, - configuration->media_codec.media_type, - configuration->media_codec.media_codec_information); + case AVDTP_CODEC_SBC: { + avdtp_signaling_emit_media_codec_sbc(stream_endpoint, avdtp_cid, reconfigure, + configuration->media_codec.media_type, + configuration->media_codec.media_codec_information); + } break; case AVDTP_CODEC_MPEG_1_2_AUDIO: avdtp_signaling_emit_media_codec_mpeg_audio_configuration( - stream_endpoint, avdtp_cid, 0, + stream_endpoint, avdtp_cid, reconfigure, configuration->media_codec.media_type, configuration->media_codec.media_codec_information); break; case AVDTP_CODEC_MPEG_2_4_AAC: avdtp_signaling_emit_media_codec_mpeg_aac_configuration( - stream_endpoint, avdtp_cid, 0, + stream_endpoint, avdtp_cid, reconfigure, configuration->media_codec.media_type, configuration->media_codec.media_codec_information); break; case AVDTP_CODEC_ATRAC_FAMILY: avdtp_signaling_emit_media_codec_atrac_configuration( - stream_endpoint, avdtp_cid, 0, + stream_endpoint, avdtp_cid, reconfigure, configuration->media_codec.media_type, configuration->media_codec.media_codec_information); break; default: - avdtp_signaling_emit_media_codec_other_configuration(stream_endpoint, avdtp_cid, - &configuration->media_codec); + avdtp_signaling_emit_media_codec_other_configuration(stream_endpoint, avdtp_cid, reconfigure, &configuration->media_codec); break; } } diff --git a/src/classic/avdtp_util.h b/src/classic/avdtp_util.h index 2ac98ccc9..0be9a89ea 100644 --- a/src/classic/avdtp_util.h +++ b/src/classic/avdtp_util.h @@ -92,14 +92,9 @@ void avdtp_signaling_emit_capabilities(uint16_t avdtp_cid, uint8_t remote_seid, void avdtp_signaling_emit_delay(uint16_t avdtp_cid, uint8_t local_seid, uint16_t delay); -void avdtp_signaling_emit_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, - avdtp_capabilities_t *configuration, uint16_t configured_service_categories); - -void avdtp_signaling_emit_media_codec_sbc_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, - avdtp_media_type_t media_type, - const uint8_t *media_codec_information); -void avdtp_signaling_emit_media_codec_other_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, - adtvp_media_codec_capabilities_t * media_codec); +void +avdtp_signaling_emit_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, uint8_t reconfigure, + avdtp_capabilities_t *configuration, uint16_t configured_service_categories); void avdtp_streaming_emit_connection_established(avdtp_stream_endpoint_t *stream_endpoint, uint8_t status);