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

Commit 61677dd5 authored by Patty Huang's avatar Patty Huang
Browse files

BQR: Add Bluetooth Quality Report v4 feature

- Add Event Bitmask for LE Audio Choppy
- Extend the link quality report event fields for isochronous channels

Bug: 212222351
Bug: 197297645
Tag: #feature
Test: Verified the BQR event for new added fields.

Change-Id: Ic1de91259d7726750e6e488f243f1901d567eb5b
(cherry picked from commit f726977c)
Merged-In: Ic1de91259d7726750e6e488f243f1901d567eb5b
parent 47bc6c59
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -128,6 +128,8 @@ static int BtSchedulingTraceLogFd = INVALID_FD;
static uint16_t LmpLlMessageTraceCounter = 0;
// Counter of Bluetooth Multi-profile/Coex scheduling trace
static uint16_t BtSchedulingTraceCounter = 0;
// The version supports ISO packets start from v1.01(257)
static constexpr uint16_t kBqrIsoVersion = 257;

// Action definition
//
@@ -147,6 +149,7 @@ enum BqrQualityReportId : uint8_t {
  QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY = 0x03,
  QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04,
  QUALITY_REPORT_ID_ROOT_INFLAMMATION = 0x05,
  QUALITY_REPORT_ID_LE_AUDIO_CHOPPY = 0x07,
  QUALITY_REPORT_ID_LMP_LL_MESSAGE_TRACE = 0x11,
  QUALITY_REPORT_ID_BT_SCHEDULING_TRACE = 0x12,
  QUALITY_REPORT_ID_CONTROLLER_DBG_INFO = 0x13
@@ -181,7 +184,8 @@ enum BqrPacketType : uint8_t {
  PACKET_TYPE_2DH5,
  PACKET_TYPE_3DH1,
  PACKET_TYPE_3DH3,
  PACKET_TYPE_3DH5
  PACKET_TYPE_3DH5,
  PACKET_TYPE_ISO = 0x51
};

// Configuration Parameters
@@ -242,6 +246,20 @@ typedef struct {
  uint32_t buffer_overflow_bytes;
  // Buffer underflow count (in byte).
  uint32_t buffer_underflow_bytes;
  // The number of packets that are sent out.
  uint32_t tx_total_packets;
  // The number of packets that don't receive an acknowledgment.
  uint32_t tx_unacked_packets;
  // The number of packets that are not sent out by its flush point.
  uint32_t tx_flushed_packets;
  // The number of packets that Link Layer transmits a CIS Data PDU in the last
  // subevent of a CIS event.
  uint32_t tx_last_subevent_packets;
  // The number of received packages with CRC error since the last event.
  uint32_t crc_error_packets;
  // The number of duplicate(retransmission) packages that are received since
  // the last event.
  uint32_t rx_duplicate_packets;
  // For the controller vendor to obtain more vendor specific parameters.
  const uint8_t* vendor_specific_parameter;
} BqrLinkQualityEvent;
+40 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "btif_bqr.h"
#include "btif_common.h"
#include "btm_api.h"
#include "btm_ble_api.h"
#include "common/leaky_bonded_queue.h"
#include "common/time_util.h"
#include "osi/include/properties.h"
@@ -40,6 +41,8 @@ using std::chrono::system_clock;
static std::unique_ptr<LeakyBondedQueue<BqrVseSubEvt>> kpBqrEventQueue(
    new LeakyBondedQueue<BqrVseSubEvt>(kBqrEventQueueSize));

static uint16_t vendor_cap_supported_version;

void BqrVseSubEvt::ParseBqrLinkQualityEvt(uint8_t length,
                                          const uint8_t* p_param_buf) {
  if (length < kLinkQualityParamTotalLen) {
@@ -73,6 +76,16 @@ void BqrVseSubEvt::ParseBqrLinkQualityEvt(uint8_t length,
  STREAM_TO_UINT32(bqr_link_quality_event_.buffer_overflow_bytes, p_param_buf);
  STREAM_TO_UINT32(bqr_link_quality_event_.buffer_underflow_bytes, p_param_buf);

  if (vendor_cap_supported_version >= kBqrIsoVersion) {
    STREAM_TO_UINT32(bqr_link_quality_event_.tx_total_packets, p_param_buf);
    STREAM_TO_UINT32(bqr_link_quality_event_.tx_unacked_packets, p_param_buf);
    STREAM_TO_UINT32(bqr_link_quality_event_.tx_flushed_packets, p_param_buf);
    STREAM_TO_UINT32(bqr_link_quality_event_.tx_last_subevent_packets,
                     p_param_buf);
    STREAM_TO_UINT32(bqr_link_quality_event_.crc_error_packets, p_param_buf);
    STREAM_TO_UINT32(bqr_link_quality_event_.rx_duplicate_packets, p_param_buf);
  }

  const auto now = system_clock::to_time_t(system_clock::now());
  localtime_r(&now, &tm_timestamp_);
}
@@ -144,6 +157,22 @@ std::string BqrVseSubEvt::ToString() const {
     << std::to_string(bqr_link_quality_event_.buffer_overflow_bytes)
     << ", UndFlow: "
     << std::to_string(bqr_link_quality_event_.buffer_underflow_bytes);

  if (vendor_cap_supported_version >= kBqrIsoVersion) {
    ss << ", TxTotal: "
       << std::to_string(bqr_link_quality_event_.tx_total_packets)
       << ", TxUnAcked: "
       << std::to_string(bqr_link_quality_event_.tx_unacked_packets)
       << ", TxFlushed: "
       << std::to_string(bqr_link_quality_event_.tx_flushed_packets)
       << ", TxLastSubEvent: "
       << std::to_string(bqr_link_quality_event_.tx_last_subevent_packets)
       << ", CRCError: "
       << std::to_string(bqr_link_quality_event_.crc_error_packets)
       << ", RxDuplicate: "
       << std::to_string(bqr_link_quality_event_.rx_duplicate_packets);
  }

  return ss.str();
}

@@ -157,6 +186,8 @@ std::string QualityReportIdToString(uint8_t quality_report_id) {
      return "A2DP Choppy";
    case QUALITY_REPORT_ID_SCO_VOICE_CHOPPY:
      return "SCO Choppy ";
    case QUALITY_REPORT_ID_LE_AUDIO_CHOPPY:
      return "LE Audio Choppy";
    default:
      return "Invalid    ";
  }
@@ -220,6 +251,8 @@ std::string PacketTypeToString(uint8_t packet_type) {
      return "3DH3";
    case PACKET_TYPE_3DH5:
      return "3DH5";
    case PACKET_TYPE_ISO:
      return "ISO";
    default:
      return "UnKnown ";
  }
@@ -254,9 +287,15 @@ void EnableBtQualityReport(bool is_enable) {
    bqr_config.minimum_report_interval_ms = kMinReportIntervalNoLimit;
  }

  tBTM_BLE_VSC_CB cmn_vsc_cb;
  BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
  vendor_cap_supported_version = cmn_vsc_cb.version_supported;

  LOG(INFO) << __func__
            << ": Event Mask: " << loghex(bqr_config.quality_event_mask)
            << ", Interval: " << bqr_config.minimum_report_interval_ms;
            << ", Interval: " << bqr_config.minimum_report_interval_ms
            << ", vendor_cap_supported_version: "
            << vendor_cap_supported_version;
  ConfigureBqr(bqr_config);
}