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