/******************************************************************************
 *
 *  Copyright (C) 1999-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  This file contains functions that handle the SDP server functions.
 *  This is mainly dealing with client requests
 *
 ******************************************************************************/

#include <cutils/log.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bt_common.h"
#include "bt_types.h"
#include "bt_utils.h"
#include "btu.h"

#include "hcidefs.h"
#include "hcimsgs.h"
#include "l2cdefs.h"

#include "osi/include/osi.h"
#include "sdp_api.h"
#include "sdpint.h"

#if (SDP_SERVER_ENABLED == TRUE)

/* Maximum number of bytes to reserve out of SDP MTU for response data */
#define SDP_MAX_SERVICE_RSPHDR_LEN 12
#define SDP_MAX_SERVATTR_RSPHDR_LEN 10
#define SDP_MAX_ATTR_RSPHDR_LEN 10

/******************************************************************************/
/*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
/******************************************************************************/
static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
                                   uint16_t param_len, uint8_t* p_req,
                                   uint8_t* p_req_end);

static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
                                     uint16_t param_len, uint8_t* p_req,
                                     uint8_t* p_req_end);

static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
                                            uint16_t param_len, uint8_t* p_req,
                                            uint8_t* p_req_end);

/******************************************************************************/
/*                E R R O R   T E X T   S T R I N G S                         */
/*                                                                            */
/* The default is to have no text string, but we allow the strings to be      */
/* configured in target.h if people want them.                                */
/******************************************************************************/
#ifndef SDP_TEXT_BAD_HEADER
#define SDP_TEXT_BAD_HEADER NULL
#endif

#ifndef SDP_TEXT_BAD_PDU
#define SDP_TEXT_BAD_PDU NULL
#endif

#ifndef SDP_TEXT_BAD_UUID_LIST
#define SDP_TEXT_BAD_UUID_LIST NULL
#endif

#ifndef SDP_TEXT_BAD_HANDLE
#define SDP_TEXT_BAD_HANDLE NULL
#endif

#ifndef SDP_TEXT_BAD_ATTR_LIST
#define SDP_TEXT_BAD_ATTR_LIST NULL
#endif

#ifndef SDP_TEXT_BAD_CONT_LEN
#define SDP_TEXT_BAD_CONT_LEN NULL
#endif

#ifndef SDP_TEXT_BAD_CONT_INX
#define SDP_TEXT_BAD_CONT_INX NULL
#endif

#ifndef SDP_TEXT_BAD_MAX_RECORDS_LIST
#define SDP_TEXT_BAD_MAX_RECORDS_LIST NULL
#endif

/*******************************************************************************
 *
 * Function         sdp_server_handle_client_req
 *
 * Description      This is the main dispatcher of the SDP server. It is called
 *                  when any data is received from L2CAP, and dispatches the
 *                  request to the appropriate handler.
 *
 * Returns          void
 *
 ******************************************************************************/
void sdp_server_handle_client_req(tCONN_CB* p_ccb, BT_HDR* p_msg) {
  uint8_t* p_req = (uint8_t*)(p_msg + 1) + p_msg->offset;
  uint8_t* p_req_end = p_req + p_msg->len;
  uint8_t pdu_id;
  uint16_t trans_num, param_len;

  /* Start inactivity timer */
  alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
                     sdp_conn_timer_timeout, p_ccb);

  if (p_req + sizeof(pdu_id) + sizeof(trans_num) > p_req_end) {
    android_errorWriteLog(0x534e4554, "69384124");
    trans_num = 0;
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                            SDP_TEXT_BAD_HEADER);
  }

  /* The first byte in the message is the pdu type */
  pdu_id = *p_req++;

  /* Extract the transaction number and parameter length */
  BE_STREAM_TO_UINT16(trans_num, p_req);

  if (p_req + sizeof(param_len) > p_req_end) {
    android_errorWriteLog(0x534e4554, "69384124");
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                            SDP_TEXT_BAD_HEADER);
  }

  BE_STREAM_TO_UINT16(param_len, p_req);

  if ((p_req + param_len) != p_req_end) {
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_PDU_SIZE,
                            SDP_TEXT_BAD_HEADER);
    return;
  }

  switch (pdu_id) {
    case SDP_PDU_SERVICE_SEARCH_REQ:
      process_service_search(p_ccb, trans_num, param_len, p_req, p_req_end);
      break;

    case SDP_PDU_SERVICE_ATTR_REQ:
      process_service_attr_req(p_ccb, trans_num, param_len, p_req, p_req_end);
      break;

    case SDP_PDU_SERVICE_SEARCH_ATTR_REQ:
      process_service_search_attr_req(p_ccb, trans_num, param_len, p_req,
                                      p_req_end);
      break;

    default:
      sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                              SDP_TEXT_BAD_PDU);
      SDP_TRACE_WARNING("SDP - server got unknown PDU: 0x%x", pdu_id);
      break;
  }
}

/*******************************************************************************
 *
 * Function         process_service_search
 *
 * Description      This function handles a service search request from the
 *                  client. It builds a reply message with info from the
 *                  database, and sends the reply back to the client.
 *
 * Returns          void
 *
 ******************************************************************************/
static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
                                   uint16_t param_len, uint8_t* p_req,
                                   uint8_t* p_req_end) {
  uint16_t max_replies, cur_handles, rem_handles, cont_offset;
  tSDP_UUID_SEQ uid_seq;
  uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
  uint16_t rsp_param_len, num_rsp_handles, xx;
  uint32_t rsp_handles[SDP_MAX_RECORDS] = {0};
  tSDP_RECORD* p_rec = NULL;
  bool is_cont = false;

  p_req = sdpu_extract_uid_seq(p_req, param_len, &uid_seq);

  if ((!p_req) || (!uid_seq.num_uids)) {
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                            SDP_TEXT_BAD_UUID_LIST);
    return;
  }

  /* Get the max replies we can send. Cap it at our max anyways. */
  if (p_req + sizeof(max_replies) + sizeof(uint8_t) > p_req_end) {
    android_errorWriteLog(0x534e4554, "69384124");
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                            SDP_TEXT_BAD_MAX_RECORDS_LIST);
    return;
  }
  BE_STREAM_TO_UINT16(max_replies, p_req);

  if (max_replies > SDP_MAX_RECORDS) max_replies = SDP_MAX_RECORDS;

  /* Get a list of handles that match the UUIDs given to us */
  for (num_rsp_handles = 0; num_rsp_handles < max_replies;) {
    p_rec = sdp_db_service_search(p_rec, &uid_seq);

    if (p_rec)
      rsp_handles[num_rsp_handles++] = p_rec->record_handle;
    else
      break;
  }

  /* Check if this is a continuation request */
  if (*p_req) {
    if (*p_req++ != SDP_CONTINUATION_LEN ||
        (p_req + sizeof(cont_offset) > p_req_end)) {
      sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
                              SDP_TEXT_BAD_CONT_LEN);
      return;
    }
    BE_STREAM_TO_UINT16(cont_offset, p_req);

    if (cont_offset != p_ccb->cont_offset || num_rsp_handles < cont_offset) {
      sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
                              SDP_TEXT_BAD_CONT_INX);
      return;
    }

    rem_handles =
        num_rsp_handles - cont_offset; /* extract the remaining handles */
  } else {
    rem_handles = num_rsp_handles;
    cont_offset = 0;
    p_ccb->cont_offset = 0;
  }

  /* Calculate how many handles will fit in one PDU */
  cur_handles =
      (uint16_t)((p_ccb->rem_mtu_size - SDP_MAX_SERVICE_RSPHDR_LEN) / 4);

  if (rem_handles <= cur_handles)
    cur_handles = rem_handles;
  else /* Continuation is set */
  {
    p_ccb->cont_offset += cur_handles;
    is_cont = true;
  }

  /* Get a buffer to use to build the response */
  BT_HDR* p_buf = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
  p_buf->offset = L2CAP_MIN_OFFSET;
  p_rsp = p_rsp_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;

  /* Start building a rsponse */
  UINT8_TO_BE_STREAM(p_rsp, SDP_PDU_SERVICE_SEARCH_RSP);
  UINT16_TO_BE_STREAM(p_rsp, trans_num);

  /* Skip the length, we need to add it at the end */
  p_rsp_param_len = p_rsp;
  p_rsp += 2;

  /* Put in total and current number of handles, and handles themselves */
  UINT16_TO_BE_STREAM(p_rsp, num_rsp_handles);
  UINT16_TO_BE_STREAM(p_rsp, cur_handles);

  /*  SDP_TRACE_DEBUG("SDP Service Rsp: tothdl %d, curhdlr %d, start %d, end %d,
     cont %d",
                       num_rsp_handles, cur_handles, cont_offset,
                       cont_offset + cur_handles-1, is_cont); */
  for (xx = cont_offset; xx < cont_offset + cur_handles; xx++)
    UINT32_TO_BE_STREAM(p_rsp, rsp_handles[xx]);

  if (is_cont) {
    UINT8_TO_BE_STREAM(p_rsp, SDP_CONTINUATION_LEN);
    UINT16_TO_BE_STREAM(p_rsp, p_ccb->cont_offset);
  } else
    UINT8_TO_BE_STREAM(p_rsp, 0);

  /* Go back and put the parameter length into the buffer */
  rsp_param_len = p_rsp - p_rsp_param_len - 2;
  UINT16_TO_BE_STREAM(p_rsp_param_len, rsp_param_len);

  /* Set the length of the SDP data in the buffer */
  p_buf->len = p_rsp - p_rsp_start;

  /* Send the buffer through L2CAP */
  L2CA_DataWrite(p_ccb->connection_id, p_buf);
}

/*******************************************************************************
 *
 * Function         process_service_attr_req
 *
 * Description      This function handles an attribute request from the client.
 *                  It builds a reply message with info from the database,
 *                  and sends the reply back to the client.
 *
 * Returns          void
 *
 ******************************************************************************/
static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
                                     uint16_t param_len, uint8_t* p_req,
                                     uint8_t* p_req_end) {
  uint16_t max_list_len, len_to_send, cont_offset;
  int16_t rem_len;
  tSDP_ATTR_SEQ attr_seq, attr_seq_sav;
  uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
  uint16_t rsp_param_len, xx;
  uint32_t rec_handle;
  tSDP_RECORD* p_rec;
  tSDP_ATTRIBUTE* p_attr;
  bool is_cont = false;
  uint16_t attr_len;

  if (p_req + sizeof(rec_handle) + sizeof(max_list_len) > p_req_end) {
    android_errorWriteLog(0x534e4554, "69384124");
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_SERV_REC_HDL,
                            SDP_TEXT_BAD_HANDLE);
    return;
  }

  /* Extract the record handle */
  BE_STREAM_TO_UINT32(rec_handle, p_req);
  param_len -= sizeof(rec_handle);

  /* Get the max list length we can send. Cap it at MTU size minus overhead */
  BE_STREAM_TO_UINT16(max_list_len, p_req);
  param_len -= sizeof(max_list_len);

  if (max_list_len > (p_ccb->rem_mtu_size - SDP_MAX_ATTR_RSPHDR_LEN))
    max_list_len = p_ccb->rem_mtu_size - SDP_MAX_ATTR_RSPHDR_LEN;

  p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);

  if ((!p_req) || (!attr_seq.num_attr) ||
      (p_req + sizeof(uint8_t) > p_req_end)) {
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                            SDP_TEXT_BAD_ATTR_LIST);
    return;
  }

  memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ));

  /* Find a record with the record handle */
  p_rec = sdp_db_find_record(rec_handle);
  if (!p_rec) {
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_SERV_REC_HDL,
                            SDP_TEXT_BAD_HANDLE);
    return;
  }

  if (max_list_len < 4) {
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_ILLEGAL_PARAMETER, NULL);
    android_errorWriteLog(0x534e4554, "68776054");
    return;
  }

  /* Free and reallocate buffer */
  osi_free(p_ccb->rsp_list);
  p_ccb->rsp_list = (uint8_t*)osi_malloc(max_list_len);

  /* Check if this is a continuation request */
  if (*p_req) {
    if (*p_req++ != SDP_CONTINUATION_LEN ||
        (p_req + sizeof(cont_offset) > p_req_end)) {
      sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
                              SDP_TEXT_BAD_CONT_LEN);
      return;
    }
    BE_STREAM_TO_UINT16(cont_offset, p_req);

    if (cont_offset != p_ccb->cont_offset) {
      sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
                              SDP_TEXT_BAD_CONT_INX);
      return;
    }
    is_cont = true;

    /* Initialise for continuation response */
    p_rsp = &p_ccb->rsp_list[0];
    attr_seq.attr_entry[p_ccb->cont_info.next_attr_index].start =
        p_ccb->cont_info.next_attr_start_id;
  } else {
    p_ccb->cont_offset = 0;
    p_rsp = &p_ccb->rsp_list[3]; /* Leave space for data elem descr */

    /* Reset continuation parameters in p_ccb */
    p_ccb->cont_info.prev_sdp_rec = NULL;
    p_ccb->cont_info.next_attr_index = 0;
    p_ccb->cont_info.attr_offset = 0;
  }

  /* Search for attributes that match the list given to us */
  for (xx = p_ccb->cont_info.next_attr_index; xx < attr_seq.num_attr; xx++) {
    p_attr = sdp_db_find_attr_in_rec(p_rec, attr_seq.attr_entry[xx].start,
                                     attr_seq.attr_entry[xx].end);

    if (p_attr) {
      /* Check if attribute fits. Assume 3-byte value type/length */
      rem_len = max_list_len - (int16_t)(p_rsp - &p_ccb->rsp_list[0]);

      /* just in case */
      if (rem_len <= 0) {
        p_ccb->cont_info.next_attr_index = xx;
        p_ccb->cont_info.next_attr_start_id = p_attr->id;
        break;
      }

      attr_len = sdpu_get_attrib_entry_len(p_attr);
      /* if there is a partial attribute pending to be sent */
      if (p_ccb->cont_info.attr_offset) {
        p_rsp = sdpu_build_partial_attrib_entry(p_rsp, p_attr, rem_len,
                                                &p_ccb->cont_info.attr_offset);

        /* If the partial attrib could not been fully added yet */
        if (p_ccb->cont_info.attr_offset != attr_len)
          break;
        else /* If the partial attrib has been added in full by now */
          p_ccb->cont_info.attr_offset = 0; /* reset attr_offset */
      } else if (rem_len <
                 attr_len) /* Not enough space for attr... so add partially */
      {
        if (attr_len >= SDP_MAX_ATTR_LEN) {
          SDP_TRACE_ERROR("SDP attr too big: max_list_len=%d,attr_len=%d",
                          max_list_len, attr_len);
          sdpu_build_n_send_error(p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
          return;
        }

        /* add the partial attribute if possible */
        p_rsp = sdpu_build_partial_attrib_entry(
            p_rsp, p_attr, (uint16_t)rem_len, &p_ccb->cont_info.attr_offset);

        p_ccb->cont_info.next_attr_index = xx;
        p_ccb->cont_info.next_attr_start_id = p_attr->id;
        break;
      } else /* build the whole attribute */
        p_rsp = sdpu_build_attrib_entry(p_rsp, p_attr);

      /* If doing a range, stick with this one till no more attributes found */
      if (attr_seq.attr_entry[xx].start != attr_seq.attr_entry[xx].end) {
        /* Update for next time through */
        attr_seq.attr_entry[xx].start = p_attr->id + 1;

        xx--;
      }
    }
  }
  /* If all the attributes have been accomodated in p_rsp,
     reset next_attr_index */
  if (xx == attr_seq.num_attr) p_ccb->cont_info.next_attr_index = 0;

  len_to_send = (uint16_t)(p_rsp - &p_ccb->rsp_list[0]);
  cont_offset = 0;

  if (!is_cont) {
    p_ccb->list_len = sdpu_get_attrib_seq_len(p_rec, &attr_seq_sav) + 3;
    /* Put in the sequence header (2 or 3 bytes) */
    if (p_ccb->list_len > 255) {
      p_ccb->rsp_list[0] =
          (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
      p_ccb->rsp_list[1] = (uint8_t)((p_ccb->list_len - 3) >> 8);
      p_ccb->rsp_list[2] = (uint8_t)(p_ccb->list_len - 3);
    } else {
      cont_offset = 1;

      p_ccb->rsp_list[1] =
          (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
      p_ccb->rsp_list[2] = (uint8_t)(p_ccb->list_len - 3);

      p_ccb->list_len--;
      len_to_send--;
    }
  }

  /* Get a buffer to use to build the response */
  BT_HDR* p_buf = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
  p_buf->offset = L2CAP_MIN_OFFSET;
  p_rsp = p_rsp_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;

  /* Start building a rsponse */
  UINT8_TO_BE_STREAM(p_rsp, SDP_PDU_SERVICE_ATTR_RSP);
  UINT16_TO_BE_STREAM(p_rsp, trans_num);

  /* Skip the parameter length, add it when we know the length */
  p_rsp_param_len = p_rsp;
  p_rsp += 2;

  UINT16_TO_BE_STREAM(p_rsp, len_to_send);

  memcpy(p_rsp, &p_ccb->rsp_list[cont_offset], len_to_send);
  p_rsp += len_to_send;

  p_ccb->cont_offset += len_to_send;

  /* If anything left to send, continuation needed */
  if (p_ccb->cont_offset < p_ccb->list_len) {
    is_cont = true;

    UINT8_TO_BE_STREAM(p_rsp, SDP_CONTINUATION_LEN);
    UINT16_TO_BE_STREAM(p_rsp, p_ccb->cont_offset);
  } else
    UINT8_TO_BE_STREAM(p_rsp, 0);

  /* Go back and put the parameter length into the buffer */
  rsp_param_len = p_rsp - p_rsp_param_len - 2;
  UINT16_TO_BE_STREAM(p_rsp_param_len, rsp_param_len);

  /* Set the length of the SDP data in the buffer */
  p_buf->len = p_rsp - p_rsp_start;

  /* Send the buffer through L2CAP */
  L2CA_DataWrite(p_ccb->connection_id, p_buf);
}

/*******************************************************************************
 *
 * Function         process_service_search_attr_req
 *
 * Description      This function handles a combined service search and
 *                  attribute read request from the client. It builds a reply
 *                  message with info from the database, and sends the reply
 *                  back to the client.
 *
 * Returns          void
 *
 ******************************************************************************/
static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
                                            uint16_t param_len, uint8_t* p_req,
                                            uint8_t* p_req_end) {
  uint16_t max_list_len;
  int16_t rem_len;
  uint16_t len_to_send, cont_offset;
  tSDP_UUID_SEQ uid_seq;
  uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
  uint16_t rsp_param_len, xx;
  tSDP_RECORD* p_rec;
  tSDP_ATTR_SEQ attr_seq, attr_seq_sav;
  tSDP_ATTRIBUTE* p_attr;
  bool maxxed_out = false, is_cont = false;
  uint8_t* p_seq_start;
  uint16_t seq_len, attr_len;

  /* Extract the UUID sequence to search for */
  p_req = sdpu_extract_uid_seq(p_req, param_len, &uid_seq);

  if ((!p_req) || (!uid_seq.num_uids) ||
      (p_req + sizeof(uint16_t) > p_req_end)) {
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                            SDP_TEXT_BAD_UUID_LIST);
    return;
  }

  /* Get the max list length we can send. Cap it at our max list length. */
  BE_STREAM_TO_UINT16(max_list_len, p_req);

  if (max_list_len > (p_ccb->rem_mtu_size - SDP_MAX_SERVATTR_RSPHDR_LEN))
    max_list_len = p_ccb->rem_mtu_size - SDP_MAX_SERVATTR_RSPHDR_LEN;

  p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);

  if ((!p_req) || (!attr_seq.num_attr) ||
      (p_req + sizeof(uint8_t) > p_req_end)) {
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                            SDP_TEXT_BAD_ATTR_LIST);
    return;
  }

  memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ));

  if (max_list_len < 4) {
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_ILLEGAL_PARAMETER, NULL);
    android_errorWriteLog(0x534e4554, "68817966");
    return;
  }

  /* Free and reallocate buffer */
  osi_free(p_ccb->rsp_list);
  p_ccb->rsp_list = (uint8_t*)osi_malloc(max_list_len);

  /* Check if this is a continuation request */
  if (*p_req) {
    if (*p_req++ != SDP_CONTINUATION_LEN ||
        (p_req + sizeof(uint16_t) > p_req_end)) {
      sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
                              SDP_TEXT_BAD_CONT_LEN);
      return;
    }
    BE_STREAM_TO_UINT16(cont_offset, p_req);

    if (cont_offset != p_ccb->cont_offset) {
      sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
                              SDP_TEXT_BAD_CONT_INX);
      return;
    }
    is_cont = true;

    /* Initialise for continuation response */
    p_rsp = &p_ccb->rsp_list[0];
    attr_seq.attr_entry[p_ccb->cont_info.next_attr_index].start =
        p_ccb->cont_info.next_attr_start_id;
  } else {
    p_ccb->cont_offset = 0;
    p_rsp = &p_ccb->rsp_list[3]; /* Leave space for data elem descr */

    /* Reset continuation parameters in p_ccb */
    p_ccb->cont_info.prev_sdp_rec = NULL;
    p_ccb->cont_info.next_attr_index = 0;
    p_ccb->cont_info.last_attr_seq_desc_sent = false;
    p_ccb->cont_info.attr_offset = 0;
  }

  /* Get a list of handles that match the UUIDs given to us */
  for (p_rec = sdp_db_service_search(p_ccb->cont_info.prev_sdp_rec, &uid_seq);
       p_rec; p_rec = sdp_db_service_search(p_rec, &uid_seq)) {
    /* Allow space for attribute sequence type and length */
    p_seq_start = p_rsp;
    if (p_ccb->cont_info.last_attr_seq_desc_sent == false) {
      /* See if there is enough room to include a new service in the current
       * response */
      rem_len = max_list_len - (int16_t)(p_rsp - &p_ccb->rsp_list[0]);
      if (rem_len < 3) {
        /* Not enough room. Update continuation info for next response */
        p_ccb->cont_info.next_attr_index = 0;
        p_ccb->cont_info.next_attr_start_id = attr_seq.attr_entry[0].start;
        break;
      }
      p_rsp += 3;
    }

    /* Get a list of handles that match the UUIDs given to us */
    for (xx = p_ccb->cont_info.next_attr_index; xx < attr_seq.num_attr; xx++) {
      p_attr = sdp_db_find_attr_in_rec(p_rec, attr_seq.attr_entry[xx].start,
                                       attr_seq.attr_entry[xx].end);

      if (p_attr) {
        /* Check if attribute fits. Assume 3-byte value type/length */
        rem_len = max_list_len - (int16_t)(p_rsp - &p_ccb->rsp_list[0]);

        /* just in case */
        if (rem_len <= 0) {
          p_ccb->cont_info.next_attr_index = xx;
          p_ccb->cont_info.next_attr_start_id = p_attr->id;
          maxxed_out = true;
          break;
        }

        attr_len = sdpu_get_attrib_entry_len(p_attr);
        /* if there is a partial attribute pending to be sent */
        if (p_ccb->cont_info.attr_offset) {
          p_rsp = sdpu_build_partial_attrib_entry(
              p_rsp, p_attr, rem_len, &p_ccb->cont_info.attr_offset);

          /* If the partial attrib could not been fully added yet */
          if (p_ccb->cont_info.attr_offset != attr_len) {
            maxxed_out = true;
            break;
          } else /* If the partial attrib has been added in full by now */
            p_ccb->cont_info.attr_offset = 0; /* reset attr_offset */
        } else if (rem_len <
                   attr_len) /* Not enough space for attr... so add partially */
        {
          if (attr_len >= SDP_MAX_ATTR_LEN) {
            SDP_TRACE_ERROR("SDP attr too big: max_list_len=%d,attr_len=%d",
                            max_list_len, attr_len);
            sdpu_build_n_send_error(p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
            return;
          }

          /* add the partial attribute if possible */
          p_rsp = sdpu_build_partial_attrib_entry(
              p_rsp, p_attr, (uint16_t)rem_len, &p_ccb->cont_info.attr_offset);

          p_ccb->cont_info.next_attr_index = xx;
          p_ccb->cont_info.next_attr_start_id = p_attr->id;
          maxxed_out = true;
          break;
        } else /* build the whole attribute */
          p_rsp = sdpu_build_attrib_entry(p_rsp, p_attr);

        /* If doing a range, stick with this one till no more attributes found
         */
        if (attr_seq.attr_entry[xx].start != attr_seq.attr_entry[xx].end) {
          /* Update for next time through */
          attr_seq.attr_entry[xx].start = p_attr->id + 1;

          xx--;
        }
      }
    }

    /* Go back and put the type and length into the buffer */
    if (p_ccb->cont_info.last_attr_seq_desc_sent == false) {
      seq_len = sdpu_get_attrib_seq_len(p_rec, &attr_seq_sav);
      if (seq_len != 0) {
        UINT8_TO_BE_STREAM(p_seq_start,
                           (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
        UINT16_TO_BE_STREAM(p_seq_start, seq_len);

        if (maxxed_out) p_ccb->cont_info.last_attr_seq_desc_sent = true;
      } else
        p_rsp = p_seq_start;
    }

    if (maxxed_out) break;

    /* Restore the attr_seq to look for in the next sdp record */
    memcpy(&attr_seq, &attr_seq_sav, sizeof(tSDP_ATTR_SEQ));

    /* Reset the next attr index */
    p_ccb->cont_info.next_attr_index = 0;
    p_ccb->cont_info.prev_sdp_rec = p_rec;
    p_ccb->cont_info.last_attr_seq_desc_sent = false;
  }

  /* response length */
  len_to_send = (uint16_t)(p_rsp - &p_ccb->rsp_list[0]);
  cont_offset = 0;

  // The current SDP server design has a critical flaw where it can run into
  // an infinite request/response loop with the client. Here's the scenario:
  // - client makes SDP request
  // - server returns the first fragment of the response with a continuation
  //   token
  // - an SDP record is deleted from the server
  // - client issues another request with previous continuation token
  // - server has nothing to send back because the record is unavailable but
  //   in the first fragment, it had specified more response bytes than are
  //   now available
  // - server sends back no additional response bytes and returns the same
  //   continuation token
  // - client issues another request with the continuation token, and the
  //   process repeats
  //
  // We work around this design flaw here by checking if we will make forward
  // progress (i.e. we will send > 0 response bytes) on a continued request.
  // If not, we must have run into the above situation and we tell the peer an
  // error occurred.
  //
  // TODO(sharvil): rewrite SDP server.
  if (is_cont && len_to_send == 0) {
    sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE, NULL);
    return;
  }

  /* If first response, insert sequence header */
  if (!is_cont) {
    /* Get the total list length for requested uid and attribute sequence */
    p_ccb->list_len = sdpu_get_list_len(&uid_seq, &attr_seq_sav) + 3;
    /* Put in the sequence header (2 or 3 bytes) */
    if (p_ccb->list_len > 255) {
      p_ccb->rsp_list[0] =
          (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
      p_ccb->rsp_list[1] = (uint8_t)((p_ccb->list_len - 3) >> 8);
      p_ccb->rsp_list[2] = (uint8_t)(p_ccb->list_len - 3);
    } else {
      cont_offset = 1;

      p_ccb->rsp_list[1] =
          (uint8_t)((DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
      p_ccb->rsp_list[2] = (uint8_t)(p_ccb->list_len - 3);

      p_ccb->list_len--;
      len_to_send--;
    }
  }

  /* Get a buffer to use to build the response */
  BT_HDR* p_buf = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
  p_buf->offset = L2CAP_MIN_OFFSET;
  p_rsp = p_rsp_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;

  /* Start building a rsponse */
  UINT8_TO_BE_STREAM(p_rsp, SDP_PDU_SERVICE_SEARCH_ATTR_RSP);
  UINT16_TO_BE_STREAM(p_rsp, trans_num);

  /* Skip the parameter length, add it when we know the length */
  p_rsp_param_len = p_rsp;
  p_rsp += 2;

  /* Stream the list length to send */
  UINT16_TO_BE_STREAM(p_rsp, len_to_send);

  /* copy from rsp_list to the actual buffer to be sent */
  memcpy(p_rsp, &p_ccb->rsp_list[cont_offset], len_to_send);
  p_rsp += len_to_send;

  p_ccb->cont_offset += len_to_send;

  /* If anything left to send, continuation needed */
  if (p_ccb->cont_offset < p_ccb->list_len) {
    is_cont = true;

    UINT8_TO_BE_STREAM(p_rsp, SDP_CONTINUATION_LEN);
    UINT16_TO_BE_STREAM(p_rsp, p_ccb->cont_offset);
  } else
    UINT8_TO_BE_STREAM(p_rsp, 0);

  /* Go back and put the parameter length into the buffer */
  rsp_param_len = p_rsp - p_rsp_param_len - 2;
  UINT16_TO_BE_STREAM(p_rsp_param_len, rsp_param_len);

  /* Set the length of the SDP data in the buffer */
  p_buf->len = p_rsp - p_rsp_start;

  /* Send the buffer through L2CAP */
  L2CA_DataWrite(p_ccb->connection_id, p_buf);
}

#endif /* SDP_SERVER_ENABLED == TRUE */
