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