1 2 /* 3 * Copyright (C) 2016 BlueKitchen GmbH 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the copyright holders nor the names of 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 4. Any redistribution, use, or modification is done solely for 18 * personal benefit and not for any commercial purpose or for 19 * monetary gain. 20 * 21 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 25 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 31 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * Please inquire about commercial licensing options at 35 * [email protected] 36 * 37 */ 38 39 #define __BTSTACK_FILE__ "avdtp_source.c" 40 41 42 #include <stdint.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <unistd.h> 47 #include <math.h> 48 49 #include "btstack.h" 50 #include "avdtp.h" 51 #include "avdtp_util.h" 52 #include "avdtp_source.h" 53 54 static avdtp_context_t * avdtp_source_context; 55 static avdtp_connection_t * avtdp_connection_doing_sdp_query = NULL; 56 static int record_id = -1; 57 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 58 59 static uint8_t attribute_value[1000]; 60 static const unsigned int attribute_value_buffer_size = sizeof(attribute_value); 61 62 void avdtp_source_register_media_transport_category(uint8_t seid){ 63 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_source_context); 64 avdtp_register_media_transport_category(stream_endpoint); 65 } 66 67 void avdtp_source_register_reporting_category(uint8_t seid){ 68 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_source_context); 69 avdtp_register_reporting_category(stream_endpoint); 70 } 71 72 void avdtp_source_register_delay_reporting_category(uint8_t seid){ 73 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_source_context); 74 avdtp_register_delay_reporting_category(stream_endpoint); 75 } 76 77 void avdtp_source_register_recovery_category(uint8_t seid, uint8_t maximum_recovery_window_size, uint8_t maximum_number_media_packets){ 78 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_source_context); 79 avdtp_register_recovery_category(stream_endpoint, maximum_recovery_window_size, maximum_number_media_packets); 80 } 81 82 void avdtp_source_register_content_protection_category(uint8_t seid, uint16_t cp_type, const uint8_t * cp_type_value, uint8_t cp_type_value_len){ 83 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_source_context); 84 avdtp_register_content_protection_category(stream_endpoint, cp_type, cp_type_value, cp_type_value_len); 85 } 86 87 void avdtp_source_register_header_compression_category(uint8_t seid, uint8_t back_ch, uint8_t media, uint8_t recovery){ 88 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_source_context); 89 avdtp_register_header_compression_category(stream_endpoint, back_ch, media, recovery); 90 } 91 92 void avdtp_source_register_media_codec_category(uint8_t seid, avdtp_media_type_t media_type, avdtp_media_codec_type_t media_codec_type, uint8_t * media_codec_info, uint16_t media_codec_info_len){ 93 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_source_context); 94 avdtp_register_media_codec_category(stream_endpoint, media_type, media_codec_type, media_codec_info, media_codec_info_len); 95 } 96 97 void avdtp_source_register_multiplexing_category(uint8_t seid, uint8_t fragmentation){ 98 avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_source_context); 99 avdtp_register_multiplexing_category(stream_endpoint, fragmentation); 100 } 101 102 avdtp_stream_endpoint_t * avdtp_source_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type){ 103 return avdtp_create_stream_endpoint(sep_type, media_type, avdtp_source_context); 104 } 105 106 void avdtp_source_register_packet_handler(btstack_packet_handler_t callback){ 107 if (callback == NULL){ 108 log_error("avdtp_source_register_packet_handler called with NULL callback"); 109 return; 110 } 111 avdtp_source_context->avdtp_callback = callback; 112 } 113 114 static void avdtp_source_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 115 UNUSED(packet_type); 116 UNUSED(channel); 117 UNUSED(size); 118 119 des_iterator_t des_list_it; 120 des_iterator_t prot_it; 121 uint32_t avdtp_remote_uuid = 0; 122 uint16_t avdtp_l2cap_psm = 0; 123 uint16_t avdtp_version = 0; 124 125 if (!avtdp_connection_doing_sdp_query) return; 126 127 switch (hci_event_packet_get_type(packet)){ 128 case SDP_EVENT_QUERY_ATTRIBUTE_VALUE: 129 // Handle new SDP record 130 if (sdp_event_query_attribute_byte_get_record_id(packet) != record_id) { 131 record_id = sdp_event_query_attribute_byte_get_record_id(packet); 132 printf("SDP Record: Nr: %d\n", record_id); 133 } 134 135 if (sdp_event_query_attribute_byte_get_attribute_length(packet) <= attribute_value_buffer_size) { 136 attribute_value[sdp_event_query_attribute_byte_get_data_offset(packet)] = sdp_event_query_attribute_byte_get_data(packet); 137 138 if ((uint16_t)(sdp_event_query_attribute_byte_get_data_offset(packet)+1) == sdp_event_query_attribute_byte_get_attribute_length(packet)) { 139 140 switch(sdp_event_query_attribute_byte_get_attribute_id(packet)) { 141 case BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST: 142 if (de_get_element_type(attribute_value) != DE_DES) break; 143 for (des_iterator_init(&des_list_it, attribute_value); des_iterator_has_more(&des_list_it); des_iterator_next(&des_list_it)) { 144 uint8_t * element = des_iterator_get_element(&des_list_it); 145 if (de_get_element_type(element) != DE_UUID) continue; 146 uint32_t uuid = de_get_uuid32(element); 147 switch (uuid){ 148 case BLUETOOTH_SERVICE_CLASS_AUDIO_SOURCE: 149 printf("SDP Attribute 0x%04x: AVDTP SOURCE protocol UUID: 0x%04x\n", sdp_event_query_attribute_byte_get_attribute_id(packet), uuid); 150 avdtp_remote_uuid = uuid; 151 break; 152 case BLUETOOTH_SERVICE_CLASS_AUDIO_SINK: 153 printf("SDP Attribute 0x%04x: AVDTP SINK protocol UUID: 0x%04x\n", sdp_event_query_attribute_byte_get_attribute_id(packet), uuid); 154 avdtp_remote_uuid = uuid; 155 break; 156 default: 157 break; 158 } 159 } 160 break; 161 162 case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST: { 163 printf("SDP Attribute: 0x%04x\n", sdp_event_query_attribute_byte_get_attribute_id(packet)); 164 165 for (des_iterator_init(&des_list_it, attribute_value); des_iterator_has_more(&des_list_it); des_iterator_next(&des_list_it)) { 166 uint8_t *des_element; 167 uint8_t *element; 168 uint32_t uuid; 169 170 if (des_iterator_get_type(&des_list_it) != DE_DES) continue; 171 172 des_element = des_iterator_get_element(&des_list_it); 173 des_iterator_init(&prot_it, des_element); 174 element = des_iterator_get_element(&prot_it); 175 176 if (de_get_element_type(element) != DE_UUID) continue; 177 178 uuid = de_get_uuid32(element); 179 switch (uuid){ 180 case BLUETOOTH_PROTOCOL_L2CAP: 181 if (!des_iterator_has_more(&prot_it)) continue; 182 des_iterator_next(&prot_it); 183 de_element_get_uint16(des_iterator_get_element(&prot_it), &avdtp_l2cap_psm); 184 break; 185 case BLUETOOTH_PROTOCOL_AVDTP: 186 if (!des_iterator_has_more(&prot_it)) continue; 187 des_iterator_next(&prot_it); 188 de_element_get_uint16(des_iterator_get_element(&prot_it), &avdtp_version); 189 break; 190 default: 191 break; 192 } 193 } 194 printf("l2cap_psm 0x%04x, avdtp_version 0x%04x\n", avdtp_l2cap_psm, avdtp_version); 195 196 /* Create AVDTP connection */ 197 avtdp_connection_doing_sdp_query->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED; 198 l2cap_create_channel(packet_handler, avtdp_connection_doing_sdp_query->remote_addr, avdtp_l2cap_psm, l2cap_max_mtu(), NULL); 199 } 200 break; 201 default: 202 break; 203 } 204 } 205 } else { 206 fprintf(stderr, "SDP attribute value buffer size exceeded: available %d, required %d\n", attribute_value_buffer_size, sdp_event_query_attribute_byte_get_attribute_length(packet)); 207 } 208 break; 209 210 case SDP_EVENT_QUERY_COMPLETE: 211 fprintf(stderr, "General query done with status %d.\n", sdp_event_query_complete_get_status(packet)); 212 break; 213 } 214 } 215 216 void avdtp_source_connect(bd_addr_t remote){ 217 avtdp_connection_doing_sdp_query = NULL; 218 avdtp_connection_t * connection = avdtp_connection_for_bd_addr(remote, avdtp_source_context); 219 if (!connection){ 220 connection = avdtp_create_connection(remote, avdtp_source_context); 221 } 222 if (connection->state != AVDTP_SIGNALING_CONNECTION_IDLE) return; 223 avtdp_connection_doing_sdp_query = connection; 224 connection->state = AVDTP_SIGNALING_W4_SDP_QUERY_COMPLETE; 225 sdp_client_query_uuid16(&avdtp_source_handle_sdp_client_query_result, remote, BLUETOOTH_PROTOCOL_AVDTP); 226 } 227 228 void avdtp_source_disconnect(uint16_t con_handle){ 229 avdtp_disconnect(con_handle, avdtp_source_context); 230 } 231 232 void avdtp_source_open_stream(uint16_t con_handle, uint8_t int_seid, uint8_t acp_seid){ 233 avdtp_open_stream(con_handle, int_seid, acp_seid, avdtp_source_context); 234 } 235 236 void avdtp_source_start_stream(uint8_t int_seid){ 237 avdtp_start_stream(int_seid, avdtp_source_context); 238 } 239 240 void avdtp_source_stop_stream(uint8_t int_seid){ 241 avdtp_stop_stream(int_seid, avdtp_source_context); 242 } 243 244 void avdtp_source_abort_stream(uint8_t int_seid){ 245 avdtp_abort_stream(int_seid, avdtp_source_context); 246 } 247 248 void avdtp_source_suspend(uint8_t int_seid){ 249 avdtp_suspend_stream(int_seid, avdtp_source_context); 250 } 251 252 void avdtp_source_discover_stream_endpoints(uint16_t con_handle){ 253 avdtp_discover_stream_endpoints(con_handle, avdtp_source_context); 254 } 255 256 void avdtp_source_get_capabilities(uint16_t con_handle, uint8_t acp_seid){ 257 avdtp_get_capabilities(con_handle, acp_seid, avdtp_source_context); 258 } 259 260 void avdtp_source_get_all_capabilities(uint16_t con_handle, uint8_t acp_seid){ 261 avdtp_get_all_capabilities(con_handle, acp_seid, avdtp_source_context); 262 } 263 264 void avdtp_source_get_configuration(uint16_t con_handle, uint8_t acp_seid){ 265 avdtp_get_configuration(con_handle, acp_seid, avdtp_source_context); 266 } 267 268 void avdtp_source_set_configuration(uint16_t con_handle, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){ 269 avdtp_set_configuration(con_handle, int_seid, acp_seid, configured_services_bitmap, configuration, avdtp_source_context); 270 } 271 272 void avdtp_source_reconfigure(uint16_t con_handle, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){ 273 avdtp_reconfigure(con_handle, int_seid, acp_seid, configured_services_bitmap, configuration, avdtp_source_context); 274 } 275 276 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 277 avdtp_packet_handler(packet_type, channel, packet, size, avdtp_source_context); 278 } 279 280 void avdtp_source_init(avdtp_context_t * avdtp_context){ 281 if (!avdtp_context){ 282 log_error("avdtp_source_context is NULL"); 283 return; 284 } 285 avdtp_source_context = avdtp_context; 286 avdtp_source_context->stream_endpoints = NULL; 287 avdtp_source_context->connections = NULL; 288 avdtp_source_context->stream_endpoints_id_counter = 0; 289 avdtp_source_context->packet_handler = packet_handler; 290 291 l2cap_register_service(&packet_handler, BLUETOOTH_PROTOCOL_AVDTP, 0xffff, LEVEL_0); 292 } 293 294 uint8_t avdtp_source_remote_seps_num(uint16_t avdtp_cid){ 295 return avdtp_remote_seps_num(avdtp_cid, avdtp_source_context); 296 } 297 298 avdtp_sep_t * avdtp_source_remote_sep(uint16_t avdtp_cid, uint8_t index){ 299 return avdtp_remote_sep(avdtp_cid, index, avdtp_source_context); 300 } 301