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

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

Merge "Print warn log when rotation happens outside expected time range" into main

parents 237dc23f f20f383a
Loading
Loading
Loading
Loading
+44 −4
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#include <bluetooth/log.h>
#include <com_android_bluetooth_flags.h>

#include <ctime>

#include "hci/octets.h"
#include "include/macros.h"
#include "os/rand.h"
@@ -78,6 +80,12 @@ LeAddressManager::~LeAddressManager() {
    address_rotation_non_wake_alarm_->Cancel();
    address_rotation_non_wake_alarm_.reset();
  }
  if (address_rotation_interval_min.has_value()) {
    address_rotation_interval_min.reset();
  }
  if (address_rotation_interval_max.has_value()) {
    address_rotation_interval_max.reset();
  }
}

// Called on initialization, and on IRK rotation
@@ -382,7 +390,8 @@ void LeAddressManager::prepare_to_rotate() {

void LeAddressManager::schedule_rotate_random_address() {
  if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
    auto privateAddressIntervalRange = GetNextPrivateAddressIntervalRange();
    std::string client_name = "LeAddressManager";
    auto privateAddressIntervalRange = GetNextPrivateAddressIntervalRange(client_name);
    address_rotation_wake_alarm_->Schedule(
            common::BindOnce(
                    []() { log::info("deadline wakeup in schedule_rotate_random_address"); }),
@@ -390,6 +399,16 @@ void LeAddressManager::schedule_rotate_random_address() {
    address_rotation_non_wake_alarm_->Schedule(
            common::BindOnce(&LeAddressManager::prepare_to_rotate, common::Unretained(this)),
            privateAddressIntervalRange.min);

    auto now = std::chrono::system_clock::now();
    if (address_rotation_interval_min.has_value()) {
      CheckAddressRotationHappenedInExpectedTimeInterval(
              *address_rotation_interval_min, *address_rotation_interval_max, now, client_name);
    }

    // Update the expected range here.
    address_rotation_interval_min.emplace(now + privateAddressIntervalRange.min);
    address_rotation_interval_max.emplace(now + privateAddressIntervalRange.max);
  } else {
    address_rotation_wake_alarm_->Schedule(
            common::BindOnce(&LeAddressManager::prepare_to_rotate, common::Unretained(this)),
@@ -513,7 +532,8 @@ std::chrono::milliseconds LeAddressManager::GetNextPrivateAddressIntervalMs() {
  return minimum_rotation_time_ + random_ms;
}

PrivateAddressIntervalRange LeAddressManager::GetNextPrivateAddressIntervalRange() {
PrivateAddressIntervalRange LeAddressManager::GetNextPrivateAddressIntervalRange(
        const std::string& client_name) {
  // Get both alarms' delays as following:
  // - Non-wake  : Random between [minimum_rotation_time_, (minimum_rotation_time_ + 2 min)]
  // - Wake      : Random between [(maximum_rotation_time_ - 2 min), maximum_rotation_time_]
@@ -534,12 +554,32 @@ PrivateAddressIntervalRange LeAddressManager::GetNextPrivateAddressIntervalRange
  auto min_seconds = std::chrono::duration_cast<std::chrono::seconds>(nonwake_delay - min_minutes);
  auto max_minutes = std::chrono::duration_cast<std::chrono::minutes>(wake_delay);
  auto max_seconds = std::chrono::duration_cast<std::chrono::seconds>(wake_delay - max_minutes);
  log::info("nonwake={}m{}s, wake={}m{}s", min_minutes.count(), min_seconds.count(),
            max_minutes.count(), max_seconds.count());
  log::info("client={}, nonwake={}m{}s, wake={}m{}s", client_name, min_minutes.count(),
            min_seconds.count(), max_minutes.count(), max_seconds.count());

  return PrivateAddressIntervalRange{nonwake_delay, wake_delay};
}

void LeAddressManager::CheckAddressRotationHappenedInExpectedTimeInterval(
        const std::chrono::time_point<std::chrono::system_clock>& interval_min,
        const std::chrono::time_point<std::chrono::system_clock>& interval_max,
        const std::chrono::time_point<std::chrono::system_clock>& event_time,
        const std::string& client_name) {
  // Give some tolerance to upper limit since alarms may ring a little bit late.
  auto upper_limit_tolerance = std::chrono::seconds(5);

  if (event_time < interval_min || event_time > interval_max + upper_limit_tolerance) {
    log::warn("RPA rotation happened outside expected time interval. client={}", client_name);

    auto tt_interval_min = std::chrono::system_clock::to_time_t(interval_min);
    auto tt_interval_max = std::chrono::system_clock::to_time_t(interval_max);
    auto tt_event_time = std::chrono::system_clock::to_time_t(event_time);
    log::warn("interval_min={}", ctime(&tt_interval_min));
    log::warn("interval_max={}", ctime(&tt_interval_max));
    log::warn("event_time=  {}", ctime(&tt_event_time));
  }
}

uint8_t LeAddressManager::GetFilterAcceptListSize() { return accept_list_size_; }

uint8_t LeAddressManager::GetResolvingListSize() { return resolving_list_size_; }
+10 −1
Original line number Diff line number Diff line
@@ -98,7 +98,12 @@ public:
  void ClearResolvingList();
  void OnCommandComplete(CommandCompleteView view);
  std::chrono::milliseconds GetNextPrivateAddressIntervalMs();
  PrivateAddressIntervalRange GetNextPrivateAddressIntervalRange();
  PrivateAddressIntervalRange GetNextPrivateAddressIntervalRange(const std::string& client_name);
  void CheckAddressRotationHappenedInExpectedTimeInterval(
          const std::chrono::time_point<std::chrono::system_clock>& interval_min,
          const std::chrono::time_point<std::chrono::system_clock>& interval_max,
          const std::chrono::time_point<std::chrono::system_clock>& event_time,
          const std::string& client_name);

  // Unsynchronized check for testing purposes
  size_t NumberCachedCommands() const { return cached_commands_.size(); }
@@ -177,6 +182,10 @@ private:
  uint8_t resolving_list_size_;
  std::queue<Command> cached_commands_;
  bool supports_ble_privacy_{false};

  // Only used for logging error in address rotation time.
  std::optional<std::chrono::time_point<std::chrono::system_clock>> address_rotation_interval_min;
  std::optional<std::chrono::time_point<std::chrono::system_clock>> address_rotation_interval_max;
};

}  // namespace hci
+57 −3
Original line number Diff line number Diff line
@@ -88,6 +88,10 @@ struct Advertiser {
  bool is_periodic = false;
  std::unique_ptr<os::Alarm> address_rotation_wake_alarm_;
  std::unique_ptr<os::Alarm> address_rotation_non_wake_alarm_;

  // Only used for logging error in address rotation time.
  std::optional<std::chrono::time_point<std::chrono::system_clock>> address_rotation_interval_min;
  std::optional<std::chrono::time_point<std::chrono::system_clock>> address_rotation_interval_max;
};

/**
@@ -318,6 +322,12 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
      advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Cancel();
      advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_.reset();
    }
    if (advertising_sets_[advertiser_id].address_rotation_interval_min.has_value()) {
      advertising_sets_[advertiser_id].address_rotation_interval_min.reset();
    }
    if (advertising_sets_[advertiser_id].address_rotation_interval_max.has_value()) {
      advertising_sets_[advertiser_id].address_rotation_interval_max.reset();
    }

    enabled_sets_[advertiser_id].advertising_handle_ = kInvalidHandle;

@@ -359,8 +369,9 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
            advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_ =
                    std::make_unique<os::Alarm>(module_handler_, false);

            std::string client_name = "advertising_set_" + std::to_string(advertiser_id);
            auto privateAddressIntervalRange =
                    le_address_manager_->GetNextPrivateAddressIntervalRange();
                    le_address_manager_->GetNextPrivateAddressIntervalRange(client_name);

            advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
                    common::BindOnce(
@@ -370,6 +381,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
                    common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
                                     common::Unretained(this), advertiser_id),
                    privateAddressIntervalRange.min);

            // Update the expected range here.
            auto now = std::chrono::system_clock::now();
            advertising_sets_[advertiser_id].address_rotation_interval_min.emplace(
                    now + privateAddressIntervalRange.min);
            advertising_sets_[advertiser_id].address_rotation_interval_max.emplace(
                    now + privateAddressIntervalRange.max);
          } else {
            advertising_sets_[advertiser_id].address_rotation_wake_alarm_ =
                    std::make_unique<os::Alarm>(module_handler_);
@@ -643,8 +661,9 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
          advertising_sets_[id].address_rotation_non_wake_alarm_ =
                  std::make_unique<os::Alarm>(module_handler_, false);

          std::string client_name = "advertising_set_" + std::to_string(id);
          auto privateAddressIntervalRange =
                  le_address_manager_->GetNextPrivateAddressIntervalRange();
                  le_address_manager_->GetNextPrivateAddressIntervalRange(client_name);

          advertising_sets_[id].address_rotation_wake_alarm_->Schedule(
                  common::BindOnce([]() {
@@ -655,6 +674,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
                  common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
                                   common::Unretained(this), id),
                  privateAddressIntervalRange.min);

          // Update the expected range here.
          auto now = std::chrono::system_clock::now();
          advertising_sets_[id].address_rotation_interval_min.emplace(
                  now + privateAddressIntervalRange.min);
          advertising_sets_[id].address_rotation_interval_max.emplace(
                  now + privateAddressIntervalRange.max);
        } else {
          advertising_sets_[id].address_rotation_wake_alarm_ =
                  std::make_unique<os::Alarm>(module_handler_);
@@ -762,6 +788,12 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
        advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Cancel();
        advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_.reset();
      }
      if (advertising_sets_[advertiser_id].address_rotation_interval_min.has_value()) {
        advertising_sets_[advertiser_id].address_rotation_interval_min.reset();
      }
      if (advertising_sets_[advertiser_id].address_rotation_interval_max.has_value()) {
        advertising_sets_[advertiser_id].address_rotation_interval_max.reset();
      }
      return;
    }

@@ -796,7 +828,9 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb

    log::info("Scheduling address rotation for advertiser_id={}", advertiser_id);
    if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
      auto privateAddressIntervalRange = le_address_manager_->GetNextPrivateAddressIntervalRange();
      std::string client_name = "advertising_set_" + std::to_string(advertiser_id);
      auto privateAddressIntervalRange =
              le_address_manager_->GetNextPrivateAddressIntervalRange(client_name);
      advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
              common::BindOnce([]() {
                log::info("deadline wakeup in set_advertising_set_random_address_on_timer");
@@ -806,6 +840,20 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
              common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
                               common::Unretained(this), advertiser_id),
              privateAddressIntervalRange.min);

      auto now = std::chrono::system_clock::now();
      if (advertising_sets_[advertiser_id].address_rotation_interval_min.has_value()) {
        le_address_manager_->CheckAddressRotationHappenedInExpectedTimeInterval(
                *(advertising_sets_[advertiser_id].address_rotation_interval_min),
                *(advertising_sets_[advertiser_id].address_rotation_interval_max), now,
                client_name);
      }

      // Update the expected range here.
      advertising_sets_[advertiser_id].address_rotation_interval_min.emplace(
              now + privateAddressIntervalRange.min);
      advertising_sets_[advertiser_id].address_rotation_interval_max.emplace(
              now + privateAddressIntervalRange.max);
    } else {
      advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
              common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
@@ -1230,6 +1278,12 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
        advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Cancel();
        advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_.reset();
      }
      if (advertising_sets_[advertiser_id].address_rotation_interval_min.has_value()) {
        advertising_sets_[advertiser_id].address_rotation_interval_min.reset();
      }
      if (advertising_sets_[advertiser_id].address_rotation_interval_max.has_value()) {
        advertising_sets_[advertiser_id].address_rotation_interval_max.reset();
      }
    }
  }