OSDN Git Service

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