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

Commit 1b7954a6 authored by Hyundo Moon's avatar Hyundo Moon Committed by Automerger Merge Worker
Browse files

Merge "Use nonwake alarm for RPA rotation" into main am: 61a1afe5

parents 85f17469 61a1afe5
Loading
Loading
Loading
Loading
+78 −12
Original line number Diff line number Diff line
@@ -67,9 +67,13 @@ LeAddressManager::LeAddressManager(
      resolving_list_size_(resolving_list_size) {}

LeAddressManager::~LeAddressManager() {
  if (address_rotation_alarm_ != nullptr) {
    address_rotation_alarm_->Cancel();
    address_rotation_alarm_.reset();
  if (address_rotation_wake_alarm_ != nullptr) {
    address_rotation_wake_alarm_->Cancel();
    address_rotation_wake_alarm_.reset();
  }
  if (address_rotation_non_wake_alarm_ != nullptr) {
    address_rotation_non_wake_alarm_->Cancel();
    address_rotation_non_wake_alarm_.reset();
  }
}

@@ -102,6 +106,8 @@ void LeAddressManager::SetPrivacyPolicyForInitiatorAddress(
  if (com::android::bluetooth::flags::nrpa_non_connectable_adv()) {
    minimum_rotation_time_ = minimum_rotation_time;
    maximum_rotation_time_ = maximum_rotation_time;
    log::info("minimum_rotation_time_={}ms, maximum_rotation_time_={}ms",
              minimum_rotation_time_.count(), maximum_rotation_time_.count());
  }

  switch (address_policy_) {
@@ -133,8 +139,15 @@ void LeAddressManager::SetPrivacyPolicyForInitiatorAddress(
      if (!com::android::bluetooth::flags::nrpa_non_connectable_adv()) {
        minimum_rotation_time_ = minimum_rotation_time;
        maximum_rotation_time_ = maximum_rotation_time;
        log::info("minimum_rotation_time_={}ms, maximum_rotation_time_={}ms",
                  minimum_rotation_time_.count(), maximum_rotation_time_.count());
      }
      if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
        address_rotation_wake_alarm_ = std::make_unique<os::Alarm>(handler_, true);
        address_rotation_non_wake_alarm_ = std::make_unique<os::Alarm>(handler_, false);
      } else {
        address_rotation_wake_alarm_ = std::make_unique<os::Alarm>(handler_);
      }
      address_rotation_alarm_ = std::make_unique<os::Alarm>(handler_);
      set_random_address();
      break;
    case AddressPolicy::POLICY_NOT_SET:
@@ -179,7 +192,14 @@ void LeAddressManager::SetPrivacyPolicyForInitiatorAddressForTest(
      rotation_irk_ = rotation_irk;
      minimum_rotation_time_ = minimum_rotation_time;
      maximum_rotation_time_ = maximum_rotation_time;
      address_rotation_alarm_ = std::make_unique<os::Alarm>(handler_);
      log::info("minimum_rotation_time_={}ms, maximum_rotation_time_={}ms",
                minimum_rotation_time_.count(), maximum_rotation_time_.count());
      if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
        address_rotation_wake_alarm_ = std::make_unique<os::Alarm>(handler_, true);
        address_rotation_non_wake_alarm_ = std::make_unique<os::Alarm>(handler_, false);
      } else {
        address_rotation_wake_alarm_ = std::make_unique<os::Alarm>(handler_);
      }
      set_random_address();
      break;
    case AddressPolicy::POLICY_NOT_SET:
@@ -227,8 +247,13 @@ void LeAddressManager::unregister_client(LeAddressManagerCallback* callback) {
    registered_clients_.erase(callback);
    log::info("Client unregistered");
  }
  if (registered_clients_.empty() && address_rotation_alarm_ != nullptr) {
    address_rotation_alarm_->Cancel();
  if (registered_clients_.empty()) {
    if (address_rotation_wake_alarm_ != nullptr) {
      address_rotation_wake_alarm_->Cancel();
    }
    if (address_rotation_non_wake_alarm_ != nullptr) {
      address_rotation_non_wake_alarm_->Cancel();
    }
    log::info("Cancelled address rotation alarm");
  }
}
@@ -353,10 +378,21 @@ void LeAddressManager::prepare_to_rotate() {
}

void LeAddressManager::schedule_rotate_random_address() {
  address_rotation_alarm_->Schedule(
  if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
    auto privateAddressIntervalRange = GetNextPrivateAddressIntervalRange();
    address_rotation_wake_alarm_->Schedule(
            common::BindOnce(
                    []() { log::info("deadline wakeup in schedule_rotate_random_address"); }),
            privateAddressIntervalRange.max);
    address_rotation_non_wake_alarm_->Schedule(
            common::BindOnce(&LeAddressManager::prepare_to_rotate, common::Unretained(this)),
            privateAddressIntervalRange.min);
  } else {
    address_rotation_wake_alarm_->Schedule(
            common::BindOnce(&LeAddressManager::prepare_to_rotate, common::Unretained(this)),
            GetNextPrivateAddressIntervalMs());
  }
}

void LeAddressManager::set_random_address() {
  if (address_policy_ != AddressPolicy::USE_RESOLVABLE_ADDRESS &&
@@ -401,6 +437,8 @@ void LeAddressManager::update_irk(UpdateIRKCommand command) {
  rotation_irk_ = command.rotation_irk;
  minimum_rotation_time_ = command.minimum_rotation_time;
  maximum_rotation_time_ = command.maximum_rotation_time;
  log::info("minimum_rotation_time_={}ms, maximum_rotation_time_={}ms",
            minimum_rotation_time_.count(), maximum_rotation_time_.count());
  set_random_address();
  for (auto& client : registered_clients_) {
    client.first->NotifyOnIRKChange();
@@ -466,11 +504,39 @@ hci::Address LeAddressManager::generate_nrpa() {
}

std::chrono::milliseconds LeAddressManager::GetNextPrivateAddressIntervalMs() {
  auto interval_random_part_max_ms = maximum_rotation_time_ - minimum_rotation_time_;
  auto random_ms = std::chrono::milliseconds(os::GenerateRandom()) % (interval_random_part_max_ms);
  auto interval_random_part_wake_delay = maximum_rotation_time_ - minimum_rotation_time_;
  auto random_ms =
          std::chrono::milliseconds(os::GenerateRandom()) % (interval_random_part_wake_delay);
  return minimum_rotation_time_ + random_ms;
}

PrivateAddressIntervalRange LeAddressManager::GetNextPrivateAddressIntervalRange() {
  // 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_]
  // - Ensure that delays are in the given range [minimum_rotation_time_, maximum_rotation_time_]
  // - Ensure that the non-wake alarm's delay is not greater than wake alarm's delay.
  auto random_part_max_length = std::chrono::minutes(2);

  auto nonwake_delay = minimum_rotation_time_ +
                       (std::chrono::milliseconds(os::GenerateRandom()) % random_part_max_length);
  nonwake_delay = min(nonwake_delay, maximum_rotation_time_);

  auto wake_delay = maximum_rotation_time_ -
                    (std::chrono::milliseconds(os::GenerateRandom()) % random_part_max_length);
  wake_delay = max(nonwake_delay, max(wake_delay, minimum_rotation_time_));

  // For readable logging, the durations are rounded down to integer seconds.
  auto min_minutes = std::chrono::duration_cast<std::chrono::minutes>(nonwake_delay);
  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());

  return PrivateAddressIntervalRange{nonwake_delay, wake_delay};
}

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

uint8_t LeAddressManager::GetResolvingListSize() { return resolving_list_size_; }
+8 −1
Original line number Diff line number Diff line
@@ -38,6 +38,11 @@ public:
  virtual void NotifyOnIRKChange() {}
};

struct PrivateAddressIntervalRange {
  std::chrono::milliseconds min;
  std::chrono::milliseconds max;
};

class LeAddressManager {
public:
  LeAddressManager(common::Callback<void(std::unique_ptr<CommandBuilder>)> enqueue_command,
@@ -93,6 +98,7 @@ public:
  void ClearResolvingList();
  void OnCommandComplete(CommandCompleteView view);
  std::chrono::milliseconds GetNextPrivateAddressIntervalMs();
  PrivateAddressIntervalRange GetNextPrivateAddressIntervalRange();

  // Unsynchronized check for testing purposes
  size_t NumberCachedCommands() const { return cached_commands_.size(); }
@@ -164,7 +170,8 @@ private:
  AddressWithType le_address_;
  AddressWithType cached_address_;
  Address public_address_;
  std::unique_ptr<os::Alarm> address_rotation_alarm_;
  std::unique_ptr<os::Alarm> address_rotation_wake_alarm_;
  std::unique_ptr<os::Alarm> address_rotation_non_wake_alarm_;
  Octet16 rotation_irk_;
  uint8_t accept_list_size_;
  uint8_t resolving_list_size_;
+102 −28
Original line number Diff line number Diff line
@@ -83,7 +83,8 @@ struct Advertiser {
  bool directed = false;
  bool in_use = false;
  bool is_periodic = false;
  std::unique_ptr<os::Alarm> address_rotation_alarm;
  std::unique_ptr<os::Alarm> address_rotation_wake_alarm_;
  std::unique_ptr<os::Alarm> address_rotation_non_wake_alarm_;
};

/**
@@ -305,11 +306,16 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
    uint8_t advertiser_id = event_view.GetAdvertisingHandle();

    bool was_rotating_address = false;
    if (advertising_sets_[advertiser_id].address_rotation_alarm != nullptr) {
    if (advertising_sets_[advertiser_id].address_rotation_wake_alarm_ != nullptr) {
      was_rotating_address = true;
      advertising_sets_[advertiser_id].address_rotation_alarm->Cancel();
      advertising_sets_[advertiser_id].address_rotation_alarm.reset();
      advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Cancel();
      advertising_sets_[advertiser_id].address_rotation_wake_alarm_.reset();
    }
    if (advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_ != nullptr) {
      advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Cancel();
      advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_.reset();
    }

    enabled_sets_[advertiser_id].advertising_handle_ = kInvalidHandle;

    AddressWithType advertiser_address =
@@ -343,13 +349,33 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
          advertising_sets_[advertiser_id].max_extended_advertising_events == 0) {
        log::info("Reenable advertising");
        if (was_rotating_address) {
          advertising_sets_[advertiser_id].address_rotation_alarm =
          log::info("Scheduling address rotation for advertiser_id={}", advertiser_id);
          if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
            advertising_sets_[advertiser_id].address_rotation_wake_alarm_ =
                    std::make_unique<os::Alarm>(module_handler_, true);
            advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_ =
                    std::make_unique<os::Alarm>(module_handler_, false);

            auto privateAddressIntervalRange =
                    le_address_manager_->GetNextPrivateAddressIntervalRange();

            advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
                    common::BindOnce(
                            []() { log::info("deadline wakeup in handle_set_terminated"); }),
                    privateAddressIntervalRange.max);
            advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Schedule(
                    common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
                                     common::Unretained(this), advertiser_id),
                    privateAddressIntervalRange.min);
          } else {
            advertising_sets_[advertiser_id].address_rotation_wake_alarm_ =
                    std::make_unique<os::Alarm>(module_handler_);
          advertising_sets_[advertiser_id].address_rotation_alarm->Schedule(
            advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
                    common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
                                     common::Unretained(this), advertiser_id),
                    le_address_manager_->GetNextPrivateAddressIntervalMs());
          }
        }
        enable_advertiser(advertiser_id, true, 0, 0);
      }
    }
@@ -380,9 +406,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
              hci::LeRemoveAdvertisingSetBuilder::Create(advertiser_id),
              module_handler_->BindOnce(check_complete<LeRemoveAdvertisingSetCompleteView>));

      if (advertising_sets_[advertiser_id].address_rotation_alarm != nullptr) {
        advertising_sets_[advertiser_id].address_rotation_alarm->Cancel();
        advertising_sets_[advertiser_id].address_rotation_alarm.reset();
      if (advertising_sets_[advertiser_id].address_rotation_wake_alarm_ != nullptr) {
        advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Cancel();
        advertising_sets_[advertiser_id].address_rotation_wake_alarm_.reset();
      }
      if (advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_ != nullptr) {
        advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Cancel();
        advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_.reset();
      }
    }
    advertising_sets_.erase(advertiser_id);
@@ -603,13 +633,35 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
      if (advertising_sets_[id].address_type != AdvertiserAddressType::PUBLIC &&
          !leaudio_requested_nrpa) {
        // start timer for random address
        advertising_sets_[id].address_rotation_alarm = std::make_unique<os::Alarm>(module_handler_);
        advertising_sets_[id].address_rotation_alarm->Schedule(
        log::info("Scheduling address rotation for advertiser_id={}", id);
        if (com::android::bluetooth::flags::non_wake_alarm_for_rpa_rotation()) {
          advertising_sets_[id].address_rotation_wake_alarm_ =
                  std::make_unique<os::Alarm>(module_handler_, true);
          advertising_sets_[id].address_rotation_non_wake_alarm_ =
                  std::make_unique<os::Alarm>(module_handler_, false);

          auto privateAddressIntervalRange =
                  le_address_manager_->GetNextPrivateAddressIntervalRange();

          advertising_sets_[id].address_rotation_wake_alarm_->Schedule(
                  common::BindOnce([]() {
                    log::info("deadline wakeup in create_extended_advertiser_with_id");
                  }),
                  privateAddressIntervalRange.max);
          advertising_sets_[id].address_rotation_non_wake_alarm_->Schedule(
                  common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
                                   common::Unretained(this), id),
                  privateAddressIntervalRange.min);
        } else {
          advertising_sets_[id].address_rotation_wake_alarm_ =
                  std::make_unique<os::Alarm>(module_handler_);
          advertising_sets_[id].address_rotation_wake_alarm_->Schedule(
                  common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
                                   common::Unretained(this), id),
                  le_address_manager_->GetNextPrivateAddressIntervalMs());
        }
      }
    }
    if (config.advertising_type == AdvertisingType::ADV_IND ||
        config.advertising_type == AdvertisingType::ADV_NONCONN_IND) {
      set_data(id, true, config.scan_response);
@@ -699,9 +751,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
  void set_advertising_set_random_address_on_timer(AdvertiserId advertiser_id) {
    // This function should only be trigger by enabled advertising set or IRK rotation
    if (enabled_sets_[advertiser_id].advertising_handle_ == kInvalidHandle) {
      if (advertising_sets_[advertiser_id].address_rotation_alarm != nullptr) {
        advertising_sets_[advertiser_id].address_rotation_alarm->Cancel();
        advertising_sets_[advertiser_id].address_rotation_alarm.reset();
      if (advertising_sets_[advertiser_id].address_rotation_wake_alarm_ != nullptr) {
        advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Cancel();
        advertising_sets_[advertiser_id].address_rotation_wake_alarm_.reset();
      }
      if (advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_ != nullptr) {
        advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Cancel();
        advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_.reset();
      }
      return;
    }
@@ -735,11 +791,25 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
                      check_complete<LeSetExtendedAdvertisingEnableCompleteView>));
    }

    advertising_sets_[advertiser_id].address_rotation_alarm->Schedule(
    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();
      advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
              common::BindOnce([]() {
                log::info("deadline wakeup in set_advertising_set_random_address_on_timer");
              }),
              privateAddressIntervalRange.max);
      advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Schedule(
              common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
                               common::Unretained(this), advertiser_id),
              privateAddressIntervalRange.min);
    } else {
      advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Schedule(
              common::BindOnce(&impl::set_advertising_set_random_address_on_timer,
                               common::Unretained(this), advertiser_id),
              le_address_manager_->GetNextPrivateAddressIntervalMs());
    }
  }

  void register_advertiser(
          common::ContextualOnceCallback<void(uint8_t /* inst_id */,
@@ -1149,9 +1219,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
              max_extended_advertising_events;
    } else {
      enabled_sets_[advertiser_id].advertising_handle_ = kInvalidHandle;
      if (advertising_sets_[advertiser_id].address_rotation_alarm != nullptr) {
        advertising_sets_[advertiser_id].address_rotation_alarm->Cancel();
        advertising_sets_[advertiser_id].address_rotation_alarm.reset();
      if (advertising_sets_[advertiser_id].address_rotation_wake_alarm_ != nullptr) {
        advertising_sets_[advertiser_id].address_rotation_wake_alarm_->Cancel();
        advertising_sets_[advertiser_id].address_rotation_wake_alarm_.reset();
      }
      if (advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_ != nullptr) {
        advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_->Cancel();
        advertising_sets_[advertiser_id].address_rotation_non_wake_alarm_.reset();
      }
    }
  }