OSDN Git Service

btm: Add main/shim/acl:: connection history
authorChris Manton <cmanton@google.com>
Wed, 25 Nov 2020 02:38:19 +0000 (18:38 -0800)
committerChris Manton <cmanton@google.com>
Thu, 3 Dec 2020 00:48:07 +0000 (00:48 +0000)
Toward loggable code

Bug: 163134718
Tag: #refactor
Test: gd/cert/run --host

Change-Id: I48cd10d0d4dee8632614f9b5c74be1f33358dee2

main/shim/acl.cc
main/shim/acl.h
stack/acl/acl.h

index 09efc58..754d1c9 100644 (file)
 
 #include <base/location.h>
 
+#include <time.h>
 #include <chrono>
 #include <cstdint>
 #include <functional>
 #include <map>
 #include <memory>
+#include <string>
 
 #include "gd/common/bidi_queue.h"
 #include "gd/common/bind.h"
+#include "gd/common/strings.h"
 #include "gd/hci/acl_manager.h"
 #include "gd/hci/acl_manager/acl_connection.h"
 #include "gd/hci/acl_manager/classic_acl_connection.h"
 #include "gd/hci/controller.h"
 #include "gd/os/handler.h"
 #include "gd/os/queue.h"
+#include "main/shim/dumpsys.h"
 #include "main/shim/entry.h"
 #include "main/shim/helpers.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_status.h"
 #include "stack/include/sec_hci_link_interface.h"
+#include "stack/l2cap/l2c_int.h"
 
 bt_status_t do_in_main_thread(const base::Location& from_here,
                               base::OnceClosure task);
@@ -419,6 +425,95 @@ struct bluetooth::shim::legacy::Acl::impl {
   }
 };
 
+#define DUMPSYS_TAG "shim::legacy::l2cap"
+extern tL2C_CB l2cb;
+void DumpsysL2cap(int fd) {
+  LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
+  for (int i = 0; i < MAX_L2CAP_LINKS; i++) {
+    const tL2C_LCB& lcb = l2cb.lcb_pool[i];
+    if (!lcb.in_use) continue;
+    LOG_DUMPSYS(fd, "link_state:%s", link_state_text(lcb.link_state).c_str());
+    LOG_DUMPSYS(fd, "handle:0x%04x", lcb.Handle());
+
+    const tL2C_CCB* ccb = lcb.ccb_queue.p_first_ccb;
+    while (ccb != nullptr) {
+      LOG_DUMPSYS(
+          fd, "  active channel lcid:0x%04x rcid:0x%04x is_ecoc:%s in_use:%s",
+          ccb->local_cid, ccb->remote_cid, common::ToString(ccb->ecoc).c_str(),
+          common::ToString(ccb->in_use).c_str());
+      ccb = ccb->p_next_ccb;
+    }
+  }
+}
+
+#undef DUMPSYS_TAG
+#define DUMPSYS_TAG "shim::legacy::acl"
+extern tBTM_CB btm_cb;
+void DumpsysAcl(int fd) {
+  const tACL_CB& acl_cb = btm_cb.acl_cb_;
+
+  LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
+
+  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];
+    if (!acl_conn.in_use) continue;
+
+    LOG_DUMPSYS(fd, "    peer_le_features:%s",
+                bd_features_text(acl_conn.peer_le_features).c_str());
+    for (int j = 0; j < HCI_EXT_FEATURES_PAGE_MAX + 1; j++) {
+      LOG_DUMPSYS(fd, "    peer_lmp_features[%d]:%s", j,
+                  bd_features_text(acl_conn.peer_lmp_feature_pages[j]).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",
+                acl_conn.active_remote_addr.ToString().c_str());
+    LOG_DUMPSYS(fd, "    [le] conn_addr:%s",
+                acl_conn.conn_addr.ToString().c_str());
+    LOG_DUMPSYS(fd, "    link_up_issued:%s",
+                (acl_conn.link_up_issued) ? "true" : "false");
+    LOG_DUMPSYS(fd, "    transport:%s",
+                BtTransportText(acl_conn.transport).c_str());
+    LOG_DUMPSYS(fd, "    flush_timeout:0x%04x",
+                acl_conn.flush_timeout_in_ticks);
+    LOG_DUMPSYS(fd, "    [classic] link_policy:0x%x", acl_conn.link_policy);
+    LOG_DUMPSYS(fd, "    link_super_tout:0x%04x", acl_conn.link_super_tout);
+    LOG_DUMPSYS(fd, "    pkt_types_mask:0x%04x", acl_conn.pkt_types_mask);
+    LOG_DUMPSYS(fd, "    disconnect_reason:0x%02x", acl_conn.disconnect_reason);
+    LOG_DUMPSYS(fd, "    chg_ind:%s", (btm_pm_mcb.chg_ind) ? "true" : "false");
+  }
+}
+#undef DUMPSYS_TAG
+
+using Record = bluetooth::common::TimestampedEntry<std::string>;
+const std::string kTimeFormat("%Y-%m-%d %H:%M:%S");
+
+#define DUMPSYS_TAG "shim::legacy::btm"
+extern tBTM_CB btm_cb;
+void DumpsysBtm(int fd) {
+  LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
+  if (btm_cb.history_ != nullptr) {
+    std::vector<Record> history = btm_cb.history_->Pull();
+    for (auto& record : history) {
+      time_t then = record.timestamp / 1000;
+      struct tm tm;
+      localtime_r(&then, &tm);
+      auto s2 = common::StringFormatTime(kTimeFormat, tm);
+      LOG_DUMPSYS(fd, " %s.%03u %s", s2.c_str(),
+                  static_cast<unsigned int>(record.timestamp % 1000),
+                  record.entry.c_str());
+    }
+  }
+}
+#undef DUMPSYS_TAG
+
+void bluetooth::shim::legacy::Acl::Dump(int fd) const {
+  DumpsysAcl(fd);
+  DumpsysL2cap(fd);
+  DumpsysBtm(fd);
+}
+
 bluetooth::shim::legacy::Acl::Acl(os::Handler* handler,
                                   const acl_interface_t& acl_interface)
     : handler_(handler), acl_interface_(acl_interface) {
@@ -462,6 +557,8 @@ void bluetooth::shim::legacy::Acl::CreateClassicConnection(
   LOG_DEBUG("Initiate the creation of a classic connection %s",
             address.ToString().c_str());
   GetAclManager()->CreateConnection(address);
+  btm_cb.history_->Push("%-32s: %s classic", "Initiated connection",
+                        PRIVATE_ADDRESS(address));
 }
 
 void bluetooth::shim::legacy::Acl::CreateLeConnection(
@@ -469,40 +566,53 @@ void bluetooth::shim::legacy::Acl::CreateLeConnection(
   GetAclManager()->CreateLeConnection(address_with_type);
   LOG_DEBUG("Started Le device to connection %s",
             address_with_type.ToString().c_str());
+  btm_cb.history_->Push("%-32s: %s le", "Initiated connection",
+                        PRIVATE_ADDRESS(address_with_type));
 }
 
 void bluetooth::shim::legacy::Acl::CancelLeConnection(
     const bluetooth::hci::AddressWithType& address_with_type) {
-  LOG_DEBUG("Terminate and cancel a le connection %s",
-            address_with_type.ToString().c_str());
   GetAclManager()->CancelLeConnect(address_with_type);
+  LOG_DEBUG("Canceled le connection %s", address_with_type.ToString().c_str());
+  btm_cb.history_->Push("%-32s: %s le", "Cancelled connection",
+                        PRIVATE_ADDRESS(address_with_type));
 }
 
 void bluetooth::shim::legacy::Acl::OnClassicLinkDisconnected(
     HciHandle handle, hci::ErrorCode reason) {
   LOG_DEBUG("Classic link disconnected handle:%hu reason:%s", handle,
             ErrorCodeText(reason).c_str());
+  bluetooth::hci::Address remote_address =
+      pimpl_->handle_to_classic_connection_map_[handle]->GetRemoteAddress();
+  pimpl_->handle_to_classic_connection_map_.erase(handle);
   TRY_POSTING_ON_MAIN(acl_interface_.connection.classic.on_disconnected,
                       ToLegacyHciErrorCode(hci::ErrorCode::SUCCESS), handle,
                       ToLegacyHciErrorCode(reason));
-  pimpl_->handle_to_classic_connection_map_.erase(handle);
+  btm_cb.history_->Push("%-32s: %s classic reason:%s", "Disconnected",
+                        PRIVATE_ADDRESS(remote_address),
+                        ErrorCodeText(reason).c_str());
 }
 
 void bluetooth::shim::legacy::Acl::OnLeLinkDisconnected(HciHandle handle,
                                                         hci::ErrorCode reason) {
   LOG_DEBUG("Le link disconnected handle:%hu reason:%s", handle,
             ErrorCodeText(reason).c_str());
+  hci::AddressWithType remote_address_with_type =
+      pimpl_->handle_to_le_connection_map_[handle]->GetRemoteAddressWithType();
   pimpl_->handle_to_le_connection_map_.erase(handle);
   TRY_POSTING_ON_MAIN(acl_interface_.connection.le.on_disconnected,
                       ToLegacyHciErrorCode(hci::ErrorCode::SUCCESS), handle,
                       ToLegacyHciErrorCode(reason));
-  pimpl_->handle_to_le_connection_map_.erase(handle);
+  btm_cb.history_->Push("%-32s: %s le reason:%s", "Disconnected",
+                        PRIVATE_ADDRESS(remote_address_with_type),
+                        ErrorCodeText(reason).c_str());
 }
 
 void bluetooth::shim::legacy::Acl::OnConnectSuccess(
     std::unique_ptr<hci::acl_manager::ClassicAclConnection> connection) {
   ASSERT(connection != nullptr);
   auto handle = connection->GetHandle();
+  bool locally_initiated = connection->locally_initiated_;
   const RawAddress bd_addr = ToRawAddress(connection->GetAddress());
 
   pimpl_->handle_to_classic_connection_map_.emplace(
@@ -518,15 +628,21 @@ void bluetooth::shim::legacy::Acl::OnConnectSuccess(
 
   TRY_POSTING_ON_MAIN(acl_interface_.connection.classic.on_connected, bd_addr,
                       handle, HCI_SUCCESS, false);
+  btm_cb.history_->Push(
+      "%-32s: %s %s classic", "Connection successful", PRIVATE_ADDRESS(bd_addr),
+      (locally_initiated) ? "Local initiated" : "Remote initiated");
 }
 
 void bluetooth::shim::legacy::Acl::OnConnectFail(hci::Address address,
                                                  hci::ErrorCode reason) {
   const RawAddress bd_addr = ToRawAddress(address);
-  LOG_WARN("Classic ACL connection failed peer:%s reason:%s",
-           address.ToString().c_str(), hci::ErrorCodeText(reason).c_str());
   TRY_POSTING_ON_MAIN(acl_interface_.connection.classic.on_failed, bd_addr,
                       kInvalidHciHandle, HCI_SUCCESS, false);
+  LOG_WARN("Classic ACL connection failed peer:%s reason:%s",
+           address.ToString().c_str(), hci::ErrorCodeText(reason).c_str());
+  btm_cb.history_->Push("%-32s: %s classic reason:%s", "Connection failed",
+                        PRIVATE_ADDRESS(address),
+                        hci::ErrorCodeText(reason).c_str());
 }
 
 void bluetooth::shim::legacy::Acl::OnLeConnectSuccess(
@@ -536,6 +652,7 @@ void bluetooth::shim::legacy::Acl::OnLeConnectSuccess(
   auto handle = connection->GetHandle();
 
   bluetooth::hci::Role connection_role = connection->GetRole();
+  bool locally_initiated = connection->locally_initiated_;
 
   pimpl_->handle_to_le_connection_map_.emplace(
       handle, std::make_unique<LeShimAclConnection>(
@@ -563,12 +680,15 @@ void bluetooth::shim::legacy::Acl::OnLeConnectSuccess(
       acl_interface_.connection.le.on_connected, legacy_address_with_type,
       handle, static_cast<uint8_t>(connection_role), conn_interval,
       conn_latency, conn_timeout, local_rpa, peer_rpa, peer_addr_type);
+
+  btm_cb.history_->Push(
+      "%-32s: %s %s le", "Connection successful",
+      PRIVATE_ADDRESS(address_with_type),
+      (locally_initiated) ? "Local Initiate" : "Remote initiate");
 }
 
 void bluetooth::shim::legacy::Acl::OnLeConnectFail(
     hci::AddressWithType address_with_type, hci::ErrorCode reason) {
-  LOG_WARN("Le ACL failed peer:%s", address_with_type.ToString().c_str());
-
   tBLE_BD_ADDR legacy_address_with_type =
       ToLegacyAddressWithType(address_with_type);
 
@@ -578,6 +698,10 @@ void bluetooth::shim::legacy::Acl::OnLeConnectFail(
 
   TRY_POSTING_ON_MAIN(acl_interface_.connection.le.on_failed,
                       legacy_address_with_type, handle, enhanced, status);
+  LOG_WARN("Le ACL failed peer:%s", address_with_type.ToString().c_str());
+  btm_cb.history_->Push("%-32s: %s le reason:%s", "Connection failed",
+                        PRIVATE_ADDRESS(address_with_type),
+                        hci::ErrorCodeText(reason).c_str());
 }
 
 void bluetooth::shim::legacy::Acl::ConfigureLePrivacy(
index 9912439..e3a2a26 100644 (file)
@@ -59,6 +59,8 @@ class Acl : public hci::acl_manager::ConnectionCallbacks,
 
   void ConfigureLePrivacy(bool is_le_privacy_enabled);
 
+  void Dump(int fd) const;
+
  protected:
   void on_incoming_acl_credits(uint16_t handle, uint16_t credits);
   void write_data_sync(uint16_t hci_handle,
index 1e54481..72e34fc 100644 (file)
@@ -157,6 +157,8 @@ typedef struct {
     return is_switch_role_switching() || is_switch_role_in_progress();
   }
 
+  friend void DumpsysL2cap(int fd);
+
  public:
   uint8_t sca; /* Sleep clock accuracy */
 } tACL_CONN;
@@ -238,6 +240,8 @@ typedef struct {
   friend void btm_read_remote_version_complete_raw(uint8_t* p);
   friend void btm_read_rssi_complete(uint8_t* p);
   friend void btm_read_tx_power_complete(uint8_t* p, bool is_ble);
+  friend void DumpsysL2cap(int fd);
+  friend void DumpsysAcl(int fd);
 
   friend struct StackAclBtmAcl;
   friend struct StackAclBtmPm;