/******************************************************************************
 *
 *  Copyright 2009-2014 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.
 *
 ******************************************************************************/

/*******************************************************************************
 *
 *  Filename:      btif_gatt_client.c
 *
 *  Description:   GATT client implementation
 *
 ******************************************************************************/

#define LOG_TAG "bt_btif_gattc"

#include <base/at_exit.h>
#include <base/bind.h>
#include <base/threading/thread.h>
#include <errno.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_gatt.h>

#include <string>

#include "bta_api.h"
#include "bta_gatt_api.h"
#include "btif_common.h"
#include "btif_config.h"
#include "btif_dm.h"
#include "btif_gatt.h"
#include "btif_gatt_util.h"
#include "btif_storage.h"
#include "btif_util.h"
#include "device/include/controller.h"
#include "osi/include/log.h"
#include "stack/include/acl_api.h"
#include "stack/include/acl_api_types.h"
#include "stack/include/btu.h"
#include "types/bt_transport.h"
#include "vendor_api.h"

using base::Bind;
using base::Owned;
using bluetooth::Uuid;
using std::vector;

extern bt_status_t btif_gattc_test_command_impl(
    int command, const btgatt_test_params_t* params);
extern const btgatt_callbacks_t* bt_gatt_callbacks;

/*******************************************************************************
 *  Constants & Macros
 ******************************************************************************/

#define CLI_CBACK_IN_JNI(P_CBACK, ...)                                         \
  do {                                                                         \
    if (bt_gatt_callbacks && bt_gatt_callbacks->client->P_CBACK) {             \
      BTIF_TRACE_API("HAL bt_gatt_callbacks->client->%s", #P_CBACK);           \
      do_in_jni_thread(Bind(bt_gatt_callbacks->client->P_CBACK, __VA_ARGS__)); \
    } else {                                                                   \
      ASSERTC(0, "Callback is NULL", 0);                                       \
    }                                                                          \
  } while (0)

#define CHECK_BTGATT_INIT()                             \
  do {                                                  \
    if (bt_gatt_callbacks == NULL) {                    \
      LOG_WARN("%s: BTGATT not initialized", __func__); \
      return BT_STATUS_NOT_READY;                       \
    } else {                                            \
      LOG_VERBOSE("%s", __func__);                      \
    }                                                   \
  } while (0)

namespace {

uint8_t rssi_request_client_if;

std::string bta_gattc_event_text(const tBTA_GATTC_EVT& event) {
  switch (event) {
    case BTA_GATTC_DEREG_EVT:
      return std::string("GATT client deregistered");
    case BTA_GATTC_OPEN_EVT:
      return std::string("GATTC open request status");
    case BTA_GATTC_CLOSE_EVT:
      return std::string("GATTC close request status");
    case BTA_GATTC_SEARCH_CMPL_EVT:
      return std::string("GATT discovery complete");
    case BTA_GATTC_SEARCH_RES_EVT:
      return std::string("GATT discovery result");
    case BTA_GATTC_SRVC_DISC_DONE_EVT:
      return std::string("GATT service discovery done");
    case BTA_GATTC_NOTIF_EVT:
      return std::string("GATT attribute notification");
    case BTA_GATTC_EXEC_EVT:
      return std::string("execute write complete");
    case BTA_GATTC_ACL_EVT:
      return std::string("ACL up");
    case BTA_GATTC_CANCEL_OPEN_EVT:
      return std::string("cancel open");
    case BTA_GATTC_SRVC_CHG_EVT:
      return std::string("service change");
    case BTA_GATTC_ENC_CMPL_CB_EVT:
      return std::string("encryption complete callback");
    case BTA_GATTC_CFG_MTU_EVT:
      return std::string("configure MTU complete");
    case BTA_GATTC_CONGEST_EVT:
      return std::string("congestion");
    case BTA_GATTC_PHY_UPDATE_EVT:
      return std::string("PHY change");
    case BTA_GATTC_CONN_UPDATE_EVT:
      return std::string("connection parameters update");
  }
}

static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) {
  LOG_DEBUG("Event %s [%d]",
            bta_gattc_event_text(static_cast<tBTA_GATTC_EVT>(event)).c_str(),
            event);

  tBTA_GATTC* p_data = (tBTA_GATTC*)p_param;
  switch (event) {
    case BTA_GATTC_EXEC_EVT: {
      HAL_CBACK(bt_gatt_callbacks, client->execute_write_cb,
                p_data->exec_cmpl.conn_id, p_data->exec_cmpl.status);
      break;
    }

    case BTA_GATTC_SEARCH_CMPL_EVT: {
      HAL_CBACK(bt_gatt_callbacks, client->search_complete_cb,
                p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
      break;
    }

    case BTA_GATTC_NOTIF_EVT: {
      btgatt_notify_params_t data;

      data.bda = p_data->notify.bda;
      memcpy(data.value, p_data->notify.value, p_data->notify.len);

      data.handle = p_data->notify.handle;
      data.is_notify = p_data->notify.is_notify;
      data.len = p_data->notify.len;

      HAL_CBACK(bt_gatt_callbacks, client->notify_cb, p_data->notify.conn_id,
                data);

      if (!p_data->notify.is_notify)
        BTA_GATTC_SendIndConfirm(p_data->notify.conn_id, p_data->notify.cid);

      break;
    }

    case BTA_GATTC_OPEN_EVT: {
      DVLOG(1) << "BTA_GATTC_OPEN_EVT " << p_data->open.remote_bda;
      HAL_CBACK(bt_gatt_callbacks, client->open_cb, p_data->open.conn_id,
                p_data->open.status, p_data->open.client_if,
                p_data->open.remote_bda);

      if (GATT_DEF_BLE_MTU_SIZE != p_data->open.mtu && p_data->open.mtu) {
        HAL_CBACK(bt_gatt_callbacks, client->configure_mtu_cb,
                  p_data->open.conn_id, p_data->open.status, p_data->open.mtu);
      }

      if (p_data->open.status == GATT_SUCCESS)
        btif_gatt_check_encrypted_link(p_data->open.remote_bda,
                                       p_data->open.transport);
      break;
    }

    case BTA_GATTC_CLOSE_EVT: {
      HAL_CBACK(bt_gatt_callbacks, client->close_cb, p_data->close.conn_id,
                p_data->close.status, p_data->close.client_if,
                p_data->close.remote_bda);
      break;
    }

    case BTA_GATTC_ACL_EVT:
    case BTA_GATTC_DEREG_EVT:
    case BTA_GATTC_SEARCH_RES_EVT:
    case BTA_GATTC_CANCEL_OPEN_EVT:
    case BTA_GATTC_SRVC_DISC_DONE_EVT:
      LOG_DEBUG("Ignoring event (%d)", event);
      break;

    case BTA_GATTC_CFG_MTU_EVT: {
      HAL_CBACK(bt_gatt_callbacks, client->configure_mtu_cb,
                p_data->cfg_mtu.conn_id, p_data->cfg_mtu.status,
                p_data->cfg_mtu.mtu);
      break;
    }

    case BTA_GATTC_CONGEST_EVT:
      HAL_CBACK(bt_gatt_callbacks, client->congestion_cb,
                p_data->congest.conn_id, p_data->congest.congested);
      break;

    case BTA_GATTC_PHY_UPDATE_EVT:
      HAL_CBACK(bt_gatt_callbacks, client->phy_updated_cb,
                p_data->phy_update.conn_id, p_data->phy_update.tx_phy,
                p_data->phy_update.rx_phy, p_data->phy_update.status);
      break;

    case BTA_GATTC_CONN_UPDATE_EVT:
      HAL_CBACK(bt_gatt_callbacks, client->conn_updated_cb,
                p_data->conn_update.conn_id, p_data->conn_update.interval,
                p_data->conn_update.latency, p_data->conn_update.timeout,
                p_data->conn_update.status);
      break;

    case BTA_GATTC_SRVC_CHG_EVT:
      HAL_CBACK(bt_gatt_callbacks, client->service_changed_cb,
                p_data->service_changed.conn_id);
      break;

    default:
      LOG_ERROR("Unhandled event (%d)!", event);
      break;
  }
}

static void bta_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
  LOG_DEBUG(" gatt client callback event:%s [%d]",
            gatt_client_event_text(event).c_str(), event);
  bt_status_t status =
      btif_transfer_context(btif_gattc_upstreams_evt, (uint16_t)event,
                            (char*)p_data, sizeof(tBTA_GATTC), NULL);
  ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
}

void btm_read_rssi_cb(void* p_void) {
  tBTM_RSSI_RESULT* p_result = (tBTM_RSSI_RESULT*)p_void;

  if (!p_result) return;

  CLI_CBACK_IN_JNI(read_remote_rssi_cb, rssi_request_client_if,
                   p_result->rem_bda, p_result->rssi, p_result->status);
}

/*******************************************************************************
 *  Client API Functions
 ******************************************************************************/

static bt_status_t btif_gattc_register_app(const Uuid& uuid,
                                           bool eatt_support) {
  CHECK_BTGATT_INIT();

  return do_in_jni_thread(Bind(
      [](const Uuid& uuid, bool eatt_support) {
        BTA_GATTC_AppRegister(
            bta_gattc_cback,
            base::Bind(
                [](const Uuid& uuid, uint8_t client_id, uint8_t status) {
                  do_in_jni_thread(Bind(
                      [](const Uuid& uuid, uint8_t client_id, uint8_t status) {
                        HAL_CBACK(bt_gatt_callbacks, client->register_client_cb,
                                  status, client_id, uuid);
                      },
                      uuid, client_id, status));
                },
                uuid),
            eatt_support);
      },
      uuid, eatt_support));
}

static void btif_gattc_unregister_app_impl(int client_if) {
  BTA_GATTC_AppDeregister(client_if);
}

static bt_status_t btif_gattc_unregister_app(int client_if) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(Bind(&btif_gattc_unregister_app_impl, client_if));
}

void btif_gattc_open_impl(int client_if, RawAddress address, bool is_direct,
                          int transport_p, bool opportunistic,
                          int initiating_phys) {
  // Ensure device is in inquiry database
  tBLE_ADDR_TYPE addr_type = BLE_ADDR_PUBLIC;
  int device_type = 0;
  tBT_TRANSPORT transport = (tBT_TRANSPORT)BT_TRANSPORT_LE;

  if (btif_get_address_type(address, &addr_type) &&
      btif_get_device_type(address, &device_type) &&
      device_type != BT_DEVICE_TYPE_BREDR) {
    BTA_DmAddBleDevice(address, addr_type, device_type);
  }

  // Check for background connections
  if (!is_direct) {
    // Check for privacy 1.0 and 1.1 controller and do not start background
    // connection if RPA offloading is not supported, since it will not
    // connect after change of random address
    if (!controller_get_interface()->supports_ble_privacy() &&
        (addr_type == BLE_ADDR_RANDOM) && BTM_BLE_IS_RESOLVE_BDA(address)) {
      tBTM_BLE_VSC_CB vnd_capabilities;
      BTM_BleGetVendorCapabilities(&vnd_capabilities);
      if (!vnd_capabilities.rpa_offloading) {
        HAL_CBACK(bt_gatt_callbacks, client->open_cb, 0, BT_STATUS_UNSUPPORTED,
                  client_if, address);
        return;
      }
    }
  }

  // Determine transport
  if (transport_p != BT_TRANSPORT_AUTO) {
    transport = transport_p;
  } else {
    switch (device_type) {
      case BT_DEVICE_TYPE_BREDR:
        transport = BT_TRANSPORT_BR_EDR;
        break;

      case BT_DEVICE_TYPE_BLE:
        transport = BT_TRANSPORT_LE;
        break;

      case BT_DEVICE_TYPE_DUMO:
        if (transport_p == BT_TRANSPORT_LE)
          transport = BT_TRANSPORT_LE;
        else
          transport = BT_TRANSPORT_BR_EDR;
        break;
    }
  }

  // Connect!
  BTIF_TRACE_DEBUG("%s Transport=%d, device type=%d, phy=%d", __func__,
                   transport, device_type, initiating_phys);
  BTA_GATTC_Open(client_if, address, is_direct, transport, opportunistic,
                 initiating_phys);
}

static bt_status_t btif_gattc_open(int client_if, const RawAddress& bd_addr,
                                   bool is_direct, int transport,
                                   bool opportunistic, int initiating_phys) {
  CHECK_BTGATT_INIT();
  // Closure will own this value and free it.
  return do_in_jni_thread(Bind(&btif_gattc_open_impl, client_if, bd_addr,
                               is_direct, transport, opportunistic,
                               initiating_phys));
}

void btif_gattc_close_impl(int client_if, RawAddress address, int conn_id) {
  // Disconnect established connections
  if (conn_id != 0)
    BTA_GATTC_Close(conn_id);
  else
    BTA_GATTC_CancelOpen(client_if, address, true);

  // Cancel pending background connections (remove from acceptlist)
  BTA_GATTC_CancelOpen(client_if, address, false);
}

static bt_status_t btif_gattc_close(int client_if, const RawAddress& bd_addr,
                                    int conn_id) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(
      Bind(&btif_gattc_close_impl, client_if, bd_addr, conn_id));
}

static bt_status_t btif_gattc_refresh(int client_if,
                                      const RawAddress& bd_addr) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(Bind(&BTA_GATTC_Refresh, bd_addr));
}

static bt_status_t btif_gattc_search_service(int conn_id,
                                             const Uuid* filter_uuid) {
  CHECK_BTGATT_INIT();

  if (filter_uuid) {
    Uuid* uuid = new Uuid(*filter_uuid);
    return do_in_jni_thread(
        Bind(&BTA_GATTC_ServiceSearchRequest, conn_id, base::Owned(uuid)));
  } else {
    return do_in_jni_thread(
        Bind(&BTA_GATTC_ServiceSearchRequest, conn_id, nullptr));
  }
}

static void btif_gattc_discover_service_by_uuid(int conn_id, const Uuid& uuid) {
  do_in_jni_thread(Bind(&BTA_GATTC_DiscoverServiceByUuid, conn_id, uuid));
}

void btif_gattc_get_gatt_db_impl(int conn_id) {
  btgatt_db_element_t* db = NULL;
  int count = 0;
  BTA_GATTC_GetGattDb(conn_id, 0x0000, 0xFFFF, &db, &count);

  HAL_CBACK(bt_gatt_callbacks, client->get_gatt_db_cb, conn_id, db, count);
  osi_free(db);
}

static bt_status_t btif_gattc_get_gatt_db(int conn_id) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(Bind(&btif_gattc_get_gatt_db_impl, conn_id));
}

void read_char_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
                  uint16_t len, uint8_t* value, void* data) {
  btgatt_read_params_t* params = new btgatt_read_params_t;
  params->value_type = 0x00 /* GATTC_READ_VALUE_TYPE_VALUE */;
  params->status = status;
  params->handle = handle;
  params->value.len = len;
  CHECK(len <= BTGATT_MAX_ATTR_LEN);
  if (len > 0) memcpy(params->value.value, value, len);

  // clang-tidy analyzer complains about |params| is leaked.  It doesn't know
  // that |param| will be freed by the callback function.
  CLI_CBACK_IN_JNI(read_characteristic_cb, conn_id, status, /* NOLINT */
                   base::Owned(params));
}

static bt_status_t btif_gattc_read_char(int conn_id, uint16_t handle,
                                        int auth_req) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(Bind(&BTA_GATTC_ReadCharacteristic, conn_id, handle,
                               auth_req, read_char_cb, nullptr));
}

void read_using_char_uuid_cb(uint16_t conn_id, tGATT_STATUS status,
                             uint16_t handle, uint16_t len, uint8_t* value,
                             void* data) {
  btgatt_read_params_t* params = new btgatt_read_params_t;
  params->value_type = 0x00 /* GATTC_READ_VALUE_TYPE_VALUE */;
  params->status = status;
  params->handle = handle;
  params->value.len = len;
  CHECK(len <= BTGATT_MAX_ATTR_LEN);
  if (len > 0) memcpy(params->value.value, value, len);

  // clang-tidy analyzer complains about |params| is leaked.  It doesn't know
  // that |param| will be freed by the callback function.
  CLI_CBACK_IN_JNI(read_characteristic_cb, conn_id, status, /* NOLINT */
                   base::Owned(params));
}

static bt_status_t btif_gattc_read_using_char_uuid(int conn_id,
                                                   const Uuid& uuid,
                                                   uint16_t s_handle,
                                                   uint16_t e_handle,
                                                   int auth_req) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(Bind(&BTA_GATTC_ReadUsingCharUuid, conn_id, uuid,
                               s_handle, e_handle, auth_req,
                               read_using_char_uuid_cb, nullptr));
}

void read_desc_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
                  uint16_t len, uint8_t* value, void* data) {
  btgatt_read_params_t params;
  params.value_type = 0x00 /* GATTC_READ_VALUE_TYPE_VALUE */;
  params.status = status;
  params.handle = handle;
  params.value.len = len;
  CHECK(len <= BTGATT_MAX_ATTR_LEN);
  if (len > 0) memcpy(params.value.value, value, len);

  CLI_CBACK_IN_JNI(read_descriptor_cb, conn_id, status, params);
}

static bt_status_t btif_gattc_read_char_descr(int conn_id, uint16_t handle,
                                              int auth_req) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(Bind(&BTA_GATTC_ReadCharDescr, conn_id, handle,
                               auth_req, read_desc_cb, nullptr));
}

void write_char_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
                   void* data) {
  CLI_CBACK_IN_JNI(write_characteristic_cb, conn_id, status, handle);
}

static bt_status_t btif_gattc_write_char(int conn_id, uint16_t handle,
                                         int write_type, int auth_req,
                                         vector<uint8_t> value) {
  CHECK_BTGATT_INIT();

  if (value.size() > BTGATT_MAX_ATTR_LEN) value.resize(BTGATT_MAX_ATTR_LEN);

  return do_in_jni_thread(Bind(&BTA_GATTC_WriteCharValue, conn_id, handle,
                               write_type, std::move(value), auth_req,
                               write_char_cb, nullptr));
}

void write_descr_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
                    void* data) {
  CLI_CBACK_IN_JNI(write_descriptor_cb, conn_id, status, handle);
}

static bt_status_t btif_gattc_write_char_descr(int conn_id, uint16_t handle,
                                               int auth_req,
                                               vector<uint8_t> value) {
  CHECK_BTGATT_INIT();

  if (value.size() > BTGATT_MAX_ATTR_LEN) value.resize(BTGATT_MAX_ATTR_LEN);

  return do_in_jni_thread(Bind(&BTA_GATTC_WriteCharDescr, conn_id, handle,
                               std::move(value), auth_req, write_descr_cb,
                               nullptr));
}

static bt_status_t btif_gattc_execute_write(int conn_id, int execute) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(
      Bind(&BTA_GATTC_ExecuteWrite, conn_id, (uint8_t)execute));
}

static void btif_gattc_reg_for_notification_impl(tGATT_IF client_if,
                                                 const RawAddress& bda,
                                                 uint16_t handle) {
  tGATT_STATUS status =
      BTA_GATTC_RegisterForNotifications(client_if, bda, handle);

  // TODO(jpawlowski): conn_id is currently unused
  HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
            /* conn_id */ 0, 1, status, handle);
}

bt_status_t btif_gattc_reg_for_notification(int client_if,
                                            const RawAddress& bd_addr,
                                            uint16_t handle) {
  CHECK_BTGATT_INIT();

  return do_in_jni_thread(
      Bind(base::IgnoreResult(&btif_gattc_reg_for_notification_impl), client_if,
           bd_addr, handle));
}

static void btif_gattc_dereg_for_notification_impl(tGATT_IF client_if,
                                                   const RawAddress& bda,
                                                   uint16_t handle) {
  tGATT_STATUS status =
      BTA_GATTC_DeregisterForNotifications(client_if, bda, handle);

  // TODO(jpawlowski): conn_id is currently unused
  HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
            /* conn_id */ 0, 0, status, handle);
}

bt_status_t btif_gattc_dereg_for_notification(int client_if,
                                              const RawAddress& bd_addr,
                                              uint16_t handle) {
  CHECK_BTGATT_INIT();

  return do_in_jni_thread(
      Bind(base::IgnoreResult(&btif_gattc_dereg_for_notification_impl),
           client_if, bd_addr, handle));
}

static bt_status_t btif_gattc_read_remote_rssi(int client_if,
                                               const RawAddress& bd_addr) {
  CHECK_BTGATT_INIT();
  rssi_request_client_if = client_if;

  return do_in_jni_thread(
      Bind(base::IgnoreResult(&BTM_ReadRSSI), bd_addr, btm_read_rssi_cb));
}

static bt_status_t btif_gattc_configure_mtu(int conn_id, int mtu) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(
      Bind(base::IgnoreResult(
        static_cast<void (*)(uint16_t,uint16_t)>(&BTA_GATTC_ConfigureMTU)),
        conn_id, mtu));
}

static void btif_gattc_conn_parameter_update_impl(
    RawAddress addr, int min_interval, int max_interval, int latency,
    int timeout, uint16_t min_ce_len, uint16_t max_ce_len) {
  if (BTA_DmGetConnectionState(addr))
    BTA_DmBleUpdateConnectionParams(addr, min_interval, max_interval, latency,
                                    timeout, min_ce_len, max_ce_len);
  else
    BTA_DmSetBlePrefConnParams(addr, min_interval, max_interval, latency,
                               timeout);
}

bt_status_t btif_gattc_conn_parameter_update(const RawAddress& bd_addr,
                                             int min_interval, int max_interval,
                                             int latency, int timeout,
                                             uint16_t min_ce_len,
                                             uint16_t max_ce_len) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(Bind(
      base::IgnoreResult(&btif_gattc_conn_parameter_update_impl), bd_addr,
      min_interval, max_interval, latency, timeout, min_ce_len, max_ce_len));
}

static bt_status_t btif_gattc_set_preferred_phy(const RawAddress& bd_addr,
                                                uint8_t tx_phy, uint8_t rx_phy,
                                                uint16_t phy_options) {
  CHECK_BTGATT_INIT();
  do_in_main_thread(FROM_HERE,
                    Bind(&BTM_BleSetPhy, bd_addr, tx_phy, rx_phy, phy_options));
  return BT_STATUS_SUCCESS;
}

static bt_status_t btif_gattc_read_phy(
    const RawAddress& bd_addr,
    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
  CHECK_BTGATT_INIT();
  do_in_main_thread(FROM_HERE, Bind(&BTM_BleReadPhy, bd_addr,
                                    jni_thread_wrapper(FROM_HERE, cb)));
  return BT_STATUS_SUCCESS;
}

static int btif_gattc_get_device_type(const RawAddress& bd_addr) {
  int device_type = 0;

  if (btif_config_get_int(bd_addr.ToString().c_str(), "DevType", &device_type))
    return device_type;
  return 0;
}

static bt_status_t btif_gattc_test_command(int command,
                                           const btgatt_test_params_t& params) {
  return btif_gattc_test_command_impl(command, &params);
}

}  // namespace

const btgatt_client_interface_t btgattClientInterface = {
    btif_gattc_register_app,
    btif_gattc_unregister_app,
    btif_gattc_open,
    btif_gattc_close,
    btif_gattc_refresh,
    btif_gattc_search_service,
    btif_gattc_discover_service_by_uuid,
    btif_gattc_read_char,
    btif_gattc_read_using_char_uuid,
    btif_gattc_write_char,
    btif_gattc_read_char_descr,
    btif_gattc_write_char_descr,
    btif_gattc_execute_write,
    btif_gattc_reg_for_notification,
    btif_gattc_dereg_for_notification,
    btif_gattc_read_remote_rssi,
    btif_gattc_get_device_type,
    btif_gattc_configure_mtu,
    btif_gattc_conn_parameter_update,
    btif_gattc_set_preferred_phy,
    btif_gattc_read_phy,
    btif_gattc_test_command,
    btif_gattc_get_gatt_db};
