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 /******************************************************************************
20  *
21  *  This file contains functions that handle the SDP server functions.
22  *  This is mainly dealing with client requests
23  *
24  ******************************************************************************/
25 #define LOG_TAG "stack::sdp"
26 
27 #include <bluetooth/log.h>
28 #include <string.h>  // memcpy
29 
30 #include <cstdint>
31 
32 #include "btif/include/btif_storage.h"
33 #include "device/include/interop.h"
34 #include "device/include/interop_config.h"
35 #include "internal_include/bt_target.h"
36 #include "osi/include/allocator.h"
37 #include "osi/include/properties.h"
38 #include "stack/btm/btm_sco_hfp_hal.h"
39 #include "stack/include/bt_hdr.h"
40 #include "stack/include/bt_types.h"
41 #include "stack/include/bt_uuid16.h"
42 #include "stack/include/sdpdefs.h"
43 #include "stack/sdp/sdpint.h"
44 
45 /* Maximum number of bytes to reserve out of SDP MTU for response data */
46 #define SDP_MAX_SERVICE_RSPHDR_LEN 12
47 #define SDP_MAX_SERVATTR_RSPHDR_LEN 10
48 #define SDP_MAX_ATTR_RSPHDR_LEN 10
49 #define PROFILE_VERSION_POSITION 7
50 #define SDP_PROFILE_DESC_LENGTH 8
51 #define HFP_PROFILE_MINOR_VERSION_6 0x06
52 #define HFP_PROFILE_MINOR_VERSION_7 0x07
53 #define HFP_PROFILE_MINOR_VERSION_9 0x09
54 #define PBAP_GOEP_L2CAP_PSM_LEN 0x06
55 #define PBAP_SUPP_FEA_LEN 0x08
56 
57 #ifndef SDP_ENABLE_PTS_PBAP
58 #define SDP_ENABLE_PTS_PBAP "bluetooth.pts.pbap"
59 #endif
60 
61 #define PBAP_1_2 0x0102
62 #define PBAP_1_2_BL_LEN 14
63 
64 using namespace bluetooth;
65 
66 /* Used to set PBAP local SDP device record for PBAP 1.2 upgrade */
67 struct tSDP_PSE_LOCAL_RECORD {
68   int32_t rfcomm_channel_number;
69   int32_t l2cap_psm;
70   int32_t profile_version;
71   uint32_t supported_features;
72   uint32_t supported_repositories;
73 };
74 
75 static tSDP_PSE_LOCAL_RECORD sdpPseLocalRecord;
76 
77 /******************************************************************************/
78 /*                E R R O R   T E X T   S T R I N G S                         */
79 /*                                                                            */
80 /* The default is to have no text string, but we allow the strings to be      */
81 /* configured in target.h if people want them.                                */
82 /******************************************************************************/
83 #ifndef SDP_TEXT_BAD_HEADER
84 #define SDP_TEXT_BAD_HEADER NULL
85 #endif
86 
87 #ifndef SDP_TEXT_BAD_PDU
88 #define SDP_TEXT_BAD_PDU NULL
89 #endif
90 
91 #ifndef SDP_TEXT_BAD_UUID_LIST
92 #define SDP_TEXT_BAD_UUID_LIST NULL
93 #endif
94 
95 #ifndef SDP_TEXT_BAD_HANDLE
96 #define SDP_TEXT_BAD_HANDLE NULL
97 #endif
98 
99 #ifndef SDP_TEXT_BAD_ATTR_LIST
100 #define SDP_TEXT_BAD_ATTR_LIST NULL
101 #endif
102 
103 #ifndef SDP_TEXT_BAD_CONT_LEN
104 #define SDP_TEXT_BAD_CONT_LEN NULL
105 #endif
106 
107 #ifndef SDP_TEXT_BAD_CONT_INX
108 #define SDP_TEXT_BAD_CONT_INX NULL
109 #endif
110 
111 #ifndef SDP_TEXT_BAD_MAX_RECORDS_LIST
112 #define SDP_TEXT_BAD_MAX_RECORDS_LIST NULL
113 #endif
114 
115 /*************************************************************************************
116 **
117 ** Function        sdp_dynamic_change_hfp_version
118 **
119 ** Description     Checks if UUID is AG_HANDSFREE, attribute id
120 **                 is Profile descriptor list and remote BD address
121 **                 matches device Allow list, change hfp version to 1.7
122 **
123 ** Returns         BOOLEAN
124 **
125 +***************************************************************************************/
sdp_dynamic_change_hfp_version(const tSDP_ATTRIBUTE * p_attr,const RawAddress & remote_address)126 bool sdp_dynamic_change_hfp_version(const tSDP_ATTRIBUTE* p_attr,
127                                     const RawAddress& remote_address) {
128   if ((p_attr->id != ATTR_ID_BT_PROFILE_DESC_LIST) || (p_attr->len < SDP_PROFILE_DESC_LENGTH)) {
129     return false;
130   }
131   /* As per current DB implementation UUID is condidered as 16 bit */
132   if (((p_attr->value_ptr[3] << SDP_PROFILE_DESC_LENGTH) | (p_attr->value_ptr[4])) !=
133       UUID_SERVCLASS_HF_HANDSFREE) {
134     return false;
135   }
136   bool is_allowlisted_1_7 = interop_match_addr_or_name(INTEROP_HFP_1_7_ALLOWLIST, &remote_address,
137                                                        &btif_storage_get_remote_device_property);
138   bool is_allowlisted_1_9 = interop_match_addr_or_name(INTEROP_HFP_1_9_ALLOWLIST, &remote_address,
139                                                        &btif_storage_get_remote_device_property);
140   /* For PTS we should update AG's HFP version as 1.7 */
141   if (!(is_allowlisted_1_7) && !(is_allowlisted_1_9) &&
142       !(osi_property_get_bool("vendor.bt.pts.certification", false))) {
143     return false;
144   }
145   if (hfp_hal_interface::get_swb_supported() && is_allowlisted_1_9) {
146     p_attr->value_ptr[PROFILE_VERSION_POSITION] = HFP_PROFILE_MINOR_VERSION_9;
147   } else {
148     p_attr->value_ptr[PROFILE_VERSION_POSITION] = HFP_PROFILE_MINOR_VERSION_7;
149   }
150   log::verbose("SDP Change HFP Version = {} for {}", p_attr->value_ptr[PROFILE_VERSION_POSITION],
151                remote_address);
152   return true;
153 }
154 /******************************************************************************
155  *
156  * Function         hfp_fallback
157  *
158  * Description      Update HFP version back to 1.6
159  *
160  * Returns          void
161  *
162  *****************************************************************************/
hfp_fallback(bool & is_hfp_fallback,const tSDP_ATTRIBUTE * p_attr)163 static void hfp_fallback(bool& is_hfp_fallback, const tSDP_ATTRIBUTE* p_attr) {
164   /* Update HFP version back to 1.6 */
165   p_attr->value_ptr[PROFILE_VERSION_POSITION] = HFP_PROFILE_MINOR_VERSION_6;
166   log::verbose("Restore HFP version to 1.6");
167   is_hfp_fallback = false;
168 }
169 
170 /*******************************************************************************
171  *
172  * Function         process_service_search
173  *
174  * Description      This function handles a service search request from the
175  *                  client. It builds a reply message with info from the
176  *                  database, and sends the reply back to the client.
177  *
178  * Returns          void
179  *
180  ******************************************************************************/
process_service_search(tCONN_CB * p_ccb,uint16_t trans_num,uint16_t param_len,uint8_t * p_req,uint8_t * p_req_end)181 static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num, uint16_t param_len,
182                                    uint8_t* p_req, uint8_t* p_req_end) {
183   uint16_t max_replies, cur_handles, rem_handles, cont_offset;
184   tSDP_UUID_SEQ uid_seq;
185   uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
186   uint16_t rsp_param_len, num_rsp_handles, xx;
187   uint32_t rsp_handles[SDP_MAX_RECORDS] = {0};
188   const tSDP_RECORD* p_rec = NULL;
189   bool is_cont = false;
190 
191   p_req = sdpu_extract_uid_seq(p_req, param_len, &uid_seq);
192 
193   if ((!p_req) || (!uid_seq.num_uids)) {
194     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_REQ_SYNTAX,
195                             SDP_TEXT_BAD_UUID_LIST);
196     return;
197   }
198 
199   /* Get the max replies we can send. Cap it at our max anyways. */
200   if (p_req + sizeof(max_replies) + sizeof(uint8_t) > p_req_end) {
201     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_REQ_SYNTAX,
202                             SDP_TEXT_BAD_MAX_RECORDS_LIST);
203     return;
204   }
205   BE_STREAM_TO_UINT16(max_replies, p_req);
206 
207   if (max_replies > SDP_MAX_RECORDS) {
208     max_replies = SDP_MAX_RECORDS;
209   }
210 
211   /* Get a list of handles that match the UUIDs given to us */
212   for (num_rsp_handles = 0; num_rsp_handles < max_replies;) {
213     p_rec = sdp_db_service_search(p_rec, &uid_seq);
214 
215     if (p_rec) {
216       rsp_handles[num_rsp_handles++] = p_rec->record_handle;
217     } else {
218       break;
219     }
220   }
221 
222   /* Check if this is a continuation request */
223   if (p_req + 1 > p_req_end) {
224     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE,
225                             SDP_TEXT_BAD_CONT_LEN);
226     return;
227   }
228   if (*p_req) {
229     if (*p_req++ != SDP_CONTINUATION_LEN || (p_req + sizeof(cont_offset) > p_req_end)) {
230       sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE,
231                               SDP_TEXT_BAD_CONT_LEN);
232       return;
233     }
234     BE_STREAM_TO_UINT16(cont_offset, p_req);
235 
236     if (cont_offset != p_ccb->cont_offset || num_rsp_handles < cont_offset) {
237       sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE,
238                               SDP_TEXT_BAD_CONT_INX);
239       return;
240     }
241 
242     rem_handles = num_rsp_handles - cont_offset; /* extract the remaining handles */
243   } else {
244     rem_handles = num_rsp_handles;
245     cont_offset = 0;
246     p_ccb->cont_offset = 0;
247   }
248 
249   /* Calculate how many handles will fit in one PDU */
250   cur_handles = (uint16_t)((p_ccb->rem_mtu_size - SDP_MAX_SERVICE_RSPHDR_LEN) / 4);
251 
252   if (rem_handles <= cur_handles) {
253     cur_handles = rem_handles;
254   } else /* Continuation is set */
255   {
256     p_ccb->cont_offset += cur_handles;
257     is_cont = true;
258   }
259 
260   /* Get a buffer to use to build the response */
261   BT_HDR* p_buf = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
262   p_buf->offset = L2CAP_MIN_OFFSET;
263   p_rsp = p_rsp_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
264 
265   /* Start building a rsponse */
266   UINT8_TO_BE_STREAM(p_rsp, SDP_PDU_SERVICE_SEARCH_RSP);
267   UINT16_TO_BE_STREAM(p_rsp, trans_num);
268 
269   /* Skip the length, we need to add it at the end */
270   p_rsp_param_len = p_rsp;
271   p_rsp += 2;
272 
273   /* Put in total and current number of handles, and handles themselves */
274   UINT16_TO_BE_STREAM(p_rsp, num_rsp_handles);
275   UINT16_TO_BE_STREAM(p_rsp, cur_handles);
276 
277   /*
278     log::verbose("SDP Service Rsp: tothdl {}, curhdlr {}, start {}, end {}, cont
279     {}", num_rsp_handles, cur_handles, cont_offset, cont_offset + cur_handles-1,
280     is_cont); */
281   for (xx = cont_offset; xx < cont_offset + cur_handles; xx++) {
282     UINT32_TO_BE_STREAM(p_rsp, rsp_handles[xx]);
283   }
284 
285   if (is_cont) {
286     UINT8_TO_BE_STREAM(p_rsp, SDP_CONTINUATION_LEN);
287     UINT16_TO_BE_STREAM(p_rsp, p_ccb->cont_offset);
288   } else {
289     UINT8_TO_BE_STREAM(p_rsp, 0);
290   }
291 
292   /* Go back and put the parameter length into the buffer */
293   rsp_param_len = p_rsp - p_rsp_param_len - 2;
294   UINT16_TO_BE_STREAM(p_rsp_param_len, rsp_param_len);
295 
296   /* Set the length of the SDP data in the buffer */
297   p_buf->len = p_rsp - p_rsp_start;
298 
299   /* Send the buffer through L2CAP */
300   if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_buf) !=
301       tL2CAP_DW_RESULT::SUCCESS) {
302     log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address,
303               p_ccb->connection_id, p_rsp - p_rsp_start);
304   }
305 }
306 
307 /*******************************************************************************
308  *
309  * Function         process_service_attr_req
310  *
311  * Description      This function handles an attribute request from the client.
312  *                  It builds a reply message with info from the database,
313  *                  and sends the reply back to the client.
314  *
315  * Returns          void
316  *
317  ******************************************************************************/
process_service_attr_req(tCONN_CB * p_ccb,uint16_t trans_num,uint16_t param_len,uint8_t * p_req,uint8_t * p_req_end)318 static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, uint16_t param_len,
319                                      uint8_t* p_req, uint8_t* p_req_end) {
320   uint16_t max_list_len, len_to_send, cont_offset;
321   int16_t rem_len;
322   tSDP_ATTR_SEQ attr_seq, attr_seq_sav;
323   uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
324   uint16_t rsp_param_len, xx;
325   uint32_t rec_handle;
326   const tSDP_RECORD* p_rec;
327   const tSDP_ATTRIBUTE* p_attr;
328   bool is_cont = false;
329   bool is_hfp_fallback = false;
330   uint16_t attr_len;
331 
332   if (p_req + sizeof(rec_handle) + sizeof(max_list_len) > p_req_end) {
333     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_SERV_REC_HDL,
334                             SDP_TEXT_BAD_HANDLE);
335     return;
336   }
337 
338   /* Extract the record handle */
339   BE_STREAM_TO_UINT32(rec_handle, p_req);
340   param_len -= sizeof(rec_handle);
341 
342   /* Get the max list length we can send. Cap it at MTU size minus overhead */
343   BE_STREAM_TO_UINT16(max_list_len, p_req);
344   param_len -= sizeof(max_list_len);
345 
346   if (max_list_len > (p_ccb->rem_mtu_size - SDP_MAX_ATTR_RSPHDR_LEN)) {
347     max_list_len = p_ccb->rem_mtu_size - SDP_MAX_ATTR_RSPHDR_LEN;
348   }
349 
350   p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);
351 
352   if ((!p_req) || (!attr_seq.num_attr) || (p_req + sizeof(uint8_t) > p_req_end)) {
353     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_REQ_SYNTAX,
354                             SDP_TEXT_BAD_ATTR_LIST);
355     return;
356   }
357 
358   memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ));
359 
360   /* Find a record with the record handle */
361   p_rec = sdp_db_find_record(rec_handle);
362   if (!p_rec) {
363     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_SERV_REC_HDL,
364                             SDP_TEXT_BAD_HANDLE);
365     return;
366   }
367 
368   if (max_list_len < 4) {
369     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_ILLEGAL_PARAMETER, NULL);
370     return;
371   }
372 
373   /* Free and reallocate buffer */
374   osi_free(p_ccb->rsp_list);
375   p_ccb->rsp_list = (uint8_t*)osi_malloc(max_list_len);
376 
377   /* Check if this is a continuation request */
378   if (p_req + 1 > p_req_end) {
379     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE,
380                             SDP_TEXT_BAD_CONT_LEN);
381     return;
382   }
383   if (*p_req) {
384     if (*p_req++ != SDP_CONTINUATION_LEN || (p_req + sizeof(cont_offset) > p_req_end)) {
385       sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE,
386                               SDP_TEXT_BAD_CONT_LEN);
387       return;
388     }
389     BE_STREAM_TO_UINT16(cont_offset, p_req);
390 
391     if (cont_offset != p_ccb->cont_offset) {
392       sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE,
393                               SDP_TEXT_BAD_CONT_INX);
394       return;
395     }
396     is_cont = true;
397 
398     /* Initialise for continuation response */
399     p_rsp = &p_ccb->rsp_list[0];
400     attr_seq.attr_entry[p_ccb->cont_info.next_attr_index].start =
401             p_ccb->cont_info.next_attr_start_id;
402   } else {
403     p_ccb->cont_offset = 0;
404     p_rsp = &p_ccb->rsp_list[3]; /* Leave space for data elem descr */
405 
406     /* Reset continuation parameters in p_ccb */
407     p_ccb->cont_info.prev_sdp_rec = NULL;
408     p_ccb->cont_info.next_attr_index = 0;
409     p_ccb->cont_info.attr_offset = 0;
410   }
411 
412   bool is_service_avrc_target = false;
413   const tSDP_ATTRIBUTE* p_attr_service_id;
414   const tSDP_ATTRIBUTE* p_attr_profile_desc_list_id;
415   uint16_t avrc_sdp_version = 0;
416   p_attr_service_id = sdp_db_find_attr_in_rec(p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST,
417                                               ATTR_ID_SERVICE_CLASS_ID_LIST);
418   p_attr_profile_desc_list_id = sdp_db_find_attr_in_rec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST,
419                                                         ATTR_ID_BT_PROFILE_DESC_LIST);
420   if (p_attr_service_id) {
421     is_service_avrc_target = sdpu_is_service_id_avrc_target(p_attr_service_id);
422   }
423   /* Search for attributes that match the list given to us */
424   for (xx = p_ccb->cont_info.next_attr_index; xx < attr_seq.num_attr; xx++) {
425     p_attr = sdp_db_find_attr_in_rec(p_rec, attr_seq.attr_entry[xx].start,
426                                      attr_seq.attr_entry[xx].end);
427     if (p_attr) {
428       if (is_service_avrc_target) {
429         sdpu_set_avrc_target_version(p_attr, &(p_ccb->device_address));
430         if (p_attr->id == ATTR_ID_SUPPORTED_FEATURES) {
431           avrc_sdp_version = sdpu_is_avrcp_profile_description_list(p_attr_profile_desc_list_id);
432           log::error("avrc_sdp_version in SDP records {:x}", avrc_sdp_version);
433           sdpu_set_avrc_target_features(p_attr, &(p_ccb->device_address), avrc_sdp_version);
434         }
435       }
436       is_hfp_fallback = sdp_dynamic_change_hfp_version(p_attr, p_ccb->device_address);
437       /* Check if attribute fits. Assume 3-byte value type/length */
438       rem_len = max_list_len - (int16_t)(p_rsp - &p_ccb->rsp_list[0]);
439 
440       /* just in case */
441       if (rem_len <= 0) {
442         p_ccb->cont_info.next_attr_index = xx;
443         p_ccb->cont_info.next_attr_start_id = p_attr->id;
444         break;
445       }
446 
447       attr_len = sdpu_get_attrib_entry_len(p_attr);
448       /* if there is a partial attribute pending to be sent */
449       if (p_ccb->cont_info.attr_offset) {
450         if (attr_len < p_ccb->cont_info.attr_offset) {
451           log::error("offset is bigger than attribute length");
452           sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE,
453                                   SDP_TEXT_BAD_CONT_LEN);
454           return;
455         }
456         p_rsp = sdpu_build_partial_attrib_entry(p_rsp, p_attr, rem_len,
457                                                 &p_ccb->cont_info.attr_offset);
458 
459         /* If the partial attrib could not been fully added yet */
460         if (p_ccb->cont_info.attr_offset != attr_len) {
461           break;
462         } else { /* If the partial attrib has been added in full by now */
463           p_ccb->cont_info.attr_offset = 0; /* reset attr_offset */
464         }
465       } else if (rem_len < attr_len) /* Not enough space for attr... so add partially */
466       {
467         if (attr_len >= SDP_MAX_ATTR_LEN) {
468           log::error("SDP attr too big: max_list_len={},attr_len={}", max_list_len, attr_len);
469           sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_NO_RESOURCES, NULL);
470           return;
471         }
472 
473         /* add the partial attribute if possible */
474         p_rsp = sdpu_build_partial_attrib_entry(p_rsp, p_attr, (uint16_t)rem_len,
475                                                 &p_ccb->cont_info.attr_offset);
476 
477         p_ccb->cont_info.next_attr_index = xx;
478         p_ccb->cont_info.next_attr_start_id = p_attr->id;
479         break;
480       } else { /* build the whole attribute */
481         p_rsp = sdpu_build_attrib_entry(p_rsp, p_attr);
482       }
483 
484       /* If doing a range, stick with this one till no more attributes found */
485       if (attr_seq.attr_entry[xx].start != attr_seq.attr_entry[xx].end) {
486         /* Update for next time through */
487         attr_seq.attr_entry[xx].start = p_attr->id + 1;
488 
489         xx--;
490       }
491       if (is_hfp_fallback) {
492         hfp_fallback(is_hfp_fallback, p_attr);
493       }
494     }
495   }
496   if (is_hfp_fallback) {
497     hfp_fallback(is_hfp_fallback, p_attr);
498   }
499   /* If all the attributes have been accomodated in p_rsp,
500      reset next_attr_index */
501   if (xx == attr_seq.num_attr) {
502     p_ccb->cont_info.next_attr_index = 0;
503   }
504 
505   len_to_send = (uint16_t)(p_rsp - &p_ccb->rsp_list[0]);
506   cont_offset = 0;
507 
508   if (!is_cont) {
509     p_ccb->list_len = sdpu_get_attrib_seq_len(p_rec, &attr_seq_sav) + 3;
510     /* Put in the sequence header (2 or 3 bytes) */
511     if (p_ccb->list_len > 255) {
512       p_ccb->rsp_list[0] = (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
513       p_ccb->rsp_list[1] = (uint8_t)((p_ccb->list_len - 3) >> 8);
514       p_ccb->rsp_list[2] = (uint8_t)(p_ccb->list_len - 3);
515     } else {
516       cont_offset = 1;
517 
518       p_ccb->rsp_list[1] = (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
519       p_ccb->rsp_list[2] = (uint8_t)(p_ccb->list_len - 3);
520 
521       p_ccb->list_len--;
522       len_to_send--;
523     }
524   }
525 
526   /* Get a buffer to use to build the response */
527   BT_HDR* p_buf = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
528   p_buf->offset = L2CAP_MIN_OFFSET;
529   p_rsp = p_rsp_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
530 
531   /* Start building a rsponse */
532   UINT8_TO_BE_STREAM(p_rsp, SDP_PDU_SERVICE_ATTR_RSP);
533   UINT16_TO_BE_STREAM(p_rsp, trans_num);
534 
535   /* Skip the parameter length, add it when we know the length */
536   p_rsp_param_len = p_rsp;
537   p_rsp += 2;
538 
539   UINT16_TO_BE_STREAM(p_rsp, len_to_send);
540 
541   memcpy(p_rsp, &p_ccb->rsp_list[cont_offset], len_to_send);
542   p_rsp += len_to_send;
543 
544   p_ccb->cont_offset += len_to_send;
545 
546   /* If anything left to send, continuation needed */
547   if (p_ccb->cont_offset < p_ccb->list_len) {
548     is_cont = true;
549 
550     UINT8_TO_BE_STREAM(p_rsp, SDP_CONTINUATION_LEN);
551     UINT16_TO_BE_STREAM(p_rsp, p_ccb->cont_offset);
552   } else {
553     UINT8_TO_BE_STREAM(p_rsp, 0);
554   }
555 
556   /* Go back and put the parameter length into the buffer */
557   rsp_param_len = p_rsp - p_rsp_param_len - 2;
558   UINT16_TO_BE_STREAM(p_rsp_param_len, rsp_param_len);
559 
560   /* Set the length of the SDP data in the buffer */
561   p_buf->len = p_rsp - p_rsp_start;
562 
563   /* Send the buffer through L2CAP */
564   if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_buf) !=
565       tL2CAP_DW_RESULT::SUCCESS) {
566     log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address,
567               p_ccb->connection_id, p_rsp - p_rsp_start);
568   }
569 }
570 
571 /*******************************************************************************
572  *
573  * Function         process_service_search_attr_req
574  *
575  * Description      This function handles a combined service search and
576  *                  attribute read request from the client. It builds a reply
577  *                  message with info from the database, and sends the reply
578  *                  back to the client.
579  *
580  * Returns          void
581  *
582  ******************************************************************************/
process_service_search_attr_req(tCONN_CB * p_ccb,uint16_t trans_num,uint16_t param_len,uint8_t * p_req,uint8_t * p_req_end)583 static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, uint16_t param_len,
584                                             uint8_t* p_req, uint8_t* p_req_end) {
585   uint16_t max_list_len;
586   int16_t rem_len;
587   uint16_t len_to_send, cont_offset;
588   tSDP_UUID_SEQ uid_seq;
589   uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
590   uint16_t rsp_param_len, xx;
591   const tSDP_RECORD* p_rec;
592   tSDP_RECORD* p_prev_rec;
593   tSDP_ATTR_SEQ attr_seq, attr_seq_sav;
594   const tSDP_ATTRIBUTE* p_attr;
595   bool maxxed_out = false, is_cont = false;
596   uint8_t* p_seq_start;
597   bool is_hfp_fallback = false;
598   uint16_t seq_len, attr_len;
599 
600   /* Extract the UUID sequence to search for */
601   p_req = sdpu_extract_uid_seq(p_req, param_len, &uid_seq);
602 
603   if ((!p_req) || (!uid_seq.num_uids) || (p_req + sizeof(uint16_t) > p_req_end)) {
604     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_REQ_SYNTAX,
605                             SDP_TEXT_BAD_UUID_LIST);
606     return;
607   }
608 
609   /* Get the max list length we can send. Cap it at our max list length. */
610   BE_STREAM_TO_UINT16(max_list_len, p_req);
611 
612   if (max_list_len > (p_ccb->rem_mtu_size - SDP_MAX_SERVATTR_RSPHDR_LEN)) {
613     max_list_len = p_ccb->rem_mtu_size - SDP_MAX_SERVATTR_RSPHDR_LEN;
614   }
615 
616   param_len = static_cast<uint16_t>(p_req_end - p_req);
617   p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);
618 
619   if ((!p_req) || (!attr_seq.num_attr) || (p_req + sizeof(uint8_t) > p_req_end)) {
620     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_REQ_SYNTAX,
621                             SDP_TEXT_BAD_ATTR_LIST);
622     return;
623   }
624 
625   memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ));
626 
627   if (max_list_len < 4) {
628     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_ILLEGAL_PARAMETER, NULL);
629     return;
630   }
631 
632   /* Free and reallocate buffer */
633   osi_free(p_ccb->rsp_list);
634   p_ccb->rsp_list = (uint8_t*)osi_malloc(max_list_len);
635 
636   /* Check if this is a continuation request */
637   if (p_req + 1 > p_req_end) {
638     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE,
639                             SDP_TEXT_BAD_CONT_LEN);
640     return;
641   }
642   if (*p_req) {
643     if (*p_req++ != SDP_CONTINUATION_LEN || (p_req + sizeof(uint16_t) > p_req_end)) {
644       sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE,
645                               SDP_TEXT_BAD_CONT_LEN);
646       return;
647     }
648     BE_STREAM_TO_UINT16(cont_offset, p_req);
649 
650     if (cont_offset != p_ccb->cont_offset) {
651       sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE,
652                               SDP_TEXT_BAD_CONT_INX);
653       return;
654     }
655     is_cont = true;
656 
657     /* Initialise for continuation response */
658     p_rsp = &p_ccb->rsp_list[0];
659     attr_seq.attr_entry[p_ccb->cont_info.next_attr_index].start =
660             p_ccb->cont_info.next_attr_start_id;
661   } else {
662     p_ccb->cont_offset = 0;
663     p_rsp = &p_ccb->rsp_list[3]; /* Leave space for data elem descr */
664 
665     /* Reset continuation parameters in p_ccb */
666     p_ccb->cont_info.prev_sdp_rec = NULL;
667     p_ccb->cont_info.next_attr_index = 0;
668     p_ccb->cont_info.last_attr_seq_desc_sent = false;
669     p_ccb->cont_info.attr_offset = 0;
670   }
671 
672   /* Get a list of handles that match the UUIDs given to us */
673   for (p_rec = sdp_db_service_search(p_ccb->cont_info.prev_sdp_rec, &uid_seq); p_rec;
674        p_rec = sdp_db_service_search(p_rec, &uid_seq)) {
675     /* Store the actual record pointer which would be reused later */
676     p_prev_rec = (tSDP_RECORD*)p_rec;
677     /* Allow space for attribute sequence type and length */
678     p_seq_start = p_rsp;
679     if (!p_ccb->cont_info.last_attr_seq_desc_sent) {
680       /* See if there is enough room to include a new service in the current
681        * response */
682       rem_len = max_list_len - (int16_t)(p_rsp - &p_ccb->rsp_list[0]);
683       if (rem_len < 3) {
684         /* Not enough room. Update continuation info for next response */
685         p_ccb->cont_info.next_attr_index = 0;
686         p_ccb->cont_info.next_attr_start_id = attr_seq.attr_entry[0].start;
687         break;
688       }
689       p_rsp += 3;
690     }
691 
692     bool is_service_avrc_target = false;
693     const tSDP_ATTRIBUTE* p_attr_service_id;
694     const tSDP_ATTRIBUTE* p_attr_profile_desc_list_id;
695     uint16_t avrc_sdp_version = 0;
696     p_attr_service_id = sdp_db_find_attr_in_rec(p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST,
697                                                 ATTR_ID_SERVICE_CLASS_ID_LIST);
698     p_attr_profile_desc_list_id = sdp_db_find_attr_in_rec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST,
699                                                           ATTR_ID_BT_PROFILE_DESC_LIST);
700     if (p_attr_service_id) {
701       is_service_avrc_target = sdpu_is_service_id_avrc_target(p_attr_service_id);
702     }
703     /* Get a list of handles that match the UUIDs given to us */
704     for (xx = p_ccb->cont_info.next_attr_index; xx < attr_seq.num_attr; xx++) {
705       p_attr = sdp_db_find_attr_in_rec(p_rec, attr_seq.attr_entry[xx].start,
706                                        attr_seq.attr_entry[xx].end);
707 
708       if (p_attr) {
709         if (is_service_avrc_target) {
710           sdpu_set_avrc_target_version(p_attr, &(p_ccb->device_address));
711           if (p_attr->id == ATTR_ID_SUPPORTED_FEATURES && p_attr_profile_desc_list_id != nullptr) {
712             avrc_sdp_version = sdpu_is_avrcp_profile_description_list(p_attr_profile_desc_list_id);
713             log::error("avrc_sdp_version in SDP records {:x}", avrc_sdp_version);
714             sdpu_set_avrc_target_features(p_attr, &(p_ccb->device_address), avrc_sdp_version);
715           }
716         }
717         is_hfp_fallback = sdp_dynamic_change_hfp_version(p_attr, p_ccb->device_address);
718         /* Check if attribute fits. Assume 3-byte value type/length */
719         rem_len = max_list_len - (int16_t)(p_rsp - &p_ccb->rsp_list[0]);
720 
721         /* just in case */
722         if (rem_len <= 0) {
723           p_ccb->cont_info.next_attr_index = xx;
724           p_ccb->cont_info.next_attr_start_id = p_attr->id;
725           maxxed_out = true;
726           break;
727         }
728 
729         attr_len = sdpu_get_attrib_entry_len(p_attr);
730         /* if there is a partial attribute pending to be sent */
731         if (p_ccb->cont_info.attr_offset) {
732           if (attr_len < p_ccb->cont_info.attr_offset) {
733             log::error("offset is bigger than attribute length");
734             sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE,
735                                     SDP_TEXT_BAD_CONT_LEN);
736             return;
737           }
738           p_rsp = sdpu_build_partial_attrib_entry(p_rsp, p_attr, rem_len,
739                                                   &p_ccb->cont_info.attr_offset);
740 
741           /* If the partial attrib could not been fully added yet */
742           if (p_ccb->cont_info.attr_offset != attr_len) {
743             maxxed_out = true;
744             break;
745           } else { /* If the partial attrib has been added in full by now */
746             p_ccb->cont_info.attr_offset = 0; /* reset attr_offset */
747           }
748         } else if (rem_len < attr_len) /* Not enough space for attr... so add partially */
749         {
750           if (attr_len >= SDP_MAX_ATTR_LEN) {
751             log::error("SDP attr too big: max_list_len={},attr_len={}", max_list_len, attr_len);
752             sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_NO_RESOURCES, NULL);
753             return;
754           }
755 
756           /* add the partial attribute if possible */
757           p_rsp = sdpu_build_partial_attrib_entry(p_rsp, p_attr, (uint16_t)rem_len,
758                                                   &p_ccb->cont_info.attr_offset);
759 
760           p_ccb->cont_info.next_attr_index = xx;
761           p_ccb->cont_info.next_attr_start_id = p_attr->id;
762           maxxed_out = true;
763           break;
764         } else { /* build the whole attribute */
765           p_rsp = sdpu_build_attrib_entry(p_rsp, p_attr);
766         }
767 
768         /* If doing a range, stick with this one till no more attributes found
769          */
770         if (attr_seq.attr_entry[xx].start != attr_seq.attr_entry[xx].end) {
771           /* Update for next time through */
772           attr_seq.attr_entry[xx].start = p_attr->id + 1;
773 
774           xx--;
775         }
776         if (is_hfp_fallback) {
777           hfp_fallback(is_hfp_fallback, p_attr);
778         }
779       }
780     }
781     if (is_hfp_fallback) {
782       hfp_fallback(is_hfp_fallback, p_attr);
783     }
784 
785     /* Go back and put the type and length into the buffer */
786     if (!p_ccb->cont_info.last_attr_seq_desc_sent) {
787       seq_len = sdpu_get_attrib_seq_len(p_rec, &attr_seq_sav);
788       if (seq_len != 0) {
789         UINT8_TO_BE_STREAM(p_seq_start, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
790         UINT16_TO_BE_STREAM(p_seq_start, seq_len);
791 
792         if (maxxed_out) {
793           p_ccb->cont_info.last_attr_seq_desc_sent = true;
794         }
795       } else {
796         p_rsp = p_seq_start;
797       }
798     }
799 
800     if (maxxed_out) {
801       break;
802     }
803 
804     /* Restore the attr_seq to look for in the next sdp record */
805     memcpy(&attr_seq, &attr_seq_sav, sizeof(tSDP_ATTR_SEQ));
806 
807     /* Reset the next attr index */
808     p_ccb->cont_info.next_attr_index = 0;
809     /* restore the record pointer.*/
810     p_rec = p_prev_rec;
811     p_ccb->cont_info.prev_sdp_rec = p_rec;
812     p_ccb->cont_info.last_attr_seq_desc_sent = false;
813   }
814 
815   /* response length */
816   len_to_send = (uint16_t)(p_rsp - &p_ccb->rsp_list[0]);
817   cont_offset = 0;
818 
819   // The current SDP server design has a critical flaw where it can run into
820   // an infinite request/response loop with the client. Here's the scenario:
821   // - client makes SDP request
822   // - server returns the first fragment of the response with a continuation
823   //   token
824   // - an SDP record is deleted from the server
825   // - client issues another request with previous continuation token
826   // - server has nothing to send back because the record is unavailable but
827   //   in the first fragment, it had specified more response bytes than are
828   //   now available
829   // - server sends back no additional response bytes and returns the same
830   //   continuation token
831   // - client issues another request with the continuation token, and the
832   //   process repeats
833   //
834   // We work around this design flaw here by checking if we will make forward
835   // progress (i.e. we will send > 0 response bytes) on a continued request.
836   // If not, we must have run into the above situation and we tell the peer an
837   // error occurred.
838   //
839   // TODO(sharvil): rewrite SDP server.
840   if (is_cont && len_to_send == 0) {
841     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_CONT_STATE, NULL);
842     return;
843   }
844 
845   /* If first response, insert sequence header */
846   if (!is_cont) {
847     /* Get the total list length for requested uid and attribute sequence */
848     p_ccb->list_len = sdpu_get_list_len(&uid_seq, &attr_seq_sav) + 3;
849 
850     /* Get the length of denylisted attributes to be updated if device is
851      * denylisted */
852     p_ccb->pse_dynamic_attributes_len = 0;
853 
854     log::verbose("p_ccb->list_len = {} pse_dynamic_attributes_len = {}", p_ccb->list_len,
855                  p_ccb->pse_dynamic_attributes_len);
856 
857     /* Put in the sequence header (2 or 3 bytes) */
858     if (p_ccb->list_len > 255) {
859       p_ccb->rsp_list[0] = (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
860       p_ccb->rsp_list[1] =
861               (uint8_t)((p_ccb->list_len - 3 + p_ccb->pse_dynamic_attributes_len) >> 8);
862       p_ccb->rsp_list[2] = (uint8_t)(p_ccb->list_len - 3 + p_ccb->pse_dynamic_attributes_len);
863     } else {
864       cont_offset = 1;
865 
866       p_ccb->rsp_list[1] = (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
867       p_ccb->rsp_list[2] = (uint8_t)(p_ccb->list_len - 3 + p_ccb->pse_dynamic_attributes_len);
868 
869       p_ccb->list_len--;
870       len_to_send--;
871     }
872   }
873 
874   /* Get a buffer to use to build the response */
875   BT_HDR* p_buf = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
876   p_buf->offset = L2CAP_MIN_OFFSET;
877   p_rsp = p_rsp_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
878 
879   /* Start building a rsponse */
880   UINT8_TO_BE_STREAM(p_rsp, SDP_PDU_SERVICE_SEARCH_ATTR_RSP);
881   UINT16_TO_BE_STREAM(p_rsp, trans_num);
882 
883   /* Skip the parameter length, add it when we know the length */
884   p_rsp_param_len = p_rsp;
885   p_rsp += 2;
886 
887   /* Stream the list length to send */
888   UINT16_TO_BE_STREAM(p_rsp, len_to_send);
889 
890   /* copy from rsp_list to the actual buffer to be sent */
891   memcpy(p_rsp, &p_ccb->rsp_list[cont_offset], len_to_send);
892   p_rsp += len_to_send;
893 
894   p_ccb->cont_offset += len_to_send;
895 
896   log::verbose(
897           "p_ccb->pse_dynamic_attributes_len {}, cont_offset = {}, p_ccb->list_len "
898           "= {}",
899           p_ccb->pse_dynamic_attributes_len, p_ccb->cont_offset,
900           p_ccb->list_len + p_ccb->pse_dynamic_attributes_len);
901   /* If anything left to send, continuation needed */
902   if (p_ccb->cont_offset < (p_ccb->list_len + p_ccb->pse_dynamic_attributes_len)) {
903     is_cont = true;
904     UINT8_TO_BE_STREAM(p_rsp, SDP_CONTINUATION_LEN);
905     UINT16_TO_BE_STREAM(p_rsp, p_ccb->cont_offset);
906   } else {
907     UINT8_TO_BE_STREAM(p_rsp, 0);
908     if (p_ccb->pse_dynamic_attributes_len) {
909       p_ccb->pse_dynamic_attributes_len = 0;
910     }
911   }
912 
913   /* Go back and put the parameter length into the buffer */
914   rsp_param_len = p_rsp - p_rsp_param_len - 2;
915   UINT16_TO_BE_STREAM(p_rsp_param_len, rsp_param_len);
916 
917   /* Set the length of the SDP data in the buffer */
918   p_buf->len = p_rsp - p_rsp_start;
919 
920   /* Send the buffer through L2CAP */
921   if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_buf) !=
922       tL2CAP_DW_RESULT::SUCCESS) {
923     log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address,
924               p_ccb->connection_id, p_rsp - p_rsp_start);
925   }
926 }
927 
928 /*******************************************************************************
929  *
930  * Function         sdp_server_handle_client_req
931  *
932  * Description      This is the main dispatcher of the SDP server. It is called
933  *                  when any data is received from L2CAP, and dispatches the
934  *                  request to the appropriate handler.
935  *
936  * Returns          void
937  *
938  ******************************************************************************/
sdp_server_handle_client_req(tCONN_CB * p_ccb,BT_HDR * p_msg)939 void sdp_server_handle_client_req(tCONN_CB* p_ccb, BT_HDR* p_msg) {
940   uint8_t* p_req = (uint8_t*)(p_msg + 1) + p_msg->offset;
941   uint8_t* p_req_end = p_req + p_msg->len;
942   uint8_t pdu_id;
943   uint16_t trans_num, param_len;
944 
945   /* Start inactivity timer */
946   alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS, sdp_conn_timer_timeout, p_ccb);
947 
948   if (p_req + sizeof(pdu_id) + sizeof(trans_num) > p_req_end) {
949     trans_num = 0;
950     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_REQ_SYNTAX,
951                             SDP_TEXT_BAD_HEADER);
952     return;
953   }
954 
955   /* The first byte in the message is the pdu type */
956   pdu_id = *p_req++;
957 
958   /* Extract the transaction number and parameter length */
959   BE_STREAM_TO_UINT16(trans_num, p_req);
960 
961   if (p_req + sizeof(param_len) > p_req_end) {
962     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_REQ_SYNTAX,
963                             SDP_TEXT_BAD_HEADER);
964     return;
965   }
966 
967   BE_STREAM_TO_UINT16(param_len, p_req);
968 
969   if ((p_req + param_len) != p_req_end) {
970     sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_PDU_SIZE,
971                             SDP_TEXT_BAD_HEADER);
972     return;
973   }
974 
975   switch (pdu_id) {
976     case SDP_PDU_SERVICE_SEARCH_REQ:
977       process_service_search(p_ccb, trans_num, param_len, p_req, p_req_end);
978       break;
979 
980     case SDP_PDU_SERVICE_ATTR_REQ:
981       process_service_attr_req(p_ccb, trans_num, param_len, p_req, p_req_end);
982       break;
983 
984     case SDP_PDU_SERVICE_SEARCH_ATTR_REQ:
985       process_service_search_attr_req(p_ccb, trans_num, param_len, p_req, p_req_end);
986       break;
987 
988     default:
989       sdpu_build_n_send_error(p_ccb, trans_num, tSDP_STATUS::SDP_INVALID_REQ_SYNTAX,
990                               SDP_TEXT_BAD_PDU);
991       log::warn("SDP - server got unknown PDU: 0x{:x}", pdu_id);
992       break;
993   }
994 }
995 
996 /*************************************************************************************
997 **
998 ** Function        update_pce_entry_to_interop_database
999 **
1000 ** Description     Update PCE 1.2 entry to dynamic interop database
1001 **
1002 ***************************************************************************************/
update_pce_entry_to_interop_database(RawAddress remote_addr)1003 void update_pce_entry_to_interop_database(RawAddress remote_addr) {
1004   if (!interop_match_addr_or_name(INTEROP_ADV_PBAP_VER_1_2, &remote_addr,
1005                                   &btif_storage_get_remote_device_property)) {
1006     interop_database_add_addr(INTEROP_ADV_PBAP_VER_1_2, &remote_addr, 3);
1007     log::verbose("device: {} is added into interop list", remote_addr);
1008   } else {
1009     log::warn("device: {} is already found on interop list", remote_addr);
1010   }
1011 }
1012 
1013 /*************************************************************************************
1014 **
1015 ** Function        is_sdp_pbap_pce_disabled
1016 **
1017 ** Description     Checks if given PBAP record is for PBAP PSE and SDP
1018 *denylisted
1019 **
1020 ** Returns         BOOLEAN
1021 **
1022 ***************************************************************************************/
is_sdp_pbap_pce_disabled(RawAddress remote_address)1023 bool is_sdp_pbap_pce_disabled(RawAddress remote_address) {
1024   if (interop_match_addr_or_name(INTEROP_DISABLE_PCE_SDP_AFTER_PAIRING, &remote_address,
1025                                  &btif_storage_get_remote_device_property)) {
1026     log::verbose("device is denylisted for PCE SDP");
1027     return true;
1028   } else {
1029     return false;
1030   }
1031 }
1032 
1033 /*************************************************************************************
1034 **
1035 ** Function        sdp_save_local_pse_record_attributes_val
1036 **
1037 ** Description     Save pbap 1.2 sdp record attributes values, which would be
1038 *used for dynamic version upgrade.
1039 **
1040 ** Returns         BOOLEAN
1041 **
1042 ***************************************************************************************/
sdp_save_local_pse_record_attributes(int32_t rfcomm_channel_number,int32_t l2cap_psm,int32_t profile_version,uint32_t supported_features,uint32_t supported_repositories)1043 void sdp_save_local_pse_record_attributes(int32_t rfcomm_channel_number, int32_t l2cap_psm,
1044                                           int32_t profile_version, uint32_t supported_features,
1045                                           uint32_t supported_repositories) {
1046   log::warn(
1047           "rfcomm_channel_number: 0x{:x}, l2cap_psm: 0x{:x} profile_version: "
1048           "0x{:x}supported_features: 0x{:x} supported_repositories:  0x{:x}",
1049           rfcomm_channel_number, l2cap_psm, profile_version, supported_features,
1050           supported_repositories);
1051   sdpPseLocalRecord.rfcomm_channel_number = rfcomm_channel_number;
1052   sdpPseLocalRecord.l2cap_psm = l2cap_psm;
1053   sdpPseLocalRecord.profile_version = profile_version;
1054   sdpPseLocalRecord.supported_features = supported_features;
1055   sdpPseLocalRecord.supported_repositories = supported_repositories;
1056 }
1057