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

Commit 9a20d4ac authored by Jayden Kim's avatar Jayden Kim Committed by Gerrit Code Review
Browse files

Merge "Adds RF path loss compensation for LE advertise and scan"

parents a51ba9d4 73addef9
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <mutex>

#include "common/init_flags.h"
#include "common/strings.h"
#include "hci/acl_manager.h"
#include "hci/controller.h"
#include "hci/hci_layer.h"
@@ -36,6 +37,13 @@ namespace hci {
const ModuleFactory LeAdvertisingManager::Factory = ModuleFactory([]() { return new LeAdvertisingManager(); });
constexpr int kIdLocal = 0xff;  // Id for advertiser not register from Java layer
constexpr uint16_t kLenOfFlags = 0x03;
constexpr int64_t kLeAdvertisingTxPowerMin = -127;
constexpr int64_t kLeAdvertisingTxPowerMax = 20;
constexpr int64_t kLeTxPathLossCompMin = -128;
constexpr int64_t kLeTxPathLossCompMax = 127;

// system properties
const std::string kLeTxPathLossCompProperty = "bluetooth.hardware.radio.le_tx_path_loss_comp_db";

enum class AdvertisingApiType {
  LEGACY = 1,
@@ -149,6 +157,40 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
    for (size_t i = 0; i < enabled_sets_.size(); i++) {
      enabled_sets_[i].advertising_handle_ = kInvalidHandle;
    }
    le_tx_path_loss_comp_ = get_tx_path_loss_compensation();
  }

  int8_t get_tx_path_loss_compensation() {
    int8_t compensation = 0;
    auto compensation_prop = os::GetSystemProperty(kLeTxPathLossCompProperty);
    if (compensation_prop) {
      auto compensation_number = common::Int64FromString(compensation_prop.value());
      if (compensation_number) {
        int64_t number = compensation_number.value();
        if (number < kLeTxPathLossCompMin || number > kLeTxPathLossCompMax) {
          LOG_ERROR("Invalid number for tx path loss compensation: %" PRId64, number);
        } else {
          compensation = number;
        }
      }
    }
    LOG_INFO("Tx path loss compensation: %d", compensation);
    return compensation;
  }

  int8_t get_tx_power_after_calibration(int8_t tx_power) {
    if (le_tx_path_loss_comp_ == 0) {
      return tx_power;
    }
    int8_t calibrated_tx_power = tx_power;
    int64_t number = tx_power + le_tx_path_loss_comp_;
    if (number < kLeAdvertisingTxPowerMin || number > kLeAdvertisingTxPowerMax) {
      LOG_ERROR("Invalid number for calibrated tx power: %" PRId64, number);
    } else {
      calibrated_tx_power = number;
    }
    LOG_INFO("tx_power: %d, calibrated_tx_power: %d", tx_power, calibrated_tx_power);
    return calibrated_tx_power;
  }

  size_t GetNumberOfAdvertisingInstances() const {
@@ -630,6 +672,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
  }

  void set_parameters(AdvertiserId advertiser_id, AdvertisingConfig config) {
    config.tx_power = get_tx_power_after_calibration(static_cast<int8_t>(config.tx_power));
    advertising_sets_[advertiser_id].connectable = config.connectable;
    advertising_sets_[advertiser_id].discoverable = config.discoverable;
    advertising_sets_[advertiser_id].tx_power = config.tx_power;
@@ -1251,6 +1294,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
  hci::Controller* controller_;
  uint16_t le_maximum_advertising_data_length_;
  int8_t le_physical_channel_tx_power_ = 0;
  int8_t le_tx_path_loss_comp_ = 0;
  hci::LeAdvertisingInterface* le_advertising_interface_;
  std::map<AdvertiserId, Advertiser> advertising_sets_;
  hci::LeAddressManager* le_address_manager_;
+44 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include "module.h"
#include "os/handler.h"
#include "os/log.h"
#include "os/system_properties.h"
#include "storage/storage_module.h"

namespace bluetooth {
@@ -36,6 +37,11 @@ namespace hci {

constexpr uint16_t kLeScanWindowMin = 0x0004;
constexpr uint16_t kLeScanWindowMax = 0x4000;
constexpr int64_t kLeScanRssiMin = -127;
constexpr int64_t kLeScanRssiMax = 20;
constexpr int64_t kLeScanRssiUnknown = 127;
constexpr int64_t kLeRxPathLossCompMin = -128;
constexpr int64_t kLeRxPathLossCompMax = 127;
constexpr uint16_t kDefaultLeExtendedScanWindow = 4800;
constexpr uint16_t kLeExtendedScanWindowMax = 0xFFFF;
constexpr uint16_t kLeScanIntervalMin = 0x0004;
@@ -49,6 +55,9 @@ constexpr uint8_t kScanResponseBit = 3;
constexpr uint8_t kLegacyBit = 4;
constexpr uint8_t kDataStatusBits = 5;

// system properties
const std::string kLeRxPathLossCompProperty = "bluetooth.hardware.radio.le_rx_path_loss_comp_db";

const ModuleFactory LeScanningManager::Factory = ModuleFactory([]() { return new LeScanningManager(); });

enum class ScanApiType {
@@ -212,6 +221,7 @@ struct LeScanningManager::impl : public LeAddressManagerCallback {
    }
    batch_scan_config_.current_state = BatchScanState::DISABLED_STATE;
    batch_scan_config_.ref_value = kInvalidScannerId;
    le_rx_path_loss_comp_ = get_rx_path_loss_compensation();
  }

  void stop() {
@@ -277,6 +287,38 @@ struct LeScanningManager::impl : public LeAddressManagerCallback {
    bool truncated{false};
  };

  int8_t get_rx_path_loss_compensation() {
    int8_t compensation = 0;
    auto compensation_prop = os::GetSystemProperty(kLeRxPathLossCompProperty);
    if (compensation_prop) {
      auto compensation_number = common::Int64FromString(compensation_prop.value());
      if (compensation_number) {
        int64_t number = compensation_number.value();
        if (number < kLeRxPathLossCompMin || number > kLeRxPathLossCompMax) {
          LOG_ERROR("Invalid number for rx path loss compensation: %" PRId64, number);
        } else {
          compensation = number;
        }
      }
    }
    LOG_INFO("Rx path loss compensation: %d", compensation);
    return compensation;
  }

  int8_t get_rssi_after_calibration(int8_t rssi) {
    if (le_rx_path_loss_comp_ == 0 || rssi == kLeScanRssiUnknown) {
      return rssi;
    }
    int8_t calibrated_rssi = rssi;
    int64_t number = rssi + le_rx_path_loss_comp_;
    if (number < kLeScanRssiMin || number > kLeScanRssiMax) {
      LOG_ERROR("Invalid number for calibrated rssi: %" PRId64, number);
    } else {
      calibrated_rssi = number;
    }
    return calibrated_rssi;
  }

  uint16_t transform_to_extended_event_type(ExtendedEventTypeOptions o) {
    return (o.connectable ? 0x0001 << 0 : 0) | (o.scannable ? 0x0001 << 1 : 0) |
           (o.directed ? 0x0001 << 2 : 0) | (o.scan_response ? 0x0001 << 3 : 0) |
@@ -414,7 +456,7 @@ struct LeScanningManager::impl : public LeAddressManagerCallback {
          secondary_phy,
          advertising_sid,
          tx_power,
          rssi,
          get_rssi_after_calibration(rssi),
          periodic_advertising_interval,
          complete_advertising_data.value());
    }
@@ -1584,6 +1626,7 @@ struct LeScanningManager::impl : public LeAddressManagerCallback {
  std::map<ScannerId, std::vector<uint8_t>> batch_scan_result_cache_;
  std::unordered_map<uint8_t, ScannerId> tracker_id_map_;
  uint16_t total_num_of_advt_tracked_ = 0x00;
  int8_t le_rx_path_loss_comp_ = 0;

  static void check_status(CommandCompleteView view) {
    switch (view.GetCommandOpCode()) {
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@

#pragma once

#include <inttypes.h>

#include <cstdlib>

#ifndef LOG_TAG