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

Commit b2ebe04a authored by Katherine Lai's avatar Katherine Lai
Browse files

Implement Bluetooth classic sysprops

Implement Sniff parameters

Bug: 233119719
Tag: #refactor
Test: Manually verified
Change-Id: I344aefc34307bc2c9c221ee02e9e92137a1c6378
parent 272c4647
Loading
Loading
Loading
Loading
+68 −1
Original line number Diff line number Diff line
@@ -24,8 +24,10 @@
 ******************************************************************************/

#include <base/bind.h>

#include <cstdint>
#include <mutex>
#include <vector>

#include "bta/dm/bta_dm_int.h"
#include "bta/include/bta_api.h"
@@ -34,6 +36,7 @@
#include "device/include/controller.h"
#include "main/shim/dumpsys.h"
#include "osi/include/log.h"
#include "osi/include/properties.h"
#include "stack/include/acl_api.h"
#include "stack/include/btu.h"  // do_in_main_thread
#include "types/raw_address.h"
@@ -63,6 +66,16 @@ tBTA_DM_CONNECTED_SRVCS bta_dm_conn_srvcs;
static std::recursive_mutex pm_timer_schedule_mutex;
static std::recursive_mutex pm_timer_state_mutex;

/* Sysprop paths for sniff parameters */
static const char kPropertySniffMaxIntervals[] =
    "bluetooth.core.classic.sniff_max_intervals";
static const char kPropertySniffMinIntervals[] =
    "bluetooth.core.classic.sniff_min_intervals";
static const char kPropertySniffAttempts[] =
    "bluetooth.core.classic.sniff_attempts";
static const char kPropertySniffTimeouts[] =
    "bluetooth.core.classic.sniff_timeouts";

/*******************************************************************************
 *
 * Function         bta_dm_init_pm
@@ -689,7 +702,60 @@ static bool bta_dm_pm_park(const RawAddress& peer_addr) {
  }
  return true;
}
/*******************************************************************************
 *
 * Function         get_sniff_entry
 *
 * Description      Helper function to get sniff entry from sysprop or
 *                  default table.
 *
 *
 * Returns          tBTM_PM_PWR_MD with specified |index|.
 *
 ******************************************************************************/
tBTM_PM_PWR_MD get_sniff_entry(uint8_t index) {
  static std::vector<tBTM_PM_PWR_MD> pwr_mds_cache;
  if (pwr_mds_cache.size() == BTA_DM_PM_PARK_IDX) {
    if (index >= BTA_DM_PM_PARK_IDX) {
      return pwr_mds_cache[0];
    }
    return pwr_mds_cache[index];
  }

  std::vector<uint32_t> invalid_list(BTA_DM_PM_PARK_IDX, 0);
  std::vector<uint32_t> max =
      osi_property_get_uintlist(kPropertySniffMaxIntervals, invalid_list);
  std::vector<uint32_t> min =
      osi_property_get_uintlist(kPropertySniffMinIntervals, invalid_list);
  std::vector<uint32_t> attempt =
      osi_property_get_uintlist(kPropertySniffAttempts, invalid_list);
  std::vector<uint32_t> timeout =
      osi_property_get_uintlist(kPropertySniffTimeouts, invalid_list);

  // If any of the sysprops are malformed or don't exist, use default table
  // value
  bool use_defaults =
      (max.size() < BTA_DM_PM_PARK_IDX || max == invalid_list ||
       min.size() < BTA_DM_PM_PARK_IDX || min == invalid_list ||
       attempt.size() < BTA_DM_PM_PARK_IDX || attempt == invalid_list ||
       timeout.size() < BTA_DM_PM_PARK_IDX || timeout == invalid_list);

  for (auto i = 0; i < BTA_DM_PM_PARK_IDX; i++) {
    if (use_defaults) {
      pwr_mds_cache.push_back(p_bta_dm_pm_md[i]);
    } else {
      pwr_mds_cache.push_back(tBTM_PM_PWR_MD{
          static_cast<uint16_t>(max[i]), static_cast<uint16_t>(min[i]),
          static_cast<uint16_t>(attempt[i]), static_cast<uint16_t>(timeout[i]),
          BTM_PM_MD_SNIFF});
    }
  }

  if (index >= BTA_DM_PM_PARK_IDX) {
    return pwr_mds_cache[0];
  }
  return pwr_mds_cache[index];
}
/*******************************************************************************
 *
 * Function         bta_ag_pm_sniff
@@ -734,7 +800,8 @@ void bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE* p_peer_dev, uint8_t index) {
  }
  /* if the current mode is not sniff, issue the sniff command.
   * If sniff, but SSR is not used in this link, still issue the command */
  memcpy(&pwr_md, &p_bta_dm_pm_md[index], sizeof(tBTM_PM_PWR_MD));
  tBTM_PM_PWR_MD sniff_entry = get_sniff_entry(index);
  memcpy(&pwr_md, &sniff_entry, sizeof(tBTM_PM_PWR_MD));
  if (p_peer_dev->Info() & BTA_DM_DI_INT_SNIFF) {
    LOG_DEBUG("Trying to force power mode");
    pwr_md.mode |= BTM_PM_MD_FORCE;
+4 −0
Original line number Diff line number Diff line
@@ -77,6 +77,10 @@ void SyspropsModule::parse_config(std::string file_path) {
      "bluetooth.core.classic.inq_scan_window",
      "bluetooth.core.acl.link_supervision_timeout",
      "bluetooth.core.classic.page_timeout",
      "bluetooth.core.classic.sniff_max_intervals",
      "bluetooth.core.classic.sniff_min_intervals",
      "bluetooth.core.classic.sniff_attempts",
      "bluetooth.core.classic.sniff_timeouts",
  };

  auto config = storage::LegacyConfigFile::FromPath(file_path).Read(kDefaultCapacity);
+7 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#pragma once

#include <cstdint>
#include <vector>

#ifndef PROPERTY_VALUE_MAX
#define PROPERTY_VALUE_MAX 92
@@ -51,3 +52,8 @@ int32_t osi_property_get_int32(const char* key, int32_t default_value);
// returns the value of |key| coerced into a bool. If the property is not set,
// then the |default_value| is used.
bool osi_property_get_bool(const char* key, bool default_value);

// Helper function that returns the value of |key| coerced into a vector of
// uint32_t. If the property is not set, then the |default_value| is used.
std::vector<uint32_t> osi_property_get_uintlist(
    const char* key, std::vector<uint32_t> default_value);
 No newline at end of file
+28 −0
Original line number Diff line number Diff line
@@ -72,3 +72,31 @@ bool osi_property_get_bool(const char* key, bool default_value) {
    return default_value;
  }
}

std::vector<uint32_t> osi_property_get_uintlist(
    const char* key, const std::vector<uint32_t> default_value) {
  std::optional<std::string> result = bluetooth::os::GetSystemProperty(key);
  if (!result || result->empty() || result->size() > PROPERTY_VALUE_MAX) {
    return default_value;
  }

  std::vector<uint32_t> list;
  for (uint i = 0; i < result->size(); i++) {
    // Build a string of all the chars until the next comma or end of the
    // string is reached. If any char is not a digit, then return the default.
    std::string value;
    while ((*result)[i] != ',' && i < result->size()) {
      char c = (*result)[i];
      if (!std::isdigit(c)) {
        return default_value;
      }
      value += c;
      i++;
    }

    // grab value
    list.push_back(static_cast<uint32_t>(std::stoul(value)));
  }

  return list;
}
+5 −0
Original line number Diff line number Diff line
@@ -61,6 +61,11 @@ int32_t osi_property_get_int32(const char* key, int32_t default_value) {
  mock_function_count_map[__func__]++;
  return test::mock::osi_properties::osi_property_get_int32(key, default_value);
}
std::vector<uint32_t> osi_property_get_uintlist(
    const char* key, std::vector<uint32_t> default_value) {
  mock_function_count_map[__func__]++;
  return default_value;
}
int osi_property_set(const char* key, const char* value) {
  mock_function_count_map[__func__]++;
  return test::mock::osi_properties::osi_property_set(key, value);