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

Commit fc966368 authored by Łukasz Rymanowski (xWF)'s avatar Łukasz Rymanowski (xWF) Committed by Gerrit Code Review
Browse files

Merge "gatt: Extend dumpsys information" into main

parents f573541f 62a595e9
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -28,10 +28,13 @@
#include <unordered_set>
#include <vector>

#include "common/circular_buffer.h"
#include "common/init_flags.h"
#include "common/strings.h"
#include "gatt_api.h"
#include "internal_include/bt_target.h"
#include "macros.h"
#include "main/shim/dumpsys.h"
#include "osi/include/fixed_queue.h"
#include "stack/include/bt_hdr.h"
#include "types/bluetooth/uuid.h"
@@ -465,6 +468,34 @@ extern tGATT_CB gatt_cb;
void gatt_set_err_rsp(bool enable, uint8_t req_op_code, uint8_t err_status);
#endif

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

constexpr unsigned MillisPerSecond = 1000;
inline std::string EpochMillisToString(long long time_ms) {
  time_t time_sec = time_ms / MillisPerSecond;
  struct tm tm;
  localtime_r(&time_sec, &tm);
  std::string s = bluetooth::common::StringFormatTime(kTimeFormatString, tm);
  return base::StringPrintf("%s.%03u", s.c_str(),
                            static_cast<unsigned int>(time_ms % MillisPerSecond));
}
}  // namespace

struct tTCB_STATE_HISTORY {
  RawAddress address;
  tBT_TRANSPORT transport;
  tGATT_CH_STATE state;
  std::string holders_info;
  std::string ToString() const {
    return base::StringPrintf("%s, %s, state: %s, %s", ADDRESS_TO_LOGGABLE_CSTR(address),
                              bt_transport_text(transport).c_str(),
                              gatt_channel_state_text(state).c_str(), holders_info.c_str());
  }
};

extern bluetooth::common::TimestampedCircularBuffer<tTCB_STATE_HISTORY> tcb_state_history_;

/* from gatt_main.cc */
bool gatt_disconnect(tGATT_TCB* p_tcb);
void gatt_cancel_connect(const RawAddress& bd_addr, tBT_TRANSPORT transport);
@@ -584,6 +615,7 @@ bool gatt_tcb_get_cid_available_for_indication(tGATT_TCB* p_tcb, bool eatt_suppo
bool gatt_tcb_find_indicate_handle(tGATT_TCB& tcb, uint16_t cid, uint16_t* indicated_handle_p);
uint16_t gatt_tcb_get_att_cid(tGATT_TCB& tcb, bool eatt_support);
uint16_t gatt_tcb_get_payload_size(tGATT_TCB& tcb, uint16_t cid);
std::string gatt_tcb_get_holders_info_string(const tGATT_TCB* p_tcb);
void gatt_clcb_invalidate(tGATT_TCB* p_tcb, const tGATT_CLCB* p_clcb);
uint16_t gatt_get_mtu(const RawAddress& bda, tBT_TRANSPORT transport);
bool gatt_is_pending_mtu_exchange(tGATT_TCB* p_tcb);
+34 −3
Original line number Diff line number Diff line
@@ -55,6 +55,9 @@
using bluetooth::eatt::EattExtension;
using namespace bluetooth;

bluetooth::common::TimestampedCircularBuffer<tTCB_STATE_HISTORY> tcb_state_history_(
        100 /*history size*/);

/******************************************************************************/
/*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
/******************************************************************************/
@@ -338,6 +341,12 @@ static bool gatt_update_app_hold_link_status(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
    } else {
      log::warn("attempt to add already existing gatt_if={}", gatt_if);
    }

    auto holders_string = gatt_tcb_get_holders_info_string(p_tcb);
    tcb_state_history_.Push({.address = p_tcb->peer_bda,
                             .transport = p_tcb->transport,
                             .state = p_tcb->ch_state,
                             .holders_info = holders_string});
    return true;
  }

@@ -348,6 +357,12 @@ static bool gatt_update_app_hold_link_status(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
  }

  log::info("removed gatt_if={}", gatt_if);

  auto holders_string = gatt_tcb_get_holders_info_string(p_tcb);
  tcb_state_history_.Push({.address = p_tcb->peer_bda,
                           .transport = p_tcb->transport,
                           .state = p_tcb->ch_state,
                           .holders_info = holders_string});
  return true;
}

@@ -416,7 +431,13 @@ void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb, bool is_a
        gatt_disconnect(p_tcb);
      }
    } else {
      log::info("is_add=false, but some app is still using the ACL link");
      auto holders = gatt_tcb_get_holders_info_string(p_tcb);
      log::info("is_add=false, but some app is still using the ACL link. {}", holders);

      tcb_state_history_.Push({.address = p_tcb->peer_bda,
                               .transport = p_tcb->transport,
                               .state = p_tcb->ch_state,
                               .holders_info = holders});
    }
  }
}
@@ -1261,7 +1282,16 @@ void gatt_set_ch_state(tGATT_TCB* p_tcb, tGATT_CH_STATE ch_state) {
    return;
  }

  log::verbose("old={} new=0x{:x}", p_tcb->ch_state, static_cast<uint8_t>(ch_state));
  std::string holders_string = gatt_tcb_get_holders_info_string(p_tcb);
  log::verbose("{}, transport: {}, state: {} -> {}, {}", p_tcb->peer_bda,
               bt_transport_text(p_tcb->transport), gatt_channel_state_text(p_tcb->ch_state),
               gatt_channel_state_text(ch_state), holders_string);

  tcb_state_history_.Push({.address = p_tcb->peer_bda,
                           .transport = p_tcb->transport,
                           .state = ch_state,
                           .holders_info = holders_string});

  p_tcb->ch_state = ch_state;
}

@@ -1271,6 +1301,7 @@ tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb) {
    return GATT_CH_CLOSE;
  }

  log::verbose("gatt_get_ch_state: ch_state={}", p_tcb->ch_state);
  log::verbose("{}, transport {},  ch_state={}", p_tcb->peer_bda,
               bt_transport_text(p_tcb->transport), gatt_channel_state_text(p_tcb->ch_state));
  return p_tcb->ch_state;
}
+26 −2
Original line number Diff line number Diff line
@@ -453,6 +453,21 @@ tGATT_TCB* gatt_find_tcb_by_addr(const RawAddress& bda, tBT_TRANSPORT transport)
  return p_tcb;
}

std::string gatt_tcb_get_holders_info_string(const tGATT_TCB* p_tcb) {
  std::stringstream stream;

  if (p_tcb->app_hold_link.size() == 0) {
    stream << "No ACL holders";
  } else {
    stream << "ACL holders gatt_if:";

    for (auto gatt_if : p_tcb->app_hold_link) {
      stream << static_cast<int>(gatt_if) << ",";
    }
  }
  return stream.str();
}

/*******************************************************************************
 *
 * Function     gatt_tcb_dump
@@ -462,10 +477,18 @@ tGATT_TCB* gatt_find_tcb_by_addr(const RawAddress& bda, tBT_TRANSPORT transport)
 * Returns      void
 *
 ******************************************************************************/
#define DUMPSYS_TAG "stack::gatt"
void gatt_tcb_dump(int fd) {
  std::stringstream stream;
  int in_use_cnt = 0;

  auto copy = tcb_state_history_.Pull();
  LOG_DUMPSYS(fd, "   last %zu tcb state transitions:", copy.size());
  for (const auto& it : copy) {
    LOG_DUMPSYS(fd, "   %s %s", EpochMillisToString(it.timestamp).c_str(),
                it.entry.ToString().c_str());
  }

  for (int i = 0; i < gatt_get_max_phy_channel(); i++) {
    tGATT_TCB* p_tcb = &gatt_cb.tcb[i];

@@ -474,14 +497,15 @@ void gatt_tcb_dump(int fd) {
      stream << "  id: " << +p_tcb->tcb_idx
             << "  address: " << ADDRESS_TO_LOGGABLE_STR(p_tcb->peer_bda)
             << "  transport: " << bt_transport_text(p_tcb->transport)
             << "  ch_state: " << gatt_channel_state_text(p_tcb->ch_state);
      stream << "\n";
             << "  ch_state: " << gatt_channel_state_text(p_tcb->ch_state) << ", "
             << gatt_tcb_get_holders_info_string(p_tcb) << "\n";
    }
  }

  dprintf(fd, "TCB (GATT_MAX_PHY_CHANNEL: %d) in_use: %d\n%s\n", gatt_get_max_phy_channel(),
          in_use_cnt, stream.str().c_str());
}
#undef DUMPSYS_TAG

/*******************************************************************************
 *
+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@

static bluetooth::gatt::MockGattInterface* gatt_interface = nullptr;

bluetooth::common::TimestampedCircularBuffer<tTCB_STATE_HISTORY> tcb_state_history_(
        100 /*history size*/);

void bluetooth::gatt::SetMockGattInterface(MockGattInterface* mock_gatt_interface) {
  gatt_interface = mock_gatt_interface;
}