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