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