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