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