15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 1999-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  this file contains SDP discovery functions
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include <stdio.h>
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdlib.h>
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov#include "bt_common.h"
30911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "bt_target.h"
31911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "btm_api.h"
32911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "btu.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hcidefs.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hcimsgs.h"
35911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "l2cdefs.h"
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "sdp_api.h"
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "sdpint.h"
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifndef SDP_DEBUG_RAW
40911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define SDP_DEBUG_RAW false
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
43ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/
449ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson/*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
45ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************/
46911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply);
47911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply);
48911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply);
49911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end);
50911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic tSDP_DISC_REC* add_record(tSDP_DISCOVERY_DB* p_db, BD_ADDR p_bda);
51911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic uint8_t* add_attr(uint8_t* p, tSDP_DISCOVERY_DB* p_db,
52911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                         tSDP_DISC_REC* p_rec, uint16_t attr_id,
53911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                         tSDP_DISC_ATTR* p_parent_attr, uint8_t nest_level);
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Safety check in case we go crazy */
56911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define MAX_NEST_LEVELS 5
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
58911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonextern fixed_queue_t* btu_general_alarm_queue;
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
61ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
62ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         sdpu_build_uuid_seq
63ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
64ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function builds a UUID sequence from the list of
65ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  passed UUIDs. It is also passed the address of the output
66ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  buffer.
67ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
68ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          Pointer to next byte in the output buffer.
69ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
70ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
71911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic uint8_t* sdpu_build_uuid_seq(uint8_t* p_out, uint16_t num_uuids,
72911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                    tSDP_UUID* p_uuid_list) {
73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t xx;
74911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p_len;
75911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
76911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* First thing is the data element header */
77911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p_out, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
78911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
79911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Remember where the length goes. Leave space for it. */
80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_len = p_out;
81911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_out += 1;
82911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
83911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Now, loop through and put in all the UUID(s) */
84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (xx = 0; xx < num_uuids; xx++, p_uuid_list++) {
85911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_uuid_list->len == 2) {
86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES);
87911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      UINT16_TO_BE_STREAM(p_out, p_uuid_list->uu.uuid16);
88911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else if (p_uuid_list->len == 4) {
89911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
90911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      UINT32_TO_BE_STREAM(p_out, p_uuid_list->uu.uuid32);
91911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
92911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
93911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      ARRAY_TO_BE_STREAM(p_out, p_uuid_list->uu.uuid128, p_uuid_list->len);
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Now, put in the length */
98911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  xx = (uint16_t)(p_out - p_len - 1);
99911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p_len, xx);
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return (p_out);
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
105ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
106ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         sdp_snd_service_search_req
107ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
108ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      Send a service search request to the SDP server.
109ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
110ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
111ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
112ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len,
114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                       uint8_t* p_cont) {
115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t *p, *p_start, *p_param_len;
116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BT_HDR* p_cmd = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
117911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t param_len;
118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Prepare the buffer for sending the packet to L2CAP */
120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cmd->offset = L2CAP_MIN_OFFSET;
121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = p_start = (uint8_t*)(p_cmd + 1) + L2CAP_MIN_OFFSET;
122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Build a service search request packet */
124911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, SDP_PDU_SERVICE_SEARCH_REQ);
125911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_BE_STREAM(p, p_ccb->transaction_id);
126911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_ccb->transaction_id++;
127911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
128911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Skip the length, we need to add it at the end */
129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_param_len = p;
130911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p += 2;
131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
132911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson/* Build the UID sequence. */
133d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen#if (SDP_BROWSE_PLUS == TRUE)
134911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = sdpu_build_uuid_seq(p, 1,
135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                          &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx]);
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters,
138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                          p_ccb->p_db->uuid_filters);
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
141911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Set max service record count */
142911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_BE_STREAM(p, sdp_cb.max_recs_per_search);
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Set continuation state */
145911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_BE_STREAM(p, cont_len);
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* if this is not the first request */
148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (cont_len && p_cont) {
149911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p, p_cont, cont_len);
150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p += cont_len;
151911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
153911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Go back and put the parameter length into the buffer */
154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  param_len = (uint16_t)(p - p_param_len - 2);
155911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT16_TO_BE_STREAM(p_param_len, param_len);
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
157911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_ccb->disc_state = SDP_DISC_WAIT_HANDLES;
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
159911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Set the length of the SDP data in the buffer */
160911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cmd->len = (uint16_t)(p - p_start);
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
163911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SDP_TRACE_WARNING("sdp_snd_service_search_req cont_len :%d disc_state:%d",
164911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                    cont_len, p_ccb->disc_state);
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
167911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  L2CA_DataWrite(p_ccb->connection_id, p_cmd);
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
169911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Start inactivity timer */
170911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  alarm_set_on_queue(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
171911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                     sdp_conn_timer_timeout, p_ccb, btu_general_alarm_queue);
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
175ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
176ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         sdp_disc_connected
177ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
178ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called when an SDP discovery attempt is
179ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  connected.
180ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
181ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
182ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
183ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
184911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid sdp_disc_connected(tCONN_CB* p_ccb) {
185911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_ccb->is_attr_search) {
186911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_ccb->disc_state = SDP_DISC_WAIT_SEARCH_ATTR;
187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    process_service_search_attr_rsp(p_ccb, NULL);
189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
190911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* First step is to get a list of the handles from the server. */
191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* We are not searching for a specific attribute, so we will   */
192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* first search for the service, then get all attributes of it */
193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_ccb->num_handles = 0;
195911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    sdp_snd_service_search_req(p_ccb, 0, NULL);
196911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
200ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
201ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         sdp_disc_server_rsp
202ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
203ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called when there is a response from
204ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  the server.
205ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
206ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
207ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
208ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
209911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid sdp_disc_server_rsp(tCONN_CB* p_ccb, BT_HDR* p_msg) {
210911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t *p, rsp_pdu;
211911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bool invalid_pdu = true;
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
214911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SDP_TRACE_WARNING("sdp_disc_server_rsp disc_state:%d", p_ccb->disc_state);
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
217911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* stop inactivity timer when we receive a response */
218911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  alarm_cancel(p_ccb->sdp_conn_timer);
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
220911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Got a reply!! Check what we got back */
221911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
223911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BE_STREAM_TO_UINT8(rsp_pdu, p);
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
225911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_msg->len--;
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
227911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (rsp_pdu) {
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case SDP_PDU_SERVICE_SEARCH_RSP:
229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_ccb->disc_state == SDP_DISC_WAIT_HANDLES) {
230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        process_service_search_rsp(p_ccb, p);
231911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        invalid_pdu = false;
232911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
233911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case SDP_PDU_SERVICE_ATTR_RSP:
236911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_ccb->disc_state == SDP_DISC_WAIT_ATTR) {
237911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        process_service_attr_rsp(p_ccb, p);
238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        invalid_pdu = false;
239911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
240911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case SDP_PDU_SERVICE_SEARCH_ATTR_RSP:
243911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_ccb->disc_state == SDP_DISC_WAIT_SEARCH_ATTR) {
244911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        process_service_search_attr_rsp(p_ccb, p);
245911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        invalid_pdu = false;
246911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
247911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
248911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
249911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
250911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (invalid_pdu) {
251911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("SDP - Unexp. PDU: %d in state: %d", rsp_pdu,
252911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                      p_ccb->disc_state);
253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    sdp_disconnect(p_ccb, SDP_GENERIC_ERROR);
254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
258ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
259ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         process_service_search_rsp
260ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
261ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called when there is a search response from
262ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  the server.
263ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
264ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
265ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
266ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
267911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply) {
268911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t xx;
269911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t total, cur_handles, orig;
270911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t cont_len;
271911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
272911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Skip transaction, and param len */
273911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_reply += 4;
274911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BE_STREAM_TO_UINT16(total, p_reply);
275911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BE_STREAM_TO_UINT16(cur_handles, p_reply);
276911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
277911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  orig = p_ccb->num_handles;
278911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_ccb->num_handles += cur_handles;
279911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_ccb->num_handles == 0) {
280911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("SDP - Rcvd ServiceSearchRsp, no matches");
281911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    sdp_disconnect(p_ccb, SDP_NO_RECS_MATCH);
282911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
283911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
284911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
285911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Save the handles that match. We will can only process a certain number. */
286911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (total > sdp_cb.max_recs_per_search) total = sdp_cb.max_recs_per_search;
287911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_ccb->num_handles > sdp_cb.max_recs_per_search)
288911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_ccb->num_handles = sdp_cb.max_recs_per_search;
289911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
290911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (xx = orig; xx < p_ccb->num_handles; xx++)
291911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BE_STREAM_TO_UINT32(p_ccb->handles[xx], p_reply);
292911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
293911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BE_STREAM_TO_UINT8(cont_len, p_reply);
294911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (cont_len != 0) {
295911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (cont_len > SDP_MAX_CONTINUATION_LEN) {
296911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
297911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
299911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* stay in the same state */
300911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    sdp_snd_service_search_req(p_ccb, cont_len, p_reply);
301911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
302911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* change state */
303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_ccb->disc_state = SDP_DISC_WAIT_ATTR;
304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
305911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Kick off the first attribute request */
306911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    process_service_attr_rsp(p_ccb, NULL);
307911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
311ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
312ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         sdp_copy_raw_data
313ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
314ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      copy the raw data
315ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
316ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
317ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
318ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
319ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_RAW_DATA_INCLUDED == TRUE)
321911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) {
322911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  unsigned int cpy_len;
323911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint32_t list_len;
324911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p;
325911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t type;
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
328911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t num_array[SDP_MAX_LIST_BYTE_COUNT];
329911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint32_t i;
330911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
331911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  for (i = 0; i < p_ccb->list_len; i++) {
332911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    snprintf((char*)&num_array[i * 2], sizeof(num_array) - i * 2, "%02X",
333911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson             (uint8_t)(p_ccb->rsp_list[i]));
334911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
335911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SDP_TRACE_WARNING("result :%s", num_array);
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
338911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_ccb->p_db->raw_data) {
339911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    cpy_len = p_ccb->p_db->raw_size - p_ccb->p_db->raw_used;
340911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    list_len = p_ccb->list_len;
341911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p = &p_ccb->rsp_list[0];
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
343911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (offset) {
344911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      type = *p++;
345911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p = sdpu_get_len_from_type(p, type, &list_len);
346911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
347911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (list_len && list_len < cpy_len) {
348911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      cpy_len = list_len;
349911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
3509f9166c5830e06f816ff8299f74518f7ec781347Pavlin Radoslavov    SDP_TRACE_WARNING(
3519f9166c5830e06f816ff8299f74518f7ec781347Pavlin Radoslavov        "%s: list_len:%d cpy_len:%d p:%p p_ccb:%p p_db:%p raw_size:%d "
3529f9166c5830e06f816ff8299f74518f7ec781347Pavlin Radoslavov        "raw_used:%d raw_data:%p",
3539f9166c5830e06f816ff8299f74518f7ec781347Pavlin Radoslavov        __func__, list_len, cpy_len, p, p_ccb, p_ccb->p_db,
3549f9166c5830e06f816ff8299f74518f7ec781347Pavlin Radoslavov        p_ccb->p_db->raw_size, p_ccb->p_db->raw_used, p_ccb->p_db->raw_data);
355911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(&p_ccb->p_db->raw_data[p_ccb->p_db->raw_used], p, cpy_len);
356911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_ccb->p_db->raw_used += cpy_len;
357911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
362ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
363ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         process_service_attr_rsp
364ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
3659ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      This function is called when there is a attribute response
3669ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  from the server.
367ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
368ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
369ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
370ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
371911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply) {
372911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t *p_start, *p_param_len;
373911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t param_len, list_byte_count;
374911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bool cont_request_needed = false;
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
377911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SDP_TRACE_WARNING("process_service_attr_rsp raw inc:%d",
378911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                    SDP_RAW_DATA_INCLUDED);
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
380911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* If p_reply is NULL, we were called after the records handles were read */
381911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_reply) {
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
383911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("ID & len: 0x%02x-%02x-%02x-%02x", p_reply[0], p_reply[1],
384911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                      p_reply[2], p_reply[3]);
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
386911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Skip transaction ID and length */
387911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_reply += 4;
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
389911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BE_STREAM_TO_UINT16(list_byte_count, p_reply);
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
391911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("list_byte_count:%d", list_byte_count);
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
394911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Copy the response to the scratchpad. First, a safety check on the length
395911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson     */
396911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((p_ccb->list_len + list_byte_count) > SDP_MAX_LIST_BYTE_COUNT) {
397911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      sdp_disconnect(p_ccb, SDP_INVALID_PDU_SIZE);
398911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
399911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
402911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("list_len: %d, list_byte_count: %d", p_ccb->list_len,
403911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                      list_byte_count);
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
405911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_ccb->rsp_list == NULL)
406911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_ccb->rsp_list = (uint8_t*)osi_malloc(SDP_MAX_LIST_BYTE_COUNT);
407911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(&p_ccb->rsp_list[p_ccb->list_len], p_reply, list_byte_count);
408911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_ccb->list_len += list_byte_count;
409911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_reply += list_byte_count;
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
411911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("list_len: %d(attr_rsp)", p_ccb->list_len);
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
413911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Check if we need to request a continuation */
414911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("*p_reply:%d(%d)", *p_reply, SDP_MAX_CONTINUATION_LEN);
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
416911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (*p_reply) {
417911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (*p_reply > SDP_MAX_CONTINUATION_LEN) {
418911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
419911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        return;
420911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
421911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      cont_request_needed = true;
422911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_RAW_DATA_INCLUDED == TRUE)
424911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SDP_TRACE_WARNING("process_service_attr_rsp");
425911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      sdp_copy_raw_data(p_ccb, false);
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
428911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Save the response in the database. Stop on any error */
429911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (!save_attr_seq(p_ccb, &p_ccb->rsp_list[0],
430911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                         &p_ccb->rsp_list[p_ccb->list_len])) {
431911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        sdp_disconnect(p_ccb, SDP_DB_FULL);
432911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        return;
433911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
434911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_ccb->list_len = 0;
435911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_ccb->cur_handle++;
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
437911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
439911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Now, ask for the next handle. Re-use the buffer we just got. */
440911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_ccb->cur_handle < p_ccb->num_handles) {
441911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BT_HDR* p_msg = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
442911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* p;
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
444911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_msg->offset = L2CAP_MIN_OFFSET;
445911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p = p_start = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
447911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Get all the attributes from the server */
448911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT8_TO_BE_STREAM(p, SDP_PDU_SERVICE_ATTR_REQ);
449911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_BE_STREAM(p, p_ccb->transaction_id);
450911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_ccb->transaction_id++;
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
452911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Skip the length, we need to add it at the end */
453911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_param_len = p;
454911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p += 2;
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
456911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT32_TO_BE_STREAM(p, p_ccb->handles[p_ccb->cur_handle]);
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
458911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Max attribute byte count */
459911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_BE_STREAM(p, sdp_cb.max_attr_list_size);
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
461911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* If no attribute filters, build a wildcard attribute sequence */
462911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_ccb->p_db->num_attr_filters)
463911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p = sdpu_build_attrib_seq(p, p_ccb->p_db->attr_filters,
464911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                p_ccb->p_db->num_attr_filters);
465911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    else
466911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p = sdpu_build_attrib_seq(p, NULL, 0);
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
468911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Was this a continuation request ? */
469911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (cont_request_needed) {
470911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memcpy(p, p_reply, *p_reply + 1);
471911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += *p_reply + 1;
472911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else
473911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      UINT8_TO_BE_STREAM(p, 0);
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
475911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Go back and put the parameter length into the buffer */
476911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    param_len = (uint16_t)(p - p_param_len - 2);
477911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_BE_STREAM(p_param_len, param_len);
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
479911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Set the length of the SDP data in the buffer */
480911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_msg->len = (uint16_t)(p - p_start);
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
482911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    L2CA_DataWrite(p_ccb->connection_id, p_msg);
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
484911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Start inactivity timer */
485911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    alarm_set_on_queue(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
486911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       sdp_conn_timer_timeout, p_ccb, btu_general_alarm_queue);
487911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
488911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    sdp_disconnect(p_ccb, SDP_SUCCESS);
489911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
490911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
494ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
495ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         process_service_search_attr_rsp
496ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
497ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called when there is a search attribute
498ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  response from the server.
499ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
500ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
501ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
502ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
503911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply) {
504911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t *p, *p_start, *p_end, *p_param_len;
505911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t type;
506911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint32_t seq_len;
507911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t param_len, lists_byte_count = 0;
508911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bool cont_request_needed = false;
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
511911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SDP_TRACE_WARNING("process_service_search_attr_rsp");
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
513911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* If p_reply is NULL, we were called for the initial read */
514911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_reply) {
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
516911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("ID & len: 0x%02x-%02x-%02x-%02x", p_reply[0], p_reply[1],
517911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                      p_reply[2], p_reply[3]);
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
519911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Skip transaction ID and length */
520911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_reply += 4;
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
522911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BE_STREAM_TO_UINT16(lists_byte_count, p_reply);
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
524911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("lists_byte_count:%d", lists_byte_count);
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
527911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Copy the response to the scratchpad. First, a safety check on the length
528911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson     */
529911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((p_ccb->list_len + lists_byte_count) > SDP_MAX_LIST_BYTE_COUNT) {
530911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      sdp_disconnect(p_ccb, SDP_INVALID_PDU_SIZE);
531911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
532911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
535911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("list_len: %d, list_byte_count: %d", p_ccb->list_len,
536911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                      lists_byte_count);
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
538911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_ccb->rsp_list == NULL)
539911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_ccb->rsp_list = (uint8_t*)osi_malloc(SDP_MAX_LIST_BYTE_COUNT);
540911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(&p_ccb->rsp_list[p_ccb->list_len], p_reply, lists_byte_count);
541911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_ccb->list_len += lists_byte_count;
542911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_reply += lists_byte_count;
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
544911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("list_len: %d(search_attr_rsp)", p_ccb->list_len);
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
546911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Check if we need to request a continuation */
547911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("*p_reply:%d(%d)", *p_reply, SDP_MAX_CONTINUATION_LEN);
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
549911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (*p_reply) {
550911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (*p_reply > SDP_MAX_CONTINUATION_LEN) {
551911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
552911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        return;
553911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
555911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      cont_request_needed = true;
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
557911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_DEBUG_RAW == TRUE)
560911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SDP_TRACE_WARNING("cont_request_needed:%d", cont_request_needed);
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
562911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* If continuation request (or first time request) */
563911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((cont_request_needed) || (!p_reply)) {
564911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BT_HDR* p_msg = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
565911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* p;
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
567911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_msg->offset = L2CAP_MIN_OFFSET;
568911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p = p_start = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
570911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Build a service search request packet */
571911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT8_TO_BE_STREAM(p, SDP_PDU_SERVICE_SEARCH_ATTR_REQ);
572911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_BE_STREAM(p, p_ccb->transaction_id);
573911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_ccb->transaction_id++;
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
575911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Skip the length, we need to add it at the end */
576911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_param_len = p;
577911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p += 2;
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
579911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson/* Build the UID sequence. */
580d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen#if (SDP_BROWSE_PLUS == TRUE)
581911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p = sdpu_build_uuid_seq(p, 1,
582911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                            &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx]);
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
584911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters,
585911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                            p_ccb->p_db->uuid_filters);
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
588911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Max attribute byte count */
589911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_BE_STREAM(p, sdp_cb.max_attr_list_size);
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
591911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* If no attribute filters, build a wildcard attribute sequence */
592911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_ccb->p_db->num_attr_filters)
593911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p = sdpu_build_attrib_seq(p, p_ccb->p_db->attr_filters,
594911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                p_ccb->p_db->num_attr_filters);
595911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    else
596911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p = sdpu_build_attrib_seq(p, NULL, 0);
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
598911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* No continuation for first request */
599911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_reply) {
600911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memcpy(p, p_reply, *p_reply + 1);
601911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p += *p_reply + 1;
602911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else
603911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      UINT8_TO_BE_STREAM(p, 0);
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
605911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Go back and put the parameter length into the buffer */
606911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    param_len = p - p_param_len - 2;
607911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    UINT16_TO_BE_STREAM(p_param_len, param_len);
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
609911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Set the length of the SDP data in the buffer */
610911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_msg->len = p - p_start;
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
612911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    L2CA_DataWrite(p_ccb->connection_id, p_msg);
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
614911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Start inactivity timer */
615911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    alarm_set_on_queue(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
616911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       sdp_conn_timer_timeout, p_ccb, btu_general_alarm_queue);
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
618911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
619911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
621911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson/*******************************************************************/
622911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson/* We now have the full response, which is a sequence of sequences */
623911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson/*******************************************************************/
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (SDP_RAW_DATA_INCLUDED == TRUE)
626911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SDP_TRACE_WARNING("process_service_search_attr_rsp");
627911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  sdp_copy_raw_data(p_ccb, true);
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
630911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = &p_ccb->rsp_list[0];
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
632911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* The contents is a sequence of attribute sequences */
633911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  type = *p++;
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
635911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((type >> 3) != DATA_ELE_SEQ_DESC_TYPE) {
636911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("SDP - Wrong type: 0x%02x in attr_rsp", type);
637911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
638911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
639911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = sdpu_get_len_from_type(p, type, &seq_len);
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
641911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_end = &p_ccb->rsp_list[p_ccb->list_len];
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
643911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p + seq_len) != p_end) {
644911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
645911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
646911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
648911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  while (p < p_end) {
649911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p = save_attr_seq(p_ccb, p, &p_ccb->rsp_list[p_ccb->list_len]);
650911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (!p) {
651911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      sdp_disconnect(p_ccb, SDP_DB_FULL);
652911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
654911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
656911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Since we got everything we need, disconnect the call */
657911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  sdp_disconnect(p_ccb, SDP_SUCCESS);
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
661ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
662ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         save_attr_seq
663ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
664ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called when there is a response from
665ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  the server.
666ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
667ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          pointer to next byte or NULL if error
668ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
669ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
670911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end) {
671911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint32_t seq_len, attr_len;
672911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t attr_id;
673911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t type, *p_seq_end;
674911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSDP_DISC_REC* p_rec;
675911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
676911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  type = *p++;
677911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
678911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((type >> 3) != DATA_ELE_SEQ_DESC_TYPE) {
679911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("SDP - Wrong type: 0x%02x in attr_rsp", type);
680911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return (NULL);
681911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
682911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
683911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = sdpu_get_len_from_type(p, type, &seq_len);
684911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p + seq_len) > p_msg_end) {
685911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("SDP - Bad len in attr_rsp %d", seq_len);
686911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return (NULL);
687911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
688911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
689911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Create a record */
690911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_rec = add_record(p_ccb->p_db, p_ccb->device_address);
691911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!p_rec) {
692911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SDP_TRACE_WARNING("SDP - DB full add_record");
693911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return (NULL);
694911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
695911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
696911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_seq_end = p + seq_len;
697911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
698911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  while (p < p_seq_end) {
699911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* First get the attribute ID */
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    type = *p++;
701911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p = sdpu_get_len_from_type(p, type, &attr_len);
702911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (((type >> 3) != UINT_DESC_TYPE) || (attr_len != 2)) {
703911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SDP_TRACE_WARNING("SDP - Bad type: 0x%02x or len: %d in attr_rsp", type,
704911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                        attr_len);
705911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return (NULL);
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
707911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BE_STREAM_TO_UINT16(attr_id, p);
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
709911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Now, add the attribute value */
710911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p = add_attr(p, p_ccb->p_db, p_rec, attr_id, NULL, 0);
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
712911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (!p) {
713911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SDP_TRACE_WARNING("SDP - DB full add_attr");
714911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return (NULL);
7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
716911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
718911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return (p);
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
722ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
723ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         add_record
724ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
725ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function allocates space for a record from the DB.
726ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
727ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          pointer to next byte in data stream
728ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
729ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
730911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsontSDP_DISC_REC* add_record(tSDP_DISCOVERY_DB* p_db, BD_ADDR p_bda) {
731911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSDP_DISC_REC* p_rec;
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
733911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* See if there is enough space in the database */
734911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_db->mem_free < sizeof(tSDP_DISC_REC)) return (NULL);
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
736911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_rec = (tSDP_DISC_REC*)p_db->p_free_mem;
737911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_db->p_free_mem += sizeof(tSDP_DISC_REC);
738911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_db->mem_free -= sizeof(tSDP_DISC_REC);
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
740911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_rec->p_first_attr = NULL;
741911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_rec->p_next_rec = NULL;
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
743911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memcpy(p_rec->remote_bd_addr, p_bda, BD_ADDR_LEN);
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
745911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Add the record to the end of chain */
746911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!p_db->p_first_rec)
747911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_db->p_first_rec = p_rec;
748911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else {
749911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    tSDP_DISC_REC* p_rec1 = p_db->p_first_rec;
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
751911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    while (p_rec1->p_next_rec) p_rec1 = p_rec1->p_next_rec;
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
753911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_rec1->p_next_rec = p_rec;
754911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
756911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return (p_rec);
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
759911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define SDP_ADDITIONAL_LIST_MASK 0x80
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
761ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
762ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         add_attr
763ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
764ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function allocates space for an attribute from the DB
765ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  and copies the data into it.
766ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
767ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          pointer to next byte in data stream
768ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
769ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
770911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic uint8_t* add_attr(uint8_t* p, tSDP_DISCOVERY_DB* p_db,
771911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                         tSDP_DISC_REC* p_rec, uint16_t attr_id,
772911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                         tSDP_DISC_ATTR* p_parent_attr, uint8_t nest_level) {
773911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSDP_DISC_ATTR* p_attr;
774911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint32_t attr_len;
775911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint32_t total_len;
776911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t attr_type;
777911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t id;
778911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t type;
779911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p_end;
780911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t is_additional_list = nest_level & SDP_ADDITIONAL_LIST_MASK;
781911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
782911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  nest_level &= ~(SDP_ADDITIONAL_LIST_MASK);
783911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
784911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  type = *p++;
785911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = sdpu_get_len_from_type(p, type, &attr_len);
786911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
787911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  attr_len &= SDP_DISC_ATTR_LEN_MASK;
788911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  attr_type = (type >> 3) & 0x0f;
789911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
790911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* See if there is enough space in the database */
791911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (attr_len > 4)
792911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    total_len = attr_len - 4 + (uint16_t)sizeof(tSDP_DISC_ATTR);
793911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else
794911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    total_len = sizeof(tSDP_DISC_ATTR);
795911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
796911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Ensure it is a multiple of 4 */
797911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  total_len = (total_len + 3) & ~3;
798911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
799911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* See if there is enough space in the database */
800911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_db->mem_free < total_len) return (NULL);
801911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
802911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_attr = (tSDP_DISC_ATTR*)p_db->p_free_mem;
803911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_attr->attr_id = attr_id;
804911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_attr->attr_len_type = (uint16_t)attr_len | (attr_type << 12);
805911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_attr->p_next_attr = NULL;
806911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
807911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Store the attribute value */
808911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (attr_type) {
809911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case UINT_DESC_TYPE:
810911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if ((is_additional_list != 0) && (attr_len == 2)) {
811911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        BE_STREAM_TO_UINT16(id, p);
812911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (id != ATTR_ID_PROTOCOL_DESC_LIST)
813911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p -= 2;
814911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        else {
815911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          /* Reserve the memory for the attribute now, as we need to add
816911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson           * sub-attributes */
817911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_db->p_free_mem += sizeof(tSDP_DISC_ATTR);
818911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_db->mem_free -= sizeof(tSDP_DISC_ATTR);
819911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_end = p + attr_len;
820911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          total_len = 0;
821911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
822911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          /* SDP_TRACE_DEBUG ("SDP - attr nest level:%d(list)", nest_level); */
823911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          if (nest_level >= MAX_NEST_LEVELS) {
824911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            SDP_TRACE_ERROR("SDP - attr nesting too deep");
825911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            return (p_end);
826911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          }
8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
828911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          /* Now, add the list entry */
829911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p = add_attr(p, p_db, p_rec, ATTR_ID_PROTOCOL_DESC_LIST, p_attr,
830911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                       (uint8_t)(nest_level + 1));
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
832911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
834911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
835911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* Case falls through */
8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case TWO_COMP_INT_DESC_TYPE:
838911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      switch (attr_len) {
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case 1:
840911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_attr->attr_value.v.u8 = *p++;
841911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case 2:
843911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          BE_STREAM_TO_UINT16(p_attr->attr_value.v.u16, p);
844911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case 4:
846911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          BE_STREAM_TO_UINT32(p_attr->attr_value.v.u32, p);
847911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
849911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          BE_STREAM_TO_ARRAY(p, p_attr->attr_value.v.array, (int32_t)attr_len);
850911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
851911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
852911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case UUID_DESC_TYPE:
855911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      switch (attr_len) {
8565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case 2:
857911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          BE_STREAM_TO_UINT16(p_attr->attr_value.v.u16, p);
858911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case 4:
860911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          BE_STREAM_TO_UINT32(p_attr->attr_value.v.u32, p);
861911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          if (p_attr->attr_value.v.u32 < 0x10000) {
862911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            attr_len = 2;
863911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            p_attr->attr_len_type = (uint16_t)attr_len | (attr_type << 12);
864911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            p_attr->attr_value.v.u16 = (uint16_t)p_attr->attr_value.v.u32;
865911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          }
866911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case 16:
868911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          /* See if we can compress his UUID down to 16 or 32bit UUIDs */
869911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          if (sdpu_is_base_uuid(p)) {
870911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            if ((p[0] == 0) && (p[1] == 0)) {
871911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              p_attr->attr_len_type =
872911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                  (p_attr->attr_len_type & ~SDP_DISC_ATTR_LEN_MASK) | 2;
873911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              p += 2;
874911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              BE_STREAM_TO_UINT16(p_attr->attr_value.v.u16, p);
875911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              p += MAX_UUID_SIZE - 4;
876911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            } else {
877911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              p_attr->attr_len_type =
878911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                  (p_attr->attr_len_type & ~SDP_DISC_ATTR_LEN_MASK) | 4;
879911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              BE_STREAM_TO_UINT32(p_attr->attr_value.v.u32, p);
880911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              p += MAX_UUID_SIZE - 4;
8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
882911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          } else {
883911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            BE_STREAM_TO_ARRAY(p, p_attr->attr_value.v.array,
884911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                               (int32_t)attr_len);
885911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          }
886911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
888911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          SDP_TRACE_WARNING("SDP - bad len in UUID attr: %d", attr_len);
889911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          return (p + attr_len);
890911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
891911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case DATA_ELE_SEQ_DESC_TYPE:
8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case DATA_ELE_ALT_DESC_TYPE:
895911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Reserve the memory for the attribute now, as we need to add
896911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       * sub-attributes */
897911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_db->p_free_mem += sizeof(tSDP_DISC_ATTR);
898911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_db->mem_free -= sizeof(tSDP_DISC_ATTR);
899911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_end = p + attr_len;
900911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      total_len = 0;
901911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
902911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* SDP_TRACE_DEBUG ("SDP - attr nest level:%d", nest_level); */
903911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (nest_level >= MAX_NEST_LEVELS) {
904911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        SDP_TRACE_ERROR("SDP - attr nesting too deep");
905911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        return (p_end);
906911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
907911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (is_additional_list != 0 ||
908911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          attr_id == ATTR_ID_ADDITION_PROTO_DESC_LISTS)
909911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        nest_level |= SDP_ADDITIONAL_LIST_MASK;
910911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* SDP_TRACE_DEBUG ("SDP - attr nest level:0x%x(finish)", nest_level); */
911911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
912911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      while (p < p_end) {
913911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /* Now, add the list entry */
914911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p = add_attr(p, p_db, p_rec, 0, p_attr, (uint8_t)(nest_level + 1));
915911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
916911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (!p) return (NULL);
917911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
918911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case TEXT_STR_DESC_TYPE:
9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case URL_DESC_TYPE:
922911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BE_STREAM_TO_ARRAY(p, p_attr->attr_value.v.array, (int32_t)attr_len);
923911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BOOLEAN_DESC_TYPE:
926911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      switch (attr_len) {
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case 1:
928911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_attr->attr_value.v.u8 = *p++;
929911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
931911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          SDP_TRACE_WARNING("SDP - bad len in boolean attr: %d", attr_len);
932911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          return (p + attr_len);
933911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
934911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
936911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    default: /* switch (attr_type) */
937911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
938911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
940911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_db->p_free_mem += total_len;
941911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_db->mem_free -= total_len;
9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
943911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Add the attribute to the end of the chain */
944911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!p_parent_attr) {
945911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (!p_rec->p_first_attr)
946911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_rec->p_first_attr = p_attr;
947911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    else {
948911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      tSDP_DISC_ATTR* p_attr1 = p_rec->p_first_attr;
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
950911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      while (p_attr1->p_next_attr) p_attr1 = p_attr1->p_next_attr;
9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
952911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_attr1->p_next_attr = p_attr;
9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
954911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
955911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (!p_parent_attr->attr_value.v.p_sub_attr) {
956911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_parent_attr->attr_value.v.p_sub_attr = p_attr;
957911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* SDP_TRACE_DEBUG ("parent:0x%x(id:%d), ch:0x%x(id:%d)",
958911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_parent_attr, p_parent_attr->attr_id, p_attr, p_attr->attr_id); */
959911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
960911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      tSDP_DISC_ATTR* p_attr1 = p_parent_attr->attr_value.v.p_sub_attr;
961911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* SDP_TRACE_DEBUG ("parent:0x%x(id:%d), ch1:0x%x(id:%d)",
962911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_parent_attr, p_parent_attr->attr_id, p_attr1, p_attr1->attr_id); */
963911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
964911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      while (p_attr1->p_next_attr) p_attr1 = p_attr1->p_next_attr;
965911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
966911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_attr1->p_next_attr = p_attr;
967911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* SDP_TRACE_DEBUG ("new ch:0x%x(id:%d)", p_attr, p_attr->attr_id); */
9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
969911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
971911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return (p);
9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
973