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