• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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