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