Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7032d1e7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Separate LE scanner and GATT client BTIF interfaces (3/3)"

parents fab3be33 8cb96fda
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ btifCommonSrc += \
  src/btif_av.cc \
  src/btif_avrcp_audio_track.cc \
  src/btif_ble_advertiser.cc \
  src/btif_ble_scanner.cc \
  src/btif_config.cc \
  src/btif_config_transcode.cc \
  src/btif_core.cc \
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ static_library("btif") {
    #TODO(jpawlowski): heavily depends on Android,
    #   "src/btif_avrcp_audio_track.cc",
    "src/btif_ble_advertiser.cc",
    "src/btif_ble_scanner.cc",
    "src/btif_config.cc",
    "src/btif_config_transcode.cc",
    "src/btif_core.cc",
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@

extern const btgatt_client_interface_t btgattClientInterface;
extern const btgatt_server_interface_t btgattServerInterface;
extern const btgatt_scanner_interface_t btgattScannerInterface;

BleAdvertiserInterface* get_ble_advertiser_instance();
#endif
+668 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright (C) 2016 The Android Open Source Project
 *
 *  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.
 *
 ******************************************************************************/

#define LOG_TAG "bt_btif_scanner"

#include <base/bind.h>
#include <base/threading/thread.h>
#include <errno.h>
#include <hardware/bluetooth.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unordered_set>
#include "device/include/controller.h"

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

#if (BLE_INCLUDED == TRUE)

#include <hardware/bt_gatt.h>

#include "bta_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 do_in_jni_thread(const base::Closure& task);
extern const btgatt_callbacks_t* bt_gatt_callbacks;

#define  SCAN_CBACK_IN_JNI(P_CBACK, ...)                                       \
  do {                                                                         \
    if (bt_gatt_callbacks && bt_gatt_callbacks->scanner->P_CBACK) {            \
      BTIF_TRACE_API("HAL bt_gatt_callbacks->client->%s", #P_CBACK);           \
      do_in_jni_thread(Bind(bt_gatt_callbacks->scanner->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)

namespace std {
template <>
struct hash<bt_bdaddr_t> {
  size_t operator()(const bt_bdaddr_t& f) const {
    return f.address[0] + f.address[1] + f.address[2] + f.address[3] +
           f.address[4] + f.address[5];
  }
};

template <>
struct equal_to<bt_bdaddr_t> {
  size_t operator()(const bt_bdaddr_t& x, const bt_bdaddr_t& y) const {
    return memcmp(x.address, y.address, BD_ADDR_LEN);
  }
};
}

namespace {

std::unordered_set<bt_bdaddr_t> p_dev_cb;

void btif_gattc_add_remote_bdaddr(BD_ADDR p_bda, uint8_t addr_type) {
  bt_bdaddr_t bd_addr;
  memcpy(bd_addr.address, p_bda, BD_ADDR_LEN);
  p_dev_cb.insert(bd_addr);
}

bool btif_gattc_find_bdaddr(BD_ADDR p_bda) {
  bt_bdaddr_t bd_addr;
  memcpy(bd_addr.address, p_bda, BD_ADDR_LEN);
  return (p_dev_cb.count(bd_addr) != 0);
}

void btif_gattc_init_dev_cb(void) { p_dev_cb.clear(); }

btgattc_error_t btif_gattc_translate_btm_status(tBTM_STATUS status) {
  switch (status) {
    case BTM_SUCCESS:
    case BTM_SUCCESS_NO_SECURITY:
      return BT_GATTC_COMMAND_SUCCESS;

    case BTM_CMD_STARTED:
      return BT_GATTC_COMMAND_STARTED;

    case BTM_BUSY:
      return BT_GATTC_COMMAND_BUSY;

    case BTM_CMD_STORED:
      return BT_GATTC_COMMAND_STORED;

    case BTM_NO_RESOURCES:
      return BT_GATTC_NO_RESOURCES;

    case BTM_MODE_UNSUPPORTED:
    case BTM_WRONG_MODE:
    case BTM_MODE4_LEVEL4_NOT_SUPPORTED:
      return BT_GATTC_MODE_UNSUPPORTED;

    case BTM_ILLEGAL_VALUE:
    case BTM_SCO_BAD_LENGTH:
      return BT_GATTC_ILLEGAL_VALUE;

    case BTM_UNKNOWN_ADDR:
      return BT_GATTC_UNKNOWN_ADDR;

    case BTM_DEVICE_TIMEOUT:
      return BT_GATTC_DEVICE_TIMEOUT;

    case BTM_FAILED_ON_SECURITY:
    case BTM_REPEATED_ATTEMPTS:
    case BTM_NOT_AUTHORIZED:
      return BT_GATTC_SECURITY_ERROR;

    case BTM_DEV_RESET:
    case BTM_ILLEGAL_ACTION:
      return BT_GATTC_INCORRECT_STATE;

    case BTM_BAD_VALUE_RET:
      return BT_GATTC_INVALID_CONTROLLER_OUTPUT;

    case BTM_DELAY_CHECK:
      return BT_GATTC_DELAYED_ENCRYPTION_CHECK;

    case BTM_ERR_PROCESSING:
    default:
      return BT_GATTC_ERR_PROCESSING;
  }
}

void btif_gatts_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_REG_EVT: {
      bt_uuid_t app_uuid;
      bta_to_btif_uuid(&app_uuid, &p_data->reg_oper.app_uuid);
      HAL_CBACK(bt_gatt_callbacks, scanner->register_scanner_cb,
                p_data->reg_oper.status, p_data->reg_oper.client_if, &app_uuid);
      break;
    }

    case BTA_GATTC_DEREG_EVT:
      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;
    }

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

void bta_gatts_cback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
  bt_status_t status =
      btif_transfer_context(btif_gatts_upstreams_evt, (uint16_t)event,
                            (char*)p_data, sizeof(tBTA_GATTC), NULL);
  ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
}

void bta_scan_param_setup_cb(tGATT_IF client_if, tBTM_STATUS status) {
  SCAN_CBACK_IN_JNI(scan_parameter_setup_completed_cb, client_if,
                   btif_gattc_translate_btm_status(status));
}

void bta_scan_filt_cfg_cb(tBTA_DM_BLE_PF_ACTION action,
                          tBTA_DM_BLE_SCAN_COND_OP cfg_op,
                          tBTA_DM_BLE_PF_AVBL_SPACE avbl_space,
                          tBTA_STATUS status, tBTA_DM_BLE_REF_VALUE ref_value) {
  SCAN_CBACK_IN_JNI(scan_filter_cfg_cb, action, ref_value, status, cfg_op,
                   avbl_space);
}

void bta_scan_filt_param_setup_cb(uint8_t action_type,
                                  tBTA_DM_BLE_PF_AVBL_SPACE avbl_space,
                                  tBTA_DM_BLE_REF_VALUE ref_value,
                                  tBTA_STATUS status) {
  SCAN_CBACK_IN_JNI(scan_filter_param_cb, action_type, ref_value, status,
                   avbl_space);
}

void bta_scan_filt_status_cb(uint8_t action, tBTA_STATUS status,
                             tBTA_DM_BLE_REF_VALUE ref_value) {
  SCAN_CBACK_IN_JNI(scan_filter_status_cb, action, ref_value, status);
}

void bta_batch_scan_setup_cb(tBTA_BLE_BATCH_SCAN_EVT evt,
                             tBTA_DM_BLE_REF_VALUE ref_value,
                             tBTA_STATUS status) {
  BTIF_TRACE_DEBUG("bta_batch_scan_setup_cb-Status:%x, client_if:%d, evt=%d",
                   status, ref_value, evt);

  switch (evt) {
    case BTA_BLE_BATCH_SCAN_ENB_EVT: {
      SCAN_CBACK_IN_JNI(batchscan_enb_disable_cb, 1, ref_value, status);
      return;
    }

    case BTA_BLE_BATCH_SCAN_DIS_EVT: {
      SCAN_CBACK_IN_JNI(batchscan_enb_disable_cb, 0, ref_value, status);
      return;
    }

    case BTA_BLE_BATCH_SCAN_CFG_STRG_EVT: {
      SCAN_CBACK_IN_JNI(batchscan_cfg_storage_cb, ref_value, status);
      return;
    }

    case BTA_BLE_BATCH_SCAN_DATA_EVT: {
      SCAN_CBACK_IN_JNI(batchscan_reports_cb, ref_value, status, 0, 0,
                       vector<uint8_t>());
      return;
    }

    case BTA_BLE_BATCH_SCAN_THRES_EVT: {
      SCAN_CBACK_IN_JNI(batchscan_threshold_cb, ref_value);
      return;
    }

    default:
      return;
  }
}

void bta_batch_scan_threshold_cb(tBTA_DM_BLE_REF_VALUE ref_value) {
  SCAN_CBACK_IN_JNI(batchscan_threshold_cb, ref_value);
}

void bta_batch_scan_reports_cb(tBTA_DM_BLE_REF_VALUE ref_value,
                               uint8_t report_format, uint8_t num_records,
                               uint16_t data_len, uint8_t* p_rep_data,
                               tBTA_STATUS status) {
  BTIF_TRACE_DEBUG("%s - client_if:%d, %d, %d, %d", __func__, ref_value, status,
                   num_records, data_len);

  if (data_len > 0) {
    vector<uint8_t> data(p_rep_data, p_rep_data + data_len);
    osi_free(p_rep_data);

    SCAN_CBACK_IN_JNI(batchscan_reports_cb, ref_value, status, report_format,
                     num_records, std::move(data));
  } else {
    SCAN_CBACK_IN_JNI(batchscan_reports_cb, ref_value, status, report_format,
                     num_records, vector<uint8_t>());
  }
}

void bta_scan_results_cb_impl(bt_bdaddr_t bd_addr, tBT_DEVICE_TYPE device_type,
                              int8_t rssi, uint8_t addr_type,
                              vector<uint8_t> value) {
  uint8_t remote_name_len;
  const uint8_t* p_eir_remote_name = NULL;
  bt_device_type_t dev_type;
  bt_property_t properties;

  p_eir_remote_name = BTM_CheckEirData(
      value.data(), BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);

  if (p_eir_remote_name == NULL) {
    p_eir_remote_name = BTM_CheckEirData(
        value.data(), BT_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len);
  }

  if ((addr_type != BLE_ADDR_RANDOM) || (p_eir_remote_name)) {
    if (!btif_gattc_find_bdaddr(bd_addr.address)) {
      btif_gattc_add_remote_bdaddr(bd_addr.address, addr_type);

      if (p_eir_remote_name) {
        bt_bdname_t bdname;
        memcpy(bdname.name, p_eir_remote_name, remote_name_len);
        bdname.name[remote_name_len] = '\0';

        LOG_VERBOSE(LOG_TAG, "%s BLE device name=%s len=%d dev_type=%d",
                    __func__, bdname.name, remote_name_len, device_type);
        btif_dm_update_ble_remote_properties(bd_addr.address, bdname.name,
                                             device_type);
      }
    }
  }

  dev_type = (bt_device_type_t)device_type;
  BTIF_STORAGE_FILL_PROPERTY(&properties, BT_PROPERTY_TYPE_OF_DEVICE,
                             sizeof(dev_type), &dev_type);
  btif_storage_set_remote_device_property(&(bd_addr), &properties);

  btif_storage_set_remote_addr_type(&bd_addr, addr_type);

  HAL_CBACK(bt_gatt_callbacks, scanner->scan_result_cb, &bd_addr, rssi,
            std::move(value));
}

void bta_scan_results_cb(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) {
  uint8_t len;

  if (event == BTA_DM_INQ_CMPL_EVT) {
    BTIF_TRACE_DEBUG("%s  BLE observe complete. Num Resp %d", __func__,
                     p_data->inq_cmpl.num_resps);
    return;
  }

  if (event != BTA_DM_INQ_RES_EVT) {
    BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __func__, event);
    return;
  }

  vector<uint8_t> value(BTGATT_MAX_ATTR_LEN);
  if (p_data->inq_res.p_eir) {
    value.insert(value.begin(), p_data->inq_res.p_eir,
                 p_data->inq_res.p_eir + 62);

    if (BTM_CheckEirData(p_data->inq_res.p_eir,
                         BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &len)) {
      p_data->inq_res.remt_name_not_required = true;
    }
  }

  bt_bdaddr_t bdaddr;
  bdcpy(bdaddr.address, p_data->inq_res.bd_addr);
  do_in_jni_thread(Bind(bta_scan_results_cb_impl, bdaddr,
                        p_data->inq_res.device_type, p_data->inq_res.rssi,
                        p_data->inq_res.ble_addr_type, std::move(value)));
}

void bta_track_adv_event_cb(tBTA_DM_BLE_TRACK_ADV_DATA* p_track_adv_data) {
  btgatt_track_adv_info_t* btif_scan_track_cb = new btgatt_track_adv_info_t;

  BTIF_TRACE_DEBUG("%s", __func__);
  btif_gatt_move_track_adv_data(btif_scan_track_cb,
                                (btgatt_track_adv_info_t*)p_track_adv_data);

  SCAN_CBACK_IN_JNI(track_adv_event_cb, Owned(btif_scan_track_cb));
}


void btif_gattc_register_scanner_impl(tBT_UUID uuid) {
  BTA_GATTC_AppRegister(&uuid, bta_gatts_cback);
}

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

  tBT_UUID bt_uuid;
  btif_to_bta_uuid(&bt_uuid, uuid);
  return do_in_jni_thread(Bind(&btif_gattc_register_scanner_impl, bt_uuid));
}

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

bt_status_t btif_gattc_unregister_scanner(int scanner_id) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(Bind(&btif_gattc_unregister_scanner_impl, scanner_id));
}

bt_status_t btif_gattc_scan(bool start) {
  CHECK_BTGATT_INIT();
  if (start) {
    btif_gattc_init_dev_cb();
    return do_in_jni_thread(Bind(&BTA_DmBleObserve, true, 0,
                                 (tBTA_DM_SEARCH_CBACK*)bta_scan_results_cb));
  }

  return do_in_jni_thread(Bind(&BTA_DmBleObserve, false, 0, nullptr));
}

void btif_gattc_scan_filter_param_setup_impl(
    int client_if, uint8_t action, int filt_index,
    tBTA_DM_BLE_PF_FILT_PARAMS* adv_filt_param) {
  if (1 == adv_filt_param->dely_mode) {
    BTA_DmBleTrackAdvertiser(client_if, bta_track_adv_event_cb);
  }

  BTA_DmBleScanFilterSetup(action, filt_index, adv_filt_param, NULL,
                           bta_scan_filt_param_setup_cb, client_if);
}

bt_status_t btif_gattc_scan_filter_param_setup(
    btgatt_filt_param_setup_t filt_param) {
  CHECK_BTGATT_INIT();
  BTIF_TRACE_DEBUG("%s", __func__);

  tBTA_DM_BLE_PF_FILT_PARAMS* adv_filt_param = new tBTA_DM_BLE_PF_FILT_PARAMS;
  adv_filt_param->feat_seln = filt_param.feat_seln;
  adv_filt_param->list_logic_type = filt_param.list_logic_type;
  adv_filt_param->filt_logic_type = filt_param.filt_logic_type;
  adv_filt_param->rssi_high_thres = filt_param.rssi_high_thres;
  adv_filt_param->rssi_low_thres = filt_param.rssi_low_thres;
  adv_filt_param->dely_mode = filt_param.dely_mode;
  adv_filt_param->found_timeout = filt_param.found_timeout;
  adv_filt_param->lost_timeout = filt_param.lost_timeout;
  adv_filt_param->found_timeout_cnt = filt_param.found_timeout_cnt;
  adv_filt_param->num_of_tracking_entries = filt_param.num_of_tracking_entries;

  return do_in_jni_thread(
      Bind(base::IgnoreResult(&btif_gattc_scan_filter_param_setup_impl),
           filt_param.client_if, filt_param.action, filt_param.filt_index,
           base::Owned(adv_filt_param)));
}

void btif_gattc_scan_filter_add_srvc_uuid(tBT_UUID uuid,
                                          tBTA_DM_BLE_PF_COND_MASK* p_uuid_mask,
                                          int action, int filt_type,
                                          int filt_index, int client_if) {
  tBTA_DM_BLE_PF_COND_PARAM cond;
  memset(&cond, 0, sizeof(tBTA_DM_BLE_PF_COND_PARAM));

  cond.srvc_uuid.p_target_addr = NULL;
  cond.srvc_uuid.cond_logic = BTA_DM_BLE_PF_LOGIC_AND;
  cond.srvc_uuid.uuid = uuid;
  cond.srvc_uuid.p_uuid_mask = p_uuid_mask;

  BTA_DmBleCfgFilterCondition(action, filt_type, filt_index, &cond,
                              &bta_scan_filt_cfg_cb, client_if);
}

void btif_gattc_scan_filter_add_local_name(vector<uint8_t> data, int action,
                                           int filt_type, int filt_index,
                                           int client_if) {
  tBTA_DM_BLE_PF_COND_PARAM cond;
  memset(&cond, 0, sizeof(tBTA_DM_BLE_PF_COND_PARAM));

  cond.local_name.data_len = data.size();
  cond.local_name.p_data = const_cast<uint8_t*>(data.data());
  BTA_DmBleCfgFilterCondition(action, filt_type, filt_index, &cond,
                              &bta_scan_filt_cfg_cb, client_if);
}

void btif_gattc_scan_filter_add_manu_data(int company_id, int company_id_mask,
                                          vector<uint8_t> pattern,
                                          vector<uint8_t> pattern_mask,
                                          int action, int filt_type,
                                          int filt_index, int client_if) {
  tBTA_DM_BLE_PF_COND_PARAM cond;
  memset(&cond, 0, sizeof(tBTA_DM_BLE_PF_COND_PARAM));

  cond.manu_data.company_id = company_id;
  cond.manu_data.company_id_mask = company_id_mask ? company_id_mask : 0xFFFF;
  cond.manu_data.data_len = pattern.size();
  cond.manu_data.p_pattern = const_cast<uint8_t*>(pattern.data());
  cond.manu_data.p_pattern_mask = const_cast<uint8_t*>(pattern_mask.data());
  BTA_DmBleCfgFilterCondition(action, filt_type, filt_index, &cond,
                              &bta_scan_filt_cfg_cb, client_if);
}

void btif_gattc_scan_filter_add_data_pattern(vector<uint8_t> pattern,
                                             vector<uint8_t> pattern_mask,
                                             int action, int filt_type,
                                             int filt_index, int client_if) {
  tBTA_DM_BLE_PF_COND_PARAM cond;
  memset(&cond, 0, sizeof(tBTA_DM_BLE_PF_COND_PARAM));

  cond.srvc_data.data_len = pattern.size();
  cond.srvc_data.p_pattern = const_cast<uint8_t*>(pattern.data());
  cond.srvc_data.p_pattern_mask = const_cast<uint8_t*>(pattern_mask.data());
  BTA_DmBleCfgFilterCondition(action, filt_type, filt_index, &cond,
                              &bta_scan_filt_cfg_cb, client_if);
}

bt_status_t btif_gattc_scan_filter_add_remove(
    int client_if, int action, int filt_type, int filt_index, int company_id,
    int company_id_mask, const bt_uuid_t* p_uuid, const bt_uuid_t* p_uuid_mask,
    const bt_bdaddr_t* bd_addr, char addr_type, vector<uint8_t> data,
    vector<uint8_t> mask) {
  CHECK_BTGATT_INIT();
  BTIF_TRACE_DEBUG("%s, %d, %d", __func__, action, filt_type);

  /* If data is passed, both mask and data have to be the same length */
  if (data.size() != mask.size() && data.size() != 0 && mask.size() != 0)
    return BT_STATUS_PARM_INVALID;

  switch (filt_type) {
    case BTA_DM_BLE_PF_ADDR_FILTER:
    {
      tBTA_DM_BLE_PF_COND_PARAM* cond = new tBTA_DM_BLE_PF_COND_PARAM;
      memset(cond, 0, sizeof(tBTA_DM_BLE_PF_COND_PARAM));

      bdcpy(cond->target_addr.bda, bd_addr->address);
      cond->target_addr.type = addr_type;
      return do_in_jni_thread(Bind(&BTA_DmBleCfgFilterCondition, action,
                                   filt_type, filt_index, base::Owned(cond),
                                   &bta_scan_filt_cfg_cb, client_if));
    }

    case BTA_DM_BLE_PF_SRVC_DATA:
      return do_in_jni_thread(Bind(&BTA_DmBleCfgFilterCondition, action,
                                   filt_type, filt_index, nullptr,
                                   &bta_scan_filt_cfg_cb, client_if));

    case BTA_DM_BLE_PF_SRVC_UUID:
    {
      tBT_UUID bt_uuid;
      btif_to_bta_uuid(&bt_uuid, p_uuid);

      if (p_uuid_mask != NULL) {
        tBTA_DM_BLE_PF_COND_MASK* uuid_mask = new tBTA_DM_BLE_PF_COND_MASK;
        btif_to_bta_uuid_mask(uuid_mask, p_uuid_mask, p_uuid);
        return do_in_jni_thread(Bind(&btif_gattc_scan_filter_add_srvc_uuid,
                                     bt_uuid, base::Owned(uuid_mask), action,
                                     filt_type, filt_index, client_if));
      }

      return do_in_jni_thread(Bind(&btif_gattc_scan_filter_add_srvc_uuid,
                                   bt_uuid, nullptr, action, filt_type,
                                   filt_index, client_if));
    }

    case BTA_DM_BLE_PF_SRVC_SOL_UUID:
    {
      tBTA_DM_BLE_PF_COND_PARAM* cond = new tBTA_DM_BLE_PF_COND_PARAM;
      memset(cond, 0, sizeof(tBTA_DM_BLE_PF_COND_PARAM));

      cond->solicitate_uuid.p_target_addr = NULL;
      cond->solicitate_uuid.cond_logic = BTA_DM_BLE_PF_LOGIC_AND;
      btif_to_bta_uuid(&cond->solicitate_uuid.uuid, p_uuid);

      return do_in_jni_thread(Bind(&BTA_DmBleCfgFilterCondition, action,
                                   filt_type, filt_index, base::Owned(cond),
                                   &bta_scan_filt_cfg_cb, client_if));
    }

    case BTA_DM_BLE_PF_LOCAL_NAME:
    {
      return do_in_jni_thread(Bind(&btif_gattc_scan_filter_add_local_name,
                                   std::move(data), action, filt_type,
                                   filt_index, client_if));
    }

    case BTA_DM_BLE_PF_MANU_DATA:
    {
      return do_in_jni_thread(Bind(&btif_gattc_scan_filter_add_manu_data,
                                   company_id, company_id_mask, std::move(data),
                                   std::move(mask), action, filt_type,
                                   filt_index, client_if));
    }

    case BTA_DM_BLE_PF_SRVC_DATA_PATTERN:
    {
      return do_in_jni_thread(Bind(&btif_gattc_scan_filter_add_data_pattern,
                                   std::move(data), std::move(mask), action,
                                   filt_type, filt_index, client_if));
    }

    default:
      LOG_ERROR(LOG_TAG, "%s: Unknown filter type (%d)!", __func__, action);
      return (bt_status_t)BTA_GATT_OK;
  }
}

bt_status_t btif_gattc_scan_filter_clear(int client_if, int filter_index) {
  CHECK_BTGATT_INIT();
  BTIF_TRACE_DEBUG("%s: filter_index: %d", __func__, filter_index);

  return do_in_jni_thread(Bind(&BTA_DmBleCfgFilterCondition,
                               BTA_DM_BLE_SCAN_COND_CLEAR,
                               BTA_DM_BLE_PF_TYPE_ALL, filter_index, nullptr,
                               &bta_scan_filt_cfg_cb, client_if));
}

bt_status_t btif_gattc_scan_filter_enable(int client_if, bool enable) {
  CHECK_BTGATT_INIT();
  BTIF_TRACE_DEBUG("%s: enable: %d", __func__, enable);

  uint8_t action = enable ? 1 : 0;

  return do_in_jni_thread(Bind(&BTA_DmEnableScanFilter, action,
                               &bta_scan_filt_status_cb, client_if));
}

bt_status_t btif_gattc_set_scan_parameters(int client_if, int scan_interval,
                                           int scan_window) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(
      Bind(BTA_DmSetBleScanParams, client_if, scan_interval, scan_window,
           BTM_BLE_SCAN_MODE_ACTI,
           (tBLE_SCAN_PARAM_SETUP_CBACK)bta_scan_param_setup_cb));
}


bt_status_t btif_gattc_cfg_storage(int client_if, int batch_scan_full_max,
                                   int batch_scan_trunc_max,
                                   int batch_scan_notify_threshold) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(
      Bind(BTA_DmBleSetStorageParams, batch_scan_full_max, batch_scan_trunc_max,
           batch_scan_notify_threshold,
           (tBTA_BLE_SCAN_SETUP_CBACK*)bta_batch_scan_setup_cb,
           (tBTA_BLE_SCAN_THRESHOLD_CBACK*)bta_batch_scan_threshold_cb,
           (tBTA_BLE_SCAN_REP_CBACK*)bta_batch_scan_reports_cb,
           (tBTA_DM_BLE_REF_VALUE)client_if));
}

bt_status_t btif_gattc_enb_batch_scan(int client_if, int scan_mode,
                                      int scan_interval, int scan_window,
                                      int addr_type, int discard_rule) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(Bind(BTA_DmBleEnableBatchScan, scan_mode,
                               scan_interval, scan_window, discard_rule,
                               addr_type, client_if));
}

bt_status_t btif_gattc_dis_batch_scan(int client_if) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(Bind(BTA_DmBleDisableBatchScan, client_if));
}

bt_status_t btif_gattc_read_batch_scan_reports(int client_if, int scan_mode) {
  CHECK_BTGATT_INIT();
  return do_in_jni_thread(Bind(BTA_DmBleReadScanReports, scan_mode, client_if));
}

} //namespace

const btgatt_scanner_interface_t btgattScannerInterface = {
    btif_gattc_register_scanner,
    btif_gattc_unregister_scanner,
    btif_gattc_scan,
    btif_gattc_scan_filter_param_setup,
    btif_gattc_scan_filter_add_remove,
    btif_gattc_scan_filter_clear,
    btif_gattc_scan_filter_enable,
    btif_gattc_set_scan_parameters,
    btif_gattc_cfg_storage,
    btif_gattc_enb_batch_scan,
    btif_gattc_dis_batch_scan,
    btif_gattc_read_batch_scan_reports,
};

#endif
Loading