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