From 4b7d40bbedae1bfcf7f8a6bbb50a862490856d5f Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Wed, 19 Aug 2020 11:49:12 +0200 Subject: [PATCH] avdtp: collect all emit functions in avdtp_util --- src/classic/avdtp.c | 194 +--------------------- src/classic/avdtp.h | 5 +- src/classic/avdtp_acceptor.c | 6 +- src/classic/avdtp_initiator.c | 6 +- src/classic/avdtp_util.c | 300 ++++++++++++++++++++++++++++------ src/classic/avdtp_util.h | 11 +- 6 files changed, 269 insertions(+), 253 deletions(-) diff --git a/src/classic/avdtp.c b/src/classic/avdtp.c index dfeee7d0e..70fe810d4 100644 --- a/src/classic/avdtp.c +++ b/src/classic/avdtp.c @@ -89,200 +89,12 @@ void avdtp_emit_sink_and_source(uint8_t * packet, uint16_t size){ } } -static void avdtp_streaming_emit_connection_established(avdtp_stream_endpoint_t *stream_endpoint, uint8_t status) { - uint8_t event[14]; - int pos = 0; - event[pos++] = HCI_EVENT_AVDTP_META; - event[pos++] = sizeof(event) - 2; - event[pos++] = AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED; - little_endian_store_16(event, pos, stream_endpoint->connection->avdtp_cid); - pos += 2; - reverse_bd_addr(stream_endpoint->connection->remote_addr, &event[pos]); - pos += 6; - event[pos++] = avdtp_local_seid(stream_endpoint); - event[pos++] = avdtp_remote_seid(stream_endpoint); - event[pos++] = status; - - btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); - (*packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event)); -} - -static void avdtp_streaming_emit_connection_released(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, uint8_t local_seid) { - uint8_t event[6]; - int pos = 0; - event[pos++] = HCI_EVENT_AVDTP_META; - event[pos++] = sizeof(event) - 2; - event[pos++] = AVDTP_SUBEVENT_STREAMING_CONNECTION_RELEASED; - little_endian_store_16(event, pos, avdtp_cid); - pos += 2; - event[pos++] = local_seid; - - btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); - (*packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event)); -} - -void avdtp_streaming_emit_can_send_media_packet_now(avdtp_stream_endpoint_t *stream_endpoint, uint16_t sequence_number) { - uint8_t event[8]; - int pos = 0; - event[pos++] = HCI_EVENT_AVDTP_META; - event[pos++] = sizeof(event) - 2; - event[pos++] = AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW; - little_endian_store_16(event, pos, stream_endpoint->connection->avdtp_cid); - pos += 2; - event[pos++] = avdtp_local_seid(stream_endpoint); - little_endian_store_16(event, pos, sequence_number); - pos += 2; - - btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); - (*packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event)); -} - - -void avdtp_signaling_emit_delay(uint16_t avdtp_cid, uint8_t local_seid, uint16_t delay) { - uint8_t event[8]; - int pos = 0; - event[pos++] = HCI_EVENT_AVDTP_META; - event[pos++] = sizeof(event) - 2; - event[pos++] = AVDTP_SUBEVENT_SIGNALING_DELAY_REPORT; - little_endian_store_16(event, pos, avdtp_cid); - pos += 2; - event[pos++] = local_seid; - little_endian_store_16(event, pos, delay); - pos += 2; - (*avdtp_source_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); -} - -void avdtp_emit_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, - avdtp_capabilities_t *configuration, uint16_t configured_service_categories) { - - uint8_t local_seid = avdtp_local_seid(stream_endpoint); - uint8_t remote_seid = avdtp_remote_seid(stream_endpoint); - - 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); - break; - default: - avdtp_signaling_emit_media_codec_other_configuration(stream_endpoint, avdtp_cid, - local_seid, remote_seid, - configuration->media_codec); - break; - } +void avdtp_emit_source(uint8_t * packet, uint16_t size){ + if (avdtp_source_callback != NULL){ + (*avdtp_source_callback)(HCI_EVENT_PACKET, 0, packet, size); } } -static inline void -avdtp_signaling_emit_media_codec_sbc(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, - avdtp_media_type_t media_type, const uint8_t *media_codec_information, - uint8_t reconfigure) { - - btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); - uint8_t local_seid = avdtp_local_seid(stream_endpoint); - uint8_t remote_seid = avdtp_remote_seid(stream_endpoint); - - uint8_t event[16 + 2]; - int pos = 0; - event[pos++] = HCI_EVENT_AVDTP_META; - event[pos++] = sizeof(event) - 2; - - event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION; - little_endian_store_16(event, pos, avdtp_cid); - pos += 2; - event[pos++] = local_seid; - event[pos++] = remote_seid; - event[pos++] = reconfigure; - - - uint8_t sampling_frequency_bitmap = media_codec_information[0] >> 4; - uint8_t channel_mode_bitmap = media_codec_information[0] & 0x0F; - uint8_t block_length_bitmap = media_codec_information[1] >> 4; - uint8_t subbands_bitmap = (media_codec_information[1] & 0x0F) >> 2; - - uint8_t num_channels = 0; - if ((channel_mode_bitmap & AVDTP_SBC_JOINT_STEREO) || - (channel_mode_bitmap & AVDTP_SBC_STEREO) || - (channel_mode_bitmap & AVDTP_SBC_DUAL_CHANNEL)) { - num_channels = 2; - } else if (channel_mode_bitmap & AVDTP_SBC_MONO) { - num_channels = 1; - } - - uint16_t sampling_frequency = 0; - if (sampling_frequency_bitmap & AVDTP_SBC_48000) { - sampling_frequency = 48000; - } else if (sampling_frequency_bitmap & AVDTP_SBC_44100) { - sampling_frequency = 44100; - } else if (sampling_frequency_bitmap & AVDTP_SBC_32000) { - sampling_frequency = 32000; - } else if (sampling_frequency_bitmap & AVDTP_SBC_16000) { - sampling_frequency = 16000; - } - - uint8_t subbands = 0; - if (subbands_bitmap & AVDTP_SBC_SUBBANDS_8){ - subbands = 8; - } else if (subbands_bitmap & AVDTP_SBC_SUBBANDS_4){ - subbands = 4; - } - - uint8_t block_length = 0; - if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_16){ - block_length = 16; - } else if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_12){ - block_length = 12; - } else if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_8){ - block_length = 8; - } else if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_4){ - block_length = 4; - } - - event[pos++] = media_type; - little_endian_store_16(event, pos, sampling_frequency); - pos += 2; - - event[pos++] = channel_mode_bitmap; - event[pos++] = num_channels; - event[pos++] = block_length; - event[pos++] = subbands; - event[pos++] = media_codec_information[1] & 0x03; - event[pos++] = media_codec_information[2]; - event[pos++] = media_codec_information[3]; - (*packet_handler)(HCI_EVENT_PACKET, 0, 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, media_type, - media_codec_information, 0); -} - -void avdtp_signaling_emit_media_codec_sbc_reconfiguration(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, media_type, - media_codec_information, 1); -} - -void avdtp_signaling_emit_media_codec_other_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, - uint8_t local_seid, uint8_t remote_seid, - adtvp_media_codec_capabilities_t media_codec) { - btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); - avdtp_signaling_emit_media_codec_other(packet_handler, avdtp_cid, local_seid, remote_seid, media_codec, 0); -} - -void -avdtp_signaling_emit_media_codec_other_reconfiguration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, - uint8_t local_seid, uint8_t remote_seid, - adtvp_media_codec_capabilities_t media_codec) { - btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); - avdtp_signaling_emit_media_codec_other(packet_handler, avdtp_cid, local_seid, remote_seid, media_codec, 1); -} - btstack_linked_list_t * avdtp_get_stream_endpoints(void){ return &stream_endpoints; } diff --git a/src/classic/avdtp.h b/src/classic/avdtp.h index 8a3b887ba..a127d0ade 100644 --- a/src/classic/avdtp.h +++ b/src/classic/avdtp.h @@ -561,6 +561,7 @@ avdtp_stream_endpoint_t * avdtp_get_stream_endpoint_associated_with_acp_seid(uin btstack_packet_handler_t avdtp_packet_handler_for_stream_endpoint(const avdtp_stream_endpoint_t *stream_endpoint); void avdtp_emit_sink_and_source(uint8_t * packet, uint16_t size); +void avdtp_emit_source(uint8_t * packet, uint16_t size); void avdtp_register_media_transport_category(avdtp_stream_endpoint_t * stream_endpoint); void avdtp_register_reporting_category(avdtp_stream_endpoint_t * stream_endpoint); @@ -613,8 +614,8 @@ uint8_t avdtp_stream_endpoint_seid(avdtp_stream_endpoint_t * stream_endpoint); void avdtp_streaming_emit_can_send_media_packet_now(avdtp_stream_endpoint_t *stream_endpoint, uint16_t sequence_number); void avdtp_signaling_emit_delay(uint16_t avdtp_cid, uint8_t local_seid, uint16_t delay); -void avdtp_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, + 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); diff --git a/src/classic/avdtp_acceptor.c b/src/classic/avdtp_acceptor.c index f7b7bf3de..e628f8927 100644 --- a/src/classic/avdtp_acceptor.c +++ b/src/classic/avdtp_acceptor.c @@ -133,7 +133,8 @@ avdtp_acceptor_handle_configuration_command(avdtp_connection_t *connection, int log_info("ACP: add seid %d, to %p", stream_endpoint->remote_sep.seid, stream_endpoint); } - avdtp_emit_configuration(stream_endpoint, connection->avdtp_cid, &sep.configuration, sep.configured_service_categories); + avdtp_signaling_emit_configuration(stream_endpoint, connection->avdtp_cid, &sep.configuration, + sep.configured_service_categories); avdtp_signaling_emit_accept(connection->avdtp_cid, avdtp_local_seid(stream_endpoint), connection->acceptor_signaling_packet.signal_identifier, false); } @@ -314,7 +315,8 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t *connection, uint8_t log_info("ACP: update active remote seid %d", stream_endpoint->remote_sep.seid); - avdtp_emit_configuration(stream_endpoint, connection->avdtp_cid, &sep.configuration, sep.configured_service_categories); + avdtp_signaling_emit_configuration(stream_endpoint, connection->avdtp_cid, &sep.configuration, + sep.configured_service_categories); break; } diff --git a/src/classic/avdtp_initiator.c b/src/classic/avdtp_initiator.c index dbc1285fd..ce6060904 100644 --- a/src/classic/avdtp_initiator.c +++ b/src/classic/avdtp_initiator.c @@ -134,9 +134,9 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t *connection, uint8_t case AVDTP_SI_GET_CAPABILITIES: case AVDTP_SI_GET_ALL_CAPABILITIES: sep.registered_service_categories = avdtp_unpack_service_capabilities(connection, connection->initiator_signaling_packet.signal_identifier, &sep.capabilities, packet+offset, size-offset); - avdtp_emit_capabilities(connection->avdtp_cid, connection->initiator_local_seid, - connection->initiator_remote_seid, &sep.capabilities, - sep.registered_service_categories); + avdtp_signaling_emit_capabilities(connection->avdtp_cid, connection->initiator_local_seid, + connection->initiator_remote_seid, &sep.capabilities, + sep.registered_service_categories); break; case AVDTP_SI_RECONFIGURE: diff --git a/src/classic/avdtp_util.c b/src/classic/avdtp_util.c index 3cc3688b5..de43d20f1 100644 --- a/src/classic/avdtp_util.c +++ b/src/classic/avdtp_util.c @@ -537,6 +537,20 @@ void avdtp_signaling_emit_general_reject(uint16_t avdtp_cid, uint8_t local_seid, avdtp_emit_sink_and_source(event, pos); } +static inline void +avdtp_signaling_emit_capability(uint8_t capability_subevent_id, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid) { + uint8_t event[7]; + int pos = 0; + event[pos++] = HCI_EVENT_AVDTP_META; + event[pos++] = sizeof(event) - 2; + event[pos++] = capability_subevent_id; + little_endian_store_16(event, pos, avdtp_cid); + pos += 2; + event[pos++] = local_seid; + event[pos++] = remote_seid; + avdtp_emit_sink_and_source(event, pos); +} + static void avdtp_signaling_emit_media_codec_sbc_capability(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec) { uint8_t event[15]; @@ -559,17 +573,24 @@ static void avdtp_signaling_emit_media_codec_sbc_capability(uint16_t avdtp_cid, avdtp_emit_sink_and_source(event, pos); } -static inline void -avdtp_signaling_emit_capability(uint8_t capability_subevent_id, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid) { - uint8_t event[7]; +static void avdtp_signaling_emit_media_codec_other_capability(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, + adtvp_media_codec_capabilities_t media_codec) { + uint8_t event[MAX_MEDIA_CODEC_INFORMATION_LENGTH + 12]; int pos = 0; event[pos++] = HCI_EVENT_AVDTP_META; event[pos++] = sizeof(event) - 2; - event[pos++] = capability_subevent_id; + event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY; little_endian_store_16(event, pos, avdtp_cid); pos += 2; event[pos++] = local_seid; event[pos++] = remote_seid; + event[pos++] = media_codec.media_type; + little_endian_store_16(event, pos, media_codec.media_codec_type); + pos += 2; + little_endian_store_16(event, pos, media_codec.media_codec_information_len); + pos += 2; + (void)memcpy(event + pos, media_codec.media_codec_information, + btstack_min(media_codec.media_codec_information_len, MAX_MEDIA_CODEC_INFORMATION_LENGTH)); avdtp_emit_sink_and_source(event, pos); } @@ -677,28 +698,6 @@ avdtp_signaling_emit_content_multiplexing_capability(uint16_t avdtp_cid, uint8_t avdtp_emit_sink_and_source(event, pos); } -static void -avdtp_signaling_emit_media_codec_other_capability(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, - adtvp_media_codec_capabilities_t media_codec) { - uint8_t event[MAX_MEDIA_CODEC_INFORMATION_LENGTH + 12]; - int pos = 0; - event[pos++] = HCI_EVENT_AVDTP_META; - event[pos++] = sizeof(event) - 2; - event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY; - little_endian_store_16(event, pos, avdtp_cid); - pos += 2; - event[pos++] = local_seid; - event[pos++] = remote_seid; - event[pos++] = media_codec.media_type; - little_endian_store_16(event, pos, media_codec.media_codec_type); - pos += 2; - little_endian_store_16(event, pos, media_codec.media_codec_information_len); - pos += 2; - (void)memcpy(event + pos, media_codec.media_codec_information, - btstack_min(media_codec.media_codec_information_len, MAX_MEDIA_CODEC_INFORMATION_LENGTH)); - avdtp_emit_sink_and_source(event, pos); -} - static void avdtp_signaling_emit_capability_done(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid) { uint8_t event[7]; int pos = 0; @@ -712,33 +711,9 @@ static void avdtp_signaling_emit_capability_done(uint16_t avdtp_cid, uint8_t loc avdtp_emit_sink_and_source(event, pos); } -void avdtp_signaling_emit_media_codec_other(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec, uint8_t reconfigure){ - btstack_assert(callback != NULL); - uint8_t event[MAX_MEDIA_CODEC_INFORMATION_LENGTH + 13]; - int pos = 0; - event[pos++] = HCI_EVENT_AVDTP_META; - event[pos++] = sizeof(event) - 2; - event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION; - little_endian_store_16(event, pos, avdtp_cid); - pos += 2; - event[pos++] = local_seid; - event[pos++] = remote_seid; - event[pos++] = reconfigure; - event[pos++] = media_codec.media_type; - little_endian_store_16(event, pos, media_codec.media_codec_type); - pos += 2; - little_endian_store_16(event, pos, media_codec.media_codec_information_len); - pos += 2; - - int media_codec_len = btstack_min(MAX_MEDIA_CODEC_INFORMATION_LENGTH, media_codec.media_codec_information_len); - (void)memcpy(event + pos, media_codec.media_codec_information, - media_codec_len); - - (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); -} - -void avdtp_emit_capabilities(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_capabilities_t *capabilities, - uint16_t registered_service_categories) { +// emit events for all capabilities incl. final done event +void avdtp_signaling_emit_capabilities(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_capabilities_t *capabilities, + uint16_t registered_service_categories) { if (get_bit16(registered_service_categories, AVDTP_MEDIA_CODEC)){ switch (capabilities->media_codec.media_codec_type){ case AVDTP_CODEC_SBC: @@ -777,6 +752,223 @@ void avdtp_emit_capabilities(uint16_t avdtp_cid, uint8_t local_seid, uint8_t rem avdtp_signaling_emit_capability_done(avdtp_cid, local_seid, remote_seid); } +void avdtp_signaling_emit_media_codec_sbc(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, + avdtp_media_type_t media_type, const uint8_t *media_codec_information, + uint8_t reconfigure) { + + btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); + uint8_t local_seid = avdtp_local_seid(stream_endpoint); + uint8_t remote_seid = avdtp_remote_seid(stream_endpoint); + + uint8_t event[16 + 2]; + int pos = 0; + event[pos++] = HCI_EVENT_AVDTP_META; + event[pos++] = sizeof(event) - 2; + + event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION; + little_endian_store_16(event, pos, avdtp_cid); + pos += 2; + event[pos++] = local_seid; + event[pos++] = remote_seid; + event[pos++] = reconfigure; + + + uint8_t sampling_frequency_bitmap = media_codec_information[0] >> 4; + uint8_t channel_mode_bitmap = media_codec_information[0] & 0x0F; + uint8_t block_length_bitmap = media_codec_information[1] >> 4; + uint8_t subbands_bitmap = (media_codec_information[1] & 0x0F) >> 2; + + uint8_t num_channels = 0; + if ((channel_mode_bitmap & AVDTP_SBC_JOINT_STEREO) || + (channel_mode_bitmap & AVDTP_SBC_STEREO) || + (channel_mode_bitmap & AVDTP_SBC_DUAL_CHANNEL)) { + num_channels = 2; + } else if (channel_mode_bitmap & AVDTP_SBC_MONO) { + num_channels = 1; + } + + uint16_t sampling_frequency = 0; + if (sampling_frequency_bitmap & AVDTP_SBC_48000) { + sampling_frequency = 48000; + } else if (sampling_frequency_bitmap & AVDTP_SBC_44100) { + sampling_frequency = 44100; + } else if (sampling_frequency_bitmap & AVDTP_SBC_32000) { + sampling_frequency = 32000; + } else if (sampling_frequency_bitmap & AVDTP_SBC_16000) { + sampling_frequency = 16000; + } + + uint8_t subbands = 0; + if (subbands_bitmap & AVDTP_SBC_SUBBANDS_8){ + subbands = 8; + } else if (subbands_bitmap & AVDTP_SBC_SUBBANDS_4){ + subbands = 4; + } + + uint8_t block_length = 0; + if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_16){ + block_length = 16; + } else if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_12){ + block_length = 12; + } else if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_8){ + block_length = 8; + } else if (block_length_bitmap & AVDTP_SBC_BLOCK_LENGTH_4){ + block_length = 4; + } + + event[pos++] = media_type; + little_endian_store_16(event, pos, sampling_frequency); + pos += 2; + + event[pos++] = channel_mode_bitmap; + event[pos++] = num_channels; + event[pos++] = block_length; + event[pos++] = subbands; + event[pos++] = media_codec_information[1] & 0x03; + event[pos++] = media_codec_information[2]; + event[pos++] = media_codec_information[3]; + (*packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event)); +} + +void avdtp_signaling_emit_media_codec_other(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec, uint8_t reconfigure){ + btstack_assert(callback != NULL); + uint8_t event[MAX_MEDIA_CODEC_INFORMATION_LENGTH + 13]; + int pos = 0; + event[pos++] = HCI_EVENT_AVDTP_META; + event[pos++] = sizeof(event) - 2; + event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION; + little_endian_store_16(event, pos, avdtp_cid); + pos += 2; + event[pos++] = local_seid; + event[pos++] = remote_seid; + event[pos++] = reconfigure; + event[pos++] = media_codec.media_type; + little_endian_store_16(event, pos, media_codec.media_codec_type); + pos += 2; + little_endian_store_16(event, pos, media_codec.media_codec_information_len); + pos += 2; + + int media_codec_len = btstack_min(MAX_MEDIA_CODEC_INFORMATION_LENGTH, media_codec.media_codec_information_len); + (void)memcpy(event + pos, media_codec.media_codec_information, + media_codec_len); + + (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); +} + +void avdtp_signaling_emit_delay(uint16_t avdtp_cid, uint8_t local_seid, uint16_t delay) { + uint8_t event[8]; + int pos = 0; + event[pos++] = HCI_EVENT_AVDTP_META; + event[pos++] = sizeof(event) - 2; + event[pos++] = AVDTP_SUBEVENT_SIGNALING_DELAY_REPORT; + little_endian_store_16(event, pos, avdtp_cid); + pos += 2; + event[pos++] = local_seid; + little_endian_store_16(event, pos, delay); + pos += 2; + 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, media_type, + media_codec_information, 0); +} + +void avdtp_signaling_emit_media_codec_sbc_reconfiguration(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, media_type, + media_codec_information, 1); +} + +void avdtp_signaling_emit_media_codec_other_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, + uint8_t local_seid, uint8_t remote_seid, + adtvp_media_codec_capabilities_t media_codec) { + btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); + avdtp_signaling_emit_media_codec_other(packet_handler, avdtp_cid, local_seid, remote_seid, media_codec, 0); +} + +void +avdtp_signaling_emit_media_codec_other_reconfiguration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, + uint8_t local_seid, uint8_t remote_seid, + adtvp_media_codec_capabilities_t media_codec) { + btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); + avdtp_signaling_emit_media_codec_other(packet_handler, avdtp_cid, local_seid, remote_seid, media_codec, 1); +} + +void avdtp_signaling_emit_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, + avdtp_capabilities_t *configuration, uint16_t configured_service_categories) { + + uint8_t local_seid = avdtp_local_seid(stream_endpoint); + uint8_t remote_seid = avdtp_remote_seid(stream_endpoint); + + 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); + break; + default: + avdtp_signaling_emit_media_codec_other_configuration(stream_endpoint, avdtp_cid, + local_seid, remote_seid, + configuration->media_codec); + break; + } + } +} + +void avdtp_streaming_emit_connection_established(avdtp_stream_endpoint_t *stream_endpoint, uint8_t status) { + uint8_t event[14]; + int pos = 0; + event[pos++] = HCI_EVENT_AVDTP_META; + event[pos++] = sizeof(event) - 2; + event[pos++] = AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED; + little_endian_store_16(event, pos, stream_endpoint->connection->avdtp_cid); + pos += 2; + reverse_bd_addr(stream_endpoint->connection->remote_addr, &event[pos]); + pos += 6; + event[pos++] = avdtp_local_seid(stream_endpoint); + event[pos++] = avdtp_remote_seid(stream_endpoint); + event[pos++] = status; + + btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); + (*packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event)); +} + +void avdtp_streaming_emit_connection_released(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, uint8_t local_seid) { + uint8_t event[6]; + int pos = 0; + event[pos++] = HCI_EVENT_AVDTP_META; + event[pos++] = sizeof(event) - 2; + event[pos++] = AVDTP_SUBEVENT_STREAMING_CONNECTION_RELEASED; + little_endian_store_16(event, pos, avdtp_cid); + pos += 2; + event[pos++] = local_seid; + + btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); + (*packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event)); +} + +void avdtp_streaming_emit_can_send_media_packet_now(avdtp_stream_endpoint_t *stream_endpoint, uint16_t sequence_number) { + uint8_t event[8]; + int pos = 0; + event[pos++] = HCI_EVENT_AVDTP_META; + event[pos++] = sizeof(event) - 2; + event[pos++] = AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW; + little_endian_store_16(event, pos, stream_endpoint->connection->avdtp_cid); + pos += 2; + event[pos++] = avdtp_local_seid(stream_endpoint); + little_endian_store_16(event, pos, sequence_number); + pos += 2; + + btstack_packet_handler_t packet_handler = avdtp_packet_handler_for_stream_endpoint(stream_endpoint); + (*packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event)); +} + uint8_t avdtp_request_can_send_now_acceptor(avdtp_connection_t * connection, uint16_t l2cap_cid){ if (!connection) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; connection->wait_to_send_acceptor = 1; @@ -802,6 +994,8 @@ uint8_t avdtp_remote_seid(avdtp_stream_endpoint_t * stream_endpoint){ return stream_endpoint->remote_sep.seid; } +// helper for A2DP + void a2dp_replace_subevent_id_and_emit_cmd(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size, uint8_t subevent_id){ UNUSED(size); btstack_assert(callback != NULL); diff --git a/src/classic/avdtp_util.h b/src/classic/avdtp_util.h index 15d3cf7d5..522b2c42c 100644 --- a/src/classic/avdtp_util.h +++ b/src/classic/avdtp_util.h @@ -69,6 +69,10 @@ uint16_t avdtp_unpack_service_capabilities(avdtp_connection_t * connection, avdt void avdtp_prepare_capabilities(avdtp_signaling_packet_t * signaling_packet, uint8_t transaction_label, uint16_t service_categories, avdtp_capabilities_t capabilities, uint8_t identifier); int avdtp_signaling_create_fragment(uint16_t cid, avdtp_signaling_packet_t * signaling_packet, uint8_t * out_buffer); +void avdtp_streaming_emit_connection_established(avdtp_stream_endpoint_t *stream_endpoint, uint8_t status); + +void avdtp_streaming_emit_connection_released(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, uint8_t local_seid); + void avdtp_signaling_emit_connection_established(uint16_t avdtp_cid, bd_addr_t addr, uint8_t status); void avdtp_signaling_emit_connection_released(uint16_t avdtp_cid); @@ -84,9 +88,12 @@ void avdtp_signaling_emit_reject(uint16_t avdtp_cid, uint8_t local_seid, avdtp_s bool is_initiator); void -avdtp_emit_capabilities(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_capabilities_t *capabilities, - uint16_t registered_service_categories); +avdtp_signaling_emit_capabilities(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_capabilities_t *capabilities, + uint16_t registered_service_categories); +void avdtp_signaling_emit_media_codec_sbc(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, + avdtp_media_type_t media_type, const uint8_t *media_codec_information, + uint8_t reconfigure) ; void avdtp_signaling_emit_media_codec_other_reconfiguration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid,