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

Commit 2633d351 authored by Katherine Lai's avatar Katherine Lai Committed by Gerrit Code Review
Browse files

Merge changes from topic "bt_sniff_le_sysprops"

* changes:
  Implement Bluetooth LE connection sysprops
  Update BTA_DM_PM_PARK_IDX with actual number of current entries in Sniff Table
  Implement Bluetooth classic sysprops
parents 2d4560b7 2935034e
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;
+1 −1
Original line number Diff line number Diff line
@@ -548,7 +548,7 @@ enum {

#ifndef BTA_DM_PM_PARK_IDX
#define BTA_DM_PM_PARK_IDX \
  6 /* the actual index to bta_dm_pm_md[] for PARK mode */
  7 /* the actual index to bta_dm_pm_md[] for PARK mode */
#endif

#ifndef BTA_DM_PM_SNIFF_A2DP_IDX
+33 −14
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "hci/le_address_manager.h"
#include "os/alarm.h"
#include "os/handler.h"
#include "os/system_properties.h"
#include "packet/packet_view.h"

using bluetooth::crypto_toolbox::Octet16;
@@ -49,18 +50,34 @@ namespace acl_manager {

using common::BindOnce;

constexpr uint16_t kConnIntervalMin = 0x0018;
constexpr uint16_t kConnIntervalMax = 0x0028;
constexpr uint16_t kConnLatency = 0x0000;
constexpr uint16_t kSupervisionTimeout = 0x01f4;
constexpr uint16_t kScanIntervalFast = 0x0060;    /* 30 ~ 60 ms (use 60)  = 96 *0.625 */
constexpr uint16_t kScanWindowFast = 0x0030;      /* 30 ms = 48 *0.625 */
constexpr uint16_t kScanWindow2mFast = 0x0018;    /* 15 ms = 24 *0.625 */
constexpr uint16_t kScanWindowCodedFast = 0x0018; /* 15 ms = 24 *0.625 */
constexpr uint16_t kScanIntervalSlow = 0x0800;    /* 1.28 s = 2048 *0.625 */
constexpr uint16_t kScanWindowSlow = 0x0030;      /* 30 ms = 48 *0.625 */
constexpr std::chrono::milliseconds kCreateConnectionTimeoutMs = std::chrono::milliseconds(30 * 1000);
constexpr uint32_t kCreateConnectionTimeoutMs = 30 * 1000;
constexpr uint8_t PHY_LE_NO_PACKET = 0x00;
constexpr uint8_t PHY_LE_1M = 0x01;
constexpr uint8_t PHY_LE_2M = 0x02;
constexpr uint8_t PHY_LE_CODED = 0x04;

static const std::string kPropertyMinConnInterval = "bluetooth.core.le.min_connection_interval";
static const std::string kPropertyMaxConnInterval = "bluetooth.core.le.max_connection_interval";
static const std::string kPropertyConnLatency = "bluetooth.core.le.connection_latency";
static const std::string kPropertyConnSupervisionTimeout = "bluetooth.core.le.connection_supervision_timeout";
static const std::string kPropertyDirectConnTimeout = "bluetooth.core.le.direct_connection_timeout";
static const std::string kPropertyConnScanIntervalFast = "bluetooth.core.le.connection_scan_interval_fast";
static const std::string kPropertyConnScanWindowFast = "bluetooth.core.le.connection_scan_window_fast";
static const std::string kPropertyConnScanWindow2mFast = "bluetooth.core.le.connection_scan_window_2m_fast";
static const std::string kPropertyConnScanWindowCodedFast = "bluetooth.core.le.connection_scan_window_coded_fast";
static const std::string kPropertyConnScanIntervalSlow = "bluetooth.core.le.connection_scan_interval_slow";
static const std::string kPropertyConnScanWindowSlow = "bluetooth.core.le.connection_scan_window_slow";

enum class ConnectabilityState {
  DISARMED = 0,
  ARMING = 1,
@@ -654,24 +671,24 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
    connectability_state_ = ConnectabilityState::ARMING;
    connecting_le_ = connect_list;

    uint16_t le_scan_interval = kScanIntervalSlow;
    uint16_t le_scan_window = kScanWindowSlow;
    uint16_t le_scan_window_2m = kScanWindowSlow;
    uint16_t le_scan_window_coded = kScanWindowSlow;
    uint16_t le_scan_interval = os::GetSystemPropertyUint32(kPropertyConnScanIntervalSlow, kScanIntervalSlow);
    uint16_t le_scan_window = os::GetSystemPropertyUint32(kPropertyConnScanWindowSlow, kScanWindowSlow);
    uint16_t le_scan_window_2m = le_scan_window;
    uint16_t le_scan_window_coded = le_scan_window;
    // If there is any direct connection in the connection list, use the fast parameter
    if (!direct_connections_.empty()) {
      le_scan_interval = kScanIntervalFast;
      le_scan_window = kScanWindowFast;
      le_scan_window_2m = kScanWindow2mFast;
      le_scan_window_coded = kScanWindowCodedFast;
      le_scan_interval = os::GetSystemPropertyUint32(kPropertyConnScanIntervalFast, kScanIntervalFast);
      le_scan_window = os::GetSystemPropertyUint32(kPropertyConnScanWindowFast, kScanWindowFast);
      le_scan_window_2m = os::GetSystemPropertyUint32(kPropertyConnScanWindow2mFast, kScanWindow2mFast);
      le_scan_window_coded = os::GetSystemPropertyUint32(kPropertyConnScanWindowCodedFast, kScanWindowCodedFast);
    }
    InitiatorFilterPolicy initiator_filter_policy = InitiatorFilterPolicy::USE_FILTER_ACCEPT_LIST;
    OwnAddressType own_address_type =
        static_cast<OwnAddressType>(le_address_manager_->GetCurrentAddress().GetAddressType());
    uint16_t conn_interval_min = 0x0018;
    uint16_t conn_interval_max = 0x0028;
    uint16_t conn_latency = 0x0000;
    uint16_t supervision_timeout = 0x001f4;
    uint16_t conn_interval_min = os::GetSystemPropertyUint32(kPropertyMinConnInterval, kConnIntervalMin);
    uint16_t conn_interval_max = os::GetSystemPropertyUint32(kPropertyMaxConnInterval, kConnIntervalMax);
    uint16_t conn_latency = os::GetSystemPropertyUint32(kPropertyConnLatency, kConnLatency);
    uint16_t supervision_timeout = os::GetSystemPropertyUint32(kPropertyConnSupervisionTimeout, kSupervisionTimeout);
    ASSERT(check_connection_parameters(conn_interval_min, conn_interval_max, conn_latency, supervision_timeout));

    AddressWithType address_with_type = connection_peer_address_with_type_;
@@ -782,10 +799,12 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
              std::piecewise_construct,
              std::forward_as_tuple(address_with_type.GetAddress(), address_with_type.GetAddressType()),
              std::forward_as_tuple(handler_));
          uint32_t connection_timeout =
              os::GetSystemPropertyUint32(kPropertyDirectConnTimeout, kCreateConnectionTimeoutMs);
          create_connection_timeout_alarms_.at(address_with_type)
              .Schedule(
                  common::BindOnce(&le_impl::on_create_connection_timeout, common::Unretained(this), address_with_type),
                  kCreateConnectionTimeoutMs);
                  std::chrono::milliseconds(connection_timeout));
        }
      }
    }
+9 −0
Original line number Diff line number Diff line
@@ -36,6 +36,15 @@ std::optional<std::string> GetSystemProperty(const std::string& property) {
  return std::string(value_array.data(), value_len);
}

uint32_t GetSystemPropertyUint32(const std::string& property, uint32_t default_value) {
  std::optional<std::string> result = GetSystemProperty(property);
  if (result) {
    return static_cast<uint32_t>(std::stoul(*result));
  } else {
    return default_value;
  }
}

bool SetSystemProperty(const std::string& property, const std::string& value) {
  if (value.size() >= PROPERTY_VALUE_MAX) {
    LOG_ERROR("Property value's maximum size is %d, but %zu chars were given", PROPERTY_VALUE_MAX - 1, value.size());
+9 −0
Original line number Diff line number Diff line
@@ -37,6 +37,15 @@ std::optional<std::string> GetSystemProperty(const std::string& property) {
  return iter->second;
}

uint32_t GetSystemPropertyUint32(const std::string& property, uint32_t default_value) {
  std::optional<std::string> result = GetSystemProperty(property);
  if (result) {
    return static_cast<uint32_t>(std::stoul(*result));
  } else {
    return default_value;
  }
}

bool SetSystemProperty(const std::string& property, const std::string& value) {
  std::lock_guard<std::mutex> lock(properties_mutex);
  properties.insert_or_assign(property, value);
Loading