/******************************************************************************
 *
 *  Copyright (C) 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 <stdlib.h>
#include <string.h>
#include "device/include/controller.h"

#include "btcore/include/bdaddr.h"
#include "btif_common.h"
#include "btif_util.h"

#include <hardware/bt_gatt.h>

#include "bta_api.h"
#include "bta_closure_api.h"
#include "bta_gatt_api.h"
#include "btif_config.h"
#include "btif_dm.h"
#include "btif_gatt.h"
#include "btif_gatt_util.h"
#include "btif_storage.h"
#include "osi/include/log.h"
#include "vendor_api.h"

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

extern bt_status_t btif_gattc_test_command_impl(int command,
                                                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(LOG_TAG, "%s: BTGATT not initialized", __func__); \
      return BT_STATUS_NOT_READY;                                \
    } else {                                                     \
      LOG_VERBOSE(LOG_TAG, "%s", __func__);                      \
    }                                                            \
  } while (0)

#define BLE_RESOLVE_ADDR_MSB                                                   \
  0x40                             /* bit7, bit6 is 01 to be resolvable random \
                                      */
#define BLE_RESOLVE_ADDR_MASK 0xc0 /* bit 6, and bit7 */
#define BTM_BLE_IS_RESOLVE_BDA(x) \
  (((x)[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB)

namespace {

uint8_t rssi_request_client_if;

void btif_gattc_upstreams_evt(uint16_t event, char* p_param) {
  LOG_VERBOSE(LOG_TAG, "%s: Event %d", __func__, event);

  tBTA_GATTC* p_data = (tBTA_GATTC*)p_param;
  switch (event) {
    case BTA_GATTC_DEREG_EVT:
      break;

    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;

      bdcpy(data.bda.address, 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 == false)
        BTA_GATTC_SendIndConfirm(p_data->notify.conn_id, p_data->notify.handle);

      break;
    }

    case BTA_GATTC_OPEN_EVT: {
      bt_bdaddr_t bda;
      bdcpy(bda.address, 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, &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 == BTA_GATT_OK)
        btif_gatt_check_encrypted_link(p_data->open.remote_bda,
                                       p_data->open.transport);
      break;
    }

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

    case BTA_GATTC_ACL_EVT:
      LOG_DEBUG(LOG_TAG, "BTA_GATTC_ACL_EVT: status = %d", p_data->status);
      /* Ignore for now */
      break;

    case BTA_GATTC_CANCEL_OPEN_EVT:
      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;

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

void bta_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
  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(tBTM_RSSI_RESULTS* p_result) {
  if (!p_result) return;

  bt_bdaddr_t* addr = new bt_bdaddr_t;
  bdcpy(addr->address, p_result->rem_bda);
  CLI_CBACK_IN_JNI(read_remote_rssi_cb, rssi_request_client_if,
                   base::Owned(addr), p_result->rssi, p_result->status);
}

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

bt_status_t btif_gattc_register_app(bt_uuid_t* uuid) {
  CHECK_BTGATT_INIT();

  tBT_UUID bt_uuid;
  btif_to_bta_uuid(&bt_uuid, uuid);

  return do_in_jni_thread(Bind(
      [](tBT_UUID bt_uuid) {
        BTA_GATTC_AppRegister(
            bta_gattc_cback,
            base::Bind(
                [](tBT_UUID bt_uuid, uint8_t client_id, uint8_t status) {
                  do_in_jni_thread(Bind(
                      [](tBT_UUID bt_uuid, uint8_t client_id, uint8_t status) {
                        bt_uuid_t app_uuid;
                        bta_to_btif_uuid(&app_uuid, &bt_uuid);
                        HAL_CBACK(bt_gatt_callbacks, client->register_client_cb,
                                  status, client_id, &app_uuid);
                      },
                      bt_uuid, client_id, status));
                },
                bt_uuid));
      },
      bt_uuid));
}

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

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, BD_ADDR address, bool is_direct,
                          int transport_p, int initiating_phys) {
  // Ensure device is in inquiry database
  int addr_type = 0;
  int device_type = 0;
  tBTA_GATT_TRANSPORT transport = (tBTA_GATT_TRANSPORT)BTA_GATT_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, (bt_bdaddr_t*)&address);
        return;
      }
    }
    BTA_DmBleStartAutoConn();
  }

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

      case BT_DEVICE_TYPE_BLE:
        transport = BTA_GATT_TRANSPORT_LE;
        break;

      case BT_DEVICE_TYPE_DUMO:
        if (transport == GATT_TRANSPORT_LE)
          transport = BTA_GATT_TRANSPORT_LE;
        else
          transport = BTA_GATT_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, initiating_phys);
}

bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t* bd_addr,
                            bool is_direct, int transport,
                            int initiating_phys) {
  CHECK_BTGATT_INIT();
  // Closure will own this value and free it.
  uint8_t* address = new BD_ADDR;
  bdcpy(address, bd_addr->address);
  return do_in_jni_thread(Bind(&btif_gattc_open_impl, client_if,
                               base::Owned(address), is_direct, transport,
                               initiating_phys));
}

void btif_gattc_close_impl(int client_if, BD_ADDR 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 whitelist)
  BTA_GATTC_CancelOpen(client_if, address, false);
}

bt_status_t btif_gattc_close(int client_if, const bt_bdaddr_t* bd_addr,
                             int conn_id) {
  CHECK_BTGATT_INIT();
  // Closure will own this value and free it.
  uint8_t* address = new BD_ADDR;
  bdcpy(address, bd_addr->address);
  return do_in_jni_thread(
      Bind(&btif_gattc_close_impl, client_if, base::Owned(address), conn_id));
}

bt_status_t btif_gattc_refresh(int client_if, const bt_bdaddr_t* bd_addr) {
  CHECK_BTGATT_INIT();
  // Closure will own this value and free it.
  uint8_t* address = new BD_ADDR;
  bdcpy(address, bd_addr->address);
  return do_in_jni_thread(Bind(&BTA_GATTC_Refresh, base::Owned(address)));
}

bt_status_t btif_gattc_search_service(int conn_id, bt_uuid_t* filter_uuid) {
  CHECK_BTGATT_INIT();

  if (filter_uuid) {
    tBT_UUID* uuid = new tBT_UUID;
    btif_to_bta_uuid(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));
  }
}

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);
}

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);

  CLI_CBACK_IN_JNI(read_characteristic_cb, conn_id, status,
                   base::Owned(params));
}

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);

  CLI_CBACK_IN_JNI(read_characteristic_cb, conn_id, status,
                   base::Owned(params));
}

bt_status_t btif_gattc_read_using_char_uuid(int conn_id, bt_uuid_t* uuid,
                                            uint16_t s_handle,
                                            uint16_t e_handle, int auth_req) {
  CHECK_BTGATT_INIT();
  tBT_UUID bt_uuid;
  btif_to_bta_uuid(&bt_uuid, uuid);
  return do_in_jni_thread(Bind(&BTA_GATTC_ReadUsingCharUuid, conn_id, bt_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 = 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);

  CLI_CBACK_IN_JNI(read_descriptor_cb, conn_id, status, base::Owned(params));
}

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);
}

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);
}

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));
}

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));
}

void btif_gattc_reg_for_notification_impl(tBTA_GATTC_IF client_if,
                                          const BD_ADDR bda, uint16_t handle) {
  tBTA_GATT_STATUS status = BTA_GATTC_RegisterForNotifications(
      client_if, const_cast<uint8_t*>(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 bt_bdaddr_t* bd_addr,
                                            uint16_t handle) {
  CHECK_BTGATT_INIT();

  uint8_t* address = new BD_ADDR;
  bdcpy(address, bd_addr->address);
  return do_in_jni_thread(
      Bind(base::IgnoreResult(&btif_gattc_reg_for_notification_impl), client_if,
           base::Owned(address), handle));
}

void btif_gattc_dereg_for_notification_impl(tBTA_GATTC_IF client_if,
                                            const BD_ADDR bda,
                                            uint16_t handle) {
  tBTA_GATT_STATUS status = BTA_GATTC_DeregisterForNotifications(
      client_if, const_cast<uint8_t*>(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 bt_bdaddr_t* bd_addr,
                                              uint16_t handle) {
  CHECK_BTGATT_INIT();

  uint8_t* address = new BD_ADDR;
  bdcpy(address, bd_addr->address);
  return do_in_jni_thread(
      Bind(base::IgnoreResult(&btif_gattc_dereg_for_notification_impl),
           client_if, base::Owned(address), handle));
}

bt_status_t btif_gattc_read_remote_rssi(int client_if,
                                        const bt_bdaddr_t* bd_addr) {
  CHECK_BTGATT_INIT();
  rssi_request_client_if = client_if;
  // Closure will own this value and free it.
  uint8_t* address = new BD_ADDR;
  bdcpy(address, bd_addr->address);
  return do_in_jni_thread(Bind(base::IgnoreResult(&BTM_ReadRSSI),
                               base::Owned(address),
                               (tBTM_CMPL_CB*)btm_read_rssi_cb));
}

bt_status_t btif_gattc_configure_mtu(int conn_id, int mtu) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(
      Bind(base::IgnoreResult(&BTA_GATTC_ConfigureMTU), conn_id, mtu));
}

void btif_gattc_conn_parameter_update_impl(bt_bdaddr_t addr, int min_interval,
                                           int max_interval, int latency,
                                           int timeout) {
  if (BTA_DmGetConnectionState(addr.address))
    BTA_DmBleUpdateConnectionParams(addr.address, min_interval, max_interval,
                                    latency, timeout);
  else
    BTA_DmSetBlePrefConnParams(addr.address, min_interval, max_interval,
                               latency, timeout);
}

bt_status_t btif_gattc_conn_parameter_update(const bt_bdaddr_t* bd_addr,
                                             int min_interval, int max_interval,
                                             int latency, int timeout) {
  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));
}

bt_status_t btif_gattc_set_preferred_phy(int conn_id, uint8_t tx_phy,
                                         uint8_t rx_phy, uint16_t phy_options) {
  CHECK_BTGATT_INIT();
  do_in_bta_thread(FROM_HERE, Bind(&GATTC_SetPreferredPHY, conn_id, tx_phy,
                                   rx_phy, phy_options));
  return BT_STATUS_SUCCESS;
}

bt_status_t btif_gattc_read_phy(
    int conn_id,
    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
  CHECK_BTGATT_INIT();
  do_in_bta_thread(FROM_HERE, Bind(&GATTC_ReadPHY, conn_id,
                                   jni_thread_wrapper(FROM_HERE, cb)));
  return BT_STATUS_SUCCESS;
}

int btif_gattc_get_device_type(const bt_bdaddr_t* bd_addr) {
  int device_type = 0;
  char bd_addr_str[18] = {0};

  bdaddr_to_string(bd_addr, bd_addr_str, sizeof(bd_addr_str));
  if (btif_config_get_int(bd_addr_str, "DevType", &device_type))
    return device_type;
  return 0;
}

bt_status_t btif_gattc_test_command(int command, 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_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};
