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