/******************************************************************************
 *
 *  Copyright (c) 2014 The Android Open Source Project
 *  Copyright (C) 2003-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 the audio gateway functions performing SDP
 *  operations.
 *
 ******************************************************************************/

#include <string.h>

#include "bt_utils.h"
#include "bta_api.h"
#include "bta_hf_client_api.h"
#include "bta_hf_client_int.h"
#include "bta_sys.h"
#include "osi/include/osi.h"

/* Number of protocol elements in protocol element list. */
#define BTA_HF_CLIENT_NUM_PROTO_ELEMS 2

/* Number of elements in service class id list. */
#define BTA_HF_CLIENT_NUM_SVC_ELEMS 2

/*******************************************************************************
 *
 * Function         bta_hf_client_sdp_cback
 *
 * Description      SDP callback function.
 *
 *
 * Returns          void
 *
 ******************************************************************************/
static void bta_hf_client_sdp_cback(uint16_t status, void* data) {
  uint16_t event;
  tBTA_HF_CLIENT_DISC_RESULT* p_buf = (tBTA_HF_CLIENT_DISC_RESULT*)osi_malloc(
      sizeof(tBTA_HF_CLIENT_DISC_RESULT));

  APPL_TRACE_DEBUG("bta_hf_client_sdp_cback status:0x%x", status);
  tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;

  /* set event according to int/acp */
  if (client_cb->role == BTA_HF_CLIENT_ACP)
    event = BTA_HF_CLIENT_DISC_ACP_RES_EVT;
  else
    event = BTA_HF_CLIENT_DISC_INT_RES_EVT;

  p_buf->hdr.event = event;
  p_buf->hdr.layer_specific = client_cb->handle;
  p_buf->status = status;

  bta_sys_sendmsg(p_buf);
}

/******************************************************************************
 *
 * Function         bta_hf_client_add_record
 *
 * Description      This function is called by a server application to add
 *                  HFP Client information to an SDP record.  Prior to
 *                  calling this function the application must call
 *                  SDP_CreateRecord() to create an SDP record.
 *
 * Returns          true if function execution succeeded,
 *                  false if function execution failed.
 *
 *****************************************************************************/
bool bta_hf_client_add_record(const char* p_service_name, uint8_t scn,
                              tBTA_HF_CLIENT_FEAT features,
                              uint32_t sdp_handle) {
  tSDP_PROTOCOL_ELEM proto_elem_list[BTA_HF_CLIENT_NUM_PROTO_ELEMS];
  uint16_t svc_class_id_list[BTA_HF_CLIENT_NUM_SVC_ELEMS];
  uint16_t browse_list[] = {UUID_SERVCLASS_PUBLIC_BROWSE_GROUP};
  uint16_t version;
  uint16_t profile_uuid;
  bool result = true;
  uint8_t buf[2];
  uint16_t sdp_features = 0;

  APPL_TRACE_DEBUG("bta_hf_client_add_record");

  memset(proto_elem_list, 0,
         BTA_HF_CLIENT_NUM_PROTO_ELEMS * sizeof(tSDP_PROTOCOL_ELEM));

  /* add the protocol element sequence */
  proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
  proto_elem_list[0].num_params = 0;
  proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
  proto_elem_list[1].num_params = 1;
  proto_elem_list[1].params[0] = scn;
  result &= SDP_AddProtocolList(sdp_handle, BTA_HF_CLIENT_NUM_PROTO_ELEMS,
                                proto_elem_list);

  /* add service class id list */
  svc_class_id_list[0] = UUID_SERVCLASS_HF_HANDSFREE;
  svc_class_id_list[1] = UUID_SERVCLASS_GENERIC_AUDIO;
  result &= SDP_AddServiceClassIdList(sdp_handle, BTA_HF_CLIENT_NUM_SVC_ELEMS,
                                      svc_class_id_list);

  /* add profile descriptor list */
  profile_uuid = UUID_SERVCLASS_HF_HANDSFREE;
  version = HFP_VERSION_1_6;

  result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version);

  /* add service name */
  if (p_service_name != NULL && p_service_name[0] != 0) {
    result &= SDP_AddAttribute(
        sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
        (uint32_t)(strlen(p_service_name) + 1), (uint8_t*)p_service_name);
  }

  /* add features */
  if (features & BTA_HF_CLIENT_FEAT_ECNR)
    sdp_features |= BTA_HF_CLIENT_FEAT_ECNR;

  if (features & BTA_HF_CLIENT_FEAT_3WAY)
    sdp_features |= BTA_HF_CLIENT_FEAT_3WAY;

  if (features & BTA_HF_CLIENT_FEAT_CLI) sdp_features |= BTA_HF_CLIENT_FEAT_CLI;

  if (features & BTA_HF_CLIENT_FEAT_VREC)
    sdp_features |= BTA_HF_CLIENT_FEAT_VREC;

  if (features & BTA_HF_CLIENT_FEAT_VOL) sdp_features |= BTA_HF_CLIENT_FEAT_VOL;

  /* Codec bit position is different in SDP (bit 5) and in BRSF (bit 7) */
  if (features & BTA_HF_CLIENT_FEAT_CODEC) sdp_features |= 0x0020;

  UINT16_TO_BE_FIELD(buf, sdp_features);
  result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES,
                             UINT_DESC_TYPE, 2, buf);

  /* add browse group list */
  result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1,
                                browse_list);

  return result;
}

/*******************************************************************************
 *
 * Function         bta_hf_client_create_record
 *
 * Description      Create SDP record for registered service.
 *
 *
 * Returns          void
 *
 ******************************************************************************/
void bta_hf_client_create_record(tBTA_HF_CLIENT_CB_ARR* client_cb_arr,
                                 const char* p_service_name) {
  /* add sdp record if not already registered */
  if (client_cb_arr->sdp_handle == 0) {
    client_cb_arr->sdp_handle = SDP_CreateRecord();
    client_cb_arr->scn = BTM_AllocateSCN();
    bta_hf_client_add_record(p_service_name, client_cb_arr->scn,
                             client_cb_arr->features,
                             client_cb_arr->sdp_handle);

    bta_sys_add_uuid(UUID_SERVCLASS_HF_HANDSFREE);
  }
}

/*******************************************************************************
 *
 * Function         bta_hf_client_del_record
 *
 * Description      Delete SDP record for registered service.
 *
 *
 * Returns          void
 *
 ******************************************************************************/
void bta_hf_client_del_record(tBTA_HF_CLIENT_CB_ARR* client_cb) {
  APPL_TRACE_DEBUG("%s", __func__);

  if (client_cb->sdp_handle != 0) {
    SDP_DeleteRecord(client_cb->sdp_handle);
    client_cb->sdp_handle = 0;
    BTM_FreeSCN(client_cb->scn);
    BTM_SecClrService(BTM_SEC_SERVICE_HF_HANDSFREE);
    bta_sys_remove_uuid(UUID_SERVCLASS_HF_HANDSFREE);
  }
}

/*******************************************************************************
 *
 * Function         bta_hf_client_sdp_find_attr
 *
 * Description      Process SDP discovery results to find requested attribute
 *
 *
 * Returns          true if results found, false otherwise.
 *
 ******************************************************************************/
bool bta_hf_client_sdp_find_attr(tBTA_HF_CLIENT_CB* client_cb) {
  tSDP_DISC_REC* p_rec = NULL;
  tSDP_DISC_ATTR* p_attr;
  tSDP_PROTOCOL_ELEM pe;
  bool result = false;

  client_cb->peer_version = HFP_VERSION_1_1; /* Default version */

  /* loop through all records we found */
  while (true) {
    /* get next record; if none found, we're done */
    p_rec = SDP_FindServiceInDb(client_cb->p_disc_db,
                                UUID_SERVCLASS_AG_HANDSFREE, p_rec);
    if (p_rec == NULL) {
      break;
    }

    /* get scn from proto desc list if initiator */
    if (client_cb->role == BTA_HF_CLIENT_INT) {
      if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
        client_cb->peer_scn = (uint8_t)pe.params[0];
      } else {
        continue;
      }
    }

    /* get profile version (if failure, version parameter is not updated) */
    SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_HF_HANDSFREE,
                                &client_cb->peer_version);

    /* get features */
    p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
    if (p_attr != NULL) {
      /* Found attribute. Get value. */
      /* There might be race condition between SDP and BRSF.  */
      /* Do not update if we already received BRSF.           */
      if (client_cb->peer_features == 0) {
        client_cb->peer_features = p_attr->attr_value.v.u16;

        /* SDP and BRSF WBS bit are different, correct it if set */
        if (client_cb->peer_features & 0x0020) {
          client_cb->peer_features &= ~0x0020;
          client_cb->peer_features |= BTA_HF_CLIENT_PEER_CODEC;
        }

        /* get network for ability to reject calls */
        p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_NETWORK);
        if (p_attr != NULL) {
          if (p_attr->attr_value.v.u16 == 0x01) {
            client_cb->peer_features |= BTA_HF_CLIENT_PEER_REJECT;
          }
        }
      }
    }

    /* found what we needed */
    result = true;
    break;
  }

  APPL_TRACE_DEBUG("%s: peer_version=0x%x peer_features=0x%x", __func__,
                   client_cb->peer_version, client_cb->peer_features);

  return result;
}

/*******************************************************************************
 *
 * Function         bta_hf_client_do_disc
 *
 * Description      Do service discovery.
 *
 *
 * Returns          void
 *
 ******************************************************************************/
void bta_hf_client_do_disc(tBTA_HF_CLIENT_CB* client_cb) {
  tSDP_UUID uuid_list[2];
  uint16_t num_uuid = 1;
  uint16_t attr_list[4];
  uint8_t num_attr;
  bool db_inited = false;

  /* initiator; get proto list and features */
  if (client_cb->role == BTA_HF_CLIENT_INT) {
    attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
    attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
    attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST;
    attr_list[3] = ATTR_ID_SUPPORTED_FEATURES;
    num_attr = 4;
    uuid_list[0].uu.uuid16 = UUID_SERVCLASS_AG_HANDSFREE;
  }
  /* acceptor; get features */
  else {
    attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
    attr_list[1] = ATTR_ID_BT_PROFILE_DESC_LIST;
    attr_list[2] = ATTR_ID_SUPPORTED_FEATURES;
    num_attr = 3;
    uuid_list[0].uu.uuid16 = UUID_SERVCLASS_AG_HANDSFREE;
  }

  /* allocate buffer for sdp database */
  client_cb->p_disc_db = (tSDP_DISCOVERY_DB*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);

  /* set up service discovery database; attr happens to be attr_list len */
  uuid_list[0].len = LEN_UUID_16;
  uuid_list[1].len = LEN_UUID_16;
  db_inited = SDP_InitDiscoveryDb(client_cb->p_disc_db, BT_DEFAULT_BUFFER_SIZE,
                                  num_uuid, uuid_list, num_attr, attr_list);

  if (db_inited) {
    /*Service discovery not initiated */
    db_inited = SDP_ServiceSearchAttributeRequest2(
        client_cb->peer_addr, client_cb->p_disc_db, bta_hf_client_sdp_cback,
        (void*)client_cb);
  }

  if (!db_inited) {
    /*free discover db */
    bta_hf_client_free_db(NULL);
    /* sent failed event */
    tBTA_HF_CLIENT_DATA msg;
    msg.hdr.layer_specific = client_cb->handle;
    bta_hf_client_sm_execute(BTA_HF_CLIENT_DISC_FAIL_EVT, &msg);
  }
}

/*******************************************************************************
 *
 * Function         bta_hf_client_free_db
 *
 * Description      Free discovery database.
 *
 *
 * Returns          void
 *
 ******************************************************************************/
void bta_hf_client_free_db(tBTA_HF_CLIENT_DATA* p_data) {
  tBTA_HF_CLIENT_CB* client_cb =
      bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
  if (client_cb == NULL) {
    APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
                     p_data->hdr.layer_specific);
    return;
  }

  osi_free_and_reset((void**)&client_cb->p_disc_db);
}
