mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Refactor, remove scan_request dependency from AdvertisementDecoder
- Removes banned_data_types_, PUBLIC identity advertisements will never have any corresponding credentials anyways, so decryption will always be skipped and this is now guarenteed by asserts in UpdatePublicCredentials - Filtering adv based on identity is moved into advertisement Filter which already contains the requested identity info from scan_request - LegacyPresenceScanFilter is no longer used by AdvertisementDecoder since this is not being used anywhere at the moment - Cleanup miscellaneous clang-tidy lints about missing or unused includes PiperOrigin-RevId: 620086399
This commit is contained in:
@@ -170,6 +170,9 @@ cc_test(
|
||||
"//internal/proto:credential_cc_proto",
|
||||
"//presence:types",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
] + select({
|
||||
@@ -370,12 +373,19 @@ cc_test(
|
||||
srcs = ["scan_manager_test.cc"],
|
||||
deps = [
|
||||
":internal",
|
||||
":internal_test",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:comm",
|
||||
"//internal/platform:test_util",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation:comm",
|
||||
"//internal/platform/implementation:types",
|
||||
"//internal/proto:credential_cc_proto",
|
||||
"//presence:types",
|
||||
"//presence/implementation/mediums",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:variant",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
] + select({
|
||||
"@platforms//os:windows": [
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
|
||||
#include "presence/implementation/advertisement_decoder.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
@@ -155,8 +157,8 @@ absl::StatusOr<DataElement> ParseDataElement(const absl::string_view input,
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void AdvertisementDecoder::DecodeBaseAction(
|
||||
absl::string_view serialized_action) {
|
||||
void DecodeBaseAction(absl::string_view serialized_action,
|
||||
Advertisement& decoded_advertisement) {
|
||||
if (serialized_action.empty() || serialized_action.size() > 3) {
|
||||
NEARBY_LOGS(WARNING) << "Base NP action \'"
|
||||
<< absl::BytesToHexString(serialized_action)
|
||||
@@ -171,25 +173,25 @@ void AdvertisementDecoder::DecodeBaseAction(
|
||||
action.action |= serialized_action[i] << offset;
|
||||
}
|
||||
|
||||
ActionFactory::DecodeAction(action, decoded_advertisement_.data_elements);
|
||||
ActionFactory::DecodeAction(action, decoded_advertisement.data_elements);
|
||||
}
|
||||
|
||||
absl::StatusOr<std::string> AdvertisementDecoder::DecryptLdt(
|
||||
absl::StatusOr<std::string> DecryptLdt(
|
||||
const std::vector<internal::SharedCredential>& credentials,
|
||||
absl::string_view salt, absl::string_view data_elements) {
|
||||
absl::string_view salt, absl::string_view encrypted_contents,
|
||||
Advertisement& decoded_advertisement) {
|
||||
if (credentials.empty()) {
|
||||
return absl::UnavailableError("No credentials");
|
||||
}
|
||||
for (const auto& credential : credentials) {
|
||||
absl::StatusOr<LdtEncryptor> encryptor = LdtEncryptor::Create(
|
||||
credential.key_seed(),
|
||||
credential.metadata_encryption_key_tag_v0());
|
||||
credential.key_seed(), credential.metadata_encryption_key_tag_v0());
|
||||
if (encryptor.ok()) {
|
||||
absl::StatusOr<std::string> result =
|
||||
encryptor->DecryptAndVerify(data_elements, salt);
|
||||
encryptor->DecryptAndVerify(encrypted_contents, salt);
|
||||
if (result.ok() && result->size() > kBaseMetadataSize) {
|
||||
decoded_advertisement_.public_credential = credential;
|
||||
decoded_advertisement_.metadata_key =
|
||||
decoded_advertisement.public_credential = credential;
|
||||
decoded_advertisement.metadata_key =
|
||||
result->substr(0, kBaseMetadataSize);
|
||||
return result->substr(kBaseMetadataSize);
|
||||
}
|
||||
@@ -199,18 +201,20 @@ absl::StatusOr<std::string> AdvertisementDecoder::DecryptLdt(
|
||||
"Couldn't decrypt the message with any credentials");
|
||||
}
|
||||
|
||||
absl::Status AdvertisementDecoder::DecryptDataElements(
|
||||
const DataElement& elem) {
|
||||
absl::Status DecryptDataElements(
|
||||
const std::vector<internal::SharedCredential>& credentials,
|
||||
const DataElement& elem, Advertisement& decoded_advertisement) {
|
||||
if (elem.GetValue().size() <= kEncryptedIdentityAdditionalLength) {
|
||||
return absl::OutOfRangeError(absl::StrFormat(
|
||||
"Encrypted identity data element is too short - %d bytes",
|
||||
elem.GetValue().size()));
|
||||
}
|
||||
absl::string_view salt = elem.GetValue().substr(0, kSaltSize);
|
||||
decoded_advertisement_.data_elements.emplace_back(DataElement::kSaltFieldType,
|
||||
salt);
|
||||
decoded_advertisement.data_elements.emplace_back(DataElement::kSaltFieldType,
|
||||
salt);
|
||||
absl::string_view encrypted = elem.GetValue().substr(kSaltSize);
|
||||
absl::StatusOr<std::string> decrypted = Decrypt(salt, encrypted);
|
||||
absl::StatusOr<std::string> decrypted =
|
||||
DecryptLdt(credentials, salt, encrypted, decoded_advertisement);
|
||||
if (!decrypted.ok()) {
|
||||
NEARBY_LOGS(WARNING) << "Failed to decrypt advertisement, status: "
|
||||
<< decrypted.status();
|
||||
@@ -226,74 +230,19 @@ absl::Status AdvertisementDecoder::DecryptDataElements(
|
||||
return internal_elem.status();
|
||||
}
|
||||
if (internal_elem->GetType() == DataElement::kActionFieldType) {
|
||||
DecodeBaseAction(internal_elem->GetValue());
|
||||
DecodeBaseAction(internal_elem->GetValue(), decoded_advertisement);
|
||||
} else {
|
||||
decoded_advertisement_.data_elements.push_back(*std::move(internal_elem));
|
||||
decoded_advertisement.data_elements.push_back(*std::move(internal_elem));
|
||||
}
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::StatusOr<std::string> AdvertisementDecoder::Decrypt(
|
||||
absl::string_view salt, absl::string_view encrypted) {
|
||||
for (const auto& scan_filter : scan_request_.scan_filters) {
|
||||
if (!absl::holds_alternative<LegacyPresenceScanFilter>(scan_filter)) {
|
||||
continue;
|
||||
}
|
||||
const std::vector<nearby::internal::SharedCredential>& credentials =
|
||||
absl::get<LegacyPresenceScanFilter>(scan_filter)
|
||||
.remote_public_credentials;
|
||||
if (credentials.empty()) {
|
||||
continue;
|
||||
}
|
||||
absl::StatusOr<std::string> decrypted =
|
||||
DecryptLdt(credentials, salt, encrypted);
|
||||
if (decrypted.ok()) {
|
||||
return decrypted;
|
||||
}
|
||||
}
|
||||
if (credentials_ == nullptr) {
|
||||
return absl::FailedPreconditionError("Missing credentials");
|
||||
}
|
||||
|
||||
return DecryptLdt((*credentials_)[decoded_advertisement_.identity_type], salt,
|
||||
encrypted);
|
||||
}
|
||||
|
||||
void AdvertisementDecoder::AddBannedDataTypes() {
|
||||
// The scan request has information what identity types the client is
|
||||
// interested in. We'll ban all other idenitity data types.
|
||||
banned_data_types_ = {DataElement::kPrivateIdentityFieldType,
|
||||
DataElement::kTrustedIdentityFieldType,
|
||||
DataElement::kPublicIdentityFieldType,
|
||||
DataElement::kProvisionedIdentityFieldType};
|
||||
for (nearby::internal::IdentityType identity_type :
|
||||
scan_request_.identity_types) {
|
||||
switch (identity_type) {
|
||||
case internal::IDENTITY_TYPE_PRIVATE:
|
||||
banned_data_types_.erase(DataElement::kPrivateIdentityFieldType);
|
||||
break;
|
||||
case internal::IDENTITY_TYPE_TRUSTED:
|
||||
banned_data_types_.erase(DataElement::kTrustedIdentityFieldType);
|
||||
break;
|
||||
case internal::IDENTITY_TYPE_PUBLIC:
|
||||
banned_data_types_.erase(DataElement::kPublicIdentityFieldType);
|
||||
break;
|
||||
case internal::IDENTITY_TYPE_PROVISIONED:
|
||||
banned_data_types_.erase(DataElement::kProvisionedIdentityFieldType);
|
||||
break;
|
||||
default:
|
||||
// Nothing to do
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
absl::StatusOr<Advertisement> AdvertisementDecoder::DecodeAdvertisement(
|
||||
absl::string_view advertisement) {
|
||||
// Let's keep the result advertisement in a member variable to avoid passing
|
||||
// it around all the time.
|
||||
decoded_advertisement_ = Advertisement{};
|
||||
Advertisement decoded_advertisement = Advertisement{};
|
||||
std::vector<DataElement> result;
|
||||
NEARBY_LOGS(INFO) << "Advertisement: "
|
||||
<< absl::BytesToHexString(advertisement);
|
||||
@@ -306,7 +255,7 @@ absl::StatusOr<Advertisement> AdvertisementDecoder::DecodeAdvertisement(
|
||||
return absl::UnimplementedError(absl::StrFormat(
|
||||
"Advertisement version (%d) is not supported", version));
|
||||
}
|
||||
decoded_advertisement_.version = version;
|
||||
decoded_advertisement.version = version;
|
||||
size_t index = 1;
|
||||
absl::StatusOr<std::string> decrypted;
|
||||
while (index < advertisement.size()) {
|
||||
@@ -316,31 +265,30 @@ absl::StatusOr<Advertisement> AdvertisementDecoder::DecodeAdvertisement(
|
||||
<< elem.status();
|
||||
return elem.status();
|
||||
}
|
||||
// This checks allows us to bail before decryption when, for example, the
|
||||
// client is scanning for advertisements with private identity but the
|
||||
// advertisement uses trusted identity.
|
||||
if (banned_data_types_.contains(elem->GetType())) {
|
||||
return absl::FailedPreconditionError(
|
||||
absl::StrFormat("Ignoring advertisement with data element type: %d",
|
||||
elem->GetType()));
|
||||
}
|
||||
if (IsIdentity(elem->GetType())) {
|
||||
decoded_advertisement_.identity_type = GetIdentityType(elem->GetType());
|
||||
decoded_advertisement.identity_type = GetIdentityType(elem->GetType());
|
||||
}
|
||||
if (IsEncryptedIdentity(elem->GetType())) {
|
||||
absl::Status status = DecryptDataElements(*elem);
|
||||
if (credentials_map_ == nullptr) {
|
||||
return absl::FailedPreconditionError("Missing credentials");
|
||||
}
|
||||
auto identity_type_specific_creds =
|
||||
(*credentials_map_)[decoded_advertisement.identity_type];
|
||||
absl::Status status = DecryptDataElements(identity_type_specific_creds,
|
||||
*elem, decoded_advertisement);
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
if (elem->GetType() == DataElement::kActionFieldType) {
|
||||
DecodeBaseAction(elem->GetValue());
|
||||
DecodeBaseAction(elem->GetValue(), decoded_advertisement);
|
||||
} else {
|
||||
decoded_advertisement_.data_elements.push_back(*std::move(elem));
|
||||
decoded_advertisement.data_elements.push_back(*std::move(elem));
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::move(decoded_advertisement_);
|
||||
|
||||
return std::move(decoded_advertisement);
|
||||
}
|
||||
|
||||
} // namespace presence
|
||||
|
||||
@@ -15,17 +15,16 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_DECODER_H_
|
||||
#define THIRD_PARTY_NEARBY_PRESENCE_ADVERTISEMENT_DECODER_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "internal/platform/implementation/credential_callbacks.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/proto/credential.pb.h"
|
||||
#include "presence/data_element.h"
|
||||
#include "presence/scan_request.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace presence {
|
||||
@@ -42,20 +41,13 @@ struct Advertisement {
|
||||
// Decodes BLE NP advertisements
|
||||
class AdvertisementDecoder {
|
||||
public:
|
||||
using IdentityType = ::nearby::internal::IdentityType;
|
||||
explicit AdvertisementDecoder(
|
||||
absl::flat_hash_map<internal::IdentityType,
|
||||
std::vector<internal::SharedCredential>>*
|
||||
credentials_map)
|
||||
: credentials_map_(credentials_map) {};
|
||||
|
||||
AdvertisementDecoder(
|
||||
ScanRequest scan_request,
|
||||
absl::flat_hash_map<IdentityType,
|
||||
std::vector<internal::SharedCredential>>* credentials)
|
||||
: scan_request_(scan_request), credentials_(credentials) {
|
||||
AddBannedDataTypes();
|
||||
}
|
||||
|
||||
explicit AdvertisementDecoder(ScanRequest scan_request)
|
||||
: scan_request_(scan_request) {
|
||||
AddBannedDataTypes();
|
||||
}
|
||||
explicit AdvertisementDecoder() = default;
|
||||
|
||||
// Returns a list of Data Elements decoded from the advertisement.
|
||||
// Returns an error if the advertisement is misformatted or if it couldn't be
|
||||
@@ -64,22 +56,9 @@ class AdvertisementDecoder {
|
||||
absl::string_view advertisement);
|
||||
|
||||
private:
|
||||
// Decrypts data elements stored inside encrypted `elem` and appends them to
|
||||
// `decoded_advertisement_`.
|
||||
absl::Status DecryptDataElements(const DataElement& elem);
|
||||
absl::StatusOr<std::string> Decrypt(absl::string_view salt,
|
||||
absl::string_view encrypted);
|
||||
void DecodeBaseAction(absl::string_view serialized_action);
|
||||
absl::StatusOr<std::string> DecryptLdt(
|
||||
const std::vector<internal::SharedCredential>& credentials,
|
||||
absl::string_view salt, absl::string_view data_elements);
|
||||
void AddBannedDataTypes();
|
||||
|
||||
ScanRequest scan_request_;
|
||||
absl::flat_hash_map<IdentityType, std::vector<internal::SharedCredential>>*
|
||||
credentials_ = nullptr;
|
||||
absl::flat_hash_set<int> banned_data_types_;
|
||||
Advertisement decoded_advertisement_;
|
||||
absl::flat_hash_map<internal::IdentityType,
|
||||
std::vector<internal::SharedCredential>>*
|
||||
credentials_map_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace presence
|
||||
|
||||
@@ -14,15 +14,16 @@
|
||||
|
||||
#include "presence/implementation/advertisement_decoder.h"
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/proto/credential.pb.h"
|
||||
@@ -34,13 +35,10 @@ namespace nearby {
|
||||
namespace presence {
|
||||
|
||||
namespace {
|
||||
using ::nearby::ByteArray; // NOLINT
|
||||
using ::nearby::internal::IdentityType;
|
||||
using ::nearby::ByteArray; // NOLINT
|
||||
using ::nearby::internal::IdentityType; // NOLINT
|
||||
using ::nearby::internal::SharedCredential; // NOLINT
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Matcher;
|
||||
using ::testing::Pointwise;
|
||||
using ::testing::Return;
|
||||
using ::testing::UnorderedElementsAre;
|
||||
using ::testing::status::StatusIs;
|
||||
|
||||
@@ -64,7 +62,6 @@ ScanRequest GetScanRequest(std::vector<SharedCredential> credentials) {
|
||||
.AddIdentityType(IdentityType::IDENTITY_TYPE_TRUSTED)
|
||||
.AddIdentityType(IdentityType::IDENTITY_TYPE_PUBLIC)
|
||||
.AddIdentityType(IdentityType::IDENTITY_TYPE_PROVISIONED)
|
||||
.AddScanFilter(scan_filter)
|
||||
.Build();
|
||||
}
|
||||
|
||||
@@ -92,11 +89,10 @@ TEST(AdvertisementDecoder, DecodeBaseNpPrivateAdvertisement) {
|
||||
credentials;
|
||||
credentials[IdentityType::IDENTITY_TYPE_PRIVATE].push_back(
|
||||
GetPublicCredential());
|
||||
AdvertisementDecoder decoder(GetScanRequest(), &credentials);
|
||||
AdvertisementDecoder decoder(&credentials);
|
||||
|
||||
absl::StatusOr<Advertisement> result = decoder.DecodeAdvertisement(
|
||||
absl::HexStringToBytes("00514142b8412efb0bc657ba514baf4d1b50ddc842cd1c"));
|
||||
|
||||
ASSERT_OK(result);
|
||||
EXPECT_EQ(result->metadata_key, metadata_key.AsStringView());
|
||||
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PRIVATE);
|
||||
@@ -113,13 +109,15 @@ TEST(AdvertisementDecoder,
|
||||
const std::string salt = "AB";
|
||||
ByteArray metadata_key(
|
||||
{205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174});
|
||||
std::vector<SharedCredential> credentials = {GetPublicCredential()};
|
||||
|
||||
AdvertisementDecoder decoder(GetScanRequest(credentials));
|
||||
absl::flat_hash_map<IdentityType, std::vector<internal::SharedCredential>>
|
||||
credentials;
|
||||
credentials[IdentityType::IDENTITY_TYPE_PRIVATE].push_back(
|
||||
GetPublicCredential());
|
||||
AdvertisementDecoder decoder(&credentials);
|
||||
|
||||
absl::StatusOr<Advertisement> result = decoder.DecodeAdvertisement(
|
||||
absl::HexStringToBytes("00514142b8412efb0bc657ba514baf4d1b50ddc842cd1c"));
|
||||
|
||||
ASSERT_OK(result);
|
||||
EXPECT_EQ(result->metadata_key, metadata_key.AsStringView());
|
||||
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PRIVATE);
|
||||
@@ -139,11 +137,10 @@ TEST(AdvertisementDecoder, DecodeBaseNpTrustedAdvertisement) {
|
||||
credentials;
|
||||
credentials[IdentityType::IDENTITY_TYPE_TRUSTED].push_back(
|
||||
GetPublicCredential());
|
||||
AdvertisementDecoder decoder(GetScanRequest(), &credentials);
|
||||
AdvertisementDecoder decoder(&credentials);
|
||||
|
||||
absl::StatusOr<Advertisement> result = decoder.DecodeAdvertisement(
|
||||
absl::HexStringToBytes("0052414257a35c020f1c547d7e169303196d75da7118ba"));
|
||||
|
||||
ASSERT_OK(result);
|
||||
EXPECT_EQ(result->metadata_key, metadata_key.AsStringView());
|
||||
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_TRUSTED);
|
||||
@@ -166,11 +163,10 @@ TEST(AdvertisementDecoder, DecodeBaseNpProvisionedAdvertisement) {
|
||||
credentials;
|
||||
credentials[IdentityType::IDENTITY_TYPE_PROVISIONED].push_back(
|
||||
GetPublicCredential());
|
||||
AdvertisementDecoder decoder(GetScanRequest(), &credentials);
|
||||
AdvertisementDecoder decoder(&credentials);
|
||||
|
||||
absl::StatusOr<Advertisement> result = decoder.DecodeAdvertisement(
|
||||
absl::HexStringToBytes("0054414257a35c020f1c547d7e169303196d75da7118ba"));
|
||||
|
||||
ASSERT_OK(result);
|
||||
EXPECT_EQ(result->metadata_key, metadata_key.AsStringView());
|
||||
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PROVISIONED);
|
||||
@@ -193,7 +189,7 @@ TEST(AdvertisementDecoder, InvalidEncryptedContent) {
|
||||
credentials;
|
||||
credentials[IdentityType::IDENTITY_TYPE_PRIVATE].push_back(
|
||||
GetPublicCredential());
|
||||
AdvertisementDecoder decoder(GetScanRequest(), &credentials);
|
||||
AdvertisementDecoder decoder(&credentials);
|
||||
|
||||
EXPECT_THAT(decoder.DecodeAdvertisement(absl::HexStringToBytes(
|
||||
"00414142f085d661ac8cb110e792e7faeb736294")),
|
||||
@@ -204,7 +200,7 @@ TEST(AdvertisementDecoder, InvalidEncryptedContent) {
|
||||
|
||||
TEST(AdvertisementDecoder, DecodeBaseNpPublicAdvertisement) {
|
||||
const std::string salt = "AB";
|
||||
AdvertisementDecoder decoder(GetScanRequest());
|
||||
AdvertisementDecoder decoder;
|
||||
|
||||
const absl::StatusOr<Advertisement> result = decoder.DecodeAdvertisement(
|
||||
absl::HexStringToBytes("002041420337C1C2C31BEE"));
|
||||
@@ -224,7 +220,7 @@ TEST(AdvertisementDecoder, DecodeBaseNpPublicAdvertisement) {
|
||||
|
||||
TEST(AdvertisementDecoder, DecodeBaseNpWithTxAndActionFields) {
|
||||
std::string salt = "AB";
|
||||
AdvertisementDecoder decoder(GetScanRequest());
|
||||
AdvertisementDecoder decoder;
|
||||
|
||||
auto result = decoder.DecodeAdvertisement(
|
||||
absl::HexStringToBytes("0020414203155036B04180"));
|
||||
@@ -243,12 +239,11 @@ TEST(AdvertisementDecoder, DecodeBaseNpWithTxAndActionFields) {
|
||||
}
|
||||
|
||||
TEST(AdvertisementDecoder, DecodeBaseNpV0PublicIdentityWithTxAndActionFields) {
|
||||
AdvertisementDecoder decoder(GetScanRequest());
|
||||
AdvertisementDecoder decoder;
|
||||
|
||||
auto result = decoder.DecodeAdvertisement(
|
||||
// v0 public identity, power and action, action value 8 for active unlock.
|
||||
absl::HexStringToBytes("000315FF260080"));
|
||||
|
||||
EXPECT_OK(result);
|
||||
EXPECT_THAT(result->data_elements,
|
||||
UnorderedElementsAre(
|
||||
@@ -258,21 +253,8 @@ TEST(AdvertisementDecoder, DecodeBaseNpV0PublicIdentityWithTxAndActionFields) {
|
||||
DataElement(DataElement(ActionBit::kActiveUnlockAction))));
|
||||
}
|
||||
|
||||
TEST(AdvertisementDecoder,
|
||||
ScanForEncryptedIdentityIgnoresPublicIdentityAdvertisement) {
|
||||
AdvertisementDecoder decoder(
|
||||
{.account_name = std::string(kAccountName),
|
||||
.identity_types = {IdentityType::IDENTITY_TYPE_PRIVATE,
|
||||
IdentityType::IDENTITY_TYPE_TRUSTED,
|
||||
IdentityType::IDENTITY_TYPE_PROVISIONED}});
|
||||
|
||||
EXPECT_THAT(decoder.DecodeAdvertisement(
|
||||
absl::HexStringToBytes("00204142034650B04180")),
|
||||
StatusIs(absl::StatusCode::kFailedPrecondition));
|
||||
}
|
||||
|
||||
TEST(AdvertisementDecoder, DecodeEddystone) {
|
||||
AdvertisementDecoder decoder(GetScanRequest());
|
||||
AdvertisementDecoder decoder;
|
||||
std::string eddystone_id =
|
||||
absl::HexStringToBytes("A0A1A2A3A4A5A6A7A8A9B0B1B2B3B4B5B6B7B8B9");
|
||||
|
||||
@@ -288,7 +270,7 @@ TEST(AdvertisementDecoder, DecodeEddystone) {
|
||||
// TODO(b/238214467): Add more negative tests
|
||||
TEST(AdvertisementDecoder, UnsupportedDataElement) {
|
||||
std::string valid_header_and_salt = absl::HexStringToBytes("00204142");
|
||||
AdvertisementDecoder decoder(GetScanRequest());
|
||||
AdvertisementDecoder decoder;
|
||||
|
||||
EXPECT_THAT(decoder.DecodeAdvertisement(valid_header_and_salt +
|
||||
absl::HexStringToBytes("0D")),
|
||||
@@ -296,7 +278,7 @@ TEST(AdvertisementDecoder, UnsupportedDataElement) {
|
||||
}
|
||||
|
||||
TEST(AdvertisementDecoder, InvalidAdvertisementFieldTooShort) {
|
||||
AdvertisementDecoder decoder(GetScanRequest());
|
||||
AdvertisementDecoder decoder;
|
||||
|
||||
// 0x59 header means 5 bytes long Account Key Data but only 4 bytes follow.
|
||||
EXPECT_THAT(
|
||||
@@ -305,7 +287,7 @@ TEST(AdvertisementDecoder, InvalidAdvertisementFieldTooShort) {
|
||||
}
|
||||
|
||||
TEST(AdvertisementDecoder, ZeroLengthPayload) {
|
||||
AdvertisementDecoder decoder(GetScanRequest());
|
||||
AdvertisementDecoder decoder;
|
||||
|
||||
// A action with type 0xA and no payload
|
||||
const absl::StatusOr<Advertisement> result =
|
||||
@@ -316,14 +298,14 @@ TEST(AdvertisementDecoder, ZeroLengthPayload) {
|
||||
}
|
||||
|
||||
TEST(AdvertisementDecoder, EmptyAdvertisement) {
|
||||
AdvertisementDecoder decoder(GetScanRequest());
|
||||
AdvertisementDecoder decoder;
|
||||
|
||||
EXPECT_THAT(decoder.DecodeAdvertisement(""),
|
||||
StatusIs(absl::StatusCode::kOutOfRange));
|
||||
}
|
||||
|
||||
TEST(AdvertisementDecoder, UnsupportedAdvertisementVersion) {
|
||||
AdvertisementDecoder decoder(GetScanRequest());
|
||||
AdvertisementDecoder decoder;
|
||||
|
||||
EXPECT_THAT(decoder.DecodeAdvertisement(
|
||||
absl::HexStringToBytes("012041420318CD29EEFF")),
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/variant.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "presence/data_element.h"
|
||||
#include "presence/implementation/advertisement_decoder.h"
|
||||
#include "presence/scan_request.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -54,21 +56,42 @@ bool ContainsAny(const std::vector<DataElement>& data_elements,
|
||||
}
|
||||
|
||||
bool AdvertisementFilter::MatchesScanFilter(
|
||||
const std::vector<DataElement>& data_elements) {
|
||||
const Advertisement& advertisement) {
|
||||
// Verify the identity is one requested in the scan_request.
|
||||
// Per the Public API of scan_request, if identity_types provided in the
|
||||
// scan_request is empty then decode advertisements of every identity type
|
||||
auto requested_identity_types = scan_request_.identity_types;
|
||||
if (!requested_identity_types.empty() &&
|
||||
!(std::find(
|
||||
requested_identity_types.begin(), requested_identity_types.end(),
|
||||
advertisement.identity_type) != requested_identity_types.end())) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Skipping advertisement with identity type: "
|
||||
<< advertisement.identity_type
|
||||
<< " because that identity type was not requested in the scan "
|
||||
"request";
|
||||
return false;
|
||||
}
|
||||
|
||||
// The advertisement matches the scan request when it matches at least
|
||||
// one of the filters in the request.
|
||||
if (scan_request_.scan_filters.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOLINT is used to suppress google3-legacy-absl-backport lints because the
|
||||
// the suggestion is not compatible with Chrome
|
||||
for (const auto& filter : scan_request_.scan_filters) {
|
||||
if (absl::holds_alternative<PresenceScanFilter>(filter)) {
|
||||
if (MatchesScanFilter(data_elements,
|
||||
absl::get<PresenceScanFilter>(filter))) {
|
||||
if (absl::holds_alternative<PresenceScanFilter>(filter)) { // NOLINT
|
||||
if (MatchesScanFilter(advertisement.data_elements,
|
||||
absl::get<PresenceScanFilter>(filter))) { // NOLINT
|
||||
return true;
|
||||
}
|
||||
} else if (absl::holds_alternative<LegacyPresenceScanFilter>(filter)) {
|
||||
if (MatchesScanFilter(data_elements,
|
||||
absl::get<LegacyPresenceScanFilter>(filter))) {
|
||||
} else if (absl::holds_alternative<LegacyPresenceScanFilter>( // NOLINT
|
||||
filter)) {
|
||||
if (MatchesScanFilter(
|
||||
advertisement.data_elements,
|
||||
absl::get<LegacyPresenceScanFilter>(filter))) { // NOLINT
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "presence/data_element.h"
|
||||
#include "presence/implementation/advertisement_decoder.h"
|
||||
#include "presence/scan_request.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -29,7 +30,7 @@ class AdvertisementFilter {
|
||||
|
||||
// Returns true if the decoded advertisement in `data_elements` matches the
|
||||
// filters in `scan_request`.
|
||||
bool MatchesScanFilter(const std::vector<DataElement>& data_elements);
|
||||
bool MatchesScanFilter(const Advertisement& adv);
|
||||
|
||||
private:
|
||||
bool MatchesScanFilter(const std::vector<DataElement>& data_elements,
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/proto/credential.pb.h"
|
||||
#include "presence/data_element.h"
|
||||
#include "presence/implementation/advertisement_decoder.h"
|
||||
#include "presence/scan_request.h"
|
||||
#include "presence/scan_request_builder.h"
|
||||
|
||||
@@ -42,7 +43,8 @@ TEST(AdvertisementFilter, MatchesScanFilterNoFilterPasses) {
|
||||
|
||||
// A scan request without scan filters matches any advertisement
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter(
|
||||
{DataElement(DataElement::kPrivateIdentityFieldType, "payload")}));
|
||||
{.data_elements = {
|
||||
DataElement(DataElement::kPrivateIdentityFieldType, "payload")}}));
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter({}));
|
||||
}
|
||||
|
||||
@@ -56,14 +58,16 @@ TEST(AdvertisementFilter, MatchesPresenceScanFilter) {
|
||||
PresenceScanFilter filter = {.extended_properties = {model_id, salt}};
|
||||
|
||||
AdvertisementFilter adv_filter(
|
||||
|
||||
ScanRequestBuilder().AddScanFilter(filter).Build());
|
||||
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter({}));
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter({salt}));
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter({salt, model_id}));
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter({salt, salt2, model_id}));
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter({salt2, model_id}));
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter({.data_elements = {salt}}));
|
||||
EXPECT_TRUE(
|
||||
adv_filter.MatchesScanFilter({.data_elements = {salt, model_id}}));
|
||||
EXPECT_TRUE(
|
||||
adv_filter.MatchesScanFilter({.data_elements = {salt, salt2, model_id}}));
|
||||
EXPECT_FALSE(
|
||||
adv_filter.MatchesScanFilter({.data_elements = {salt2, model_id}}));
|
||||
}
|
||||
|
||||
TEST(AdvertisementFilter, MatchesLegacyPresenceScanFilter) {
|
||||
@@ -76,14 +80,48 @@ TEST(AdvertisementFilter, MatchesLegacyPresenceScanFilter) {
|
||||
LegacyPresenceScanFilter filter = {.extended_properties = {model_id, salt}};
|
||||
|
||||
AdvertisementFilter adv_filter(
|
||||
|
||||
ScanRequestBuilder().AddScanFilter(filter).Build());
|
||||
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter({}));
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter({salt}));
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter({salt, model_id}));
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter({salt, salt2, model_id}));
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter({salt2, model_id}));
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter(Advertisement{}));
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter({.data_elements = {salt}}));
|
||||
EXPECT_TRUE(
|
||||
adv_filter.MatchesScanFilter({.data_elements = {salt, model_id}}));
|
||||
EXPECT_TRUE(
|
||||
adv_filter.MatchesScanFilter({.data_elements = {salt, salt2, model_id}}));
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter(
|
||||
Advertisement{.data_elements = {salt2, model_id}}));
|
||||
}
|
||||
|
||||
TEST(AdvertisementFilter,
|
||||
EncryptedIdentityFilterIgnoresPublicIdentityAdvertisement) {
|
||||
AdvertisementFilter adv_filter(
|
||||
{.identity_types = {internal::IdentityType::IDENTITY_TYPE_PRIVATE,
|
||||
internal::IdentityType::IDENTITY_TYPE_TRUSTED,
|
||||
internal::IdentityType::IDENTITY_TYPE_PROVISIONED}});
|
||||
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter(
|
||||
{.identity_type = internal::IdentityType::IDENTITY_TYPE_PUBLIC}));
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter(
|
||||
{.identity_type = internal::IdentityType::IDENTITY_TYPE_PRIVATE}));
|
||||
}
|
||||
|
||||
TEST(AdvertisementFilter, PublicIdentityFilterMatchesPublicIdentityAdv) {
|
||||
AdvertisementFilter adv_filter(
|
||||
{.identity_types = {internal::IdentityType::IDENTITY_TYPE_PUBLIC}});
|
||||
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter(
|
||||
{.identity_type = internal::IdentityType::IDENTITY_TYPE_PUBLIC}));
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter(
|
||||
{.identity_type = internal::IdentityType::IDENTITY_TYPE_PRIVATE}));
|
||||
}
|
||||
|
||||
TEST(AdvertisementFilter, EmptyIdentityFilterMatchesAllAdvIdentityTypes) {
|
||||
AdvertisementFilter adv_filter({});
|
||||
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter(
|
||||
{.identity_type = internal::IdentityType::IDENTITY_TYPE_PUBLIC}));
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter(
|
||||
{.identity_type = internal::IdentityType::IDENTITY_TYPE_PRIVATE}));
|
||||
}
|
||||
|
||||
TEST(AdvertisementFilter, MatchesLegacyPresenceScanFilterWithActions) {
|
||||
@@ -99,11 +137,12 @@ TEST(AdvertisementFilter, MatchesLegacyPresenceScanFilterWithActions) {
|
||||
.extended_properties = {model_id, salt}};
|
||||
|
||||
AdvertisementFilter adv_filter(
|
||||
|
||||
ScanRequestBuilder().AddScanFilter(filter).Build());
|
||||
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter({salt, model_id}));
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter({salt, ttt_action, model_id}));
|
||||
EXPECT_FALSE(
|
||||
adv_filter.MatchesScanFilter({.data_elements = {salt, model_id}}));
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter(
|
||||
{.data_elements = {salt, ttt_action, model_id}}));
|
||||
}
|
||||
|
||||
TEST(AdvertisementFilter, MatchesMultipleFilters) {
|
||||
@@ -124,9 +163,10 @@ TEST(AdvertisementFilter, MatchesMultipleFilters) {
|
||||
.AddScanFilter(legacy_filter)
|
||||
.Build());
|
||||
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter({model_id}));
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter({salt, ttt_action}));
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter({ttt_action}));
|
||||
EXPECT_TRUE(adv_filter.MatchesScanFilter({.data_elements = {model_id}}));
|
||||
EXPECT_TRUE(
|
||||
adv_filter.MatchesScanFilter({.data_elements = {salt, ttt_action}}));
|
||||
EXPECT_FALSE(adv_filter.MatchesScanFilter({.data_elements = {ttt_action}}));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -14,24 +14,29 @@
|
||||
|
||||
#include "presence/implementation/scan_manager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <assert.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/types/variant.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/future.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/implementation/credential_callbacks.h"
|
||||
#include "internal/platform/implementation/crypto.h"
|
||||
#include "internal/platform/uuid.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "presence//implementation/advertisement_filter.h"
|
||||
#include "presence/data_element.h"
|
||||
#include "presence/data_types.h"
|
||||
#include "presence/device_motion.h"
|
||||
#include "presence/implementation/advertisement_decoder.h"
|
||||
#include "presence/implementation/mediums/ble.h"
|
||||
#include "presence/presence_action.h"
|
||||
#include "presence/presence_device.h"
|
||||
#include "presence/scan_request.h"
|
||||
|
||||
@@ -75,7 +80,7 @@ ScanSessionId ScanManager::StartScan(ScanRequest scan_request,
|
||||
{id, ScanSessionState{
|
||||
.request = scan_request,
|
||||
.callback = std::move(scan_callback),
|
||||
.decoder = AdvertisementDecoder(scan_request),
|
||||
.decoder = AdvertisementDecoder(),
|
||||
.advertisement_filter = AdvertisementFilter(scan_request),
|
||||
.scanning_session = mediums_->GetBle().StartScanning(
|
||||
scan_request, std::move(callback))}});
|
||||
@@ -113,8 +118,8 @@ void ScanManager::NotifyFoundBle(ScanSessionId id, BleAdvertisementData data,
|
||||
// This advertisement is not relevant to the current element, skip.
|
||||
return;
|
||||
}
|
||||
if (it->second.advertisement_filter.MatchesScanFilter(
|
||||
advert->data_elements)) {
|
||||
|
||||
if (it->second.advertisement_filter.MatchesScanFilter(*advert)) {
|
||||
internal::DeviceIdentityMetaData device_identity_metadata;
|
||||
device_identity_metadata.set_bluetooth_mac_address(
|
||||
std::string(remote_address));
|
||||
@@ -194,13 +199,19 @@ void ScanManager::FetchCredentials(ScanSessionId id,
|
||||
void ScanManager::UpdateCredentials(ScanSessionId id,
|
||||
IdentityType identity_type,
|
||||
std::vector<SharedCredential> credentials) {
|
||||
// Credentials should never get fetched for PUBLIC of No-Identity requests
|
||||
assert(identity_type != internal::IDENTITY_TYPE_UNSPECIFIED);
|
||||
assert(identity_type != internal::IDENTITY_TYPE_PUBLIC);
|
||||
|
||||
auto it = scan_sessions_.find(id);
|
||||
|
||||
if (it == scan_sessions_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScanSessionState& session = it->second;
|
||||
session.credentials[identity_type] = std::move(credentials);
|
||||
session.decoder = AdvertisementDecoder(session.request, &session.credentials);
|
||||
session.decoder = AdvertisementDecoder(&session.credentials);
|
||||
}
|
||||
|
||||
int ScanManager::ScanningCallbacksLengthForTest() {
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
|
||||
#include "presence/implementation/scan_manager.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@@ -25,17 +23,30 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/variant.h"
|
||||
#include "internal/platform/bluetooth_adapter.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/implementation/credential_callbacks.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/platform/single_thread_executor.h"
|
||||
#include "internal/proto/credential.proto.h"
|
||||
#include "presence/broadcast_request.h"
|
||||
#include "presence/data_element.h"
|
||||
#include "presence/data_types.h"
|
||||
#include "presence/implementation/advertisement_factory.h"
|
||||
#include "presence/implementation/base_broadcast_request.h"
|
||||
#include "presence/implementation/credential_manager_impl.h"
|
||||
#include "presence/implementation/mediums/advertisement_data.h"
|
||||
#include "presence/implementation/mediums/ble.h"
|
||||
#include "presence/implementation/mediums/mediums.h"
|
||||
#include "presence/implementation/mock_credential_manager.h"
|
||||
#include "presence/power_mode.h"
|
||||
#include "presence/presence_action.h"
|
||||
#include "presence/presence_device.h"
|
||||
#include "presence/scan_request.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace presence {
|
||||
@@ -325,6 +336,90 @@ TEST_F(ScanManagerTest, NoDeviceFoundAfterStopScan) {
|
||||
executor_.Shutdown();
|
||||
}
|
||||
|
||||
internal::SharedCredential GetPublicCredential() {
|
||||
// Values copied from LDT tests
|
||||
ByteArray seed({204, 219, 36, 137, 233, 252, 172, 66, 179, 147, 72,
|
||||
184, 148, 30, 209, 154, 29, 54, 14, 117, 224, 152,
|
||||
200, 193, 94, 107, 28, 194, 182, 32, 205, 57});
|
||||
ByteArray known_mac({0xB4, 0xC5, 0x9F, 0xA5, 0x99, 0x24, 0x1B, 0x81,
|
||||
0x75, 0x8D, 0x97, 0x6B, 0x5A, 0x62, 0x1C, 0x05,
|
||||
0x23, 0x2F, 0xE1, 0xBF, 0x89, 0xAE, 0x59, 0x87,
|
||||
0xCA, 0x25, 0x4C, 0x35, 0x54, 0xDC, 0xE5, 0x0E});
|
||||
internal::SharedCredential public_credential;
|
||||
public_credential.set_key_seed(seed.AsStringView());
|
||||
public_credential.set_metadata_encryption_key_tag_v0(
|
||||
known_mac.AsStringView());
|
||||
return public_credential;
|
||||
}
|
||||
|
||||
std::vector<internal::SharedCredential> BuildSharedCredentials() {
|
||||
return {GetPublicCredential()};
|
||||
}
|
||||
|
||||
internal::LocalCredential CreateLocalCredential(
|
||||
internal::IdentityType identity_type) {
|
||||
// Values copied from LDT tests
|
||||
ByteArray seed({204, 219, 36, 137, 233, 252, 172, 66, 179, 147, 72,
|
||||
184, 148, 30, 209, 154, 29, 54, 14, 117, 224, 152,
|
||||
200, 193, 94, 107, 28, 194, 182, 32, 205, 57});
|
||||
ByteArray metadata_key(
|
||||
{205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174});
|
||||
|
||||
internal::LocalCredential private_credential;
|
||||
private_credential.set_identity_type(identity_type);
|
||||
private_credential.set_key_seed(seed.AsStringView());
|
||||
private_credential.set_metadata_encryption_key_v0(
|
||||
metadata_key.AsStringView());
|
||||
return private_credential;
|
||||
}
|
||||
|
||||
TEST_F(ScanManagerTest, ScanningE2EWithEncryptedAdvertisementAndCredentials) {
|
||||
Mediums mediums;
|
||||
auto mock_credential_manager = MockCredentialManager();
|
||||
EXPECT_CALL(mock_credential_manager, GetPublicCredentials)
|
||||
.WillOnce([&](const CredentialSelector& credential_selector,
|
||||
PublicCredentialType public_credential_type,
|
||||
GetPublicCredentialsResultCallback callback) {
|
||||
callback.credentials_fetched_cb(BuildSharedCredentials());
|
||||
});
|
||||
ScanManager manager(mediums, mock_credential_manager, executor_);
|
||||
|
||||
// Set up advertiser to broadcast a private identity adv
|
||||
nearby::BluetoothAdapter server_adapter;
|
||||
Ble ble2(server_adapter);
|
||||
PresenceBroadcast::BroadcastSection section = {
|
||||
.identity = internal::IdentityType::IDENTITY_TYPE_PRIVATE,
|
||||
.extended_properties = MakeDefaultExtendedProperties(),
|
||||
.account_name = "Test account"};
|
||||
PresenceBroadcast presence_request = {.sections = {section}};
|
||||
BroadcastRequest input = {.tx_power = 30, .variant = presence_request};
|
||||
absl::StatusOr<BaseBroadcastRequest> request =
|
||||
BaseBroadcastRequest::Create(input);
|
||||
EXPECT_OK(request);
|
||||
absl::StatusOr<AdvertisementData> advertisement =
|
||||
AdvertisementFactory().CreateAdvertisement(
|
||||
request.value(),
|
||||
CreateLocalCredential(internal::IdentityType::IDENTITY_TYPE_PRIVATE));
|
||||
EXPECT_OK(advertisement);
|
||||
std::unique_ptr<AdvertisingSession> session = ble2.StartAdvertising(
|
||||
advertisement.value(), PowerMode::kLowPower,
|
||||
AdvertisingCallback{.start_advertising_result = [](absl::Status) {}});
|
||||
env_.Sync();
|
||||
|
||||
auto scan_request = MakeDefaultScanRequest();
|
||||
scan_request.identity_types = {
|
||||
nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE};
|
||||
|
||||
// Start scanning
|
||||
ScanSessionId scan_session =
|
||||
manager.StartScan(scan_request, MakeDefaultScanCallback());
|
||||
EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 1);
|
||||
EXPECT_TRUE(start_latch_.Await().Ok());
|
||||
EXPECT_TRUE(found_latch_.Await().Ok());
|
||||
manager.StopScan(scan_session);
|
||||
EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace presence
|
||||
} // namespace nearby
|
||||
|
||||
Reference in New Issue
Block a user