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 
shorten_sdp_uuid(const tBT_UUID * u)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 
bta_create_mns_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)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 
bta_create_mas_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)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 
bta_create_pse_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)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 
bta_create_ops_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)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 
bta_create_sap_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)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 
bta_create_raw_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)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  ******************************************************************************/
bta_sdp_search_cback(uint16_t result,void * user_data)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  ******************************************************************************/
bta_sdp_enable(tBTA_SDP_MSG * p_data)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  ******************************************************************************/
bta_sdp_search(tBTA_SDP_MSG * p_data)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  ******************************************************************************/
bta_sdp_create_record(tBTA_SDP_MSG * p_data)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  ******************************************************************************/
bta_sdp_remove_record(tBTA_SDP_MSG * p_data)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