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

Commit 93a40eab authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I48f17bc8,I46294bbf,I74d0b45a,I749eb082,I71224efc, ...

* changes:
  gd_acl: Add ACL connection history
  Add gd/common/strings::StringFormatTimeWithMilliseconds
  bt_headless: Add connect/disconnect timeouts
  Include BTM_PmRegister::callback
  Use main/shim/dumpsys::supervision_timeout_to_seconds
  Add main/shim/dumpsys::supervision_timeout_to_seconds
  bt_headless: Add connect test
parents e3140362 1341cf9b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ void bta_dm_init_pm(void) {
 *
 ******************************************************************************/
void bta_dm_disable_pm(void) {
  BTM_PmRegister(BTM_PM_DEREG, &bta_dm_cb.pm_id, NULL);
  BTM_PmRegister(BTM_PM_DEREG, &bta_dm_cb.pm_id, bta_dm_pm_btm_cback);

  /*
   * Deregister the PM callback from the system handling to prevent
+12 −0
Original line number Diff line number Diff line
@@ -96,5 +96,17 @@ inline std::string StringFormatTime(const std::string& format, const struct std:
  return os.str();
}

inline std::string StringFormatTimeWithMilliseconds(
    const std::string& format,
    std::chrono::time_point<std::chrono::system_clock> time_point,
    struct tm* (*calendar_to_tm)(const time_t* timep) = localtime) {
  std::time_t epoch_time = std::chrono::system_clock::to_time_t(time_point);
  auto millis = time_point.time_since_epoch() / std::chrono::milliseconds(1) % 1000;
  std::tm tm = *calendar_to_tm(&epoch_time);
  std::ostringstream os;
  os << std::put_time(&tm, format.c_str()) << StringFormat(".%03u", millis);
  return os.str();
}

}  // namespace common
}  // namespace bluetooth
+24 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ using bluetooth::common::FromHexString;
using bluetooth::common::Int64FromString;
using bluetooth::common::StringFormat;
using bluetooth::common::StringFormatTime;
using bluetooth::common::StringFormatTimeWithMilliseconds;
using bluetooth::common::StringJoin;
using bluetooth::common::StringSplit;
using bluetooth::common::StringTrim;
@@ -179,8 +180,29 @@ TEST(StringsTest, string_format_time_test) {
  std::string format("%Y-%m-%d %H:%M:%S");
  time_t then = 123456789;
  struct std::tm tm;
  localtime_r(&then, &tm);
  ASSERT_THAT(StringFormatTime(format, tm), StrEq("1973-11-29 13:33:09"));
  gmtime_r(&then, &tm);
  ASSERT_THAT(StringFormatTime(format, tm), StrEq("1973-11-29 21:33:09"));
}

TEST(StringsTest, string_format_time_with_ms_in_the_beginning_test) {
  std::string format("%Y-%m-%d %H:%M:%S");
  std::time_t from_time = 0;
  std::chrono::time_point<std::chrono::system_clock> time_point = std::chrono::system_clock::from_time_t(from_time);

  ASSERT_THAT(StringFormatTimeWithMilliseconds(format, time_point, gmtime), StrEq("1970-01-01 00:00:00.000"));
}

TEST(StringsTest, string_format_time_with_ms_test) {
  std::string format("%Y-%m-%d %H:%M:%S");
  std::time_t from_time1 = 1234567890;
  std::chrono::time_point<std::chrono::system_clock> time_point1 = std::chrono::system_clock::from_time_t(from_time1);
  std::time_t from_time2 = 1234567890;
  std::chrono::time_point<std::chrono::system_clock> time_point2 = std::chrono::system_clock::from_time_t(from_time2);

  time_point2 += std::chrono::milliseconds(1);

  ASSERT_THAT(StringFormatTimeWithMilliseconds(format, time_point1, gmtime), StrEq("2009-02-13 23:31:30.000"));
  ASSERT_THAT(StringFormatTimeWithMilliseconds(format, time_point2, gmtime), StrEq("2009-02-13 23:31:30.001"));
}

}  // namespace testing
+217 −13
Original line number Diff line number Diff line
@@ -42,10 +42,12 @@
#include "main/shim/dumpsys.h"
#include "main/shim/entry.h"
#include "main/shim/helpers.h"
#include "main/shim/stack.h"
#include "stack/acl/acl.h"
#include "stack/btm/btm_int_types.h"
#include "stack/include/acl_hci_link_interface.h"
#include "stack/include/ble_acl_interface.h"
#include "stack/include/btm_api.h"
#include "stack/include/btm_status.h"
#include "stack/include/sec_hci_link_interface.h"
#include "stack/l2cap/l2c_int.h"
@@ -62,12 +64,104 @@ namespace {
using HciHandle = uint16_t;
using PageNumber = uint8_t;

using CreationTime = std::chrono::time_point<std::chrono::system_clock>;
using TeardownTime = std::chrono::time_point<std::chrono::system_clock>;

constexpr PageNumber kRemoteExtendedFeaturesPageZero = 0;
constexpr char kBtmLogTag[] = "ACL";

using SendDataUpwards = void (*const)(BT_HDR*);
using OnDisconnect = std::function<void(HciHandle, hci::ErrorCode reason)>;

constexpr char kConnectionDescriptorTimeFormat[] = "%Y-%m-%d %H:%M:%S";

struct ConnectionDescriptor {
  CreationTime creation_time_;
  TeardownTime teardown_time_;
  uint16_t handle_;
  bool is_locally_initiated_;
  hci::ErrorCode disconnect_reason_;
  ConnectionDescriptor(CreationTime creation_time, TeardownTime teardown_time,
                       uint16_t handle, bool is_locally_initiated,
                       hci::ErrorCode disconnect_reason)
      : creation_time_(creation_time),
        teardown_time_(teardown_time),
        handle_(handle),
        is_locally_initiated_(is_locally_initiated),
        disconnect_reason_(disconnect_reason) {}
  virtual std::string GetPrivateRemoteAddress() const = 0;
  virtual ~ConnectionDescriptor() {}
  std::string ToString() const {
    return base::StringPrintf(
        "peer:%s handle:0x%04x is_locally_initiated:%s"
        " creation_time:%s teardown_time:%s disconnect_reason:%s",
        GetPrivateRemoteAddress().c_str(), handle_,
        logbool(is_locally_initiated_).c_str(),
        bluetooth::common::StringFormatTimeWithMilliseconds(
            kConnectionDescriptorTimeFormat, creation_time_)
            .c_str(),
        bluetooth::common::StringFormatTimeWithMilliseconds(
            kConnectionDescriptorTimeFormat, teardown_time_)
            .c_str(),
        hci::ErrorCodeText(disconnect_reason_).c_str());
  }
};

struct ClassicConnectionDescriptor : public ConnectionDescriptor {
  const hci::Address remote_address_;
  ClassicConnectionDescriptor(const hci::Address& remote_address,
                              CreationTime creation_time,
                              TeardownTime teardown_time, uint16_t handle,
                              bool is_locally_initiated,
                              hci::ErrorCode disconnect_reason)
      : ConnectionDescriptor(creation_time, teardown_time, handle,
                             is_locally_initiated, disconnect_reason),
        remote_address_(remote_address) {}
  virtual std::string GetPrivateRemoteAddress() const {
    return PRIVATE_ADDRESS(remote_address_);
  }
};

struct LeConnectionDescriptor : public ConnectionDescriptor {
  const hci::AddressWithType remote_address_with_type_;
  LeConnectionDescriptor(hci::AddressWithType& remote_address_with_type,
                         CreationTime creation_time, TeardownTime teardown_time,
                         uint16_t handle, bool is_locally_initiated,
                         hci::ErrorCode disconnect_reason)
      : ConnectionDescriptor(creation_time, teardown_time, handle,
                             is_locally_initiated, disconnect_reason),
        remote_address_with_type_(remote_address_with_type) {}
  std::string GetPrivateRemoteAddress() const {
    return PRIVATE_ADDRESS(remote_address_with_type_);
  }
};

template <typename T>
class FixedQueue {
 public:
  explicit FixedQueue(size_t max_size) : max_size_(max_size) {}
  void Push(T element) {
    if (queue_.size() == max_size_) {
      queue_.pop_front();
    }
    queue_.push_back(std::move(element));
  }

  std::vector<std::string> ReadElementsAsString() const {
    std::vector<std::string> vector;
    for (auto& entry : queue_) {
      vector.push_back(entry->ToString());
    }
    return vector;
  }

 private:
  size_t max_size_{1};
  std::deque<T> queue_;
};

constexpr size_t kConnectionHistorySize = 40;

inline uint8_t LowByte(uint16_t val) { return val & 0xff; }
inline uint8_t HighByte(uint16_t val) { return val >> 8; }

@@ -109,11 +203,13 @@ class ShimAclConnection {
 public:
  ShimAclConnection(const HciHandle handle, SendDataUpwards send_data_upwards,
                    os::Handler* handler,
                    hci::acl_manager::AclConnection::QueueUpEnd* queue_up_end)
                    hci::acl_manager::AclConnection::QueueUpEnd* queue_up_end,
                    CreationTime creation_time)
      : handle_(handle),
        handler_(handler),
        send_data_upwards_(send_data_upwards),
        queue_up_end_(queue_up_end) {
        queue_up_end_(queue_up_end),
        creation_time_(creation_time) {
    queue_up_end_->RegisterDequeue(
        handler_, common::Bind(&ShimAclConnection::data_ready_callback,
                               common::Unretained(this)));
@@ -154,6 +250,10 @@ class ShimAclConnection {
  }

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

  CreationTime GetCreationTime() const { return creation_time_; }
  uint16_t Handle() const { return handle_; }

 protected:
  const uint16_t handle_{kInvalidHciHandle};
@@ -181,6 +281,7 @@ class ShimAclConnection {
  std::queue<std::unique_ptr<bluetooth::packet::RawBuilder>> queue_;
  bool is_enqueue_registered_{false};
  bool is_disconnected_{false};
  CreationTime creation_time_;

  void RegisterEnqueue() {
    ASSERT_LOG(!is_disconnected_,
@@ -203,9 +304,10 @@ class ClassicShimAclConnection
      SendDataUpwards send_data_upwards, OnDisconnect on_disconnect,
      const shim::legacy::acl_classic_link_interface_t& interface,
      os::Handler* handler,
      std::unique_ptr<hci::acl_manager::ClassicAclConnection> connection)
      std::unique_ptr<hci::acl_manager::ClassicAclConnection> connection,
      CreationTime creation_time)
      : ShimAclConnection(connection->GetHandle(), send_data_upwards, handler,
                          connection->GetAclQueueEnd()),
                          connection->GetAclQueueEnd(), creation_time),
        on_disconnect_(on_disconnect),
        interface_(interface),
        connection_(std::move(connection)) {}
@@ -378,6 +480,14 @@ class ClassicShimAclConnection
                                       minimum_local_timeout));
  }

  void SetConnectionEncryption(hci::Enable is_encryption_enabled) {
    ASSERT(connection_->SetConnectionEncryption(is_encryption_enabled));
  }

  bool IsLocallyInitiated() const override {
    return connection_->locally_initiated_;
  }

 private:
  OnDisconnect on_disconnect_;
  const shim::legacy::acl_classic_link_interface_t interface_;
@@ -392,9 +502,10 @@ class LeShimAclConnection
      SendDataUpwards send_data_upwards, OnDisconnect on_disconnect,
      const shim::legacy::acl_le_link_interface_t& interface,
      os::Handler* handler,
      std::unique_ptr<hci::acl_manager::LeAclConnection> connection)
      std::unique_ptr<hci::acl_manager::LeAclConnection> connection,
      std::chrono::time_point<std::chrono::system_clock> creation_time)
      : ShimAclConnection(connection->GetHandle(), send_data_upwards, handler,
                          connection->GetAclQueueEnd()),
                          connection->GetAclQueueEnd(), creation_time),
        on_disconnect_(on_disconnect),
        interface_(interface),
        connection_(std::move(connection)) {}
@@ -442,6 +553,10 @@ class LeShimAclConnection
    connection_->Disconnect(reason);
  }

  bool IsLocallyInitiated() const override {
    return connection_->locally_initiated_;
  }

 private:
  OnDisconnect on_disconnect_;
  const shim::legacy::acl_le_link_interface_t interface_;
@@ -454,6 +569,9 @@ struct bluetooth::shim::legacy::Acl::impl {
  std::map<HciHandle, std::unique_ptr<LeShimAclConnection>>
      handle_to_le_connection_map_;

  FixedQueue<std::unique_ptr<ConnectionDescriptor>> connection_history_ =
      FixedQueue<std::unique_ptr<ConnectionDescriptor>>(kConnectionHistorySize);

  bool IsClassicAcl(HciHandle handle) {
    return handle_to_classic_connection_map_.find(handle) !=
           handle_to_classic_connection_map_.end();
@@ -506,6 +624,30 @@ struct bluetooth::shim::legacy::Acl::impl {
      handle_to_classic_connection_map_[handle]->SniffSubrating(
          maximum_latency, minimum_remote_timeout, minimum_local_timeout);
  }

  void SetConnectionEncryption(HciHandle handle, hci::Enable enable) {
    if (ClassicConnectionExists(handle))
      handle_to_classic_connection_map_[handle]->SetConnectionEncryption(
          enable);
  }

  void DumpConnectionHistory() const {
    std::vector<std::string> history =
        connection_history_.ReadElementsAsString();
    for (auto& entry : history) {
      LOG_DEBUG("%s", entry.c_str());
    }
  }

#define DUMPSYS_TAG "shim::acl"
  void DumpConnectionHistory(int fd) const {
    std::vector<std::string> history =
        connection_history_.ReadElementsAsString();
    for (auto& entry : history) {
      LOG_DUMPSYS(fd, "%s", entry.c_str());
    }
  }
#undef DUMPSYS_TAG
};

#define DUMPSYS_TAG "shim::legacy::l2cap"
@@ -536,6 +678,8 @@ void DumpsysAcl(int fd) {

  LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);

  bluetooth::shim::Stack::GetInstance()->GetAcl()->DumpConnectionHistory(fd);

  for (int i = 0; i < MAX_L2CAP_LINKS; i++) {
    const tACL_CONN& acl_conn = acl_cb.acl_db[i];
    const tBTM_PM_MCB& btm_pm_mcb = acl_cb.pm_mode_db[i];
@@ -647,6 +791,39 @@ bluetooth::shim::legacy::Acl::Acl(os::Handler* handler,
bluetooth::shim::legacy::Acl::~Acl() {
  bluetooth::shim::UnregisterDumpsysFunction(static_cast<void*>(this));
  GetController()->UnregisterCompletedMonitorAclPacketsCallback();

  bool dump_connection_history = false;

  if (!pimpl_->handle_to_classic_connection_map_.empty()) {
    LOG_ERROR("About to destroy classic active ACL");
    for (auto& connection : pimpl_->handle_to_classic_connection_map_) {
      LOG_ERROR("  Orphaned classic ACL handle:0x%04x bd_addr:%s created:%s",
                connection.second->Handle(),
                PRIVATE_ADDRESS(connection.second->GetRemoteAddress()),
                bluetooth::common::StringFormatTimeWithMilliseconds(
                    kConnectionDescriptorTimeFormat,
                    connection.second->GetCreationTime())
                    .c_str());
    }
    dump_connection_history = true;
  }

  if (!pimpl_->handle_to_le_connection_map_.empty()) {
    LOG_ERROR("About to destroy le active ACL");
    for (auto& connection : pimpl_->handle_to_le_connection_map_) {
      LOG_ERROR("  Orphaned le ACL handle:0x%04x bd_addr:%s created:%s",
                connection.second->Handle(),
                PRIVATE_ADDRESS(connection.second->GetRemoteAddressWithType()),
                bluetooth::common::StringFormatTimeWithMilliseconds(
                    kConnectionDescriptorTimeFormat,
                    connection.second->GetCreationTime())
                    .c_str());
    }
    dump_connection_history = true;
  }
  if (dump_connection_history) {
    pimpl_->DumpConnectionHistory();
  }
}

void bluetooth::shim::legacy::Acl::on_incoming_acl_credits(uint16_t handle,
@@ -703,6 +880,13 @@ void bluetooth::shim::legacy::Acl::OnClassicLinkDisconnected(
    HciHandle handle, hci::ErrorCode reason) {
  bluetooth::hci::Address remote_address =
      pimpl_->handle_to_classic_connection_map_[handle]->GetRemoteAddress();
  CreationTime creation_time =
      pimpl_->handle_to_classic_connection_map_[handle]->GetCreationTime();
  bool is_locally_initiated =
      pimpl_->handle_to_classic_connection_map_[handle]->IsLocallyInitiated();

  TeardownTime teardown_time = std::chrono::system_clock::now();

  pimpl_->handle_to_classic_connection_map_.erase(handle);
  TRY_POSTING_ON_MAIN(acl_interface_.connection.classic.on_disconnected,
                      ToLegacyHciErrorCode(hci::ErrorCode::SUCCESS), handle,
@@ -713,12 +897,23 @@ void bluetooth::shim::legacy::Acl::OnClassicLinkDisconnected(
  BTM_LogHistory(
      kBtmLogTag, ToRawAddress(remote_address), "Disconnected",
      base::StringPrintf("classic reason:%s", ErrorCodeText(reason).c_str()));
  pimpl_->connection_history_.Push(
      std::move(std::make_unique<ClassicConnectionDescriptor>(
          remote_address, creation_time, teardown_time, handle,
          is_locally_initiated, reason)));
}

void bluetooth::shim::legacy::Acl::OnLeLinkDisconnected(HciHandle handle,
                                                        hci::ErrorCode reason) {
  hci::AddressWithType remote_address_with_type =
      pimpl_->handle_to_le_connection_map_[handle]->GetRemoteAddressWithType();
  CreationTime creation_time =
      pimpl_->handle_to_classic_connection_map_[handle]->GetCreationTime();
  bool is_locally_initiated =
      pimpl_->handle_to_classic_connection_map_[handle]->IsLocallyInitiated();

  TeardownTime teardown_time = std::chrono::system_clock::now();

  pimpl_->handle_to_le_connection_map_.erase(handle);
  TRY_POSTING_ON_MAIN(acl_interface_.connection.le.on_disconnected,
                      ToLegacyHciErrorCode(hci::ErrorCode::SUCCESS), handle,
@@ -730,6 +925,10 @@ void bluetooth::shim::legacy::Acl::OnLeLinkDisconnected(HciHandle handle,
      kBtmLogTag, ToLegacyAddressWithType(remote_address_with_type),
      "Disconnected",
      base::StringPrintf("le reason:%s", ErrorCodeText(reason).c_str()));
  pimpl_->connection_history_.Push(
      std::move(std::make_unique<LeConnectionDescriptor>(
          remote_address_with_type, creation_time, teardown_time, handle,
          is_locally_initiated, reason)));
}

void bluetooth::shim::legacy::Acl::OnConnectSuccess(
@@ -741,12 +940,12 @@ void bluetooth::shim::legacy::Acl::OnConnectSuccess(
  const RawAddress bd_addr = ToRawAddress(remote_address);

  pimpl_->handle_to_classic_connection_map_.emplace(
      handle,
      std::make_unique<ClassicShimAclConnection>(
      handle, std::make_unique<ClassicShimAclConnection>(
                  acl_interface_.on_send_data_upwards,
                  std::bind(&shim::legacy::Acl::OnClassicLinkDisconnected, this,
                            std::placeholders::_1, std::placeholders::_2),
          acl_interface_.link.classic, handler_, std::move(connection)));
                  acl_interface_.link.classic, handler_, std::move(connection),
                  std::chrono::system_clock::now()));
  pimpl_->handle_to_classic_connection_map_[handle]->RegisterCallbacks();
  pimpl_->handle_to_classic_connection_map_[handle]
      ->ReadRemoteControllerInformation();
@@ -787,7 +986,8 @@ void bluetooth::shim::legacy::Acl::OnLeConnectSuccess(
                  acl_interface_.on_send_data_upwards,
                  std::bind(&shim::legacy::Acl::OnLeLinkDisconnected, this,
                            std::placeholders::_1, std::placeholders::_2),
                  acl_interface_.link.le, handler_, std::move(connection)));
                  acl_interface_.link.le, handler_, std::move(connection),
                  std::chrono::system_clock::now()));
  pimpl_->handle_to_le_connection_map_[handle]->RegisterCallbacks();

  pimpl_->handle_to_le_connection_map_[handle]
@@ -926,3 +1126,7 @@ bool bluetooth::shim::legacy::Acl::SniffSubrating(
                   minimum_local_timeout);
  return false;
}

void bluetooth::shim::legacy::Acl::DumpConnectionHistory(int fd) const {
  pimpl_->DumpConnectionHistory(fd);
}
+1 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ class Acl : public hci::acl_manager::ConnectionCallbacks,
  void ConfigureLePrivacy(bool is_le_privacy_enabled);

  void Dump(int fd) const;
  void DumpConnectionHistory(int fd) const;

 protected:
  void on_incoming_acl_credits(uint16_t handle, uint16_t credits);
Loading