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