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

Commit 386ded10 authored by Barry Wang's avatar Barry Wang Committed by Gerrit Code Review
Browse files

Merge "BQR: Add Bluetooth Quality Report v6 feature" into main

parents b52f1bdf 2900c804
Loading
Loading
Loading
Loading
+26 −2
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@ static constexpr uint32_t kQualityEventMaskRootInflammation = 0x1 << 4;
static constexpr uint32_t kQualityEventMaskEnergyMonitoring = 0x1 << 5;
static constexpr uint32_t kQualityEventMaskLeAudioChoppy = 0x1 << 6;
static constexpr uint32_t kQualityEventMaskConnectFail = 0x1 << 7;
static constexpr uint32_t kQualityEventMaskAdvRFStatsEvent = 0x1 << 8;
static constexpr uint32_t kQualityEventMaskAdvRFStatsMonitor = 0x1 << 9;
static constexpr uint32_t kQualityEventMaskVendorSpecificQuality = 0x1 << 15;
static constexpr uint32_t kQualityEventMaskLmpMessageTrace = 0x1 << 16;
static constexpr uint32_t kQualityEventMaskBtSchedulingTrace = 0x1 << 17;
@@ -98,14 +100,22 @@ static constexpr uint32_t kQualityEventMaskAll =
    kQualityEventMaskA2dpAudioChoppy | kQualityEventMaskScoVoiceChoppy |
    kQualityEventMaskRootInflammation | kQualityEventMaskEnergyMonitoring |
    kQualityEventMaskLeAudioChoppy | kQualityEventMaskConnectFail |
    kQualityEventMaskAdvRFStatsEvent | kQualityEventMaskAdvRFStatsMonitor |
    kQualityEventMaskVendorSpecificQuality | kQualityEventMaskLmpMessageTrace |
    kQualityEventMaskBtSchedulingTrace | kQualityEventMaskControllerDbgInfo |
    kQualityEventMaskVendorSpecificTrace;
// Define the minimum time interval (in ms) of quality event reporting for the
// selected quality event(s). Controller Firmware should not report the next
// event within the defined time interval.
// event within the defined Minimum Report Interval * Report Interval
// Multiple.
static constexpr uint16_t kMinReportIntervalNoLimit = 0;
static constexpr uint16_t kMinReportIntervalMaxMs = 0xFFFF;
// Define the Report Interval Multiple of quality event reporting for the
// selected quality event(s). Controller Firmware should not report the next
// event within interval: Minimum Report interval * Report Interval Multiple.
// When Report Interval Multiple set to 0 is equal set to 1
static constexpr uint32_t kReportIntervalMultipleNoLimit = 0;
static constexpr uint32_t kReportIntervalMultipleMax = 0xFFFFFFFF;
// The maximum count of Log Dump related event can be written in the log file.
static constexpr uint16_t kLogDumpEventPerFile = 0x00FF;
// Total length of all parameters of the link Quality related event except
@@ -122,6 +132,8 @@ static constexpr uint8_t kLogDumpParamTotalLen = 3;
// Remote address and calibration failure count parameters len
// Added in BQR V5.0
static constexpr uint8_t kVersion5_0ParamsTotalLen = 7;
// Added in BQR V6.0
static constexpr uint8_t kVersion6_0ParamsTotalLen = 6;
// Warning criteria of the RSSI value.
static constexpr int8_t kCriWarnRssi = -80;
// Warning criteria of the unused AFH channel count.
@@ -140,6 +152,9 @@ static constexpr const char* kpPropertyVndTraceMask =
// The Property of BQR minimum report interval configuration.
static constexpr const char* kpPropertyMinReportIntervalMs =
    "persist.bluetooth.bqr.min_interval_ms";
// The Property of BQR minimum report interval multiple.
static constexpr const char* kpPropertyIntervalMultiple =
    "persist.bluetooth.bqr.interval_multiple";
// Path of the LMP/LL message trace log file.
static constexpr const char* kpLmpLlMessageTraceLogPath =
    "/data/misc/bluetooth/logs/lmp_ll_message_trace.log";
@@ -174,6 +189,8 @@ static constexpr uint16_t kBqrVndLogVersion = 0x102;
// The version supports remote address info and calibration failure count
// start from v1.03(259)
static constexpr uint16_t kBqrVersion5_0 = 0x103;
// The REPORT_ACTION_QUERY and BQR_Report_interval starting v1.04(260)
static constexpr uint16_t kBqrVersion6_0 = 0x104;

// Action definition
//
@@ -183,7 +200,8 @@ static constexpr uint16_t kBqrVersion5_0 = 0x103;
enum BqrReportAction : uint8_t {
  REPORT_ACTION_ADD = 0x00,
  REPORT_ACTION_DELETE = 0x01,
  REPORT_ACTION_CLEAR = 0x02
  REPORT_ACTION_CLEAR = 0x02,
  REPORT_ACTION_QUERY = 0x03
};

// Report ID definition
@@ -242,6 +260,7 @@ typedef struct {
  uint16_t minimum_report_interval_ms;
  uint32_t vnd_quality_mask;
  uint32_t vnd_trace_mask;
  uint32_t report_interval_multiple;
} BqrConfiguration;

// Link quality related BQR event
@@ -313,6 +332,11 @@ typedef struct {
  // The number of duplicate(retransmission) packages that are received since
  // the last event.
  uint32_t rx_duplicate_packets;
  // The number of unreceived packets is the same as the parameter of LE Read
  // ISO Link Quality command.
  uint32_t rx_unreceived_packets;
  // Bitmask to indicate various coex related information
  uint16_t coex_info_mask;
  // For the controller vendor to obtain more vendor specific parameters.
  const uint8_t* vendor_specific_parameter;
} BqrLinkQualityEvent;
+71 −16
Original line number Diff line number Diff line
@@ -126,6 +126,23 @@ void BqrVseSubEvt::ParseBqrLinkQualityEvt(uint8_t length,
    }
  }

  if (vendor_cap_supported_version >= kBqrVersion6_0) {
    if (length < kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen +
                     kVersion5_0ParamsTotalLen + kVersion6_0ParamsTotalLen) {
      log::warn(
          "Parameter total length: {} is abnormal. "
          "vendor_cap_supported_version: {}  (>= kBqrVersion6_0={}), It should "
          "not be shorter than: {}",
          length, vendor_cap_supported_version, kBqrVersion6_0,
          kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen +
              kVersion5_0ParamsTotalLen + kVersion6_0ParamsTotalLen);
    } else {
      STREAM_TO_UINT32(bqr_link_quality_event_.rx_unreceived_packets,
                       p_param_buf);
      STREAM_TO_UINT16(bqr_link_quality_event_.coex_info_mask, p_param_buf);
    }
  }

  const auto now = system_clock::to_time_t(system_clock::now());
  localtime_r(&now, &tm_timestamp_);
}
@@ -312,10 +329,12 @@ void EnableBtQualityReport(bool is_enable) {
  char bqr_prop_interval_ms[PROPERTY_VALUE_MAX] = {0};
  char bqr_prop_vnd_quality_mask[PROPERTY_VALUE_MAX] = {0};
  char bqr_prop_vnd_trace_mask[PROPERTY_VALUE_MAX] = {0};
  char bqr_prop_interval_multiple[PROPERTY_VALUE_MAX] = {0};
  osi_property_get(kpPropertyEventMask, bqr_prop_evtmask, "");
  osi_property_get(kpPropertyMinReportIntervalMs, bqr_prop_interval_ms, "");
  osi_property_get(kpPropertyVndQualityMask, bqr_prop_vnd_quality_mask, "");
  osi_property_get(kpPropertyVndTraceMask, bqr_prop_vnd_trace_mask, "");
  osi_property_get(kpPropertyIntervalMultiple, bqr_prop_interval_multiple, "");

  if (strlen(bqr_prop_evtmask) == 0 || strlen(bqr_prop_interval_ms) == 0) {
    log::warn(
@@ -337,39 +356,59 @@ void EnableBtQualityReport(bool is_enable) {
        static_cast<uint32_t>(atoi(bqr_prop_vnd_quality_mask));
    bqr_config.vnd_trace_mask =
        static_cast<uint32_t>(atoi(bqr_prop_vnd_trace_mask));
    bqr_config.report_interval_multiple =
        static_cast<uint32_t>(atoi(bqr_prop_interval_multiple));
  } else {
    bqr_config.report_action = REPORT_ACTION_CLEAR;
    bqr_config.quality_event_mask = kQualityEventMaskAllOff;
    bqr_config.minimum_report_interval_ms = kMinReportIntervalNoLimit;
    bqr_config.vnd_quality_mask = 0;
    bqr_config.vnd_trace_mask = 0;
    bqr_config.report_interval_multiple = 0;
  }

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

  log::info("Event Mask: {}, Interval: {}, vendor_cap_supported_version: {}",
  log::info(
      "Event Mask: {}, Interval: {}, Multiple: {}, "
      "vendor_cap_supported_version: {}",
      loghex(bqr_config.quality_event_mask),
      bqr_config.minimum_report_interval_ms,
            vendor_cap_supported_version);
      bqr_config.report_interval_multiple, vendor_cap_supported_version);
  ConfigureBqr(bqr_config);
}

void ConfigureBqr(const BqrConfiguration& bqr_config) {
  if (vendor_cap_supported_version >= kBqrVersion6_0) {
    if (bqr_config.report_action > REPORT_ACTION_QUERY ||
        bqr_config.quality_event_mask > kQualityEventMaskAll ||
        bqr_config.minimum_report_interval_ms > kMinReportIntervalMaxMs) {
      log::fatal(
          "Invalid Parameter, Action: {}, Mask: {}, Interval: {} Multiple: {}",
          bqr_config.report_action, loghex(bqr_config.quality_event_mask),
          bqr_config.minimum_report_interval_ms,
          bqr_config.report_interval_multiple);
      return;
    } else {
      if (bqr_config.report_action > REPORT_ACTION_CLEAR ||
          bqr_config.quality_event_mask > kQualityEventMaskAll ||
          bqr_config.minimum_report_interval_ms > kMinReportIntervalMaxMs) {
        log::fatal("Invalid Parameter, Action: {}, Mask: {}, Interval: {}",
               bqr_config.report_action, loghex(bqr_config.quality_event_mask),
                   bqr_config.report_action,
                   loghex(bqr_config.quality_event_mask),
                   bqr_config.minimum_report_interval_ms);
        return;
      }
    }
  }

  log::info("Action: {}, Mask: {}, Interval: {}",
  log::info("Action: {}, Mask: {}, Interval: {} Multiple: {}",
            loghex(static_cast<uint8_t>(bqr_config.report_action)),
            loghex(bqr_config.quality_event_mask),
            bqr_config.minimum_report_interval_ms);
            bqr_config.minimum_report_interval_ms,
            bqr_config.report_interval_multiple);

  uint8_t param[sizeof(BqrConfiguration)];
  uint8_t* p_param = param;
@@ -380,6 +419,9 @@ void ConfigureBqr(const BqrConfiguration& bqr_config) {
    UINT32_TO_STREAM(p_param, bqr_config.vnd_quality_mask);
    UINT32_TO_STREAM(p_param, bqr_config.vnd_trace_mask);
  }
  if (vendor_cap_supported_version >= kBqrVersion6_0) {
    UINT32_TO_STREAM(p_param, bqr_config.report_interval_multiple);
  }

  BTM_VendorSpecificCommand(HCI_CONTROLLER_BQR, p_param - param, param,
                            BqrVscCompleteCallback);
@@ -396,11 +438,14 @@ void BqrVscCompleteCallback(tBTM_VSC_CMPL* p_vsc_cmpl_params) {
  uint8_t command_complete_param_len = 5;
  uint32_t current_vnd_quality_mask = 0;
  uint32_t current_vnd_trace_mask = 0;
  uint32_t bqr_report_interval = 0;
  // [Return Parameter]         | [Size]   | [Purpose]
  // Status                     | 1 octet  | Command complete status
  // Current_Quality_Event_Mask | 4 octets | Indicates current bit mask setting
  // Vendor_Specific_Quality_Mask | 4 octets | vendor quality bit mask setting
  // Vendor_Specific_Trace_Mask | 4 octets | vendor trace bit mask setting
  // bqr_report_interval | 4 octets | report interval from controller setting

  STREAM_TO_UINT8(status, p_event_param_buf);
  if (status != HCI_SUCCESS) {
    log::error("Fail to configure BQR. status: {}", loghex(status));
@@ -411,6 +456,10 @@ void BqrVscCompleteCallback(tBTM_VSC_CMPL* p_vsc_cmpl_params) {
    command_complete_param_len = 13;
  }

  if (vendor_cap_supported_version >= kBqrVersion6_0) {
    command_complete_param_len = 17;
  }

  if (p_vsc_cmpl_params->param_len != command_complete_param_len) {
    log::fatal("The length of returned parameters is incorrect: {}",
               p_vsc_cmpl_params->param_len);
@@ -425,9 +474,15 @@ void BqrVscCompleteCallback(tBTM_VSC_CMPL* p_vsc_cmpl_params) {
    STREAM_TO_UINT32(current_vnd_trace_mask, p_event_param_buf);
  }

  log::info("current event mask: {}, vendor quality: {}, vendor trace: {}",
            loghex(current_quality_event_mask),
            loghex(current_vnd_quality_mask), loghex(current_vnd_trace_mask));
  if (vendor_cap_supported_version >= kBqrVersion6_0) {
    STREAM_TO_UINT32(bqr_report_interval, p_event_param_buf);
  }

  log::info(
      "current event mask: {}, vendor quality: {}, vendor trace: {}, report "
      "interval: {}",
      loghex(current_quality_event_mask), loghex(current_vnd_quality_mask),
      loghex(current_vnd_trace_mask), loghex(bqr_report_interval));

  ConfigureBqrCmpl(current_quality_event_mask);
}