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