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

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

Merge "Handle BQR root inflammation event"

parents c413fec5 6a76766b
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
@@ -35,6 +35,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"
@@ -55,6 +57,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);
@@ -111,7 +114,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;
@@ -166,6 +169,14 @@ void iso_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();
@@ -264,12 +275,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;
@@ -442,7 +447,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);

@@ -451,6 +456,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());
@@ -500,7 +511,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;
  }

@@ -526,13 +537,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
@@ -619,7 +630,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();

@@ -628,6 +643,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
@@ -55,6 +55,7 @@ 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 iso_data_received(BT_HDR* packet);
extern void hal_service_died();

android::sp<V1_0::IBluetoothHci> btHci;
android::sp<V1_1::IBluetoothHci> btHci_1_1;
@@ -63,7 +64,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();