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

Commit 7d338480 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I65399f4e,Iad27b185,Ia43609b6,I78a06be7,I8e518f2b, ...

* changes:
  Properly retrieve acl_conn stack/acl/btm_acl::btm_pm_proc_mode_change
  Re-log stack/acl/btm_pm::BTM_SetPowerMode
  Re-log bta/dm/bta_dm_pm::bta_dm_pm_cback
  Introduce bluetooth::legacy::hci::Interface
  gd_acl: Add bluetooth::shim::ACL_Disconnect
  gd_acl: Add shim disconnect
  gd_acl: Add main/shim/helpers::ToDisconnectReasonFromLegacy
  Remove unnecessary stack/acl/btm_acl::l2c_link_hci_conn_comp
  Add stack/btm/btm_main::BTM_LogHistory
  Properly retrieve acl_conn stack/acl/btm_acl::btm_acl_encrypt_change
  Properly retrieve acl_conn stack/acl/btm_acl::btm_acl_process_sca_cmpl_pkt
  Properly retrieve acl_conn stack/acl/btm_acl::btm_read_failed_contact_counter_complete
  Properly retrieve acl_conn stack/acl/btm_acl::btm_read_link_quality_complete
  Properly retrieve acl_conn stack/acl/btm_acl::btm_read_remote_ext_features_failed
  gd_acl: Add sniff_subrating to dumpsys
  Add stack/acl/btm_pm::StackAclBtmPm::btm_pm_get_power_manager_from_handle
  Add stack/acl/btm_acl::acl_disconnect_from_handle
  Add stack/acl/btm_acl::hci_btsnd_hcic_disconnect
  Add tBTA_DM_SSR_SPEC.name[] field for sniff subrating options
  Add bta/dm/bta_dm_int::device_info_text
parents 6d141b5c 637051a6
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -534,14 +534,15 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTM_PM_PWR_MD bta_dm_pm_md[] = {
 * lowest latency */
tBTA_DM_SSR_SPEC bta_dm_ssr_spec[] = {
    /*max_lat, min_rmt_to, min_loc_to*/
    {0, 0, 0}, /* BTA_DM_PM_SSR0 - do not use SSR */
    {0, 0, 0, "no_ssr"}, /* BTA_DM_PM_SSR0 - do not use SSR */
    /* BTA_DM_PM_SSR1 - HH, can NOT share entry with any other profile, seting
       default max latency and min remote timeout as 0, and always read
       individual device preference from HH module */
    {0, 0, 2},
    {1200, 2, 2},     /* BTA_DM_PM_SSR2 - others (as long as sniff is allowed)*/
    {360, 160, 1600}, /* BTA_DM_PM_SSR3 - HD */
    {1200, 65534, 65534} /* BTA_DM_PM_SSR4 - A2DP streaming */
    {0, 0, 2, "hid_host"},
    {1200, 2, 2, "sniff_capable"},  /* BTA_DM_PM_SSR2 - others (as long as sniff
                                       is allowed)*/
    {360, 160, 1600, "hid_device"}, /* BTA_DM_PM_SSR3 - HD */
    {1200, 65534, 65534, "a2dp"}    /* BTA_DM_PM_SSR4 - A2DP streaming */
};

tBTA_DM_SSR_SPEC* p_bta_dm_ssr_spec = &bta_dm_ssr_spec[0];
+18 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#ifndef BTA_DM_INT_H
#define BTA_DM_INT_H

#include <base/strings/stringprintf.h>
#include <memory>
#include "bt_target.h"
#include "bta/sys/bta_sys.h"
@@ -167,11 +168,27 @@ typedef enum : uint8_t {
  BTA_DM_DI_INT_SNIFF = 0x02, /* set this bit if call BTM_SetPowerMode(sniff) &
                                 enter sniff mode */
  BTA_DM_DI_ACP_SNIFF = 0x04, /* set this bit if peer init sniff */
  BTA_DM_DI_UNUSED = 0x08,
  BTA_DM_DI_USE_SSR = 0x10, /* set this bit if ssr is supported for this link */
  BTA_DM_DI_AV_ACTIVE = 0x20, /* set this bit if AV is active for this link */
} tBTA_DM_DEV_INFO_BITMASK;
typedef uint8_t tBTA_DM_DEV_INFO;

inline std::string device_info_text(tBTA_DM_DEV_INFO info) {
  const char* const device_info_text[] = {
      ":set_sniff", ":int_sniff", ":acp_sniff",
      ":unused",    ":use_ssr",   ":av_active",
  };

  std::string s = base::StringPrintf("0x%02x", info);
  if (info == BTA_DM_DI_NONE) return s + std::string(":none");
  for (size_t i = 0; i < sizeof(device_info_text) / sizeof(device_info_text[0]);
       i++) {
    if (info & (1u << i)) s += std::string(device_info_text[i]);
  }
  return s;
}

/* set power mode request type */
#define BTA_DM_PM_RESTART 1
#define BTA_DM_PM_NEW_REQ 2
@@ -379,6 +396,7 @@ typedef struct {
  uint16_t max_lat;
  uint16_t min_rmt_to;
  uint16_t min_loc_to;
  const char* name{nullptr};
} tBTA_DM_SSR_SPEC;

typedef struct {
+56 −30
Original line number Diff line number Diff line
@@ -336,10 +336,9 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
  tBTA_DM_PEER_DEVICE* p_dev;
  tBTA_DM_PM_REQ pm_req = BTA_DM_PM_NEW_REQ;

  APPL_TRACE_DEBUG("bta_dm_pm_cback: st(%d), id(%d), app(%d)", status, id,
                   app_id);

  p_dev = bta_dm_find_peer_device(peer_addr);
  LOG_DEBUG("Power management callback status:%s[%hhu] id:%s[%d], app:%hhu",
            bta_sys_conn_status_text(status).c_str(), status,
            BtaIdSysText(id).c_str(), id, app_id);

  /* find if there is an power mode entry for the service */
  for (i = 1; i <= p_bta_dm_pm_cfg[0].app_id; i++) {
@@ -350,10 +349,21 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
  }

  /* if no entries are there for the app_id and subsystem in p_bta_dm_pm_spec*/
  if (i > p_bta_dm_pm_cfg[0].app_id) return;
  if (i > p_bta_dm_pm_cfg[0].app_id) {
    LOG_DEBUG("Ignoring power management callback as no service entries exist");
    return;
  }

  LOG_DEBUG("Stopped all timers for service to device:%s id:%hhu",
            PRIVATE_ADDRESS(peer_addr), id);
  bta_dm_pm_stop_timer_by_srvc_id(peer_addr, id);
/*p_dev = bta_dm_find_peer_device(peer_addr);*/

  p_dev = bta_dm_find_peer_device(peer_addr);
  if (p_dev) {
    LOG_DEBUG("Device info:%s", device_info_text(p_dev->info).c_str());
  } else {
    LOG_ERROR("Unable to find peer device...yet soldiering on...");
  }

  /* set SSR parameters on SYS CONN OPEN */
  int index = BTA_DM_PM_SSR0;
@@ -441,11 +451,7 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
    p_dev->pm_mode_failed = 0;
  }

  if (p_bta_dm_ssr_spec[index].max_lat
#if (BTA_HH_INCLUDED == TRUE)
      || index == BTA_DM_PM_SSR_HH
#endif
      ) {
  if (p_bta_dm_ssr_spec[index].max_lat || index == BTA_DM_PM_SSR_HH) {
    bta_dm_pm_ssr(peer_addr, index);
  } else {
    const controller_t* controller = controller_get_interface();
@@ -709,6 +715,9 @@ static void bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE* p_peer_dev, uint8_t index) {
            p_peer_dev->info);

  uint8_t* p_rem_feat = BTM_ReadRemoteFeatures(p_peer_dev->peer_bdaddr);
  LOG_DEBUG("Current power mode:%s[0x%x] peer_info:%s",
            power_mode_status_text(mode).c_str(), mode,
            device_info_text(p_peer_dev->info).c_str());

  const controller_t* controller = controller_get_interface();
  if (mode != BTM_PM_MD_SNIFF ||
@@ -760,6 +769,8 @@ static void bta_dm_pm_ssr(const RawAddress& peer_addr, int ssr) {
  int ssr_index = ssr;
  tBTA_DM_SSR_SPEC* p_spec = &p_bta_dm_ssr_spec[ssr_index];

  LOG_DEBUG("Request to put link to device:%s into power_mode:%s",
            PRIVATE_ADDRESS(peer_addr), p_spec->name);
  /* go through the connected services */
  for (int i = 0; i < bta_dm_conn_srvcs.count; i++) {
    const tBTA_DM_SRVCS& service = bta_dm_conn_srvcs.conn_srvc[i];
@@ -773,9 +784,10 @@ static void bta_dm_pm_ssr(const RawAddress& peer_addr, int ssr) {
      current_ssr_index = p_bta_dm_pm_spec[config.spec_idx].ssr;
      if ((config.id == service.id) && ((config.app_id == BTA_ALL_APP_ID) ||
                                        (config.app_id == service.app_id))) {
        LOG_INFO("Found connected service:%s app_id:%d peer:%s",
        LOG_INFO("Found connected service:%s app_id:%d peer:%s spec_name:%s",
                 BtaIdSysText(service.id).c_str(), service.app_id,
                 PRIVATE_ADDRESS(peer_addr));
                 PRIVATE_ADDRESS(peer_addr),
                 p_bta_dm_ssr_spec[current_ssr_index].name);
        break;
      }
    }
@@ -793,16 +805,17 @@ static void bta_dm_pm_ssr(const RawAddress& peer_addr, int ssr) {
#endif
    if (p_spec_cur->max_lat < p_spec->max_lat ||
        (ssr_index == BTA_DM_PM_SSR0 && current_ssr_index != BTA_DM_PM_SSR0)) {
      LOG_DEBUG(
          "Changing sniff subrating specification for %s from %s[%d] ==> "
          "%s[%d]",
          PRIVATE_ADDRESS(peer_addr), p_spec->name, ssr_index, p_spec_cur->name,
          current_ssr_index);
      ssr_index = current_ssr_index;
      p_spec = &p_bta_dm_ssr_spec[ssr_index];
    }
  }

  if (p_spec->max_lat) {
    LOG_DEBUG(
        "Max latency is non zero max_lat:0x%04x min_loc_to:0x%04x "
        "min_rmt_to:0x%04x",
        p_spec->max_lat, p_spec->min_loc_to, p_spec->min_rmt_to);
    /* Avoid SSR reset on device which has SCO connected */
    if (bta_dm_pm_is_sco_active()) {
      int idx = bta_dm_get_sco_index();
@@ -815,37 +828,50 @@ static void bta_dm_pm_ssr(const RawAddress& peer_addr, int ssr) {
    }

    LOG_DEBUG(
        "Setting sniff subrating for device:%s max_lat:0x%04x "
        "min_loc_to:0x%04x min_rmt_to:0x%04x",
        PRIVATE_ADDRESS(peer_addr), p_spec->max_lat, p_spec->min_loc_to,
        p_spec->min_rmt_to);

        "Setting sniff subrating for device:%s spec_name:%s max_latency(s):%.2f"
        " min_local_timeout(s):%.2f min_remote_timeout(s):%.2f",
        PRIVATE_ADDRESS(peer_addr), p_spec->name,
        ticks_to_seconds(p_spec->max_lat), ticks_to_seconds(p_spec->min_loc_to),
        ticks_to_seconds(p_spec->min_rmt_to));
    /* set the SSR parameters. */
    BTM_SetSsrParams(peer_addr, p_spec->max_lat, p_spec->min_rmt_to,
                     p_spec->min_loc_to);
  }
}

/*******************************************************************************
 *
 * Function         bta_dm_pm_active
 *
 * Description      Brings connection to active mode
 *
 *
 * Returns          void
 *
 ******************************************************************************/
void bta_dm_pm_active(const RawAddress& peer_addr) {
  tBTM_PM_PWR_MD pm;

  memset((void*)&pm, 0, sizeof(pm));
  tBTM_PM_PWR_MD pm{
      .mode = BTM_PM_MD_ACTIVE,
  };

  /* switch to active mode */
  pm.mode = BTM_PM_MD_ACTIVE;
  tBTM_STATUS status = BTM_SetPowerMode(bta_dm_cb.pm_id, peer_addr, &pm);
  if (status != BTM_CMD_STORED && status != BTM_CMD_STARTED) {
    LOG_WARN("Unable to set active mode for device:%s",
  switch (status) {
    case BTM_CMD_STORED:
      LOG_DEBUG("Active power mode stored for execution later for remote:%s",
                PRIVATE_ADDRESS(peer_addr));
      break;
    case BTM_CMD_STARTED:
      LOG_DEBUG("Active power mode started for remote:%s",
                PRIVATE_ADDRESS(peer_addr));
      break;
    case BTM_SUCCESS:
      LOG_INFO("Active power mode already set for device:%s",
               PRIVATE_ADDRESS(peer_addr));
      break;
    default:
      LOG_WARN("Unable to set active power mode for device:%s status:%s",
               PRIVATE_ADDRESS(peer_addr), btm_status_text(status).c_str());
      break;
  }
}

+50 −0
Original line number Diff line number Diff line
@@ -150,6 +150,8 @@ class ShimAclConnection {
    TRY_POSTING_ON_MAIN(send_data_upwards_, p_buf);
  }

  virtual void InitiateDisconnect(hci::DisconnectReason reason) = 0;

 protected:
  const uint16_t handle_{kInvalidHciHandle};
  os::Handler* handler_;
@@ -340,6 +342,10 @@ class ClassicShimAclConnection

  hci::Address GetRemoteAddress() const { return connection_->GetAddress(); }

  void InitiateDisconnect(hci::DisconnectReason reason) override {
    connection_->Disconnect(reason);
  }

 private:
  OnDisconnect on_disconnect_;
  const shim::legacy::acl_classic_link_interface_t interface_;
@@ -400,6 +406,10 @@ class LeShimAclConnection
    return connection_->GetRemoteAddress();
  }

  void InitiateDisconnect(hci::DisconnectReason reason) override {
    connection_->Disconnect(reason);
  }

 private:
  OnDisconnect on_disconnect_;
  const shim::legacy::acl_le_link_interface_t interface_;
@@ -474,6 +484,11 @@ void DumpsysAcl(int fd) {
                  common::ToString(acl_conn.peer_lmp_feature_valid[j]).c_str(),
                  bd_features_text(acl_conn.peer_lmp_feature_pages[j]).c_str());
    }
    LOG_DUMPSYS(fd, "      sniff_subrating:%s",
                common::ToString(HCI_SNIFF_SUB_RATE_SUPPORTED(
                                     acl_conn.peer_lmp_feature_pages[0]))
                    .c_str());

    LOG_DUMPSYS(fd, "remote_addr:%s", acl_conn.remote_addr.ToString().c_str());
    LOG_DUMPSYS(fd, "    handle:0x%04x", acl_conn.hci_handle);
    LOG_DUMPSYS(fd, "    [le] active_remote_addr:%s",
@@ -756,3 +771,38 @@ void bluetooth::shim::legacy::Acl::ConfigureLePrivacy(
      address_policy, empty_address_with_type, rotation_irk,
      minimum_rotation_time, maximum_rotation_time);
}

void bluetooth::shim::legacy::Acl::DisconnectClassic(uint16_t handle,
                                                     tHCI_STATUS reason) {
  auto connection = pimpl_->handle_to_classic_connection_map_.find(handle);
  if (connection != pimpl_->handle_to_classic_connection_map_.end()) {
    auto remote_address = connection->second->GetRemoteAddress();
    connection->second->InitiateDisconnect(
        ToDisconnectReasonFromLegacy(reason));
    LOG_DEBUG("Disconnection initiated classic remote:%s handle:%hu",
              PRIVATE_ADDRESS(remote_address), handle);
    btm_cb.history_->Push("%-32s: %s classic", "Disconnection initiated",
                          PRIVATE_ADDRESS(remote_address));
  } else {
    LOG_WARN("Unable to disconnect unknown classic connection handle:0x%04x",
             handle);
  }
}

void bluetooth::shim::legacy::Acl::DisconnectLe(uint16_t handle,
                                                tHCI_STATUS reason) {
  auto connection = pimpl_->handle_to_le_connection_map_.find(handle);
  if (connection != pimpl_->handle_to_le_connection_map_.end()) {
    auto remote_address_with_type =
        connection->second->GetRemoteAddressWithType();
    connection->second->InitiateDisconnect(
        ToDisconnectReasonFromLegacy(reason));
    LOG_DEBUG("Disconnection initiated le remote:%s handle:%hu",
              PRIVATE_ADDRESS(remote_address_with_type), handle);
    btm_cb.history_->Push("%-32s: %s le", "Disconnection initiated",
                          PRIVATE_ADDRESS(remote_address_with_type));
  } else {
    LOG_WARN("Unable to disconnect unknown le connection handle:0x%04x",
             handle);
  }
}
+3 −0
Original line number Diff line number Diff line
@@ -59,6 +59,9 @@ class Acl : public hci::acl_manager::ConnectionCallbacks,

  void ConfigureLePrivacy(bool is_le_privacy_enabled);

  void DisconnectClassic(uint16_t handle, tHCI_STATUS reason);
  void DisconnectLe(uint16_t handle, tHCI_STATUS reason);

  void Dump(int fd) const;

 protected:
Loading