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

Commit 4e5e965c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Handle BQR root inflammation event" into qt-qpr1-dev

parents b806184d 6095c9b0
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -67,6 +67,11 @@ static constexpr int8_t kCriWarnRssi = -80;
static constexpr uint8_t kCriWarnUnusedCh = 55;
// The queue size of recording the BQR events.
static constexpr uint8_t kBqrEventQueueSize = 25;
// The minimum size of the ROOT_INFLAMMATION event
// HCI_VENDOR_SPECIFIC_EVT(1) + BQR sub event(1) + BQR report ID(1) +
// error code(1) + vendor error code(1) = 5
static constexpr uint8_t kRootInflammationPacketMinSize = 5;

// The Property of BQR event mask configuration.
static constexpr const char* kpPropertyEventMask =
    "persist.bluetooth.bqr.event_mask";
@@ -90,7 +95,8 @@ enum BqrQualityReportId : uint8_t {
  QUALITY_REPORT_ID_MONITOR_MODE = 0x01,
  QUALITY_REPORT_ID_APPROACH_LSTO = 0x02,
  QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY = 0x03,
  QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04
  QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04,
  QUALITY_REPORT_ID_ROOT_INFLAMMATION = 0x05
};

// Packet Type definition
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ cc_library_static {
        "packages/modules/Bluetooth/system/stack/include",
        "packages/modules/Bluetooth/system/utils/include",
        "packages/modules/Bluetooth/system/bta/include",
        "packages/modules/Bluetooth/system/btif/include",
        "system/libhwbinder/include",
    ],
}
+78 −20
Original line number Diff line number Diff line
@@ -36,10 +36,12 @@
#include <mutex>

#include "btcore/include/module.h"
#include "btif/include/btif_bqr.h"
#include "btsnoop.h"
#include "buffer_allocator.h"
#include "common/message_loop_thread.h"
#include "common/metrics.h"
#include "common/once_timer.h"
#include "hci_inject.h"
#include "hci_internals.h"
#include "hcidefs.h"
@@ -54,6 +56,7 @@
#define BT_HCI_TIMEOUT_TAG_NUM 1010000

using bluetooth::common::MessageLoopThread;
using bluetooth::common::OnceTimer;

extern void hci_initialize();
extern void hci_transmit(BT_HDR* packet);
@@ -110,7 +113,7 @@ static std::queue<base::Closure> command_queue;
static alarm_t* command_response_timer;
static list_t* commands_pending_response;
static std::recursive_timed_mutex commands_pending_response_mutex;
static alarm_t* hci_timeout_abort_timer;
static OnceTimer abort_timer;

// The hand-off point for data going to a higher layer, set by the higher layer
static base::Callback<void(const base::Location&, BT_HDR*)> send_data_upwards;
@@ -160,6 +163,14 @@ void sco_data_received(BT_HDR* packet) {
  packet_fragmenter->reassemble_and_dispatch(packet);
}

void hal_service_died() {
  if (abort_timer.IsScheduled()) {
    LOG(ERROR) << "abort_timer is scheduled, wait for timeout";
    return;
  }
  abort();
}

// Module lifecycle functions

static future_t* hci_module_shut_down();
@@ -258,12 +269,6 @@ static future_t* hci_module_shut_down() {

  packet_fragmenter->cleanup();

  // Clean up abort timer, if it exists.
  if (hci_timeout_abort_timer != NULL) {
    alarm_free(hci_timeout_abort_timer);
    hci_timeout_abort_timer = NULL;
  }

  if (hci_firmware_log_fd != INVALID_FD) {
    hci_close_firmware_log_file(hci_firmware_log_fd);
    hci_firmware_log_fd = INVALID_FD;
@@ -436,7 +441,7 @@ static void fragmenter_transmit_finished(BT_HDR* packet,
}

// Abort.  The chip has had time to write any debugging information.
static void hci_timeout_abort(void* unused_data) {
static void hci_timeout_abort(void) {
  LOG_ERROR(LOG_TAG, "%s restarting the Bluetooth process.", __func__);
  hci_close_firmware_log_file(hci_firmware_log_fd);

@@ -445,6 +450,12 @@ static void hci_timeout_abort(void* unused_data) {
  abort();
}

static void hci_root_inflamed_abort(uint8_t error_code,
                                    uint8_t vendor_error_code) {
  LOG(FATAL) << __func__ << ": error_code = " << std::to_string(error_code)
             << ", vendor_error_code = " << std::to_string(vendor_error_code);
}

static void command_timed_out_log_info(void* original_wait_entry) {
  LOG_ERROR(LOG_TAG, "%s: %d commands pending response", __func__,
            get_num_waiting_commands());
@@ -494,7 +505,7 @@ static void command_timed_out(void* original_wait_entry) {
  }

  // Don't request a firmware dump for multiple hci timeouts
  if (hci_timeout_abort_timer != NULL || hci_firmware_log_fd != INVALID_FD) {
  if (hci_firmware_log_fd != INVALID_FD) {
    return;
  }

@@ -521,13 +532,13 @@ static void command_timed_out(void* original_wait_entry) {
  osi_free(bt_hdr);
  LOG_ERROR(LOG_TAG, "%s: Setting a timer to restart.", __func__);

  hci_timeout_abort_timer = alarm_new("hci.hci_timeout_aborter");
  if (!hci_timeout_abort_timer) {
  // alarm_default_callbacks thread post to hci_thread.
  if (!abort_timer.Schedule(
          hci_thread.GetWeakPtr(), FROM_HERE, base::Bind(hci_timeout_abort),
          base::TimeDelta::FromMilliseconds(COMMAND_TIMEOUT_RESTART_MS))) {
    LOG_ERROR(LOG_TAG, "%s unable to create an abort timer.", __func__);
    abort();
  }
  alarm_set(hci_timeout_abort_timer, COMMAND_TIMEOUT_RESTART_MS,
            hci_timeout_abort, nullptr);
}

// Event/packet receiving functions
@@ -614,7 +625,11 @@ static bool filter_incoming_event(BT_HDR* packet) {
    }

    goto intercepted;
  } else if (event_code == HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT) {
  } else if (event_code == HCI_VENDOR_SPECIFIC_EVT) {
    uint8_t sub_event_code;
    STREAM_TO_UINT8(sub_event_code, stream);

    if (sub_event_code == HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT) {
      if (hci_firmware_log_fd == INVALID_FD)
        hci_firmware_log_fd = hci_open_firmware_log_file();

@@ -623,6 +638,49 @@ static bool filter_incoming_event(BT_HDR* packet) {

      buffer_allocator->free(packet);
      return true;
    } else if (sub_event_code == HCI_VSE_SUBCODE_BQR_SUB_EVT) {
      uint8_t bqr_report_id;
      STREAM_TO_UINT8(bqr_report_id, stream);

      if (bqr_report_id ==
              bluetooth::bqr::QUALITY_REPORT_ID_ROOT_INFLAMMATION &&
          packet->len >= bluetooth::bqr::kRootInflammationPacketMinSize) {
        uint8_t error_code;
        uint8_t vendor_error_code;
        STREAM_TO_UINT8(error_code, stream);
        STREAM_TO_UINT8(vendor_error_code, stream);
        // TODO(ugoyu) Report to bluetooth metrics here

        LOG(ERROR) << __func__
                   << ": Root inflammation event! setting timer to restart.";
        {
          // Try to stop hci command and startup timers
          std::unique_lock<std::recursive_timed_mutex> lock(
              commands_pending_response_mutex, std::defer_lock);
          if (lock.try_lock_for(std::chrono::milliseconds(
                  COMMAND_PENDING_MUTEX_ACQUIRE_TIMEOUT_MS))) {
            if (alarm_is_scheduled(startup_timer)) {
              alarm_cancel(startup_timer);
            }
            if (alarm_is_scheduled(command_response_timer)) {
              alarm_cancel(command_response_timer);
            }
          } else {
            LOG(ERROR) << __func__ << ": Failed to obtain mutex";
          }
        }

        // HwBinder thread post to hci_thread
        if (!abort_timer.Schedule(hci_thread.GetWeakPtr(), FROM_HERE,
                                  base::Bind(hci_root_inflamed_abort,
                                             error_code, vendor_error_code),
                                  base::TimeDelta::FromMilliseconds(
                                      COMMAND_TIMEOUT_RESTART_MS))) {
          LOG(ERROR) << "Failed to schedule abort_timer!";
          hci_root_inflamed_abort(error_code, vendor_error_code);
        }
      }
    }
  }

  return false;
+2 −1
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ extern void initialization_complete();
extern void hci_event_received(const base::Location& from_here, BT_HDR* packet);
extern void acl_event_received(BT_HDR* packet);
extern void sco_data_received(BT_HDR* packet);
extern void hal_service_died();

android::sp<IBluetoothHci> btHci;

@@ -58,7 +59,7 @@ class BluetoothHciDeathRecipient : public hidl_death_recipient {
 public:
  virtual void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
    LOG_ERROR(LOG_TAG, "Bluetooth HAL service died!");
    abort();
    hal_service_died();
  }
};
android::sp<BluetoothHciDeathRecipient> bluetoothHciDeathRecipient = new BluetoothHciDeathRecipient();