1 /******************************************************************************
2 *
3 * Copyright 2014 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 * This file contains action functions for SDP search.
21 ******************************************************************************/
22
23 #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
24 #include <hardware/bt_sdp.h>
25
26 #include <cstdint>
27
28 #include "bta/include/bta_sdp_api.h"
29 #include "bta/sdp/bta_sdp_int.h"
30 #include "btif/include/btif_profile_storage.h"
31 #include "btif/include/btif_sock_sdp.h"
32 #include "main/shim/metrics_api.h"
33 #include "osi/include/allocator.h"
34 #include "stack/include/sdp_api.h"
35 #include "types/bluetooth/uuid.h"
36 #include "types/raw_address.h"
37
bta_create_mns_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)38 static void bta_create_mns_sdp_record(bluetooth_sdp_record* record,
39 tSDP_DISC_REC* p_rec) {
40 tSDP_DISC_ATTR* p_attr;
41 tSDP_PROTOCOL_ELEM pe;
42 uint16_t pversion = 0;
43 record->mns.hdr.type = SDP_TYPE_MAP_MNS;
44 record->mns.hdr.service_name_length = 0;
45 record->mns.hdr.service_name = NULL;
46 record->mns.hdr.rfcomm_channel_number = 0;
47 record->mns.hdr.l2cap_psm = -1;
48 record->mns.hdr.profile_version = 0;
49 record->mns.supported_features = 0x0000001F; // default value if not found
50
51 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES);
52 if (p_attr != NULL) {
53 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
54 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 4) {
55 record->mns.supported_features = p_attr->attr_value.v.u32;
56 } else {
57 LOG_ERROR("ATTR_ID_MAP_SUPPORTED_FEATURES attr type or size wrong!!");
58 }
59 } else {
60 LOG_ERROR("ATTR_ID_MAP_SUPPORTED_FEATURES attr not found!!");
61 }
62
63 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
64 if (p_attr != NULL) {
65 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
66 record->mns.hdr.service_name_length =
67 SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
68 record->mns.hdr.service_name = (char*)p_attr->attr_value.v.array;
69 } else {
70 LOG_ERROR("ATTR_ID_SERVICE_NAME attr type not TEXT_STR_DESC_TYPE!!");
71 }
72 } else {
73 LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!");
74 }
75
76 if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE,
77 &pversion)) {
78 record->mns.hdr.profile_version = pversion;
79 }
80
81 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
82 record->mns.hdr.rfcomm_channel_number = pe.params[0];
83 }
84
85 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
86 if (p_attr != NULL) {
87 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
88 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
89 record->mns.hdr.l2cap_psm = p_attr->attr_value.v.u16;
90 } else {
91 LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!");
92 }
93 } else {
94 LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr not found!!");
95 }
96 }
97
bta_create_mas_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)98 static void bta_create_mas_sdp_record(bluetooth_sdp_record* record,
99 tSDP_DISC_REC* p_rec) {
100 tSDP_DISC_ATTR* p_attr;
101 tSDP_PROTOCOL_ELEM pe;
102 uint16_t pversion = -1;
103
104 record->mas.hdr.type = SDP_TYPE_MAP_MAS;
105 record->mas.hdr.service_name_length = 0;
106 record->mas.hdr.service_name = NULL;
107 record->mas.hdr.rfcomm_channel_number = 0;
108 record->mas.hdr.l2cap_psm = -1;
109 record->mas.hdr.profile_version = 0;
110 record->mas.mas_instance_id = 0;
111 record->mas.supported_features = 0x0000001F;
112 record->mas.supported_message_types = 0;
113
114 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAS_INSTANCE_ID);
115 if (p_attr != NULL) {
116 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
117 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) {
118 record->mas.mas_instance_id = p_attr->attr_value.v.u8;
119 } else {
120 LOG_ERROR("ATTR_ID_MAS_INSTANCE_ID attr type or len wrong!!");
121 }
122 } else {
123 LOG_ERROR("ATTR_ID_MAS_INSTANCE_ID attr not found!!");
124 }
125
126 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_MSG_TYPE);
127 if (p_attr != NULL) {
128 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
129 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) {
130 record->mas.supported_message_types = p_attr->attr_value.v.u8;
131 } else {
132 LOG_ERROR("ATTR_ID_SUPPORTED_MSG_TYPE attr type or len wrong!!");
133 }
134 } else {
135 LOG_ERROR("ATTR_ID_SUPPORTED_MSG_TYPE attr not found!!");
136 }
137
138 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES);
139 if (p_attr != NULL) {
140 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
141 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 4) {
142 record->mas.supported_features = p_attr->attr_value.v.u32;
143 } else {
144 LOG_ERROR("ATTR_ID_MAP_SUPPORTED_FEATURES attr type or len wrong!!");
145 }
146 } else {
147 LOG_ERROR("ATTR_ID_MAP_SUPPORTED_FEATURES attr not found!!");
148 }
149
150 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
151 if (p_attr != NULL) {
152 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
153 record->mas.hdr.service_name_length =
154 SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
155 record->mas.hdr.service_name = (char*)p_attr->attr_value.v.array;
156 } else {
157 LOG_ERROR("ATTR_ID_SERVICE_NAME attr type wrong!!");
158 }
159 } else {
160 LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!");
161 }
162
163 if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE,
164 &pversion)) {
165 record->mas.hdr.profile_version = pversion;
166 }
167
168 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
169 record->mas.hdr.rfcomm_channel_number = pe.params[0];
170 }
171
172 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
173 if (p_attr != NULL) {
174 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
175 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
176 record->mas.hdr.l2cap_psm = p_attr->attr_value.v.u16;
177 } else {
178 LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!");
179 }
180 } else {
181 LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr not found!!");
182 }
183 }
184
bta_create_pse_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)185 static void bta_create_pse_sdp_record(bluetooth_sdp_record* record,
186 tSDP_DISC_REC* p_rec) {
187 tSDP_DISC_ATTR* p_attr;
188 uint16_t pversion;
189 tSDP_PROTOCOL_ELEM pe;
190
191 record->pse.hdr.type = SDP_TYPE_PBAP_PSE;
192 record->pse.hdr.service_name_length = 0;
193 record->pse.hdr.service_name = NULL;
194 record->pse.hdr.rfcomm_channel_number = 0;
195 record->pse.hdr.l2cap_psm = -1;
196 record->pse.hdr.profile_version = 0;
197 record->pse.supported_features = 0x00000003;
198 record->pse.supported_repositories = 0;
199
200 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_REPOSITORIES);
201 if (p_attr != NULL) {
202 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
203 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) {
204 record->pse.supported_repositories = p_attr->attr_value.v.u8;
205 } else {
206 LOG_ERROR("ATTR_ID_SUPPORTED_REPOSITORIES attr type or len wrong!!");
207 }
208 } else {
209 LOG_ERROR("ATTR_ID_SUPPORTED_REPOSITORIES attr not found!!");
210 }
211 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES);
212 if (p_attr != NULL) {
213 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
214 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 4) {
215 record->pse.supported_features = p_attr->attr_value.v.u32;
216 } else {
217 LOG_ERROR("ATTR_ID_PBAP_SUPPORTED_FEATURES attr type or len wrong!!");
218 }
219 } else {
220 LOG_ERROR("ATTR_ID_PBAP_SUPPORTED_FEATURES attr not found!!");
221 }
222
223 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
224 if (p_attr != NULL) {
225 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
226 record->pse.hdr.service_name_length =
227 SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
228 // TODO: validate the lifetime of this value
229 record->pse.hdr.service_name = (char*)p_attr->attr_value.v.array;
230 } else {
231 LOG_ERROR("ATTR_ID_SERVICE_NAME attr type NOT string!!");
232 }
233 } else {
234 LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!");
235 }
236
237 if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PHONE_ACCESS,
238 &pversion)) {
239 record->pse.hdr.profile_version = pversion;
240 }
241
242 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
243 record->pse.hdr.rfcomm_channel_number = pe.params[0];
244 }
245
246 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
247 if (p_attr != NULL) {
248 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
249 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
250 record->pse.hdr.l2cap_psm = p_attr->attr_value.v.u16;
251 } else {
252 LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!");
253 }
254 } else {
255 LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr not found!!");
256 }
257 }
258
bta_create_ops_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)259 static void bta_create_ops_sdp_record(bluetooth_sdp_record* record,
260 tSDP_DISC_REC* p_rec) {
261 tSDP_DISC_ATTR *p_attr, *p_sattr;
262 tSDP_PROTOCOL_ELEM pe;
263 uint16_t pversion = -1;
264
265 record->ops.hdr.type = SDP_TYPE_OPP_SERVER;
266 record->ops.hdr.service_name_length = 0;
267 record->ops.hdr.service_name = NULL;
268 record->ops.hdr.rfcomm_channel_number = 0;
269 record->ops.hdr.l2cap_psm = -1;
270 record->ops.hdr.profile_version = 0;
271 record->ops.supported_formats_list_len = 0;
272
273 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
274 if (p_attr != NULL) {
275 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
276 record->ops.hdr.service_name_length =
277 SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
278 record->ops.hdr.service_name = (char*)p_attr->attr_value.v.array;
279 } else {
280 LOG_ERROR("ATTR_ID_SERVICE_NAME attr type NOT string!!");
281 }
282 } else {
283 LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!");
284 }
285
286 if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_OBEX_OBJECT_PUSH,
287 &pversion)) {
288 record->ops.hdr.profile_version = pversion;
289 }
290
291 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
292 record->ops.hdr.rfcomm_channel_number = pe.params[0];
293 }
294
295 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
296 if (p_attr != NULL) {
297 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
298 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
299 record->ops.hdr.l2cap_psm = p_attr->attr_value.v.u16;
300 } else {
301 LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!");
302 }
303 } else {
304 LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr not found!!");
305 }
306
307 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FORMATS_LIST);
308 if (p_attr != NULL) {
309 /* Safety check - each entry should itself be a sequence */
310 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) {
311 record->ops.supported_formats_list_len = 0;
312 APPL_TRACE_ERROR(
313 "%s() - supported_formats_list - wrong attribute length/type:"
314 " 0x%02x - expected 0x06",
315 __func__, p_attr->attr_len_type);
316 } else {
317 int count = 0;
318 /* 1 byte for type/length 1 byte for value */
319 record->ops.supported_formats_list_len =
320 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) / 2;
321
322 /* Extract each value into */
323 for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr != NULL;
324 p_sattr = p_sattr->p_next_attr) {
325 if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UINT_DESC_TYPE) &&
326 (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) >= 1)) {
327 if (count == sizeof(record->ops.supported_formats_list)) {
328 APPL_TRACE_ERROR(
329 "%s() - supported_formats_list - count overflow - "
330 "too many sub attributes!!",
331 __func__);
332 /* If you hit this, new formats have been added,
333 * update SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH */
334 break;
335 }
336 record->ops.supported_formats_list[count] = p_sattr->attr_value.v.u8;
337 count++;
338 } else {
339 APPL_TRACE_ERROR(
340 "%s() - supported_formats_list - wrong sub attribute "
341 "length/type: 0x%02x - expected 0x80",
342 __func__, p_sattr->attr_len_type);
343 break;
344 }
345 }
346 if (record->ops.supported_formats_list_len != count) {
347 APPL_TRACE_WARNING(
348 "%s() - supported_formats_list - Length of attribute different "
349 "from the actual number of sub-attributes in the sequence "
350 "att-length: %d - number of elements: %d",
351 __func__, record->ops.supported_formats_list_len, count);
352 }
353 record->ops.supported_formats_list_len = count;
354 }
355 }
356 }
357
bta_create_sap_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)358 static void bta_create_sap_sdp_record(bluetooth_sdp_record* record,
359 tSDP_DISC_REC* p_rec) {
360 tSDP_DISC_ATTR* p_attr;
361 tSDP_PROTOCOL_ELEM pe;
362 uint16_t pversion = -1;
363
364 record->sap.hdr.type = SDP_TYPE_MAP_MAS;
365 record->sap.hdr.service_name_length = 0;
366 record->sap.hdr.service_name = NULL;
367 record->sap.hdr.rfcomm_channel_number = 0;
368 record->sap.hdr.l2cap_psm = -1;
369 record->sap.hdr.profile_version = 0;
370
371 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
372 if (p_attr != NULL) {
373 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
374 record->sap.hdr.service_name_length =
375 SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
376 record->sap.hdr.service_name = (char*)p_attr->attr_value.v.array;
377 } else {
378 LOG_ERROR("ATTR_ID_SERVICE_NAME attr type NOT string!!");
379 }
380 } else {
381 LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!");
382 }
383
384 if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_SAP, &pversion)) {
385 record->sap.hdr.profile_version = pversion;
386 }
387
388 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
389 record->sap.hdr.rfcomm_channel_number = pe.params[0];
390 }
391 }
392
bta_create_dip_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)393 static void bta_create_dip_sdp_record(bluetooth_sdp_record* record,
394 tSDP_DISC_REC* p_rec) {
395 tSDP_DISC_ATTR* p_attr;
396
397 APPL_TRACE_DEBUG("%s()", __func__);
398
399 /* hdr is redundancy in dip */
400 record->dip.hdr.type = SDP_TYPE_DIP;
401 record->dip.hdr.service_name_length = 0;
402 record->dip.hdr.service_name = nullptr;
403 record->dip.hdr.rfcomm_channel_number = 0;
404 record->dip.hdr.l2cap_psm = -1;
405 record->dip.hdr.profile_version = 0;
406
407 p_attr =
408 SDP_FindAttributeInRec(p_rec, ATTR_ID_SPECIFICATION_ID);
409 if (p_attr != nullptr) {
410 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
411 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
412 record->dip.spec_id = p_attr->attr_value.v.u16;
413 } else {
414 LOG_ERROR("ATTR_ID_SPECIFICATION_ID attr type or len wrong!!");
415 }
416 } else {
417 APPL_TRACE_ERROR("%s() ATTR_ID_SPECIFICATION_ID not found", __func__);
418 }
419
420 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_VENDOR_ID);
421 if (p_attr != nullptr) {
422 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
423 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
424 record->dip.vendor = p_attr->attr_value.v.u16;
425 } else {
426 LOG_ERROR("ATTR_ID_VENDOR_ID attr type or len wrong!!");
427 }
428 } else {
429 APPL_TRACE_ERROR("%s() ATTR_ID_VENDOR_ID not found", __func__);
430 }
431
432 p_attr =
433 SDP_FindAttributeInRec(p_rec, ATTR_ID_VENDOR_ID_SOURCE);
434 if (p_attr != nullptr) {
435 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
436 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
437 record->dip.vendor_id_source = p_attr->attr_value.v.u16;
438 } else {
439 LOG_ERROR("ATTR_ID_VENDOR_ID_SOURCE attr type or len wrong!!");
440 }
441 } else {
442 APPL_TRACE_ERROR("%s() ATTR_ID_VENDOR_ID_SOURCE not found", __func__);
443 }
444
445 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_ID);
446 if (p_attr != nullptr) {
447 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
448 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
449 record->dip.product = p_attr->attr_value.v.u16;
450 } else {
451 LOG_ERROR("ATTR_ID_PRODUCT_ID attr type or len wrong!!");
452 }
453 } else {
454 APPL_TRACE_ERROR("%s() ATTR_ID_PRODUCT_ID not found", __func__);
455 }
456
457 p_attr =
458 SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_VERSION);
459
460 if (p_attr != nullptr) {
461 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
462 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
463 record->dip.version = p_attr->attr_value.v.u16;
464 } else {
465 LOG_ERROR("ATTR_ID_PRODUCT_VERSION attr type or len wrong!!");
466 }
467 } else {
468 APPL_TRACE_ERROR("%s() ATTR_ID_PRODUCT_VERSION not found", __func__);
469 }
470
471 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRIMARY_RECORD);
472 if (p_attr != nullptr) {
473 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == BOOLEAN_DESC_TYPE &&
474 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) {
475 record->dip.primary_record = !(!p_attr->attr_value.v.u8);
476 } else {
477 LOG_ERROR("ATTR_ID_PRIMARY_RECORD attr type or len wrong!!");
478 }
479 } else {
480 APPL_TRACE_ERROR("%s() ATTR_ID_PRIMARY_RECORD not found", __func__);
481 }
482 }
483
bta_create_raw_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)484 static void bta_create_raw_sdp_record(bluetooth_sdp_record* record,
485 tSDP_DISC_REC* p_rec) {
486 tSDP_DISC_ATTR* p_attr;
487 tSDP_PROTOCOL_ELEM pe;
488
489 record->hdr.type = SDP_TYPE_RAW;
490 record->hdr.service_name_length = 0;
491 record->hdr.service_name = NULL;
492 record->hdr.rfcomm_channel_number = -1;
493 record->hdr.l2cap_psm = -1;
494 record->hdr.profile_version = -1;
495
496 /* Try to extract a service name */
497 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
498 if (p_attr != NULL) {
499 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
500 record->pse.hdr.service_name_length =
501 SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
502 record->pse.hdr.service_name = (char*)p_attr->attr_value.v.array;
503 } else {
504 LOG_ERROR("ATTR_ID_SERVICE_NAME attr type NOT string!!");
505 }
506 } else {
507 LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!");
508 }
509
510 /* Try to extract an RFCOMM channel */
511 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
512 record->pse.hdr.rfcomm_channel_number = pe.params[0];
513 }
514 record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size;
515 record->hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data;
516 }
517
518 /** Callback from btm after search is completed */
bta_sdp_search_cback(tSDP_RESULT result,const void * user_data)519 static void bta_sdp_search_cback(tSDP_RESULT result, const void* user_data) {
520 tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
521 int count = 0;
522 APPL_TRACE_DEBUG("%s() - res: 0x%x", __func__, result);
523
524 bta_sdp_cb.sdp_active = false;
525
526 if (bta_sdp_cb.p_dm_cback == NULL) return;
527
528 Uuid& uuid = *(reinterpret_cast<Uuid*>(const_cast<void*>(user_data)));
529
530 tBTA_SDP_SEARCH_COMP evt_data;
531 memset(&evt_data, 0, sizeof(evt_data));
532 evt_data.remote_addr = bta_sdp_cb.remote_addr;
533 evt_data.uuid = uuid;
534
535 if (result == SDP_SUCCESS || result == SDP_DB_FULL) {
536 tSDP_DISC_REC* p_rec = NULL;
537 do {
538 p_rec = SDP_FindServiceUUIDInDb(p_bta_sdp_cfg->p_sdp_db, uuid, p_rec);
539 /* generate the matching record data pointer */
540 if (!p_rec) {
541 APPL_TRACE_DEBUG("%s() - UUID not found", __func__);
542 continue;
543 }
544
545 status = BTA_SDP_SUCCESS;
546 if (uuid == UUID_MAP_MAS) {
547 APPL_TRACE_DEBUG("%s() - found MAP (MAS) uuid", __func__);
548 bta_create_mas_sdp_record(&evt_data.records[count], p_rec);
549 } else if (uuid == UUID_MAP_MNS) {
550 APPL_TRACE_DEBUG("%s() - found MAP (MNS) uuid", __func__);
551 bta_create_mns_sdp_record(&evt_data.records[count], p_rec);
552 } else if (uuid == UUID_PBAP_PSE) {
553 APPL_TRACE_DEBUG("%s() - found PBAP (PSE) uuid", __func__);
554 bta_create_pse_sdp_record(&evt_data.records[count], p_rec);
555 } else if (uuid == UUID_OBEX_OBJECT_PUSH) {
556 APPL_TRACE_DEBUG("%s() - found Object Push Server (OPS) uuid",
557 __func__);
558 bta_create_ops_sdp_record(&evt_data.records[count], p_rec);
559 } else if (uuid == UUID_SAP) {
560 APPL_TRACE_DEBUG("%s() - found SAP uuid", __func__);
561 bta_create_sap_sdp_record(&evt_data.records[count], p_rec);
562 } else if (uuid == UUID_PBAP_PCE) {
563 APPL_TRACE_DEBUG("%s() - found PBAP (PCE) uuid", __func__);
564 if (p_rec != NULL) {
565 uint16_t peer_pce_version = 0;
566
567 SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PHONE_ACCESS,
568 &peer_pce_version);
569 if (peer_pce_version != 0) {
570 btif_storage_set_pce_profile_version(p_rec->remote_bd_addr,
571 peer_pce_version);
572 }
573 } else {
574 APPL_TRACE_DEBUG("%s() - PCE Record is null", __func__);
575 }
576 } else if (uuid == UUID_DIP) {
577 APPL_TRACE_DEBUG("%s() - found DIP uuid", __func__);
578 bta_create_dip_sdp_record(&evt_data.records[count], p_rec);
579 } else {
580 /* we do not have specific structure for this */
581 APPL_TRACE_DEBUG("%s() - profile not identified. using raw data",
582 __func__);
583 bta_create_raw_sdp_record(&evt_data.records[count], p_rec);
584 p_rec = NULL; // Terminate loop
585 /* For raw, we only extract the first entry, and then return the
586 entire raw data chunk.
587 TODO: Find a way to split the raw data into record chunks, and
588 iterate to extract generic data for each chunk - e.g. rfcomm
589 channel and service name. */
590 }
591 count++;
592 } while (p_rec != NULL && count < BTA_SDP_MAX_RECORDS);
593
594 evt_data.record_count = count;
595 }
596 evt_data.status = status;
597
598 tBTA_SDP bta_sdp;
599 bta_sdp.sdp_search_comp = evt_data;
600 bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, &bta_sdp, (void*)&uuid);
601 bluetooth::shim::CountCounterMetrics(
602 android::bluetooth::CodePathCounterKeyEnum::SDP_SUCCESS, 1);
603 osi_free(const_cast<void*>(
604 user_data)); // We no longer need the user data to track the search
605 }
606
607 /*******************************************************************************
608 *
609 * Function bta_sdp_enable
610 *
611 * Description Initializes the SDP I/F
612 *
613 * Returns void
614 *
615 ******************************************************************************/
bta_sdp_enable(tBTA_SDP_DM_CBACK * p_cback)616 void bta_sdp_enable(tBTA_SDP_DM_CBACK* p_cback) {
617 APPL_TRACE_DEBUG("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active);
618 tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;
619 bta_sdp_cb.p_dm_cback = p_cback;
620 tBTA_SDP bta_sdp;
621 bta_sdp.status = status;
622 bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, &bta_sdp, NULL);
623 }
624
625 /*******************************************************************************
626 *
627 * Function bta_sdp_search
628 *
629 * Description Discovers all sdp records for an uuid on remote device
630 *
631 * Returns void
632 *
633 ******************************************************************************/
bta_sdp_search(const RawAddress bd_addr,const bluetooth::Uuid uuid)634 void bta_sdp_search(const RawAddress bd_addr, const bluetooth::Uuid uuid) {
635 tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
636
637 APPL_TRACE_DEBUG("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active);
638
639 if (bta_sdp_cb.sdp_active) {
640 /* SDP is still in progress */
641 status = BTA_SDP_BUSY;
642 if (bta_sdp_cb.p_dm_cback) {
643 tBTA_SDP_SEARCH_COMP result;
644 memset(&result, 0, sizeof(result));
645 result.uuid = uuid;
646 result.remote_addr = bd_addr;
647 result.status = status;
648 tBTA_SDP bta_sdp;
649 bta_sdp.sdp_search_comp = result;
650 bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, &bta_sdp, NULL);
651 }
652 return;
653 }
654
655 bta_sdp_cb.sdp_active = true;
656 bta_sdp_cb.remote_addr = bd_addr;
657
658 /* initialize the search for the uuid */
659 APPL_TRACE_DEBUG("%s init discovery with UUID: %s", __func__,
660 uuid.ToString().c_str());
661 SDP_InitDiscoveryDb(p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1,
662 &uuid, 0, NULL);
663
664 Uuid* bta_sdp_search_uuid = (Uuid*)osi_malloc(sizeof(Uuid));
665 *bta_sdp_search_uuid = uuid;
666 if (!SDP_ServiceSearchAttributeRequest2(bd_addr, p_bta_sdp_cfg->p_sdp_db,
667 bta_sdp_search_cback,
668 (void*)bta_sdp_search_uuid)) {
669 bta_sdp_cb.sdp_active = false;
670
671 /* failed to start SDP. report the failure right away */
672 if (bta_sdp_cb.p_dm_cback) {
673 tBTA_SDP_SEARCH_COMP result;
674 memset(&result, 0, sizeof(result));
675 result.uuid = uuid;
676 result.remote_addr = bd_addr;
677 result.status = status;
678 tBTA_SDP bta_sdp;
679 bta_sdp.sdp_search_comp = result;
680 bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, &bta_sdp, NULL);
681 bluetooth::shim::CountCounterMetrics(
682 android::bluetooth::CodePathCounterKeyEnum::SDP_FAILURE, 1);
683 }
684 }
685 /*
686 else report the result when the cback is called
687 */
688 }
689
690 /*******************************************************************************
691 *
692 * Function bta_sdp_record
693 *
694 * Description Discovers all sdp records for an uuid on remote device
695 *
696 * Returns void
697 *
698 ******************************************************************************/
bta_sdp_create_record(void * user_data)699 void bta_sdp_create_record(void* user_data) {
700 if (bta_sdp_cb.p_dm_cback)
701 bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, NULL, user_data);
702 }
703
704 /*******************************************************************************
705 *
706 * Function bta_sdp_create_record
707 *
708 * Description Discovers all sdp records for an uuid on remote device
709 *
710 * Returns void
711 *
712 ******************************************************************************/
bta_sdp_remove_record(void * user_data)713 void bta_sdp_remove_record(void* user_data) {
714 if (bta_sdp_cb.p_dm_cback)
715 bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, NULL, user_data);
716 }
717