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 SDP discovery functions
22 *
23 ******************************************************************************/
24
25 #define LOG_TAG "stack::sdp"
26
27 #include <bluetooth/log.h>
28 #include <com_android_bluetooth_flags.h>
29
30 #include <cstdint>
31
32 #include "internal_include/bt_target.h"
33 #include "osi/include/allocator.h"
34 #include "stack/include/bt_hdr.h"
35 #include "stack/include/bt_types.h"
36 #include "stack/include/sdpdefs.h"
37 #include "stack/sdp/sdp_discovery_db.h"
38 #include "stack/sdp/sdpint.h"
39 #include "types/bluetooth/uuid.h"
40 #include "types/raw_address.h"
41
42 using bluetooth::Uuid;
43 using namespace bluetooth;
44
45 /* Safety check in case we go crazy */
46 #define MAX_NEST_LEVELS 5
47
48 /*******************************************************************************
49 *
50 * Function sdpu_build_uuid_seq
51 *
52 * Description This function builds a UUID sequence from the list of
53 * passed UUIDs. It is also passed the address of the output
54 * buffer.
55 *
56 * Returns Pointer to next byte in the output buffer.
57 *
58 ******************************************************************************/
sdpu_build_uuid_seq(uint8_t * p_out,uint16_t num_uuids,Uuid * p_uuid_list,uint16_t & bytes_left)59 static uint8_t* sdpu_build_uuid_seq(uint8_t* p_out, uint16_t num_uuids, Uuid* p_uuid_list,
60 uint16_t& bytes_left) {
61 uint16_t xx;
62 uint8_t* p_len;
63
64 if (bytes_left < 2) {
65 DCHECK(0) << "SDP: No space for data element header";
66 return p_out;
67 }
68
69 /* First thing is the data element header */
70 UINT8_TO_BE_STREAM(p_out, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
71
72 /* Remember where the length goes. Leave space for it. */
73 p_len = p_out;
74 p_out += 1;
75
76 /* Account for data element header and length */
77 bytes_left -= 2;
78
79 /* Now, loop through and put in all the UUID(s) */
80 for (xx = 0; xx < num_uuids; xx++, p_uuid_list++) {
81 int len = p_uuid_list->GetShortestRepresentationSize();
82
83 if (len + 1 > bytes_left) {
84 DCHECK(0) << "SDP: Too many UUIDs for internal buffer";
85 break;
86 } else {
87 bytes_left -= (len + 1);
88 }
89
90 if (len == Uuid::kNumBytes16) {
91 UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES);
92 UINT16_TO_BE_STREAM(p_out, p_uuid_list->As16Bit());
93 } else if (len == Uuid::kNumBytes32) {
94 UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
95 UINT32_TO_BE_STREAM(p_out, p_uuid_list->As32Bit());
96 } else if (len == Uuid::kNumBytes128) {
97 UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
98 ARRAY_TO_BE_STREAM(p_out, p_uuid_list->To128BitBE(), (int)Uuid::kNumBytes128);
99 } else {
100 DCHECK(0) << "SDP: Passed UUID has invalid length " << len;
101 }
102 }
103
104 /* Now, put in the length */
105 xx = (uint16_t)(p_out - p_len - 1);
106 UINT8_TO_BE_STREAM(p_len, xx);
107
108 return p_out;
109 }
110
111 /*******************************************************************************
112 *
113 * Function sdp_snd_service_search_req
114 *
115 * Description Send a service search request to the SDP server.
116 *
117 * Returns void
118 *
119 ******************************************************************************/
sdp_snd_service_search_req(tCONN_CB * p_ccb,uint8_t cont_len,uint8_t * p_cont)120 static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len, uint8_t* p_cont) {
121 uint8_t *p, *p_start, *p_param_len;
122 BT_HDR* p_cmd = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
123 uint16_t param_len;
124 uint16_t bytes_left = SDP_DATA_BUF_SIZE;
125
126 /* Prepare the buffer for sending the packet to L2CAP */
127 p_cmd->offset = L2CAP_MIN_OFFSET;
128 p = p_start = (uint8_t*)(p_cmd + 1) + L2CAP_MIN_OFFSET;
129
130 /* Build a service search request packet */
131 UINT8_TO_BE_STREAM(p, SDP_PDU_SERVICE_SEARCH_REQ);
132 UINT16_TO_BE_STREAM(p, p_ccb->transaction_id);
133 p_ccb->transaction_id++;
134
135 /* Skip the length, we need to add it at the end */
136 p_param_len = p;
137 p += 2;
138
139 /* Account for header size, max service record count and
140 * continuation state */
141 const uint16_t base_bytes =
142 (sizeof(BT_HDR) + L2CAP_MIN_OFFSET + 3u + /* service search request header */
143 2u + /* param len */
144 3u + ((p_cont) ? cont_len : 0));
145
146 if (base_bytes > bytes_left) {
147 DCHECK(0) << "SDP: Overran SDP data buffer";
148 osi_free(p_cmd);
149 return;
150 }
151
152 bytes_left -= base_bytes;
153
154 log::assert_that(p_ccb->p_db != nullptr, "SDP database has not been set");
155
156 /* Build the UID sequence. */
157 p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters, p_ccb->p_db->uuid_filters, bytes_left);
158
159 /* Set max service record count */
160 UINT16_TO_BE_STREAM(p, sdp_cb.max_recs_per_search);
161
162 /* Set continuation state */
163 UINT8_TO_BE_STREAM(p, cont_len);
164
165 /* if this is not the first request */
166 if (cont_len && p_cont) {
167 memcpy(p, p_cont, cont_len);
168 p += cont_len;
169 }
170
171 /* Go back and put the parameter length into the buffer */
172 param_len = (uint16_t)(p - p_param_len - 2);
173 UINT16_TO_BE_STREAM(p_param_len, param_len);
174
175 p_ccb->disc_state = SDP_DISC_WAIT_HANDLES;
176
177 /* Set the length of the SDP data in the buffer */
178 p_cmd->len = (uint16_t)(p - p_start);
179
180 if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_cmd) !=
181 tL2CAP_DW_RESULT::SUCCESS) {
182 log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address,
183 p_ccb->connection_id, p - p_start);
184 }
185
186 /* Start inactivity timer */
187 alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS, sdp_conn_timer_timeout, p_ccb);
188 }
189
190 /*******************************************************************************
191 *
192 * Function sdp_copy_raw_data
193 *
194 * Description copy the raw data
195 *
196 *
197 * Returns bool
198 * true if successful
199 * false if not copied
200 *
201 ******************************************************************************/
sdp_copy_raw_data(tCONN_CB * p_ccb,bool offset)202 static bool sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) {
203 unsigned int cpy_len, rem_len;
204 uint32_t list_len;
205 uint8_t* p;
206 uint8_t* p_end;
207 uint8_t type;
208
209 if (p_ccb->p_db && p_ccb->p_db->raw_data) {
210 cpy_len = p_ccb->p_db->raw_size - p_ccb->p_db->raw_used;
211 list_len = p_ccb->list_len;
212 p = &p_ccb->rsp_list[0];
213 p_end = &p_ccb->rsp_list[0] + list_len;
214
215 if (offset) {
216 cpy_len -= 1;
217 type = *p++;
218 uint8_t* old_p = p;
219 p = sdpu_get_len_from_type(p, p_end, type, &list_len);
220 if (p == NULL || (p + list_len) > p_end) {
221 log::warn("bad length");
222 return false;
223 }
224 if ((int)cpy_len < (p - old_p)) {
225 log::warn("no bytes left for data");
226 return false;
227 }
228 cpy_len -= (p - old_p);
229 }
230 if (list_len < cpy_len) {
231 cpy_len = list_len;
232 }
233 rem_len = SDP_MAX_LIST_BYTE_COUNT - (unsigned int)(p - &p_ccb->rsp_list[0]);
234 if (cpy_len > rem_len) {
235 log::warn("rem_len :{} less than cpy_len:{}", rem_len, cpy_len);
236 cpy_len = rem_len;
237 }
238 memcpy(&p_ccb->p_db->raw_data[p_ccb->p_db->raw_used], p, cpy_len);
239 p_ccb->p_db->raw_used += cpy_len;
240 }
241 return true;
242 }
243
244 /*******************************************************************************
245 *
246 * Function add_record
247 *
248 * Description This function allocates space for a record from the DB.
249 *
250 * Returns pointer to next byte in data stream
251 *
252 ******************************************************************************/
add_record(tSDP_DISCOVERY_DB * p_db,const RawAddress & bd_addr)253 static tSDP_DISC_REC* add_record(tSDP_DISCOVERY_DB* p_db, const RawAddress& bd_addr) {
254 tSDP_DISC_REC* p_rec;
255
256 /* See if there is enough space in the database */
257 if (p_db->mem_free < sizeof(tSDP_DISC_REC)) {
258 return NULL;
259 }
260
261 p_rec = (tSDP_DISC_REC*)p_db->p_free_mem;
262 p_db->p_free_mem += sizeof(tSDP_DISC_REC);
263 p_db->mem_free -= sizeof(tSDP_DISC_REC);
264
265 p_rec->p_first_attr = NULL;
266 p_rec->p_next_rec = NULL;
267
268 p_rec->remote_bd_addr = bd_addr;
269
270 /* Add the record to the end of chain */
271 if (!p_db->p_first_rec) {
272 p_db->p_first_rec = p_rec;
273 } else {
274 tSDP_DISC_REC* p_rec1 = p_db->p_first_rec;
275
276 while (p_rec1->p_next_rec) {
277 p_rec1 = p_rec1->p_next_rec;
278 }
279
280 p_rec1->p_next_rec = p_rec;
281 }
282
283 return p_rec;
284 }
285
286 #define SDP_ADDITIONAL_LIST_MASK 0x80
287 /*******************************************************************************
288 *
289 * Function add_attr
290 *
291 * Description This function allocates space for an attribute from the DB
292 * and copies the data into it.
293 *
294 * Returns pointer to next byte in data stream
295 *
296 ******************************************************************************/
add_attr(uint8_t * p,uint8_t * p_end,tSDP_DISCOVERY_DB * p_db,tSDP_DISC_REC * p_rec,uint16_t attr_id,tSDP_DISC_ATTR * p_parent_attr,uint8_t nest_level)297 static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, tSDP_DISC_REC* p_rec,
298 uint16_t attr_id, tSDP_DISC_ATTR* p_parent_attr, uint8_t nest_level) {
299 tSDP_DISC_ATTR* p_attr;
300 uint32_t attr_len;
301 uint32_t total_len;
302 uint16_t attr_type;
303 uint16_t id;
304 uint8_t type;
305 uint8_t* p_attr_end;
306 uint8_t is_additional_list = nest_level & SDP_ADDITIONAL_LIST_MASK;
307
308 nest_level &= ~(SDP_ADDITIONAL_LIST_MASK);
309
310 type = *p++;
311 p = sdpu_get_len_from_type(p, p_end, type, &attr_len);
312 if (p == NULL || (p + attr_len) > p_end) {
313 log::warn("bad length in attr_rsp");
314 return NULL;
315 }
316 attr_len &= SDP_DISC_ATTR_LEN_MASK;
317 attr_type = (type >> 3) & 0x0f;
318
319 /* See if there is enough space in the database */
320 if (attr_len > 4) {
321 total_len = attr_len - 4 + (uint16_t)sizeof(tSDP_DISC_ATTR);
322 } else {
323 total_len = sizeof(tSDP_DISC_ATTR);
324 }
325
326 p_attr_end = p + attr_len;
327 if (p_attr_end > p_end) {
328 log::warn("SDP - Attribute length beyond p_end");
329 return NULL;
330 }
331
332 /* Ensure it is a multiple of 4 */
333 total_len = (total_len + 3) & ~3;
334
335 /* See if there is enough space in the database */
336 if (p_db->mem_free < total_len) {
337 return NULL;
338 }
339
340 p_attr = (tSDP_DISC_ATTR*)p_db->p_free_mem;
341 p_attr->attr_id = attr_id;
342 p_attr->attr_len_type = (uint16_t)attr_len | (attr_type << 12);
343 p_attr->p_next_attr = NULL;
344
345 /* Store the attribute value */
346 switch (attr_type) {
347 case UINT_DESC_TYPE:
348 if ((is_additional_list != 0) && (attr_len == 2)) {
349 BE_STREAM_TO_UINT16(id, p);
350 if (id != ATTR_ID_PROTOCOL_DESC_LIST) {
351 p -= 2;
352 } else {
353 /* Reserve the memory for the attribute now, as we need to add
354 * sub-attributes */
355 p_db->p_free_mem += sizeof(tSDP_DISC_ATTR);
356 p_db->mem_free -= sizeof(tSDP_DISC_ATTR);
357 total_len = 0;
358
359 /* LOG_VERBOSE ("SDP - attr nest level:%d(list)", nest_level); */
360 if (nest_level >= MAX_NEST_LEVELS) {
361 log::error("SDP - attr nesting too deep");
362 return p_attr_end;
363 }
364
365 /* Now, add the list entry */
366 p = add_attr(p, p_end, p_db, p_rec, ATTR_ID_PROTOCOL_DESC_LIST, p_attr,
367 (uint8_t)(nest_level + 1));
368
369 break;
370 }
371 }
372 FALLTHROUGH_INTENDED; /* FALLTHROUGH */
373
374 case TWO_COMP_INT_DESC_TYPE:
375 switch (attr_len) {
376 case 1:
377 p_attr->attr_value.v.u8 = *p++;
378 break;
379 case 2:
380 BE_STREAM_TO_UINT16(p_attr->attr_value.v.u16, p);
381 break;
382 case 4:
383 BE_STREAM_TO_UINT32(p_attr->attr_value.v.u32, p);
384 break;
385 default:
386 BE_STREAM_TO_ARRAY(p, p_attr->attr_value.v.array, (int32_t)attr_len);
387 break;
388 }
389 break;
390
391 case UUID_DESC_TYPE:
392 switch (attr_len) {
393 case 2:
394 BE_STREAM_TO_UINT16(p_attr->attr_value.v.u16, p);
395 break;
396 case 4:
397 BE_STREAM_TO_UINT32(p_attr->attr_value.v.u32, p);
398 if (p_attr->attr_value.v.u32 < 0x10000) {
399 attr_len = 2;
400 p_attr->attr_len_type = (uint16_t)attr_len | (attr_type << 12);
401 p_attr->attr_value.v.u16 = (uint16_t)p_attr->attr_value.v.u32;
402 }
403 break;
404 case 16:
405 /* See if we can compress the UUID down to 16 or 32bit UUIDs */
406 if (sdpu_is_base_uuid(p)) {
407 if ((p[0] == 0) && (p[1] == 0)) {
408 p_attr->attr_len_type = (p_attr->attr_len_type & ~SDP_DISC_ATTR_LEN_MASK) | 2;
409 p += 2;
410 BE_STREAM_TO_UINT16(p_attr->attr_value.v.u16, p);
411 p += Uuid::kNumBytes128 - 4;
412 } else {
413 p_attr->attr_len_type = (p_attr->attr_len_type & ~SDP_DISC_ATTR_LEN_MASK) | 4;
414 BE_STREAM_TO_UINT32(p_attr->attr_value.v.u32, p);
415 p += Uuid::kNumBytes128 - 4;
416 }
417 } else {
418 BE_STREAM_TO_ARRAY(p, p_attr->attr_value.v.array, (int32_t)attr_len);
419 }
420 break;
421 default:
422 log::warn("SDP - bad len in UUID attr: {}", attr_len);
423 return p_attr_end;
424 }
425 break;
426
427 case DATA_ELE_SEQ_DESC_TYPE:
428 case DATA_ELE_ALT_DESC_TYPE:
429 /* Reserve the memory for the attribute now, as we need to add
430 * sub-attributes */
431 p_db->p_free_mem += sizeof(tSDP_DISC_ATTR);
432 p_db->mem_free -= sizeof(tSDP_DISC_ATTR);
433 total_len = 0;
434
435 /* LOG_VERBOSE ("SDP - attr nest level:%d", nest_level); */
436 if (nest_level >= MAX_NEST_LEVELS) {
437 log::error("SDP - attr nesting too deep");
438 return p_attr_end;
439 }
440 if (is_additional_list != 0 || attr_id == ATTR_ID_ADDITION_PROTO_DESC_LISTS) {
441 nest_level |= SDP_ADDITIONAL_LIST_MASK;
442 }
443 /* LOG_VERBOSE ("SDP - attr nest level:0x%x(finish)", nest_level); */
444
445 while (p < p_attr_end) {
446 /* Now, add the list entry */
447 p = add_attr(p, p_end, p_db, p_rec, 0, p_attr, (uint8_t)(nest_level + 1));
448
449 if (!p) {
450 return NULL;
451 }
452 }
453 break;
454
455 case TEXT_STR_DESC_TYPE:
456 case URL_DESC_TYPE:
457 BE_STREAM_TO_ARRAY(p, p_attr->attr_value.v.array, (int32_t)attr_len);
458 break;
459
460 case BOOLEAN_DESC_TYPE:
461 switch (attr_len) {
462 case 1:
463 p_attr->attr_value.v.u8 = *p++;
464 break;
465 default:
466 log::warn("SDP - bad len in boolean attr: {}", attr_len);
467 return p_attr_end;
468 }
469 break;
470
471 default: /* switch (attr_type) */
472 break;
473 }
474
475 p_db->p_free_mem += total_len;
476 p_db->mem_free -= total_len;
477
478 /* Add the attribute to the end of the chain */
479 if (!p_parent_attr) {
480 if (!p_rec->p_first_attr) {
481 p_rec->p_first_attr = p_attr;
482 } else {
483 tSDP_DISC_ATTR* p_attr1 = p_rec->p_first_attr;
484
485 while (p_attr1->p_next_attr) {
486 p_attr1 = p_attr1->p_next_attr;
487 }
488
489 p_attr1->p_next_attr = p_attr;
490 }
491 } else {
492 if (!p_parent_attr->attr_value.v.p_sub_attr) {
493 p_parent_attr->attr_value.v.p_sub_attr = p_attr;
494 /* LOG_VERBOSE ("parent:0x%x(id:%d), ch:0x%x(id:%d)",
495 p_parent_attr, p_parent_attr->attr_id, p_attr, p_attr->attr_id); */
496 } else {
497 tSDP_DISC_ATTR* p_attr1 = p_parent_attr->attr_value.v.p_sub_attr;
498 /* LOG_VERBOSE ("parent:0x%x(id:%d), ch1:0x%x(id:%d)",
499 p_parent_attr, p_parent_attr->attr_id, p_attr1, p_attr1->attr_id); */
500
501 while (p_attr1->p_next_attr) {
502 p_attr1 = p_attr1->p_next_attr;
503 }
504
505 p_attr1->p_next_attr = p_attr;
506 /* LOG_VERBOSE ("new ch:0x%x(id:%d)", p_attr, p_attr->attr_id); */
507 }
508 }
509
510 return p;
511 }
512
513 /*******************************************************************************
514 *
515 * Function save_attr_seq
516 *
517 * Description This function is called when there is a response from
518 * the server.
519 *
520 * Returns pointer to next byte or NULL if error
521 *
522 ******************************************************************************/
save_attr_seq(tCONN_CB * p_ccb,uint8_t * p,uint8_t * p_msg_end)523 static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end) {
524 uint32_t seq_len, attr_len;
525 uint16_t attr_id;
526 uint8_t type, *p_seq_end;
527 tSDP_DISC_REC* p_rec;
528
529 type = *p++;
530
531 if ((type >> 3) != DATA_ELE_SEQ_DESC_TYPE) {
532 log::warn("SDP - Wrong type: 0x{:02x} in attr_rsp", type);
533 return NULL;
534 }
535 p = sdpu_get_len_from_type(p, p_msg_end, type, &seq_len);
536 if (p == NULL || (p + seq_len) > p_msg_end) {
537 log::warn("SDP - Bad len in attr_rsp {}", seq_len);
538 return NULL;
539 }
540
541 /* Create a record */
542 p_rec = add_record(p_ccb->p_db, p_ccb->device_address);
543 if (!p_rec) {
544 log::warn("SDP - DB full add_record");
545 return NULL;
546 }
547
548 p_seq_end = p + seq_len;
549
550 while (p < p_seq_end) {
551 /* First get the attribute ID */
552 type = *p++;
553 p = sdpu_get_len_from_type(p, p_msg_end, type, &attr_len);
554 if (p == NULL || (p + attr_len) > p_seq_end) {
555 log::warn("Bad len in attr_rsp {}", attr_len);
556 return NULL;
557 }
558 if (((type >> 3) != UINT_DESC_TYPE) || (attr_len != 2)) {
559 log::warn("SDP - Bad type: 0x{:02x} or len: {} in attr_rsp", type, attr_len);
560 return NULL;
561 }
562 BE_STREAM_TO_UINT16(attr_id, p);
563
564 /* Now, add the attribute value */
565 p = add_attr(p, p_seq_end, p_ccb->p_db, p_rec, attr_id, NULL, 0);
566
567 if (!p) {
568 log::warn("SDP - DB full add_attr");
569 return NULL;
570 }
571 }
572
573 return p;
574 }
575
576 /*******************************************************************************
577 *
578 * Function process_service_search_attr_rsp
579 *
580 * Description This function is called when there is a search attribute
581 * response from the server.
582 *
583 * Returns void
584 *
585 ******************************************************************************/
process_service_search_attr_rsp(tCONN_CB * p_ccb,uint8_t * p_reply,uint8_t * p_reply_end)586 static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
587 uint8_t* p_reply_end) {
588 uint8_t *p, *p_start, *p_end, *p_param_len;
589 uint8_t type;
590 uint32_t seq_len;
591 uint16_t param_len, lists_byte_count = 0;
592 bool cont_request_needed = false;
593
594 /* If p_reply is NULL, we were called for the initial read */
595 if (p_reply) {
596 if (p_reply + 4 /* transaction ID and length */ + sizeof(lists_byte_count) > p_reply_end) {
597 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_PDU_SIZE);
598 return;
599 }
600
601 /* Skip transaction ID and length */
602 p_reply += 4;
603
604 BE_STREAM_TO_UINT16(lists_byte_count, p_reply);
605
606 /* Copy the response to the scratchpad. First, a safety check on the length
607 */
608 if ((p_ccb->list_len + lists_byte_count) > SDP_MAX_LIST_BYTE_COUNT) {
609 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_PDU_SIZE);
610 return;
611 }
612
613 if (p_reply + lists_byte_count + 1 /* continuation */ > p_reply_end) {
614 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_PDU_SIZE);
615 return;
616 }
617
618 if (p_ccb->rsp_list == NULL) {
619 p_ccb->rsp_list = (uint8_t*)osi_malloc(SDP_MAX_LIST_BYTE_COUNT);
620 }
621 memcpy(&p_ccb->rsp_list[p_ccb->list_len], p_reply, lists_byte_count);
622 p_ccb->list_len += lists_byte_count;
623 p_reply += lists_byte_count;
624 if (*p_reply) {
625 if (*p_reply > SDP_MAX_CONTINUATION_LEN) {
626 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_CONT_STATE);
627 return;
628 }
629
630 cont_request_needed = true;
631 }
632 }
633
634 /* If continuation request (or first time request) */
635 if ((cont_request_needed) || (!p_reply)) {
636 BT_HDR* p_msg = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
637 uint8_t* p;
638 uint16_t bytes_left = SDP_DATA_BUF_SIZE;
639
640 /* If we don't have a valid discovery database, we can't do anything. */
641 if (com::android::bluetooth::flags::btsec_check_valid_discovery_database() &&
642 p_ccb->p_db == NULL) {
643 log::warn(
644 "Attempted continuation or first time request with invalid discovery "
645 "database");
646 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_CONT_STATE);
647 return;
648 }
649
650 p_msg->offset = L2CAP_MIN_OFFSET;
651 p = p_start = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
652
653 /* Build a service search request packet */
654 UINT8_TO_BE_STREAM(p, SDP_PDU_SERVICE_SEARCH_ATTR_REQ);
655 UINT16_TO_BE_STREAM(p, p_ccb->transaction_id);
656 p_ccb->transaction_id++;
657
658 /* Skip the length, we need to add it at the end */
659 p_param_len = p;
660 p += 2;
661
662 /* Account for header size, max service record count and
663 * continuation state */
664 const uint16_t base_bytes =
665 (sizeof(BT_HDR) + L2CAP_MIN_OFFSET + 3u + /* service search request header */
666 2u + /* param len */
667 3u + /* max service record count */
668 ((p_reply) ? (*p_reply) : 0));
669
670 if (base_bytes > bytes_left) {
671 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_CONT_STATE);
672 return;
673 }
674
675 bytes_left -= base_bytes;
676
677 /* Build the UID sequence. */
678 p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters, p_ccb->p_db->uuid_filters,
679 bytes_left);
680
681 /* Max attribute byte count */
682 UINT16_TO_BE_STREAM(p, sdp_cb.max_attr_list_size);
683
684 /* If no attribute filters, build a wildcard attribute sequence */
685 if (p_ccb->p_db->num_attr_filters) {
686 p = sdpu_build_attrib_seq(p, p_ccb->p_db->attr_filters, p_ccb->p_db->num_attr_filters);
687 } else {
688 p = sdpu_build_attrib_seq(p, NULL, 0);
689 }
690
691 /* No continuation for first request */
692 if (p_reply) {
693 if ((p_reply + *p_reply + 1) <= p_reply_end) {
694 memcpy(p, p_reply, *p_reply + 1);
695 p += *p_reply + 1;
696 }
697 } else {
698 UINT8_TO_BE_STREAM(p, 0);
699 }
700
701 /* Go back and put the parameter length into the buffer */
702 param_len = p - p_param_len - 2;
703 UINT16_TO_BE_STREAM(p_param_len, param_len);
704
705 /* Set the length of the SDP data in the buffer */
706 p_msg->len = p - p_start;
707
708 if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_msg) !=
709 tL2CAP_DW_RESULT::SUCCESS) {
710 log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address,
711 p_ccb->connection_id, p - p_start);
712 }
713
714 /* Start inactivity timer */
715 alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS, sdp_conn_timer_timeout, p_ccb);
716
717 return;
718 }
719
720 /*******************************************************************/
721 /* We now have the full response, which is a sequence of sequences */
722 /*******************************************************************/
723
724 if (!sdp_copy_raw_data(p_ccb, true)) {
725 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_ILLEGAL_PARAMETER);
726 return;
727 }
728
729 p = &p_ccb->rsp_list[0];
730
731 /* The contents is a sequence of attribute sequences */
732 type = *p++;
733
734 if ((type >> 3) != DATA_ELE_SEQ_DESC_TYPE) {
735 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_ILLEGAL_PARAMETER);
736 return;
737 }
738 p = sdpu_get_len_from_type(p, p + p_ccb->list_len, type, &seq_len);
739 if (p == NULL || (p + seq_len) > (p + p_ccb->list_len)) {
740 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_ILLEGAL_PARAMETER);
741 return;
742 }
743 p_end = &p_ccb->rsp_list[p_ccb->list_len];
744
745 if ((p + seq_len) != p_end) {
746 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_CONT_STATE);
747 return;
748 }
749
750 while (p < p_end) {
751 p = save_attr_seq(p_ccb, p, &p_ccb->rsp_list[p_ccb->list_len]);
752 if (!p) {
753 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_DB_FULL);
754 return;
755 }
756 }
757
758 /* Since we got everything we need, disconnect the call */
759 sdpu_log_attribute_metrics(p_ccb->device_address, p_ccb->p_db);
760 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_SUCCESS);
761 }
762
763 /*******************************************************************************
764 *
765 * Function process_service_attr_rsp
766 *
767 * Description This function is called when there is a attribute response
768 * from the server.
769 *
770 * Returns void
771 *
772 ******************************************************************************/
process_service_attr_rsp(tCONN_CB * p_ccb,uint8_t * p_reply,uint8_t * p_reply_end)773 static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, uint8_t* p_reply_end) {
774 uint8_t *p_start, *p_param_len;
775 uint16_t param_len, list_byte_count;
776 bool cont_request_needed = false;
777
778 /* If p_reply is NULL, we were called after the records handles were read */
779 if (p_reply) {
780 if (p_reply + 4 /* transaction ID and length */ + sizeof(list_byte_count) > p_reply_end) {
781 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_PDU_SIZE);
782 return;
783 }
784
785 /* Skip transaction ID and length */
786 p_reply += 4;
787
788 BE_STREAM_TO_UINT16(list_byte_count, p_reply);
789
790 /* Copy the response to the scratchpad. First, a safety check on the length
791 */
792 if ((p_ccb->list_len + list_byte_count) > SDP_MAX_LIST_BYTE_COUNT) {
793 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_PDU_SIZE);
794 return;
795 }
796
797 if (p_reply + list_byte_count + 1 /* continuation */ > p_reply_end) {
798 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_PDU_SIZE);
799 return;
800 }
801
802 if (p_ccb->rsp_list == NULL) {
803 p_ccb->rsp_list = (uint8_t*)osi_malloc(SDP_MAX_LIST_BYTE_COUNT);
804 }
805 memcpy(&p_ccb->rsp_list[p_ccb->list_len], p_reply, list_byte_count);
806 p_ccb->list_len += list_byte_count;
807 p_reply += list_byte_count;
808 if (*p_reply) {
809 if (*p_reply > SDP_MAX_CONTINUATION_LEN) {
810 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_CONT_STATE);
811 return;
812 }
813 cont_request_needed = true;
814 } else {
815 log::warn("process_service_attr_rsp");
816 if (!sdp_copy_raw_data(p_ccb, false)) {
817 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_ILLEGAL_PARAMETER);
818 return;
819 }
820
821 /* Save the response in the database. Stop on any error */
822 if (!save_attr_seq(p_ccb, &p_ccb->rsp_list[0], &p_ccb->rsp_list[p_ccb->list_len])) {
823 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_DB_FULL);
824 return;
825 }
826 p_ccb->list_len = 0;
827 p_ccb->cur_handle++;
828 }
829 }
830
831 /* Now, ask for the next handle. Re-use the buffer we just got. */
832 if (p_ccb->cur_handle < p_ccb->num_handles) {
833 BT_HDR* p_msg = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
834 uint8_t* p;
835
836 p_msg->offset = L2CAP_MIN_OFFSET;
837 p = p_start = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
838
839 /* Get all the attributes from the server */
840 UINT8_TO_BE_STREAM(p, SDP_PDU_SERVICE_ATTR_REQ);
841 UINT16_TO_BE_STREAM(p, p_ccb->transaction_id);
842 p_ccb->transaction_id++;
843
844 /* Skip the length, we need to add it at the end */
845 p_param_len = p;
846 p += 2;
847
848 UINT32_TO_BE_STREAM(p, p_ccb->handles[p_ccb->cur_handle]);
849
850 /* Max attribute byte count */
851 UINT16_TO_BE_STREAM(p, sdp_cb.max_attr_list_size);
852
853 /* If no attribute filters, build a wildcard attribute sequence */
854 if (p_ccb->p_db->num_attr_filters) {
855 p = sdpu_build_attrib_seq(p, p_ccb->p_db->attr_filters, p_ccb->p_db->num_attr_filters);
856 } else {
857 p = sdpu_build_attrib_seq(p, NULL, 0);
858 }
859
860 /* Was this a continuation request ? */
861 if (cont_request_needed) {
862 if ((p_reply + *p_reply + 1) <= p_reply_end) {
863 memcpy(p, p_reply, *p_reply + 1);
864 p += *p_reply + 1;
865 }
866 } else {
867 UINT8_TO_BE_STREAM(p, 0);
868 }
869
870 /* Go back and put the parameter length into the buffer */
871 param_len = (uint16_t)(p - p_param_len - 2);
872 UINT16_TO_BE_STREAM(p_param_len, param_len);
873
874 /* Set the length of the SDP data in the buffer */
875 p_msg->len = (uint16_t)(p - p_start);
876
877 if (stack::l2cap::get_interface().L2CA_DataWrite(p_ccb->connection_id, p_msg) !=
878 tL2CAP_DW_RESULT::SUCCESS) {
879 log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address,
880 p_ccb->connection_id, p - p_start);
881 }
882
883 /* Start inactivity timer */
884 alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS, sdp_conn_timer_timeout, p_ccb);
885 } else {
886 sdpu_log_attribute_metrics(p_ccb->device_address, p_ccb->p_db);
887 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_SUCCESS);
888 return;
889 }
890 }
891
892 /******************************************************************************
893 *
894 * Function process_service_search_rsp
895 *
896 * Description This function is called when there is a search response from
897 * the server.
898 *
899 * Returns void
900 *
901 ******************************************************************************/
process_service_search_rsp(tCONN_CB * p_ccb,uint8_t * p_reply,uint8_t * p_reply_end)902 static void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, uint8_t* p_reply_end) {
903 uint16_t xx;
904 uint16_t total, cur_handles, orig;
905 uint8_t cont_len;
906
907 if (p_reply + 8 > p_reply_end) {
908 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_GENERIC_ERROR);
909 return;
910 }
911 /* Skip transaction, and param len */
912 p_reply += 4;
913 BE_STREAM_TO_UINT16(total, p_reply);
914 BE_STREAM_TO_UINT16(cur_handles, p_reply);
915
916 orig = p_ccb->num_handles;
917 p_ccb->num_handles += cur_handles;
918 if (p_ccb->num_handles == 0 || p_ccb->num_handles < orig) {
919 log::warn("SDP - Rcvd ServiceSearchRsp, no matches");
920 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_NO_RECS_MATCH);
921 return;
922 }
923
924 /* Save the handles that match. We will can only process a certain number. */
925 if (total > sdp_cb.max_recs_per_search) {
926 total = sdp_cb.max_recs_per_search;
927 }
928 if (p_ccb->num_handles > sdp_cb.max_recs_per_search) {
929 p_ccb->num_handles = sdp_cb.max_recs_per_search;
930 }
931
932 if (p_reply + ((p_ccb->num_handles - orig) * 4) + 1 > p_reply_end) {
933 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_GENERIC_ERROR);
934 return;
935 }
936
937 for (xx = orig; xx < p_ccb->num_handles; xx++) {
938 BE_STREAM_TO_UINT32(p_ccb->handles[xx], p_reply);
939 }
940
941 BE_STREAM_TO_UINT8(cont_len, p_reply);
942 if (cont_len != 0) {
943 if (cont_len > SDP_MAX_CONTINUATION_LEN) {
944 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_CONT_STATE);
945 return;
946 }
947 if (p_reply + cont_len > p_reply_end) {
948 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_INVALID_CONT_STATE);
949 return;
950 }
951 /* stay in the same state */
952 sdp_snd_service_search_req(p_ccb, cont_len, p_reply);
953 } else {
954 /* change state */
955 p_ccb->disc_state = SDP_DISC_WAIT_ATTR;
956
957 /* Kick off the first attribute request */
958 process_service_attr_rsp(p_ccb, NULL, NULL);
959 }
960 }
961
962 /*******************************************************************************
963 *
964 * Function sdp_disc_connected
965 *
966 * Description This function is called when an SDP discovery attempt is
967 * connected.
968 *
969 * Returns void
970 *
971 ******************************************************************************/
sdp_disc_connected(tCONN_CB * p_ccb)972 void sdp_disc_connected(tCONN_CB* p_ccb) {
973 if (p_ccb->is_attr_search) {
974 p_ccb->disc_state = SDP_DISC_WAIT_SEARCH_ATTR;
975
976 process_service_search_attr_rsp(p_ccb, NULL, NULL);
977 } else {
978 /* First step is to get a list of the handles from the server. */
979 /* We are not searching for a specific attribute, so we will */
980 /* first search for the service, then get all attributes of it */
981
982 p_ccb->num_handles = 0;
983 sdp_snd_service_search_req(p_ccb, 0, NULL);
984 }
985 }
986
987 /*******************************************************************************
988 *
989 * Function sdp_disc_server_rsp
990 *
991 * Description This function is called when there is a response from
992 * the server.
993 *
994 * Returns void
995 *
996 ******************************************************************************/
sdp_disc_server_rsp(tCONN_CB * p_ccb,BT_HDR * p_msg)997 void sdp_disc_server_rsp(tCONN_CB* p_ccb, BT_HDR* p_msg) {
998 uint8_t *p, rsp_pdu;
999 bool invalid_pdu = true;
1000
1001 /* stop inactivity timer when we receive a response */
1002 alarm_cancel(p_ccb->sdp_conn_timer);
1003
1004 /* Got a reply!! Check what we got back */
1005 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
1006 uint8_t* p_end = p + p_msg->len;
1007
1008 if (p_msg->len < 1) {
1009 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_GENERIC_ERROR);
1010 return;
1011 }
1012
1013 BE_STREAM_TO_UINT8(rsp_pdu, p);
1014
1015 p_msg->len--;
1016
1017 switch (rsp_pdu) {
1018 case SDP_PDU_SERVICE_SEARCH_RSP:
1019 if (p_ccb->disc_state == SDP_DISC_WAIT_HANDLES) {
1020 process_service_search_rsp(p_ccb, p, p_end);
1021 invalid_pdu = false;
1022 }
1023 break;
1024
1025 case SDP_PDU_SERVICE_ATTR_RSP:
1026 if (p_ccb->disc_state == SDP_DISC_WAIT_ATTR) {
1027 process_service_attr_rsp(p_ccb, p, p_end);
1028 invalid_pdu = false;
1029 }
1030 break;
1031
1032 case SDP_PDU_SERVICE_SEARCH_ATTR_RSP:
1033 if (p_ccb->disc_state == SDP_DISC_WAIT_SEARCH_ATTR) {
1034 process_service_search_attr_rsp(p_ccb, p, p_end);
1035 invalid_pdu = false;
1036 }
1037 break;
1038 }
1039
1040 if (invalid_pdu) {
1041 log::warn("SDP - Unexp. PDU: {} in state: {}", rsp_pdu, p_ccb->disc_state);
1042 sdp_disconnect(p_ccb, tSDP_STATUS::SDP_GENERIC_ERROR);
1043 }
1044 }
1045