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

Commit bc95be5a authored by Chienyuan's avatar Chienyuan
Browse files

gd: Implement address rotation for advertising set

Tag: #gd-refactor
Bug: 149221472
Test: cert/run --host
Test: atest --host bluetooth_test_gd
Change-Id: If9870dc667c59228edc258998ad9dc183b89dba1
parent fa817026
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -132,6 +132,9 @@ void LeAddressManager::SetPrivacyPolicyForInitiatorAddressForTest(
      LOG_ALWAYS_FATAL("invalid parameters");
  }
}
LeAddressManager::AddressPolicy LeAddressManager::GetAddressPolicy() {
  return address_policy_;
}

LeAddressManager::AddressPolicy LeAddressManager::Register(LeAddressManagerCallback* callback) {
  handler_->BindOnceOn(this, &LeAddressManager::register_client, callback).Invoke();
@@ -246,7 +249,7 @@ void LeAddressManager::prepare_to_rotate() {
void LeAddressManager::schedule_rotate_random_address() {
  address_rotation_alarm_->Schedule(
      common::BindOnce(&LeAddressManager::prepare_to_rotate, common::Unretained(this)),
      get_next_private_address_interval_ms());
      GetNextPrivateAddressIntervalMs());
}

void LeAddressManager::set_random_address() {
@@ -331,7 +334,7 @@ hci::Address LeAddressManager::generate_nrpa() {
  return address;
}

std::chrono::milliseconds LeAddressManager::get_next_private_address_interval_ms() {
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);
  return minimum_rotation_time_ + random_ms;
+2 −1
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ class LeAddressManager {
      crypto_toolbox::Octet16 rotation_irk,
      std::chrono::milliseconds minimum_rotation_time,
      std::chrono::milliseconds maximum_rotation_time);
  AddressPolicy GetAddressPolicy();
  void AckPause(LeAddressManagerCallback* callback);
  void AckResume(LeAddressManagerCallback* callback);
  virtual AddressPolicy Register(LeAddressManagerCallback* callback);
@@ -86,6 +87,7 @@ class LeAddressManager {
  void ClearConnectList();
  void ClearResolvingList();
  void OnCommandComplete(CommandCompleteView view);
  std::chrono::milliseconds GetNextPrivateAddressIntervalMs();

 private:
  enum ClientState {
@@ -123,7 +125,6 @@ class LeAddressManager {
  void set_random_address();
  hci::Address generate_rpa();
  hci::Address generate_nrpa();
  std::chrono::milliseconds get_next_private_address_interval_ms();
  void handle_next_command();

  common::Callback<void(std::unique_ptr<CommandBuilder>)> enqueue_command_;
+109 −10
Original line number Diff line number Diff line
@@ -52,8 +52,10 @@ struct Advertiser {
  common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback;
  int8_t tx_power;
  uint16_t duration;
  uint8_t max_extended_advertising_events;
  bool started = false;
  bool connectable = false;
  std::unique_ptr<os::Alarm> address_rotation_alarm;
};

ExtendedAdvertisingConfig::ExtendedAdvertisingConfig(const AdvertisingConfig& config) : AdvertisingConfig(config) {
@@ -89,6 +91,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
    if (address_manager_registered) {
      le_address_manager_->Unregister(this);
    }
    advertising_sets_.clear();
  }

  void start(os::Handler* handler, hci::HciLayer* hci_layer, hci::Controller* controller,
@@ -163,6 +166,14 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
      return;
    }

    uint8_t advertiser_id = event_view.GetAdvertisingHandle();

    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();
    }
    enabled_sets_[advertiser_id].advertising_handle_ = kInvalidHandle;

    AddressWithType advertiser_address = advertising_sets_[event_view.GetAdvertisingHandle()].current_address;

    set_terminated_callback_.InvokeIfNotEmpty(
@@ -199,6 +210,11 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
      le_advertising_interface_->EnqueueCommand(
          hci::LeRemoveAdvertisingSetBuilder::Create(advertiser_id),
          module_handler_->BindOnce(impl::check_status<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();
      }
    }
  }

@@ -274,21 +290,37 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
    advertising_sets_[id].scan_callback = scan_callback;
    advertising_sets_[id].set_terminated_callback = set_terminated_callback;
    advertising_sets_[id].duration = duration;
    advertising_sets_[id].max_extended_advertising_events = max_ext_adv_events;
    advertising_sets_[id].handler = handler;

    if (!address_manager_registered) {
      le_address_manager_->Register(this);
      address_manager_registered = true;
    }

    set_parameters(id, config);

    auto address_policy = le_address_manager_->GetAddressPolicy();
    if (config.own_address_type == OwnAddressType::RANDOM_DEVICE_ADDRESS) {
      advertising_sets_[id].current_address = le_address_manager_->GetAnotherAddress();
      if (address_policy == LeAddressManager::AddressPolicy::USE_NON_RESOLVABLE_ADDRESS ||
          address_policy == LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS) {
        AddressWithType address_with_type = le_address_manager_->GetAnotherAddress();
        le_advertising_interface_->EnqueueCommand(
            hci::LeSetExtendedAdvertisingRandomAddressBuilder::Create(id, address_with_type.GetAddress()),
            module_handler_->BindOnceOn(
                this,
                &impl::on_set_advertising_set_random_address_complete<
                    LeSetExtendedAdvertisingRandomAddressCompleteView>,
                id,
                address_with_type));

        // 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(
            common::BindOnce(&impl::set_advertising_set_random_address, common::Unretained(this), id),
            le_address_manager_->GetNextPrivateAddressIntervalMs());
      } else {
        advertising_sets_[id].current_address = le_address_manager_->GetCurrentAddress();
        le_advertising_interface_->EnqueueCommand(
            hci::LeSetExtendedAdvertisingRandomAddressBuilder::Create(
                id, advertising_sets_[id].current_address.GetAddress()),
            module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingRandomAddressCompleteView>));
      }
    } else {
      advertising_sets_[id].current_address =
          AddressWithType(controller_->GetMacAddress(), AddressType::PUBLIC_DEVICE_ADDRESS);
@@ -355,6 +387,50 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
    enabled_sets_[advertiser_id].advertising_handle_ = kInvalidHandle;
  }

  void set_advertising_set_random_address(AdvertiserId advertiser_id) {
    // This function should only be trigger by enabled advertising set
    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();
      }
      return;
    }

    // TODO handle duration and max_extended_advertising_events_
    EnabledSet curr_set;
    curr_set.advertising_handle_ = advertiser_id;
    curr_set.duration_ = advertising_sets_[advertiser_id].duration;
    curr_set.max_extended_advertising_events_ = advertising_sets_[advertiser_id].max_extended_advertising_events;
    std::vector<EnabledSet> enabled_sets = {curr_set};

    // For connectable advertising, we should disable it first
    if (advertising_sets_[advertiser_id].connectable) {
      le_advertising_interface_->EnqueueCommand(
          hci::LeSetExtendedAdvertisingEnableBuilder::Create(Enable::DISABLED, enabled_sets),
          module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingEnableCompleteView>));
    }

    AddressWithType address_with_type = le_address_manager_->GetAnotherAddress();
    le_advertising_interface_->EnqueueCommand(
        hci::LeSetExtendedAdvertisingRandomAddressBuilder::Create(advertiser_id, address_with_type.GetAddress()),
        module_handler_->BindOnceOn(
            this,
            &impl::on_set_advertising_set_random_address_complete<LeSetExtendedAdvertisingRandomAddressCompleteView>,
            advertiser_id,
            address_with_type));

    if (advertising_sets_[advertiser_id].connectable) {
      le_advertising_interface_->EnqueueCommand(
          hci::LeSetExtendedAdvertisingEnableBuilder::Create(Enable::ENABLED, enabled_sets),
          module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingEnableCompleteView>));
    }

    advertising_sets_[advertiser_id].address_rotation_alarm->Schedule(
        common::BindOnce(&impl::set_advertising_set_random_address, common::Unretained(this), advertiser_id),
        le_address_manager_->GetNextPrivateAddressIntervalMs());
  }

  void set_parameters(AdvertiserId advertiser_id, ExtendedAdvertisingConfig config) {
    advertising_sets_[advertiser_id].connectable = config.connectable;

@@ -627,8 +703,14 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb

    if (enable) {
      enabled_sets_[advertiser_id].advertising_handle_ = advertiser_id;
      advertising_sets_[advertiser_id].duration = duration;
      advertising_sets_[advertiser_id].max_extended_advertising_events = 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();
      }
    }
  }

@@ -945,6 +1027,23 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
    advertising_callbacks_->OnPeriodicAdvertisingEnabled(id, enable, advertising_status);
  }

  template <class View>
  void on_set_advertising_set_random_address_complete(
      AdvertiserId advertiser_id, AddressWithType address_with_type, CommandCompleteView view) {
    ASSERT(view.IsValid());
    auto complete_view = LeSetExtendedAdvertisingRandomAddressCompleteView::Create(view);
    ASSERT(complete_view.IsValid());
    if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
      LOG_INFO("Got a command complete with status %s", ErrorCodeText(complete_view.GetStatus()).c_str());
    } else {
      LOG_INFO(
          "update random address for advertising set %d : %s",
          advertiser_id,
          address_with_type.GetAddress().ToString().c_str());
      advertising_sets_[advertiser_id].current_address = address_with_type;
    }
  }

  template <class View>
  void check_status_with_id(AdvertiserId id, CommandCompleteView view) {
    ASSERT(view.IsValid());
+2 −5
Original line number Diff line number Diff line
@@ -364,11 +364,8 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface,
        static_cast<bluetooth::hci::Enable>(
            params.scan_request_notification_enable);

    if (bluetooth::shim::BTM_BleLocalPrivacyEnabled()) {
    // TODO set own_address_type based on address policy
    config.own_address_type = OwnAddressType::RANDOM_DEVICE_ADDRESS;
    } else {
      config.own_address_type = OwnAddressType::PUBLIC_DEVICE_ADDRESS;
    }
  }
};