diff --git a/src/classic/avdtp.c b/src/classic/avdtp.c index 9ba7429bd..5cb06e620 100644 --- a/src/classic/avdtp.c +++ b/src/classic/avdtp.c @@ -156,8 +156,10 @@ void avdtp_emit_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t 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(packet_handler, avdtp_cid, local_seid, remote_seid, - configuration->media_codec.media_type, configuration->media_codec.media_codec_information); + 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(packet_handler, avdtp_cid, local_seid, remote_seid, configuration->media_codec); @@ -166,6 +168,99 @@ void avdtp_emit_configuration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t } } +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); +} + 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 e232a2ddb..a206b58d4 100644 --- a/src/classic/avdtp.h +++ b/src/classic/avdtp.h @@ -610,6 +610,12 @@ void avdtp_streaming_emit_can_send_media_packet_now(avdtp_stream_endpoint_t *str 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_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_sbc_reconfiguration(avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, + avdtp_media_type_t media_type, + const uint8_t *media_codec_information); uint8_t is_avdtp_remote_seid_registered(avdtp_stream_endpoint_t * stream_endpoint); diff --git a/src/classic/avdtp_initiator.c b/src/classic/avdtp_initiator.c index cc1f42c5e..273bc22a0 100644 --- a/src/classic/avdtp_initiator.c +++ b/src/classic/avdtp_initiator.c @@ -187,9 +187,12 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_ log_info("INT: configured remote seid %d, to %p", stream_endpoint->remote_sep.seid, stream_endpoint); switch (stream_endpoint->media_codec_type){ - case AVDTP_CODEC_SBC: - avdtp_signaling_emit_media_codec_sbc_configuration(context->avdtp_callback, connection->avdtp_cid, connection->initiator_local_seid, connection->initiator_remote_seid, - stream_endpoint->media_type, stream_endpoint->media_codec_sbc_info); + case AVDTP_CODEC_SBC: + avdtp_signaling_emit_media_codec_sbc_configuration( + stream_endpoint, + connection->avdtp_cid, + stream_endpoint->media_type, + stream_endpoint->media_codec_sbc_info); break; default: // TODO: we don\t have codec info to emit config diff --git a/src/classic/avdtp_util.c b/src/classic/avdtp_util.c index 5626d1196..39dc73017 100644 --- a/src/classic/avdtp_util.c +++ b/src/classic/avdtp_util.c @@ -692,90 +692,6 @@ static void avdtp_signaling_emit_media_codec_other_capability(btstack_packet_han (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); } -static inline void avdtp_signaling_emit_media_codec_sbc(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, - avdtp_media_type_t media_type, const uint8_t * media_codec_information, uint8_t reconfigure) { - btstack_assert(callback != NULL); - 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]; - (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); -} - -void avdtp_signaling_emit_media_codec_sbc_configuration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_media_type_t media_type, const uint8_t * media_codec_information){ - btstack_assert(callback != NULL); - avdtp_signaling_emit_media_codec_sbc(callback, avdtp_cid, local_seid, remote_seid, media_type, media_codec_information, 0); -} - -void avdtp_signaling_emit_media_codec_sbc_reconfiguration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_media_type_t media_type, const uint8_t * media_codec_information){ - btstack_assert(callback != NULL); - avdtp_signaling_emit_media_codec_sbc(callback, avdtp_cid, local_seid, remote_seid, media_type, media_codec_information, 1); -} - - static inline 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]; diff --git a/src/classic/avdtp_util.h b/src/classic/avdtp_util.h index fce77ad22..fd1693ca5 100644 --- a/src/classic/avdtp_util.h +++ b/src/classic/avdtp_util.h @@ -82,9 +82,7 @@ void avdtp_signaling_emit_reject(btstack_packet_handler_t callback, uint16_t avd void avdtp_emit_capabilities(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_capabilities_t * configuration, uint16_t configured_service_categories); -void avdtp_signaling_emit_media_codec_sbc_configuration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_media_type_t media_type, const uint8_t * media_codec_information); void avdtp_signaling_emit_media_codec_other_configuration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec); -void avdtp_signaling_emit_media_codec_sbc_reconfiguration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_media_type_t media_type, const uint8_t * media_codec_information); void avdtp_signaling_emit_media_codec_other_reconfiguration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec); uint8_t avdtp_request_can_send_now_acceptor(avdtp_connection_t * connection, uint16_t l2cap_cid);