1 /* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "sdp_client_rfcomm.c" 39 40 /* 41 * sdp_rfcomm_query.c 42 */ 43 44 #include <stdint.h> 45 #include <string.h> 46 47 #include "bluetooth_sdp.h" 48 #include "btstack_debug.h" 49 #include "btstack_event.h" 50 #include "classic/core.h" 51 #include "classic/sdp_client.h" 52 #include "classic/sdp_client_rfcomm.h" 53 #include "classic/sdp_util.h" 54 #include "hci_cmd.h" 55 56 #if (SDP_SERVICE_NAME_LEN < 16) 57 #error "SDP_SERVICE_NAME_LEN must be at least 16 bytes" 58 #endif 59 60 // called by test/sdp_client 61 void sdp_client_query_rfcomm_init(void); 62 63 static enum { 64 GET_PROTOCOL_LIST_LENGTH = 1, 65 GET_PROTOCOL_LENGTH, 66 GET_PROTOCOL_ID_HEADER_LENGTH, 67 GET_PROTOCOL_ID, 68 GET_PROTOCOL_VALUE_LENGTH, 69 GET_PROTOCOL_VALUE 70 } protokoll_descriptor_list_state; 71 72 static enum { 73 GET_SERVICE_LIST_LENGTH = 1, 74 GET_SERVICE_LIST_ITEM_GET_UUID_TYPE, 75 GET_SERVICE_LIST_ITEM, 76 GET_SERVICE_LIST_ITEM_SHORT, 77 GET_SERVICE_LIST_ITEM_LONG, 78 GET_SERVICE_INVALID, 79 } service_class_id_list_state; 80 81 // higher layer query - get rfcomm channel and name 82 83 // All attributes: 0x0001 - 0x0100 84 static const uint8_t des_attributeIDList[] = { 0x35, 0x05, 0x0A, 0x00, 0x01, 0x01, 0x00}; 85 86 static uint8_t sdp_service_name[SDP_SERVICE_NAME_LEN+1]; 87 static uint8_t sdp_service_name_len = 0; 88 static uint8_t sdp_rfcomm_channel_nr = 0; 89 90 static uint8_t sdp_service_name_header_size; 91 92 static bool sdp_client_rfcomm_serviceclass_matched; 93 static bool sdp_client_rfcomm_match_serviceclass; 94 static uint16_t sdp_client_rfcomm_uuid16; 95 96 static int protocol_value_bytes_received = 0; 97 static int protocol_value_size; 98 static int protocol_offset; 99 static int protocol_size; 100 static int protocol_id_bytes_to_read; 101 static uint32_t protocol_id = 0; 102 103 static de_state_t de_header_state; 104 static btstack_packet_handler_t sdp_app_callback; 105 // 106 107 static void sdp_rfcomm_query_prepare(void){ 108 sdp_rfcomm_channel_nr = 0; 109 sdp_service_name[0] = 0; 110 sdp_client_rfcomm_serviceclass_matched = false; 111 } 112 113 static void sdp_rfcomm_query_emit_service(void){ 114 uint8_t event[3+SDP_SERVICE_NAME_LEN+1]; 115 event[0] = SDP_EVENT_QUERY_RFCOMM_SERVICE; 116 event[1] = sdp_service_name_len + 1; 117 event[2] = sdp_rfcomm_channel_nr; 118 (void)memcpy(&event[3], sdp_service_name, sdp_service_name_len); 119 event[3+sdp_service_name_len] = 0; 120 (*sdp_app_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 121 } 122 123 static void sdp_client_query_rfcomm_handle_record_parsed(void){ 124 if (sdp_rfcomm_channel_nr == 0) return; 125 if (sdp_client_rfcomm_match_serviceclass && (sdp_client_rfcomm_serviceclass_matched == false)) return; 126 sdp_rfcomm_query_emit_service(); 127 sdp_rfcomm_query_prepare(); 128 } 129 130 // Format: DE Sequence of UUIDs 131 static void sdp_client_query_rfcomm_handle_service_class_list_data(uint32_t attribute_value_length, uint32_t data_offset, uint8_t data){ 132 UNUSED(attribute_value_length); 133 134 // init state on first byte 135 if (data_offset == 0){ 136 service_class_id_list_state = GET_SERVICE_LIST_LENGTH; 137 de_state_init(&de_header_state); 138 } 139 140 // process data 141 switch(service_class_id_list_state){ 142 143 case GET_SERVICE_LIST_LENGTH: 144 // read DES sequence header 145 if (!de_state_size(data, &de_header_state)) break; 146 service_class_id_list_state = GET_SERVICE_LIST_ITEM_GET_UUID_TYPE; 147 break; 148 149 case GET_SERVICE_LIST_ITEM_GET_UUID_TYPE: 150 protocol_id = 0; 151 protocol_offset = 0; 152 // validate UUID type 153 if (de_get_element_type(&data) != DE_UUID) { 154 service_class_id_list_state = GET_SERVICE_INVALID; 155 break; 156 } 157 // get UUID length 158 protocol_id_bytes_to_read = de_get_data_size(&data); 159 if (protocol_id_bytes_to_read > 16) { 160 service_class_id_list_state = GET_SERVICE_INVALID; 161 break; 162 } 163 service_class_id_list_state = GET_SERVICE_LIST_ITEM; 164 break; 165 166 case GET_SERVICE_LIST_ITEM: 167 sdp_service_name[protocol_offset++] = data; 168 protocol_id_bytes_to_read--; 169 if (protocol_id_bytes_to_read > 0) break; 170 // parse 2/4/16 bytes UUID 171 switch (protocol_offset){ 172 case 2: 173 protocol_id = big_endian_read_16(sdp_service_name, 0); 174 break; 175 case 4: 176 protocol_id = big_endian_read_32(sdp_service_name, 0); 177 break; 178 case 16: 179 if (uuid_has_bluetooth_prefix(sdp_service_name)){ 180 protocol_id = big_endian_read_32(sdp_service_name, 0); 181 } 182 break; 183 default: 184 break; 185 } 186 if (protocol_id == sdp_client_rfcomm_uuid16){ 187 sdp_client_rfcomm_serviceclass_matched = true; 188 } 189 service_class_id_list_state = GET_SERVICE_LIST_ITEM_GET_UUID_TYPE; 190 break; 191 192 default: 193 break; 194 } 195 } 196 197 static void sdp_client_query_rfcomm_handle_protocol_descriptor_list_data(uint32_t attribute_value_length, uint32_t data_offset, uint8_t data){ 198 UNUSED(attribute_value_length); 199 200 // init state on first byte 201 if (data_offset == 0){ 202 de_state_init(&de_header_state); 203 protokoll_descriptor_list_state = GET_PROTOCOL_LIST_LENGTH; 204 } 205 206 switch(protokoll_descriptor_list_state){ 207 208 case GET_PROTOCOL_LIST_LENGTH: 209 if (!de_state_size(data, &de_header_state)) break; 210 211 protokoll_descriptor_list_state = GET_PROTOCOL_LENGTH; 212 break; 213 214 case GET_PROTOCOL_LENGTH: 215 // check size 216 if (!de_state_size(data, &de_header_state)) break; 217 218 // cache protocol info 219 protocol_offset = de_header_state.de_offset; 220 protocol_size = de_header_state.de_size; 221 222 protokoll_descriptor_list_state = GET_PROTOCOL_ID_HEADER_LENGTH; 223 break; 224 225 case GET_PROTOCOL_ID_HEADER_LENGTH: 226 protocol_offset++; 227 if (!de_state_size(data, &de_header_state)) break; 228 229 protocol_id = 0; 230 protocol_id_bytes_to_read = de_header_state.de_size; 231 protokoll_descriptor_list_state = GET_PROTOCOL_ID; 232 233 break; 234 235 case GET_PROTOCOL_ID: 236 protocol_offset++; 237 238 protocol_id = (protocol_id << 8) | data; 239 protocol_id_bytes_to_read--; 240 if (protocol_id_bytes_to_read > 0) break; 241 242 243 if (protocol_offset >= protocol_size){ 244 protokoll_descriptor_list_state = GET_PROTOCOL_LENGTH; 245 break; 246 } 247 248 protokoll_descriptor_list_state = GET_PROTOCOL_VALUE_LENGTH; 249 protocol_value_bytes_received = 0; 250 break; 251 252 case GET_PROTOCOL_VALUE_LENGTH: 253 protocol_offset++; 254 255 if (!de_state_size(data, &de_header_state)) break; 256 257 protocol_value_size = de_header_state.de_size; 258 protokoll_descriptor_list_state = GET_PROTOCOL_VALUE; 259 sdp_rfcomm_channel_nr = 0; 260 break; 261 262 case GET_PROTOCOL_VALUE: 263 protocol_offset++; 264 protocol_value_bytes_received++; 265 266 if (protocol_value_bytes_received < protocol_value_size) break; 267 268 if (protocol_id == BLUETOOTH_PROTOCOL_RFCOMM){ 269 // log_info("\n\n ******* Data ***** %02x\n\n", data); 270 sdp_rfcomm_channel_nr = data; 271 } 272 273 if (protocol_offset >= protocol_size) { 274 protokoll_descriptor_list_state = GET_PROTOCOL_LENGTH; 275 break; 276 277 } 278 protokoll_descriptor_list_state = GET_PROTOCOL_ID_HEADER_LENGTH; 279 break; 280 default: 281 break; 282 } 283 } 284 285 static void sdp_client_query_rfcomm_handle_service_name_data(uint32_t attribute_value_length, uint32_t data_offset, uint8_t data){ 286 287 // Get Header Len 288 if (data_offset == 0){ 289 de_state_init(&de_header_state); 290 de_state_size(data, &de_header_state); 291 sdp_service_name_header_size = de_header_state.addon_header_bytes + 1; 292 return; 293 } 294 295 // Get Header 296 if (data_offset < sdp_service_name_header_size){ 297 de_state_size(data, &de_header_state); 298 return; 299 } 300 301 // Process payload 302 int name_len = attribute_value_length - sdp_service_name_header_size; 303 int name_pos = data_offset - sdp_service_name_header_size; 304 305 if (name_pos < SDP_SERVICE_NAME_LEN){ 306 sdp_service_name[name_pos] = data; 307 name_pos++; 308 309 // terminate if name complete 310 if (name_pos >= name_len){ 311 sdp_service_name[name_pos] = 0; 312 sdp_service_name_len = name_pos; 313 } 314 315 // terminate if buffer full 316 if (name_pos == SDP_SERVICE_NAME_LEN){ 317 sdp_service_name[name_pos] = 0; 318 sdp_service_name_len = name_pos; 319 } 320 } 321 322 // notify on last char 323 if ((data_offset == (attribute_value_length - 1)) && (sdp_rfcomm_channel_nr!=0)){ 324 sdp_client_query_rfcomm_handle_record_parsed(); 325 } 326 } 327 328 static void sdp_client_query_rfcomm_handle_sdp_parser_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 329 UNUSED(packet_type); 330 UNUSED(channel); 331 332 switch (hci_event_packet_get_type(packet)){ 333 case SDP_EVENT_QUERY_SERVICE_RECORD_HANDLE: 334 sdp_client_query_rfcomm_handle_record_parsed(); 335 336 // prepare for new record 337 sdp_rfcomm_query_prepare(); 338 break; 339 case SDP_EVENT_QUERY_ATTRIBUTE_VALUE: 340 switch (sdp_event_query_attribute_byte_get_attribute_id(packet)){ 341 case BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST: 342 if (sdp_client_rfcomm_match_serviceclass){ 343 sdp_client_query_rfcomm_handle_service_class_list_data(sdp_event_query_attribute_byte_get_attribute_length(packet), 344 sdp_event_query_attribute_byte_get_data_offset(packet), 345 sdp_event_query_attribute_byte_get_data(packet)); 346 } 347 break; 348 case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST: 349 // find rfcomm channel 350 sdp_client_query_rfcomm_handle_protocol_descriptor_list_data(sdp_event_query_attribute_byte_get_attribute_length(packet), 351 sdp_event_query_attribute_byte_get_data_offset(packet), 352 sdp_event_query_attribute_byte_get_data(packet)); 353 break; 354 case 0x0100: 355 // get service name 356 sdp_client_query_rfcomm_handle_service_name_data(sdp_event_query_attribute_byte_get_attribute_length(packet), 357 sdp_event_query_attribute_byte_get_data_offset(packet), 358 sdp_event_query_attribute_byte_get_data(packet)); 359 break; 360 default: 361 // give up 362 return; 363 } 364 break; 365 case SDP_EVENT_QUERY_COMPLETE: 366 sdp_client_query_rfcomm_handle_record_parsed(); 367 (*sdp_app_callback)(HCI_EVENT_PACKET, 0, packet, size); 368 break; 369 default: 370 break; 371 } 372 } 373 374 void sdp_client_query_rfcomm_init(void){ 375 // init 376 protokoll_descriptor_list_state = GET_PROTOCOL_LIST_LENGTH; 377 protocol_offset = 0; 378 sdp_rfcomm_channel_nr = 0; 379 sdp_service_name[0] = 0; 380 } 381 382 static uint8_t sdp_client_query_rfcomm(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * service_search_pattern){ 383 sdp_app_callback = callback; 384 sdp_client_query_rfcomm_init(); 385 return sdp_client_query(&sdp_client_query_rfcomm_handle_sdp_parser_event, remote, service_search_pattern, (uint8_t*)&des_attributeIDList[0]); 386 } 387 388 // Public API 389 390 uint8_t sdp_client_query_rfcomm_channel_and_name_for_uuid(btstack_packet_handler_t callback, bd_addr_t remote, uint16_t uuid16){ 391 if (!sdp_client_ready()) return SDP_QUERY_BUSY; 392 sdp_client_rfcomm_match_serviceclass = false; 393 return sdp_client_query_rfcomm(callback, remote, sdp_service_search_pattern_for_uuid16(uuid16)); 394 } 395 396 uint8_t sdp_client_query_rfcomm_channel_and_name_for_service_class_uuid(btstack_packet_handler_t callback, bd_addr_t remote, uint16_t uuid16){ 397 if (!sdp_client_ready()) return SDP_QUERY_BUSY; 398 sdp_client_rfcomm_match_serviceclass = true; 399 sdp_client_rfcomm_uuid16 = uuid16; 400 return sdp_client_query_rfcomm(callback, remote, sdp_service_search_pattern_for_uuid16(uuid16)); 401 } 402 403 uint8_t sdp_client_query_rfcomm_channel_and_name_for_uuid128(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * uuid128){ 404 if (!sdp_client_ready()) return SDP_QUERY_BUSY; 405 sdp_client_rfcomm_match_serviceclass = false; 406 return sdp_client_query_rfcomm(callback, remote, sdp_service_search_pattern_for_uuid128(uuid128)); 407 } 408 409 uint8_t sdp_client_query_rfcomm_channel_and_name_for_search_pattern(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * service_search_pattern){ 410 if (!sdp_client_ready()) return SDP_QUERY_BUSY; 411 sdp_client_rfcomm_match_serviceclass = false; 412 return sdp_client_query_rfcomm(callback, remote, service_search_pattern); 413 } 414