/******************************************************************************
 *
 *  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 GATT interface functions
 *
 ******************************************************************************/
#include "bt_target.h"

#include <base/strings/stringprintf.h>
#include <stdio.h>
#include <string.h>
#include "bt_common.h"
#include "btm_int.h"
#include "device/include/controller.h"
#include "gatt_api.h"
#include "gatt_int.h"
#include "l2c_api.h"

using base::StringPrintf;

/**
 * Add an service handle range to the list in decending order of the start
 * handle. Return reference to the newly added element.
 **/
tGATT_HDL_LIST_ELEM& gatt_add_an_item_to_list(uint16_t s_handle) {
  auto lst_ptr = gatt_cb.hdl_list_info;
  auto it = lst_ptr->begin();
  for (; it != lst_ptr->end(); it++) {
    if (s_handle > it->asgn_range.s_handle) break;
  }

  auto rit = lst_ptr->emplace(it);
  return *rit;
}

/*****************************************************************************
 *
 *                  GATT SERVER API
 *
 *****************************************************************************/
/*******************************************************************************
 *
 * Function         GATTS_AddHandleRange
 *
 * Description      This function add the allocated handles range for the
 *                  specified application UUID, service UUID and service
 *                  instance
 *
 * Parameter        p_hndl_range:   pointer to allocated handles information
 *
 **/

void GATTS_AddHandleRange(tGATTS_HNDL_RANGE* p_hndl_range) {
  gatt_add_an_item_to_list(p_hndl_range->s_handle);
}

/*******************************************************************************
 *
 * Function         GATTS_NVRegister
 *
 * Description      Application manager calls this function to register for
 *                  NV save callback function.  There can be one and only one
 *                  NV save callback function.
 *
 * Parameter        p_cb_info : callback informaiton
 *
 * Returns          true if registered OK, else false
 *
 ******************************************************************************/
bool GATTS_NVRegister(tGATT_APPL_INFO* p_cb_info) {
  bool status = false;
  if (p_cb_info) {
    gatt_cb.cb_info = *p_cb_info;
    status = true;
    gatt_init_srv_chg();
  }

  return status;
}

static uint8_t BASE_UUID[16] = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
                                0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

static int uuidType(unsigned char* p_uuid) {
  if (memcmp(p_uuid, BASE_UUID, 12) != 0) return LEN_UUID_128;
  if (memcmp(p_uuid + 14, BASE_UUID + 14, 2) != 0) return LEN_UUID_32;

  return LEN_UUID_16;
}

/*******************************************************************************
 * BTIF -> BTA conversion functions
 ******************************************************************************/

static void btif_to_bta_uuid(tBT_UUID* p_dest, bt_uuid_t* p_src) {
  char* p_byte = (char*)p_src;
  int i = 0;

  p_dest->len = uuidType(p_src->uu);

  switch (p_dest->len) {
    case LEN_UUID_16:
      p_dest->uu.uuid16 = (p_src->uu[13] << 8) + p_src->uu[12];
      break;

    case LEN_UUID_32:
      p_dest->uu.uuid32 = (p_src->uu[15] << 24) + (p_src->uu[14] << 16) +
                          (p_src->uu[13] << 8) + p_src->uu[12];
      break;

    case LEN_UUID_128:
      for (i = 0; i != 16; ++i) p_dest->uu.uuid128[i] = p_byte[i];
      break;

    default:
      LOG(ERROR) << __func__ << ": Unknown UUID length %d!" << +p_dest->len;
      break;
  }
}

void uuid_128_from_16(bt_uuid_t* uuid, uint16_t uuid16) {
  memcpy(uuid, &BASE_UUID, sizeof(bt_uuid_t));

  uuid->uu[13] = (uint8_t)((0xFF00 & uuid16) >> 8);
  uuid->uu[12] = (uint8_t)(0x00FF & uuid16);
}

static uint16_t compute_service_size(btgatt_db_element_t* service, int count) {
  int db_size = 0;
  btgatt_db_element_t* el = service;

  for (int i = 0; i < count; i++, el++)
    if (el->type == BTGATT_DB_PRIMARY_SERVICE ||
        el->type == BTGATT_DB_SECONDARY_SERVICE ||
        el->type == BTGATT_DB_DESCRIPTOR ||
        el->type == BTGATT_DB_INCLUDED_SERVICE)
      db_size += 1;
    else if (el->type == BTGATT_DB_CHARACTERISTIC)
      db_size += 2;
    else
      LOG(ERROR) << __func__ << ": Unknown element type: " << el->type;

  return db_size;
}

static bool is_gatt_attr_type(const tBT_UUID& uuid) {
  if (uuid.len == LEN_UUID_16 && (uuid.uu.uuid16 == GATT_UUID_PRI_SERVICE ||
                                  uuid.uu.uuid16 == GATT_UUID_SEC_SERVICE ||
                                  uuid.uu.uuid16 == GATT_UUID_INCLUDE_SERVICE ||
                                  uuid.uu.uuid16 == GATT_UUID_CHAR_DECLARE)) {
    return true;
  }
  return false;
}

/** Update the the last primary info for the service list info */
static void gatt_update_last_pri_srv_info() {
  gatt_cb.last_primary_s_handle = 0;

  for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info)
    if (el.is_primary) gatt_cb.last_primary_s_handle = el.s_hdl;
}

/*******************************************************************************
 *
 * Function         GATTS_AddService
 *
 * Description      This function is called to add GATT service.
 *
 * Parameter        gatt_if : application if
 *                  service : pseudo-representation of service and it's content
 *                  count   : size of service
 *
 * Returns          on success GATT_SERVICE_STARTED is returned, and
 *                  attribute_handle field inside service elements are filled.
 *                  on error error status is returned.
 *
 ******************************************************************************/
uint16_t GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service,
                          int count) {
  uint16_t s_hdl = 0;
  bool save_hdl = false;
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
  tBT_UUID* p_app_uuid128;

  bool is_pri = (service->type == BTGATT_DB_PRIMARY_SERVICE) ? true : false;
  tBT_UUID svc_uuid;
  btif_to_bta_uuid(&svc_uuid, &service->uuid);

  LOG(INFO) << __func__;

  if (p_reg == NULL) {
    LOG(ERROR) << "Inavlid gatt_if=" << +gatt_if;
    return GATT_INTERNAL_ERROR;
  }

  p_app_uuid128 = &p_reg->app_uuid128;

  uint16_t num_handles = compute_service_size(service, count);

  if ((svc_uuid.len == LEN_UUID_16) &&
      (svc_uuid.uu.uuid16 == UUID_SERVCLASS_GATT_SERVER)) {
    s_hdl = gatt_cb.hdl_cfg.gatt_start_hdl;
  } else if ((svc_uuid.len == LEN_UUID_16) &&
             (svc_uuid.uu.uuid16 == UUID_SERVCLASS_GAP_SERVER)) {
    s_hdl = gatt_cb.hdl_cfg.gap_start_hdl;
  } else {
    if (!gatt_cb.hdl_list_info->empty()) {
      s_hdl = gatt_cb.hdl_list_info->front().asgn_range.e_handle + 1;
    }

    if (s_hdl < gatt_cb.hdl_cfg.app_start_hdl)
      s_hdl = gatt_cb.hdl_cfg.app_start_hdl;

    save_hdl = true;
  }

  /* check for space */
  if (num_handles > (0xFFFF - s_hdl + 1)) {
    LOG(ERROR) << StringPrintf(
        "GATTS_ReserveHandles: no handles, s_hdl: %u  needed: %u", s_hdl,
        num_handles);
    return GATT_INTERNAL_ERROR;
  }

  tGATT_HDL_LIST_ELEM& list = gatt_add_an_item_to_list(s_hdl);
  list.asgn_range.app_uuid128 = *p_app_uuid128;
  list.asgn_range.svc_uuid = svc_uuid;
  list.asgn_range.s_handle = s_hdl;
  list.asgn_range.e_handle = s_hdl + num_handles - 1;
  list.asgn_range.is_primary = is_pri;

  if (save_hdl) {
    if (gatt_cb.cb_info.p_nv_save_callback)
      (*gatt_cb.cb_info.p_nv_save_callback)(true, &list.asgn_range);
  }

  gatts_init_service_db(list.svc_db, &svc_uuid, is_pri, s_hdl, num_handles);

  VLOG(1) << StringPrintf(
      "%s: handles needed:%u s_hdl=%u e_hdl=%u %s[%x] is_primary=%d", __func__,
      num_handles, list.asgn_range.s_handle, list.asgn_range.e_handle,
      ((list.asgn_range.svc_uuid.len == 2) ? "uuid16" : "uuid128"),
      list.asgn_range.svc_uuid.uu.uuid16, list.asgn_range.is_primary);

  service->attribute_handle = s_hdl;

  btgatt_db_element_t* el = service + 1;
  for (int i = 0; i < count - 1; i++, el++) {
    tBT_UUID uuid;
    btif_to_bta_uuid(&uuid, &el->uuid);

    if (el->type == BTGATT_DB_CHARACTERISTIC) {
      /* data validity checking */
      if (((el->properties & GATT_CHAR_PROP_BIT_AUTH) &&
           !(el->permissions & GATT_WRITE_SIGNED_PERM)) ||
          ((el->permissions & GATT_WRITE_SIGNED_PERM) &&
           !(el->properties & GATT_CHAR_PROP_BIT_AUTH))) {
        VLOG(1) << StringPrintf(
            "Invalid configuration property=0x%02x perm=0x%04x ",
            el->properties, el->permissions);
        return GATT_INTERNAL_ERROR;
      }

      if (is_gatt_attr_type(uuid)) {
        LOG(ERROR) << StringPrintf(
            "%s: attept to add characteristic with UUID equal to GATT "
            "Attribute Type 0x%04x ",
            __func__, uuid.uu.uuid16);
        return GATT_INTERNAL_ERROR;
      }

      el->attribute_handle = gatts_add_characteristic(
          list.svc_db, el->permissions, el->properties, uuid);
    } else if (el->type == BTGATT_DB_DESCRIPTOR) {
      if (is_gatt_attr_type(uuid)) {
        LOG(ERROR) << StringPrintf(
            "%s: attept to add descriptor with UUID equal to GATT "
            "Attribute Type 0x%04x ",
            __func__, uuid.uu.uuid16);
        return GATT_INTERNAL_ERROR;
      }

      el->attribute_handle =
          gatts_add_char_descr(list.svc_db, el->permissions, uuid);
    } else if (el->type == BTGATT_DB_INCLUDED_SERVICE) {
      tGATT_HDL_LIST_ELEM* p_incl_decl;
      p_incl_decl = gatt_find_hdl_buffer_by_handle(el->attribute_handle);
      if (p_incl_decl == nullptr) {
        VLOG(1) << "Included Service not created";
        return GATT_INTERNAL_ERROR;
      }

      el->attribute_handle = gatts_add_included_service(
          list.svc_db, p_incl_decl->asgn_range.s_handle,
          p_incl_decl->asgn_range.e_handle, p_incl_decl->asgn_range.svc_uuid);
    }
  }

  LOG(INFO) << __func__ << ": service parsed correctly, now starting";

  /*this is a new application service start */

  // find a place for this service in the list
  auto lst_ptr = gatt_cb.srv_list_info;
  auto it = lst_ptr->begin();
  for (; it != lst_ptr->end(); it++) {
    if (list.asgn_range.s_handle < it->s_hdl) break;
  }
  auto rit = lst_ptr->emplace(it);

  tGATT_SRV_LIST_ELEM& elem = *rit;
  elem.gatt_if = gatt_if;
  elem.s_hdl = list.asgn_range.s_handle;
  elem.e_hdl = list.asgn_range.e_handle;
  elem.p_db = &list.svc_db;
  elem.is_primary = list.asgn_range.is_primary;

  memcpy(&elem.app_uuid, &list.asgn_range.app_uuid128, sizeof(tBT_UUID));
  elem.type = list.asgn_range.is_primary ? GATT_UUID_PRI_SERVICE
                                         : GATT_UUID_SEC_SERVICE;

  if (elem.type == GATT_UUID_PRI_SERVICE) {
    tBT_UUID* p_uuid = gatts_get_service_uuid(elem.p_db);
    elem.sdp_handle = gatt_add_sdp_record(p_uuid, elem.s_hdl, elem.e_hdl);
  } else {
    elem.sdp_handle = 0;
  }

  gatt_update_last_pri_srv_info();

  VLOG(1) << StringPrintf(
      "%s: allocated el: s_hdl=%d e_hdl=%d type=0x%x sdp_hdl=0x%x", __func__,
      elem.s_hdl, elem.e_hdl, elem.type, elem.sdp_handle);

  gatt_proc_srv_chg();

  return GATT_SERVICE_STARTED;
}

bool is_active_service(tBT_UUID* p_app_uuid128, tBT_UUID* p_svc_uuid,
                       uint16_t start_handle) {
  for (auto& info : *gatt_cb.srv_list_info) {
    tBT_UUID* p_this_uuid = gatts_get_service_uuid(info.p_db);

    if (p_this_uuid && gatt_uuid_compare(*p_app_uuid128, info.app_uuid) &&
        gatt_uuid_compare(*p_svc_uuid, *p_this_uuid) &&
        (start_handle == info.s_hdl)) {
      LOG(ERROR) << "Active Service Found";
      gatt_dbg_display_uuid(*p_svc_uuid);

      return true;
    }
  }
  return false;
}

/*******************************************************************************
 *
 * Function         GATTS_DeleteService
 *
 * Description      This function is called to delete a service.
 *
 * Parameter        gatt_if       : application interface
 *                  p_svc_uuid    : service UUID
 *                  start_handle  : start handle of the service
 *
 * Returns          true if the operation succeeded, false if the handle block
 *                  was not found.
 *
 ******************************************************************************/
bool GATTS_DeleteService(tGATT_IF gatt_if, tBT_UUID* p_svc_uuid,
                         uint16_t svc_inst) {
  VLOG(1) << __func__;

  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
  if (p_reg == NULL) {
    LOG(ERROR) << "Applicaiton not foud";
    return false;
  }

  tBT_UUID* p_app_uuid128 = &p_reg->app_uuid128;
  auto it = gatt_find_hdl_buffer_by_app_id(p_app_uuid128, p_svc_uuid, svc_inst);
  if (it == gatt_cb.hdl_list_info->end()) {
    LOG(ERROR) << "No Service found";
    return false;
  }

  gatt_proc_srv_chg();

  if (is_active_service(p_app_uuid128, p_svc_uuid, svc_inst)) {
    GATTS_StopService(it->asgn_range.s_handle);
  }

  VLOG(1) << StringPrintf("released handles s_hdl=%u e_hdl=%u",
                          it->asgn_range.s_handle, it->asgn_range.e_handle);

  if ((it->asgn_range.s_handle >= gatt_cb.hdl_cfg.app_start_hdl) &&
      gatt_cb.cb_info.p_nv_save_callback)
    (*gatt_cb.cb_info.p_nv_save_callback)(false, &it->asgn_range);

  gatt_cb.hdl_list_info->erase(it);
  return true;
}

/*******************************************************************************
 *
 * Function         GATTS_StopService
 *
 * Description      This function is called to stop a service
 *
 * Parameter         service_handle : this is the start handle of a service
 *
 * Returns          None.
 *
 ******************************************************************************/
void GATTS_StopService(uint16_t service_handle) {
  LOG(INFO) << __func__ << ": 0x" << std::hex << +service_handle;

  auto it = gatt_sr_find_i_rcb_by_handle(service_handle);
  if (it == gatt_cb.srv_list_info->end()) {
    LOG(ERROR) << StringPrintf("%s: service_handle: %u is not in use", __func__,
                               service_handle);
  }

  if (it->sdp_handle) {
    SDP_DeleteRecord(it->sdp_handle);
  }

  gatt_cb.srv_list_info->erase(it);
  gatt_update_last_pri_srv_info();
}
/*******************************************************************************
 *
 * Function         GATTs_HandleValueIndication
 *
 * Description      This function sends a handle value indication to a client.
 *
 * Parameter        conn_id: connection identifier.
 *                  attr_handle: Attribute handle of this handle value
 *                               indication.
 *                  val_len: Length of the indicated attribute value.
 *                  p_val: Pointer to the indicated attribute value data.
 *
 * Returns          GATT_SUCCESS if sucessfully sent or queued; otherwise error
 *                  code.
 *
 ******************************************************************************/
tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle,
                                         uint16_t val_len, uint8_t* p_val) {
  tGATT_STATUS cmd_status = GATT_NO_RESOURCES;

  tGATT_VALUE indication;
  BT_HDR* p_msg;
  tGATT_VALUE* p_buf;
  tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);

  VLOG(1) << __func__;
  if ((p_reg == NULL) || (p_tcb == NULL)) {
    LOG(ERROR) << __func__ << ": Unknown  conn_id: " << +conn_id;
    return (tGATT_STATUS)GATT_INVALID_CONN_ID;
  }

  if (!GATT_HANDLE_IS_VALID(attr_handle)) return GATT_ILLEGAL_PARAMETER;

  indication.conn_id = conn_id;
  indication.handle = attr_handle;
  indication.len = val_len;
  memcpy(indication.value, p_val, val_len);
  indication.auth_req = GATT_AUTH_REQ_NONE;

  if (GATT_HANDLE_IS_VALID(p_tcb->indicate_handle)) {
    VLOG(1) << "Add a pending indication";
    p_buf = gatt_add_pending_ind(p_tcb, &indication);
    if (p_buf != NULL) {
      cmd_status = GATT_SUCCESS;
    } else {
      cmd_status = GATT_NO_RESOURCES;
    }
  } else {
    tGATT_SR_MSG gatt_sr_msg;
    gatt_sr_msg.attr_value = indication;
    p_msg = attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_IND, &gatt_sr_msg);
    if (p_msg != NULL) {
      cmd_status = attp_send_sr_msg(*p_tcb, p_msg);

      if (cmd_status == GATT_SUCCESS || cmd_status == GATT_CONGESTED) {
        p_tcb->indicate_handle = indication.handle;
        gatt_start_conf_timer(p_tcb);
      }
    }
  }
  return cmd_status;
}

/*******************************************************************************
 *
 * Function         GATTS_HandleValueNotification
 *
 * Description      This function sends a handle value notification to a client.
 *
 * Parameter        conn_id: connection identifier.
 *                  attr_handle: Attribute handle of this handle value
 *                               indication.
 *                  val_len: Length of the indicated attribute value.
 *                  p_val: Pointer to the indicated attribute value data.
 *
 * Returns          GATT_SUCCESS if sucessfully sent; otherwise error code.
 *
 ******************************************************************************/
tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id,
                                           uint16_t attr_handle,
                                           uint16_t val_len, uint8_t* p_val) {
  tGATT_VALUE notif;
  tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);

  VLOG(1) << __func__;

  if ((p_reg == NULL) || (p_tcb == NULL)) {
    LOG(ERROR) << __func__ << "Unknown  conn_id: " << conn_id;
    return (tGATT_STATUS)GATT_INVALID_CONN_ID;
  }

  if (!GATT_HANDLE_IS_VALID(attr_handle)) {
    return GATT_ILLEGAL_PARAMETER;
  }

  notif.handle = attr_handle;
  notif.len = val_len;
  memcpy(notif.value, p_val, val_len);
  notif.auth_req = GATT_AUTH_REQ_NONE;

  tGATT_STATUS cmd_sent;
  tGATT_SR_MSG gatt_sr_msg;
  gatt_sr_msg.attr_value = notif;
  BT_HDR* p_buf =
      attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_NOTIF, &gatt_sr_msg);
  if (p_buf != NULL) {
    cmd_sent = attp_send_sr_msg(*p_tcb, p_buf);
  } else
    cmd_sent = GATT_NO_RESOURCES;
  return cmd_sent;
}

/*******************************************************************************
 *
 * Function         GATTS_SendRsp
 *
 * Description      This function sends the server response to client.
 *
 * Parameter        conn_id: connection identifier.
 *                  trans_id: transaction id
 *                  status: response status
 *                  p_msg: pointer to message parameters structure.
 *
 * Returns          GATT_SUCCESS if sucessfully sent; otherwise error code.
 *
 ******************************************************************************/
tGATT_STATUS GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id,
                           tGATT_STATUS status, tGATTS_RSP* p_msg) {
  tGATT_STATUS cmd_sent = GATT_ILLEGAL_PARAMETER;
  tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);

  VLOG(1) << __func__
          << StringPrintf(": conn_id: %u  trans_id: %u  Status: 0x%04x",
                          conn_id, trans_id, status);

  if ((p_reg == NULL) || (p_tcb == NULL)) {
    LOG(ERROR) << StringPrintf("Unknown  conn_id: %u ", conn_id);
    return (tGATT_STATUS)GATT_INVALID_CONN_ID;
  }

  if (p_tcb->sr_cmd.trans_id != trans_id) {
    LOG(ERROR) << StringPrintf("conn_id: %u  waiting for op_code = %02x",
                               conn_id, p_tcb->sr_cmd.op_code);

    return (GATT_WRONG_STATE);
  }
  /* Process App response */
  cmd_sent = gatt_sr_process_app_rsp(*p_tcb, gatt_if, trans_id,
                                     p_tcb->sr_cmd.op_code, status, p_msg);

  return cmd_sent;
}

/******************************************************************************/
/* GATT Profile Srvr Functions */
/******************************************************************************/

/******************************************************************************/
/*                                                                            */
/*                  GATT CLIENT APIs                                          */
/*                                                                            */
/******************************************************************************/

/*******************************************************************************
 *
 * Function         GATTC_ConfigureMTU
 *
 * Description      This function is called to configure the ATT MTU size.
 *
 * Parameters       conn_id: connection identifier.
 *                  mtu    - attribute MTU size..
 *
 * Returns          GATT_SUCCESS if command started successfully.
 *
 ******************************************************************************/
tGATT_STATUS GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) {
  tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);

  VLOG(1) << __func__ << StringPrintf("conn_id=%d mtu=%d", conn_id, mtu);

  if ((p_tcb == NULL) || (p_reg == NULL) || (mtu < GATT_DEF_BLE_MTU_SIZE) ||
      (mtu > GATT_MAX_MTU_SIZE)) {
    return GATT_ILLEGAL_PARAMETER;
  }

  /* Validate that the link is BLE, not BR/EDR */
  if (p_tcb->transport != BT_TRANSPORT_LE) {
    return GATT_ERROR;
  }

  if (gatt_is_clcb_allocated(conn_id)) {
    LOG(ERROR) << "GATT_BUSY conn_id = " << +conn_id;
    return GATT_BUSY;
  }

  tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
  if (!p_clcb) return GATT_NO_RESOURCES;

  p_clcb->p_tcb->payload_size = mtu;
  p_clcb->operation = GATTC_OPTYPE_CONFIG;
  tGATT_CL_MSG gatt_cl_msg;
  gatt_cl_msg.mtu = mtu;
  return attp_send_cl_msg(*p_clcb->p_tcb, p_clcb, GATT_REQ_MTU, &gatt_cl_msg);
}


/*******************************************************************************
 *
 * Function         GATTC_Discover
 *
 * Description      This function is called to do a discovery procedure on ATT
 *                  server.
 *
 * Parameters       conn_id: connection identifier.
 *                  disc_type:discovery type.
 *                  p_param: parameters of discovery requirement.
 *
 * Returns          GATT_SUCCESS if command received/sent successfully.
 *
 ******************************************************************************/
tGATT_STATUS GATTC_Discover(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
                            tGATT_DISC_PARAM* p_param) {
  tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);

  LOG(INFO) << __func__
            << StringPrintf(" conn_id=%d disc_type=%d", conn_id, disc_type);

  if ((p_tcb == NULL) || (p_reg == NULL) || (p_param == NULL) ||
      (disc_type >= GATT_DISC_MAX)) {
    LOG(ERROR) << StringPrintf("Illegal param: disc_type %d conn_id = %d",
                               disc_type, conn_id);
    return GATT_ILLEGAL_PARAMETER;
  }

  if (!GATT_HANDLE_IS_VALID(p_param->s_handle) ||
      !GATT_HANDLE_IS_VALID(p_param->e_handle) ||
      /* search by type does not have a valid UUID param */
      (disc_type == GATT_DISC_SRVC_BY_UUID && p_param->service.len == 0)) {
    return GATT_ILLEGAL_PARAMETER;
  }

  if (gatt_is_clcb_allocated(conn_id)) {
    LOG(ERROR) << __func__ << "GATT_BUSY conn_id = " << +conn_id;
    return GATT_BUSY;
  }

  tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
  if (!p_clcb) return GATT_NO_RESOURCES;

  p_clcb->operation = GATTC_OPTYPE_DISCOVERY;
  p_clcb->op_subtype = disc_type;
  p_clcb->s_handle = p_param->s_handle;
  p_clcb->e_handle = p_param->e_handle;
  p_clcb->uuid = p_param->service;

  gatt_act_discovery(p_clcb);
  return GATT_SUCCESS;
}

/*******************************************************************************
 *
 * Function         GATTC_Read
 *
 * Description      This function is called to read the value of an attribute
 *                  from the server.
 *
 * Parameters       conn_id: connection identifier.
 *                  type    - attribute read type.
 *                  p_read  - read operation parameters.
 *
 * Returns          GATT_SUCCESS if command started successfully.
 *
 ******************************************************************************/
tGATT_STATUS GATTC_Read(uint16_t conn_id, tGATT_READ_TYPE type,
                        tGATT_READ_PARAM* p_read) {
  tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);

  VLOG(1) << __func__ << StringPrintf(" conn_id=%d type=%d", conn_id, type);

  if ((p_tcb == NULL) || (p_reg == NULL) || (p_read == NULL) ||
      ((type >= GATT_READ_MAX) || (type == 0))) {
    LOG(ERROR) << StringPrintf(" Illegal param: conn_id %d, type 0%d,", conn_id,
                               type);
    return GATT_ILLEGAL_PARAMETER;
  }

  if (gatt_is_clcb_allocated(conn_id)) {
    LOG(ERROR) << StringPrintf(" GATT_BUSY conn_id = %d", conn_id);
    return GATT_BUSY;
  }

  tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
  if (!p_clcb) return GATT_NO_RESOURCES;

  p_clcb->operation = GATTC_OPTYPE_READ;
  p_clcb->op_subtype = type;
  p_clcb->auth_req = p_read->by_handle.auth_req;
  p_clcb->counter = 0;

  switch (type) {
    case GATT_READ_BY_TYPE:
    case GATT_READ_CHAR_VALUE:
      p_clcb->s_handle = p_read->service.s_handle;
      p_clcb->e_handle = p_read->service.e_handle;
      memcpy(&p_clcb->uuid, &p_read->service.uuid, sizeof(tBT_UUID));
      break;
    case GATT_READ_MULTIPLE: {
      p_clcb->s_handle = 0;
      /* copy multiple handles in CB */
      tGATT_READ_MULTI* p_read_multi =
          (tGATT_READ_MULTI*)osi_malloc(sizeof(tGATT_READ_MULTI));
      p_clcb->p_attr_buf = (uint8_t*)p_read_multi;
      memcpy(p_read_multi, &p_read->read_multiple, sizeof(tGATT_READ_MULTI));
      break;
    }
    case GATT_READ_BY_HANDLE:
    case GATT_READ_PARTIAL:
      memset(&p_clcb->uuid, 0, sizeof(tBT_UUID));
      p_clcb->s_handle = p_read->by_handle.handle;

      if (type == GATT_READ_PARTIAL) {
        p_clcb->counter = p_read->partial.offset;
      }

      break;
    default:
      break;
  }

  /* start security check */
  gatt_security_check_start(p_clcb);
  return GATT_SUCCESS;
}

/*******************************************************************************
 *
 * Function         GATTC_Write
 *
 * Description      This function is called to write the value of an attribute
 *                  to the server.
 *
 * Parameters       conn_id: connection identifier.
 *                  type    - attribute write type.
 *                  p_write  - write operation parameters.
 *
 * Returns          GATT_SUCCESS if command started successfully.
 *
 ******************************************************************************/
tGATT_STATUS GATTC_Write(uint16_t conn_id, tGATT_WRITE_TYPE type,
                         tGATT_VALUE* p_write) {
  tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);

  if ((p_tcb == NULL) || (p_reg == NULL) || (p_write == NULL) ||
      ((type != GATT_WRITE) && (type != GATT_WRITE_PREPARE) &&
       (type != GATT_WRITE_NO_RSP))) {
    LOG(ERROR) << __func__
               << StringPrintf(" Illegal param: conn_id %d, type 0%d,", conn_id,
                               type);
    return GATT_ILLEGAL_PARAMETER;
  }

  if (gatt_is_clcb_allocated(conn_id)) {
    LOG(ERROR) << StringPrintf("GATT_BUSY conn_id = %d", conn_id);
    return GATT_BUSY;
  }

  tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
  if (!p_clcb) return GATT_NO_RESOURCES;

  p_clcb->operation = GATTC_OPTYPE_WRITE;
  p_clcb->op_subtype = type;
  p_clcb->auth_req = p_write->auth_req;

  p_clcb->p_attr_buf = (uint8_t*)osi_malloc(sizeof(tGATT_VALUE));
  memcpy(p_clcb->p_attr_buf, (void*)p_write, sizeof(tGATT_VALUE));

  tGATT_VALUE* p = (tGATT_VALUE*)p_clcb->p_attr_buf;
  if (type == GATT_WRITE_PREPARE) {
    p_clcb->start_offset = p_write->offset;
    p->offset = 0;
  }

  gatt_security_check_start(p_clcb);
  return GATT_SUCCESS;
}

/*******************************************************************************
 *
 * Function         GATTC_ExecuteWrite
 *
 * Description      This function is called to send an Execute write request to
 *                  the server.
 *
 * Parameters       conn_id: connection identifier.
 *                  is_execute - to execute or cancel the prepared write
 *                               request(s)
 *
 * Returns          GATT_SUCCESS if command started successfully.
 *
 ******************************************************************************/
tGATT_STATUS GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute) {
  tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);

  VLOG(1) << __func__
          << StringPrintf(": conn_id=%d is_execute=%d", conn_id, is_execute);

  if ((p_tcb == NULL) || (p_reg == NULL)) {
    LOG(ERROR) << StringPrintf(" Illegal param: conn_id %d", conn_id);
    return GATT_ILLEGAL_PARAMETER;
  }

  if (gatt_is_clcb_allocated(conn_id)) {
    LOG(ERROR) << StringPrintf(" GATT_BUSY conn_id = %d", conn_id);
    return GATT_BUSY;
  }

  tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
  if (!p_clcb) return GATT_NO_RESOURCES;

  p_clcb->operation = GATTC_OPTYPE_EXE_WRITE;
  tGATT_EXEC_FLAG flag =
      is_execute ? GATT_PREP_WRITE_EXEC : GATT_PREP_WRITE_CANCEL;
  gatt_send_queue_write_cancel(*p_clcb->p_tcb, p_clcb, flag);
  return GATT_SUCCESS;
}

/*******************************************************************************
 *
 * Function         GATTC_SendHandleValueConfirm
 *
 * Description      This function is called to send a handle value confirmation
 *                  as response to a handle value notification from server.
 *
 * Parameters       conn_id: connection identifier.
 *                  handle: the handle of the attribute confirmation.
 *
 * Returns          GATT_SUCCESS if command started successfully.
 *
 ******************************************************************************/
tGATT_STATUS GATTC_SendHandleValueConfirm(uint16_t conn_id, uint16_t handle) {
  VLOG(1) << __func__
          << StringPrintf(" conn_id=%d handle=0x%x", conn_id, handle);

  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(GATT_GET_TCB_IDX(conn_id));
  if (!p_tcb) {
    LOG(ERROR) << StringPrintf(" Unknown conn_id: %u", conn_id);
    return GATT_ILLEGAL_PARAMETER;
  }

  if (p_tcb->ind_count == 0) {
    VLOG(1) << " conn_id: " << +conn_id
            << " ignored not waiting for indicaiton ack";
    return GATT_SUCCESS;
  }

  alarm_cancel(p_tcb->ind_ack_timer);

  VLOG(1) << "notif_count= " << p_tcb->ind_count;
  /* send confirmation now */
  tGATT_CL_MSG gatt_cl_msg;
  gatt_cl_msg.handle = handle;
  tGATT_STATUS ret =
      attp_send_cl_msg(*p_tcb, nullptr, GATT_HANDLE_VALUE_CONF, &gatt_cl_msg);

  p_tcb->ind_count = 0;

  return ret;
}

/******************************************************************************/
/*                                                                            */
/*                  GATT  APIs                                                */
/*                                                                            */
/******************************************************************************/
/*******************************************************************************
 *
 * Function         GATT_SetIdleTimeout
 *
 * Description      This function (common to both client and server) sets the
 *                  idle timeout for a tansport connection
 *
 * Parameter        bd_addr:   target device bd address.
 *                  idle_tout: timeout value in seconds.
 *
 * Returns          void
 *
 ******************************************************************************/
void GATT_SetIdleTimeout(const RawAddress& bd_addr, uint16_t idle_tout,
                         tBT_TRANSPORT transport) {
  tGATT_TCB* p_tcb;
  bool status = false;

  p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
  if (p_tcb != NULL) {
    if (p_tcb->att_lcid == L2CAP_ATT_CID) {
      status = L2CA_SetFixedChannelTout(bd_addr, L2CAP_ATT_CID, idle_tout);

      if (idle_tout == GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP)
        L2CA_SetIdleTimeoutByBdAddr(p_tcb->peer_bda,
                                    GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP,
                                    BT_TRANSPORT_LE);
    } else {
      status = L2CA_SetIdleTimeout(p_tcb->att_lcid, idle_tout, false);
    }
  }

  VLOG(1) << __func__
          << StringPrintf(" idle_tout=%d status=%d(1-OK 0-not performed)",
                          idle_tout, status);
}

/*******************************************************************************
 *
 * Function         GATT_Register
 *
 * Description      This function is called to register an  application
 *                  with GATT
 *
 * Parameter        p_app_uuid128: Application UUID
 *                  p_cb_info: callback functions.
 *
 * Returns          0 for error, otherwise the index of the client registered
 *                  with GATT
 *
 ******************************************************************************/
tGATT_IF GATT_Register(tBT_UUID* p_app_uuid128, tGATT_CBACK* p_cb_info) {
  tGATT_REG* p_reg;
  uint8_t i_gatt_if = 0;
  tGATT_IF gatt_if = 0;

  LOG(INFO) << __func__;
  gatt_dbg_display_uuid(*p_app_uuid128);

  for (i_gatt_if = 0, p_reg = gatt_cb.cl_rcb; i_gatt_if < GATT_MAX_APPS;
       i_gatt_if++, p_reg++) {
    if (p_reg->in_use &&
        !memcmp(p_app_uuid128->uu.uuid128, p_reg->app_uuid128.uu.uuid128,
                LEN_UUID_128)) {
      LOG(ERROR) << "application already registered.";
      return 0;
    }
  }

  for (i_gatt_if = 0, p_reg = gatt_cb.cl_rcb; i_gatt_if < GATT_MAX_APPS;
       i_gatt_if++, p_reg++) {
    if (!p_reg->in_use) {
      memset(p_reg, 0, sizeof(tGATT_REG));
      i_gatt_if++; /* one based number */
      p_reg->app_uuid128 = *p_app_uuid128;
      gatt_if = p_reg->gatt_if = (tGATT_IF)i_gatt_if;
      p_reg->app_cb = *p_cb_info;
      p_reg->in_use = true;

      LOG(INFO) << "allocated gatt_if=" << +gatt_if;
      return gatt_if;
    }
  }

  LOG(ERROR) << "can't Register GATT client, MAX client reached: "
             << GATT_MAX_APPS;
  return 0;
}

/*******************************************************************************
 *
 * Function         GATT_Deregister
 *
 * Description      This function deregistered the application from GATT.
 *
 * Parameters       gatt_if: applicaiton interface.
 *
 * Returns          None.
 *
 ******************************************************************************/
void GATT_Deregister(tGATT_IF gatt_if) {
  VLOG(1) << __func__ << " gatt_if=" << +gatt_if;

  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
  /* Index 0 is GAP and is never deregistered */
  if ((gatt_if == 0) || (p_reg == NULL)) {
    LOG(ERROR) << "invalid gatt_if: " << +gatt_if;
    return;
  }

  /* stop all services  */
  /* todo an applcaiton can not be deregistered if its services is also used by
    other application
    deregisteration need to bed performed in an orderly fashion
    no check for now */
  for (auto it = gatt_cb.srv_list_info->begin(); it != gatt_cb.srv_list_info->end(); ) {
    if (it->gatt_if == gatt_if) {
      GATTS_StopService(it++->s_hdl);
    } else {
      ++it;
    }
  }

  /* free all services db buffers if owned by this application */
  gatt_free_srvc_db_buffer_app_id(&p_reg->app_uuid128);

  /* When an application deregisters, check remove the link associated with the
   * app */
  tGATT_TCB* p_tcb;
  int i, j;
  for (i = 0, p_tcb = gatt_cb.tcb; i < GATT_MAX_PHY_CHANNEL; i++, p_tcb++) {
    if (p_tcb->in_use) {
      if (gatt_get_ch_state(p_tcb) != GATT_CH_CLOSE) {
        gatt_update_app_use_link_flag(gatt_if, p_tcb, false, true);
      }

      tGATT_CLCB* p_clcb;
      for (j = 0, p_clcb = &gatt_cb.clcb[j]; j < GATT_CL_MAX_LCB;
           j++, p_clcb++) {
        if (p_clcb->in_use && (p_clcb->p_reg->gatt_if == gatt_if) &&
            (p_clcb->p_tcb->tcb_idx == p_tcb->tcb_idx)) {
          alarm_cancel(p_clcb->gatt_rsp_timer_ent);
          gatt_clcb_dealloc(p_clcb);
          break;
        }
      }
    }
  }

  gatt_deregister_bgdev_list(gatt_if);

  memset(p_reg, 0, sizeof(tGATT_REG));
}

/*******************************************************************************
 *
 * Function         GATT_StartIf
 *
 * Description      This function is called after registration to start
 *                  receiving callbacks for registered interface.  Function may
 *                  call back with connection status and queued notifications
 *
 * Parameter        gatt_if: applicaiton interface.
 *
 * Returns          None.
 *
 ******************************************************************************/
void GATT_StartIf(tGATT_IF gatt_if) {
  tGATT_REG* p_reg;
  tGATT_TCB* p_tcb;
  RawAddress bda;
  uint8_t start_idx, found_idx;
  uint16_t conn_id;
  tGATT_TRANSPORT transport;

  VLOG(1) << __func__ << " gatt_if=" << gatt_if;
  p_reg = gatt_get_regcb(gatt_if);
  if (p_reg != NULL) {
    start_idx = 0;
    while (
        gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) {
      p_tcb = gatt_find_tcb_by_addr(bda, transport);
      if (p_reg->app_cb.p_conn_cb && p_tcb) {
        conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if);
        (*p_reg->app_cb.p_conn_cb)(gatt_if, bda, conn_id, true, 0, transport);
      }
      start_idx = ++found_idx;
    }
  }
}

/*******************************************************************************
 *
 * Function         GATT_Connect
 *
 * Description      This function initiate a connecttion to a remote device on
 *                  GATT channel.
 *
 * Parameters       gatt_if: applicaiton interface
 *                  bd_addr: peer device address.
 *                  is_direct: is a direct conenection or a background auto
 *                             connection
 *
 * Returns          true if connection started; false if connection start
 *                  failure.
 *
 ******************************************************************************/
bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, bool is_direct,
                  tBT_TRANSPORT transport, bool opportunistic) {
  uint8_t phy = controller_get_interface()->get_le_all_initiating_phys();
  return GATT_Connect(gatt_if, bd_addr, is_direct, transport, opportunistic,
                      phy);
}

bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, bool is_direct,
                  tBT_TRANSPORT transport, bool opportunistic,
                  uint8_t initiating_phys) {
  tGATT_REG* p_reg;
  bool status = false;

  LOG(INFO) << __func__ << "gatt_if=" << +gatt_if << " " << bd_addr;

  /* Make sure app is registered */
  p_reg = gatt_get_regcb(gatt_if);
  if (p_reg == NULL) {
    LOG(ERROR) << "gatt_if = " << gatt_if << " is not registered";
    return (false);
  }

  if (is_direct)
    status = gatt_act_connect(p_reg, bd_addr, transport, opportunistic,
                              initiating_phys);
  else {
    if (transport == BT_TRANSPORT_LE)
      status = gatt_update_auto_connect_dev(gatt_if, true, bd_addr);
    else {
      LOG(ERROR) << "Unsupported transport for background connection";
    }
  }

  return status;
}

/*******************************************************************************
 *
 * Function         GATT_CancelConnect
 *
 * Description      This function terminate the connection initaition to a
 *                  remote device on GATT channel.
 *
 * Parameters       gatt_if: client interface. If 0 used as unconditionally
 *                           disconnect, typically used for direct connection
 *                           cancellation.
 *                  bd_addr: peer device address.
 *
 * Returns          true if the connection started; false otherwise.
 *
 ******************************************************************************/
bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr,
                        bool is_direct) {
  LOG(INFO) << __func__ << ": gatt_if=" << +gatt_if;

  if (gatt_if && !gatt_get_regcb(gatt_if)) {
    LOG(ERROR) << "gatt_if =" << +gatt_if << " is not registered";
    return false;
  }

  if (is_direct) {
    if (gatt_if) {
      return gatt_cancel_open(gatt_if, bd_addr);
    }

    VLOG(1) << " unconditional";
    /* only LE connection can be cancelled */
    tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
    if (!p_tcb || p_tcb->app_hold_link.empty()) {
      LOG(ERROR) << __func__ << " no app found";
      return false;
    }

    for (auto it = p_tcb->app_hold_link.begin();
         it != p_tcb->app_hold_link.end();) {
      auto next = std::next(it);
      // gatt_cancel_open modifies the app_hold_link.
      if (!gatt_cancel_open(*it, bd_addr)) return false;

      it = next;
    }

    return true;
  }
  // is not direct

  if (gatt_if) return gatt_remove_bg_dev_for_app(gatt_if, bd_addr);

  if (!gatt_clear_bg_dev_for_addr(bd_addr)) {
    LOG(ERROR)
        << __func__
        << ": no app associated with the bg device for unconditional removal";
    return false;
  }

  return true;
}

/*******************************************************************************
 *
 * Function         GATT_Disconnect
 *
 * Description      This function disconnects the GATT channel for this
 *                  registered application.
 *
 * Parameters       conn_id: connection identifier.
 *
 * Returns          GATT_SUCCESS if disconnected.
 *
 ******************************************************************************/
tGATT_STATUS GATT_Disconnect(uint16_t conn_id) {
  tGATT_STATUS ret = GATT_ILLEGAL_PARAMETER;
  tGATT_TCB* p_tcb = NULL;
  tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);

  LOG(INFO) << __func__ << " conn_id=" << +conn_id;

  p_tcb = gatt_get_tcb_by_idx(tcb_idx);

  if (p_tcb) {
    gatt_update_app_use_link_flag(gatt_if, p_tcb, false, true);
    ret = GATT_SUCCESS;
  }
  return ret;
}

/*******************************************************************************
 *
 * Function         GATT_GetConnectionInfor
 *
 * Description      This function uses conn_id to find its associated BD address
 *                  and application interface
 *
 * Parameters        conn_id: connection id  (input)
 *                   p_gatt_if: applicaiton interface (output)
 *                   bd_addr: peer device address. (output)
 *
 * Returns          true the ligical link information is found for conn_id
 *
 ******************************************************************************/
bool GATT_GetConnectionInfor(uint16_t conn_id, tGATT_IF* p_gatt_if,
                             RawAddress& bd_addr, tBT_TRANSPORT* p_transport) {
  tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
  bool status = false;

  VLOG(1) << __func__ << " conn_id=" << +conn_id;

  if (p_tcb && p_reg) {
    bd_addr = p_tcb->peer_bda;
    *p_gatt_if = gatt_if;
    *p_transport = p_tcb->transport;
    status = true;
  }
  return status;
}

/*******************************************************************************
 *
 * Function         GATT_GetConnIdIfConnected
 *
 * Description      This function find the conn_id if the logical link for BD
 *                  address and applciation interface is connected
 *
 * Parameters        gatt_if: applicaiton interface (input)
 *                   bd_addr: peer device address. (input)
 *                   p_conn_id: connection id  (output)
 *                   transport: transport option
 *
 * Returns          true the logical link is connected
 *
 ******************************************************************************/
bool GATT_GetConnIdIfConnected(tGATT_IF gatt_if, const RawAddress& bd_addr,
                               uint16_t* p_conn_id, tBT_TRANSPORT transport) {
  tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
  bool status = false;

  if (p_reg && p_tcb && (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN)) {
    *p_conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if);
    status = true;
  }

  VLOG(1) << __func__ << " status= " << +status;
  return status;
}
