1 /******************************************************************************
2 *
3 * Copyright 1999-2012 Broadcom Corporation
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 #define LOG_TAG "SDP_Utils"
20
21 /******************************************************************************
22 *
23 * This file contains SDP utility functions
24 *
25 ******************************************************************************/
26 #include <bluetooth/log.h>
27 #include <com_android_bluetooth_flags.h>
28
29 #include <array>
30 #include <cstdint>
31 #include <cstring>
32 #include <ostream>
33 #include <type_traits>
34 #include <utility>
35 #include <vector>
36
37 #include "btif/include/btif_config.h"
38 #include "btif/include/stack_manager_t.h"
39 #include "common/init_flags.h"
40 #include "device/include/interop.h"
41 #include "internal_include/bt_target.h"
42 #include "internal_include/bt_trace.h"
43 #include "osi/include/allocator.h"
44 #include "osi/include/properties.h"
45 #include "stack/include/avrc_api.h"
46 #include "stack/include/avrc_defs.h"
47 #include "stack/include/bt_hdr.h"
48 #include "stack/include/bt_psm_types.h"
49 #include "stack/include/bt_types.h"
50 #include "stack/include/bt_uuid16.h"
51 #include "stack/include/btm_sec_api_types.h"
52 #include "stack/include/sdpdefs.h"
53 #include "stack/include/stack_metrics_logging.h"
54 #include "stack/sdp/internal/sdp_api.h"
55 #include "stack/sdp/sdpint.h"
56 #include "storage/config_keys.h"
57 #include "types/bluetooth/uuid.h"
58 #include "types/raw_address.h"
59
60 using bluetooth::Uuid;
61 using namespace bluetooth;
62
63 static const uint8_t sdp_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x10, 0x00, 0x80, 0x00, 0x00, 0x80,
65 0x5F, 0x9B, 0x34, 0xFB};
66
67 template <typename T>
to_little_endian_array(T x)68 static std::array<char, sizeof(T)> to_little_endian_array(T x) {
69 static_assert(std::is_integral<T>::value,
70 "to_little_endian_array parameter must be integral.");
71 std::array<char, sizeof(T)> array = {};
72 for (size_t i = 0; i < array.size(); i++) {
73 array[i] = static_cast<char>((x >> (8 * i)) & 0xFF);
74 }
75 return array;
76 }
77
78 /**
79 * Find the list of profile versions from Bluetooth Profile Descriptor list
80 * attribute in a SDP record
81 *
82 * @param p_rec SDP record to search
83 * @return a vector of <UUID, VERSION> pairs, empty if not found
84 */
sdpu_find_profile_version(tSDP_DISC_REC * p_rec)85 static std::vector<std::pair<uint16_t, uint16_t>> sdpu_find_profile_version(
86 tSDP_DISC_REC* p_rec) {
87 std::vector<std::pair<uint16_t, uint16_t>> result;
88 for (tSDP_DISC_ATTR* p_attr = p_rec->p_first_attr; p_attr != nullptr;
89 p_attr = p_attr->p_next_attr) {
90 // Find the profile descriptor list */
91 if (p_attr->attr_id != ATTR_ID_BT_PROFILE_DESC_LIST ||
92 SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) {
93 continue;
94 }
95 // Walk through the protocol descriptor list
96 for (tSDP_DISC_ATTR* p_sattr = p_attr->attr_value.v.p_sub_attr;
97 p_sattr != nullptr; p_sattr = p_sattr->p_next_attr) {
98 // Safety check - each entry should itself be a sequence
99 if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) !=
100 DATA_ELE_SEQ_DESC_TYPE) {
101 log::warn("Descriptor type is not sequence: 0x{:x}",
102 SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type));
103 return std::vector<std::pair<uint16_t, uint16_t>>();
104 }
105 // Now, see if the entry contains the profile UUID we are interested in
106 for (tSDP_DISC_ATTR* p_ssattr = p_sattr->attr_value.v.p_sub_attr;
107 p_ssattr != nullptr; p_ssattr = p_ssattr->p_next_attr) {
108 if (SDP_DISC_ATTR_TYPE(p_ssattr->attr_len_type) != UUID_DESC_TYPE ||
109 SDP_DISC_ATTR_LEN(p_ssattr->attr_len_type) != 2) {
110 continue;
111 }
112 uint16_t uuid = p_ssattr->attr_value.v.u16;
113 // Next attribute should be the version attribute
114 tSDP_DISC_ATTR* version_attr = p_ssattr->p_next_attr;
115 if (version_attr == nullptr ||
116 SDP_DISC_ATTR_TYPE(version_attr->attr_len_type) != UINT_DESC_TYPE ||
117 SDP_DISC_ATTR_LEN(version_attr->attr_len_type) != 2) {
118 if (version_attr == nullptr) {
119 log::warn("version attr not found");
120 } else {
121 log::warn("Bad version type 0x{:x}, or length {}",
122 SDP_DISC_ATTR_TYPE(version_attr->attr_len_type),
123 SDP_DISC_ATTR_LEN(version_attr->attr_len_type));
124 }
125 return std::vector<std::pair<uint16_t, uint16_t>>();
126 }
127 // High order 8 bits is the major number, low order is the
128 // minor number (big endian)
129 uint16_t version = version_attr->attr_value.v.u16;
130 result.emplace_back(uuid, version);
131 }
132 }
133 }
134 return result;
135 }
136
137 /**
138 * Find the most specific 16-bit service uuid represented by a SDP record
139 *
140 * @param p_rec pointer to a SDP record
141 * @return most specific 16-bit service uuid, 0 if not found
142 */
sdpu_find_most_specific_service_uuid(tSDP_DISC_REC * p_rec)143 static uint16_t sdpu_find_most_specific_service_uuid(tSDP_DISC_REC* p_rec) {
144 for (tSDP_DISC_ATTR* p_attr = p_rec->p_first_attr; p_attr != nullptr;
145 p_attr = p_attr->p_next_attr) {
146 if (p_attr->attr_id == ATTR_ID_SERVICE_CLASS_ID_LIST &&
147 SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE) {
148 tSDP_DISC_ATTR* p_first_attr = p_attr->attr_value.v.p_sub_attr;
149 if (p_first_attr == nullptr) {
150 return 0;
151 }
152 if (SDP_DISC_ATTR_TYPE(p_first_attr->attr_len_type) == UUID_DESC_TYPE &&
153 SDP_DISC_ATTR_LEN(p_first_attr->attr_len_type) == 2) {
154 return p_first_attr->attr_value.v.u16;
155 } else if (SDP_DISC_ATTR_TYPE(p_first_attr->attr_len_type) ==
156 DATA_ELE_SEQ_DESC_TYPE) {
157 // Workaround for Toyota G Block car kit:
158 // It incorrectly puts an extra data element sequence in this attribute
159 for (tSDP_DISC_ATTR* p_extra_sattr =
160 p_first_attr->attr_value.v.p_sub_attr;
161 p_extra_sattr != nullptr;
162 p_extra_sattr = p_extra_sattr->p_next_attr) {
163 // Return the first UUID data element
164 if (SDP_DISC_ATTR_TYPE(p_extra_sattr->attr_len_type) ==
165 UUID_DESC_TYPE &&
166 SDP_DISC_ATTR_LEN(p_extra_sattr->attr_len_type) == 2) {
167 return p_extra_sattr->attr_value.v.u16;
168 }
169 }
170 } else {
171 log::warn("Bad Service Class ID list attribute");
172 return 0;
173 }
174 } else if (p_attr->attr_id == ATTR_ID_SERVICE_ID) {
175 if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UUID_DESC_TYPE &&
176 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) == 2) {
177 return p_attr->attr_value.v.u16;
178 }
179 }
180 }
181 return 0;
182 }
183
sdpu_log_attribute_metrics(const RawAddress & bda,tSDP_DISCOVERY_DB * p_db)184 void sdpu_log_attribute_metrics(const RawAddress& bda,
185 tSDP_DISCOVERY_DB* p_db) {
186 log::assert_that(p_db != nullptr, "assert failed: p_db != nullptr");
187 bool has_di_record = false;
188 for (tSDP_DISC_REC* p_rec = p_db->p_first_rec; p_rec != nullptr;
189 p_rec = p_rec->p_next_rec) {
190 uint16_t service_uuid = sdpu_find_most_specific_service_uuid(p_rec);
191 if (service_uuid == 0) {
192 log::info("skipping record without service uuid {}", bda);
193 continue;
194 }
195 // Log the existence of a profile role
196 // This can be different from Bluetooth Profile Descriptor List
197 log_sdp_attribute(bda, service_uuid, 0, 0, nullptr);
198 // Log profile version from Bluetooth Profile Descriptor List
199 auto uuid_version_array = sdpu_find_profile_version(p_rec);
200 for (const auto& uuid_version_pair : uuid_version_array) {
201 uint16_t profile_uuid = uuid_version_pair.first;
202 uint16_t version = uuid_version_pair.second;
203 auto version_array = to_little_endian_array(version);
204 log_sdp_attribute(bda, profile_uuid, ATTR_ID_BT_PROFILE_DESC_LIST,
205 version_array.size(), version_array.data());
206 }
207 // Log protocol version from Protocol Descriptor List
208 uint16_t protocol_uuid = 0;
209 switch (service_uuid) {
210 case UUID_SERVCLASS_AUDIO_SOURCE:
211 case UUID_SERVCLASS_AUDIO_SINK:
212 protocol_uuid = UUID_PROTOCOL_AVDTP;
213 break;
214 case UUID_SERVCLASS_AV_REMOTE_CONTROL:
215 case UUID_SERVCLASS_AV_REM_CTRL_CONTROL:
216 case UUID_SERVCLASS_AV_REM_CTRL_TARGET:
217 protocol_uuid = UUID_PROTOCOL_AVCTP;
218 break;
219 case UUID_SERVCLASS_PANU:
220 case UUID_SERVCLASS_GN:
221 protocol_uuid = UUID_PROTOCOL_BNEP;
222 break;
223 }
224 if (protocol_uuid != 0) {
225 tSDP_PROTOCOL_ELEM protocol_elements = {};
226 if (SDP_FindProtocolListElemInRec(p_rec, protocol_uuid,
227 &protocol_elements)) {
228 if (protocol_elements.num_params >= 1) {
229 uint16_t version = protocol_elements.params[0];
230 auto version_array = to_little_endian_array(version);
231 log_sdp_attribute(bda, protocol_uuid, ATTR_ID_PROTOCOL_DESC_LIST,
232 version_array.size(), version_array.data());
233 }
234 }
235 }
236 // Log profile supported features from various supported feature attributes
237 switch (service_uuid) {
238 case UUID_SERVCLASS_AG_HANDSFREE:
239 case UUID_SERVCLASS_HF_HANDSFREE:
240 case UUID_SERVCLASS_AV_REMOTE_CONTROL:
241 case UUID_SERVCLASS_AV_REM_CTRL_CONTROL:
242 case UUID_SERVCLASS_AV_REM_CTRL_TARGET:
243 case UUID_SERVCLASS_AUDIO_SOURCE:
244 case UUID_SERVCLASS_AUDIO_SINK: {
245 tSDP_DISC_ATTR* p_attr =
246 SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
247 if (p_attr == nullptr ||
248 SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != UINT_DESC_TYPE ||
249 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < 2) {
250 break;
251 }
252 uint16_t supported_features = p_attr->attr_value.v.u16;
253 auto version_array = to_little_endian_array(supported_features);
254 log_sdp_attribute(bda, service_uuid, ATTR_ID_SUPPORTED_FEATURES,
255 version_array.size(), version_array.data());
256 break;
257 }
258 case UUID_SERVCLASS_MESSAGE_NOTIFICATION:
259 case UUID_SERVCLASS_MESSAGE_ACCESS: {
260 tSDP_DISC_ATTR* p_attr =
261 SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES);
262 if (p_attr == nullptr ||
263 SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != UINT_DESC_TYPE ||
264 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < 4) {
265 break;
266 }
267 uint32_t map_supported_features = p_attr->attr_value.v.u32;
268 auto features_array = to_little_endian_array(map_supported_features);
269 log_sdp_attribute(bda, service_uuid, ATTR_ID_MAP_SUPPORTED_FEATURES,
270 features_array.size(), features_array.data());
271 break;
272 }
273 case UUID_SERVCLASS_PBAP_PCE:
274 case UUID_SERVCLASS_PBAP_PSE: {
275 tSDP_DISC_ATTR* p_attr =
276 SDP_FindAttributeInRec(p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES);
277 if (p_attr == nullptr ||
278 SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != UINT_DESC_TYPE ||
279 SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < 4) {
280 break;
281 }
282 uint32_t pbap_supported_features = p_attr->attr_value.v.u32;
283 auto features_array = to_little_endian_array(pbap_supported_features);
284 log_sdp_attribute(bda, service_uuid, ATTR_ID_PBAP_SUPPORTED_FEATURES,
285 features_array.size(), features_array.data());
286 break;
287 }
288 }
289 if (service_uuid == UUID_SERVCLASS_PNP_INFORMATION) {
290 has_di_record = true;
291 }
292 }
293 // Log the first DI record if there is one
294 if (has_di_record) {
295 tSDP_DI_GET_RECORD di_record = {};
296 if (SDP_GetDiRecord(1, &di_record, p_db) == SDP_SUCCESS) {
297 auto version_array = to_little_endian_array(di_record.spec_id);
298 log_sdp_attribute(bda, UUID_SERVCLASS_PNP_INFORMATION,
299 ATTR_ID_SPECIFICATION_ID, version_array.size(),
300 version_array.data());
301 std::stringstream ss;
302 // [N - native]::SDP::[DIP - Device ID Profile]
303 ss << "N:SDP::DIP::" << loghex(di_record.rec.vendor_id_source);
304 log_manufacturer_info(
305 bda, android::bluetooth::AddressTypeEnum::ADDRESS_TYPE_PUBLIC,
306 android::bluetooth::DeviceInfoSrcEnum::DEVICE_INFO_INTERNAL, ss.str(),
307 loghex(di_record.rec.vendor), loghex(di_record.rec.product),
308 loghex(di_record.rec.version), "");
309
310 std::string bda_string = bda.ToString();
311 // write manufacturer, model, HW version to config
312 btif_config_set_int(bda_string, BTIF_STORAGE_KEY_SDP_DI_MANUFACTURER,
313 di_record.rec.vendor);
314 btif_config_set_int(bda_string, BTIF_STORAGE_KEY_SDP_DI_MODEL,
315 di_record.rec.product);
316 btif_config_set_int(bda_string, BTIF_STORAGE_KEY_SDP_DI_HW_VERSION,
317 di_record.rec.version);
318 btif_config_set_int(bda_string, BTIF_STORAGE_KEY_SDP_DI_VENDOR_ID_SRC,
319 di_record.rec.vendor_id_source);
320 }
321 }
322 }
323
324 /*******************************************************************************
325 *
326 * Function sdpu_find_ccb_by_cid
327 *
328 * Description This function searches the CCB table for an entry with the
329 * passed CID.
330 *
331 * Returns the CCB address, or NULL if not found.
332 *
333 ******************************************************************************/
sdpu_find_ccb_by_cid(uint16_t cid)334 tCONN_CB* sdpu_find_ccb_by_cid(uint16_t cid) {
335 uint16_t xx;
336 tCONN_CB* p_ccb;
337
338 /* Look through each connection control block */
339 for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
340 if ((p_ccb->con_state != SDP_STATE_IDLE) &&
341 (p_ccb->con_state != SDP_STATE_CONN_PEND) &&
342 (p_ccb->connection_id == cid)) {
343 return (p_ccb);
344 }
345 }
346
347 /* If here, not found */
348 return (NULL);
349 }
350
351 /*******************************************************************************
352 *
353 * Function sdpu_find_ccb_by_db
354 *
355 * Description This function searches the CCB table for an entry with the
356 * passed discovery db.
357 *
358 * Returns the CCB address, or NULL if not found.
359 *
360 ******************************************************************************/
sdpu_find_ccb_by_db(const tSDP_DISCOVERY_DB * p_db)361 tCONN_CB* sdpu_find_ccb_by_db(const tSDP_DISCOVERY_DB* p_db) {
362 uint16_t xx;
363 tCONN_CB* p_ccb;
364
365 if (p_db) {
366 /* Look through each connection control block */
367 for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
368 if ((p_ccb->con_state != SDP_STATE_IDLE) && (p_ccb->p_db == p_db))
369 return (p_ccb);
370 }
371 }
372 /* If here, not found */
373 return (NULL);
374 }
375
376 /*******************************************************************************
377 *
378 * Function sdpu_allocate_ccb
379 *
380 * Description This function allocates a new CCB.
381 *
382 * Returns CCB address, or NULL if none available.
383 *
384 ******************************************************************************/
sdpu_allocate_ccb(void)385 tCONN_CB* sdpu_allocate_ccb(void) {
386 uint16_t xx;
387 tCONN_CB* p_ccb;
388
389 /* Look through each connection control block for a free one */
390 for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
391 if (p_ccb->con_state == SDP_STATE_IDLE) {
392 alarm_t* alarm = p_ccb->sdp_conn_timer;
393 *p_ccb = {};
394 p_ccb->sdp_conn_timer = alarm;
395 return (p_ccb);
396 }
397 }
398
399 /* If here, no free CCB found */
400 return (NULL);
401 }
402
403 /*******************************************************************************
404 *
405 * Function sdpu_callback
406 *
407 * Description Tell the user if they have a callback
408 *
409 * Returns void
410 *
411 ******************************************************************************/
sdpu_callback(tCONN_CB & ccb,tSDP_REASON reason)412 void sdpu_callback(tCONN_CB& ccb, tSDP_REASON reason) {
413 if (ccb.p_cb) {
414 (ccb.p_cb)(ccb.device_address, reason);
415 } else if (ccb.complete_callback) {
416 ccb.complete_callback.Run(ccb.device_address, reason);
417 }
418 }
419
420 /*******************************************************************************
421 *
422 * Function sdpu_release_ccb
423 *
424 * Description This function releases a CCB.
425 *
426 * Returns void
427 *
428 ******************************************************************************/
sdpu_release_ccb(tCONN_CB & ccb)429 void sdpu_release_ccb(tCONN_CB& ccb) {
430 /* Ensure timer is stopped */
431 alarm_cancel(ccb.sdp_conn_timer);
432
433 /* Drop any response pointer we may be holding */
434 ccb.con_state = SDP_STATE_IDLE;
435 ccb.is_attr_search = false;
436
437 /* Free the response buffer */
438 if (ccb.rsp_list) log::verbose("releasing SDP rsp_list");
439 osi_free_and_reset((void**)&ccb.rsp_list);
440 }
441
442 /*******************************************************************************
443 *
444 * Function sdpu_get_active_ccb_cid
445 *
446 * Description This function checks if any sdp connecting is there for
447 * same remote and returns cid if its available
448 *
449 * RawAddress : Remote address
450 *
451 * Returns returns cid if any active sdp connection, else 0.
452 *
453 ******************************************************************************/
sdpu_get_active_ccb_cid(const RawAddress & bd_addr)454 uint16_t sdpu_get_active_ccb_cid(const RawAddress& bd_addr) {
455 uint16_t xx;
456 tCONN_CB* p_ccb;
457
458 // Look through each connection control block for active sdp on given remote
459 for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
460 if ((p_ccb->con_state == SDP_STATE_CONN_SETUP) ||
461 (p_ccb->con_state == SDP_STATE_CFG_SETUP) ||
462 (p_ccb->con_state == SDP_STATE_CONNECTED)) {
463 if (p_ccb->con_flags & SDP_FLAGS_IS_ORIG &&
464 p_ccb->device_address == bd_addr) {
465 return p_ccb->connection_id;
466 }
467 }
468 }
469
470 // No active sdp channel for this remote
471 return 0;
472 }
473
474 /*******************************************************************************
475 *
476 * Function sdpu_process_pend_ccb
477 *
478 * Description This function process if any sdp ccb pending for connection
479 * and reuse the same connection id
480 *
481 * tCONN_CB&: connection control block that trigget the process
482 *
483 * Returns returns true if any pending ccb, else false.
484 *
485 ******************************************************************************/
sdpu_process_pend_ccb_same_cid(tCONN_CB & ccb)486 bool sdpu_process_pend_ccb_same_cid(tCONN_CB& ccb) {
487 uint16_t xx;
488 tCONN_CB* p_ccb;
489
490 // Look through each connection control block for active sdp on given remote
491 for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
492 if ((p_ccb->con_state == SDP_STATE_CONN_PEND) &&
493 (p_ccb->connection_id == ccb.connection_id) &&
494 (p_ccb->con_flags & SDP_FLAGS_IS_ORIG)) {
495 p_ccb->con_state = SDP_STATE_CONNECTED;
496 sdp_disc_connected(p_ccb);
497 return true;
498 }
499 }
500 // No pending SDP channel for this remote
501 return false;
502 }
503
504 /*******************************************************************************
505 *
506 * Function sdpu_process_pend_ccb_new_cid
507 *
508 * Description This function process if any sdp ccb pending for connection
509 * and update their connection id with a new L2CA connection
510 *
511 * tCONN_CB&: connection control block that trigget the process
512 *
513 * Returns returns true if any pending ccb, else false.
514 *
515 ******************************************************************************/
sdpu_process_pend_ccb_new_cid(tCONN_CB & ccb)516 bool sdpu_process_pend_ccb_new_cid(tCONN_CB& ccb) {
517 uint16_t xx;
518 tCONN_CB* p_ccb;
519 uint16_t new_cid = 0;
520 bool new_conn = false;
521
522 // Look through each ccb to replace the obsolete cid with a new one.
523 for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
524 if ((p_ccb->con_state == SDP_STATE_CONN_PEND) &&
525 (p_ccb->connection_id == ccb.connection_id) &&
526 (p_ccb->con_flags & SDP_FLAGS_IS_ORIG)) {
527 if (!new_conn) {
528 // Only change state of the first ccb
529 p_ccb->con_state = SDP_STATE_CONN_SETUP;
530 new_cid = L2CA_ConnectReqWithSecurity(BT_PSM_SDP, p_ccb->device_address,
531 BTM_SEC_NONE);
532 new_conn = true;
533 }
534 // Check if L2CAP started the connection process
535 if (new_cid != 0) {
536 // update alls cid to the new one for future reference
537 p_ccb->connection_id = new_cid;
538 } else {
539 sdpu_callback(*p_ccb, SDP_CONN_FAILED);
540 sdpu_release_ccb(*p_ccb);
541 }
542 }
543 }
544 return new_conn && new_cid != 0;
545 }
546
547 /*******************************************************************************
548 *
549 * Function sdpu_clear_pend_ccb
550 *
551 * Description This function releases if any sdp ccb pending for connection
552 *
553 * uint16_t : Remote CID
554 *
555 * Returns returns none.
556 *
557 ******************************************************************************/
sdpu_clear_pend_ccb(tCONN_CB & ccb)558 void sdpu_clear_pend_ccb(tCONN_CB& ccb) {
559 uint16_t xx;
560 tCONN_CB* p_ccb;
561
562 // Look through each connection control block for active sdp on given remote
563 for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
564 if ((p_ccb->con_state == SDP_STATE_CONN_PEND) &&
565 (p_ccb->connection_id == ccb.connection_id) &&
566 (p_ccb->con_flags & SDP_FLAGS_IS_ORIG)) {
567 sdpu_callback(*p_ccb, SDP_CONN_FAILED);
568 sdpu_release_ccb(*p_ccb);
569 }
570 }
571 return;
572 }
573
574 /*******************************************************************************
575 *
576 * Function sdpu_build_attrib_seq
577 *
578 * Description This function builds an attribute sequence from the list of
579 * passed attributes. It is also passed the address of the
580 * output buffer.
581 *
582 * Returns Pointer to next byte in the output buffer.
583 *
584 ******************************************************************************/
sdpu_build_attrib_seq(uint8_t * p_out,uint16_t * p_attr,uint16_t num_attrs)585 uint8_t* sdpu_build_attrib_seq(uint8_t* p_out, uint16_t* p_attr,
586 uint16_t num_attrs) {
587 uint16_t xx;
588
589 /* First thing is the data element header. See if the length fits 1 byte */
590 /* If no attributes, assume a 4-byte wildcard */
591 if (!p_attr)
592 xx = 5;
593 else
594 xx = num_attrs * 3;
595
596 if (xx > 255) {
597 UINT8_TO_BE_STREAM(p_out,
598 (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
599 UINT16_TO_BE_STREAM(p_out, xx);
600 } else {
601 UINT8_TO_BE_STREAM(p_out,
602 (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
603 UINT8_TO_BE_STREAM(p_out, xx);
604 }
605
606 /* If there are no attributes specified, assume caller wants wildcard */
607 if (!p_attr) {
608 UINT8_TO_BE_STREAM(p_out, (UINT_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
609 UINT16_TO_BE_STREAM(p_out, 0);
610 UINT16_TO_BE_STREAM(p_out, 0xFFFF);
611 } else {
612 /* Loop through and put in all the attributes(s) */
613 for (xx = 0; xx < num_attrs; xx++, p_attr++) {
614 UINT8_TO_BE_STREAM(p_out, (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES);
615 UINT16_TO_BE_STREAM(p_out, *p_attr);
616 }
617 }
618
619 return (p_out);
620 }
621
622 /*******************************************************************************
623 *
624 * Function sdpu_build_attrib_entry
625 *
626 * Description This function builds an attribute entry from the passed
627 * attribute record. It is also passed the address of the
628 * output buffer.
629 *
630 * Returns Pointer to next byte in the output buffer.
631 *
632 ******************************************************************************/
sdpu_build_attrib_entry(uint8_t * p_out,const tSDP_ATTRIBUTE * p_attr)633 uint8_t* sdpu_build_attrib_entry(uint8_t* p_out, const tSDP_ATTRIBUTE* p_attr) {
634 /* First, store the attribute ID. Goes as a UINT */
635 UINT8_TO_BE_STREAM(p_out, (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES);
636 UINT16_TO_BE_STREAM(p_out, p_attr->id);
637
638 /* the attribute is in the db record.
639 * assuming the attribute len is less than SDP_MAX_ATTR_LEN */
640 switch (p_attr->type) {
641 case TEXT_STR_DESC_TYPE: /* 4 */
642 case DATA_ELE_SEQ_DESC_TYPE: /* 6 */
643 case DATA_ELE_ALT_DESC_TYPE: /* 7 */
644 case URL_DESC_TYPE: /* 8 */
645 #if (SDP_MAX_ATTR_LEN > 0xFFFF)
646 if (p_attr->len > 0xFFFF) {
647 UINT8_TO_BE_STREAM(p_out, (p_attr->type << 3) | SIZE_IN_NEXT_LONG);
648 UINT32_TO_BE_STREAM(p_out, p_attr->len);
649 } else
650 #endif /* 0xFFFF - 0xFF */
651 #if (SDP_MAX_ATTR_LEN > 0xFF)
652 if (p_attr->len > 0xFF) {
653 UINT8_TO_BE_STREAM(p_out, (p_attr->type << 3) | SIZE_IN_NEXT_WORD);
654 UINT16_TO_BE_STREAM(p_out, p_attr->len);
655 } else
656 #endif /* 0xFF and less*/
657 {
658 UINT8_TO_BE_STREAM(p_out, (p_attr->type << 3) | SIZE_IN_NEXT_BYTE);
659 UINT8_TO_BE_STREAM(p_out, p_attr->len);
660 }
661
662 if (p_attr->value_ptr != NULL) {
663 ARRAY_TO_BE_STREAM(p_out, p_attr->value_ptr, (int)p_attr->len);
664 }
665
666 return (p_out);
667 }
668
669 /* Now, store the attribute value */
670 switch (p_attr->len) {
671 case 1:
672 UINT8_TO_BE_STREAM(p_out, (p_attr->type << 3) | SIZE_ONE_BYTE);
673 break;
674 case 2:
675 UINT8_TO_BE_STREAM(p_out, (p_attr->type << 3) | SIZE_TWO_BYTES);
676 break;
677 case 4:
678 UINT8_TO_BE_STREAM(p_out, (p_attr->type << 3) | SIZE_FOUR_BYTES);
679 break;
680 case 8:
681 UINT8_TO_BE_STREAM(p_out, (p_attr->type << 3) | SIZE_EIGHT_BYTES);
682 break;
683 case 16:
684 UINT8_TO_BE_STREAM(p_out, (p_attr->type << 3) | SIZE_SIXTEEN_BYTES);
685 break;
686 default:
687 UINT8_TO_BE_STREAM(p_out, (p_attr->type << 3) | SIZE_IN_NEXT_BYTE);
688 UINT8_TO_BE_STREAM(p_out, p_attr->len);
689 break;
690 }
691
692 if (p_attr->value_ptr != NULL) {
693 ARRAY_TO_BE_STREAM(p_out, p_attr->value_ptr, (int)p_attr->len);
694 }
695
696 return (p_out);
697 }
698
699 /*******************************************************************************
700 *
701 * Function sdpu_build_n_send_error
702 *
703 * Description This function builds and sends an error packet.
704 *
705 * Returns void
706 *
707 ******************************************************************************/
sdpu_build_n_send_error(tCONN_CB * p_ccb,uint16_t trans_num,uint16_t error_code,char * p_error_text)708 void sdpu_build_n_send_error(tCONN_CB* p_ccb, uint16_t trans_num,
709 uint16_t error_code, char* p_error_text) {
710 uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
711 uint16_t rsp_param_len;
712 BT_HDR* p_buf = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
713
714 log::warn("SDP - sdpu_build_n_send_error code: 0x{:x} CID: 0x{:x}",
715 error_code, p_ccb->connection_id);
716
717 /* Send the packet to L2CAP */
718 p_buf->offset = L2CAP_MIN_OFFSET;
719 p_rsp = p_rsp_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
720
721 UINT8_TO_BE_STREAM(p_rsp, SDP_PDU_ERROR_RESPONSE);
722 UINT16_TO_BE_STREAM(p_rsp, trans_num);
723
724 /* Skip the parameter length, we need to add it at the end */
725 p_rsp_param_len = p_rsp;
726 p_rsp += 2;
727
728 UINT16_TO_BE_STREAM(p_rsp, error_code);
729
730 /* Unplugfest example traces do not have any error text */
731 if (p_error_text)
732 ARRAY_TO_BE_STREAM(p_rsp, p_error_text, (int)strlen(p_error_text));
733
734 /* Go back and put the parameter length into the buffer */
735 rsp_param_len = p_rsp - p_rsp_param_len - 2;
736 UINT16_TO_BE_STREAM(p_rsp_param_len, rsp_param_len);
737
738 /* Set the length of the SDP data in the buffer */
739 p_buf->len = p_rsp - p_rsp_start;
740
741 /* Send the buffer through L2CAP */
742 if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != L2CAP_DW_SUCCESS) {
743 log::warn("Unable to write L2CAP data cid:{}", p_ccb->connection_id);
744 }
745 }
746
747 /*******************************************************************************
748 *
749 * Function sdpu_extract_uid_seq
750 *
751 * Description This function extracts a UUID sequence from the passed input
752 * buffer, and puts it into the passed output list.
753 *
754 * Returns Pointer to next byte in the input buffer after the sequence.
755 *
756 ******************************************************************************/
sdpu_extract_uid_seq(uint8_t * p,uint16_t param_len,tSDP_UUID_SEQ * p_seq)757 uint8_t* sdpu_extract_uid_seq(uint8_t* p, uint16_t param_len,
758 tSDP_UUID_SEQ* p_seq) {
759 uint8_t* p_seq_end;
760 uint8_t descr, type, size;
761 uint32_t seq_len, uuid_len;
762
763 /* Assume none found */
764 p_seq->num_uids = 0;
765
766 /* A UID sequence is composed of a bunch of UIDs. */
767 if (sizeof(descr) > param_len) return (NULL);
768 param_len -= sizeof(descr);
769
770 BE_STREAM_TO_UINT8(descr, p);
771 type = descr >> 3;
772 size = descr & 7;
773
774 if (type != DATA_ELE_SEQ_DESC_TYPE) return (NULL);
775
776 switch (size) {
777 case SIZE_TWO_BYTES:
778 seq_len = 2;
779 break;
780 case SIZE_FOUR_BYTES:
781 seq_len = 4;
782 break;
783 case SIZE_SIXTEEN_BYTES:
784 seq_len = 16;
785 break;
786 case SIZE_IN_NEXT_BYTE:
787 if (sizeof(uint8_t) > param_len) return (NULL);
788 param_len -= sizeof(uint8_t);
789 BE_STREAM_TO_UINT8(seq_len, p);
790 break;
791 case SIZE_IN_NEXT_WORD:
792 if (sizeof(uint16_t) > param_len) return (NULL);
793 param_len -= sizeof(uint16_t);
794 BE_STREAM_TO_UINT16(seq_len, p);
795 break;
796 case SIZE_IN_NEXT_LONG:
797 if (sizeof(uint32_t) > param_len) return (NULL);
798 param_len -= sizeof(uint32_t);
799 BE_STREAM_TO_UINT32(seq_len, p);
800 break;
801 default:
802 return (NULL);
803 }
804
805 if (seq_len > param_len) return (NULL);
806
807 p_seq_end = p + seq_len;
808
809 /* Loop through, extracting the UIDs */
810 for (; p < p_seq_end;) {
811 BE_STREAM_TO_UINT8(descr, p);
812 type = descr >> 3;
813 size = descr & 7;
814
815 if (type != UUID_DESC_TYPE) return (NULL);
816
817 switch (size) {
818 case SIZE_TWO_BYTES:
819 uuid_len = 2;
820 break;
821 case SIZE_FOUR_BYTES:
822 uuid_len = 4;
823 break;
824 case SIZE_SIXTEEN_BYTES:
825 uuid_len = 16;
826 break;
827 case SIZE_IN_NEXT_BYTE:
828 if (p + sizeof(uint8_t) > p_seq_end) return NULL;
829 BE_STREAM_TO_UINT8(uuid_len, p);
830 break;
831 case SIZE_IN_NEXT_WORD:
832 if (p + sizeof(uint16_t) > p_seq_end) return NULL;
833 BE_STREAM_TO_UINT16(uuid_len, p);
834 break;
835 case SIZE_IN_NEXT_LONG:
836 if (p + sizeof(uint32_t) > p_seq_end) return NULL;
837 BE_STREAM_TO_UINT32(uuid_len, p);
838 break;
839 default:
840 return (NULL);
841 }
842
843 /* If UUID length is valid, copy it across */
844 if (((uuid_len == 2) || (uuid_len == 4) || (uuid_len == 16)) &&
845 (p + uuid_len <= p_seq_end)) {
846 p_seq->uuid_entry[p_seq->num_uids].len = (uint16_t)uuid_len;
847 BE_STREAM_TO_ARRAY(p, p_seq->uuid_entry[p_seq->num_uids].value,
848 (int)uuid_len);
849 p_seq->num_uids++;
850 } else
851 return (NULL);
852
853 /* We can only do so many */
854 if (p_seq->num_uids >= MAX_UUIDS_PER_SEQ) return (NULL);
855 }
856
857 if (p != p_seq_end) return (NULL);
858
859 return (p);
860 }
861
862 /*******************************************************************************
863 *
864 * Function sdpu_extract_attr_seq
865 *
866 * Description This function extracts an attribute sequence from the passed
867 * input buffer, and puts it into the passed output list.
868 *
869 * Returns Pointer to next byte in the input buffer after the sequence.
870 *
871 ******************************************************************************/
sdpu_extract_attr_seq(uint8_t * p,uint16_t param_len,tSDP_ATTR_SEQ * p_seq)872 uint8_t* sdpu_extract_attr_seq(uint8_t* p, uint16_t param_len,
873 tSDP_ATTR_SEQ* p_seq) {
874 uint8_t* p_end_list;
875 uint8_t descr, type, size;
876 uint32_t list_len, attr_len;
877
878 /* Assume none found */
879 p_seq->num_attr = 0;
880
881 /* Get attribute sequence info */
882 if (param_len < sizeof(descr)) return NULL;
883 param_len -= sizeof(descr);
884 BE_STREAM_TO_UINT8(descr, p);
885 type = descr >> 3;
886 size = descr & 7;
887
888 if (type != DATA_ELE_SEQ_DESC_TYPE) return NULL;
889
890 switch (size) {
891 case SIZE_IN_NEXT_BYTE:
892 if (param_len < sizeof(uint8_t)) return NULL;
893 param_len -= sizeof(uint8_t);
894 BE_STREAM_TO_UINT8(list_len, p);
895 break;
896
897 case SIZE_IN_NEXT_WORD:
898 if (param_len < sizeof(uint16_t)) return NULL;
899 param_len -= sizeof(uint16_t);
900 BE_STREAM_TO_UINT16(list_len, p);
901 break;
902
903 case SIZE_IN_NEXT_LONG:
904 if (param_len < sizeof(uint32_t)) return NULL;
905 param_len -= sizeof(uint32_t);
906 BE_STREAM_TO_UINT32(list_len, p);
907 break;
908
909 default:
910 return NULL;
911 }
912
913 if (list_len > param_len) return NULL;
914
915 p_end_list = p + list_len;
916
917 /* Loop through, extracting the attribute IDs */
918 for (; p < p_end_list;) {
919 BE_STREAM_TO_UINT8(descr, p);
920 type = descr >> 3;
921 size = descr & 7;
922
923 if (type != UINT_DESC_TYPE) return NULL;
924
925 switch (size) {
926 case SIZE_TWO_BYTES:
927 attr_len = 2;
928 break;
929 case SIZE_FOUR_BYTES:
930 attr_len = 4;
931 break;
932 case SIZE_IN_NEXT_BYTE:
933 if (p + sizeof(uint8_t) > p_end_list) return NULL;
934 BE_STREAM_TO_UINT8(attr_len, p);
935 break;
936 case SIZE_IN_NEXT_WORD:
937 if (p + sizeof(uint16_t) > p_end_list) return NULL;
938 BE_STREAM_TO_UINT16(attr_len, p);
939 break;
940 case SIZE_IN_NEXT_LONG:
941 if (p + sizeof(uint32_t) > p_end_list) return NULL;
942 BE_STREAM_TO_UINT32(attr_len, p);
943 break;
944 default:
945 return NULL;
946 break;
947 }
948
949 /* Attribute length must be 2-bytes or 4-bytes for a paired entry. */
950 if (p + attr_len > p_end_list) return NULL;
951 if (attr_len == 2) {
952 BE_STREAM_TO_UINT16(p_seq->attr_entry[p_seq->num_attr].start, p);
953 p_seq->attr_entry[p_seq->num_attr].end =
954 p_seq->attr_entry[p_seq->num_attr].start;
955 } else if (attr_len == 4) {
956 BE_STREAM_TO_UINT16(p_seq->attr_entry[p_seq->num_attr].start, p);
957 BE_STREAM_TO_UINT16(p_seq->attr_entry[p_seq->num_attr].end, p);
958 } else
959 return (NULL);
960
961 /* We can only do so many */
962 if (++p_seq->num_attr >= MAX_ATTR_PER_SEQ) return (NULL);
963 }
964
965 return (p);
966 }
967
968 /*******************************************************************************
969 *
970 * Function sdpu_get_len_from_type
971 *
972 * Description This function gets the data length given the element
973 * header.
974 *
975 * @param p Start of the SDP attribute bytestream
976 * p_end End of the SDP attribute bytestream
977 * type Attribute element header
978 * p_len Data size indicated by element header
979 *
980 * @return pointer to the start of the data or nullptr on failure
981 *
982 ******************************************************************************/
sdpu_get_len_from_type(uint8_t * p,uint8_t * p_end,uint8_t type,uint32_t * p_len)983 uint8_t* sdpu_get_len_from_type(uint8_t* p, uint8_t* p_end, uint8_t type,
984 uint32_t* p_len) {
985 uint8_t u8;
986 uint16_t u16;
987 uint32_t u32;
988
989 switch (type & 7) {
990 case SIZE_ONE_BYTE:
991 if (com::android::bluetooth::flags::
992 stack_sdp_detect_nil_property_type()) {
993 // Return NIL type if appropriate
994 *p_len = (type == 0) ? 0 : sizeof(uint8_t);
995 } else {
996 *p_len = 1;
997 }
998 break;
999 case SIZE_TWO_BYTES:
1000 *p_len = 2;
1001 break;
1002 case SIZE_FOUR_BYTES:
1003 *p_len = 4;
1004 break;
1005 case SIZE_EIGHT_BYTES:
1006 *p_len = 8;
1007 break;
1008 case SIZE_SIXTEEN_BYTES:
1009 *p_len = 16;
1010 break;
1011 case SIZE_IN_NEXT_BYTE:
1012 if (p + 1 > p_end) {
1013 *p_len = 0;
1014 return NULL;
1015 }
1016 BE_STREAM_TO_UINT8(u8, p);
1017 *p_len = u8;
1018 break;
1019 case SIZE_IN_NEXT_WORD:
1020 if (p + 2 > p_end) {
1021 *p_len = 0;
1022 return NULL;
1023 }
1024 BE_STREAM_TO_UINT16(u16, p);
1025 *p_len = u16;
1026 break;
1027 case SIZE_IN_NEXT_LONG:
1028 if (p + 4 > p_end) {
1029 *p_len = 0;
1030 return NULL;
1031 }
1032 BE_STREAM_TO_UINT32(u32, p);
1033 *p_len = (uint16_t)u32;
1034 break;
1035 }
1036
1037 return (p);
1038 }
1039
1040 /*******************************************************************************
1041 *
1042 * Function sdpu_is_base_uuid
1043 *
1044 * Description This function checks a 128-bit UUID with the base to see if
1045 * it matches. Only the last 12 bytes are compared.
1046 *
1047 * Returns true if matched, else false
1048 *
1049 ******************************************************************************/
sdpu_is_base_uuid(uint8_t * p_uuid)1050 bool sdpu_is_base_uuid(uint8_t* p_uuid) {
1051 uint16_t xx;
1052
1053 for (xx = 4; xx < Uuid::kNumBytes128; xx++)
1054 if (p_uuid[xx] != sdp_base_uuid[xx]) return (false);
1055
1056 /* If here, matched */
1057 return (true);
1058 }
1059
1060 /*******************************************************************************
1061 *
1062 * Function sdpu_compare_uuid_arrays
1063 *
1064 * Description This function compares 2 BE UUIDs. If needed, they are
1065 * expanded to 128-bit UUIDs, then compared.
1066 *
1067 * NOTE it is assumed that the arrays are in Big Endian format
1068 *
1069 * Returns true if matched, else false
1070 *
1071 ******************************************************************************/
sdpu_compare_uuid_arrays(const uint8_t * p_uuid1,uint32_t len1,const uint8_t * p_uuid2,uint16_t len2)1072 bool sdpu_compare_uuid_arrays(const uint8_t* p_uuid1, uint32_t len1,
1073 const uint8_t* p_uuid2, uint16_t len2) {
1074 uint8_t nu1[Uuid::kNumBytes128];
1075 uint8_t nu2[Uuid::kNumBytes128];
1076
1077 if (((len1 != 2) && (len1 != 4) && (len1 != 16)) ||
1078 ((len2 != 2) && (len2 != 4) && (len2 != 16))) {
1079 log::error("invalid length");
1080 return false;
1081 }
1082
1083 /* If lengths match, do a straight compare */
1084 if (len1 == len2) {
1085 if (len1 == 2)
1086 return ((p_uuid1[0] == p_uuid2[0]) && (p_uuid1[1] == p_uuid2[1]));
1087 if (len1 == 4)
1088 return ((p_uuid1[0] == p_uuid2[0]) && (p_uuid1[1] == p_uuid2[1]) &&
1089 (p_uuid1[2] == p_uuid2[2]) && (p_uuid1[3] == p_uuid2[3]));
1090 else
1091 return (memcmp(p_uuid1, p_uuid2, (size_t)len1) == 0);
1092 } else if (len1 > len2) {
1093 /* If the len1 was 4-byte, (so len2 is 2-byte), compare on the fly */
1094 if (len1 == 4) {
1095 return ((p_uuid1[0] == 0) && (p_uuid1[1] == 0) &&
1096 (p_uuid1[2] == p_uuid2[0]) && (p_uuid1[3] == p_uuid2[1]));
1097 } else {
1098 /* Normalize UUIDs to 16-byte form, then compare. Len1 must be 16 */
1099 memcpy(nu1, p_uuid1, Uuid::kNumBytes128);
1100 memcpy(nu2, sdp_base_uuid, Uuid::kNumBytes128);
1101
1102 if (len2 == 4)
1103 memcpy(nu2, p_uuid2, len2);
1104 else if (len2 == 2)
1105 memcpy(nu2 + 2, p_uuid2, len2);
1106
1107 return (memcmp(nu1, nu2, Uuid::kNumBytes128) == 0);
1108 }
1109 } else {
1110 /* len2 is greater than len1 */
1111 /* If the len2 was 4-byte, (so len1 is 2-byte), compare on the fly */
1112 if (len2 == 4) {
1113 return ((p_uuid2[0] == 0) && (p_uuid2[1] == 0) &&
1114 (p_uuid2[2] == p_uuid1[0]) && (p_uuid2[3] == p_uuid1[1]));
1115 } else {
1116 /* Normalize UUIDs to 16-byte form, then compare. Len1 must be 16 */
1117 memcpy(nu2, p_uuid2, Uuid::kNumBytes128);
1118 memcpy(nu1, sdp_base_uuid, Uuid::kNumBytes128);
1119
1120 if (len1 == 4)
1121 memcpy(nu1, p_uuid1, (size_t)len1);
1122 else if (len1 == 2)
1123 memcpy(nu1 + 2, p_uuid1, (size_t)len1);
1124
1125 return (memcmp(nu1, nu2, Uuid::kNumBytes128) == 0);
1126 }
1127 }
1128 }
1129
1130 /*******************************************************************************
1131 *
1132 * Function sdpu_compare_uuid_with_attr
1133 *
1134 * Description This function compares a BT UUID structure with the UUID in
1135 * an SDP attribute record. If needed, they are expanded to
1136 * 128-bit UUIDs, then compared.
1137 *
1138 * NOTE - it is assumed that BT UUID structures are compressed to the
1139 * smallest possible UUIDs (by removing the base SDP UUID).
1140 * - it is also assumed that the discovery atribute is compressed
1141 * to the smallest possible
1142 *
1143 * Returns true if matched, else false
1144 *
1145 ******************************************************************************/
sdpu_compare_uuid_with_attr(const Uuid & uuid,tSDP_DISC_ATTR * p_attr)1146 bool sdpu_compare_uuid_with_attr(const Uuid& uuid, tSDP_DISC_ATTR* p_attr) {
1147 int len = uuid.GetShortestRepresentationSize();
1148 if (len == 2) {
1149 if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) == Uuid::kNumBytes16) {
1150 return uuid.As16Bit() == p_attr->attr_value.v.u16;
1151 } else {
1152 log::error("invalid length for 16bit discovery attribute len:{}", len);
1153 return (false);
1154 }
1155 }
1156 if (len == 4) {
1157 if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) == Uuid::kNumBytes32) {
1158 return uuid.As32Bit() == p_attr->attr_value.v.u32;
1159 } else {
1160 log::error("invalid length for 32bit discovery attribute len:{}", len);
1161 return (false);
1162 }
1163 }
1164
1165 if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) != Uuid::kNumBytes128) {
1166 log::error("invalid length for 128bit discovery attribute len:{}", len);
1167 return (false);
1168 }
1169
1170 if (memcmp(uuid.To128BitBE().data(), (void*)p_attr->attr_value.v.array,
1171 Uuid::kNumBytes128) == 0)
1172 return (true);
1173
1174 return (false);
1175 }
1176
1177 /*******************************************************************************
1178 *
1179 * Function sdpu_sort_attr_list
1180 *
1181 * Description sorts a list of attributes in numeric order from lowest to
1182 * highest to conform to SDP specification
1183 *
1184 * Returns void
1185 *
1186 ******************************************************************************/
sdpu_sort_attr_list(uint16_t num_attr,tSDP_DISCOVERY_DB * p_db)1187 void sdpu_sort_attr_list(uint16_t num_attr, tSDP_DISCOVERY_DB* p_db) {
1188 uint16_t i;
1189 uint16_t x;
1190
1191 /* Done if no attributes to sort */
1192 if (num_attr <= 1) {
1193 return;
1194 } else if (num_attr > SDP_MAX_ATTR_FILTERS) {
1195 num_attr = SDP_MAX_ATTR_FILTERS;
1196 }
1197
1198 num_attr--; /* for the for-loop */
1199 for (i = 0; i < num_attr;) {
1200 if (p_db->attr_filters[i] > p_db->attr_filters[i + 1]) {
1201 /* swap the attribute IDs and start from the beginning */
1202 x = p_db->attr_filters[i];
1203 p_db->attr_filters[i] = p_db->attr_filters[i + 1];
1204 p_db->attr_filters[i + 1] = x;
1205
1206 i = 0;
1207 } else
1208 i++;
1209 }
1210 }
1211
1212 /*******************************************************************************
1213 *
1214 * Function sdpu_get_list_len
1215 *
1216 * Description gets the total list length in the sdp database for a given
1217 * uid sequence and attr sequence
1218 *
1219 * Returns void
1220 *
1221 ******************************************************************************/
sdpu_get_list_len(tSDP_UUID_SEQ * uid_seq,tSDP_ATTR_SEQ * attr_seq)1222 uint16_t sdpu_get_list_len(tSDP_UUID_SEQ* uid_seq, tSDP_ATTR_SEQ* attr_seq) {
1223 const tSDP_RECORD* p_rec;
1224 uint16_t len = 0;
1225 uint16_t len1;
1226
1227 for (p_rec = sdp_db_service_search(NULL, uid_seq); p_rec;
1228 p_rec = sdp_db_service_search(p_rec, uid_seq)) {
1229 len += 3;
1230
1231 len1 = sdpu_get_attrib_seq_len(p_rec, attr_seq);
1232
1233 if (len1 != 0)
1234 len += len1;
1235 else
1236 len -= 3;
1237 }
1238 return len;
1239 }
1240
1241 /*******************************************************************************
1242 *
1243 * Function sdpu_get_attrib_seq_len
1244 *
1245 * Description gets the length of the specific attributes in a given
1246 * sdp record
1247 *
1248 * Returns void
1249 *
1250 ******************************************************************************/
sdpu_get_attrib_seq_len(const tSDP_RECORD * p_rec,const tSDP_ATTR_SEQ * attr_seq)1251 uint16_t sdpu_get_attrib_seq_len(const tSDP_RECORD* p_rec,
1252 const tSDP_ATTR_SEQ* attr_seq) {
1253 const tSDP_ATTRIBUTE* p_attr;
1254 uint16_t len1 = 0;
1255 uint16_t xx;
1256 bool is_range = false;
1257 uint16_t start_id = 0, end_id = 0;
1258
1259 for (xx = 0; xx < attr_seq->num_attr; xx++) {
1260 if (!is_range) {
1261 start_id = attr_seq->attr_entry[xx].start;
1262 end_id = attr_seq->attr_entry[xx].end;
1263 }
1264 p_attr = sdp_db_find_attr_in_rec(p_rec, start_id, end_id);
1265 if (p_attr) {
1266 len1 += sdpu_get_attrib_entry_len(p_attr);
1267
1268 /* If doing a range, stick with this one till no more attributes found */
1269 if (start_id != end_id) {
1270 /* Update for next time through */
1271 start_id = p_attr->id + 1;
1272 xx--;
1273 is_range = true;
1274 } else
1275 is_range = false;
1276 } else
1277 is_range = false;
1278 }
1279 return len1;
1280 }
1281
1282 /*******************************************************************************
1283 *
1284 * Function sdpu_get_attrib_entry_len
1285 *
1286 * Description gets the length of a specific attribute
1287 *
1288 * Returns void
1289 *
1290 ******************************************************************************/
sdpu_get_attrib_entry_len(const tSDP_ATTRIBUTE * p_attr)1291 uint16_t sdpu_get_attrib_entry_len(const tSDP_ATTRIBUTE* p_attr) {
1292 uint16_t len = 3;
1293
1294 /* the attribute is in the db record.
1295 * assuming the attribute len is less than SDP_MAX_ATTR_LEN */
1296 switch (p_attr->type) {
1297 case TEXT_STR_DESC_TYPE: /* 4 */
1298 case DATA_ELE_SEQ_DESC_TYPE: /* 6 */
1299 case DATA_ELE_ALT_DESC_TYPE: /* 7 */
1300 case URL_DESC_TYPE: /* 8 */
1301 #if (SDP_MAX_ATTR_LEN > 0xFFFF)
1302 if (p_attr->len > 0xFFFF) {
1303 len += 5;
1304 } else
1305 #endif /* 0xFFFF - 0xFF */
1306 #if (SDP_MAX_ATTR_LEN > 0xFF)
1307 if (p_attr->len > 0xFF) {
1308 len += 3;
1309 } else
1310 #endif /* 0xFF and less*/
1311 {
1312 len += 2;
1313 }
1314 len += p_attr->len;
1315 return len;
1316 }
1317
1318 /* Now, the attribute value */
1319 switch (p_attr->len) {
1320 case 1:
1321 case 2:
1322 case 4:
1323 case 8:
1324 case 16:
1325 len += 1;
1326 break;
1327 default:
1328 len += 2;
1329 break;
1330 }
1331
1332 len += p_attr->len;
1333 return len;
1334 }
1335
1336 /*******************************************************************************
1337 *
1338 * Function sdpu_build_partial_attrib_entry
1339 *
1340 * Description This function fills a buffer with partial attribute. It is
1341 * assumed that the maximum size of any attribute is 256 bytes.
1342 *
1343 * p_out: output buffer
1344 * p_attr: attribute to be copied partially into p_out
1345 * rem_len: num bytes to copy into p_out
1346 * offset: current start offset within the attr that needs to
1347 * be copied
1348 *
1349 * Returns Pointer to next byte in the output buffer.
1350 * offset is also updated
1351 *
1352 ******************************************************************************/
sdpu_build_partial_attrib_entry(uint8_t * p_out,const tSDP_ATTRIBUTE * p_attr,uint16_t len,uint16_t * offset)1353 uint8_t* sdpu_build_partial_attrib_entry(uint8_t* p_out,
1354 const tSDP_ATTRIBUTE* p_attr,
1355 uint16_t len, uint16_t* offset) {
1356 uint8_t* p_attr_buff =
1357 (uint8_t*)osi_malloc(sizeof(uint8_t) * SDP_MAX_ATTR_LEN);
1358 sdpu_build_attrib_entry(p_attr_buff, p_attr);
1359
1360 uint16_t attr_len = sdpu_get_attrib_entry_len(p_attr);
1361
1362 if (len > SDP_MAX_ATTR_LEN) {
1363 log::error("len {} exceeds SDP_MAX_ATTR_LEN", len);
1364 len = SDP_MAX_ATTR_LEN;
1365 }
1366
1367 size_t len_to_copy =
1368 ((attr_len - *offset) < len) ? (attr_len - *offset) : len;
1369 memcpy(p_out, &p_attr_buff[*offset], len_to_copy);
1370
1371 p_out = &p_out[len_to_copy];
1372 *offset += len_to_copy;
1373
1374 osi_free(p_attr_buff);
1375 return p_out;
1376 }
1377 /*******************************************************************************
1378 *
1379 * Function sdpu_is_avrcp_profile_description_list
1380 *
1381 * Description This function is to check if attirbute contain AVRCP profile
1382 * description list
1383 *
1384 * p_attr: attibute to be check
1385 *
1386 * Returns AVRCP profile version if matched, else 0
1387 *
1388 ******************************************************************************/
sdpu_is_avrcp_profile_description_list(const tSDP_ATTRIBUTE * p_attr)1389 uint16_t sdpu_is_avrcp_profile_description_list(const tSDP_ATTRIBUTE* p_attr) {
1390 if (p_attr->id != ATTR_ID_BT_PROFILE_DESC_LIST || p_attr->len != 8) {
1391 return 0;
1392 }
1393
1394 uint8_t* p_uuid = p_attr->value_ptr + 3;
1395 // Check if AVRCP profile UUID
1396 if (p_uuid[0] != 0x11 || p_uuid[1] != 0xe) {
1397 return 0;
1398 }
1399 uint8_t p_version = *(p_uuid + 4);
1400 switch (p_version) {
1401 case 0x0:
1402 return AVRC_REV_1_0;
1403 case 0x3:
1404 return AVRC_REV_1_3;
1405 case 0x4:
1406 return AVRC_REV_1_4;
1407 case 0x5:
1408 return AVRC_REV_1_5;
1409 case 0x6:
1410 return AVRC_REV_1_6;
1411 default:
1412 return 0;
1413 }
1414 }
1415 /*******************************************************************************
1416 *
1417 * Function sdpu_is_service_id_avrc_target
1418 *
1419 * Description This function is to check if attirbute is A/V Remote Control
1420 * Target
1421 *
1422 * p_attr: attribute to be checked
1423 *
1424 * Returns true if service id of attirbute is A/V Remote Control
1425 * Target, else false
1426 *
1427 ******************************************************************************/
sdpu_is_service_id_avrc_target(const tSDP_ATTRIBUTE * p_attr)1428 bool sdpu_is_service_id_avrc_target(const tSDP_ATTRIBUTE* p_attr) {
1429 if (p_attr->id != ATTR_ID_SERVICE_CLASS_ID_LIST || p_attr->len != 3) {
1430 return false;
1431 }
1432
1433 uint8_t* p_uuid = p_attr->value_ptr + 1;
1434 // check UUID of A/V Remote Control Target
1435 if (p_uuid[0] != 0x11 || p_uuid[1] != 0xc) {
1436 return false;
1437 }
1438
1439 return true;
1440 }
1441 /*******************************************************************************
1442 *
1443 * Function spdu_is_avrcp_version_valid
1444 *
1445 * Description Check avrcp version is valid
1446 *
1447 * version: the avrcp version to check
1448 *
1449 * Returns true if avrcp version is valid, else false
1450 *
1451 ******************************************************************************/
spdu_is_avrcp_version_valid(const uint16_t version)1452 bool spdu_is_avrcp_version_valid(const uint16_t version) {
1453 return version == AVRC_REV_1_0 || version == AVRC_REV_1_3 ||
1454 version == AVRC_REV_1_4 || version == AVRC_REV_1_5 ||
1455 version == AVRC_REV_1_6;
1456 }
1457 /*******************************************************************************
1458 *
1459 * Function sdpu_set_avrc_target_version
1460 *
1461 * Description This function is to set AVRCP version of A/V Remote Control
1462 * Target according to IOP table and cached Bluetooth config
1463 *
1464 * p_attr: attribute to be modified
1465 * bdaddr: for searching IOP table and BT config
1466 *
1467 * Returns void
1468 *
1469 ******************************************************************************/
sdpu_set_avrc_target_version(const tSDP_ATTRIBUTE * p_attr,const RawAddress * bdaddr)1470 void sdpu_set_avrc_target_version(const tSDP_ATTRIBUTE* p_attr,
1471 const RawAddress* bdaddr) {
1472 // Check attribute is AVRCP profile description list and get AVRC Target
1473 // version
1474 uint16_t avrcp_version = sdpu_is_avrcp_profile_description_list(p_attr);
1475 log::info("SDP AVRCP DB Version {:x}", avrcp_version);
1476 if (avrcp_version == 0) {
1477 log::info("Not AVRCP version attribute or version not valid for device {}",
1478 *bdaddr);
1479 return;
1480 }
1481
1482 uint16_t dut_avrcp_version =
1483 (bluetooth::common::init_flags::
1484 dynamic_avrcp_version_enhancement_is_enabled())
1485 ? GetInterfaceToProfiles()
1486 ->profileSpecific_HACK->AVRC_GetProfileVersion()
1487 : avrcp_version;
1488
1489 log::info("Current DUT AVRCP Version {:x}", dut_avrcp_version);
1490 // Some remote devices will have interoperation issue when receive higher
1491 // AVRCP version. If those devices are in IOP database and our version higher
1492 // than device, we reply a lower version to them.
1493 uint16_t iop_version = 0;
1494 if (dut_avrcp_version > AVRC_REV_1_4 &&
1495 interop_match_addr(INTEROP_AVRCP_1_4_ONLY, bdaddr)) {
1496 iop_version = AVRC_REV_1_4;
1497 } else if (dut_avrcp_version > AVRC_REV_1_3 &&
1498 interop_match_addr(INTEROP_AVRCP_1_3_ONLY, bdaddr)) {
1499 iop_version = AVRC_REV_1_3;
1500 }
1501
1502 if (iop_version != 0) {
1503 log::info(
1504 "device={} is in IOP database. Reply AVRC Target version {:x} instead "
1505 "of {:x}.",
1506 *bdaddr, iop_version, avrcp_version);
1507 uint8_t* p_version = p_attr->value_ptr + 6;
1508 UINT16_TO_BE_FIELD(p_version, iop_version);
1509 return;
1510 }
1511
1512 // Dynamic AVRCP version. If our version high than remote device's version,
1513 // reply version same as its. Otherwise, reply default version.
1514 if (!osi_property_get_bool(AVRC_DYNAMIC_AVRCP_ENABLE_PROPERTY, true)) {
1515 log::info(
1516 "Dynamic AVRCP version feature is not enabled, skipping this method");
1517 return;
1518 }
1519
1520 // Read the remote device's AVRC Controller version from local storage
1521 uint16_t cached_version = 0;
1522 size_t version_value_size = btif_config_get_bin_length(
1523 bdaddr->ToString(), BTIF_STORAGE_KEY_AVRCP_CONTROLLER_VERSION);
1524 if (version_value_size != sizeof(cached_version)) {
1525 log::error("cached value len wrong, bdaddr={}. Len is {} but should be {}.",
1526 *bdaddr, version_value_size, sizeof(cached_version));
1527 return;
1528 }
1529
1530 if (!btif_config_get_bin(bdaddr->ToString(),
1531 BTIF_STORAGE_KEY_AVRCP_CONTROLLER_VERSION,
1532 (uint8_t*)&cached_version, &version_value_size)) {
1533 log::info(
1534 "no cached AVRC Controller version for {}. Reply default AVRC Target "
1535 "version {:x}.DUT AVRC Target version {:x}.",
1536 *bdaddr, avrcp_version, dut_avrcp_version);
1537 return;
1538 }
1539
1540 if (!spdu_is_avrcp_version_valid(cached_version)) {
1541 log::error(
1542 "cached AVRC Controller version {:x} of {} is not valid. Reply default "
1543 "AVRC Target version {:x}.",
1544 cached_version, *bdaddr, avrcp_version);
1545 return;
1546 }
1547
1548 if (!bluetooth::common::init_flags::
1549 dynamic_avrcp_version_enhancement_is_enabled() &&
1550 dut_avrcp_version <= cached_version) {
1551 return;
1552 }
1553
1554 uint16_t negotiated_avrcp_version =
1555 std::min(dut_avrcp_version, cached_version);
1556 log::info(
1557 "read cached AVRC Controller version {:x} of {}. DUT AVRC Target version "
1558 "{:x}.Negotiated AVRCP version to update peer {:x}.",
1559 cached_version, *bdaddr, dut_avrcp_version, negotiated_avrcp_version);
1560 uint8_t* p_version = p_attr->value_ptr + 6;
1561 UINT16_TO_BE_FIELD(p_version, negotiated_avrcp_version);
1562 }
1563 /*******************************************************************************
1564 *
1565 * Function sdpu_set_avrc_target_features
1566 *
1567 * Description This function is to set AVRCP version of A/V Remote Control
1568 * Target according to IOP table and cached Bluetooth config
1569 *
1570 * p_attr: attribute to be modified
1571 * bdaddr: for searching IOP table and BT config
1572 *
1573 * Returns void
1574 *
1575 ******************************************************************************/
sdpu_set_avrc_target_features(const tSDP_ATTRIBUTE * p_attr,const RawAddress * bdaddr,uint16_t avrcp_version)1576 void sdpu_set_avrc_target_features(const tSDP_ATTRIBUTE* p_attr,
1577 const RawAddress* bdaddr,
1578 uint16_t avrcp_version) {
1579 log::info("SDP AVRCP Version {:x}", avrcp_version);
1580
1581 if ((p_attr->id != ATTR_ID_SUPPORTED_FEATURES) || (p_attr->len != 2) ||
1582 (p_attr->value_ptr == nullptr)) {
1583 log::info("Invalid request for AVRC feature ignore");
1584 return;
1585 }
1586
1587 if (avrcp_version == 0) {
1588 log::info("AVRCP version not valid for device {}", *bdaddr);
1589 return;
1590 }
1591
1592 // Dynamic AVRCP version. If our version high than remote device's version,
1593 // reply version same as its. Otherwise, reply default version.
1594 if (!osi_property_get_bool(AVRC_DYNAMIC_AVRCP_ENABLE_PROPERTY, false)) {
1595 log::info(
1596 "Dynamic AVRCP version feature is not enabled, skipping this method");
1597 return;
1598 }
1599 // Read the remote device's AVRC Controller version from local storage
1600 uint16_t avrcp_peer_features = 0;
1601 size_t version_value_size = btif_config_get_bin_length(
1602 bdaddr->ToString(), BTIF_STORAGE_KEY_AV_REM_CTRL_FEATURES);
1603 if (version_value_size != sizeof(avrcp_peer_features)) {
1604 log::error("cached value len wrong, bdaddr={}. Len is {} but should be {}.",
1605 *bdaddr, version_value_size, sizeof(avrcp_peer_features));
1606 return;
1607 }
1608
1609 if (!btif_config_get_bin(
1610 bdaddr->ToString(), BTIF_STORAGE_KEY_AV_REM_CTRL_FEATURES,
1611 (uint8_t*)&avrcp_peer_features, &version_value_size)) {
1612 log::error("Unable to fetch cached AVRC features");
1613 return;
1614 }
1615
1616 bool browsing_supported =
1617 ((AVRCP_FEAT_BRW_BIT & avrcp_peer_features) == AVRCP_FEAT_BRW_BIT);
1618 bool coverart_supported =
1619 ((AVRCP_FEAT_CA_BIT & avrcp_peer_features) == AVRCP_FEAT_CA_BIT);
1620
1621 log::info(
1622 "SDP AVRCP DB Version 0x{:x}, browse supported {}, cover art supported "
1623 "{}",
1624 avrcp_peer_features, browsing_supported, coverart_supported);
1625 if (avrcp_version < AVRC_REV_1_4 || !browsing_supported) {
1626 log::info("Reset Browsing Feature");
1627 p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION] &=
1628 ~AVRCP_BROWSE_SUPPORT_BITMASK;
1629 p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION] &=
1630 ~AVRCP_MULTI_PLAYER_SUPPORT_BITMASK;
1631 }
1632
1633 if (avrcp_version < AVRC_REV_1_6 || !coverart_supported) {
1634 log::info("Reset CoverArt Feature");
1635 p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION - 1] &=
1636 ~AVRCP_CA_SUPPORT_BITMASK;
1637 }
1638
1639 if (avrcp_version >= AVRC_REV_1_4 && browsing_supported) {
1640 log::info("Set Browsing Feature");
1641 p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION] |=
1642 AVRCP_BROWSE_SUPPORT_BITMASK;
1643 p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION] |=
1644 AVRCP_MULTI_PLAYER_SUPPORT_BITMASK;
1645 }
1646
1647 if (avrcp_version == AVRC_REV_1_6 && coverart_supported) {
1648 log::info("Set CoverArt Feature");
1649 p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION - 1] |=
1650 AVRCP_CA_SUPPORT_BITMASK;
1651 }
1652 }
1653
sdp_get_num_records(const tSDP_DISCOVERY_DB & db)1654 size_t sdp_get_num_records(const tSDP_DISCOVERY_DB& db) {
1655 size_t num_sdp_records{0};
1656 const tSDP_DISC_REC* p_rec = db.p_first_rec;
1657 while (p_rec != nullptr) {
1658 num_sdp_records++;
1659 p_rec = p_rec->p_next_rec;
1660 }
1661 return num_sdp_records;
1662 }
1663
sdp_get_num_attributes(const tSDP_DISC_REC & sdp_disc_rec)1664 size_t sdp_get_num_attributes(const tSDP_DISC_REC& sdp_disc_rec) {
1665 size_t num_sdp_attributes{0};
1666 tSDP_DISC_ATTR* p_attr = sdp_disc_rec.p_first_attr;
1667 while (p_attr != nullptr) {
1668 num_sdp_attributes++;
1669 p_attr = p_attr->p_next_attr;
1670 }
1671 return num_sdp_attributes;
1672 }
1673