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

Commit a55b7370 authored by Hyundo Moon's avatar Hyundo Moon
Browse files

Use nonwake alarm for RPA rotation

Bug: 344712454
Bug: 360743527
Test: atest bluetooth_test_gd_unit
Test: Manual, observed rotation intervals from logs
Change-Id: Ib47845b6e328f7f8b698bbdca9c99e3fe43b1a24
parent f22d0772
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();
      }
    }
  }