1 /****************************************************************************** 2 * 3 * Copyright (C) 2014 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * This file contains action functions for SDP search. 21 ******************************************************************************/ 22 23 #include <arpa/inet.h> 24 #include <hardware/bluetooth.h> 25 #include <hardware/bt_sdp.h> 26 #include <stdlib.h> 27 #include <string.h> 28 29 #include "bt_common.h" 30 #include "bt_types.h" 31 #include "bta_api.h" 32 #include "bta_sdp_api.h" 33 #include "bta_sdp_int.h" 34 #include "bta_sys.h" 35 #include "btm_api.h" 36 #include "btm_int.h" 37 #include "osi/include/allocator.h" 38 #include "sdp_api.h" 39 #include "utl.h" 40 41 /***************************************************************************** 42 * Constants 43 ****************************************************************************/ 44 45 static const uint8_t UUID_OBEX_OBJECT_PUSH[] = { 46 0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00, 47 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 48 static const uint8_t UUID_PBAP_PSE[] = {0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 49 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 50 0x5F, 0x9B, 0x34, 0xFB}; 51 static const uint8_t UUID_MAP_MAS[] = {0x00, 0x00, 0x11, 0x32, 0x00, 0x00, 52 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 53 0x5F, 0x9B, 0x34, 0xFB}; 54 static const uint8_t UUID_MAP_MNS[] = {0x00, 0x00, 0x11, 0x33, 0x00, 0x00, 55 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 56 0x5F, 0x9B, 0x34, 0xFB}; 57 static const uint8_t UUID_SAP[] = {0x00, 0x00, 0x11, 0x2D, 0x00, 0x00, 58 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 59 0x5F, 0x9B, 0x34, 0xFB}; 60 // TODO: 61 // Both the fact that the UUIDs are declared in multiple places, plus the fact 62 // that there is a mess of UUID comparison and shortening methods will have to 63 // be fixed. 64 // The btcore->uuid module should be used for all instances. 65 66 #define UUID_MAX_LENGTH 16 67 #define IS_UUID(u1, u2) !memcmp(u1, u2, UUID_MAX_LENGTH) 68 69 static inline tBT_UUID shorten_sdp_uuid(const tBT_UUID* u) { 70 static uint8_t bt_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 71 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 72 0x5F, 0x9B, 0x34, 0xFB}; 73 74 APPL_TRACE_DEBUG("%s() - uuid len:%d", __func__, u->len); 75 if (u->len != 16) return *u; 76 77 if (memcmp(&u->uu.uuid128[4], &bt_base_uuid[4], 12) != 0) return *u; 78 79 tBT_UUID su; 80 memset(&su, 0, sizeof(su)); 81 if (u->uu.uuid128[0] == 0 && u->uu.uuid128[1] == 0) { 82 su.len = 2; 83 uint16_t u16; 84 memcpy(&u16, &u->uu.uuid128[2], sizeof(u16)); 85 su.uu.uuid16 = ntohs(u16); 86 } else { 87 su.len = 4; 88 uint32_t u32; 89 memcpy(&u32, &u->uu.uuid128[0], sizeof(u32)); 90 su.uu.uuid32 = ntohl(u32); 91 } 92 return su; 93 } 94 95 static void bta_create_mns_sdp_record(bluetooth_sdp_record* record, 96 tSDP_DISC_REC* p_rec) { 97 tSDP_DISC_ATTR* p_attr; 98 tSDP_PROTOCOL_ELEM pe; 99 uint16_t pversion = 0; 100 record->mns.hdr.type = SDP_TYPE_MAP_MNS; 101 record->mns.hdr.service_name_length = 0; 102 record->mns.hdr.service_name = NULL; 103 record->mns.hdr.rfcomm_channel_number = 0; 104 record->mns.hdr.l2cap_psm = -1; 105 record->mns.hdr.profile_version = 0; 106 record->mns.supported_features = 0x0000001F; // default value if not found 107 108 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES); 109 if (p_attr != NULL) { 110 record->mns.supported_features = p_attr->attr_value.v.u32; 111 } 112 113 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME); 114 if (p_attr != NULL) { 115 record->mns.hdr.service_name_length = 116 SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 117 record->mns.hdr.service_name = (char*)p_attr->attr_value.v.array; 118 } 119 120 if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE, 121 &pversion)) { 122 record->mns.hdr.profile_version = pversion; 123 } 124 125 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) { 126 record->mns.hdr.rfcomm_channel_number = pe.params[0]; 127 } 128 129 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM); 130 if (p_attr != NULL) { 131 record->mns.hdr.l2cap_psm = p_attr->attr_value.v.u16; 132 } 133 } 134 135 static void bta_create_mas_sdp_record(bluetooth_sdp_record* record, 136 tSDP_DISC_REC* p_rec) { 137 tSDP_DISC_ATTR* p_attr; 138 tSDP_PROTOCOL_ELEM pe; 139 uint16_t pversion = -1; 140 141 record->mas.hdr.type = SDP_TYPE_MAP_MAS; 142 record->mas.hdr.service_name_length = 0; 143 record->mas.hdr.service_name = NULL; 144 record->mas.hdr.rfcomm_channel_number = 0; 145 record->mas.hdr.l2cap_psm = -1; 146 record->mas.hdr.profile_version = 0; 147 record->mas.mas_instance_id = 0; 148 record->mas.supported_features = 0x0000001F; 149 record->mas.supported_message_types = 0; 150 151 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAS_INSTANCE_ID); 152 if (p_attr != NULL) { 153 record->mas.mas_instance_id = p_attr->attr_value.v.u8; 154 } 155 156 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_MSG_TYPE); 157 if (p_attr != NULL) { 158 record->mas.supported_message_types = p_attr->attr_value.v.u8; 159 } 160 161 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES); 162 if (p_attr != NULL) { 163 record->mas.supported_features = p_attr->attr_value.v.u32; 164 } 165 166 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME); 167 if (p_attr != NULL) { 168 record->mas.hdr.service_name_length = 169 SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 170 record->mas.hdr.service_name = (char*)p_attr->attr_value.v.array; 171 } 172 173 if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE, 174 &pversion)) { 175 record->mas.hdr.profile_version = pversion; 176 } 177 178 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) { 179 record->mas.hdr.rfcomm_channel_number = pe.params[0]; 180 } 181 182 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM); 183 if (p_attr != NULL) { 184 record->mas.hdr.l2cap_psm = p_attr->attr_value.v.u16; 185 } 186 } 187 188 static void bta_create_pse_sdp_record(bluetooth_sdp_record* record, 189 tSDP_DISC_REC* p_rec) { 190 tSDP_DISC_ATTR* p_attr; 191 uint16_t pversion; 192 tSDP_PROTOCOL_ELEM pe; 193 194 record->pse.hdr.type = SDP_TYPE_PBAP_PSE; 195 record->pse.hdr.service_name_length = 0; 196 record->pse.hdr.service_name = NULL; 197 record->pse.hdr.rfcomm_channel_number = 0; 198 record->pse.hdr.l2cap_psm = -1; 199 record->pse.hdr.profile_version = 0; 200 record->pse.supported_features = 0x00000003; 201 record->pse.supported_repositories = 0; 202 203 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_REPOSITORIES); 204 if (p_attr != NULL) { 205 record->pse.supported_repositories = p_attr->attr_value.v.u8; 206 } 207 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES); 208 if (p_attr != NULL) { 209 record->pse.supported_features = p_attr->attr_value.v.u32; 210 } 211 212 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME); 213 if (p_attr != NULL) { 214 record->pse.hdr.service_name_length = 215 SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 216 record->pse.hdr.service_name = (char*)p_attr->attr_value.v.array; 217 } 218 219 if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PHONE_ACCESS, 220 &pversion)) { 221 record->pse.hdr.profile_version = pversion; 222 } 223 224 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) { 225 record->pse.hdr.rfcomm_channel_number = pe.params[0]; 226 } 227 228 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM); 229 if (p_attr != NULL) { 230 record->pse.hdr.l2cap_psm = p_attr->attr_value.v.u16; 231 } 232 } 233 234 static void bta_create_ops_sdp_record(bluetooth_sdp_record* record, 235 tSDP_DISC_REC* p_rec) { 236 tSDP_DISC_ATTR *p_attr, *p_sattr; 237 tSDP_PROTOCOL_ELEM pe; 238 uint16_t pversion = -1; 239 240 record->ops.hdr.type = SDP_TYPE_OPP_SERVER; 241 record->ops.hdr.service_name_length = 0; 242 record->ops.hdr.service_name = NULL; 243 record->ops.hdr.rfcomm_channel_number = 0; 244 record->ops.hdr.l2cap_psm = -1; 245 record->ops.hdr.profile_version = 0; 246 record->ops.supported_formats_list_len = 0; 247 248 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME); 249 if (p_attr != NULL) { 250 record->ops.hdr.service_name_length = 251 SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 252 record->ops.hdr.service_name = (char*)p_attr->attr_value.v.array; 253 } 254 255 if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_OBEX_OBJECT_PUSH, 256 &pversion)) { 257 record->ops.hdr.profile_version = pversion; 258 } 259 260 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) { 261 record->ops.hdr.rfcomm_channel_number = pe.params[0]; 262 } 263 264 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM); 265 if (p_attr != NULL) { 266 record->ops.hdr.l2cap_psm = p_attr->attr_value.v.u16; 267 } 268 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FORMATS_LIST); 269 if (p_attr != NULL) { 270 /* Safety check - each entry should itself be a sequence */ 271 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) { 272 record->ops.supported_formats_list_len = 0; 273 APPL_TRACE_ERROR( 274 "%s() - supported_formats_list - wrong attribute length/type:" 275 " 0x%02x - expected 0x06", 276 __func__, p_attr->attr_len_type); 277 } else { 278 int count = 0; 279 /* 1 byte for type/length 1 byte for value */ 280 record->ops.supported_formats_list_len = 281 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) / 2; 282 283 /* Extract each value into */ 284 for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr != NULL; 285 p_sattr = p_sattr->p_next_attr) { 286 if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UINT_DESC_TYPE) && 287 (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 1)) { 288 if (count == sizeof(record->ops.supported_formats_list)) { 289 APPL_TRACE_ERROR( 290 "%s() - supported_formats_list - count overflow - " 291 "too many sub attributes!!", 292 __func__); 293 /* If you hit this, new formats have been added, 294 * update SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH */ 295 break; 296 } 297 record->ops.supported_formats_list[count] = p_sattr->attr_value.v.u8; 298 count++; 299 } else { 300 APPL_TRACE_ERROR( 301 "%s() - supported_formats_list - wrong sub attribute " 302 "length/type: 0x%02x - expected 0x80", 303 __func__, p_sattr->attr_len_type); 304 break; 305 } 306 } 307 if (record->ops.supported_formats_list_len != count) { 308 APPL_TRACE_WARNING( 309 "%s() - supported_formats_list - Length of attribute different " 310 "from the actual number of sub-attributes in the sequence " 311 "att-length: %d - number of elements: %d", 312 __func__, record->ops.supported_formats_list_len, count); 313 } 314 record->ops.supported_formats_list_len = count; 315 } 316 } 317 } 318 319 static void bta_create_sap_sdp_record(bluetooth_sdp_record* record, 320 tSDP_DISC_REC* p_rec) { 321 tSDP_DISC_ATTR* p_attr; 322 tSDP_PROTOCOL_ELEM pe; 323 uint16_t pversion = -1; 324 325 record->sap.hdr.type = SDP_TYPE_MAP_MAS; 326 record->sap.hdr.service_name_length = 0; 327 record->sap.hdr.service_name = NULL; 328 record->sap.hdr.rfcomm_channel_number = 0; 329 record->sap.hdr.l2cap_psm = -1; 330 record->sap.hdr.profile_version = 0; 331 332 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME); 333 if (p_attr != NULL) { 334 record->sap.hdr.service_name_length = 335 SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 336 record->sap.hdr.service_name = (char*)p_attr->attr_value.v.array; 337 } 338 339 if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_SAP, &pversion)) { 340 record->sap.hdr.profile_version = pversion; 341 } 342 343 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) { 344 record->sap.hdr.rfcomm_channel_number = pe.params[0]; 345 } 346 } 347 348 static void bta_create_raw_sdp_record(bluetooth_sdp_record* record, 349 tSDP_DISC_REC* p_rec) { 350 tSDP_DISC_ATTR* p_attr; 351 tSDP_PROTOCOL_ELEM pe; 352 353 record->hdr.type = SDP_TYPE_RAW; 354 record->hdr.service_name_length = 0; 355 record->hdr.service_name = NULL; 356 record->hdr.rfcomm_channel_number = -1; 357 record->hdr.l2cap_psm = -1; 358 record->hdr.profile_version = -1; 359 360 /* Try to extract a service name */ 361 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME); 362 if (p_attr != NULL) { 363 record->pse.hdr.service_name_length = 364 SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 365 record->pse.hdr.service_name = (char*)p_attr->attr_value.v.array; 366 } 367 368 /* Try to extract an RFCOMM channel */ 369 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) { 370 record->pse.hdr.rfcomm_channel_number = pe.params[0]; 371 } 372 record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size; 373 record->hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data; 374 } 375 376 /******************************************************************************* 377 * 378 * Function bta_sdp_search_cback 379 * 380 * Description Callback from btm after search is completed 381 * 382 * Returns void 383 * 384 ******************************************************************************/ 385 static void bta_sdp_search_cback(uint16_t result, void* user_data) { 386 tSDP_DISC_REC* p_rec = NULL; 387 tBTA_SDP_SEARCH_COMP evt_data; 388 tBTA_SDP_STATUS status = BTA_SDP_FAILURE; 389 int count = 0; 390 tBT_UUID su; 391 APPL_TRACE_DEBUG("%s() - res: 0x%x", __func__, result); 392 393 memset(&evt_data, 0, sizeof(evt_data)); 394 bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE; 395 396 if (bta_sdp_cb.p_dm_cback == NULL) return; 397 398 bdcpy(evt_data.remote_addr, bta_sdp_cb.remote_addr); 399 tBT_UUID* uuid = (tBT_UUID*)user_data; 400 memcpy(&evt_data.uuid, uuid, sizeof(tBT_UUID)); 401 su = shorten_sdp_uuid(uuid); 402 403 if (result == SDP_SUCCESS || result == SDP_DB_FULL) { 404 do { 405 p_rec = SDP_FindServiceUUIDInDb(p_bta_sdp_cfg->p_sdp_db, &su, p_rec); 406 /* generate the matching record data pointer */ 407 if (p_rec != NULL) { 408 status = BTA_SDP_SUCCESS; 409 if (IS_UUID(UUID_MAP_MAS, uuid->uu.uuid128)) { 410 APPL_TRACE_DEBUG("%s() - found MAP (MAS) uuid", __func__); 411 bta_create_mas_sdp_record(&evt_data.records[count], p_rec); 412 } else if (IS_UUID(UUID_MAP_MNS, uuid->uu.uuid128)) { 413 APPL_TRACE_DEBUG("%s() - found MAP (MNS) uuid", __func__); 414 bta_create_mns_sdp_record(&evt_data.records[count], p_rec); 415 } else if (IS_UUID(UUID_PBAP_PSE, uuid->uu.uuid128)) { 416 APPL_TRACE_DEBUG("%s() - found PBAP (PSE) uuid", __func__); 417 bta_create_pse_sdp_record(&evt_data.records[count], p_rec); 418 } else if (IS_UUID(UUID_OBEX_OBJECT_PUSH, uuid->uu.uuid128)) { 419 APPL_TRACE_DEBUG("%s() - found Object Push Server (OPS) uuid", 420 __func__); 421 bta_create_ops_sdp_record(&evt_data.records[count], p_rec); 422 } else if (IS_UUID(UUID_SAP, uuid->uu.uuid128)) { 423 APPL_TRACE_DEBUG("%s() - found SAP uuid", __func__); 424 bta_create_sap_sdp_record(&evt_data.records[count], p_rec); 425 } else { 426 /* we do not have specific structure for this */ 427 APPL_TRACE_DEBUG("%s() - profile not identified. using raw data", 428 __func__); 429 bta_create_raw_sdp_record(&evt_data.records[count], p_rec); 430 p_rec = NULL; // Terminate loop 431 /* For raw, we only extract the first entry, and then return the 432 entire 433 raw data chunk. 434 TODO: Find a way to split the raw data into record chunks, and 435 iterate 436 to extract generic data for each chunk - e.g. rfcomm channel 437 and 438 service name. */ 439 } 440 count++; 441 } else { 442 APPL_TRACE_DEBUG("%s() - UUID not found", __func__); 443 } 444 } while (p_rec != NULL && count < BTA_SDP_MAX_RECORDS); 445 446 evt_data.record_count = count; 447 } 448 evt_data.status = status; 449 450 bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP*)&evt_data, 451 (void*)&uuid->uu.uuid128); 452 osi_free(user_data); // We no longer need the user data to track the search 453 } 454 455 /******************************************************************************* 456 * 457 * Function bta_sdp_enable 458 * 459 * Description Initializes the SDP I/F 460 * 461 * Returns void 462 * 463 ******************************************************************************/ 464 void bta_sdp_enable(tBTA_SDP_MSG* p_data) { 465 APPL_TRACE_DEBUG("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active); 466 tBTA_SDP_STATUS status = BTA_SDP_SUCCESS; 467 bta_sdp_cb.p_dm_cback = p_data->enable.p_cback; 468 bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, (tBTA_SDP*)&status, NULL); 469 } 470 471 /******************************************************************************* 472 * 473 * Function bta_sdp_search 474 * 475 * Description Discovers all sdp records for an uuid on remote device 476 * 477 * Returns void 478 * 479 ******************************************************************************/ 480 void bta_sdp_search(tBTA_SDP_MSG* p_data) { 481 if (p_data == NULL) { 482 APPL_TRACE_DEBUG("SDP control block handle is null"); 483 return; 484 } 485 tBTA_SDP_STATUS status = BTA_SDP_FAILURE; 486 487 APPL_TRACE_DEBUG("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active); 488 489 if (bta_sdp_cb.sdp_active != BTA_SDP_ACTIVE_NONE) { 490 /* SDP is still in progress */ 491 status = BTA_SDP_BUSY; 492 if (bta_sdp_cb.p_dm_cback) { 493 tBTA_SDP_SEARCH_COMP result; 494 memset(&result, 0, sizeof(result)); 495 result.uuid = p_data->get_search.uuid; 496 bdcpy(result.remote_addr, p_data->get_search.bd_addr); 497 result.status = status; 498 bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP*)&result, NULL); 499 } 500 return; 501 } 502 503 bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_YES; 504 bdcpy(bta_sdp_cb.remote_addr, p_data->get_search.bd_addr); 505 /* set the uuid used in the search */ 506 tBT_UUID* bta_sdp_search_uuid = 507 static_cast<tBT_UUID*>(osi_malloc(sizeof(tBT_UUID))); 508 memcpy(bta_sdp_search_uuid, &(p_data->get_search.uuid), sizeof(tBT_UUID)); 509 510 /* initialize the search for the uuid */ 511 APPL_TRACE_DEBUG("%s init discovery with UUID(len: %d):", __func__, 512 bta_sdp_search_uuid->len); 513 for (int x = 0; x < bta_sdp_search_uuid->len; x++) { 514 APPL_TRACE_DEBUG("%X", bta_sdp_search_uuid->uu.uuid128[x]); 515 } 516 SDP_InitDiscoveryDb(p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1, 517 bta_sdp_search_uuid, 0, NULL); 518 519 if (!SDP_ServiceSearchAttributeRequest2( 520 p_data->get_search.bd_addr, p_bta_sdp_cfg->p_sdp_db, 521 bta_sdp_search_cback, (void*)bta_sdp_search_uuid)) { 522 bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE; 523 524 /* failed to start SDP. report the failure right away */ 525 if (bta_sdp_cb.p_dm_cback) { 526 tBTA_SDP_SEARCH_COMP result; 527 memset(&result, 0, sizeof(result)); 528 result.uuid = p_data->get_search.uuid; 529 bdcpy(result.remote_addr, p_data->get_search.bd_addr); 530 result.status = status; 531 bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP*)&result, NULL); 532 } 533 } 534 /* 535 else report the result when the cback is called 536 */ 537 } 538 539 /******************************************************************************* 540 * 541 * Function bta_sdp_record 542 * 543 * Description Discovers all sdp records for an uuid on remote device 544 * 545 * Returns void 546 * 547 ******************************************************************************/ 548 void bta_sdp_create_record(tBTA_SDP_MSG* p_data) { 549 APPL_TRACE_DEBUG("%s() event: %d", __func__, p_data->record.hdr.event); 550 if (bta_sdp_cb.p_dm_cback) 551 bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, NULL, 552 p_data->record.user_data); 553 } 554 555 /******************************************************************************* 556 * 557 * Function bta_sdp_create_record 558 * 559 * Description Discovers all sdp records for an uuid on remote device 560 * 561 * Returns void 562 * 563 ******************************************************************************/ 564 void bta_sdp_remove_record(tBTA_SDP_MSG* p_data) { 565 APPL_TRACE_DEBUG("%s() event: %d", __func__, p_data->record.hdr.event); 566 if (bta_sdp_cb.p_dm_cback) 567 bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, NULL, 568 p_data->record.user_data); 569 } 570