a2dp_sink: use general a2dp packet handler, configure sep for outgoing connections

This commit is contained in:
Matthias Ringwald 2022-03-15 16:34:05 +01:00
parent b776322ebe
commit 31683d475e

View File

@ -164,152 +164,10 @@ static void a2dp_sink_packet_handler_internal(uint8_t packet_type, uint16_t chan
UNUSED(channel);
UNUSED(size);
uint16_t cid;
avdtp_connection_t * connection;
uint8_t status;
uint8_t local_seid;
uint8_t signal_identifier;
bool reconfigure;
uint8_t subevent_id;
if (packet_type != HCI_EVENT_PACKET) return;
if (hci_event_packet_get_type(packet) != HCI_EVENT_AVDTP_META) return;
switch (packet[2]){
case AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
if (a2dp_sink_stream_endpoint_configured) return;
cid = avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet);
connection = avdtp_get_connection_for_avdtp_cid(cid);
btstack_assert(connection != NULL);
status = avdtp_subevent_signaling_connection_established_get_status(packet);
if (status != ERROR_CODE_SUCCESS){
// notify about connection error only if we're initiator
if (connection->a2dp_sink_config_process.outgoing_active) {
log_info("A2DP sink signaling connection failed status %d", status);
connection->a2dp_sink_config_process.outgoing_active = false;
a2dp_replace_subevent_id_and_emit_sink(packet, size,
A2DP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED);
}
}
a2dp_replace_subevent_id_and_emit_sink(packet, size,
A2DP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED);
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_SBC_CONFIGURATION:
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 (a2dp_sink_stream_endpoint_configured != reconfigure) break;
a2dp_sink_stream_endpoint_configured = true;
a2dp_sink_cid = avdtp_subevent_signaling_media_codec_other_capability_get_avdtp_cid(packet);
subevent_id = a2dp_subevent_id_for_avdtp_subevent_id(packet[2]);
a2dp_replace_subevent_id_and_emit_sink(packet, size, subevent_id);
break;
case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED:
if (a2dp_sink_stream_endpoint_configured == false) break;
if (a2dp_sink_cid != avdtp_subevent_streaming_connection_established_get_avdtp_cid(packet)) break;
connection = avdtp_get_connection_for_avdtp_cid(a2dp_sink_cid);
btstack_assert(connection != NULL);
// about to notify client
connection->a2dp_sink_config_process.outgoing_active = false;
status = avdtp_subevent_streaming_connection_established_get_status(packet);
if (status != ERROR_CODE_SUCCESS){
log_info("A2DP sink streaming connection could not be established, avdtp_cid 0x%02x, status 0x%02x ---", a2dp_sink_cid, status);
a2dp_replace_subevent_id_and_emit_sink(packet, size,
A2DP_SUBEVENT_STREAM_ESTABLISHED);
break;
}
log_info("A2DP streaming connection established --- avdtp_cid 0x%02x, local seid %d, remote seid %d", a2dp_sink_cid,
avdtp_subevent_streaming_connection_established_get_local_seid(packet),
avdtp_subevent_streaming_connection_established_get_remote_seid(packet));
a2dp_replace_subevent_id_and_emit_sink(packet, size,
A2DP_SUBEVENT_STREAM_ESTABLISHED);
break;
case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
if (a2dp_sink_stream_endpoint_configured == false) break;
if (a2dp_sink_cid != avdtp_subevent_signaling_accept_get_avdtp_cid(packet)) break;
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
local_seid = avdtp_subevent_signaling_accept_get_local_seid(packet);
switch (signal_identifier){
case AVDTP_SI_START:
a2dp_emit_sink_stream_event(a2dp_sink_cid, local_seid, A2DP_SUBEVENT_STREAM_STARTED);
break;
case AVDTP_SI_SUSPEND:
a2dp_emit_sink_stream_event(a2dp_sink_cid, local_seid, A2DP_SUBEVENT_STREAM_SUSPENDED);
break;
case AVDTP_SI_ABORT:
case AVDTP_SI_CLOSE:
a2dp_emit_sink_stream_event(a2dp_sink_cid, local_seid, A2DP_SUBEVENT_STREAM_STOPPED);
break;
#ifdef ENABLE_AVDTP_ACCEPTOR_EXPLICIT_START_STREAM_CONFIRMATION
case AVDTP_SI_ACCEPT_START:
a2dp_emit_sink_stream_event(a2dp_sink_cid, local_seid, A2DP_SUBEVENT_START_STREAM_REQUESTED);
break;
#endif
default:
break;
}
break;
case AVDTP_SUBEVENT_SIGNALING_REJECT:
if (a2dp_sink_stream_endpoint_configured == false) break;
if (a2dp_sink_cid != avdtp_subevent_signaling_reject_get_avdtp_cid(packet)) break;
a2dp_replace_subevent_id_and_emit_sink(packet, size,
A2DP_SUBEVENT_COMMAND_REJECTED);
break;
case AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT:
if (a2dp_sink_stream_endpoint_configured == false) break;
if (a2dp_sink_cid != avdtp_subevent_signaling_general_reject_get_avdtp_cid(packet)) break;
a2dp_replace_subevent_id_and_emit_sink(packet, size,
A2DP_SUBEVENT_COMMAND_REJECTED);
break;
case AVDTP_SUBEVENT_STREAMING_CONNECTION_RELEASED:
if (a2dp_sink_stream_endpoint_configured == false) break;
if (a2dp_sink_cid != avdtp_subevent_streaming_connection_released_get_avdtp_cid(packet)) break;
a2dp_sink_stream_endpoint_configured = false;
a2dp_replace_subevent_id_and_emit_sink(packet, size,
A2DP_SUBEVENT_STREAM_RELEASED);
break;
case AVDTP_SUBEVENT_SIGNALING_CONNECTION_RELEASED:
cid = avdtp_subevent_signaling_connection_released_get_avdtp_cid(packet);
connection = avdtp_get_connection_for_avdtp_cid(cid);
btstack_assert(connection != NULL);
connection->a2dp_sink_config_process.outgoing_active = false;
if (a2dp_sink_cid != cid) break;
a2dp_sink_stream_endpoint_configured = false;
a2dp_replace_subevent_id_and_emit_sink(packet, size,
A2DP_SUBEVENT_SIGNALING_CONNECTION_RELEASED);
break;
default:
break;
}
a2dp_config_process_avdtp_event_handler(AVDTP_ROLE_SINK, packet, size);
}
static uint8_t a2dp_sink_media_config_validator_callback(const avdtp_stream_endpoint_t * stream_endpoint, const uint8_t * event, uint16_t size){