[BLE Refactor] Add Psm value to BleAdvertisement and BleAdvertisementHeader.

PiperOrigin-RevId: 440410863
This commit is contained in:
edwinwu
2022-04-08 11:20:59 -07:00
committed by Copybara-Service
parent 338faab8c9
commit 59ea8e8005
9 changed files with 181 additions and 76 deletions
+4 -4
View File
@@ -100,9 +100,9 @@ bool BleV2::StartAdvertising(
ByteArray medium_advertisement_bytes{mediums::BleAdvertisement{
mediums::BleAdvertisement::Version::kV2,
mediums::BleAdvertisement::SocketVersion::kV2,
/* service_id_hash= */
is_fast_advertisement ? ByteArray{} : service_id_hash,
advertisement_bytes, mediums::bleutils::GenerateDeviceToken()}};
/*service_id_hash=*/is_fast_advertisement ? ByteArray{} : service_id_hash,
advertisement_bytes, mediums::bleutils::GenerateDeviceToken(),
mediums::BleAdvertisementHeader::kDefaultPsmValue}};
if (medium_advertisement_bytes.Empty()) {
NEARBY_LOGS(INFO) << "Failed to BLE advertise because we could not wrap a "
"connection advertisement to medium advertisement.";
@@ -443,7 +443,7 @@ ByteArray BleV2::CreateAdvertisementHeader() {
mediums::BloomFilter bloom_filter(
std::make_unique<mediums::BitSetImpl<
mediums::BleAdvertisementHeader::kServiceIdBloomFilterLength>>());
mediums::BleAdvertisementHeader::kServiceIdBloomFilterByteLength>>());
bloom_filter.Add(dummy_service_id);
ByteArray advertisement_hash =
@@ -16,7 +16,11 @@
#include <inttypes.h>
#include <string>
#include <utility>
#include "absl/strings/str_cat.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h"
#include "internal/platform/base_input_stream.h"
#include "internal/platform/logging.h"
@@ -29,16 +33,16 @@ BleAdvertisement::BleAdvertisement(Version version,
SocketVersion socket_version,
const ByteArray &service_id_hash,
const ByteArray &data,
const ByteArray &device_token) {
const ByteArray &device_token, int psm) {
DoInitialize(/*fast_advertisement=*/service_id_hash.Empty(), version,
socket_version, service_id_hash, data, device_token);
socket_version, service_id_hash, data, device_token, psm);
}
void BleAdvertisement::DoInitialize(bool fast_advertisement, Version version,
SocketVersion socket_version,
const ByteArray &service_id_hash,
const ByteArray &data,
const ByteArray &device_token) {
const ByteArray &device_token, int psm) {
// Check that the given input is valid.
fast_advertisement_ = fast_advertisement;
if (!fast_advertisement_) {
@@ -64,6 +68,7 @@ void BleAdvertisement::DoInitialize(bool fast_advertisement, Version version,
if (!fast_advertisement_) service_id_hash_ = service_id_hash;
data_ = data;
device_token_ = device_token;
psm_ = psm;
}
BleAdvertisement::BleAdvertisement(const ByteArray &ble_advertisement_bytes) {
@@ -149,6 +154,20 @@ BleAdvertisement::BleAdvertisement(const ByteArray &ble_advertisement_bytes) {
// then read it.
if (base_input_stream.IsAvailable(kDeviceTokenLength)) {
device_token_ = base_input_stream.ReadBytes(kDeviceTokenLength);
} else {
// No device token no more optional field.
return;
}
// Extra fields, for backward compatible reason, put this field in the end of
// this advertisement. That means it must support device token if there's any
// extra field. E.g. If iOS or other platform wants to use extra fields, need
// to put a random or empty device token in the advertisement.
// TODO(b/219939733): Implement BleExtraField to read the PSM value. We fake
// this extra field as uint16, 2 bytes.
if (base_input_stream.IsAvailable(
BleAdvertisementHeader::kPsmValueByteLength)) {
psm_ = static_cast<int>(base_input_stream.ReadUint16());
}
}
@@ -173,6 +192,10 @@ BleAdvertisement::operator ByteArray() const {
SerializeDataSize(fast_advertisement_, data_size_bytes_write_ptr,
data_.size());
// For Extra fields, there's no space for legacy fast advertisement, use
// ByteArrayWithExtraField() to get the new advertisement bytes for extended
// advertising.
// clang-format on
if (fast_advertisement_) {
std::string out =
@@ -189,13 +212,27 @@ BleAdvertisement::operator ByteArray() const {
// clang-format on
}
ByteArray BleAdvertisement::ByteArrayWithExtraField() const {
ByteArray advertisement_bytes = ByteArray(*this);
// TODO(b/219939733): Implement BleExtraField for PSM value.
ByteArray psm_byte{BleAdvertisementHeader::kPsmValueByteLength};
char *data = psm_byte.data();
data[0] = psm_ & 0xFF00;
data[1] = psm_ & 0x00FF;
std::string advertisement_with_extra_bytes =
absl::StrCat(std::string(advertisement_bytes), std::string(psm_byte));
return ByteArray(std::move(advertisement_with_extra_bytes));
}
bool BleAdvertisement::operator==(const BleAdvertisement &rhs) const {
return this->GetVersion() == rhs.GetVersion() &&
this->GetSocketVersion() == rhs.GetSocketVersion() &&
this->IsFastAdvertisement() == rhs.IsFastAdvertisement() &&
this->GetServiceIdHash() == rhs.GetServiceIdHash() &&
this->GetData() == rhs.GetData() &&
this->GetDeviceToken() == rhs.GetDeviceToken();
this->GetDeviceToken() == rhs.GetDeviceToken() &&
this->GetPsm() == rhs.GetPsm();
}
bool BleAdvertisement::IsSupportedVersion(Version version) const {
@@ -17,6 +17,7 @@
#include <utility>
#include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h"
#include "internal/platform/byte_array.h"
namespace location {
@@ -27,11 +28,13 @@ namespace mediums {
// Represents the format of the Mediums BLE Advertisement used in Advertising +
// Discovery.
//
// [VERSION][SOCKET_VERSION][FAST_ADVERTISEMENT_FLAG][1_RESERVED_BIT][SERVICE_ID_HASH][DATA_SIZE][DATA][DEVICE_TOKEN]
// [VERSION][SOCKET_VERSION][FAST_ADVERTISEMENT_FLAG][1_RESERVED_BIT]
// [SERVICE_ID_HASH][DATA_SIZE][DATA][DEVICE_TOKEN][EXTRA_FIELD]
//
// For fast advertisement, we remove SERVICE_ID_HASH since we already have one
// copy in Nearby Connections(b/138447288)
// [VERSION][SOCKET_VERSION][FAST_ADVERTISEMENT_FLAG][1_RESERVED_BIT][DATA_SIZE][DATA][DEVICE_TOKEN]
// [VERSION][SOCKET_VERSION][FAST_ADVERTISEMENT_FLAG][1_RESERVED_BIT][DATA_SIZE]
// [DATA][DEVICE_TOKEN][EXTRA_FIELD]
//
// See go/nearby-ble-design for more information.
class BleAdvertisement {
@@ -63,13 +66,14 @@ class BleAdvertisement {
friend H AbslHashValue(H h, const BleAdvertisement &b) {
return H::combine(std::move(h), b.version_, b.socket_version_,
b.fast_advertisement_, b.service_id_hash_, b.data_,
b.device_token_);
b.device_token_, b.psm_);
}
BleAdvertisement() = default;
BleAdvertisement(Version version, SocketVersion socket_version,
const ByteArray &service_id_hash, const ByteArray &data,
const ByteArray &device_token);
const ByteArray &device_token,
int psm = BleAdvertisementHeader::kDefaultPsmValue);
explicit BleAdvertisement(const ByteArray &ble_advertisement_bytes);
BleAdvertisement(const BleAdvertisement &) = default;
BleAdvertisement &operator=(const BleAdvertisement &) = default;
@@ -77,8 +81,12 @@ class BleAdvertisement {
BleAdvertisement &operator=(BleAdvertisement &&) = default;
~BleAdvertisement() = default;
// Returns ByteArray for legacy advertisement.
explicit operator ByteArray() const;
// Returns ByteArray for extended advertisement, which included extra field.
ByteArray ByteArrayWithExtraField() const;
bool IsValid() const { return IsSupportedVersion(version_); }
Version GetVersion() const { return version_; }
SocketVersion GetSocketVersion() const { return socket_version_; }
@@ -89,12 +97,13 @@ class BleAdvertisement {
ByteArray &&GetData() && { return std::move(data_); }
const ByteArray &&GetData() const && { return std::move(data_); }
ByteArray GetDeviceToken() const { return device_token_; }
int GetPsm() const { return psm_; }
private:
void DoInitialize(bool fast_advertisement, Version version,
SocketVersion socket_version,
const ByteArray &service_id_hash, const ByteArray &data,
const ByteArray &device_token);
const ByteArray &device_token, int psm);
bool IsSupportedVersion(Version version) const;
bool IsSupportedSocketVersion(SocketVersion socket_version) const;
void SerializeDataSize(bool fast_advertisement,
@@ -135,6 +144,7 @@ class BleAdvertisement {
ByteArray service_id_hash_;
ByteArray data_;
ByteArray device_token_;
int psm_ = BleAdvertisementHeader::kDefaultPsmValue;
};
} // namespace mediums
@@ -16,6 +16,9 @@
#include <inttypes.h>
#include <string>
#include <utility>
#include "absl/strings/str_cat.h"
#include "internal/platform/base64_utils.h"
#include "internal/platform/base_input_stream.h"
@@ -27,16 +30,18 @@ namespace connections {
namespace mediums {
// These definitions are necessary before C++17.
constexpr int BleAdvertisementHeader::kAdvertisementHashLength;
constexpr int BleAdvertisementHeader::kServiceIdBloomFilterLength;
constexpr int BleAdvertisementHeader::kAdvertisementHashByteLength;
constexpr int BleAdvertisementHeader::kServiceIdBloomFilterByteLength;
constexpr int BleAdvertisementHeader::kDefaultPsmValue;
constexpr int BleAdvertisementHeader::kPsmValueByteLength;
BleAdvertisementHeader::BleAdvertisementHeader(
Version version, bool extended_advertisement, int num_slots,
const ByteArray &service_id_bloom_filter,
const ByteArray &advertisement_hash, int psm) {
if (version != Version::kV2 || num_slots < 0 ||
service_id_bloom_filter.size() != kServiceIdBloomFilterLength ||
advertisement_hash.size() != kAdvertisementHashLength) {
service_id_bloom_filter.size() != kServiceIdBloomFilterByteLength ||
advertisement_hash.size() != kAdvertisementHashByteLength) {
return;
}
@@ -93,13 +98,14 @@ BleAdvertisementHeader::BleAdvertisementHeader(
// The next 10 bytes are supposed to be the service_id_bloom_filter.
service_id_bloom_filter_ =
base_input_stream.ReadBytes(kServiceIdBloomFilterLength);
base_input_stream.ReadBytes(kServiceIdBloomFilterByteLength);
// The next 4 bytes are supposed to be the advertisement_hash.
advertisement_hash_ = base_input_stream.ReadBytes(kAdvertisementHashLength);
advertisement_hash_ =
base_input_stream.ReadBytes(kAdvertisementHashByteLength);
// The next 2 bytes are PSM value.
if (base_input_stream.IsAvailable(sizeof(std::uint16_t))) {
if (base_input_stream.IsAvailable(kPsmValueByteLength)) {
psm_ = static_cast<int>(base_input_stream.ReadUint16());
}
}
@@ -121,8 +127,8 @@ BleAdvertisementHeader::operator ByteArray() const {
static_cast<char>(num_slots_) & kNumSlotsBitmask;
// Convert psm_ value to 2-bytes.
ByteArray psm_byte{sizeof(std::uint16_t)};
char *data = psm_byte.data();
ByteArray psm_bytes{kPsmValueByteLength};
char *data = psm_bytes.data();
data[0] = psm_ & 0xFF00;
data[1] = psm_ & 0x00FF;
@@ -130,7 +136,7 @@ BleAdvertisementHeader::operator ByteArray() const {
std::string out = absl::StrCat(std::string(1, version_and_num_slots_byte),
std::string(service_id_bloom_filter_),
std::string(advertisement_hash_),
std::string(psm_byte));
std::string(psm_bytes));
// clang-format on
return ByteArray(std::move(out));
@@ -143,7 +149,7 @@ bool BleAdvertisementHeader::operator==(
GetNumSlots() == rhs.GetNumSlots() &&
GetServiceIdBloomFilter() == rhs.GetServiceIdBloomFilter() &&
GetAdvertisementHash() == rhs.GetAdvertisementHash() &&
GetPsmValue() == rhs.GetPsmValue();
GetPsm() == rhs.GetPsm();
}
} // namespace mediums
@@ -51,8 +51,10 @@ class BleAdvertisementHeader {
// characteristic so the two are not compatible.
};
static constexpr int kAdvertisementHashLength = 4;
static constexpr int kServiceIdBloomFilterLength = 10;
static constexpr int kAdvertisementHashByteLength = 4;
static constexpr int kServiceIdBloomFilterByteLength = 10;
static constexpr int kDefaultPsmValue = 0;
static constexpr int kPsmValueByteLength = 2;
// Hashable
bool operator==(const BleAdvertisementHeader &rhs) const;
@@ -84,13 +86,14 @@ class BleAdvertisementHeader {
int GetNumSlots() const { return num_slots_; }
ByteArray GetServiceIdBloomFilter() const { return service_id_bloom_filter_; }
ByteArray GetAdvertisementHash() const { return advertisement_hash_; }
int GetPsmValue() const { return psm_; }
int GetPsm() const { return psm_; }
void SetPsm(int psm) { psm_ = psm; }
private:
static constexpr int kVersionAndNumSlotsLength = 1;
static constexpr int kMinAdvertisementHeaderLength =
kVersionAndNumSlotsLength + kServiceIdBloomFilterLength +
kAdvertisementHashLength;
kVersionAndNumSlotsLength + kServiceIdBloomFilterByteLength +
kAdvertisementHashByteLength;
static constexpr int kVersionBitmask = 0x0E0;
static constexpr int kExtendedAdvertismentBitMask = 0x010;
static constexpr int kNumSlotsBitmask = 0x00F;
@@ -100,7 +103,7 @@ class BleAdvertisementHeader {
int num_slots_ = 0;
ByteArray service_id_bloom_filter_;
ByteArray advertisement_hash_;
int psm_ = 0;
int psm_ = kDefaultPsmValue;
};
} // namespace mediums
@@ -14,6 +14,8 @@
#include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h"
#include <string>
#include "gtest/gtest.h"
#include "absl/hash/hash_testing.h"
#include "internal/platform/base64_utils.h"
@@ -27,7 +29,7 @@ namespace {
constexpr BleAdvertisementHeader::Version kVersion =
BleAdvertisementHeader::Version::kV2;
constexpr int kNumSlots = 2;
constexpr std::int16_t kPsmValue = 1;
constexpr int kPsmValue = 127;
constexpr absl::string_view kServiceIDBloomFilter{
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"};
constexpr absl::string_view kAdvertisementHash{"\x0a\x0b\x0c\x0d"};
@@ -48,7 +50,7 @@ TEST(BleAdvertisementHeaderTest, ConstructionWorks) {
ble_advertisement_header.GetServiceIdBloomFilter());
EXPECT_EQ(advertisement_hash,
ble_advertisement_header.GetAdvertisementHash());
EXPECT_EQ(kPsmValue, ble_advertisement_header.GetPsmValue());
EXPECT_EQ(kPsmValue, ble_advertisement_header.GetPsm());
}
TEST(BleAdvertisementHeaderTest, ConstructionFailsWithBadVersion) {
@@ -165,7 +167,7 @@ TEST(BleAdvertisementHeaderTest, ConstructionFromSerializedStringWorks) {
ble_advertisement_header.GetServiceIdBloomFilter());
EXPECT_EQ(advertisement_hash,
ble_advertisement_header.GetAdvertisementHash());
EXPECT_EQ(kPsmValue, ble_advertisement_header.GetPsmValue());
EXPECT_EQ(kPsmValue, ble_advertisement_header.GetPsm());
}
TEST(BleAdvertisementHeaderTest, ConstructionFromExtraBytesWorks) {
@@ -192,7 +194,7 @@ TEST(BleAdvertisementHeaderTest, ConstructionFromExtraBytesWorks) {
long_ble_advertisement_header.GetServiceIdBloomFilter());
EXPECT_EQ(advertisement_hash,
long_ble_advertisement_header.GetAdvertisementHash());
EXPECT_EQ(kPsmValue, long_ble_advertisement_header.GetPsmValue());
EXPECT_EQ(kPsmValue, long_ble_advertisement_header.GetPsm());
}
TEST(BleAdvertisementHeaderTest, ConstructionFromShortLengthFails) {
@@ -15,6 +15,7 @@
#include "connections/implementation/mediums/ble_v2/ble_advertisement.h"
#include <algorithm>
#include <string>
#include "gtest/gtest.h"
#include "absl/hash/hash_testing.h"
@@ -220,10 +221,10 @@ TEST(BleAdvertisementTest, ConstructionFromSerializedBytesWorks) {
ByteArray data{std::string(kData)};
ByteArray device_token{std::string(kDeviceToken)};
BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion,
service_id_hash, data, device_token};
BleAdvertisement original_ble_advertisement{
kVersion, kSocketVersion, service_id_hash, data, device_token};
ByteArray ble_advertisement_bytes{org_ble_advertisement};
ByteArray ble_advertisement_bytes{original_ble_advertisement};
BleAdvertisement ble_advertisement{ble_advertisement_bytes};
EXPECT_TRUE(ble_advertisement.IsValid());
@@ -241,10 +242,10 @@ TEST(BleAdvertisementTest,
ByteArray fast_data{std::string(kFastData)};
ByteArray device_token{std::string(kDeviceToken)};
BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, ByteArray{},
fast_data, device_token};
BleAdvertisement original_ble_advertisement{
kVersion, kSocketVersion, ByteArray{}, fast_data, device_token};
ByteArray ble_advertisement_bytes{org_ble_advertisement};
ByteArray ble_advertisement_bytes{original_ble_advertisement};
BleAdvertisement ble_advertisement{ble_advertisement_bytes};
EXPECT_TRUE(ble_advertisement.IsValid());
@@ -260,9 +261,9 @@ TEST(BleAdvertisementTest, ConstructionFromSerializedBytesWithEmptyDataWorks) {
ByteArray service_id_hash{std::string(kServiceIDHashBytes)};
ByteArray device_token{std::string(kDeviceToken)};
BleAdvertisement org_ble_advertisement{
BleAdvertisement original_ble_advertisement{
kVersion, kSocketVersion, service_id_hash, ByteArray(), device_token};
ByteArray ble_advertisement_bytes{org_ble_advertisement};
ByteArray ble_advertisement_bytes{original_ble_advertisement};
BleAdvertisement ble_advertisement{ble_advertisement_bytes};
EXPECT_TRUE(ble_advertisement.IsValid());
@@ -278,9 +279,9 @@ TEST(BleAdvertisementTest,
ConstructionFromSerializedBytesWithEmptyDataWorksForFastAdvertisement) {
ByteArray device_token{std::string(kDeviceToken)};
BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, ByteArray{},
ByteArray(), device_token};
ByteArray ble_advertisement_bytes{org_ble_advertisement};
BleAdvertisement original_ble_advertisement{
kVersion, kSocketVersion, ByteArray{}, ByteArray(), device_token};
ByteArray ble_advertisement_bytes{original_ble_advertisement};
BleAdvertisement ble_advertisement{ble_advertisement_bytes};
EXPECT_TRUE(ble_advertisement.IsValid());
@@ -296,16 +297,16 @@ TEST(BleAdvertisementTest, ConstructionFromExtraSerializedBytesWorks) {
ByteArray data{std::string(kData)};
ByteArray device_token{std::string(kDeviceToken)};
BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion,
service_id_hash, data, device_token};
ByteArray org_ble_advertisement_bytes{org_ble_advertisement};
BleAdvertisement original_ble_advertisement{
kVersion, kSocketVersion, service_id_hash, data, device_token};
ByteArray original_ble_advertisement_bytes{original_ble_advertisement};
// Copy the bytes into a new array with extra bytes. We must explicitly
// define how long our array is because we can't use variable length arrays.
char raw_ble_advertisement_bytes[kLongAdvertisementLength]{};
memcpy(raw_ble_advertisement_bytes, org_ble_advertisement_bytes.data(),
memcpy(raw_ble_advertisement_bytes, original_ble_advertisement_bytes.data(),
std::min(sizeof(raw_ble_advertisement_bytes),
org_ble_advertisement_bytes.size()));
original_ble_advertisement_bytes.size()));
// Re-parse the Ble advertisement using our extra long advertisement bytes.
ByteArray long_ble_advertisement_bytes{raw_ble_advertisement_bytes,
@@ -327,16 +328,16 @@ TEST(BleAdvertisementTest,
ByteArray fast_data{std::string(kFastData)};
ByteArray device_token{std::string(kDeviceToken)};
BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, ByteArray{},
fast_data, device_token};
ByteArray org_ble_advertisement_bytes{org_ble_advertisement};
BleAdvertisement original_ble_advertisement{
kVersion, kSocketVersion, ByteArray{}, fast_data, device_token};
ByteArray original_ble_advertisement_bytes{original_ble_advertisement};
// Copy the bytes into a new array with extra bytes. We must explicitly
// define how long our array is because we can't use variable length arrays.
char raw_ble_advertisement_bytes[kLongAdvertisementLength]{};
memcpy(raw_ble_advertisement_bytes, org_ble_advertisement_bytes.data(),
memcpy(raw_ble_advertisement_bytes, original_ble_advertisement_bytes.data(),
std::min(sizeof(raw_ble_advertisement_bytes),
org_ble_advertisement_bytes.size()));
original_ble_advertisement_bytes.size()));
// Re-parse the Ble advertisement using our extra long advertisement bytes.
ByteArray long_ble_advertisement_bytes{raw_ble_advertisement_bytes,
@@ -363,13 +364,13 @@ TEST(BleAdvertisementTest, ConstructionFromShortLengthSerializedBytesFails) {
ByteArray data{std::string(kData)};
ByteArray device_token{std::string(kDeviceToken)};
BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion,
service_id_hash, data, device_token};
ByteArray org_ble_advertisement_bytes{org_ble_advertisement};
BleAdvertisement original_ble_advertisement{
kVersion, kSocketVersion, service_id_hash, data, device_token};
ByteArray original_ble_advertisement_bytes{original_ble_advertisement};
// Cut off the advertisement so that it's too short.
ByteArray short_ble_advertisement_bytes{org_ble_advertisement_bytes.data(),
7};
ByteArray short_ble_advertisement_bytes{
original_ble_advertisement_bytes.data(), 7};
BleAdvertisement short_ble_advertisement{short_ble_advertisement_bytes};
EXPECT_FALSE(short_ble_advertisement.IsValid());
@@ -380,13 +381,13 @@ TEST(BleAdvertisementTest,
ByteArray fast_data{std::string(kFastData)};
ByteArray device_token{std::string(kDeviceToken)};
BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, ByteArray{},
fast_data, device_token};
ByteArray org_ble_advertisement_bytes{org_ble_advertisement};
BleAdvertisement original_ble_advertisement{
kVersion, kSocketVersion, ByteArray{}, fast_data, device_token};
ByteArray original_ble_advertisement_bytes{original_ble_advertisement};
// Cut off the advertisement so that it's too short.
ByteArray short_ble_advertisement_bytes{org_ble_advertisement_bytes.data(),
2};
ByteArray short_ble_advertisement_bytes{
original_ble_advertisement_bytes.data(), 2};
BleAdvertisement short_ble_advertisement{short_ble_advertisement_bytes};
EXPECT_FALSE(short_ble_advertisement.IsValid());
@@ -398,15 +399,15 @@ TEST(BleAdvertisementTest,
ByteArray data{std::string(kData)};
ByteArray device_token{std::string(kDeviceToken)};
BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion,
service_id_hash, data, device_token};
ByteArray org_ble_advertisement_bytes{org_ble_advertisement};
BleAdvertisement original_ble_advertisement{
kVersion, kSocketVersion, service_id_hash, data, device_token};
ByteArray original_ble_advertisement_bytes{original_ble_advertisement};
// Corrupt the DATA_SIZE bits. Start by making a raw copy of the Ble
// advertisement bytes so we can modify it. We must explicitly define how
// long our array is because we can't use variable length arrays.
char raw_ble_advertisement_bytes[kAdvertisementLength];
memcpy(raw_ble_advertisement_bytes, org_ble_advertisement_bytes.data(),
memcpy(raw_ble_advertisement_bytes, original_ble_advertisement_bytes.data(),
kAdvertisementLength);
// The data size field lives in indices 4-7. Corrupt it.
@@ -426,15 +427,15 @@ TEST(BleAdvertisementTest,
ByteArray fast_data{std::string(kFastData)};
ByteArray device_token{std::string(kDeviceToken)};
BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, ByteArray{},
fast_data, device_token};
ByteArray org_ble_advertisement_bytes{org_ble_advertisement};
BleAdvertisement original_ble_advertisement{
kVersion, kSocketVersion, ByteArray{}, fast_data, device_token};
ByteArray original_ble_advertisement_bytes{original_ble_advertisement};
// Corrupt the DATA_SIZE bits. Start by making a raw copy of the Ble
// advertisement bytes so we can modify it. We must explicitly define how
// long our array is because we can't use variable length arrays.
char raw_ble_advertisement_bytes[kFastAdvertisementLength];
memcpy(raw_ble_advertisement_bytes, org_ble_advertisement_bytes.data(),
memcpy(raw_ble_advertisement_bytes, original_ble_advertisement_bytes.data(),
kFastAdvertisementLength);
// The data size field lives in index 1. Corrupt it.
@@ -449,6 +450,49 @@ TEST(BleAdvertisementTest,
EXPECT_FALSE(corrupted_ble_advertisement.IsValid());
}
TEST(BleAdvertisementTest, ConstructionWorksWithPsmValue) {
ByteArray service_id_hash{std::string(kServiceIDHashBytes)};
ByteArray data{std::string(kData)};
ByteArray device_token{std::string(kDeviceToken)};
int psm = 127;
BleAdvertisement ble_advertisement(kVersion, kSocketVersion, service_id_hash,
data, device_token, psm);
ASSERT_TRUE(ble_advertisement.IsValid());
EXPECT_FALSE(ble_advertisement.IsFastAdvertisement());
EXPECT_EQ(kVersion, ble_advertisement.GetVersion());
EXPECT_EQ(kSocketVersion, ble_advertisement.GetSocketVersion());
EXPECT_EQ(service_id_hash, ble_advertisement.GetServiceIdHash());
EXPECT_EQ(data.size(), ble_advertisement.GetData().size());
EXPECT_EQ(data, ble_advertisement.GetData());
EXPECT_EQ(device_token, ble_advertisement.GetDeviceToken());
EXPECT_EQ(psm, ble_advertisement.GetPsm());
}
TEST(BleAdvertisementTest, ConstructionFromSerializedBytesWithPsmValueWorks) {
ByteArray service_id_hash{std::string(kServiceIDHashBytes)};
ByteArray data{std::string(kData)};
ByteArray device_token{std::string(kDeviceToken)};
int psm = 127;
BleAdvertisement original_ble_advertisement(
kVersion, kSocketVersion, service_id_hash, data, device_token, psm);
ByteArray ble_advertisement_bytes =
original_ble_advertisement.ByteArrayWithExtraField();
BleAdvertisement ble_advertisement(ble_advertisement_bytes);
ASSERT_TRUE(ble_advertisement.IsValid());
EXPECT_FALSE(ble_advertisement.IsFastAdvertisement());
EXPECT_EQ(kVersion, ble_advertisement.GetVersion());
EXPECT_EQ(kSocketVersion, ble_advertisement.GetSocketVersion());
EXPECT_EQ(service_id_hash, ble_advertisement.GetServiceIdHash());
EXPECT_EQ(data.size(), ble_advertisement.GetData().size());
EXPECT_EQ(data, ble_advertisement.GetData());
EXPECT_EQ(device_token, ble_advertisement.GetDeviceToken());
EXPECT_EQ(psm, ble_advertisement.GetPsm());
}
TEST(BleAdvertisementTest, Hash) {
EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
BleAdvertisement(),
@@ -15,6 +15,7 @@
#ifndef CORE_INTERNAL_MEDIUMS_BLE_V2_BLE_PERIPHERAL_H_
#define CORE_INTERNAL_MEDIUMS_BLE_V2_BLE_PERIPHERAL_H_
#include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h"
#include "internal/platform/byte_array.h"
namespace location {
@@ -30,7 +31,8 @@ namespace mediums {
class BlePeripheral {
public:
BlePeripheral() = default;
explicit BlePeripheral(const ByteArray& id) : BlePeripheral(id, 0) {}
explicit BlePeripheral(const ByteArray& id)
: BlePeripheral(id, BleAdvertisementHeader::kDefaultPsmValue) {}
BlePeripheral(const ByteArray& id, int psm) : id_(id), psm_(psm) {}
BlePeripheral(const BlePeripheral&) = default;
BlePeripheral& operator=(const BlePeripheral&) = default;
@@ -53,8 +53,9 @@ ByteArray GenerateDeviceToken() {
}
ByteArray GenerateAdvertisementHash(const ByteArray& advertisement_bytes) {
return Utils::Sha256Hash(advertisement_bytes,
BleAdvertisementHeader::kAdvertisementHashLength);
return Utils::Sha256Hash(
advertisement_bytes,
BleAdvertisementHeader::kAdvertisementHashByteLength);
}
std::string GenerateAdvertisementUuid(int slot) {