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