• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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