[BLE Refactor] BleAdvertisementHeader by adding psm value and extended advertisement flag to align with Android's counterpart.

PiperOrigin-RevId: 421797950
This commit is contained in:
edwinwu
2022-01-14 05:08:02 -08:00
committed by Copybara-Service
parent 5e845655bb
commit cf937ed90f
9 changed files with 97 additions and 85 deletions
-5
View File
@@ -17,7 +17,6 @@ cc_library(
name = "mediums",
srcs = [
"ble.cc",
"bloom_filter.cc",
"bluetooth_classic.cc",
"bluetooth_radio.cc",
"mediums.cc",
@@ -27,7 +26,6 @@ cc_library(
],
hdrs = [
"ble.h",
"bloom_filter.h",
"bluetooth_classic.h",
"bluetooth_radio.h",
"lost_entity_tracker.h",
@@ -45,7 +43,6 @@ cc_library(
"//absl/container:flat_hash_map",
"//absl/container:flat_hash_set",
"//absl/functional:bind_front",
"//absl/numeric:int128",
"//absl/strings",
"//absl/strings:str_format",
"//absl/time",
@@ -60,7 +57,6 @@ cc_library(
"//platform/public:logging",
"//platform/public:types",
"//proto/mediums:web_rtc_signaling_frames_cc_proto",
"//smhasher:libmurmur3",
"//webrtc/api:libjingle_peerconnection_api",
],
)
@@ -96,7 +92,6 @@ cc_test(
size = "small",
srcs = [
"ble_test.cc",
"bloom_filter_test.cc",
"bluetooth_classic_test.cc",
"bluetooth_radio_test.cc",
"lost_entity_tracker_test.cc",
-5
View File
@@ -17,7 +17,6 @@ cc_library(
name = "mediums",
srcs = [
"ble.cc",
"bloom_filter.cc",
"bluetooth_classic.cc",
"bluetooth_radio.cc",
"mediums.cc",
@@ -27,7 +26,6 @@ cc_library(
],
hdrs = [
"ble.h",
"bloom_filter.h",
"bluetooth_classic.h",
"bluetooth_radio.h",
"lost_entity_tracker.h",
@@ -46,7 +44,6 @@ cc_library(
"//third_party/absl/container:flat_hash_map",
"//third_party/absl/container:flat_hash_set",
"//third_party/absl/functional:bind_front",
"//third_party/absl/numeric:int128",
"//third_party/absl/strings",
"//third_party/absl/strings:str_format",
"//third_party/absl/time",
@@ -59,7 +56,6 @@ cc_library(
"//third_party/nearby/cpp/platform/public:logging",
"//third_party/nearby/cpp/platform/public:types",
"//third_party/nearby/proto/mediums:web_rtc_signaling_frames_cc_proto",
"//third_party/smhasher:libmurmur3",
],
)
@@ -93,7 +89,6 @@ cc_test(
size = "small",
srcs = [
"ble_test.cc",
"bloom_filter_test.cc",
"bluetooth_classic_test.cc",
"bluetooth_radio_test.cc",
"lost_entity_tracker_test.cc",
+5
View File
@@ -20,6 +20,7 @@ cc_library(
"ble_advertisement.cc",
"ble_advertisement_header.cc",
"ble_packet.cc",
"bloom_filter.cc",
],
hdrs = [
"advertisement_read_result.h",
@@ -27,6 +28,7 @@ cc_library(
"ble_advertisement_header.h",
"ble_packet.h",
"ble_peripheral.h",
"bloom_filter.h",
"discovered_peripheral_callback.h",
],
compatible_with = ["//buildenv/target:non_prod"],
@@ -37,6 +39,7 @@ cc_library(
deps = [
"//absl/container:flat_hash_map",
"//absl/container:flat_hash_set",
"//absl/numeric:int128",
"//absl/strings",
"//absl/time",
"//core:core_types",
@@ -44,6 +47,7 @@ cc_library(
"//platform/base:util",
"//platform/public:logging",
"//platform/public:types",
"//smhasher:libmurmur3",
],
)
@@ -55,6 +59,7 @@ cc_test(
"ble_advertisement_test.cc",
"ble_packet_test.cc",
"ble_peripheral_test.cc",
"bloom_filter_test.cc",
],
deps = [
":ble_v2",
@@ -27,8 +27,9 @@ namespace connections {
namespace mediums {
BleAdvertisementHeader::BleAdvertisementHeader(
Version version, int num_slots, const ByteArray &service_id_bloom_filter,
const ByteArray &advertisement_hash) {
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) {
@@ -36,16 +37,15 @@ BleAdvertisementHeader::BleAdvertisementHeader(
}
version_ = version;
extended_advertisement_ = extended_advertisement;
num_slots_ = num_slots;
service_id_bloom_filter_ = service_id_bloom_filter;
advertisement_hash_ = advertisement_hash;
psm_ = psm;
}
BleAdvertisementHeader::BleAdvertisementHeader(
const std::string &ble_advertisement_header_string) {
ByteArray ble_advertisement_header_bytes =
Base64Utils::Decode(ble_advertisement_header_string);
const ByteArray &ble_advertisement_header_bytes) {
if (ble_advertisement_header_bytes.Empty()) {
NEARBY_LOG(
ERROR,
@@ -62,12 +62,14 @@ BleAdvertisementHeader::BleAdvertisementHeader(
return;
}
BaseInputStream base_input_stream{ble_advertisement_header_bytes};
ByteArray advertisement_header_bytes{ble_advertisement_header_bytes};
BaseInputStream base_input_stream{advertisement_header_bytes};
// The first 1 byte is supposed to be the version and number of slots.
auto version_and_pcp_byte = static_cast<char>(base_input_stream.ReadUint8());
auto version_and_num_slots_byte =
static_cast<char>(base_input_stream.ReadUint8());
// The upper 3 bits are supposed to be the version.
version_ =
static_cast<Version>((version_and_pcp_byte & kVersionBitmask) >> 5);
static_cast<Version>((version_and_num_slots_byte & kVersionBitmask) >> 5);
if (version_ != Version::kV2) {
NEARBY_LOG(
ERROR,
@@ -75,8 +77,11 @@ BleAdvertisementHeader::BleAdvertisementHeader(
version_);
return;
}
// The lower 5 bits are supposed to be the number of slots.
num_slots_ = static_cast<int>(version_and_pcp_byte & kNumSlotsBitmask);
// The next 1 bit is supposed to be the extended advertisement flag.
extended_advertisement_ =
((version_and_num_slots_byte & kExtendedAdvertismentBitMask) >> 4) == 1;
// The lower 4 bits are supposed to be the number of slots.
num_slots_ = static_cast<int>(version_and_num_slots_byte & kNumSlotsBitmask);
if (num_slots_ <= 0) {
version_ = Version::kUndefined;
return;
@@ -88,41 +93,43 @@ BleAdvertisementHeader::BleAdvertisementHeader(
// The next 4 bytes are supposed to be the advertisement_hash.
advertisement_hash_ = base_input_stream.ReadBytes(kAdvertisementHashLength);
// The next 2 bytes are PSM value.
if (base_input_stream.IsAvailable(sizeof(std::uint16_t))) {
psm_ = static_cast<int>(base_input_stream.ReadUint16());
}
}
BleAdvertisementHeader::operator std::string() const {
BleAdvertisementHeader::operator ByteArray() const {
if (!IsValid()) {
return "";
return ByteArray();
}
// The first 3 bits are the Version.
char version_and_num_slots_byte =
(static_cast<char>(version_) << 5) & kVersionBitmask;
// The next 1 bit is extended advertisement flag.
version_and_num_slots_byte |=
(static_cast<char>(extended_advertisement_) << 4) &
kExtendedAdvertismentBitMask;
// The next 5 bits are the number of slots.
version_and_num_slots_byte |=
static_cast<char>(num_slots_) & kNumSlotsBitmask;
// Convert psm_ value to 2-bytes.
ByteArray psm_byte{sizeof(std::uint16_t)};
char *data = psm_byte.data();
data[0] = psm_ & 0xFF00;
data[1] = psm_ & 0x00FF;
// clang-format off
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(advertisement_hash_),
std::string(psm_byte));
// clang-format on
return Base64Utils::Encode(ByteArray(std::move(out)));
}
bool BleAdvertisementHeader::operator<(
const BleAdvertisementHeader &rhs) const {
if (this->GetVersion() != rhs.GetVersion()) {
return this->GetVersion() < rhs.GetVersion();
}
if (this->GetNumSlots() != rhs.GetNumSlots()) {
return this->GetNumSlots() < rhs.GetNumSlots();
}
if (this->GetServiceIdBloomFilter() != rhs.GetServiceIdBloomFilter()) {
return this->GetServiceIdBloomFilter() < rhs.GetServiceIdBloomFilter();
}
return this->GetAdvertisementHash() < rhs.GetAdvertisementHash();
return ByteArray(std::move(out));
}
} // namespace mediums
@@ -27,7 +27,7 @@ namespace mediums {
// Represents the format of the Mediums BLE Advertisement Header used in
// Advertising + Discovery.
//
// [VERSION][NUM_SLOTS][SERVICE_ID_BLOOM_FILTER][ADVERTISEMENT_HASH]
// [VERSION][NUM_SLOTS][SERVICE_ID_BLOOM_FILTER][ADVERTISEMENT_HASH][L2_CAP_PSM]
//
// See go/nearby-ble-design for more information.
//
@@ -52,41 +52,45 @@ class BleAdvertisementHeader {
};
BleAdvertisementHeader() = default;
BleAdvertisementHeader(Version version, int num_slots,
BleAdvertisementHeader(Version version, bool extended_advertisement,
int num_slots,
const ByteArray &service_id_bloom_filter,
const ByteArray &advertisement_hash);
const ByteArray &advertisement_hash, int psm);
explicit BleAdvertisementHeader(
const std::string &ble_advertisement_header_string);
const ByteArray &ble_advertisement_header_bytes);
BleAdvertisementHeader(const BleAdvertisementHeader &) = default;
BleAdvertisementHeader &operator=(const BleAdvertisementHeader &) = default;
BleAdvertisementHeader(BleAdvertisementHeader &&) = default;
BleAdvertisementHeader &operator=(BleAdvertisementHeader &&) = default;
~BleAdvertisementHeader() = default;
// Produces an encoded binary string which can be decoded by the explicit
// constructor. The returned string is empty if BleAdvertisementHeader is not
// valid - false on IsValid().
explicit operator std::string() const;
bool operator<(const BleAdvertisementHeader &rhs) const;
explicit operator ByteArray() const;
bool IsValid() const { return version_ == Version::kV2; }
Version GetVersion() const { return version_; }
bool IsExtendedAdvertisement() const { return extended_advertisement_; }
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_; }
private:
static constexpr int kVersionAndNumSlotsLength = 1;
static constexpr int kServiceIdBloomFilterLength = 10;
static constexpr int kAdvertisementHashLength = 4;
static constexpr int kMinAdvertisementHeaderLength =
1 + kServiceIdBloomFilterLength + kAdvertisementHashLength;
kVersionAndNumSlotsLength + kServiceIdBloomFilterLength +
kAdvertisementHashLength;
static constexpr int kVersionBitmask = 0x0E0;
static constexpr int kNumSlotsBitmask = 0x01F;
static constexpr int kExtendedAdvertismentBitMask = 0x010;
static constexpr int kNumSlotsBitmask = 0x00F;
Version version_ = Version::kUndefined;
int num_slots_;
bool extended_advertisement_ = false;
int num_slots_ = 0;
ByteArray service_id_bloom_filter_;
ByteArray advertisement_hash_;
int psm_ = 0;
};
} // namespace mediums
@@ -26,6 +26,7 @@ namespace {
constexpr BleAdvertisementHeader::Version kVersion =
BleAdvertisementHeader::Version::kV2;
constexpr int kNumSlots = 2;
constexpr std::int16_t kPsmValue = 1;
constexpr absl::string_view kServiceIDBloomFilter{
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a"};
constexpr absl::string_view kAdvertisementHash{"\x0a\x0b\x0c\x0d"};
@@ -35,15 +36,18 @@ TEST(BleAdvertisementHeaderTest, ConstructionWorks) {
ByteArray advertisement_hash{std::string(kAdvertisementHash)};
BleAdvertisementHeader ble_advertisement_header{
kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash};
kVersion, false, kNumSlots, service_id_bloom_filter,
advertisement_hash, kPsmValue};
EXPECT_TRUE(ble_advertisement_header.IsValid());
EXPECT_EQ(kVersion, ble_advertisement_header.GetVersion());
EXPECT_FALSE(ble_advertisement_header.IsExtendedAdvertisement());
EXPECT_EQ(kNumSlots, ble_advertisement_header.GetNumSlots());
EXPECT_EQ(service_id_bloom_filter,
ble_advertisement_header.GetServiceIdBloomFilter());
EXPECT_EQ(advertisement_hash,
ble_advertisement_header.GetAdvertisementHash());
EXPECT_EQ(kPsmValue, ble_advertisement_header.GetPsmValue());
}
TEST(BleAdvertisementHeaderTest, ConstructionFailsWithBadVersion) {
@@ -53,7 +57,8 @@ TEST(BleAdvertisementHeaderTest, ConstructionFailsWithBadVersion) {
ByteArray advertisement_hash{std::string(kAdvertisementHash)};
BleAdvertisementHeader ble_advertisement_header{
bad_version, kNumSlots, service_id_bloom_filter, advertisement_hash};
bad_version, false, kNumSlots, service_id_bloom_filter,
advertisement_hash, kPsmValue};
EXPECT_FALSE(ble_advertisement_header.IsValid());
}
@@ -65,7 +70,8 @@ TEST(BleAdvertisementHeaderTest, ConstructionFailsWitZeroNumSlot) {
ByteArray advertisement_hash{std::string(kAdvertisementHash)};
BleAdvertisementHeader ble_advertisement_header{
kVersion, num_slot, service_id_bloom_filter, advertisement_hash};
kVersion, false, num_slot, service_id_bloom_filter,
advertisement_hash, kPsmValue};
EXPECT_FALSE(ble_advertisement_header.IsValid());
}
@@ -78,8 +84,9 @@ TEST(BleAdvertisementHeaderTest,
ByteArray advertisement_hash{std::string(kAdvertisementHash)};
BleAdvertisementHeader ble_advertisement_header{
kVersion, kNumSlots, short_service_id_bloom_filter_bytes,
advertisement_hash};
kVersion, false,
kNumSlots, short_service_id_bloom_filter_bytes,
advertisement_hash, kPsmValue};
EXPECT_FALSE(ble_advertisement_header.IsValid());
}
@@ -93,7 +100,8 @@ TEST(BleAdvertisementHeaderTest,
ByteArray advertisement_hash{std::string(kAdvertisementHash)};
BleAdvertisementHeader ble_advertisement_header{
kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash};
kVersion, false, kNumSlots, service_id_bloom_filter,
advertisement_hash, kPsmValue};
EXPECT_FALSE(ble_advertisement_header.IsValid());
}
@@ -105,7 +113,8 @@ TEST(BleAdvertisementHeaderTest, ConstructionFailsWithShortAdvertisementHash) {
ByteArray advertisement_hash{short_advertisement_hash};
BleAdvertisementHeader ble_advertisement_header{
kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash};
kVersion, false, kNumSlots, service_id_bloom_filter,
advertisement_hash, kPsmValue};
EXPECT_FALSE(ble_advertisement_header.IsValid());
}
@@ -116,7 +125,8 @@ TEST(BleAdvertisementHeaderTest, ConstructionFailsWithLongAdvertisementHash) {
ByteArray service_id_bloom_filter{std::string(kServiceIDBloomFilter)};
ByteArray advertisement_hash{long_advertisement_hash};
BleAdvertisementHeader ble_advertisement_header{
kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash};
kVersion, false, kNumSlots, service_id_bloom_filter,
advertisement_hash, kPsmValue};
EXPECT_FALSE(ble_advertisement_header.IsValid());
}
@@ -126,20 +136,22 @@ TEST(BleAdvertisementHeaderTest, ConstructionFromSerializedStringWorks) {
ByteArray advertisement_hash{std::string(kAdvertisementHash)};
BleAdvertisementHeader org_ble_advertisement_header{
kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash};
auto ble_advertisement_header_string =
std::string(org_ble_advertisement_header);
kVersion, false, kNumSlots, service_id_bloom_filter,
advertisement_hash, kPsmValue};
auto ble_advertisement_header_bytes = ByteArray(org_ble_advertisement_header);
BleAdvertisementHeader ble_advertisement_header{
ble_advertisement_header_string};
ble_advertisement_header_bytes};
EXPECT_TRUE(ble_advertisement_header.IsValid());
EXPECT_EQ(kVersion, ble_advertisement_header.GetVersion());
EXPECT_FALSE(ble_advertisement_header.IsExtendedAdvertisement());
EXPECT_EQ(kNumSlots, ble_advertisement_header.GetNumSlots());
EXPECT_EQ(service_id_bloom_filter,
ble_advertisement_header.GetServiceIdBloomFilter());
EXPECT_EQ(advertisement_hash,
ble_advertisement_header.GetAdvertisementHash());
EXPECT_EQ(kPsmValue, ble_advertisement_header.GetPsmValue());
}
TEST(BleAdvertisementHeaderTest, ConstructionFromExtraBytesWorks) {
@@ -147,28 +159,26 @@ TEST(BleAdvertisementHeaderTest, ConstructionFromExtraBytesWorks) {
ByteArray advertisement_hash{std::string(kAdvertisementHash)};
BleAdvertisementHeader ble_advertisement_header{
kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash};
auto ble_advertisement_header_string = std::string(ble_advertisement_header);
kVersion, false, kNumSlots, service_id_bloom_filter,
advertisement_hash, kPsmValue};
auto ble_advertisement_header_bytes = ByteArray(ble_advertisement_header);
// Base64 decode the string, add a character, and then re-encode it.
ByteArray ble_advertisement_header_bytes =
Base64Utils::Decode(ble_advertisement_header_string);
ByteArray long_ble_advertisement_header_bytes{
ble_advertisement_header_bytes.size() + 1};
long_ble_advertisement_header_bytes.CopyAt(0, ble_advertisement_header_bytes);
std::string long_ble_advertisement_header_string{
Base64Utils::Encode(long_ble_advertisement_header_bytes)};
BleAdvertisementHeader long_ble_advertisement_header{
long_ble_advertisement_header_string};
long_ble_advertisement_header_bytes};
EXPECT_TRUE(long_ble_advertisement_header.IsValid());
EXPECT_EQ(kVersion, long_ble_advertisement_header.GetVersion());
EXPECT_FALSE(ble_advertisement_header.IsExtendedAdvertisement());
EXPECT_EQ(kNumSlots, long_ble_advertisement_header.GetNumSlots());
EXPECT_EQ(service_id_bloom_filter,
long_ble_advertisement_header.GetServiceIdBloomFilter());
EXPECT_EQ(advertisement_hash,
long_ble_advertisement_header.GetAdvertisementHash());
EXPECT_EQ(kPsmValue, long_ble_advertisement_header.GetPsmValue());
}
TEST(BleAdvertisementHeaderTest, ConstructionFromShortLengthFails) {
@@ -176,21 +186,17 @@ TEST(BleAdvertisementHeaderTest, ConstructionFromShortLengthFails) {
ByteArray advertisement_hash{std::string(kAdvertisementHash)};
BleAdvertisementHeader ble_advertisement_header{
kVersion, kNumSlots, service_id_bloom_filter, advertisement_hash};
auto ble_advertisement_header_string = std::string(ble_advertisement_header);
kVersion, false, kNumSlots, service_id_bloom_filter,
advertisement_hash, kPsmValue};
auto ble_advertisement_header_bytes = ByteArray(ble_advertisement_header);
// Base64 decode the string, remove a character, and then re-encode it.
ByteArray ble_advertisement_header_bytes =
Base64Utils::Decode(ble_advertisement_header_string);
ByteArray short_ble_advertisement_header_bytes{
ble_advertisement_header_bytes.size() - 1};
ble_advertisement_header_bytes.size() - 3};
short_ble_advertisement_header_bytes.CopyAt(0,
ble_advertisement_header_bytes);
std::string short_ble_advertisement_header_string{
Base64Utils::Encode(short_ble_advertisement_header_bytes)};
BleAdvertisementHeader short_ble_advertisement_header{
short_ble_advertisement_header_string};
short_ble_advertisement_header_bytes};
EXPECT_FALSE(short_ble_advertisement_header.IsValid());
}
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "core/internal/mediums/bloom_filter.h"
#include "core/internal/mediums/ble_v2/bloom_filter.h"
#include "absl/numeric/int128.h"
#include "absl/strings/numbers.h"
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CORE_INTERNAL_MEDIUMS_BLOOM_FILTER_H_
#define CORE_INTERNAL_MEDIUMS_BLOOM_FILTER_H_
#ifndef CORE_INTERNAL_MEDIUMS_BLE_V2_BLOOM_FILTER_H_
#define CORE_INTERNAL_MEDIUMS_BLE_V2_BLOOM_FILTER_H_
#include <bitset>
#include <vector>
@@ -98,4 +98,4 @@ class BloomFilter final : public BloomFilterBase {
} // namespace nearby
} // namespace location
#endif // CORE_INTERNAL_MEDIUMS_BLOOM_FILTER_H_
#endif // CORE_INTERNAL_MEDIUMS_BLE_V2_BLOOM_FILTER_H_
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "core/internal/mediums/bloom_filter.h"
#include "core/internal/mediums/ble_v2/bloom_filter.h"
#include <algorithm>