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

Commit cc84da57 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Simplify LE scan filter memory management

Bug: 30622771
Test: sl4a FilteringTest
Change-Id: I58f3c335e84b4d7ee578c321109125084826efa0
parent 4b5faa47
Loading
Loading
Loading
Loading
+0 −118
Original line number Diff line number Diff line
@@ -1138,124 +1138,6 @@ void BTA_DmBleConfigLocalPrivacy(bool privacy_enable) {
#endif
}

/*******************************************************************************
 *
 * Function         BTA_DmBleCfgFilterCondition
 *
 * Description      This function is called to configure the adv data payload
 *                  filter condition.
 *
 * Parameters       action: to read/write/clear
 *                  cond_type: filter condition type
 *                  filt_index - Filter index
 *                  p_cond: filter condition parameter
 *                  p_cmpl_back - Command completed callback
 *                  ref_value - Reference value
 *
 * Returns          void
 *
 ******************************************************************************/
void BTA_DmBleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action,
                                 tBTM_BLE_PF_COND_TYPE cond_type,
                                 tBTM_BLE_PF_FILT_INDEX filt_index,
                                 tBTM_BLE_PF_COND_PARAM* p_cond,
                                 tBTM_BLE_PF_CFG_CBACK update_cb) {
  APPL_TRACE_API("BTA_DmBleCfgFilterCondition: %d, %d", action, cond_type);

  if (!p_cond) {
    do_in_bta_thread(FROM_HERE,
                     base::Bind(&BTM_BleCfgFilterCondition, action, cond_type,
                                filt_index, nullptr, update_cb));
  }

  uint16_t len = sizeof(tBTM_BLE_PF_COND_PARAM);
  uint8_t* p;

  switch (cond_type) {
    case BTM_BLE_PF_SRVC_DATA_PATTERN:
    case BTM_BLE_PF_MANU_DATA:
      /* Length of pattern and pattern mask and other elements in */
      /* tBTM_BLE_PF_MANU_COND */
      len += ((p_cond->manu_data.data_len) * 2) + sizeof(uint16_t) +
             sizeof(uint16_t) + sizeof(uint8_t);
      break;

    case BTM_BLE_PF_LOCAL_NAME:
      len += ((p_cond->local_name.data_len) + sizeof(uint8_t));
      break;

    case BTM_BLE_PF_SRVC_UUID:
    case BTM_BLE_PF_SRVC_SOL_UUID:
      len += sizeof(tBLE_BD_ADDR) + sizeof(tBTM_BLE_PF_COND_MASK);
      break;

    default:
      break;
  }

  // base::Owned will free it
  tBTM_BLE_PF_COND_PARAM* p_cond_param = new tBTM_BLE_PF_COND_PARAM;
  memcpy(p_cond_param, p_cond, sizeof(tBTM_BLE_PF_COND_PARAM));

  p = p_cond_param->additional_data;

  if (cond_type == BTM_BLE_PF_SRVC_DATA_PATTERN ||
      cond_type == BTM_BLE_PF_MANU_DATA) {
    p += sizeof(tBTM_BLE_PF_MANU_COND);
    p_cond_param->manu_data.p_pattern = p;
    p_cond_param->manu_data.data_len = p_cond->manu_data.data_len;
    memcpy(p_cond_param->manu_data.p_pattern, p_cond->manu_data.p_pattern,
           p_cond->manu_data.data_len);
    p += p_cond->manu_data.data_len;

    if (cond_type == BTM_BLE_PF_MANU_DATA) {
      p_cond_param->manu_data.company_id_mask =
          p_cond->manu_data.company_id_mask;
      if (p_cond->manu_data.p_pattern_mask != NULL) {
        p_cond_param->manu_data.p_pattern_mask = p;
        memcpy(p_cond_param->manu_data.p_pattern_mask,
               p_cond->manu_data.p_pattern_mask, p_cond->manu_data.data_len);
      }
    }
  } else if (cond_type == BTM_BLE_PF_LOCAL_NAME) {
    p += sizeof(tBTM_BLE_PF_LOCAL_NAME_COND);
    p_cond_param->local_name.p_data = p;
    p_cond_param->local_name.data_len = p_cond->local_name.data_len;
    memcpy(p_cond_param->local_name.p_data, p_cond->local_name.p_data,
           p_cond->local_name.data_len);
  } else if (cond_type == BTM_BLE_PF_SRVC_UUID ||
             cond_type == BTM_BLE_PF_SRVC_SOL_UUID) {
    p += sizeof(tBTM_BLE_PF_UUID_COND);
    if (p_cond->srvc_uuid.p_target_addr != NULL) {
      p_cond_param->srvc_uuid.p_target_addr = (tBLE_BD_ADDR*)(p);
      p_cond_param->srvc_uuid.p_target_addr->type =
          p_cond->srvc_uuid.p_target_addr->type;
      memcpy(p_cond_param->srvc_uuid.p_target_addr->bda,
             p_cond->srvc_uuid.p_target_addr->bda, BD_ADDR_LEN);
      p = (uint8_t*)(p_cond_param->srvc_uuid.p_target_addr + 1);
    }
    if (p_cond->srvc_uuid.p_uuid_mask) {
      p_cond_param->srvc_uuid.p_uuid_mask = (tBTM_BLE_PF_COND_MASK*)p;
      memcpy(p_cond_param->srvc_uuid.p_uuid_mask, p_cond->srvc_uuid.p_uuid_mask,
             sizeof(tBTM_BLE_PF_COND_MASK));
    }
  }

  do_in_bta_thread(
      FROM_HERE,
      base::Bind(&BTM_BleCfgFilterCondition, action, cond_type, filt_index,
                 base::Owned((tBTM_BLE_PF_COND_PARAM*)p_cond_param),
                 update_cb));
}

void BTA_DmBleScanFilterClear(tBTM_BLE_PF_FILT_INDEX filt_index,
                              tBTM_BLE_PF_CFG_CBACK update_cb) {
  do_in_bta_thread(
      FROM_HERE,
      base::Bind(&BTM_BleCfgFilterCondition, BTM_BLE_SCAN_COND_CLEAR,
                 BTM_BLE_PF_TYPE_ALL, filt_index, nullptr, update_cb));
}

/*******************************************************************************
 *
 * Function         BTA_DmBleScanFilterSetup
+0 −25
Original line number Diff line number Diff line
@@ -1853,31 +1853,6 @@ extern void BTA_DmBleScanFilterSetup(
    std::unique_ptr<btgatt_filt_param_setup_t> p_filt_params,
    tBTM_BLE_PF_PARAM_CB cb);

/*******************************************************************************
 *
 * Function         BTA_DmBleCfgFilterCondition
 *
 * Description      This function is called to configure the adv data payload
 *                  filter condition.
 *
 * Parameters       action: to read/write/clear
 *                  cond_type: filter condition type
 *                  filt_index - Filter index
 *                  p_cond: filter condition parameter
 *                  cb - Command completed callback
 *
 * Returns          void
 *
 ******************************************************************************/
extern void BTA_DmBleCfgFilterCondition(
    tBTM_BLE_SCAN_COND_OP action, tBTM_BLE_PF_COND_TYPE cond_type,
    tBTM_BLE_PF_FILT_INDEX filt_index, tBTM_BLE_PF_COND_PARAM* p_cond,
    base::Callback<void(uint8_t, uint8_t, uint8_t)> cb);

extern void BTA_DmBleScanFilterClear(
    tBTM_BLE_PF_FILT_INDEX filt_index,
    base::Callback<void(uint8_t, uint8_t, uint8_t)> cb);

/*******************************************************************************
 *
 * Function         BTA_DmBleTrackAdvertiser
+86 −108
Original line number Diff line number Diff line
@@ -350,69 +350,6 @@ void bta_track_adv_event_cb(tBTA_DM_BLE_TRACK_ADV_DATA* p_track_adv_data) {
  SCAN_CBACK_IN_JNI(track_adv_event_cb, Owned(btif_scan_track_cb));
}

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

  cond.srvc_uuid.p_target_addr = NULL;
  cond.srvc_uuid.cond_logic = BTM_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,
      Bind(&bta_scan_filt_cfg_cb, filt_type, 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) {
  tBTM_BLE_PF_COND_PARAM cond;
  memset(&cond, 0, sizeof(tBTM_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,
      Bind(&bta_scan_filt_cfg_cb, filt_type, 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) {
  tBTM_BLE_PF_COND_PARAM cond;
  memset(&cond, 0, sizeof(tBTM_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,
      Bind(&bta_scan_filt_cfg_cb, filt_type, 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) {
  tBTM_BLE_PF_COND_PARAM cond;
  memset(&cond, 0, sizeof(tBTM_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,
      Bind(&bta_scan_filt_cfg_cb, filt_type, client_if));
}

class BleScannerInterfaceImpl : public BleScannerInterface {
  ~BleScannerInterfaceImpl(){};

@@ -476,88 +413,129 @@ class BleScannerInterfaceImpl : public BleScannerInterface {
    if (data.size() != mask.size() && data.size() != 0 && mask.size() != 0)
      return;

    tBTM_BLE_PF_COND_PARAM* p_cond;
    switch (filt_type) {
      case BTM_BLE_PF_ADDR_FILTER: {
        tBTM_BLE_PF_COND_PARAM cond;
        memset(&cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM));

        bdcpy(cond.target_addr.bda, bd_addr->address);
        cond.target_addr.type = addr_type;
        BTA_DmBleCfgFilterCondition(
            action, filt_type, filt_index, &cond,
            Bind(&bta_scan_filt_cfg_cb, filt_type, client_if));
        return;
        p_cond = new tBTM_BLE_PF_COND_PARAM;
        memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM));

        bdcpy(p_cond->target_addr.bda, bd_addr->address);
        p_cond->target_addr.type = addr_type;
        break;
      }

      case BTM_BLE_PF_SRVC_DATA:
        BTA_DmBleCfgFilterCondition(
            action, filt_type, filt_index, nullptr,
            Bind(&bta_scan_filt_cfg_cb, filt_type, client_if));
        return;
        p_cond = nullptr;
        break;

      case BTM_BLE_PF_SRVC_UUID: {
        p_cond = new tBTM_BLE_PF_COND_PARAM;
        memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM));

        tBT_UUID bt_uuid;
        btif_to_bta_uuid(&bt_uuid, p_uuid);

        p_cond->srvc_uuid.cond_logic = BTM_BLE_PF_LOGIC_AND;
        p_cond->srvc_uuid.uuid = bt_uuid;

        if (p_uuid_mask != NULL) {
          tBTM_BLE_PF_COND_MASK uuid_mask;
          btif_to_bta_uuid_mask(&uuid_mask, p_uuid_mask, p_uuid);
          btif_gattc_scan_filter_add_srvc_uuid(
              bt_uuid, &uuid_mask, action, filt_type, filt_index, client_if);
          return;
          uint8_t* p = (uint8_t*)p_cond + sizeof(tBTM_BLE_PF_UUID_COND);
          p_cond->srvc_uuid.p_uuid_mask = (tBTM_BLE_PF_COND_MASK*)p;
          btif_to_bta_uuid_mask(p_cond->srvc_uuid.p_uuid_mask, p_uuid_mask,
                                p_uuid);
        }

        btif_gattc_scan_filter_add_srvc_uuid(bt_uuid, nullptr, action,
                                             filt_type, filt_index, client_if);
        return;
        break;
      }

      case BTM_BLE_PF_SRVC_SOL_UUID: {
        tBTM_BLE_PF_COND_PARAM cond;
        memset(&cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM));

        cond.solicitate_uuid.p_target_addr = NULL;
        cond.solicitate_uuid.cond_logic = BTM_BLE_PF_LOGIC_AND;
        btif_to_bta_uuid(&cond.solicitate_uuid.uuid, p_uuid);
        p_cond = new tBTM_BLE_PF_COND_PARAM;
        memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM));

        BTA_DmBleCfgFilterCondition(
            action, filt_type, filt_index, &cond,
            Bind(&bta_scan_filt_cfg_cb, filt_type, client_if));
        return;
        p_cond->solicitate_uuid.cond_logic = BTM_BLE_PF_LOGIC_AND;
        btif_to_bta_uuid(&p_cond->solicitate_uuid.uuid, p_uuid);
        break;
      }

      case BTM_BLE_PF_LOCAL_NAME: {
        btif_gattc_scan_filter_add_local_name(std::move(data), action,
                                              filt_type, filt_index, client_if);
        return;
        p_cond = new tBTM_BLE_PF_COND_PARAM;
        memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM));

        uint8_t* p = (uint8_t*)p_cond + sizeof(tBTM_BLE_PF_LOCAL_NAME_COND);
        p_cond->local_name.data_len = data.size();
        p_cond->local_name.p_data = p;
        memcpy(p_cond->local_name.p_data, data.data(), data.size());
        break;
      }

      case BTM_BLE_PF_MANU_DATA: {
        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);
        return;
        p_cond = new tBTM_BLE_PF_COND_PARAM;
        memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM));

        uint8_t data_len = data.size();

        p_cond->manu_data.company_id = company_id;
        p_cond->manu_data.company_id_mask =
            company_id_mask ? company_id_mask : 0xFFFF;
        p_cond->manu_data.data_len = data_len;

        uint8_t* p = (uint8_t*)p_cond + sizeof(tBTM_BLE_PF_MANU_COND);
        p_cond->manu_data.p_pattern = p;
        memcpy(p_cond->manu_data.p_pattern, data.data(), data_len);
        p += data_len;

        if (mask.size()) {
          p_cond->manu_data.p_pattern_mask = p;
          memcpy(p_cond->manu_data.p_pattern_mask, mask.data(), mask.size());
        }
        break;
      }

      case BTM_BLE_PF_SRVC_DATA_PATTERN: {
        btif_gattc_scan_filter_add_data_pattern(
            std::move(data), std::move(mask), action, filt_type, filt_index,
            client_if);
        return;
        p_cond = new tBTM_BLE_PF_COND_PARAM;
        memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM));

        p_cond->srvc_data.data_len = data.size();

        uint8_t* p = (uint8_t*)p_cond + sizeof(tBTM_BLE_PF_UUID_COND);
        p_cond->srvc_data.p_pattern = p;
        memcpy(p_cond->srvc_data.p_pattern, data.data(), data.size());
        p += data.size();
        if (mask.size()) {
          p_cond->srvc_data.p_pattern_mask = p;
          memcpy(p_cond->srvc_data.p_pattern_mask, mask.data(), mask.size());
        }
        break;
      }

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

    if (p_cond != nullptr) {
      do_in_bta_thread(
          FROM_HERE,
          base::Bind(&BTM_BleCfgFilterCondition, action, filt_type, filt_index,
                     base::Owned(p_cond),
                     Bind(&bta_scan_filt_cfg_cb, filt_type, client_if)));
    } else {
      do_in_bta_thread(FROM_HERE, base::Bind(&BTM_BleCfgFilterCondition, action,
                                             filt_type, filt_index, nullptr,
                                             Bind(&bta_scan_filt_cfg_cb,
                                                  filt_type, client_if)));
    }
  }

  void ScanFilterClear(int client_if, int filter_index) override {
    BTIF_TRACE_DEBUG("%s: filter_index: %d", __func__, filter_index);

    BTA_DmBleScanFilterClear(
        filter_index,
        Bind(&bta_scan_filt_cfg_cb, BTM_BLE_PF_TYPE_ALL, client_if));
    do_in_bta_thread(
        FROM_HERE,
        base::Bind(
            &BTM_BleCfgFilterCondition, BTM_BLE_SCAN_COND_CLEAR,
            BTM_BLE_PF_TYPE_ALL, filter_index, nullptr,
            Bind(&bta_scan_filt_cfg_cb, BTM_BLE_PF_TYPE_ALL, client_if)));
  }

  void ScanFilterEnable(int client_if, bool enable) override {