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