mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-29 22:20:37 +00:00
avdtp: collect all emit functions in avdtp_util
This commit is contained in:
parent
8a7c69df9b
commit
4b7d40bbed
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user