Loading system/gd/hci/le_address_manager.cc +78 −12 Original line number Diff line number Diff line Loading @@ -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(); } } Loading Loading @@ -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_) { Loading Loading @@ -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: Loading Loading @@ -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: Loading Loading @@ -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"); } } Loading Loading @@ -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 && Loading Loading @@ -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(); Loading Loading @@ -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_; } Loading system/gd/hci/le_address_manager.h +8 −1 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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(); } Loading Loading @@ -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_; Loading system/gd/hci/le_advertising_manager.cc +102 −28 Original line number Diff line number Diff line Loading @@ -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_; }; /** Loading Loading @@ -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 = Loading Loading @@ -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); } } Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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 */, Loading Loading @@ -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(); } } } Loading Loading
system/gd/hci/le_address_manager.cc +78 −12 Original line number Diff line number Diff line Loading @@ -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(); } } Loading Loading @@ -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_) { Loading Loading @@ -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: Loading Loading @@ -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: Loading Loading @@ -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"); } } Loading Loading @@ -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 && Loading Loading @@ -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(); Loading Loading @@ -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_; } Loading
system/gd/hci/le_address_manager.h +8 −1 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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(); } Loading Loading @@ -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_; Loading
system/gd/hci/le_advertising_manager.cc +102 −28 Original line number Diff line number Diff line Loading @@ -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_; }; /** Loading Loading @@ -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 = Loading Loading @@ -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); } } Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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 */, Loading Loading @@ -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(); } } } Loading