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