blob: 0bdea5391a2f0241ea0898fd5011c3583afa43f8 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "garnet/drivers/bluetooth/lib/gap/remote_device_cache.h"
#include "garnet/drivers/bluetooth/lib/common/device_class.h"
#include "garnet/drivers/bluetooth/lib/common/test_helpers.h"
#include "garnet/drivers/bluetooth/lib/gap/remote_device.h"
#include "garnet/drivers/bluetooth/lib/hci/low_energy_scanner.h"
#include "lib/gtest/test_loop_fixture.h"
#include "garnet/drivers/bluetooth/lib/sm/types.h"
#include "gtest/gtest.h"
namespace btlib {
namespace gap {
namespace {
// All fields are initialized to zero as they are unused in these tests.
const hci::LEConnectionParameters kTestParams;
constexpr int8_t kTestRSSI = 10;
const common::DeviceAddress kAddrPublic(common::DeviceAddress::Type::kLEPublic,
"01:02:03:04:05:06");
// TODO(armansito): Make these adhere to privacy specfication.
const common::DeviceAddress kAddrRandom(common::DeviceAddress::Type::kLERandom,
"06:05:04:03:02:01");
const common::DeviceAddress kAddrAnon(common::DeviceAddress::Type::kLEAnonymous,
"06:05:04:03:02:01");
const btlib::sm::LTK kLTK;
class GAP_RemoteDeviceCacheTest : public ::gtest::TestLoopFixture {
public:
void SetUp() {}
void TearDown() { RunLoopUntilIdle(); }
};
TEST_F(GAP_RemoteDeviceCacheTest, LookUp) {
auto kAdvData0 =
common::CreateStaticByteBuffer(0x05, 0x09, 'T', 'e', 's', 't');
auto kAdvData1 = common::CreateStaticByteBuffer(
0x0C, 0x09, 'T', 'e', 's', 't', ' ', 'D', 'e', 'v', 'i', 'c', 'e');
RemoteDeviceCache cache;
EXPECT_FALSE(cache.FindDeviceByAddress(kAddrPublic));
EXPECT_FALSE(cache.FindDeviceById("foo"));
auto device = cache.NewDevice(kAddrPublic, true);
ASSERT_TRUE(device);
EXPECT_EQ(TechnologyType::kLowEnergy, device->technology());
EXPECT_TRUE(device->connectable());
EXPECT_TRUE(device->temporary());
EXPECT_EQ(kAddrPublic, device->address());
EXPECT_EQ(0u, device->advertising_data().size());
EXPECT_EQ(hci::kRSSIInvalid, device->rssi());
// A look up should return the same instance.
EXPECT_EQ(device, cache.FindDeviceById(device->identifier()));
EXPECT_EQ(device, cache.FindDeviceByAddress(device->address()));
// Adding a device with the same address should return nullptr.
EXPECT_FALSE(cache.NewDevice(kAddrPublic, true));
device->SetLEAdvertisingData(kTestRSSI, kAdvData1);
EXPECT_TRUE(common::ContainersEqual(kAdvData1, device->advertising_data()));
EXPECT_EQ(kTestRSSI, device->rssi());
device->SetLEAdvertisingData(kTestRSSI, kAdvData0);
EXPECT_TRUE(common::ContainersEqual(kAdvData0, device->advertising_data()));
EXPECT_EQ(kTestRSSI, device->rssi());
}
TEST_F(GAP_RemoteDeviceCacheTest, TryMakeNonTemporaryNonConn) {
RemoteDeviceCache cache;
auto device = cache.NewDevice(kAddrPublic, false);
EXPECT_TRUE(device->temporary());
EXPECT_FALSE(device->TryMakeNonTemporary());
EXPECT_TRUE(device->temporary());
}
TEST_F(GAP_RemoteDeviceCacheTest, TryMakeNonTemporaryRandomAddr) {
RemoteDeviceCache cache;
auto device = cache.NewDevice(kAddrRandom, true);
EXPECT_TRUE(device->temporary());
EXPECT_FALSE(device->TryMakeNonTemporary());
EXPECT_TRUE(device->temporary());
}
TEST_F(GAP_RemoteDeviceCacheTest, TryMakeNonTemporaryAnonAddr) {
RemoteDeviceCache cache;
auto device = cache.NewDevice(kAddrAnon, true);
EXPECT_TRUE(device->temporary());
EXPECT_FALSE(device->TryMakeNonTemporary());
EXPECT_TRUE(device->temporary());
}
TEST_F(GAP_RemoteDeviceCacheTest, TryMakeNonTemporarySuccess) {
RemoteDeviceCache cache;
auto device = cache.NewDevice(kAddrPublic, true);
EXPECT_TRUE(device->temporary());
EXPECT_TRUE(device->TryMakeNonTemporary());
EXPECT_FALSE(device->temporary());
}
TEST_F(GAP_RemoteDeviceCacheTest,
NewDeviceDoesNotCrashWhenNoCallbackIsReigstered) {
RemoteDeviceCache().NewDevice(kAddrPublic, true);
}
TEST_F(GAP_RemoteDeviceCacheTest,
NewDeviceInvokesCallbackWhenDeviceIsFirstRegistered) {
RemoteDeviceCache cache;
bool was_called = false;
cache.set_device_updated_callback(
[&was_called](const auto&) { was_called = true; });
cache.NewDevice(kAddrPublic, true);
EXPECT_TRUE(was_called);
}
TEST_F(GAP_RemoteDeviceCacheTest,
NewDeviceDoesNotInvokeCallbackWhenDeviceIsReRegistered) {
RemoteDeviceCache cache;
int call_count = 0;
cache.set_device_updated_callback(
[&call_count](const auto&) { ++call_count; });
cache.NewDevice(kAddrPublic, true);
cache.NewDevice(kAddrPublic, true);
EXPECT_EQ(1, call_count);
}
class GAP_RemoteDeviceCacheTest_BondedCallbackTest : public GAP_RemoteDeviceCacheTest {
public:
void SetUp() {
was_called_ = false;
device_ = cache_.NewDevice(kAddrPublic, true);
cache_.set_device_bonded_callback(
[this](const auto&) { was_called_ = true; });
EXPECT_FALSE(was_called_);
}
protected:
RemoteDeviceCache* cache() { return &cache_; }
RemoteDevice* device() { return device_; }
bool was_called() const { return was_called_; }
private:
RemoteDeviceCache cache_;
RemoteDevice* device_;
bool was_called_;
};
TEST_F(GAP_RemoteDeviceCacheTest_BondedCallbackTest,
StoreLTKTriggersBondedCallback) {
cache()->StoreLTK(device()->identifier(), kLTK);
EXPECT_TRUE(was_called());
}
class GAP_RemoteDeviceCacheTest_UpdateCallbackTest
: public GAP_RemoteDeviceCacheTest {
public:
void SetUp() {
was_called_ = false;
device_ = cache_.NewDevice(kAddrPublic, true);
cache_.set_device_updated_callback(
[this](const auto&) { was_called_ = true; });
ir_.bd_addr = device_->address().value();
irr_.bd_addr = device_->address().value();
eirep_.bd_addr = device_->address().value();
common::MutableBufferView(&eirep_.extended_inquiry_response,
sizeof(eirep_.extended_inquiry_response))
.SetToZeros();
EXPECT_FALSE(was_called_);
}
protected:
RemoteDeviceCache* cache() { return &cache_; }
RemoteDevice* device() { return device_; }
hci::InquiryResult& ir() { return ir_; }
hci::InquiryResultRSSI& irr() { return irr_; }
hci::ExtendedInquiryResultEventParams& eirep() { return eirep_; }
bool was_called() const { return was_called_; }
void ClearWasCalled() { was_called_ = false; }
private:
RemoteDeviceCache cache_;
RemoteDevice* device_;
bool was_called_;
hci::InquiryResult ir_;
hci::InquiryResultRSSI irr_;
hci::ExtendedInquiryResultEventParams eirep_;
};
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
ChangingLEConnectionStateTriggersUpdateCallback) {
device()->SetLEConnectionState(RemoteDevice::ConnectionState::kConnected);
EXPECT_TRUE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
ChangingBrEdrConnectionStateTriggersUpdateCallback) {
device()->SetBREDRConnectionState(RemoteDevice::ConnectionState::kConnected);
EXPECT_TRUE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetLEAdvertisingDataTriggersUpdateCallbackOnNameSet) {
device()->SetLEAdvertisingData(
kTestRSSI,
common::CreateStaticByteBuffer(0x05, // Length
0x09, // AD Type: Complete Local Name
'T', 'e', 's', 't'));
EXPECT_TRUE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
AddExistingBondedDeviceFails) {
auto res = cache()->AddBondedDevice(device()->identifier(),
device()->address(), kLTK);
EXPECT_FALSE(res);
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetLEAdvertisingDataUpdateCallbackProvidesUpdatedDevice) {
const auto kAdvData =
common::CreateStaticByteBuffer(0x05, 0x09, 'T', 'e', 's', 't');
ASSERT_NE(device()->rssi(), kTestRSSI);
cache()->set_device_updated_callback([&](const auto& updated_dev) {
EXPECT_TRUE(
common::ContainersEqual(kAdvData, updated_dev.advertising_data()));
EXPECT_EQ(updated_dev.rssi(), kTestRSSI);
});
device()->SetLEAdvertisingData(
kTestRSSI,
common::CreateStaticByteBuffer(0x05, // Length
0x09, // AD Type: Complete Local Name
'T', 'e', 's', 't'));
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetLEAdvertisingDataDoesNotTriggerUpdateCallbackOnSameName) {
device()->SetLEAdvertisingData(
kTestRSSI,
common::CreateStaticByteBuffer(0x05, // Length
0x09, // AD Type: Complete Local Name
'T', 'e', 's', 't'));
ASSERT_TRUE(was_called());
ClearWasCalled();
device()->SetLEAdvertisingData(
kTestRSSI,
common::CreateStaticByteBuffer(0x05, // Length
0x09, // AD Type: Complete Local Name
'T', 'e', 's', 't'));
EXPECT_FALSE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromInquiryResultTriggersUpdateCallbackOnDeviceClassSet) {
ir().class_of_device = common::DeviceClass({0x06, 0x02, 0x02}); // Phone.
device()->SetInquiryData(ir());
EXPECT_TRUE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromInquiryResultUpdateCallbackProvidesUpdatedDevice) {
ir().class_of_device = common::DeviceClass({0x06, 0x02, 0x02}); // Phone.
ASSERT_FALSE(device()->device_class().HasValue());
cache()->set_device_updated_callback([](const auto& updated_dev) {
ASSERT_TRUE(updated_dev.device_class().HasValue());
EXPECT_EQ(updated_dev.device_class()->major_class(),
common::DeviceClass::MajorClass(0x02));
});
device()->SetInquiryData(ir());
}
TEST_F(
GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromInquiryResultDoesNotTriggerUpdateCallbackOnSameDeviceClass) {
ir().class_of_device = common::DeviceClass({0x06, 0x02, 0x02}); // Phone.
device()->SetInquiryData(ir());
ASSERT_TRUE(was_called());
ClearWasCalled();
device()->SetInquiryData(ir());
EXPECT_FALSE(was_called());
}
TEST_F(
GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromInquiryResultRSSITriggersUpdateCallbackOnDeviceClassSet) {
irr().class_of_device = common::DeviceClass({0x06, 0x02, 0x02}); // Phone.
device()->SetInquiryData(irr());
EXPECT_TRUE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromInquiryResultRSSIUpdateCallbackProvidesUpdatedDevice) {
irr().class_of_device = common::DeviceClass({0x06, 0x02, 0x02}); // Phone.
ASSERT_FALSE(device()->device_class().HasValue());
cache()->set_device_updated_callback([](const auto& updated_dev) {
ASSERT_TRUE(updated_dev.device_class().HasValue());
EXPECT_EQ(updated_dev.device_class()->major_class(),
common::DeviceClass::MajorClass(0x02));
});
device()->SetInquiryData(irr());
}
TEST_F(
GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromInquiryResultRSSIDoesNotTriggerUpdateCallbackOnSameDeviceClass) {
irr().class_of_device = common::DeviceClass({0x06, 0x02, 0x02}); // Phone.
device()->SetInquiryData(irr());
ASSERT_TRUE(was_called());
ClearWasCalled();
device()->SetInquiryData(irr());
EXPECT_FALSE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromInquiryResultRSSIDoesNotTriggerUpdateCallbackOnRSSI) {
irr().rssi = 1;
device()->SetInquiryData(irr());
ASSERT_TRUE(was_called()); // Callback due to |class_of_device|.
ClearWasCalled();
irr().rssi = 20;
device()->SetInquiryData(irr());
EXPECT_FALSE(was_called());
}
TEST_F(
GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromExtendedInquiryResultEventParamsTriggersUpdateCallbackOnDeviceClassSet) {
eirep().class_of_device = common::DeviceClass({0x06, 0x02, 0x02}); // Phone.
device()->SetInquiryData(eirep());
EXPECT_TRUE(was_called());
}
TEST_F(
GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromExtendedInquiryResultEventParamsTriggersUpdateCallbackOnNameSet) {
device()->SetInquiryData(eirep());
ASSERT_TRUE(was_called()); // Callback due to |class_of_device|.
ClearWasCalled();
common::MutableBufferView(&eirep().extended_inquiry_response,
sizeof(eirep().extended_inquiry_response))
.Write(common::CreateStaticByteBuffer(
0x05, // Payload length.
0x09, // Complete Local Name Data Type.
'N', 'a', 'm', 'e'));
device()->SetInquiryData(eirep());
EXPECT_TRUE(was_called());
}
TEST_F(
GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromExtendedInquiryResultEventParamsUpdateCallbackProvidesUpdatedDevice) {
eirep().clock_offset = htole16(1);
eirep().page_scan_repetition_mode = hci::PageScanRepetitionMode::kR1;
eirep().rssi = kTestRSSI;
eirep().class_of_device = common::DeviceClass({0x06, 0x02, 0x02}); // Phone.
common::MutableBufferView(&eirep().extended_inquiry_response,
sizeof(eirep().extended_inquiry_response))
.Write(common::CreateStaticByteBuffer(
0x05, // Payload length.
0x09, // Complete Local Name Data Type.
'N', 'a', 'm', 'e'));
ASSERT_FALSE(device()->clock_offset().HasValue());
ASSERT_FALSE(device()->page_scan_repetition_mode().HasValue());
ASSERT_FALSE(device()->device_class().HasValue());
ASSERT_FALSE(device()->name().HasValue());
cache()->set_device_updated_callback([](const auto& updated_dev) {
ASSERT_TRUE(updated_dev.clock_offset().HasValue());
ASSERT_TRUE(updated_dev.page_scan_repetition_mode().HasValue());
ASSERT_TRUE(updated_dev.device_class().HasValue());
ASSERT_TRUE(updated_dev.name().HasValue());
EXPECT_EQ(*updated_dev.clock_offset(), 0x8001);
EXPECT_EQ(*updated_dev.page_scan_repetition_mode(),
hci::PageScanRepetitionMode::kR1);
EXPECT_EQ(updated_dev.rssi(), kTestRSSI);
EXPECT_EQ(updated_dev.device_class()->major_class(),
common::DeviceClass::MajorClass(0x02));
EXPECT_EQ(*updated_dev.name(), "Name");
});
device()->SetInquiryData(eirep());
}
TEST_F(
GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromExtendedInquiryResultEventParamsGeneratesExactlyOneUpdateCallbackRegardlessOfNumberOfFieldsChanged) {
eirep().clock_offset = htole16(1);
eirep().page_scan_repetition_mode = hci::PageScanRepetitionMode::kR1;
eirep().rssi = kTestRSSI;
eirep().class_of_device = common::DeviceClass({0x06, 0x02, 0x02}); // Phone.
common::MutableBufferView(&eirep().extended_inquiry_response,
sizeof(eirep().extended_inquiry_response))
.Write(common::CreateStaticByteBuffer(
0x05, // Payload length.
0x09, // Complete Local Name Data Type.
'N', 'a', 'm', 'e'));
size_t call_count = 0;
cache()->set_device_updated_callback([&](const auto&) { ++call_count; });
device()->SetInquiryData(eirep());
EXPECT_EQ(call_count, 1U);
}
TEST_F(
GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnSameDeviceClass) {
eirep().class_of_device = common::DeviceClass({0x06, 0x02, 0x02}); // Phone.
device()->SetInquiryData(eirep());
ASSERT_TRUE(was_called());
ClearWasCalled();
device()->SetInquiryData(eirep());
EXPECT_FALSE(was_called());
}
TEST_F(
GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnSameName) {
common::MutableBufferView(&eirep().extended_inquiry_response,
sizeof(eirep().extended_inquiry_response))
.Write(common::CreateStaticByteBuffer(
0x05, // Payload length.
0x09, // Complete Local Name data type.
'N', 'a', 'm', 'e'));
device()->SetInquiryData(eirep());
ASSERT_TRUE(was_called());
ClearWasCalled();
device()->SetInquiryData(eirep());
EXPECT_FALSE(was_called());
}
TEST_F(
GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnRSSI) {
eirep().rssi = 1;
device()->SetInquiryData(eirep());
ASSERT_TRUE(was_called()); // Callback due to |class_of_device|.
ClearWasCalled();
eirep().rssi = 20;
device()->SetInquiryData(eirep());
EXPECT_FALSE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetNameTriggersUpdateCallback) {
device()->SetName("nombre");
EXPECT_TRUE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetNameDoesNotTriggerUpdateCallbackOnSameName) {
device()->SetName("nombre");
ASSERT_TRUE(was_called());
bool was_called_again = false;
cache()->set_device_updated_callback(
[&](const auto&) { was_called_again = true; });
device()->SetName("nombre");
EXPECT_FALSE(was_called_again);
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetLEConnectionParamsDoesNotTriggerUpdateCallback) {
device()->set_le_connection_params({});
EXPECT_FALSE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
SetLEPreferredConnectionParamsDoesNotTriggerUpdateCallback) {
device()->set_le_preferred_connection_params({});
EXPECT_FALSE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
TryMakeTemporaryTriggersUpdateCallbackOnSuccessfulChange) {
ASSERT_TRUE(device()->TryMakeNonTemporary());
EXPECT_TRUE(was_called());
}
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest,
TryMakeTemporaryDoesNotTriggerUpdateCallbackWhenAlreadyTemporary) {
ASSERT_TRUE(device()->TryMakeNonTemporary());
ASSERT_TRUE(was_called());
bool was_called_again = false;
cache()->set_device_updated_callback(
[&](const auto&) { was_called_again = true; });
ASSERT_TRUE(device()->TryMakeNonTemporary());
EXPECT_FALSE(was_called_again);
}
using GAP_RemoteDeviceCacheTest_UpdateCallbackTest_NoConnectablePublicDevice =
GAP_RemoteDeviceCacheTest;
TEST_F(GAP_RemoteDeviceCacheTest_UpdateCallbackTest_NoConnectablePublicDevice,
TryMakeTemporaryDoesNotTriggerUpdateCallbackOnFailure) {
RemoteDeviceCache cache;
RemoteDevice* unconnectable_device = cache.NewDevice(kAddrPublic, false);
bool was_called = false;
cache.set_device_updated_callback([&](const auto&) { was_called = true; });
ASSERT_FALSE(was_called);
ASSERT_FALSE(unconnectable_device->TryMakeNonTemporary());
EXPECT_FALSE(was_called);
}
class GAP_RemoteDeviceCacheTest_ExpirationTest
: public GAP_RemoteDeviceCacheTest {
public:
void SetUp() {
device_ptr_ = cache_.NewDevice(kAddrPublic, true);
device_id_ = device_ptr_->identifier();
device_addr_ = device_ptr_->address();
}
protected:
RemoteDeviceCache* cache() { return &cache_; }
RemoteDevice* device_ptr() { return device_ptr_; }
std::string device_id() { return device_id_; }
common::DeviceAddress device_addr() { return device_addr_; }
private:
RemoteDeviceCache cache_;
RemoteDevice* device_ptr_;
std::string device_id_;
common::DeviceAddress device_addr_;
};
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
TemporaryDiesSixtySecondsAfterBirth) {
RunLoopFor(zx::sec(60));
EXPECT_FALSE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
TemporaryLivesForSixtySecondsAfterBirth) {
RunLoopFor(zx::sec(60) - zx::msec(1));
EXPECT_TRUE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
TemporaryLivesForSixtySecondsSinceLastSeen) {
RunLoopFor(zx::sec(60) - zx::msec(1));
ASSERT_EQ(device_ptr(), cache()->FindDeviceById(device_id()));
// Tickle device, and verify it sticks around for another cache timeout.
device_ptr()->SetName("nombre");
RunLoopFor(zx::sec(60) - zx::msec(1));
EXPECT_TRUE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
TemporaryDiesSixtySecondsAfterLastSeen) {
RunLoopFor(zx::sec(60) - zx::msec(1));
ASSERT_EQ(device_ptr(), cache()->FindDeviceById(device_id()));
// Tickle device, and verify it expires after cache timeout.
device_ptr()->SetName("nombre");
RunLoopFor(zx::sec(60));
EXPECT_FALSE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
NonTemporaryLivesMuchMoreThanSixtySeconds) {
ASSERT_TRUE(device_ptr()->TryMakeNonTemporary());
RunLoopFor(zx::sec(60) * 10);
EXPECT_TRUE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
CanMakeNonTemporaryJustBeforeSixtySeconds) {
// At last possible moment, make device non-temporary,
RunLoopFor(zx::sec(60) - zx::msec(1));
ASSERT_EQ(device_ptr(), cache()->FindDeviceById(device_id()));
ASSERT_TRUE(device_ptr()->TryMakeNonTemporary());
// Verify that devices survives.
RunLoopFor(zx::sec(60) * 10);
EXPECT_TRUE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
LEConnectedDeviceLivesMuchMoreThanSixtySeconds) {
device_ptr()->SetLEConnectionState(RemoteDevice::ConnectionState::kConnected);
RunLoopFor(zx::sec(60) * 10);
EXPECT_TRUE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
BREDRConnectedDeviceLivesMuchMoreThanSixtySeconds) {
device_ptr()->SetBREDRConnectionState(
RemoteDevice::ConnectionState::kConnected);
RunLoopFor(zx::sec(60) * 10);
EXPECT_TRUE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
LEDisconnectTriggersExpirationAfterSixtySeconds) {
device_ptr()->SetLEConnectionState(RemoteDevice::ConnectionState::kConnected);
RunLoopFor(zx::sec(60) * 10);
ASSERT_TRUE(cache()->FindDeviceById(device_id()));
device_ptr()->SetLEConnectionState(
RemoteDevice::ConnectionState::kNotConnected);
RunLoopFor(zx::sec(60));
EXPECT_FALSE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
BREDRDisconnectTriggersExpirationAfterSixySeconds) {
device_ptr()->SetBREDRConnectionState(
RemoteDevice::ConnectionState::kConnected);
RunLoopFor(zx::sec(60) * 10);
ASSERT_TRUE(cache()->FindDeviceById(device_id()));
device_ptr()->SetBREDRConnectionState(
RemoteDevice::ConnectionState::kNotConnected);
RunLoopFor(zx::sec(60));
EXPECT_FALSE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest, ExpirationUpdatesAddressMap) {
RunLoopFor(zx::sec(60));
EXPECT_FALSE(cache()->FindDeviceByAddress(device_addr()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
SetLEAdvertisingDataUpdatesExpiration) {
RunLoopFor(zx::sec(60) - zx::msec(1));
device_ptr()->SetLEAdvertisingData(kTestRSSI, common::StaticByteBuffer<1>{});
RunLoopFor(zx::msec(1));
EXPECT_TRUE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
SetInquiryDataFromInquiryResultUpdatesExpiration) {
hci::InquiryResult ir;
ir.bd_addr = device_addr().value();
RunLoopFor(zx::sec(60) - zx::msec(1));
device_ptr()->SetInquiryData(ir);
RunLoopFor(zx::msec(1));
EXPECT_TRUE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
SetInquiryDataFromInquiryResultRSSIUpdatesExpiration) {
hci::InquiryResultRSSI irr;
irr.bd_addr = device_addr().value();
RunLoopFor(zx::sec(60) - zx::msec(1));
device_ptr()->SetInquiryData(irr);
RunLoopFor(zx::msec(1));
EXPECT_TRUE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest,
SetInquiryDataFromExtendedInquiryResultEventParamsUpdatesExpiration) {
hci::ExtendedInquiryResultEventParams eirep;
eirep.bd_addr = device_addr().value();
RunLoopFor(zx::sec(60) - zx::msec(1));
device_ptr()->SetInquiryData(eirep);
RunLoopFor(zx::msec(1));
EXPECT_TRUE(cache()->FindDeviceById(device_id()));
}
TEST_F(GAP_RemoteDeviceCacheTest_ExpirationTest, SetNameUpdatesExpiration) {
RunLoopFor(zx::sec(60) - zx::msec(1));
device_ptr()->SetName({});
RunLoopFor(zx::msec(1));
EXPECT_TRUE(cache()->FindDeviceById(device_id()));
}
} // namespace
} // namespace gap
} // namespace btlib