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

Commit aaf0b286 authored by Zhengping Jiang's avatar Zhengping Jiang Committed by Gerrit Code Review
Browse files

Merge "floss: allow NRPA for non-connectable advertisement with public address" into main

parents 4f6c695b d3c5a9a1
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

#include "hci/le_address_manager.h"

#include <android_bluetooth_flags.h>

#include "common/init_flags.h"
#include "hci/octets.h"
#include "os/log.h"
@@ -72,6 +74,11 @@ void LeAddressManager::SetPrivacyPolicyForInitiatorAddress(
  supports_ble_privacy_ = supports_ble_privacy;
  LOG_INFO("SetPrivacyPolicyForInitiatorAddress with policy %d", address_policy);

  if (IS_FLAG_ENABLED(nrpa_non_connectable_adv)) {
    minimum_rotation_time_ = minimum_rotation_time;
    maximum_rotation_time_ = maximum_rotation_time;
  }

  switch (address_policy_) {
    case AddressPolicy::USE_PUBLIC_ADDRESS:
      le_address_ = AddressWithType(public_address_, AddressType::PUBLIC_DEVICE_ADDRESS);
@@ -97,8 +104,10 @@ void LeAddressManager::SetPrivacyPolicyForInitiatorAddress(
    case AddressPolicy::USE_RESOLVABLE_ADDRESS:
      le_address_ = fixed_address;
      rotation_irk_ = rotation_irk;
      if (!IS_FLAG_ENABLED(nrpa_non_connectable_adv)) {
        minimum_rotation_time_ = minimum_rotation_time;
        maximum_rotation_time_ = maximum_rotation_time;
      }
      address_rotation_alarm_ = std::make_unique<os::Alarm>(handler_);
      set_random_address();
      break;
@@ -228,7 +237,9 @@ AddressWithType LeAddressManager::NewResolvableAddress() {
}

AddressWithType LeAddressManager::NewNonResolvableAddress() {
  if (!IS_FLAG_ENABLED(nrpa_non_connectable_adv)) {
    ASSERT(RotatingAddress());
  }
  hci::Address address = generate_nrpa();
  auto random_address = AddressWithType(address, AddressType::RANDOM_DEVICE_ADDRESS);
  return random_address;
+34 −5
Original line number Diff line number Diff line
@@ -110,6 +110,26 @@ AdvertiserAddressType GetAdvertiserAddressTypeFromRequestedTypeAndPolicy(
  }
}

/**
 * Determines the address type to use for non-connectable advertisement.
 * (1) if the host only supports public/static address policy, non-connectable advertisement
 *     can use both Public and NRPA if requested. Use NRPA if RPA is requested.
 * (2) in other cases, based on the requested type and the address manager policy.
 */
AdvertiserAddressType GetAdvertiserAddressTypeNonConnectable(
    AdvertiserAddressType requested_address_type, LeAddressManager::AddressPolicy address_policy) {
  switch (address_policy) {
    case LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS:
    case LeAddressManager::AddressPolicy::USE_STATIC_ADDRESS:
      return requested_address_type == AdvertiserAddressType::RESOLVABLE_RANDOM
                 ? AdvertiserAddressType::NONRESOLVABLE_RANDOM
                 : requested_address_type;
    default:
      return GetAdvertiserAddressTypeFromRequestedTypeAndPolicy(
          requested_address_type, address_policy);
  }
}

struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallback {
  impl(Module* module) : module_(module), le_advertising_interface_(nullptr), num_instances_(0) {}

@@ -440,9 +460,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
      address_manager_registered = true;
    }

    if (IS_FLAG_ENABLED(nrpa_non_connectable_adv) && !config.connectable) {
      advertising_sets_[id].address_type = GetAdvertiserAddressTypeNonConnectable(
          config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy());
    } else {
      advertising_sets_[id].address_type = GetAdvertiserAddressTypeFromRequestedTypeAndPolicy(
          config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy());

    }
    advertising_sets_[id].current_address = new_advertiser_address(id);
    set_parameters(id, config);

@@ -572,8 +596,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
    advertising_sets_[id].duration = duration;
    advertising_sets_[id].max_extended_advertising_events = max_ext_adv_events;
    advertising_sets_[id].handler = handler;
    if (IS_FLAG_ENABLED(nrpa_non_connectable_adv) && !config.connectable) {
      advertising_sets_[id].address_type = GetAdvertiserAddressTypeNonConnectable(
          config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy());
    } else {
      advertising_sets_[id].address_type = GetAdvertiserAddressTypeFromRequestedTypeAndPolicy(
          config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy());
    }
    advertising_sets_[id].current_address = new_advertiser_address(id);

    set_parameters(id, config);
+73 −0
Original line number Diff line number Diff line
@@ -1890,6 +1890,79 @@ TEST_F(LeExtendedAdvertisingManagerTest, use_public_address_type_if_public_addre
  EXPECT_EQ(set_parameters_command.GetOwnAddressType(), OwnAddressType::PUBLIC_DEVICE_ADDRESS);
}

TEST_F_WITH_FLAGS(
    LeExtendedAdvertisingManagerTest,
    use_nrpa_if_public_address_policy_non_connectable,
    REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, nrpa_non_connectable_adv))) {
  // arrange: use PUBLIC address policy
  test_acl_manager_->SetAddressPolicy(LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS);

  // act: start non-connectable advertising set with RPA
  le_advertising_manager_->ExtendedCreateAdvertiser(
      kAdvertiserClientIdJni,
      0x00,
      AdvertisingConfig{
          .requested_advertiser_address_type = AdvertiserAddressType::RESOLVABLE_RANDOM,
          .channel_map = 1,
          .connectable = false,
      },
      scan_callback,
      set_terminated_callback,
      0,
      0,
      client_handler_);
  ASSERT_EQ(
      test_hci_layer_->GetCommand().GetOpCode(), OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS);
  test_hci_layer_->IncomingEvent(LeSetExtendedAdvertisingParametersCompleteBuilder::Create(
      uint8_t{1}, ErrorCode::SUCCESS, static_cast<uint8_t>(-23)));

  auto command = LeAdvertisingCommandView::Create(test_hci_layer_->GetCommand());
  ASSERT_TRUE(command.IsValid());
  ASSERT_EQ(command.GetOpCode(), OpCode::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS);

  auto set_address_command =
      LeSetAdvertisingSetRandomAddressView::Create(LeAdvertisingCommandView::Create(command));
  ASSERT_TRUE(set_address_command.IsValid());
  EXPECT_EQ(set_address_command.GetOpCode(), OpCode::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS);

  // checking that it is an NRPA (first two bits = 0b00)
  Address address = set_address_command.GetRandomAddress();
  EXPECT_EQ(address.data()[5] >> 6, 0b00);
}

TEST_F_WITH_FLAGS(
    LeExtendedAdvertisingManagerTest,
    use_public_if_requested_with_public_address_policy_non_connectable,
    REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, nrpa_non_connectable_adv))) {
  // arrange: use PUBLIC address policy
  test_acl_manager_->SetAddressPolicy(LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS);

  // act: start non-connectable advertising set with PUBLIC
  le_advertising_manager_->ExtendedCreateAdvertiser(
      kAdvertiserClientIdJni,
      0x00,
      AdvertisingConfig{
          .requested_advertiser_address_type = AdvertiserAddressType::PUBLIC,
          .channel_map = 1,
          .connectable = false,
      },
      scan_callback,
      set_terminated_callback,
      0,
      0,
      client_handler_);
  auto command = LeAdvertisingCommandView::Create(test_hci_layer_->GetCommand());

  // assert
  ASSERT_TRUE(command.IsValid());
  EXPECT_EQ(command.GetOpCode(), OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS);

  auto set_parameters_command =
      LeSetExtendedAdvertisingParametersView::Create(LeAdvertisingCommandView::Create(command));
  ASSERT_TRUE(set_parameters_command.IsValid());
  EXPECT_EQ(set_parameters_command.GetOwnAddressType(), OwnAddressType::PUBLIC_DEVICE_ADDRESS);
}

}  // namespace
}  // namespace hci
}  // namespace bluetooth