Add initial pairing in scalable seeker

PiperOrigin-RevId: 541034178
This commit is contained in:
Janusz Sobczak
2023-06-16 16:14:14 -07:00
committed by Copybara-Service
parent 4914cbc2f9
commit 20acd4eeb9
10 changed files with 284 additions and 33 deletions
+2
View File
@@ -19,6 +19,7 @@ cc_library(
"//fastpair/scanning:scanner",
"//internal/platform:types",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings:str_format",
],
)
@@ -30,6 +31,7 @@ cc_test(
],
deps = [
":internal",
"//fastpair/message_stream:fake_gatt_callbacks",
"//fastpair/message_stream:fake_provider",
"//fastpair/server_access:test_support",
"//internal/platform:test_util",
+41 -1
View File
@@ -20,6 +20,7 @@
#include <utility>
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "fastpair/fast_pair_events.h"
#include "fastpair/pairing/pairer_broker_impl.h"
#include "fastpair/scanning/scanner_broker_impl.h"
@@ -36,10 +37,23 @@ FastPairSeekerImpl::FastPairSeekerImpl(ServiceCallbacks callbacks,
pairer_broker_->AddObserver(this);
}
FastPairSeekerImpl::~FastPairSeekerImpl() {
pairer_broker_->RemoveObserver(this);
FinishPairing(absl::AbortedError("Pairing terminated"));
DestroyOnExecutor(std::move(pairer_broker_), executor_);
}
absl::Status FastPairSeekerImpl::StartInitialPairing(
const FastPairDevice& device, const InitialPairingParam& params,
PairingCallback callback) {
return absl::UnimplementedError("StartInitialPairing");
if (pairer_broker_->IsPairing()) {
return absl::AlreadyExistsError("Already pairing");
}
pairing_callback_ = std::make_unique<PairingCallback>(std::move(callback));
device_under_pairing_ = &const_cast<FastPairDevice&>(device);
pairer_broker_->PairDevice(*device_under_pairing_);
return absl::OkStatus();
}
absl::Status FastPairSeekerImpl::StartSubsequentPairing(
@@ -84,6 +98,9 @@ void FastPairSeekerImpl::OnDeviceFound(FastPairDevice& device) {
// ScannerBroker::Observer::OnDeviceLost
void FastPairSeekerImpl::OnDeviceLost(FastPairDevice& device) {
NEARBY_LOGS(INFO) << "Device lost: " << device;
if (IsDeviceUnderPairing(device)) {
FinishPairing(absl::UnavailableError("Device lost during pairing"));
}
}
// PairerBroker:Observer::OnDevicePaired
@@ -109,6 +126,11 @@ void FastPairSeekerImpl::OnAccountKeyWrite(FastPairDevice& device,
// PairerBroker:Observer::OnPairingComplete
void FastPairSeekerImpl::OnPairingComplete(FastPairDevice& device) {
NEARBY_LOGS(INFO) << __func__ << ": " << device;
if (!IsDeviceUnderPairing(device)) {
NEARBY_LOGS(WARNING) << "unexpected on pair complete callback";
return;
}
FinishPairing(absl::OkStatus());
}
// PairerBroker:Observer::OnPairFailure
@@ -116,6 +138,24 @@ void FastPairSeekerImpl::OnPairFailure(FastPairDevice& device,
PairFailure failure) {
NEARBY_LOGS(INFO) << __func__ << ": " << device
<< " with PairFailure: " << failure;
if (!IsDeviceUnderPairing(device)) {
NEARBY_LOGS(WARNING) << "unexpected on pair failure callback";
return;
}
FinishPairing(
absl::InternalError(absl::StrFormat("Pairing failed with %v", failure)));
}
bool FastPairSeekerImpl::IsDeviceUnderPairing(const FastPairDevice& device) {
return device_under_pairing_ == &device;
}
void FastPairSeekerImpl::FinishPairing(absl::Status result) {
if (pairing_callback_ && device_under_pairing_ != nullptr) {
pairing_callback_->on_pairing_result(*device_under_pairing_, result);
}
pairing_callback_.reset();
device_under_pairing_ = nullptr;
}
void FastPairSeekerImpl::SetIsScreenLocked(bool locked) {
+8 -2
View File
@@ -22,7 +22,7 @@
#include "fastpair/fast_pair_events.h"
#include "fastpair/fast_pair_seeker.h"
#include "fastpair/internal/mediums/mediums.h"
#include "fastpair/pairing/pairer_broker.h"
#include "fastpair/pairing/pairer_broker_impl.h"
#include "fastpair/repository/fast_pair_device_repository.h"
#include "fastpair/scanning/scanner_broker_impl.h"
#include "internal/platform/single_thread_executor.h"
@@ -58,6 +58,8 @@ class FastPairSeekerImpl : public FastPairSeekerExt,
FastPairSeekerImpl(ServiceCallbacks callbacks, SingleThreadExecutor* executor,
FastPairDeviceRepository* devices);
~FastPairSeekerImpl() override;
// From FastPairSeeker.
absl::Status StartInitialPairing(const FastPairDevice& device,
const InitialPairingParam& params,
@@ -92,6 +94,8 @@ class FastPairSeekerImpl : public FastPairSeekerExt,
void OnPairFailure(FastPairDevice& device, PairFailure failure) override;
void InvalidateScanningState() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_);
bool IsDeviceUnderPairing(const FastPairDevice& device);
void FinishPairing(absl::Status result);
ServiceCallbacks callbacks_;
SingleThreadExecutor* executor_;
@@ -99,7 +103,9 @@ class FastPairSeekerImpl : public FastPairSeekerExt,
Mediums mediums_;
std::unique_ptr<ScannerBrokerImpl> scanner_;
std::unique_ptr<ScannerBrokerImpl::ScanningSession> scanning_session_;
std::unique_ptr<PairerBroker> pairer_broker_;
std::unique_ptr<PairerBrokerImpl> pairer_broker_;
std::unique_ptr<PairingCallback> pairing_callback_;
FastPairDevice* device_under_pairing_ = nullptr;
FastPairDevice* test_device_ = nullptr;
bool is_screen_locked_ = false;
};
@@ -23,6 +23,8 @@
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "fastpair/message_stream/fake_gatt_callbacks.h"
#include "fastpair/message_stream/fake_provider.h"
#include "fastpair/server_access/fake_fast_pair_repository.h"
#include "internal/platform/count_down_latch.h"
@@ -36,9 +38,13 @@ constexpr absl::string_view kServiceID{"Fast Pair"};
constexpr absl::string_view kFastPairServiceUuid{
"0000FE2C-0000-1000-8000-00805F9B34FB"};
constexpr absl::string_view kModelId{"718c17"};
constexpr absl::string_view kPublicAntiSpoof =
"Wuyr48lD3txnUhGiMF1IfzlTwRxxe+wMB1HLzP+"
"0wVcljfT3XPoiy1fntlneziyLD5knDVAJSE+RM/zlPRP/Jg==";
constexpr absl::string_view kBobPrivateKey =
"02B437B0EDD6BBD429064A4E529FCBF1C48D0D624924D592274B7ED81193D763";
constexpr absl::string_view kBobPublicKey =
"F7D496A62ECA416351540AA343BC690A6109F551500666B83B1251FB84FA2860795EBD63D3"
"B8836F44A9A3E28BB34017E015F5979305D849FDF8DE10123B61D2";
constexpr absl::string_view kPasskey = "123456";
constexpr absl::Duration kTaskWaitTimeout = absl::Milliseconds(100);
using ::testing::status::StatusIs;
@@ -52,7 +58,8 @@ class MediumEnvironmentStarter {
class FastPairSeekerImplTest : public testing::Test {
protected:
void SetUp() override {
repository_ = FakeFastPairRepository::Create(kModelId, kPublicAntiSpoof);
repository_ = FakeFastPairRepository::Create(
kModelId, absl::HexStringToBytes(kBobPublicKey));
}
void TearDown() override { executor_.Shutdown(); }
@@ -62,6 +69,7 @@ class FastPairSeekerImplTest : public testing::Test {
FastPairDeviceRepository devices_{&executor_};
std::unique_ptr<FakeFastPairRepository> repository_;
std::unique_ptr<FastPairSeekerImpl> fast_pair_seeker_;
FakeGattCallbacks fake_gatt_callbacks_;
};
TEST_F(FastPairSeekerImplTest, StartAndStopFastPairScan) {
@@ -136,6 +144,46 @@ TEST_F(FastPairSeekerImplTest, ScreenLocksDuringAdvertising) {
EXPECT_FALSE(latch.Await(kTaskWaitTimeout).result());
}
TEST_F(FastPairSeekerImplTest, InitialPairing) {
NEARBY_LOG_SET_SEVERITY(VERBOSE);
FakeProvider provider;
CountDownLatch discover_latch(1);
CountDownLatch pair_latch(1);
fast_pair_seeker_ = std::make_unique<FastPairSeekerImpl>(
FastPairSeekerImpl::ServiceCallbacks{
.on_initial_discovery =
[&](const FastPairDevice& device, InitialDiscoveryEvent event) {
EXPECT_EQ(device.GetModelId(), kModelId);
EXPECT_OK(fast_pair_seeker_->StartInitialPairing(
device, {},
{.on_pairing_result = [&](const FastPairDevice& device,
absl::Status status) {
EXPECT_EQ(device.GetBleAddress(),
provider.GetMacAddress());
EXPECT_OK(status);
pair_latch.CountDown();
}}));
discover_latch.CountDown();
}},
&executor_, &devices_);
EXPECT_OK(fast_pair_seeker_->StartFastPairScan());
provider.PrepareForInitialPairing(
{
.private_key = absl::HexStringToBytes(kBobPrivateKey),
.public_key = absl::HexStringToBytes(kBobPublicKey),
.model_id = std::string(kModelId),
.pass_key = std::string(kPasskey),
},
&fake_gatt_callbacks_);
discover_latch.Await();
pair_latch.Await();
auto fp_device = devices_.FindDevice(provider.GetMacAddress());
ASSERT_TRUE(fp_device.has_value());
EXPECT_EQ(provider.GetAccountKey(), fp_device.value()->GetAccountKey());
}
} // namespace
} // namespace fastpair
} // namespace nearby
+2
View File
@@ -55,6 +55,7 @@ cc_library(
"//fastpair:__subpackages__",
],
deps = [
":fake_gatt_callbacks",
":message_stream",
"//fastpair/common",
"//internal/platform:base",
@@ -87,6 +88,7 @@ cc_library(
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
],
)
+18 -9
View File
@@ -21,6 +21,7 @@
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/escaping.h"
#include "internal/platform/ble_v2.h"
#include "internal/platform/future.h"
@@ -43,14 +44,22 @@ class FakeGattCallbacks {
// characteristic
absl::StatusOr<std::string> read_value =
absl::FailedPreconditionError("characteristic not set");
absl::AnyInvocable<absl::Status(absl::string_view)> write_callback =
[&](absl::string_view data) {
write_value.Set(std::string(data));
return write_result;
};
absl::AnyInvocable<absl::StatusOr<std::string>()> read_callback = [&]() {
absl::AnyInvocable<absl::Status(absl::string_view)> write_callback;
absl::AnyInvocable<absl::StatusOr<std::string>()> read_callback;
absl::Status WriteCallback(absl::string_view data) {
if (write_callback) {
return write_callback(data);
}
write_value.Set(std::string(data));
return write_result;
}
absl::StatusOr<std::string> ReadCallback() {
if (read_callback) {
return read_callback();
}
return read_value;
};
}
};
BleV2Medium::ServerGattConnectionCallback GetGattCallback() {
@@ -65,7 +74,7 @@ class FakeGattCallbacks {
callback(absl::NotFoundError("characteristic not found"));
return;
}
callback(it->second.read_callback());
callback(it->second.ReadCallback());
},
.on_characteristic_write_cb =
[&](const api::ble_v2::BlePeripheral& remote_device,
@@ -78,7 +87,7 @@ class FakeGattCallbacks {
callback(absl::NotFoundError("characteristic not found"));
return;
}
callback(it->second.write_callback(data));
callback(it->second.WriteCallback(data));
}};
}
+119 -9
View File
@@ -18,7 +18,9 @@
#include "absl/status/status.h"
#include "absl/strings/escaping.h"
#include "absl/strings/numbers.h"
#include "fastpair/common/constant.h"
#include "internal/platform/medium_environment.h"
#include <openssl/base.h>
#include <openssl/bn.h>
#include <openssl/ec_key.h>
@@ -28,6 +30,10 @@ namespace fastpair {
namespace {
constexpr uint8_t kKeyBasedPairingResponseCode = 1;
constexpr uint8_t kSeekerPasskeyResponseCode = 2;
constexpr uint8_t kProviderPasskeyResponseCode = 3;
static EC_POINT *load_public_key(absl::string_view public_key) {
CHECK_EQ(public_key.size(), kPublicKeyByteSize);
BN_CTX *bn_ctx;
@@ -129,22 +135,22 @@ void FakeProvider::LoadAntiSpoofingKey(absl::string_view private_key,
}
std::string FakeProvider::DecryptKbpRequest(absl::string_view request) {
NEARBY_LOGS(INFO) << "Encrypted KBP request "
<< absl::BytesToHexString(request);
NEARBY_LOGS(VERBOSE) << "Encrypted KBP request "
<< absl::BytesToHexString(request);
CHECK_EQ(request.size(), kEncryptedDataByteSize + kPublicKeyByteSize);
absl::string_view encrypted = request.substr(0, kEncryptedDataByteSize);
absl::string_view remote_public_key =
request.substr(kEncryptedDataByteSize, kPublicKeyByteSize);
std::string shared_secret = CreateSharedSecret(remote_public_key);
std::string decrypted = Aes128Decrypt(encrypted, shared_secret);
NEARBY_LOGS(INFO) << "Decrypted KBP request "
<< absl::BytesToHexString(decrypted);
account_key_ = shared_secret;
NEARBY_LOGS(VERBOSE) << "Decrypted KBP request "
<< absl::BytesToHexString(decrypted);
shared_secret_ = shared_secret;
return decrypted;
}
std::string FakeProvider::Encrypt(absl::string_view data) {
return Aes128Encrypt(data, account_key_);
return Aes128Encrypt(data, shared_secret_);
}
std::string FakeProvider::GenSec256r1Secret(
@@ -199,9 +205,9 @@ std::string FakeProvider::CreateSharedSecret(
Crypto::Sha256(secret).AsStringView().substr(0, kAccountKeySize));
}
void FakeProvider::StartGattServer(
BleV2Medium::ServerGattConnectionCallback callback) {
gatt_server_ = ble_.StartGattServer(std::move(callback));
void FakeProvider::StartGattServer(FakeGattCallbacks *fake_gatt_callbacks) {
fake_gatt_callbacks_ = fake_gatt_callbacks;
gatt_server_ = ble_.StartGattServer(fake_gatt_callbacks_->GetGattCallback());
}
absl::Status FakeProvider::NotifyKeyBasedPairing(ByteArray response) {
@@ -211,8 +217,16 @@ absl::Status FakeProvider::NotifyKeyBasedPairing(ByteArray response) {
false, response);
}
absl::Status FakeProvider::NotifyPasskey(ByteArray response) {
CHECK_NE(gatt_server_, nullptr);
CHECK(passkey_characteristic_.has_value());
return gatt_server_->NotifyCharacteristicChanged(*passkey_characteristic_,
false, response);
}
void FakeProvider::StartDiscoverableAdvertisement(absl::string_view model_id) {
advertising_ = true;
model_id_ = model_id;
ble_v1_.StartAdvertising(std::string(kServiceID),
ByteArray(absl::HexStringToBytes(model_id)),
std::string(kFastPairServiceUuid));
@@ -225,5 +239,101 @@ void FakeProvider::StopAdvertising() {
}
}
void FakeProvider::SetKeyBasedPairingCallback() {
CHECK_NE(fake_gatt_callbacks_, nullptr);
CHECK(key_based_characteristic_.has_value());
fake_gatt_callbacks_->characteristics_[*key_based_characteristic_]
.write_callback = [this](absl::string_view request) {
NEARBY_LOGS(VERBOSE) << "Encrypted request: "
<< absl::BytesToHexString(request);
std::string decrypted_request = DecryptKbpRequest(request);
NEARBY_LOGS(VERBOSE) << "KBP decrypted request "
<< absl::BytesToHexString(decrypted_request);
fake_gatt_callbacks_->characteristics_[*key_based_characteristic_]
.write_value.Set(std::string(decrypted_request));
std::string response;
response.push_back(kKeyBasedPairingResponseCode);
response.append(GetMacAddressAsBytes());
response.resize(kEncryptedDataByteSize, 0);
absl::Status status = NotifyKeyBasedPairing(ByteArray(Encrypt(response)));
NEARBY_LOGS(VERBOSE) << "KBP notify result: " << status;
return absl::OkStatus();
};
}
void FakeProvider::SetPasskeyCallback() {
CHECK_NE(fake_gatt_callbacks_, nullptr);
CHECK(passkey_characteristic_.has_value());
fake_gatt_callbacks_->characteristics_[*passkey_characteristic_]
.write_callback = [this](absl::string_view request) {
NEARBY_LOGS(VERBOSE) << "Passkey Encrypted request: "
<< absl::BytesToHexString(request);
std::string decrypted = Aes128Decrypt(request, shared_secret_);
NEARBY_LOGS(VERBOSE) << "Passkey decrypted request "
<< absl::BytesToHexString(decrypted);
fake_gatt_callbacks_->characteristics_[*passkey_characteristic_]
.write_value.Set(std::string(decrypted));
if (decrypted[0] != kSeekerPasskeyResponseCode) {
return absl::InvalidArgumentError(
absl::StrFormat("Invalid passkey response code: 0x%x", decrypted[0]));
}
std::string response;
response.push_back(kProviderPasskeyResponseCode);
response.push_back(pass_key_ >> 16);
response.push_back(pass_key_ >> 8);
response.push_back(pass_key_);
response.resize(kEncryptedDataByteSize, 0);
absl::Status status = NotifyPasskey(ByteArray(Encrypt(response)));
NEARBY_LOGS(VERBOSE) << "Passkey notify result: " << status;
return absl::OkStatus();
};
}
void FakeProvider::SetAccountkeyCallback() {
CHECK_NE(fake_gatt_callbacks_, nullptr);
CHECK(accountkey_characteristic_.has_value());
fake_gatt_callbacks_->characteristics_[*accountkey_characteristic_]
.write_callback = [this](absl::string_view request) {
NEARBY_LOGS(VERBOSE) << "Account key encrypted request: "
<< absl::BytesToHexString(request);
std::string decrypted = Aes128Decrypt(request, shared_secret_);
NEARBY_LOGS(VERBOSE) << "Account key decrypted request "
<< absl::BytesToHexString(decrypted);
fake_gatt_callbacks_->characteristics_[*accountkey_characteristic_]
.write_value.Set(std::string(decrypted));
account_key_ = AccountKey(decrypted);
return absl::OkStatus();
};
}
void FakeProvider::ConfigurePairingContext(absl::string_view pass_key) {
api::PairingParams pairing_params;
pairing_params.pairing_type =
api::PairingParams::PairingType::kConfirmPasskey;
pairing_params.passkey = pass_key;
auto device = MediumEnvironment::Instance().FindBluetoothDevice(
provider_medium_.GetMacAddress());
CHECK_NE(device, nullptr);
MediumEnvironment::Instance().ConfigBluetoothPairingContext(device,
pairing_params);
CHECK(absl::SimpleAtoi(pass_key, &pass_key_));
}
void FakeProvider::PrepareForInitialPairing(
PairingConfig config, FakeGattCallbacks *fake_gatt_callbacks) {
LoadAntiSpoofingKey(config.private_key, config.public_key);
StartGattServer(fake_gatt_callbacks);
InsertCorrectGattCharacteristics();
SetKeyBasedPairingCallback();
SetPasskeyCallback();
SetAccountkeyCallback();
provider_adapter_.SetScanMode(
BluetoothAdapter::ScanMode::kConnectableDiscoverable);
ConfigurePairingContext(config.pass_key);
StartDiscoverableAdvertisement(config.model_id);
}
} // namespace fastpair
} // namespace nearby
+32 -4
View File
@@ -28,8 +28,10 @@
#include "absl/strings/escaping.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "fastpair/common/account_key.h"
#include "fastpair/common/constant.h"
#include "fastpair/common/fast_pair_device.h"
#include "fastpair/message_stream/fake_gatt_callbacks.h"
#include "fastpair/message_stream/message.h"
#include "internal/platform/ble.h"
#include "internal/platform/ble_v2.h"
@@ -71,8 +73,18 @@ class FakeProvider {
public:
using KeyBasedPairingCallback =
absl::AnyInvocable<std::string(absl::string_view)>;
struct PairingConfig {
std::string private_key; // binary, private Anti-Spoofing Key
std::string public_key; // binary, public Anti-Spoofing Key
std::string model_id;
std::string pass_key;
};
~FakeProvider() { Shutdown(); }
// Sets the fake provider up for initial pairing
void PrepareForInitialPairing(PairingConfig config,
FakeGattCallbacks* fake_gatt_callbacks);
void Shutdown() {
StopAdvertising();
provider_thread_.Shutdown();
@@ -151,25 +163,31 @@ class FakeProvider {
BluetoothUtils::FromString(provider_adapter_.GetMacAddress()));
}
void StartGattServer(BleV2Medium::ServerGattConnectionCallback callback);
void StartGattServer(FakeGattCallbacks* fake_gatt_callbacks);
void InsertCorrectGattCharacteristics() {
CHECK_NE(fake_gatt_callbacks_, nullptr);
key_based_characteristic_ = gatt_server_->CreateCharacteristic(
kFastPairServiceUuid, kKeyBasedCharacteristicUuidV2, permissions_,
properties_);
CHECK(key_based_characteristic_.has_value());
fake_gatt_callbacks_->characteristics_[*key_based_characteristic_]
.write_result = absl::OkStatus();
passkey_characteristic_ = gatt_server_->CreateCharacteristic(
kFastPairServiceUuid, kPasskeyCharacteristicUuidV2, permissions_,
properties_);
CHECK(passkey_characteristic_.has_value());
fake_gatt_callbacks_->characteristics_[*passkey_characteristic_]
.write_result = absl::OkStatus();
accountkey_characteristic_ = gatt_server_->CreateCharacteristic(
kFastPairServiceUuid, kAccountKeyCharacteristicUuidV2, permissions_,
properties_);
CHECK(accountkey_characteristic_.has_value());
fake_gatt_callbacks_->characteristics_[*accountkey_characteristic_]
.write_result = absl::OkStatus();
}
void LoadAntiSpoofingKey(absl::string_view private_key,
@@ -179,14 +197,20 @@ class FakeProvider {
std::string Encrypt(absl::string_view data);
absl::Status NotifyKeyBasedPairing(ByteArray response);
absl::Status NotifyPasskey(ByteArray response);
void StartDiscoverableAdvertisement(absl::string_view model_id);
void StopAdvertising();
void ConfigurePairingContext(absl::string_view pass_key);
AccountKey& GetAccountKey() { return account_key_; }
std::optional<GattCharacteristic> key_based_characteristic_;
std::optional<GattCharacteristic> passkey_characteristic_;
std::optional<GattCharacteristic> accountkey_characteristic_;
private:
void SetKeyBasedPairingCallback();
void SetPasskeyCallback();
void SetAccountkeyCallback();
std::string GenSec256r1Secret(absl::string_view remote_party_public_key);
std::string CreateSharedSecret(absl::string_view remote_public_key);
BluetoothAdapter provider_adapter_;
@@ -201,8 +225,12 @@ class FakeProvider {
Permission permissions_ = Permission::kWrite;
std::unique_ptr<EVP_PKEY, void (*)(EVP_PKEY*)> anti_spoofing_key_{
nullptr, EVP_PKEY_free};
std::string account_key_;
std::string shared_secret_;
SingleThreadExecutor provider_thread_;
std::string model_id_;
FakeGattCallbacks* fake_gatt_callbacks_ = nullptr;
unsigned int pass_key_;
AccountKey account_key_;
};
} // namespace fastpair
+1 -1
View File
@@ -55,7 +55,7 @@ class RetroactiveTest : public testing::Test {
provider_.DiscoverProvider(seeker_medium);
remote_device_ = seeker_medium.GetRemoteDevice(provider_.GetMacAddress());
provider_.StartGattServer(gatt_callbacks_.GetGattCallback());
provider_.StartGattServer(&gatt_callbacks_);
provider_.InsertCorrectGattCharacteristics();
ASSERT_TRUE(remote_device_.IsValid());
}
@@ -46,11 +46,17 @@ void FakeFastPairRepository::GetDeviceMetadata(
std::unique_ptr<FakeFastPairRepository> FakeFastPairRepository::Create(
absl::string_view model_id, absl::string_view public_anti_spoof_key) {
std::string decoded_key;
absl::Base64Unescape(public_anti_spoof_key, &decoded_key);
proto::Device metadata;
auto repository = std::make_unique<FakeFastPairRepository>();
metadata.mutable_anti_spoofing_key_pair()->set_public_key(decoded_key);
if (public_anti_spoof_key.length() == kPublicKeyByteSize) {
metadata.mutable_anti_spoofing_key_pair()->set_public_key(
public_anti_spoof_key);
} else {
std::string decoded_key;
absl::Base64Unescape(public_anti_spoof_key, &decoded_key);
CHECK_EQ(decoded_key.length(), kPublicKeyByteSize);
metadata.mutable_anti_spoofing_key_pair()->set_public_key(decoded_key);
}
repository->SetFakeMetadata(model_id, metadata);
return repository;
}