You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
464 lines
19 KiB
464 lines
19 KiB
/*
|
|
* Copyright 2020 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "hci/le_address_manager.h"
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "common/init_flags.h"
|
|
#include "os/log.h"
|
|
#include "packet/raw_builder.h"
|
|
|
|
using ::bluetooth::crypto_toolbox::Octet16;
|
|
using ::bluetooth::os::Handler;
|
|
using ::bluetooth::os::Thread;
|
|
|
|
namespace bluetooth {
|
|
namespace hci {
|
|
|
|
using packet::kLittleEndian;
|
|
using packet::PacketView;
|
|
using packet::RawBuilder;
|
|
|
|
PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
|
|
auto bytes = std::make_shared<std::vector<uint8_t>>();
|
|
BitInserter i(*bytes);
|
|
bytes->reserve(packet->size());
|
|
packet->Serialize(i);
|
|
return packet::PacketView<packet::kLittleEndian>(bytes);
|
|
}
|
|
|
|
class TestHciLayer : public HciLayer {
|
|
public:
|
|
void EnqueueCommand(
|
|
std::unique_ptr<CommandBuilder> command,
|
|
common::ContextualOnceCallback<void(CommandCompleteView)> on_complete) override {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
command_queue_.push(std::move(command));
|
|
command_complete_callbacks.push_back(std::move(on_complete));
|
|
if (command_promise_ != nullptr) {
|
|
command_promise_->set_value();
|
|
command_promise_.reset();
|
|
}
|
|
}
|
|
|
|
void SetCommandFuture() {
|
|
ASSERT_LOG(command_promise_ == nullptr, "Promises, Promises, ... Only one at a time.");
|
|
command_promise_ = std::make_unique<std::promise<void>>();
|
|
command_future_ = std::make_unique<std::future<void>>(command_promise_->get_future());
|
|
}
|
|
|
|
CommandView GetLastCommand() {
|
|
if (command_queue_.size() == 0) {
|
|
return CommandView::Create(PacketView<kLittleEndian>(std::make_shared<std::vector<uint8_t>>()));
|
|
}
|
|
auto last = std::move(command_queue_.front());
|
|
command_queue_.pop();
|
|
return CommandView::Create(GetPacketView(std::move(last)));
|
|
}
|
|
|
|
CommandView GetCommand(OpCode op_code) {
|
|
if (!command_queue_.empty()) {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
if (command_future_ != nullptr) {
|
|
command_future_.reset();
|
|
command_promise_.reset();
|
|
}
|
|
} else if (command_future_ != nullptr) {
|
|
auto result = command_future_->wait_for(std::chrono::milliseconds(1000));
|
|
EXPECT_NE(std::future_status::timeout, result);
|
|
}
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
ASSERT_LOG(
|
|
!command_queue_.empty(), "Expecting command %s but command queue was empty", OpCodeText(op_code).c_str());
|
|
CommandView command_packet_view = GetLastCommand();
|
|
EXPECT_TRUE(command_packet_view.IsValid());
|
|
EXPECT_EQ(command_packet_view.GetOpCode(), op_code);
|
|
return command_packet_view;
|
|
}
|
|
|
|
void IncomingEvent(std::unique_ptr<EventBuilder> event_builder) {
|
|
auto packet = GetPacketView(std::move(event_builder));
|
|
EventView event = EventView::Create(packet);
|
|
ASSERT_TRUE(event.IsValid());
|
|
CommandCompleteCallback(event);
|
|
}
|
|
|
|
void CommandCompleteCallback(EventView event) {
|
|
CommandCompleteView complete_view = CommandCompleteView::Create(event);
|
|
ASSERT_TRUE(complete_view.IsValid());
|
|
std::move(command_complete_callbacks.front()).Invoke(complete_view);
|
|
command_complete_callbacks.pop_front();
|
|
}
|
|
|
|
void ListDependencies(ModuleList* list) override {}
|
|
void Start() override {}
|
|
void Stop() override {}
|
|
|
|
private:
|
|
std::list<common::ContextualOnceCallback<void(CommandCompleteView)>> command_complete_callbacks;
|
|
std::queue<std::unique_ptr<CommandBuilder>> command_queue_;
|
|
std::unique_ptr<std::promise<void>> command_promise_;
|
|
std::unique_ptr<std::future<void>> command_future_;
|
|
mutable std::mutex mutex_;
|
|
};
|
|
|
|
class RotatorClient : public LeAddressManagerCallback {
|
|
public:
|
|
RotatorClient(LeAddressManager* le_address_manager, size_t id) : le_address_manager_(le_address_manager), id_(id){};
|
|
|
|
void OnPause() {
|
|
paused = true;
|
|
le_address_manager_->AckPause(this);
|
|
}
|
|
|
|
void OnResume() {
|
|
paused = false;
|
|
le_address_manager_->AckResume(this);
|
|
if (resume_promise_ != nullptr) {
|
|
resume_promise_->set_value();
|
|
resume_promise_.reset();
|
|
}
|
|
}
|
|
|
|
void WaitForResume() {
|
|
if (paused) {
|
|
resume_promise_ = std::make_unique<std::promise<void>>();
|
|
auto resume_future = resume_promise_->get_future();
|
|
auto result = resume_future.wait_for(std::chrono::milliseconds(1000));
|
|
EXPECT_NE(std::future_status::timeout, result);
|
|
}
|
|
}
|
|
|
|
bool paused{false};
|
|
LeAddressManager* le_address_manager_;
|
|
size_t id_;
|
|
std::unique_ptr<std::promise<void>> resume_promise_;
|
|
};
|
|
|
|
class LeAddressManagerTest : public ::testing::Test {
|
|
public:
|
|
void SetUp() override {
|
|
thread_ = new Thread("thread", Thread::Priority::NORMAL);
|
|
handler_ = new Handler(thread_);
|
|
test_hci_layer_ = new TestHciLayer;
|
|
Address address({0x01, 0x02, 0x03, 0x04, 0x05, 0x06});
|
|
le_address_manager_ = new LeAddressManager(
|
|
common::Bind(&LeAddressManagerTest::enqueue_command, common::Unretained(this)), handler_, address, 0x3F, 0x3F);
|
|
AllocateClients(1);
|
|
}
|
|
|
|
void sync_handler(os::Handler* handler) {
|
|
std::promise<void> promise;
|
|
auto future = promise.get_future();
|
|
handler_->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise)));
|
|
auto future_status = future.wait_for(std::chrono::seconds(1));
|
|
EXPECT_EQ(future_status, std::future_status::ready);
|
|
}
|
|
|
|
void TearDown() override {
|
|
sync_handler(handler_);
|
|
delete le_address_manager_;
|
|
delete test_hci_layer_;
|
|
handler_->Clear();
|
|
delete handler_;
|
|
delete thread_;
|
|
}
|
|
|
|
void AllocateClients(size_t num_clients) {
|
|
size_t first_id = clients.size();
|
|
for (size_t i = 0; i < num_clients; i++) {
|
|
clients.emplace_back(std::make_unique<RotatorClient>(le_address_manager_, first_id + i));
|
|
}
|
|
}
|
|
|
|
void enqueue_command(std::unique_ptr<CommandBuilder> command_packet) {
|
|
test_hci_layer_->EnqueueCommand(
|
|
std::move(command_packet),
|
|
handler_->BindOnce(&LeAddressManager::OnCommandComplete, common::Unretained(le_address_manager_)));
|
|
}
|
|
|
|
Thread* thread_;
|
|
Handler* handler_;
|
|
TestHciLayer* test_hci_layer_ = nullptr;
|
|
LeAddressManager* le_address_manager_;
|
|
std::vector<std::unique_ptr<RotatorClient>> clients;
|
|
};
|
|
|
|
TEST_F(LeAddressManagerTest, startup_teardown) {}
|
|
|
|
TEST_F(LeAddressManagerTest, register_unregister_callback) {
|
|
le_address_manager_->Register(clients[0].get());
|
|
sync_handler(handler_);
|
|
le_address_manager_->Unregister(clients[0].get());
|
|
sync_handler(handler_);
|
|
}
|
|
|
|
TEST_F(LeAddressManagerTest, rotator_address_for_single_client) {
|
|
Octet16 irk = {0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b};
|
|
auto minimum_rotation_time = std::chrono::milliseconds(1000);
|
|
auto maximum_rotation_time = std::chrono::milliseconds(3000);
|
|
AddressWithType remote_address(Address::kEmpty, AddressType::RANDOM_DEVICE_ADDRESS);
|
|
le_address_manager_->SetPrivacyPolicyForInitiatorAddress(
|
|
LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS,
|
|
remote_address,
|
|
irk,
|
|
minimum_rotation_time,
|
|
maximum_rotation_time);
|
|
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->Register(clients[0].get());
|
|
sync_handler(handler_);
|
|
test_hci_layer_->GetCommand(OpCode::LE_SET_RANDOM_ADDRESS);
|
|
test_hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
clients[0].get()->WaitForResume();
|
|
le_address_manager_->Unregister(clients[0].get());
|
|
sync_handler(handler_);
|
|
}
|
|
|
|
TEST_F(LeAddressManagerTest, rotator_non_resolvable_address_for_single_client) {
|
|
Octet16 irk = {};
|
|
auto minimum_rotation_time = std::chrono::milliseconds(1000);
|
|
auto maximum_rotation_time = std::chrono::milliseconds(3000);
|
|
AddressWithType remote_address(Address::kEmpty, AddressType::RANDOM_DEVICE_ADDRESS);
|
|
le_address_manager_->SetPrivacyPolicyForInitiatorAddress(
|
|
LeAddressManager::AddressPolicy::USE_NON_RESOLVABLE_ADDRESS,
|
|
remote_address,
|
|
irk,
|
|
minimum_rotation_time,
|
|
maximum_rotation_time);
|
|
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->Register(clients[0].get());
|
|
sync_handler(handler_);
|
|
test_hci_layer_->GetCommand(OpCode::LE_SET_RANDOM_ADDRESS);
|
|
test_hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
clients[0].get()->WaitForResume();
|
|
le_address_manager_->Unregister(clients[0].get());
|
|
sync_handler(handler_);
|
|
}
|
|
|
|
// TODO handle the case "register during rotate_random_address" and enable this
|
|
TEST_F(LeAddressManagerTest, DISABLED_rotator_address_for_multiple_clients) {
|
|
AllocateClients(2);
|
|
Octet16 irk = {0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b};
|
|
auto minimum_rotation_time = std::chrono::milliseconds(1000);
|
|
auto maximum_rotation_time = std::chrono::milliseconds(3000);
|
|
AddressWithType remote_address(Address::kEmpty, AddressType::RANDOM_DEVICE_ADDRESS);
|
|
le_address_manager_->SetPrivacyPolicyForInitiatorAddress(
|
|
LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS,
|
|
remote_address,
|
|
irk,
|
|
minimum_rotation_time,
|
|
maximum_rotation_time);
|
|
le_address_manager_->Register(clients[0].get());
|
|
le_address_manager_->Register(clients[1].get());
|
|
le_address_manager_->Register(clients[2].get());
|
|
sync_handler(handler_);
|
|
|
|
le_address_manager_->Unregister(clients[0].get());
|
|
le_address_manager_->Unregister(clients[1].get());
|
|
le_address_manager_->Unregister(clients[2].get());
|
|
sync_handler(handler_);
|
|
}
|
|
|
|
class LeAddressManagerWithSingleClientTest : public LeAddressManagerTest {
|
|
public:
|
|
void SetUp() override {
|
|
bluetooth::common::InitFlags::SetAllForTesting();
|
|
thread_ = new Thread("thread", Thread::Priority::NORMAL);
|
|
handler_ = new Handler(thread_);
|
|
test_hci_layer_ = new TestHciLayer;
|
|
Address address({0x01, 0x02, 0x03, 0x04, 0x05, 0x06});
|
|
le_address_manager_ = new LeAddressManager(
|
|
common::Bind(&LeAddressManagerWithSingleClientTest::enqueue_command, common::Unretained(this)),
|
|
handler_,
|
|
address,
|
|
0x3F,
|
|
0x3F);
|
|
AllocateClients(1);
|
|
|
|
Octet16 irk = {0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b};
|
|
auto minimum_rotation_time = std::chrono::milliseconds(1000);
|
|
auto maximum_rotation_time = std::chrono::milliseconds(3000);
|
|
AddressWithType remote_address(Address::kEmpty, AddressType::RANDOM_DEVICE_ADDRESS);
|
|
le_address_manager_->SetPrivacyPolicyForInitiatorAddress(
|
|
LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS,
|
|
remote_address,
|
|
irk,
|
|
minimum_rotation_time,
|
|
maximum_rotation_time);
|
|
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->Register(clients[0].get());
|
|
sync_handler(handler_);
|
|
test_hci_layer_->GetCommand(OpCode::LE_SET_RANDOM_ADDRESS);
|
|
test_hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
}
|
|
|
|
void enqueue_command(std::unique_ptr<CommandBuilder> command_packet) {
|
|
test_hci_layer_->EnqueueCommand(
|
|
std::move(command_packet),
|
|
handler_->BindOnce(&LeAddressManager::OnCommandComplete, common::Unretained(le_address_manager_)));
|
|
}
|
|
|
|
void TearDown() override {
|
|
le_address_manager_->Unregister(clients[0].get());
|
|
sync_handler(handler_);
|
|
delete le_address_manager_;
|
|
delete test_hci_layer_;
|
|
handler_->Clear();
|
|
delete handler_;
|
|
delete thread_;
|
|
}
|
|
};
|
|
|
|
TEST_F(LeAddressManagerWithSingleClientTest, add_device_to_connect_list) {
|
|
Address address;
|
|
Address::FromString("01:02:03:04:05:06", address);
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->AddDeviceToConnectList(ConnectListAddressType::RANDOM, address);
|
|
auto packet = test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_CONNECT_LIST);
|
|
auto packet_view =
|
|
LeAddDeviceToConnectListView::Create(LeConnectionManagementCommandView::Create(AclCommandView::Create(packet)));
|
|
ASSERT_TRUE(packet_view.IsValid());
|
|
ASSERT_EQ(ConnectListAddressType::RANDOM, packet_view.GetAddressType());
|
|
ASSERT_EQ(address, packet_view.GetAddress());
|
|
|
|
test_hci_layer_->IncomingEvent(LeAddDeviceToConnectListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
clients[0].get()->WaitForResume();
|
|
}
|
|
|
|
TEST_F(LeAddressManagerWithSingleClientTest, remove_device_from_connect_list) {
|
|
Address address;
|
|
Address::FromString("01:02:03:04:05:06", address);
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->AddDeviceToConnectList(ConnectListAddressType::RANDOM, address);
|
|
test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_CONNECT_LIST);
|
|
test_hci_layer_->IncomingEvent(LeAddDeviceToConnectListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->RemoveDeviceFromConnectList(ConnectListAddressType::RANDOM, address);
|
|
auto packet = test_hci_layer_->GetCommand(OpCode::LE_REMOVE_DEVICE_FROM_CONNECT_LIST);
|
|
auto packet_view = LeRemoveDeviceFromConnectListView::Create(
|
|
LeConnectionManagementCommandView::Create(AclCommandView::Create(packet)));
|
|
ASSERT_TRUE(packet_view.IsValid());
|
|
ASSERT_EQ(ConnectListAddressType::RANDOM, packet_view.GetAddressType());
|
|
ASSERT_EQ(address, packet_view.GetAddress());
|
|
test_hci_layer_->IncomingEvent(LeRemoveDeviceFromConnectListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
clients[0].get()->WaitForResume();
|
|
}
|
|
|
|
TEST_F(LeAddressManagerWithSingleClientTest, clear_connect_list) {
|
|
Address address;
|
|
Address::FromString("01:02:03:04:05:06", address);
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->AddDeviceToConnectList(ConnectListAddressType::RANDOM, address);
|
|
test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_CONNECT_LIST);
|
|
test_hci_layer_->IncomingEvent(LeAddDeviceToConnectListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->ClearConnectList();
|
|
test_hci_layer_->GetCommand(OpCode::LE_CLEAR_CONNECT_LIST);
|
|
test_hci_layer_->IncomingEvent(LeClearConnectListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
clients[0].get()->WaitForResume();
|
|
}
|
|
|
|
TEST_F(LeAddressManagerWithSingleClientTest, add_device_to_resolving_list) {
|
|
Address address;
|
|
Address::FromString("01:02:03:04:05:06", address);
|
|
Octet16 peer_irk = {0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b};
|
|
Octet16 local_irk = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->AddDeviceToResolvingList(
|
|
PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, address, peer_irk, local_irk);
|
|
auto packet = test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST);
|
|
auto packet_view = LeAddDeviceToResolvingListView::Create(LeSecurityCommandView::Create(packet));
|
|
ASSERT_TRUE(packet_view.IsValid());
|
|
ASSERT_EQ(PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, packet_view.GetPeerIdentityAddressType());
|
|
ASSERT_EQ(address, packet_view.GetPeerIdentityAddress());
|
|
ASSERT_EQ(peer_irk, packet_view.GetPeerIrk());
|
|
ASSERT_EQ(local_irk, packet_view.GetLocalIrk());
|
|
|
|
test_hci_layer_->IncomingEvent(LeAddDeviceToResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
clients[0].get()->WaitForResume();
|
|
}
|
|
|
|
TEST_F(LeAddressManagerWithSingleClientTest, remove_device_from_resolving_list) {
|
|
Address address;
|
|
Address::FromString("01:02:03:04:05:06", address);
|
|
Octet16 peer_irk = {0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b};
|
|
Octet16 local_irk = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->AddDeviceToResolvingList(
|
|
PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, address, peer_irk, local_irk);
|
|
test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST);
|
|
test_hci_layer_->IncomingEvent(LeAddDeviceToResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->RemoveDeviceFromResolvingList(PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, address);
|
|
auto packet = test_hci_layer_->GetCommand(OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST);
|
|
auto packet_view = LeRemoveDeviceFromResolvingListView::Create(LeSecurityCommandView::Create(packet));
|
|
ASSERT_TRUE(packet_view.IsValid());
|
|
ASSERT_EQ(PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, packet_view.GetPeerIdentityAddressType());
|
|
ASSERT_EQ(address, packet_view.GetPeerIdentityAddress());
|
|
test_hci_layer_->IncomingEvent(LeRemoveDeviceFromResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
clients[0].get()->WaitForResume();
|
|
}
|
|
|
|
TEST_F(LeAddressManagerWithSingleClientTest, clear_resolving_list) {
|
|
Address address;
|
|
Address::FromString("01:02:03:04:05:06", address);
|
|
Octet16 peer_irk = {0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b};
|
|
Octet16 local_irk = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->AddDeviceToResolvingList(
|
|
PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, address, peer_irk, local_irk);
|
|
test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST);
|
|
test_hci_layer_->IncomingEvent(LeAddDeviceToResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->ClearResolvingList();
|
|
auto packet = test_hci_layer_->GetCommand(OpCode::LE_CLEAR_RESOLVING_LIST);
|
|
auto packet_view = LeClearResolvingListView::Create(LeSecurityCommandView::Create(packet));
|
|
ASSERT_TRUE(packet_view.IsValid());
|
|
test_hci_layer_->IncomingEvent(LeClearResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
clients[0].get()->WaitForResume();
|
|
}
|
|
|
|
TEST_F(LeAddressManagerWithSingleClientTest, register_during_command_complete) {
|
|
Address address;
|
|
Address::FromString("01:02:03:04:05:06", address);
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->AddDeviceToConnectList(ConnectListAddressType::RANDOM, address);
|
|
auto packet = test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_CONNECT_LIST);
|
|
auto packet_view =
|
|
LeAddDeviceToConnectListView::Create(LeConnectionManagementCommandView::Create(AclCommandView::Create(packet)));
|
|
ASSERT_TRUE(packet_view.IsValid());
|
|
ASSERT_EQ(ConnectListAddressType::RANDOM, packet_view.GetAddressType());
|
|
ASSERT_EQ(address, packet_view.GetAddress());
|
|
test_hci_layer_->IncomingEvent(LeAddDeviceToConnectListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
|
|
|
|
AllocateClients(1);
|
|
test_hci_layer_->SetCommandFuture();
|
|
le_address_manager_->Register(clients[1].get());
|
|
clients[0].get()->WaitForResume();
|
|
clients[1].get()->WaitForResume();
|
|
}
|
|
|
|
} // namespace hci
|
|
} // namespace bluetooth
|