• 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 /******************************************************************************
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 "sdp_server"
26 
27 #include <base/location.h>
28 #include <base/logging.h>
29 #include <log/log.h>
30 #include <string.h>  // memcpy
31 
32 #include <cstdint>
33 
34 // include before bta_hfp_api for pre-defined variable
35 #include "btif/include/btif_storage.h"
36 
37 // remaining includes
38 #include "bta/include/bta_hfp_api.h"
39 #include "btif/include/btif_config.h"
40 #include "btif/include/btif_profile_storage.h"
41 #include "btif/include/btif_storage.h"
42 #include "common/init_flags.h"
43 #include "device/include/interop.h"
44 #include "device/include/interop_config.h"
45 #include "osi/include/allocator.h"
46 #include "osi/include/properties.h"
47 #include "stack/btm/btm_dev.h"
48 #include "stack/include/avrc_api.h"
49 #include "stack/include/avrc_defs.h"
50 #include "stack/include/bt_hdr.h"
51 #include "stack/include/btm_api.h"
52 #include "stack/include/sdp_api.h"
53 #include "stack/sdp/sdpint.h"
54 
55 /* Maximum number of bytes to reserve out of SDP MTU for response data */
56 #define SDP_MAX_SERVICE_RSPHDR_LEN 12
57 #define SDP_MAX_SERVATTR_RSPHDR_LEN 10
58 #define SDP_MAX_ATTR_RSPHDR_LEN 10
59 #define PROFILE_VERSION_POSITION 7
60 #define SDP_PROFILE_DESC_LENGTH 8
61 #define HFP_PROFILE_MINOR_VERSION_6 0x06
62 #define HFP_PROFILE_MINOR_VERSION_7 0x07
63 #define PBAP_GOEP_L2CAP_PSM_LEN 0x06
64 #define PBAP_SUPP_FEA_LEN 0x08
65 
66 #ifndef SDP_ENABLE_PTS_PBAP
67 #define SDP_ENABLE_PTS_PBAP "bluetooth.pts.pbap"
68 #endif
69 
70 #define PBAP_1_2 0x0102
71 #define PBAP_1_2_BL_LEN 14
72 
73 /* Used to set PBAP local SDP device record for PBAP 1.2 upgrade */
74 typedef struct {
75   int32_t rfcomm_channel_number;
76   int32_t l2cap_psm;
77   int32_t profile_version;
78   uint32_t supported_features;
79   uint32_t supported_repositories;
80 } tSDP_PSE_LOCAL_RECORD;
81 
82 static tSDP_PSE_LOCAL_RECORD sdpPseLocalRecord;
83 
84 /******************************************************************************/
85 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
86 /******************************************************************************/
87 static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
88                                    uint16_t param_len, uint8_t* p_req,
89                                    uint8_t* p_req_end);
90 
91 static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
92                                      uint16_t param_len, uint8_t* p_req,
93                                      uint8_t* p_req_end);
94 
95 static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
96                                             uint16_t param_len, uint8_t* p_req,
97                                             uint8_t* p_req_end);
98 bool sdp_dynamic_change_hfp_version(const tSDP_ATTRIBUTE* p_attr,
99                                     const RawAddress& remote_address);
100 void hfp_fallback(bool& is_hfp_fallback, const tSDP_ATTRIBUTE* p_attr);
101 
102 static bool is_device_in_allowlist_for_pbap(RawAddress remote_address,
103                                             bool check_for_1_2);
104 
105 static uint16_t sdp_pbap_pse_dynamic_attributes_len_update(
106     tCONN_CB* p_ccb, tSDP_ATTR_SEQ* attr_seq, tSDP_UUID_SEQ* uid_seq);
107 
108 static const tSDP_RECORD* sdp_upgrade_pse_record(const tSDP_RECORD* p_rec,
109                                                  RawAddress remote_address);
110 
111 /******************************************************************************/
112 /*                E R R O R   T E X T   S T R I N G S                         */
113 /*                                                                            */
114 /* The default is to have no text string, but we allow the strings to be      */
115 /* configured in target.h if people want them.                                */
116 /******************************************************************************/
117 #ifndef SDP_TEXT_BAD_HEADER
118 #define SDP_TEXT_BAD_HEADER NULL
119 #endif
120 
121 #ifndef SDP_TEXT_BAD_PDU
122 #define SDP_TEXT_BAD_PDU NULL
123 #endif
124 
125 #ifndef SDP_TEXT_BAD_UUID_LIST
126 #define SDP_TEXT_BAD_UUID_LIST NULL
127 #endif
128 
129 #ifndef SDP_TEXT_BAD_HANDLE
130 #define SDP_TEXT_BAD_HANDLE NULL
131 #endif
132 
133 #ifndef SDP_TEXT_BAD_ATTR_LIST
134 #define SDP_TEXT_BAD_ATTR_LIST NULL
135 #endif
136 
137 #ifndef SDP_TEXT_BAD_CONT_LEN
138 #define SDP_TEXT_BAD_CONT_LEN NULL
139 #endif
140 
141 #ifndef SDP_TEXT_BAD_CONT_INX
142 #define SDP_TEXT_BAD_CONT_INX NULL
143 #endif
144 
145 #ifndef SDP_TEXT_BAD_MAX_RECORDS_LIST
146 #define SDP_TEXT_BAD_MAX_RECORDS_LIST NULL
147 #endif
148 
149 /*************************************************************************************
150 **
151 ** Function        sdp_dynamic_change_hfp_version
152 **
153 ** Description     Checks if UUID is AG_HANDSFREE, attribute id
154 **                 is Profile descriptor list and remote BD address
155 **                 matches device Allow list, change hfp version to 1.7
156 **
157 ** Returns         BOOLEAN
158 **
159 +***************************************************************************************/
sdp_dynamic_change_hfp_version(const tSDP_ATTRIBUTE * p_attr,const RawAddress & remote_address)160 bool sdp_dynamic_change_hfp_version(const tSDP_ATTRIBUTE* p_attr,
161                                     const RawAddress& remote_address) {
162   if ((p_attr->id != ATTR_ID_BT_PROFILE_DESC_LIST) ||
163       (p_attr->len < SDP_PROFILE_DESC_LENGTH)) {
164     return false;
165   }
166   /* As per current DB implementation UUID is condidered as 16 bit */
167   if (((p_attr->value_ptr[3] << SDP_PROFILE_DESC_LENGTH) |
168        (p_attr->value_ptr[4])) != UUID_SERVCLASS_HF_HANDSFREE) {
169     return false;
170   }
171   bool is_allowlisted_1_7 =
172       interop_match_addr_or_name(INTEROP_HFP_1_7_ALLOWLIST, &remote_address,
173                                  &btif_storage_get_remote_device_property);
174   /* For PTS we should update AG's HFP version as 1.7 */
175   if (!(is_allowlisted_1_7) &&
176       !(osi_property_get_bool("vendor.bt.pts.certification", false))) {
177     return false;
178   }
179   p_attr->value_ptr[PROFILE_VERSION_POSITION] = HFP_PROFILE_MINOR_VERSION_7;
180   SDP_TRACE_INFO("%s SDP Change HFP Version = %d for %s", __func__,
181                  p_attr->value_ptr[PROFILE_VERSION_POSITION],
182                  ADDRESS_TO_LOGGABLE_CSTR(remote_address));
183   return true;
184 }
185 /******************************************************************************
186  *
187  * Function         hfp_fallback
188  *
189  * Description      Update HFP version back to 1.6
190  *
191  * Returns          void
192  *
193  *****************************************************************************/
hfp_fallback(bool & is_hfp_fallback,const tSDP_ATTRIBUTE * p_attr)194 void hfp_fallback(bool& is_hfp_fallback, const tSDP_ATTRIBUTE* p_attr) {
195   /* Update HFP version back to 1.6 */
196   p_attr->value_ptr[PROFILE_VERSION_POSITION] = HFP_PROFILE_MINOR_VERSION_6;
197   SDP_TRACE_INFO("Restore HFP version to 1.6");
198   is_hfp_fallback = false;
199 }
200 
201 /*******************************************************************************
202  *
203  * Function         sdp_server_handle_client_req
204  *
205  * Description      This is the main dispatcher of the SDP server. It is called
206  *                  when any data is received from L2CAP, and dispatches the
207  *                  request to the appropriate handler.
208  *
209  * Returns          void
210  *
211  ******************************************************************************/
sdp_server_handle_client_req(tCONN_CB * p_ccb,BT_HDR * p_msg)212 void sdp_server_handle_client_req(tCONN_CB* p_ccb, BT_HDR* p_msg) {
213   uint8_t* p_req = (uint8_t*)(p_msg + 1) + p_msg->offset;
214   uint8_t* p_req_end = p_req + p_msg->len;
215   uint8_t pdu_id;
216   uint16_t trans_num, param_len;
217 
218   /* Start inactivity timer */
219   alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
220                      sdp_conn_timer_timeout, p_ccb);
221 
222   if (p_req + sizeof(pdu_id) + sizeof(trans_num) > p_req_end) {
223     trans_num = 0;
224     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
225                             SDP_TEXT_BAD_HEADER);
226     return;
227   }
228 
229   /* The first byte in the message is the pdu type */
230   pdu_id = *p_req++;
231 
232   /* Extract the transaction number and parameter length */
233   BE_STREAM_TO_UINT16(trans_num, p_req);
234 
235   if (p_req + sizeof(param_len) > p_req_end) {
236     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
237                             SDP_TEXT_BAD_HEADER);
238     return;
239   }
240 
241   BE_STREAM_TO_UINT16(param_len, p_req);
242 
243   if ((p_req + param_len) != p_req_end) {
244     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_PDU_SIZE,
245                             SDP_TEXT_BAD_HEADER);
246     return;
247   }
248 
249   switch (pdu_id) {
250     case SDP_PDU_SERVICE_SEARCH_REQ:
251       process_service_search(p_ccb, trans_num, param_len, p_req, p_req_end);
252       break;
253 
254     case SDP_PDU_SERVICE_ATTR_REQ:
255       process_service_attr_req(p_ccb, trans_num, param_len, p_req, p_req_end);
256       break;
257 
258     case SDP_PDU_SERVICE_SEARCH_ATTR_REQ:
259       process_service_search_attr_req(p_ccb, trans_num, param_len, p_req,
260                                       p_req_end);
261       break;
262 
263     default:
264       sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
265                               SDP_TEXT_BAD_PDU);
266       SDP_TRACE_WARNING("SDP - server got unknown PDU: 0x%x", pdu_id);
267       break;
268   }
269 }
270 
271 /*******************************************************************************
272  *
273  * Function         process_service_search
274  *
275  * Description      This function handles a service search request from the
276  *                  client. It builds a reply message with info from the
277  *                  database, and sends the reply back to the client.
278  *
279  * Returns          void
280  *
281  ******************************************************************************/
process_service_search(tCONN_CB * p_ccb,uint16_t trans_num,uint16_t param_len,uint8_t * p_req,uint8_t * p_req_end)282 static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
283                                    uint16_t param_len, uint8_t* p_req,
284                                    uint8_t* p_req_end) {
285   uint16_t max_replies, cur_handles, rem_handles, cont_offset;
286   tSDP_UUID_SEQ uid_seq;
287   uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
288   uint16_t rsp_param_len, num_rsp_handles, xx;
289   uint32_t rsp_handles[SDP_MAX_RECORDS] = {0};
290   const tSDP_RECORD* p_rec = NULL;
291   bool is_cont = false;
292 
293   p_req = sdpu_extract_uid_seq(p_req, param_len, &uid_seq);
294 
295   if ((!p_req) || (!uid_seq.num_uids)) {
296     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
297                             SDP_TEXT_BAD_UUID_LIST);
298     return;
299   }
300 
301   /* Get the max replies we can send. Cap it at our max anyways. */
302   if (p_req + sizeof(max_replies) + sizeof(uint8_t) > p_req_end) {
303     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
304                             SDP_TEXT_BAD_MAX_RECORDS_LIST);
305     return;
306   }
307   BE_STREAM_TO_UINT16(max_replies, p_req);
308 
309   if (max_replies > SDP_MAX_RECORDS) max_replies = SDP_MAX_RECORDS;
310 
311   /* Get a list of handles that match the UUIDs given to us */
312   for (num_rsp_handles = 0; num_rsp_handles < max_replies;) {
313     p_rec = sdp_db_service_search(p_rec, &uid_seq);
314 
315     if (p_rec)
316       rsp_handles[num_rsp_handles++] = p_rec->record_handle;
317     else
318       break;
319   }
320 
321   /* Check if this is a continuation request */
322   if (p_req + 1 > p_req_end) {
323     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
324                             SDP_TEXT_BAD_CONT_LEN);
325     return;
326   }
327   if (*p_req) {
328     if (*p_req++ != SDP_CONTINUATION_LEN ||
329         (p_req + sizeof(cont_offset) > p_req_end)) {
330       sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
331                               SDP_TEXT_BAD_CONT_LEN);
332       return;
333     }
334     BE_STREAM_TO_UINT16(cont_offset, p_req);
335 
336     if (cont_offset != p_ccb->cont_offset || num_rsp_handles < cont_offset) {
337       sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
338                               SDP_TEXT_BAD_CONT_INX);
339       return;
340     }
341 
342     rem_handles =
343         num_rsp_handles - cont_offset; /* extract the remaining handles */
344   } else {
345     rem_handles = num_rsp_handles;
346     cont_offset = 0;
347     p_ccb->cont_offset = 0;
348   }
349 
350   /* Calculate how many handles will fit in one PDU */
351   cur_handles =
352       (uint16_t)((p_ccb->rem_mtu_size - SDP_MAX_SERVICE_RSPHDR_LEN) / 4);
353 
354   if (rem_handles <= cur_handles)
355     cur_handles = rem_handles;
356   else /* Continuation is set */
357   {
358     p_ccb->cont_offset += cur_handles;
359     is_cont = true;
360   }
361 
362   /* Get a buffer to use to build the response */
363   BT_HDR* p_buf = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
364   p_buf->offset = L2CAP_MIN_OFFSET;
365   p_rsp = p_rsp_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
366 
367   /* Start building a rsponse */
368   UINT8_TO_BE_STREAM(p_rsp, SDP_PDU_SERVICE_SEARCH_RSP);
369   UINT16_TO_BE_STREAM(p_rsp, trans_num);
370 
371   /* Skip the length, we need to add it at the end */
372   p_rsp_param_len = p_rsp;
373   p_rsp += 2;
374 
375   /* Put in total and current number of handles, and handles themselves */
376   UINT16_TO_BE_STREAM(p_rsp, num_rsp_handles);
377   UINT16_TO_BE_STREAM(p_rsp, cur_handles);
378 
379   /*  SDP_TRACE_DEBUG("SDP Service Rsp: tothdl %d, curhdlr %d, start %d, end %d,
380      cont %d",
381                        num_rsp_handles, cur_handles, cont_offset,
382                        cont_offset + cur_handles-1, is_cont); */
383   for (xx = cont_offset; xx < cont_offset + cur_handles; xx++)
384     UINT32_TO_BE_STREAM(p_rsp, rsp_handles[xx]);
385 
386   if (is_cont) {
387     UINT8_TO_BE_STREAM(p_rsp, SDP_CONTINUATION_LEN);
388     UINT16_TO_BE_STREAM(p_rsp, p_ccb->cont_offset);
389   } else
390     UINT8_TO_BE_STREAM(p_rsp, 0);
391 
392   /* Go back and put the parameter length into the buffer */
393   rsp_param_len = p_rsp - p_rsp_param_len - 2;
394   UINT16_TO_BE_STREAM(p_rsp_param_len, rsp_param_len);
395 
396   /* Set the length of the SDP data in the buffer */
397   p_buf->len = p_rsp - p_rsp_start;
398 
399   /* Send the buffer through L2CAP */
400   L2CA_DataWrite(p_ccb->connection_id, p_buf);
401 }
402 
403 /*******************************************************************************
404  *
405  * Function         process_service_attr_req
406  *
407  * Description      This function handles an attribute request from the client.
408  *                  It builds a reply message with info from the database,
409  *                  and sends the reply back to the client.
410  *
411  * Returns          void
412  *
413  ******************************************************************************/
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)414 static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
415                                      uint16_t param_len, uint8_t* p_req,
416                                      uint8_t* p_req_end) {
417   uint16_t max_list_len, len_to_send, cont_offset;
418   int16_t rem_len;
419   tSDP_ATTR_SEQ attr_seq, attr_seq_sav;
420   uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
421   uint16_t rsp_param_len, xx;
422   uint32_t rec_handle;
423   const tSDP_RECORD* p_rec;
424   const tSDP_ATTRIBUTE* p_attr;
425   bool is_cont = false;
426   bool is_hfp_fallback = false;
427   uint16_t attr_len;
428 
429   if (p_req + sizeof(rec_handle) + sizeof(max_list_len) > p_req_end) {
430     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_SERV_REC_HDL,
431                             SDP_TEXT_BAD_HANDLE);
432     return;
433   }
434 
435   /* Extract the record handle */
436   BE_STREAM_TO_UINT32(rec_handle, p_req);
437   param_len -= sizeof(rec_handle);
438 
439   /* Get the max list length we can send. Cap it at MTU size minus overhead */
440   BE_STREAM_TO_UINT16(max_list_len, p_req);
441   param_len -= sizeof(max_list_len);
442 
443   if (max_list_len > (p_ccb->rem_mtu_size - SDP_MAX_ATTR_RSPHDR_LEN))
444     max_list_len = p_ccb->rem_mtu_size - SDP_MAX_ATTR_RSPHDR_LEN;
445 
446   p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);
447 
448   if ((!p_req) || (!attr_seq.num_attr) ||
449       (p_req + sizeof(uint8_t) > p_req_end)) {
450     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
451                             SDP_TEXT_BAD_ATTR_LIST);
452     return;
453   }
454 
455   memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ));
456 
457   /* Find a record with the record handle */
458   p_rec = sdp_db_find_record(rec_handle);
459   if (!p_rec) {
460     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_SERV_REC_HDL,
461                             SDP_TEXT_BAD_HANDLE);
462     return;
463   }
464 
465   if (max_list_len < 4) {
466     sdpu_build_n_send_error(p_ccb, trans_num, SDP_ILLEGAL_PARAMETER, NULL);
467     return;
468   }
469 
470   if (bluetooth::common::init_flags::
471           pbap_pse_dynamic_version_upgrade_is_enabled()) {
472     p_rec = sdp_upgrade_pse_record(p_rec, p_ccb->device_address);
473   } else {
474     SDP_TRACE_WARNING("PBAP PSE dynamic version upgrade is not enabled");
475   }
476 
477   /* Free and reallocate buffer */
478   osi_free(p_ccb->rsp_list);
479   p_ccb->rsp_list = (uint8_t*)osi_malloc(max_list_len);
480 
481   /* Check if this is a continuation request */
482   if (p_req + 1 > p_req_end) {
483     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
484                             SDP_TEXT_BAD_CONT_LEN);
485     return;
486   }
487   if (*p_req) {
488     if (*p_req++ != SDP_CONTINUATION_LEN ||
489         (p_req + sizeof(cont_offset) > p_req_end)) {
490       sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
491                               SDP_TEXT_BAD_CONT_LEN);
492       return;
493     }
494     BE_STREAM_TO_UINT16(cont_offset, p_req);
495 
496     if (cont_offset != p_ccb->cont_offset) {
497       sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
498                               SDP_TEXT_BAD_CONT_INX);
499       return;
500     }
501     is_cont = true;
502 
503     /* Initialise for continuation response */
504     p_rsp = &p_ccb->rsp_list[0];
505     attr_seq.attr_entry[p_ccb->cont_info.next_attr_index].start =
506         p_ccb->cont_info.next_attr_start_id;
507   } else {
508     p_ccb->cont_offset = 0;
509     p_rsp = &p_ccb->rsp_list[3]; /* Leave space for data elem descr */
510 
511     /* Reset continuation parameters in p_ccb */
512     p_ccb->cont_info.prev_sdp_rec = NULL;
513     p_ccb->cont_info.next_attr_index = 0;
514     p_ccb->cont_info.attr_offset = 0;
515   }
516 
517   bool is_service_avrc_target = false;
518   const tSDP_ATTRIBUTE* p_attr_service_id;
519   const tSDP_ATTRIBUTE* p_attr_profile_desc_list_id;
520   uint16_t avrc_sdp_version = 0;
521   p_attr_service_id = sdp_db_find_attr_in_rec(
522       p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST, ATTR_ID_SERVICE_CLASS_ID_LIST);
523   p_attr_profile_desc_list_id = sdp_db_find_attr_in_rec(
524       p_rec, ATTR_ID_BT_PROFILE_DESC_LIST, ATTR_ID_BT_PROFILE_DESC_LIST);
525   if (p_attr_service_id) {
526     is_service_avrc_target = sdpu_is_service_id_avrc_target(p_attr_service_id);
527   }
528   /* Search for attributes that match the list given to us */
529   for (xx = p_ccb->cont_info.next_attr_index; xx < attr_seq.num_attr; xx++) {
530     p_attr = sdp_db_find_attr_in_rec(p_rec, attr_seq.attr_entry[xx].start,
531                                      attr_seq.attr_entry[xx].end);
532     if (p_attr) {
533       if (is_service_avrc_target) {
534         sdpu_set_avrc_target_version(p_attr, &(p_ccb->device_address));
535         if (p_attr->id == ATTR_ID_SUPPORTED_FEATURES &&
536             bluetooth::common::init_flags::
537                 dynamic_avrcp_version_enhancement_is_enabled()) {
538           avrc_sdp_version = sdpu_is_avrcp_profile_description_list(
539               p_attr_profile_desc_list_id);
540           SDP_TRACE_ERROR("avrc_sdp_version in SDP records %x",
541                           avrc_sdp_version);
542           sdpu_set_avrc_target_features(p_attr, &(p_ccb->device_address),
543                                         avrc_sdp_version);
544         }
545       }
546       if (bluetooth::common::init_flags::hfp_dynamic_version_is_enabled()) {
547         is_hfp_fallback =
548             sdp_dynamic_change_hfp_version(p_attr, p_ccb->device_address);
549       }
550       /* Check if attribute fits. Assume 3-byte value type/length */
551       rem_len = max_list_len - (int16_t)(p_rsp - &p_ccb->rsp_list[0]);
552 
553       /* just in case */
554       if (rem_len <= 0) {
555         p_ccb->cont_info.next_attr_index = xx;
556         p_ccb->cont_info.next_attr_start_id = p_attr->id;
557         break;
558       }
559 
560       attr_len = sdpu_get_attrib_entry_len(p_attr);
561       /* if there is a partial attribute pending to be sent */
562       if (p_ccb->cont_info.attr_offset) {
563         if (attr_len < p_ccb->cont_info.attr_offset) {
564           LOG(ERROR) << "offset is bigger than attribute length";
565           sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
566                                   SDP_TEXT_BAD_CONT_LEN);
567           return;
568         }
569         p_rsp = sdpu_build_partial_attrib_entry(p_rsp, p_attr, rem_len,
570                                                 &p_ccb->cont_info.attr_offset);
571 
572         /* If the partial attrib could not been fully added yet */
573         if (p_ccb->cont_info.attr_offset != attr_len)
574           break;
575         else /* If the partial attrib has been added in full by now */
576           p_ccb->cont_info.attr_offset = 0; /* reset attr_offset */
577       } else if (rem_len <
578                  attr_len) /* Not enough space for attr... so add partially */
579       {
580         if (attr_len >= SDP_MAX_ATTR_LEN) {
581           SDP_TRACE_ERROR("SDP attr too big: max_list_len=%d,attr_len=%d",
582                           max_list_len, attr_len);
583           sdpu_build_n_send_error(p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
584           return;
585         }
586 
587         /* add the partial attribute if possible */
588         p_rsp = sdpu_build_partial_attrib_entry(
589             p_rsp, p_attr, (uint16_t)rem_len, &p_ccb->cont_info.attr_offset);
590 
591         p_ccb->cont_info.next_attr_index = xx;
592         p_ccb->cont_info.next_attr_start_id = p_attr->id;
593         break;
594       } else /* build the whole attribute */
595         p_rsp = sdpu_build_attrib_entry(p_rsp, p_attr);
596 
597       /* If doing a range, stick with this one till no more attributes found */
598       if (attr_seq.attr_entry[xx].start != attr_seq.attr_entry[xx].end) {
599         /* Update for next time through */
600         attr_seq.attr_entry[xx].start = p_attr->id + 1;
601 
602         xx--;
603       }
604       if (is_hfp_fallback) {
605         hfp_fallback(is_hfp_fallback, p_attr);
606       }
607     }
608   }
609   if (is_hfp_fallback) {
610     hfp_fallback(is_hfp_fallback, p_attr);
611   }
612   /* If all the attributes have been accomodated in p_rsp,
613      reset next_attr_index */
614   if (xx == attr_seq.num_attr) p_ccb->cont_info.next_attr_index = 0;
615 
616   len_to_send = (uint16_t)(p_rsp - &p_ccb->rsp_list[0]);
617   cont_offset = 0;
618 
619   if (!is_cont) {
620     p_ccb->list_len = sdpu_get_attrib_seq_len(p_rec, &attr_seq_sav) + 3;
621     /* Put in the sequence header (2 or 3 bytes) */
622     if (p_ccb->list_len > 255) {
623       p_ccb->rsp_list[0] =
624           (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
625       p_ccb->rsp_list[1] = (uint8_t)((p_ccb->list_len - 3) >> 8);
626       p_ccb->rsp_list[2] = (uint8_t)(p_ccb->list_len - 3);
627     } else {
628       cont_offset = 1;
629 
630       p_ccb->rsp_list[1] =
631           (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
632       p_ccb->rsp_list[2] = (uint8_t)(p_ccb->list_len - 3);
633 
634       p_ccb->list_len--;
635       len_to_send--;
636     }
637   }
638 
639   /* Get a buffer to use to build the response */
640   BT_HDR* p_buf = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
641   p_buf->offset = L2CAP_MIN_OFFSET;
642   p_rsp = p_rsp_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
643 
644   /* Start building a rsponse */
645   UINT8_TO_BE_STREAM(p_rsp, SDP_PDU_SERVICE_ATTR_RSP);
646   UINT16_TO_BE_STREAM(p_rsp, trans_num);
647 
648   /* Skip the parameter length, add it when we know the length */
649   p_rsp_param_len = p_rsp;
650   p_rsp += 2;
651 
652   UINT16_TO_BE_STREAM(p_rsp, len_to_send);
653 
654   memcpy(p_rsp, &p_ccb->rsp_list[cont_offset], len_to_send);
655   p_rsp += len_to_send;
656 
657   p_ccb->cont_offset += len_to_send;
658 
659   /* If anything left to send, continuation needed */
660   if (p_ccb->cont_offset < p_ccb->list_len) {
661     is_cont = true;
662 
663     UINT8_TO_BE_STREAM(p_rsp, SDP_CONTINUATION_LEN);
664     UINT16_TO_BE_STREAM(p_rsp, p_ccb->cont_offset);
665   } else
666     UINT8_TO_BE_STREAM(p_rsp, 0);
667 
668   /* Go back and put the parameter length into the buffer */
669   rsp_param_len = p_rsp - p_rsp_param_len - 2;
670   UINT16_TO_BE_STREAM(p_rsp_param_len, rsp_param_len);
671 
672   /* Set the length of the SDP data in the buffer */
673   p_buf->len = p_rsp - p_rsp_start;
674 
675   /* Send the buffer through L2CAP */
676   L2CA_DataWrite(p_ccb->connection_id, p_buf);
677 }
678 
679 /*******************************************************************************
680  *
681  * Function         process_service_search_attr_req
682  *
683  * Description      This function handles a combined service search and
684  *                  attribute read request from the client. It builds a reply
685  *                  message with info from the database, and sends the reply
686  *                  back to the client.
687  *
688  * Returns          void
689  *
690  ******************************************************************************/
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)691 static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
692                                             uint16_t param_len, uint8_t* p_req,
693                                             uint8_t* p_req_end) {
694   uint16_t max_list_len;
695   int16_t rem_len;
696   uint16_t len_to_send, cont_offset;
697   tSDP_UUID_SEQ uid_seq;
698   uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
699   uint16_t rsp_param_len, xx;
700   const tSDP_RECORD* p_rec;
701   tSDP_RECORD* p_prev_rec;
702   tSDP_ATTR_SEQ attr_seq, attr_seq_sav;
703   const tSDP_ATTRIBUTE* p_attr;
704   bool maxxed_out = false, is_cont = false;
705   uint8_t* p_seq_start;
706   bool is_hfp_fallback = false;
707   uint16_t seq_len, attr_len;
708 
709   /* Extract the UUID sequence to search for */
710   p_req = sdpu_extract_uid_seq(p_req, param_len, &uid_seq);
711 
712   if ((!p_req) || (!uid_seq.num_uids) ||
713       (p_req + sizeof(uint16_t) > p_req_end)) {
714     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
715                             SDP_TEXT_BAD_UUID_LIST);
716     return;
717   }
718 
719   /* Get the max list length we can send. Cap it at our max list length. */
720   BE_STREAM_TO_UINT16(max_list_len, p_req);
721 
722   if (max_list_len > (p_ccb->rem_mtu_size - SDP_MAX_SERVATTR_RSPHDR_LEN))
723     max_list_len = p_ccb->rem_mtu_size - SDP_MAX_SERVATTR_RSPHDR_LEN;
724 
725   param_len = static_cast<uint16_t>(p_req_end - p_req);
726   p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);
727 
728   if ((!p_req) || (!attr_seq.num_attr) ||
729       (p_req + sizeof(uint8_t) > p_req_end)) {
730     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
731                             SDP_TEXT_BAD_ATTR_LIST);
732     return;
733   }
734 
735   memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ));
736 
737   if (max_list_len < 4) {
738     sdpu_build_n_send_error(p_ccb, trans_num, SDP_ILLEGAL_PARAMETER, NULL);
739     return;
740   }
741 
742   /* Free and reallocate buffer */
743   osi_free(p_ccb->rsp_list);
744   p_ccb->rsp_list = (uint8_t*)osi_malloc(max_list_len);
745 
746   /* Check if this is a continuation request */
747   if (p_req + 1 > p_req_end) {
748     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
749                             SDP_TEXT_BAD_CONT_LEN);
750     return;
751   }
752   if (*p_req) {
753     if (*p_req++ != SDP_CONTINUATION_LEN ||
754         (p_req + sizeof(uint16_t) > p_req_end)) {
755       sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
756                               SDP_TEXT_BAD_CONT_LEN);
757       return;
758     }
759     BE_STREAM_TO_UINT16(cont_offset, p_req);
760 
761     if (cont_offset != p_ccb->cont_offset) {
762       sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
763                               SDP_TEXT_BAD_CONT_INX);
764       return;
765     }
766     is_cont = true;
767 
768     /* Initialise for continuation response */
769     p_rsp = &p_ccb->rsp_list[0];
770     attr_seq.attr_entry[p_ccb->cont_info.next_attr_index].start =
771         p_ccb->cont_info.next_attr_start_id;
772   } else {
773     p_ccb->cont_offset = 0;
774     p_rsp = &p_ccb->rsp_list[3]; /* Leave space for data elem descr */
775 
776     /* Reset continuation parameters in p_ccb */
777     p_ccb->cont_info.prev_sdp_rec = NULL;
778     p_ccb->cont_info.next_attr_index = 0;
779     p_ccb->cont_info.last_attr_seq_desc_sent = false;
780     p_ccb->cont_info.attr_offset = 0;
781   }
782 
783   /* Get a list of handles that match the UUIDs given to us */
784   for (p_rec = sdp_db_service_search(p_ccb->cont_info.prev_sdp_rec, &uid_seq);
785        p_rec; p_rec = sdp_db_service_search(p_rec, &uid_seq)) {
786     /* Store the actual record pointer which would be reused later */
787     p_prev_rec = (tSDP_RECORD*)p_rec;
788     if (bluetooth::common::init_flags::
789             pbap_pse_dynamic_version_upgrade_is_enabled()) {
790       p_rec = sdp_upgrade_pse_record(p_rec, p_ccb->device_address);
791     } else {
792       SDP_TRACE_WARNING("PBAP PSE dynamic version upgrade is not enabled");
793     }
794     /* Allow space for attribute sequence type and length */
795     p_seq_start = p_rsp;
796     if (!p_ccb->cont_info.last_attr_seq_desc_sent) {
797       /* See if there is enough room to include a new service in the current
798        * response */
799       rem_len = max_list_len - (int16_t)(p_rsp - &p_ccb->rsp_list[0]);
800       if (rem_len < 3) {
801         /* Not enough room. Update continuation info for next response */
802         p_ccb->cont_info.next_attr_index = 0;
803         p_ccb->cont_info.next_attr_start_id = attr_seq.attr_entry[0].start;
804         break;
805       }
806       p_rsp += 3;
807     }
808 
809     bool is_service_avrc_target = false;
810     const tSDP_ATTRIBUTE* p_attr_service_id;
811     const tSDP_ATTRIBUTE* p_attr_profile_desc_list_id;
812     uint16_t avrc_sdp_version = 0;
813     p_attr_service_id = sdp_db_find_attr_in_rec(
814         p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST, ATTR_ID_SERVICE_CLASS_ID_LIST);
815     p_attr_profile_desc_list_id = sdp_db_find_attr_in_rec(
816         p_rec, ATTR_ID_BT_PROFILE_DESC_LIST, ATTR_ID_BT_PROFILE_DESC_LIST);
817     if (p_attr_service_id) {
818       is_service_avrc_target =
819           sdpu_is_service_id_avrc_target(p_attr_service_id);
820     }
821     /* Get a list of handles that match the UUIDs given to us */
822     for (xx = p_ccb->cont_info.next_attr_index; xx < attr_seq.num_attr; xx++) {
823       p_attr = sdp_db_find_attr_in_rec(p_rec, attr_seq.attr_entry[xx].start,
824                                        attr_seq.attr_entry[xx].end);
825 
826       if (p_attr) {
827         if (is_service_avrc_target) {
828           sdpu_set_avrc_target_version(p_attr, &(p_ccb->device_address));
829           if (p_attr->id == ATTR_ID_SUPPORTED_FEATURES &&
830               bluetooth::common::init_flags::
831                   dynamic_avrcp_version_enhancement_is_enabled() &&
832                   p_attr_profile_desc_list_id != nullptr) {
833             avrc_sdp_version = sdpu_is_avrcp_profile_description_list(
834                 p_attr_profile_desc_list_id);
835             SDP_TRACE_ERROR("avrc_sdp_version in SDP records %x",
836                             avrc_sdp_version);
837             sdpu_set_avrc_target_features(p_attr, &(p_ccb->device_address),
838                                           avrc_sdp_version);
839           }
840         }
841         if (bluetooth::common::init_flags::hfp_dynamic_version_is_enabled()) {
842           is_hfp_fallback =
843               sdp_dynamic_change_hfp_version(p_attr, p_ccb->device_address);
844         }
845         /* Check if attribute fits. Assume 3-byte value type/length */
846         rem_len = max_list_len - (int16_t)(p_rsp - &p_ccb->rsp_list[0]);
847 
848         /* just in case */
849         if (rem_len <= 0) {
850           p_ccb->cont_info.next_attr_index = xx;
851           p_ccb->cont_info.next_attr_start_id = p_attr->id;
852           maxxed_out = true;
853           break;
854         }
855 
856         attr_len = sdpu_get_attrib_entry_len(p_attr);
857         /* if there is a partial attribute pending to be sent */
858         if (p_ccb->cont_info.attr_offset) {
859           if (attr_len < p_ccb->cont_info.attr_offset) {
860             LOG(ERROR) << "offset is bigger than attribute length";
861             sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
862                                     SDP_TEXT_BAD_CONT_LEN);
863             return;
864           }
865           p_rsp = sdpu_build_partial_attrib_entry(
866               p_rsp, p_attr, rem_len, &p_ccb->cont_info.attr_offset);
867 
868           /* If the partial attrib could not been fully added yet */
869           if (p_ccb->cont_info.attr_offset != attr_len) {
870             maxxed_out = true;
871             break;
872           } else /* If the partial attrib has been added in full by now */
873             p_ccb->cont_info.attr_offset = 0; /* reset attr_offset */
874         } else if (rem_len <
875                    attr_len) /* Not enough space for attr... so add partially */
876         {
877           if (attr_len >= SDP_MAX_ATTR_LEN) {
878             SDP_TRACE_ERROR("SDP attr too big: max_list_len=%d,attr_len=%d",
879                             max_list_len, attr_len);
880             sdpu_build_n_send_error(p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
881             return;
882           }
883 
884           /* add the partial attribute if possible */
885           p_rsp = sdpu_build_partial_attrib_entry(
886               p_rsp, p_attr, (uint16_t)rem_len, &p_ccb->cont_info.attr_offset);
887 
888           p_ccb->cont_info.next_attr_index = xx;
889           p_ccb->cont_info.next_attr_start_id = p_attr->id;
890           maxxed_out = true;
891           break;
892         } else /* build the whole attribute */
893           p_rsp = sdpu_build_attrib_entry(p_rsp, p_attr);
894 
895         /* If doing a range, stick with this one till no more attributes found
896          */
897         if (attr_seq.attr_entry[xx].start != attr_seq.attr_entry[xx].end) {
898           /* Update for next time through */
899           attr_seq.attr_entry[xx].start = p_attr->id + 1;
900 
901           xx--;
902         }
903         if (is_hfp_fallback) {
904           hfp_fallback(is_hfp_fallback, p_attr);
905         }
906       }
907     }
908     if (is_hfp_fallback) {
909       hfp_fallback(is_hfp_fallback, p_attr);
910     }
911 
912     /* Go back and put the type and length into the buffer */
913     if (!p_ccb->cont_info.last_attr_seq_desc_sent) {
914       seq_len = sdpu_get_attrib_seq_len(p_rec, &attr_seq_sav);
915       if (seq_len != 0) {
916         UINT8_TO_BE_STREAM(p_seq_start,
917                            (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
918         UINT16_TO_BE_STREAM(p_seq_start, seq_len);
919 
920         if (maxxed_out) p_ccb->cont_info.last_attr_seq_desc_sent = true;
921       } else
922         p_rsp = p_seq_start;
923     }
924 
925     if (maxxed_out) break;
926 
927     /* Restore the attr_seq to look for in the next sdp record */
928     memcpy(&attr_seq, &attr_seq_sav, sizeof(tSDP_ATTR_SEQ));
929 
930     /* Reset the next attr index */
931     p_ccb->cont_info.next_attr_index = 0;
932     /* restore the record pointer.*/
933     p_rec = p_prev_rec;
934     p_ccb->cont_info.prev_sdp_rec = p_rec;
935     p_ccb->cont_info.last_attr_seq_desc_sent = false;
936   }
937 
938   /* response length */
939   len_to_send = (uint16_t)(p_rsp - &p_ccb->rsp_list[0]);
940   cont_offset = 0;
941 
942   // The current SDP server design has a critical flaw where it can run into
943   // an infinite request/response loop with the client. Here's the scenario:
944   // - client makes SDP request
945   // - server returns the first fragment of the response with a continuation
946   //   token
947   // - an SDP record is deleted from the server
948   // - client issues another request with previous continuation token
949   // - server has nothing to send back because the record is unavailable but
950   //   in the first fragment, it had specified more response bytes than are
951   //   now available
952   // - server sends back no additional response bytes and returns the same
953   //   continuation token
954   // - client issues another request with the continuation token, and the
955   //   process repeats
956   //
957   // We work around this design flaw here by checking if we will make forward
958   // progress (i.e. we will send > 0 response bytes) on a continued request.
959   // If not, we must have run into the above situation and we tell the peer an
960   // error occurred.
961   //
962   // TODO(sharvil): rewrite SDP server.
963   if (is_cont && len_to_send == 0) {
964     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE, NULL);
965     return;
966   }
967 
968   /* If first response, insert sequence header */
969   if (!is_cont) {
970     /* Get the total list length for requested uid and attribute sequence */
971     p_ccb->list_len = sdpu_get_list_len(&uid_seq, &attr_seq_sav) + 3;
972 
973     /* Get the length of denylisted attributes to be updated if device is
974      * denylisted */
975     if (bluetooth::common::init_flags::
976             pbap_pse_dynamic_version_upgrade_is_enabled()) {
977       p_ccb->pse_dynamic_attributes_len =
978           sdp_pbap_pse_dynamic_attributes_len_update(p_ccb, &attr_seq_sav,
979                                                      &uid_seq);
980     } else {
981       SDP_TRACE_WARNING("PBAP PSE dynamic version upgrade is not enabled");
982       p_ccb->pse_dynamic_attributes_len = 0;
983     }
984 
985     SDP_TRACE_DEBUG("p_ccb->list_len = %d pse_dynamic_attributes_len = %d",
986                     p_ccb->list_len, p_ccb->pse_dynamic_attributes_len);
987 
988     /* Put in the sequence header (2 or 3 bytes) */
989     if (p_ccb->list_len > 255) {
990       p_ccb->rsp_list[0] =
991           (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
992       p_ccb->rsp_list[1] =
993           (uint8_t)((p_ccb->list_len - 3 + p_ccb->pse_dynamic_attributes_len) >>
994                     8);
995       p_ccb->rsp_list[2] =
996           (uint8_t)(p_ccb->list_len - 3 + p_ccb->pse_dynamic_attributes_len);
997     } else {
998       cont_offset = 1;
999 
1000       p_ccb->rsp_list[1] =
1001           (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
1002       p_ccb->rsp_list[2] =
1003           (uint8_t)(p_ccb->list_len - 3 + p_ccb->pse_dynamic_attributes_len);
1004 
1005       p_ccb->list_len--;
1006       len_to_send--;
1007     }
1008   }
1009 
1010   /* Get a buffer to use to build the response */
1011   BT_HDR* p_buf = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
1012   p_buf->offset = L2CAP_MIN_OFFSET;
1013   p_rsp = p_rsp_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
1014 
1015   /* Start building a rsponse */
1016   UINT8_TO_BE_STREAM(p_rsp, SDP_PDU_SERVICE_SEARCH_ATTR_RSP);
1017   UINT16_TO_BE_STREAM(p_rsp, trans_num);
1018 
1019   /* Skip the parameter length, add it when we know the length */
1020   p_rsp_param_len = p_rsp;
1021   p_rsp += 2;
1022 
1023   /* Stream the list length to send */
1024   UINT16_TO_BE_STREAM(p_rsp, len_to_send);
1025 
1026   /* copy from rsp_list to the actual buffer to be sent */
1027   memcpy(p_rsp, &p_ccb->rsp_list[cont_offset], len_to_send);
1028   p_rsp += len_to_send;
1029 
1030   p_ccb->cont_offset += len_to_send;
1031 
1032   SDP_TRACE_DEBUG(
1033       "p_ccb->pse_dynamic_attributes_len %d, cont_offset = %d, p_ccb->list_len "
1034       "= %d",
1035       p_ccb->pse_dynamic_attributes_len, p_ccb->cont_offset,
1036       p_ccb->list_len + p_ccb->pse_dynamic_attributes_len);
1037   /* If anything left to send, continuation needed */
1038   if (p_ccb->cont_offset <
1039       (p_ccb->list_len + p_ccb->pse_dynamic_attributes_len)) {
1040     is_cont = true;
1041     UINT8_TO_BE_STREAM(p_rsp, SDP_CONTINUATION_LEN);
1042     UINT16_TO_BE_STREAM(p_rsp, p_ccb->cont_offset);
1043   } else {
1044     UINT8_TO_BE_STREAM(p_rsp, 0);
1045     if (p_ccb->pse_dynamic_attributes_len) {
1046       p_ccb->pse_dynamic_attributes_len = 0;
1047     }
1048   }
1049 
1050   /* Go back and put the parameter length into the buffer */
1051   rsp_param_len = p_rsp - p_rsp_param_len - 2;
1052   UINT16_TO_BE_STREAM(p_rsp_param_len, rsp_param_len);
1053 
1054   /* Set the length of the SDP data in the buffer */
1055   p_buf->len = p_rsp - p_rsp_start;
1056 
1057   /* Send the buffer through L2CAP */
1058   L2CA_DataWrite(p_ccb->connection_id, p_buf);
1059 }
1060 
1061 /*************************************************************************************
1062 **
1063 ** Function        is_device_in_allowlist_for_pbap
1064 **
1065 ** Description     Checks if given PBAP device is in allowlist for PBAP PSE.
1066 **
1067 ** Returns         BOOLEAN
1068 **
1069 ***************************************************************************************/
is_device_in_allowlist_for_pbap(RawAddress remote_address,bool check_for_1_2)1070 static bool is_device_in_allowlist_for_pbap(RawAddress remote_address,
1071                                             bool check_for_1_2) {
1072   if (!check_for_1_2 &&
1073       interop_match_addr_or_name(INTEROP_ADV_PBAP_VER_1_1, &remote_address,
1074                                  &btif_storage_get_remote_device_property)) {
1075     SDP_TRACE_DEBUG("device is in allowlist for pbap version < 1.2 ");
1076     return true;
1077   }
1078   if (check_for_1_2) {
1079     if (btm_sec_is_a_bonded_dev(remote_address)) {
1080       if (interop_match_addr_or_name(
1081               INTEROP_ADV_PBAP_VER_1_2, &remote_address,
1082               &btif_storage_get_remote_device_property)) {
1083         SDP_TRACE_DEBUG("device is in allowlist for pbap version 1.2 ");
1084         return true;
1085       }
1086     } else {
1087       char* p_name = BTM_SecReadDevName(remote_address);
1088       if ((p_name != NULL) &&
1089           interop_match_name(INTEROP_ADV_PBAP_VER_1_2, p_name)) {
1090         SDP_TRACE_DEBUG(
1091             "device is not paired & in allowlist for pbap version 1.2");
1092         return true;
1093       }
1094     }
1095   }
1096   return false;
1097 }
1098 
1099 /*************************************************************************************
1100 **
1101 ** Function        sdp_pbap_pse_dynamic_attributes_len_update
1102 **
1103 ** Description      length of the attributes need to be added in final sdp
1104 *response len
1105 **
1106 ** Returns         returns the length of denylisted attributes.
1107 **
1108 ***************************************************************************************/
sdp_pbap_pse_dynamic_attributes_len_update(tCONN_CB * p_ccb,tSDP_ATTR_SEQ * attr_seq,tSDP_UUID_SEQ * uid_seq)1109 static uint16_t sdp_pbap_pse_dynamic_attributes_len_update(
1110     tCONN_CB* p_ccb, tSDP_ATTR_SEQ* attr_seq, tSDP_UUID_SEQ* uid_seq) {
1111   if (!p_ccb || !attr_seq || !uid_seq) return 0;
1112   const tSDP_RECORD* p_rec;
1113 
1114   p_ccb->pse_dynamic_attributes_len = 0;
1115 
1116   // Check to validate if 1.2 record is getting sent
1117   bool is_pbap_102_supported =
1118       btif_storage_is_pce_version_102(p_ccb->device_address);
1119   bool is_pbap_101_allowlisted =
1120       is_device_in_allowlist_for_pbap(p_ccb->device_address, false);
1121   bool is_pbap_102_allowlisted =
1122       is_device_in_allowlist_for_pbap(p_ccb->device_address, true);
1123   bool running_pts = osi_property_get_bool(SDP_ENABLE_PTS_PBAP, false);
1124 
1125   SDP_TRACE_DEBUG(
1126       "remote BD Addr : %s is_pbap_102_supported = %d "
1127       "is_pbap_101_allowlisted = %d is_pbap_102_allowlisted = %d "
1128       "running_pts = %d",
1129       ADDRESS_TO_LOGGABLE_CSTR(p_ccb->device_address), is_pbap_102_supported,
1130       is_pbap_101_allowlisted, is_pbap_102_allowlisted, running_pts);
1131 
1132   if (is_pbap_101_allowlisted ||
1133       (!is_pbap_102_supported && !is_pbap_102_allowlisted && !running_pts)) {
1134     // Send Length without any update
1135     return p_ccb->pse_dynamic_attributes_len;
1136   }
1137 
1138   int xx;
1139   tSDP_ATTRIBUTE attr;
1140   for (p_rec = (tSDP_RECORD*)sdp_db_service_search(NULL, uid_seq); p_rec;
1141        p_rec = (tSDP_RECORD*)sdp_db_service_search(p_rec, uid_seq)) {
1142     attr = p_rec->attribute[1];
1143     if ((attr.id == ATTR_ID_SERVICE_CLASS_ID_LIST) &&
1144         (((attr.value_ptr[1] << 8) | (attr.value_ptr[2])) ==
1145          UUID_SERVCLASS_PBAP_PSE)) {
1146       // PBAP PSE Record
1147       p_rec = sdp_upgrade_pse_record(p_rec, p_ccb->device_address);
1148       SDP_TRACE_DEBUG("response has PBAP PSE record for allowlist device");
1149 
1150       int att_index;
1151       bool l2cap_psm_len_included = false, supp_attr_len_included = false;
1152       for (xx = p_ccb->cont_info.next_attr_index; xx < attr_seq->num_attr;
1153            xx++) {
1154         SDP_TRACE_DEBUG(
1155             "xx = %d attr_seq->num_attr = %d, "
1156             "attr_seq->attr_entry[xx].start = %d , "
1157             "attr_seq->attr_entry[xx].end = %d",
1158             xx, attr_seq->num_attr, attr_seq->attr_entry[xx].start,
1159             attr_seq->attr_entry[xx].end);
1160 
1161         for (att_index = 0; att_index < p_rec->num_attributes; att_index++) {
1162           tSDP_ATTRIBUTE cur_attr = p_rec->attribute[att_index];
1163           if (cur_attr.id == ATTR_ID_GOEP_L2CAP_PSM &&
1164               !l2cap_psm_len_included &&
1165               cur_attr.id >= attr_seq->attr_entry[xx].start &&
1166               cur_attr.id <= attr_seq->attr_entry[xx].end) {
1167             l2cap_psm_len_included = true;
1168             p_ccb->pse_dynamic_attributes_len += PBAP_GOEP_L2CAP_PSM_LEN;
1169             SDP_TRACE_ERROR(
1170                 "ATTR_ID_GOEP_L2CAP_PSM requested,"
1171                 " need to change length by %d",
1172                 p_ccb->pse_dynamic_attributes_len);
1173           } else if (cur_attr.id == ATTR_ID_PBAP_SUPPORTED_FEATURES &&
1174                      !supp_attr_len_included &&
1175                      cur_attr.id >= attr_seq->attr_entry[xx].start &&
1176                      cur_attr.id <= attr_seq->attr_entry[xx].end) {
1177             supp_attr_len_included = true;
1178             p_ccb->pse_dynamic_attributes_len += PBAP_SUPP_FEA_LEN;
1179             SDP_TRACE_DEBUG(
1180                 "ATTR_ID_PBAP_SUPPORTED_FEATURES requested,"
1181                 " need to change length by %d",
1182                 p_ccb->pse_dynamic_attributes_len);
1183           }
1184         }
1185         if (p_ccb->pse_dynamic_attributes_len == PBAP_1_2_BL_LEN) break;
1186       }
1187       break;
1188     }
1189   }
1190   SDP_TRACE_DEBUG("pse_dynamic_attributes_len = %d",
1191                   p_ccb->pse_dynamic_attributes_len);
1192   return p_ccb->pse_dynamic_attributes_len;
1193 }
1194 
1195 /*************************************************************************************
1196 **
1197 ** Function        sdp_upgrade_pbap_pse_record
1198 **
1199 ** Description     updates pbap record to pbap 1.2 record if remote supports
1200 *pbap 1.2
1201 **
1202 ** Returns         the address of updated record
1203 **
1204 ***************************************************************************************/
sdp_upgrade_pse_record(const tSDP_RECORD * p_rec,RawAddress remote_address)1205 static const tSDP_RECORD* sdp_upgrade_pse_record(const tSDP_RECORD* p_rec,
1206                                                  RawAddress remote_address) {
1207   static bool is_pbap_102_supported = FALSE;
1208   tSDP_ATTRIBUTE attr = p_rec->attribute[1];
1209   if (!((attr.id == ATTR_ID_SERVICE_CLASS_ID_LIST) &&
1210         (((attr.value_ptr[1] << 8) | (attr.value_ptr[2])) ==
1211          UUID_SERVCLASS_PBAP_PSE))) {
1212     // Not a PBAP PSE Record
1213     return p_rec;
1214   }
1215 
1216   /* Check if remote supports PBAP 1.2 */
1217   is_pbap_102_supported = btif_storage_is_pce_version_102(remote_address);
1218   bool is_pbap_101_allowlisted =
1219       is_device_in_allowlist_for_pbap(remote_address, false);
1220   bool is_pbap_102_allowlisted =
1221       is_device_in_allowlist_for_pbap(remote_address, true);
1222   bool running_pts = osi_property_get_bool(SDP_ENABLE_PTS_PBAP, false);
1223 
1224   SDP_TRACE_DEBUG(
1225       "%s remote BD Addr : %s is_pbap_102_supported : %d "
1226       "is_pbap_101_allowlisted = %d is_pbap_102_allowlisted = %d "
1227       "running_pts = %d",
1228       __func__, ADDRESS_TO_LOGGABLE_CSTR(remote_address), is_pbap_102_supported,
1229       is_pbap_101_allowlisted, is_pbap_102_allowlisted, running_pts);
1230 
1231   if (is_pbap_101_allowlisted ||
1232       (!is_pbap_102_supported && !is_pbap_102_allowlisted && !running_pts)) {
1233     // Send 1.1 SDP Record
1234     return p_rec;
1235   }
1236 
1237   static tSDP_RECORD pbap_102_sdp_rec = {};
1238   const tSDP_ATTRIBUTE* p_attr = &p_rec->attribute[0];
1239   uint8_t temp[4], j;
1240   uint8_t* p_temp = temp;
1241   bool status = true;
1242 
1243   /* Copying contents of the PBAP 1.1 PSE record to a new 1.2 record */
1244   for (j = 0; j < p_rec->num_attributes; j++, p_attr++) {
1245     SDP_AddAttributeToRecord(&pbap_102_sdp_rec, p_attr->id, p_attr->type,
1246                              p_attr->len, p_attr->value_ptr);
1247   }
1248 
1249   /* Add supported repositories 1 byte */
1250   status &= SDP_AddAttributeToRecord(
1251       &pbap_102_sdp_rec, ATTR_ID_SUPPORTED_REPOSITORIES, UINT_DESC_TYPE,
1252       (uint32_t)1, (uint8_t*)&sdpPseLocalRecord.supported_repositories);
1253 
1254   /* Add in the Bluetooth Profile Descriptor List */
1255   status &= SDP_AddProfileDescriptorListToRecord(
1256       &pbap_102_sdp_rec, UUID_SERVCLASS_PHONE_ACCESS,
1257       sdpPseLocalRecord.profile_version);
1258 
1259   /* Add PBAP 1.2 supported features 4 */
1260   UINT32_TO_BE_STREAM(p_temp, sdpPseLocalRecord.supported_features);
1261   status &= SDP_AddAttributeToRecord(&pbap_102_sdp_rec,
1262                                      ATTR_ID_PBAP_SUPPORTED_FEATURES,
1263                                      UINT_DESC_TYPE, (uint32_t)4, temp);
1264 
1265   /* Add the L2CAP PSM */
1266   p_temp = temp;  // The macro modifies p_temp, hence rewind.
1267   UINT16_TO_BE_STREAM(p_temp, sdpPseLocalRecord.l2cap_psm);
1268   status &= SDP_AddAttributeToRecord(&pbap_102_sdp_rec, ATTR_ID_GOEP_L2CAP_PSM,
1269                                      UINT_DESC_TYPE, (uint32_t)2, temp);
1270 
1271   if (!status) {
1272     SDP_TRACE_ERROR("FAILED");
1273     return p_rec;
1274   }
1275   return &pbap_102_sdp_rec;
1276 }
1277 
1278 /*************************************************************************************
1279 **
1280 ** Function        update_pce_entry_to_interop_database
1281 **
1282 ** Description     Update PCE 1.2 entry to dynamic interop database
1283 **
1284 ***************************************************************************************/
update_pce_entry_to_interop_database(RawAddress remote_addr)1285 void update_pce_entry_to_interop_database(RawAddress remote_addr) {
1286   if (!interop_match_addr_or_name(INTEROP_ADV_PBAP_VER_1_2, &remote_addr,
1287                                   &btif_storage_get_remote_device_property)) {
1288     interop_database_add_addr(INTEROP_ADV_PBAP_VER_1_2, &remote_addr, 3);
1289     SDP_TRACE_DEBUG("device: %s is added into interop list",
1290                     ADDRESS_TO_LOGGABLE_CSTR(remote_addr));
1291   } else {
1292     SDP_TRACE_WARNING("device: %s is already found on interop list",
1293                       ADDRESS_TO_LOGGABLE_CSTR(remote_addr));
1294   }
1295 }
1296 
1297 /*************************************************************************************
1298 **
1299 ** Function        is_sdp_pbap_pce_disabled
1300 **
1301 ** Description     Checks if given PBAP record is for PBAP PSE and SDP
1302 *denylisted
1303 **
1304 ** Returns         BOOLEAN
1305 **
1306 ***************************************************************************************/
is_sdp_pbap_pce_disabled(RawAddress remote_address)1307 bool is_sdp_pbap_pce_disabled(RawAddress remote_address) {
1308   if (interop_match_addr_or_name(INTEROP_DISABLE_PCE_SDP_AFTER_PAIRING,
1309                                  &remote_address,
1310                                  &btif_storage_get_remote_device_property)) {
1311     SDP_TRACE_DEBUG("device is denylisted for PCE SDP ");
1312     return true;
1313   } else {
1314     return false;
1315   }
1316 }
1317 
1318 /*************************************************************************************
1319 **
1320 ** Function        sdp_save_local_pse_record_attributes_val
1321 **
1322 ** Description     Save pbap 1.2 sdp record attributes values, which would be
1323 *used for dynamic version upgrade.
1324 **
1325 ** Returns         BOOLEAN
1326 **
1327 ***************************************************************************************/
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)1328 void sdp_save_local_pse_record_attributes(int32_t rfcomm_channel_number,
1329                                           int32_t l2cap_psm,
1330                                           int32_t profile_version,
1331                                           uint32_t supported_features,
1332                                           uint32_t supported_repositories) {
1333   SDP_TRACE_WARNING(
1334       "rfcomm_channel_number: 0x%x, l2cap_psm: 0x%x profile_version: 0x%x"
1335       "supported_features: 0x%x supported_repositories:  0x%x",
1336       rfcomm_channel_number, l2cap_psm, profile_version, supported_features,
1337       supported_repositories);
1338   sdpPseLocalRecord.rfcomm_channel_number = rfcomm_channel_number;
1339   sdpPseLocalRecord.l2cap_psm = l2cap_psm;
1340   sdpPseLocalRecord.profile_version = profile_version;
1341   sdpPseLocalRecord.supported_features = supported_features;
1342   sdpPseLocalRecord.supported_repositories = supported_repositories;
1343 }
1344