[BLE Refactor] Uses Uuid class for those used in Uuid string-form in /medium layer.

PiperOrigin-RevId: 450910238
This commit is contained in:
edwinwu
2022-05-25 06:36:55 -07:00
committed by Copybara-Service
parent cb8fef7875
commit 8e048f7be0
32 changed files with 546 additions and 396 deletions
+1 -1
View File
@@ -435,7 +435,6 @@ let package = Package(
"connections/implementation/mediums/ble_test.cc",
"connections/implementation/mediums/webrtc_test.cc",
"connections/implementation/mediums/lost_entity_tracker_test.cc",
"connections/implementation/mediums/uuid_test.cc",
"connections/implementation/mediums/bluetooth_radio_test.cc",
"connections/implementation/mediums/wifi_hotspot_test.cc",
"connections/implementation/endpoint_channel_manager_test.cc",
@@ -460,6 +459,7 @@ let package = Package(
"internal/platform/scheduled_executor_test.cc",
"internal/platform/count_down_latch_test.cc",
"internal/platform/pipe_test.cc",
"internal/platform/uuid_test.cc",
"internal/platform/wifi_hotspot_test.cc",
"internal/platform/wifi_lan_test.cc",
"internal/platform/condition_variable_test.cc",
+2 -3
View File
@@ -49,6 +49,7 @@ cc_library(
"//internal/platform:comm",
"//internal/platform:logging",
"//internal/platform:types",
"//internal/platform:uuid",
"//proto/mediums:web_rtc_signaling_frames_cc_proto",
"@com_google_absl//absl/container:btree",
"@com_google_absl//absl/container:flat_hash_map",
@@ -57,6 +58,7 @@ cc_library(
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:optional",
],
)
@@ -64,13 +66,11 @@ cc_library(
name = "utils",
srcs = [
"utils.cc",
"uuid.cc",
"webrtc_peer_id.cc",
],
hdrs = [
"lost_entity_tracker.h",
"utils.h",
"uuid.h",
"webrtc_peer_id.h",
"webrtc_socket_stub.h",
],
@@ -99,7 +99,6 @@ cc_test(
"bluetooth_classic_test.cc",
"bluetooth_radio_test.cc",
"lost_entity_tracker_test.cc",
"uuid_test.cc",
"wifi_hotspot_test.cc",
"wifi_lan_test.cc",
],
+26 -16
View File
@@ -19,6 +19,7 @@
#include <utility>
#include "absl/strings/escaping.h"
#include "absl/types/optional.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h"
#include "connections/implementation/mediums/ble_v2/ble_utils.h"
@@ -177,7 +178,8 @@ bool BleV2::StopAdvertising(const std::string& service_id) {
for (const auto& characteristic : hosted_gatt_characteristics_) {
if (!gatt_server_->UpdateCharacteristic(characteristic, empty_value)) {
NEARBY_LOGS(ERROR)
<< "Failed to clear characteristic uuid=" << characteristic.uuid
<< "Failed to clear characteristic uuid="
<< std::string(characteristic.uuid)
<< " after stopping BLE advertisement for service_id="
<< service_id;
}
@@ -243,7 +245,7 @@ bool BleV2::StartScanning(const std::string& service_id, PowerLevel power_level,
// Start to track the advertisement found for specific `service_id`.
discovered_peripheral_tracker_.StartTracking(
service_id, std::move(callback),
std::string(mediums::bleutils::kCopresenceServiceUuid));
mediums::bleutils::kCopresenceServiceUuid);
// Check if scan has been activated, if yes, no need to notify client
// to scan again.
@@ -258,7 +260,7 @@ bool BleV2::StartScanning(const std::string& service_id, PowerLevel power_level,
// TODO(b/213835576): We should re-start scanning once the power level is
// changed.
if (!medium_.StartScanning(
std::string(mediums::bleutils::kCopresenceServiceUuid),
mediums::bleutils::kCopresenceServiceUuid,
PowerLevelToTxPowerLevel(power_level),
{
.advertisement_found_cb =
@@ -545,12 +547,18 @@ bool BleV2::GenerateAdvertisementCharacteristic(
std::vector<GattCharacteristic::Property> properties{
GattCharacteristic::Property::kRead};
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<Uuid> advertiement_uuid =
mediums::bleutils::GenerateAdvertisementUuid(slot);
if (!advertiement_uuid.has_value()) {
NEARBY_LOGS(INFO) << "Unable to generate advertisement uuid.";
return false;
}
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<GattCharacteristic> gatt_characteristic =
gatt_server.CreateCharacteristic(
std::string(mediums::bleutils::kCopresenceServiceUuid),
mediums::bleutils::GenerateAdvertisementUuid(slot), permissions,
properties);
mediums::bleutils::kCopresenceServiceUuid, *advertiement_uuid,
permissions, properties);
if (!gatt_characteristic.has_value()) {
NEARBY_LOGS(INFO) << "Unable to create and add a characterstic to the gatt "
"server for the advertisement.";
@@ -600,9 +608,8 @@ void BleV2::ProcessFetchGattAdvertisementsRequest(
}
// Always use kCopresenceServiceUuid for service uuid.
std::string service_uuid =
std::string(mediums::bleutils::kCopresenceServiceUuid);
if (!gatt_client->DiscoverService(service_uuid)) {
if (!gatt_client->DiscoverService(
mediums::bleutils::kCopresenceServiceUuid)) {
NEARBY_LOGS(WARNING) << "GATT client can't discover service.";
advertisement_read_result.RecordLastReadStatus(false);
return;
@@ -619,9 +626,14 @@ void BleV2::ProcessFetchGattAdvertisementsRequest(
// the characteristic doesn't exist, we shouldn't count the fetch as a
// failure because there's nothing we could've done about a
// non-existed characteristic.
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<Uuid> advertiement_uuid =
mediums::bleutils::GenerateAdvertisementUuid(slot);
if (!advertiement_uuid.has_value()) {
continue;
}
auto gatt_characteristic = gatt_client->GetCharacteristic(
std::string(mediums::bleutils::kCopresenceServiceUuid),
mediums::bleutils::GenerateAdvertisementUuid(slot));
mediums::bleutils::kCopresenceServiceUuid, *advertiement_uuid);
if (!gatt_characteristic.has_value()) {
continue;
}
@@ -718,8 +730,7 @@ bool BleV2::StartFastAdvertisingLocked(
ByteArray medium_advertisement_bytes = ByteArray(medium_advertisement);
advertising_data.is_extended_advertisement = false;
advertising_data.service_data.insert(
{std::string(mediums::bleutils::kCopresenceServiceUuid),
medium_advertisement_bytes});
{mediums::bleutils::kCopresenceServiceUuid, medium_advertisement_bytes});
// Finally, start the fast advertising operation.
if (!medium_.StartAdvertising(
@@ -750,7 +761,7 @@ bool BleV2::StartRegularAdvertisingLocked(
if (medium_.IsExtendedAdvertisementsAvailable()) {
advertising_data.is_extended_advertisement = true;
advertising_data.service_data.insert(
{std::string(mediums::bleutils::kCopresenceServiceUuid),
{mediums::bleutils::kCopresenceServiceUuid,
medium_advertisement_bytes});
// Start the extended regular advertising operation.
@@ -830,8 +841,7 @@ bool BleV2::StartGattAdvertisingLocked(
}
advertising_data.service_data.insert(
{std::string(mediums::bleutils::kCopresenceServiceUuid),
advertisement_header_bytes});
{mediums::bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
// Finally, start the regular advertising operation.
if (!medium_.StartAdvertising(
@@ -24,6 +24,7 @@
#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/types/optional.h"
#include "connections/implementation/mediums/ble_v2/advertisement_read_result.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement.h"
#include "connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h"
@@ -46,6 +46,7 @@ cc_library(
"//internal/platform:logging",
"//internal/platform:types",
"//internal/platform:util",
"//internal/platform:uuid",
"@aappleby_smhasher//:libmurmur3",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
@@ -53,6 +54,7 @@ cc_library(
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:optional",
],
)
@@ -16,6 +16,8 @@
#include <string>
#include "absl/types/optional.h"
namespace location {
namespace nearby {
namespace connections {
@@ -34,6 +36,11 @@ namespace {
constexpr std::int64_t kAdvertisementUuidMsb = 0x0000000000003000;
constexpr std::int64_t kAdvertisementUuidLsb = 0x8000000000000000;
// The most significant bits and the least significant bits for the Copresence
// UUID.
const std::uint64_t kCopresenceServiceUuidMsb = 0x0000FEF300001000;
const std::uint64_t kCopresenceServiceUuidLsb = 0x800000805F9B34FB;
// Creates a string as a space separated listing of hex bytes with [] at the
// beginning and the end.
//
@@ -50,8 +57,8 @@ std::string StringToPrintableHexString(const std::string& source) {
} // namespace
const absl::string_view kCopresenceServiceUuid =
"0000FEF3-0000-1000-8000-00805F9B34FB";
const Uuid kCopresenceServiceUuid(kCopresenceServiceUuidMsb,
kCopresenceServiceUuidLsb);
ByteArray GenerateHash(const std::string& source, size_t size) {
return Utils::Sha256Hash(source, size);
@@ -85,11 +92,12 @@ ByteArray GenerateAdvertisementHash(const ByteArray& advertisement_bytes) {
BleAdvertisementHeader::kAdvertisementHashByteLength);
}
std::string GenerateAdvertisementUuid(int slot) {
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<Uuid> GenerateAdvertisementUuid(int slot) {
if (slot < 0) {
return {};
return absl::nullopt; // NOLINT
}
return std::string(Uuid(kAdvertisementUuidMsb, kAdvertisementUuidLsb | slot));
return Uuid(kAdvertisementUuidMsb, kAdvertisementUuidLsb | slot);
}
} // namespace bleutils
@@ -18,12 +18,13 @@
#include <string>
#include "absl/strings/str_format.h"
#include "absl/types/optional.h"
#include "connections/implementation/mediums/ble_v2//ble_advertisement.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h"
#include "connections/implementation/mediums/ble_v2/ble_packet.h"
#include "connections/implementation/mediums/utils.h"
#include "connections/implementation/mediums/uuid.h"
#include "internal/platform/prng.h"
#include "internal/platform/uuid.h"
namespace location {
namespace nearby {
@@ -31,7 +32,7 @@ namespace connections {
namespace mediums {
namespace bleutils {
ABSL_CONST_INIT extern const absl::string_view kCopresenceServiceUuid;
ABSL_CONST_INIT extern const Uuid kCopresenceServiceUuid;
// Return SHA256 hash.
//
@@ -61,7 +62,8 @@ ByteArray GenerateAdvertisementHash(const ByteArray& advertisement_bytes);
// Generates a BLE characteristic UUID for an advertisement at the given slot.
//
// slot - the advertisement slot to generate a UUID for.
std::string GenerateAdvertisementUuid(int slot);
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<Uuid> GenerateAdvertisementUuid(int slot);
} // namespace bleutils
} // namespace mediums
@@ -16,6 +16,8 @@
#include <string>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
namespace location {
@@ -26,6 +28,8 @@ namespace bleutils {
namespace {
using ::testing::StrCaseEq;
TEST(BleUtilsTest, CanGenerateHash) {
std::string service_id = {"service_id"};
@@ -71,22 +75,25 @@ TEST(BleUtilsTest, CanGenerateAdvertisementHash) {
}
TEST(BleUtilsTest, CanGenerateAdvertisementUuid) {
std::string generated_string = GenerateAdvertisementUuid(0);
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<Uuid> generated_uuid = GenerateAdvertisementUuid(0);
ASSERT_TRUE(generated_uuid.has_value());
EXPECT_THAT(std::string(*generated_uuid),
StrCaseEq("00000000-0000-3000-8000-000000000000"));
EXPECT_EQ("00000000-0000-3000-8000-000000000000", generated_string);
generated_uuid = GenerateAdvertisementUuid(1);
ASSERT_TRUE(generated_uuid.has_value());
EXPECT_THAT(std::string(*generated_uuid),
StrCaseEq("00000000-0000-3000-8000-000000000001"));
generated_string = GenerateAdvertisementUuid(1);
generated_uuid = GenerateAdvertisementUuid(10);
ASSERT_TRUE(generated_uuid.has_value());
EXPECT_THAT(std::string(*generated_uuid),
StrCaseEq("00000000-0000-3000-8000-00000000000a"));
EXPECT_EQ("00000000-0000-3000-8000-000000000001", generated_string);
generated_string = GenerateAdvertisementUuid(10);
EXPECT_EQ("00000000-0000-3000-8000-00000000000a", generated_string);
generated_string = GenerateAdvertisementUuid(-1);
// Can't generate an advertisement uuid for slot < 0. The result is empty.
EXPECT_TRUE(generated_string.empty());
// Can't generate an advertisement uuid for slot < 0.
generated_uuid = GenerateAdvertisementUuid(-1);
EXPECT_FALSE(generated_uuid.has_value());
}
} // namespace
@@ -20,6 +20,7 @@
#include <string>
#include <utility>
#include "absl/strings/ascii.h"
#include "absl/strings/escaping.h"
#include "connections/implementation/mediums/ble_v2/advertisement_read_result.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement.h"
@@ -37,7 +38,7 @@ namespace mediums {
void DiscoveredPeripheralTracker::StartTracking(
const std::string& service_id,
const DiscoveredPeripheralCallback& discovered_peripheral_callback,
const std::string& fast_advertisement_service_uuid) {
const Uuid& fast_advertisement_service_uuid) {
MutexLock lock(&mutex_);
ServiceIdInfo service_id_info = {
@@ -198,19 +199,20 @@ void DiscoveredPeripheralTracker::HandleAdvertisement(
// First filter out kCopresenceServiceUuid and see if any Caller UUID
// existed; if not then just take the kCopresenceServiceUuid as
// |service_uuid|.
absl::flat_hash_map<std::string, location::nearby::ByteArray> extracted_uuids;
absl::flat_hash_map<Uuid, location::nearby::ByteArray> extracted_uuids;
// Filter out kCoprsence service uuid.
std::remove_copy_if(
advertisement_data.service_data.begin(),
advertisement_data.service_data.end(),
std::inserter(extracted_uuids, extracted_uuids.end()),
[](const std::pair<const std::string, location::nearby::ByteArray>&
pair) { return pair.first == bleutils::kCopresenceServiceUuid; });
std::string service_uuid;
[](const std::pair<const Uuid, location::nearby::ByteArray>& pair) {
return pair.first == bleutils::kCopresenceServiceUuid;
});
Uuid service_uuid;
if (!extracted_uuids.empty()) {
service_uuid = extracted_uuids.begin()->first;
} else {
service_uuid = std::string(bleutils::kCopresenceServiceUuid);
service_uuid = bleutils::kCopresenceServiceUuid;
}
// Create a header tied to this fast advertisement. This helps us track the
@@ -266,7 +268,7 @@ BleAdvertisementHeader DiscoveredPeripheralTracker::HandleRawGattAdvertisements(
BleV2Peripheral peripheral,
const BleAdvertisementHeader& advertisement_header,
const std::vector<const ByteArray*>& gatt_advertisement_bytes_list,
const std::string& service_uuid) {
const Uuid& service_uuid) {
absl::flat_hash_map<std::string, BleAdvertisement>
parsed_gatt_advertisements = ParseRawGattAdvertisements(
gatt_advertisement_bytes_list, service_uuid);
@@ -353,7 +355,7 @@ BleAdvertisementHeader DiscoveredPeripheralTracker::HandleRawGattAdvertisements(
absl::flat_hash_map<std::string, BleAdvertisement>
DiscoveredPeripheralTracker::ParseRawGattAdvertisements(
const std::vector<const ByteArray*>& gatt_advertisement_bytes_list,
const std::string& service_uuid) {
const Uuid& service_uuid) {
absl::flat_hash_map<std::string, BleAdvertisement>
parsed_gatt_advertisements = {};
@@ -382,14 +384,15 @@ DiscoveredPeripheralTracker::ParseRawGattAdvertisements(
// service_id_hash is null here (mediums advertisement) because we already
// have a UUID in the fast advertisement.
if (gatt_advertisement.IsFastAdvertisement() && !service_uuid.empty()) {
if (gatt_advertisement.IsFastAdvertisement() && !service_uuid.IsEmpty()) {
const auto sii_it = service_id_infos_.find(service_id);
if (sii_it != service_id_infos_.end()) {
if (sii_it->second.fast_advertisement_service_uuid == service_uuid) {
NEARBY_LOGS(INFO)
<< "This GATT advertisement:"
<< absl::BytesToHexString(gatt_advertisement_bytes->data())
<< " is a fast advertisement and matched UUID=" << service_uuid
<< " is a fast advertisement and matched UUID="
<< service_uuid.Get16BitAsString()
<< " in a map with service_id=" << service_id;
parsed_gatt_advertisements.insert({service_id, gatt_advertisement});
}
@@ -490,7 +493,7 @@ void DiscoveredPeripheralTracker::HandleAdvertisementHeader(
if (!gatt_advertisement_bytes_list.empty()) {
HandleRawGattAdvertisements(peripheral, advertisement_header,
gatt_advertisement_bytes_list,
/*service_uuid=*/"");
/*service_uuid=*/{});
}
}
@@ -71,13 +71,13 @@ class DiscoveredPeripheralTracker {
// events.
// fast_advertisement_service_uuid - The service UUID to look for fast
// advertisements on.
// Note: fast_advertisement_service_uuid can be empty string to indicate
// Note: fast_advertisement_service_uuid can be empty UUID to indicate
// that `fast_advertisement_service_uuid` will be ignored for regular
// advertisement.
void StartTracking(
const std::string& service_id,
const DiscoveredPeripheralCallback& discovered_peripheral_callback,
const std::string& fast_advertisement_service_uuid)
const Uuid& fast_advertisement_service_uuid)
ABSL_LOCKS_EXCLUDED(mutex_);
// Stops tracking discoveries for a particular service Id.
@@ -115,7 +115,7 @@ class DiscoveredPeripheralTracker {
// Used to check for fast advertisements delivered through BLE advertisement
// service data, under the given UUID.
std::string fast_advertisement_service_uuid;
Uuid fast_advertisement_service_uuid;
};
// A container to hold the related informations for a GATT advertisement.
@@ -185,13 +185,13 @@ class DiscoveredPeripheralTracker {
BleV2Peripheral peripheral,
const BleAdvertisementHeader& advertisement_header,
const std::vector<const ByteArray*>& gatt_advertisement_bytes_list,
const std::string& service_uuid) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
const Uuid& service_uuid) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Returns a map of service IDs to GATT advertisements who belong to a tracked
// service ID.
absl::flat_hash_map<std::string, BleAdvertisement> ParseRawGattAdvertisements(
const std::vector<const ByteArray*>& gatt_advertisement_bytes_list,
const std::string& service_uuid) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
const Uuid& service_uuid) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Returns true if `new_psm` is not default value and different with
// `old_psm`.
@@ -33,10 +33,7 @@ namespace mediums {
namespace {
constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000);
constexpr absl::string_view kCopresenceServiceUuid =
"0000FEF3-0000-1000-8000-00805F9B34FB";
constexpr absl::string_view kFastAdvertisementServiceUuid =
"0000FE2C-0000-1000-8000-00805F9B34FB";
constexpr absl::string_view kFastAdvertisementServiceUuid = "FE2C";
constexpr absl::string_view kServiceIdA = "A";
constexpr absl::string_view kServiceIdB = "B";
constexpr absl::string_view kMacAddress1 = "4C:8B:1D:CE:BA:D1";
@@ -207,12 +204,12 @@ TEST_F(DiscoveredPeripheralTrackerTest,
found_latch.CountDown();
},
},
std::string(kFastAdvertisementServiceUuid));
Uuid(kFastAdvertisementServiceUuid));
api::ble_v2::BleAdvertisementData advertisement_data;
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
{Uuid(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
FindFastAdvertisement(advertisement_data, {}, fetch_latch);
@@ -246,12 +243,12 @@ TEST_F(DiscoveredPeripheralTrackerTest,
found_latch.CountDown();
},
},
std::string(kFastAdvertisementServiceUuid));
Uuid(kFastAdvertisementServiceUuid));
api::ble_v2::BleAdvertisementData advertisement_data;
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
{Uuid(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
FindFastAdvertisement(advertisement_data, {}, fetch_latch);
@@ -290,12 +287,12 @@ TEST_F(DiscoveredPeripheralTrackerTest,
found_latch.CountDown();
},
},
"0000FE2C-0000-1000-8000-00805F9B34FC");
Uuid("FE3C"));
api::ble_v2::BleAdvertisementData advertisement_data;
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
{Uuid(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
FindFastAdvertisement(advertisement_data, {}, fetch_latch);
@@ -333,7 +330,7 @@ TEST_F(DiscoveredPeripheralTrackerTest,
found_latch_a.CountDown();
},
},
std::string(kFastAdvertisementServiceUuid));
Uuid(kFastAdvertisementServiceUuid));
discovered_peripheral_tracker_.StartTracking(
std::string(kServiceIdB),
{
@@ -347,16 +344,16 @@ TEST_F(DiscoveredPeripheralTrackerTest,
found_latch_b.CountDown();
},
},
"");
{});
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
{Uuid(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
FindFastAdvertisement(advertisement_data, {advertisement_bytes}, fetch_latch);
@@ -392,12 +389,12 @@ TEST_F(DiscoveredPeripheralTrackerTest,
found_latch.CountDown();
},
},
"");
{});
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
FindAdvertisement(advertisement_data, {advertisement_bytes}, fetch_latch);
@@ -428,12 +425,12 @@ TEST_F(DiscoveredPeripheralTrackerTest,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { found_latch.CountDown(); },
},
"");
{});
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
FindAdvertisement(advertisement_data, {legacy_advertisement_bytes},
@@ -474,12 +471,12 @@ TEST_F(DiscoveredPeripheralTrackerTest,
found_latch.CountDown();
},
},
"");
{});
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
FindAdvertisement(advertisement_data,
@@ -520,12 +517,12 @@ TEST_F(DiscoveredPeripheralTrackerTest,
found_latch.CountDown();
},
},
"");
{});
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
FindAdvertisement(advertisement_data, {advertisement_bytes}, fetch_latch);
@@ -563,12 +560,12 @@ TEST_F(DiscoveredPeripheralTrackerTest,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { found_latch.CountDown(); },
},
"");
{});
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
FindAdvertisement(advertisement_data, {advertisement_bytes}, fetch_latch);
@@ -612,16 +609,16 @@ TEST_F(DiscoveredPeripheralTrackerTest,
lost_latch.CountDown();
},
},
std::string(kFastAdvertisementServiceUuid));
Uuid(kFastAdvertisementServiceUuid));
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
{Uuid(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
FindFastAdvertisement(advertisement_data, {fast_advertisement_bytes},
@@ -672,16 +669,16 @@ TEST_F(DiscoveredPeripheralTrackerTest,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { lost_latch.CountDown(); },
},
std::string(kFastAdvertisementServiceUuid));
Uuid(kFastAdvertisementServiceUuid));
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
{Uuid(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
// Start tracking a service ID and then process a loop of discoveries and
@@ -729,12 +726,12 @@ TEST_F(DiscoveredPeripheralTrackerTest, LostPeripheralForAdvertisementLost) {
const ByteArray& advertisement_bytes,
bool fast_advertisement) { lost_latch.CountDown(); },
},
"");
{});
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
FindAdvertisement(advertisement_data, {advertisement_bytes}, fetch_latch);
@@ -788,7 +785,7 @@ TEST_F(DiscoveredPeripheralTrackerTest,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { lost_latch_a.CountDown(); },
},
std::string(kFastAdvertisementServiceUuid));
Uuid(kFastAdvertisementServiceUuid));
discovered_peripheral_tracker_.StartTracking(
std::string(kServiceIdB),
{
@@ -807,16 +804,16 @@ TEST_F(DiscoveredPeripheralTrackerTest,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { lost_latch_b.CountDown(); },
},
"");
{});
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
{Uuid(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
FindFastAdvertisement(advertisement_data, {advertisement_bytes}, fetch_latch);
@@ -869,12 +866,12 @@ TEST_F(DiscoveredPeripheralTrackerTest,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { lost_latch.CountDown(); },
},
"");
{});
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
FindAdvertisement(advertisement_data, {advertisement_bytes}, fetch_latch);
@@ -18,9 +18,9 @@
#include <string>
#include <utility>
#include "connections/implementation/mediums/uuid.h"
#include "internal/platform/logging.h"
#include "internal/platform/mutex_lock.h"
#include "internal/platform/uuid.h"
namespace location {
namespace nearby {
@@ -1,87 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "connections/implementation/mediums/uuid.h"
#include <iomanip>
#include <sstream>
#include "internal/platform/crypto.h"
namespace location {
namespace nearby {
namespace connections {
namespace {
std::ostream& write_hex(std::ostream& os, absl::string_view data) {
for (const auto b : data) {
os << std::setfill('0') << std::setw(2) << std::hex
<< (static_cast<unsigned int>(b) & 0x0ff);
}
return os;
}
} // namespace
Uuid::Uuid(absl::string_view data) : data_(Crypto::Md5(data)) {
// Based on the Java counterpart at
// http://androidxref.com/8.0.0_r4/xref/libcore/ojluni/src/main/java/java/util/UUID.java#162.
data_[6] &= 0x0f; // Clear version.
data_[6] |= 0x30; // Set to version 3.
data_[8] &= 0x3f; // Clear variant.
data_[8] |= 0x80; // Set to IETF variant.
}
Uuid::Uuid(std::uint64_t most_sig_bits, std::uint64_t least_sig_bits) {
// Base on the Java counterpart at
// http://androidxref.com/8.0.0_r4/xref/libcore/ojluni/src/main/java/java/util/UUID.java#104.
data_.reserve(sizeof(most_sig_bits) + sizeof(least_sig_bits));
data_[0] = static_cast<char>((most_sig_bits >> 56) & 0x0ff);
data_[1] = static_cast<char>((most_sig_bits >> 48) & 0x0ff);
data_[2] = static_cast<char>((most_sig_bits >> 40) & 0x0ff);
data_[3] = static_cast<char>((most_sig_bits >> 32) & 0x0ff);
data_[4] = static_cast<char>((most_sig_bits >> 24) & 0x0ff);
data_[5] = static_cast<char>((most_sig_bits >> 16) & 0x0ff);
data_[6] = static_cast<char>((most_sig_bits >> 8) & 0x0ff);
data_[7] = static_cast<char>((most_sig_bits >> 0) & 0x0ff);
data_[8] = static_cast<char>((least_sig_bits >> 56) & 0x0ff);
data_[9] = static_cast<char>((least_sig_bits >> 48) & 0x0ff);
data_[10] = static_cast<char>((least_sig_bits >> 40) & 0x0ff);
data_[11] = static_cast<char>((least_sig_bits >> 32) & 0x0ff);
data_[12] = static_cast<char>((least_sig_bits >> 24) & 0x0ff);
data_[13] = static_cast<char>((least_sig_bits >> 16) & 0x0ff);
data_[14] = static_cast<char>((least_sig_bits >> 8) & 0x0ff);
data_[15] = static_cast<char>((least_sig_bits >> 0) & 0x0ff);
}
Uuid::operator std::string() const {
// Based on the Java counterpart at
// http://androidxref.com/8.0.0_r4/xref/libcore/ojluni/src/main/java/java/util/UUID.java#375.
std::ostringstream md5_hex;
write_hex(md5_hex, absl::string_view(&data_[0], 4));
md5_hex << "-";
write_hex(md5_hex, absl::string_view(&data_[4], 2));
md5_hex << "-";
write_hex(md5_hex, absl::string_view(&data_[6], 2));
md5_hex << "-";
write_hex(md5_hex, absl::string_view(&data_[8], 2));
md5_hex << "-";
write_hex(md5_hex, absl::string_view(&data_[10], 6));
return md5_hex.str();
}
} // namespace connections
} // namespace nearby
} // namespace location
-57
View File
@@ -1,57 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CORE_INTERNAL_MEDIUMS_UUID_H_
#define CORE_INTERNAL_MEDIUMS_UUID_H_
#include <cstdint>
#include <string>
#include "absl/strings/string_view.h"
namespace location {
namespace nearby {
namespace connections {
// A type 3 name-based
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based))
// UUID.
//
// https://developer.android.com/reference/java/util/UUID.html
class Uuid final {
public:
Uuid() : Uuid("uuid") {}
explicit Uuid(absl::string_view data);
Uuid(std::uint64_t most_sig_bits, std::uint64_t least_sig_bits);
Uuid(const Uuid&) = default;
Uuid& operator=(const Uuid&) = default;
Uuid(Uuid&&) = default;
Uuid& operator=(Uuid&&) = default;
~Uuid() = default;
// Returns the canonical textual representation
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of the
// UUID.
explicit operator std::string() const;
std::string data() const { return data_; }
private:
std::string data_;
};
} // namespace connections
} // namespace nearby
} // namespace location
#endif // CORE_INTERNAL_MEDIUMS_UUID_H_
@@ -1,71 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "connections/implementation/mediums/uuid.h"
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "internal/platform/crypto.h"
#include "internal/platform/logging.h"
namespace location {
namespace nearby {
namespace connections {
namespace {
constexpr absl::string_view kString{"some string"};
constexpr std::uint64_t kNum1 = 0x123456789abcdef0;
constexpr std::uint64_t kNum2 = 0x21436587a9cbed0f;
TEST(UuidTest, CreateFromStringWithMd5) {
Uuid uuid(kString);
std::string uuid_str(uuid);
std::string uuid_data(uuid.data());
std::string md5_data(Crypto::Md5(kString));
NEARBY_LOG(INFO, "MD5-based UUID: '%s'", uuid_str.c_str());
uuid_data[6] = 0;
uuid_data[8] = 0;
md5_data[6] = 0;
md5_data[8] = 0;
EXPECT_EQ(md5_data, uuid_data);
}
TEST(UuidTest, CreateFromBinary) {
Uuid uuid(kNum1, kNum2);
std::string uuid_data(uuid.data());
std::string uuid_str(uuid);
NEARBY_LOG(INFO, "UUID: '%s'", uuid_str.c_str());
EXPECT_EQ(uuid_data[0], (kNum1 >> 56) & 0xFF);
EXPECT_EQ(uuid_data[1], (kNum1 >> 48) & 0xFF);
EXPECT_EQ(uuid_data[2], (kNum1 >> 40) & 0xFF);
EXPECT_EQ(uuid_data[3], (kNum1 >> 32) & 0xFF);
EXPECT_EQ(uuid_data[4], (kNum1 >> 24) & 0xFF);
EXPECT_EQ(uuid_data[5], (kNum1 >> 16) & 0xFF);
EXPECT_EQ(uuid_data[6], (kNum1 >> 8) & 0xFF);
EXPECT_EQ(uuid_data[7], (kNum1 >> 0) & 0xFF);
EXPECT_EQ(uuid_data[8], (kNum2 >> 56) & 0xFF);
EXPECT_EQ(uuid_data[9], (kNum2 >> 48) & 0xFF);
EXPECT_EQ(uuid_data[10], (kNum2 >> 40) & 0xFF);
EXPECT_EQ(uuid_data[11], (kNum2 >> 32) & 0xFF);
EXPECT_EQ(uuid_data[12], (kNum2 >> 24) & 0xFF);
EXPECT_EQ(uuid_data[13], (kNum2 >> 16) & 0xFF);
EXPECT_EQ(uuid_data[14], (kNum2 >> 8) & 0xFF);
EXPECT_EQ(uuid_data[15], (kNum2 >> 0) & 0xFF);
}
} // namespace
} // namespace connections
} // namespace nearby
} // namespace location
+23
View File
@@ -160,6 +160,26 @@ cc_library(
],
)
cc_library(
name = "uuid",
srcs = [
"uuid.cc",
],
hdrs = [
"uuid.h",
],
defines = ["NO_WEBRTC"],
visibility = [
"//connections/implementation:__subpackages__",
"//internal/platform:__pkg__",
"//internal/platform/implementation:__subpackages__",
],
deps = [
"//internal/platform/implementation:types",
"@com_google_absl//absl/strings",
],
)
cc_library(
name = "test_util",
testonly = True,
@@ -334,6 +354,7 @@ cc_library(
deps = [
":logging",
":types",
":uuid",
"//internal/platform:base",
"//internal/platform:cancellation_flag",
"//internal/platform/implementation:comm",
@@ -366,6 +387,7 @@ cc_test(
"pipe_test.cc",
"scheduled_executor_test.cc",
"single_thread_executor_test.cc",
"uuid_test.cc",
"wifi_hotspot_test.cc",
"wifi_lan_test.cc",
],
@@ -376,6 +398,7 @@ cc_test(
":comm",
":logging",
":types",
":uuid",
"//internal/platform:base",
"//internal/platform:test_util",
"//internal/platform/implementation/g3", # build_cleaner: keep
+1 -1
View File
@@ -38,7 +38,7 @@ bool BleV2Medium::StartAdvertising(
bool BleV2Medium::StopAdvertising() { return impl_->StopAdvertising(); }
bool BleV2Medium::StartScanning(const std::string& service_uuid,
bool BleV2Medium::StartScanning(const Uuid& service_uuid,
TxPowerLevel tx_power_level,
ScanCallback callback) {
MutexLock lock(&mutex_);
+5 -5
View File
@@ -27,6 +27,7 @@
#include "internal/platform/implementation/platform.h"
#include "internal/platform/logging.h"
#include "internal/platform/mutex.h"
#include "internal/platform/uuid.h"
namespace location {
namespace nearby {
@@ -152,7 +153,7 @@ class GattServer final {
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<api::ble_v2::GattCharacteristic> CreateCharacteristic(
const std::string& service_uuid, const std::string& characteristic_uuid,
const Uuid& service_uuid, const Uuid& characteristic_uuid,
const std::vector<api::ble_v2::GattCharacteristic::Permission>&
permissions,
const std::vector<api::ble_v2::GattCharacteristic::Property>&
@@ -191,14 +192,13 @@ class GattClient final {
std::unique_ptr<api::ble_v2::GattClient> client_gatt_connection)
: impl_(std::move(client_gatt_connection)) {}
bool DiscoverService(const std::string& service_uuid) {
bool DiscoverService(const Uuid& service_uuid) {
return impl_->DiscoverService(service_uuid);
}
// TODO(edwinwu): Change std::string to Uuid.
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<api::ble_v2::GattCharacteristic> GetCharacteristic(
const std::string& service_uuid, const std::string& characteristic_uuid) {
const Uuid& service_uuid, const Uuid& characteristic_uuid) {
return impl_->GetCharacteristic(service_uuid, characteristic_uuid);
}
@@ -267,7 +267,7 @@ class BleV2Medium final {
bool StopAdvertising();
// Returns true once the BLE scan has been initiated.
bool StartScanning(const std::string& service_uuid,
bool StartScanning(const Uuid& service_uuid,
api::ble_v2::TxPowerLevel tx_power_level,
ScanCallback callback);
bool StopScanning();
+27 -32
View File
@@ -48,7 +48,6 @@ using ::testing::Optional;
constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000);
constexpr absl::string_view kAdvertisementString = "\x0a\x0b\x0c\x0d";
constexpr absl::string_view kAdvertisementHeaderString = "\x0x\x0y\x0z";
constexpr absl::string_view kCopresenceServiceUuid = "F3FE";
constexpr TxPowerLevel kTxPowerLevel(TxPowerLevel::kHigh);
constexpr absl::string_view kServiceIDA{
"com.google.location.nearby.apps.test.a"};
@@ -81,6 +80,7 @@ TEST_P(BleV2MediumTest, CanConnectToService) {
BluetoothAdapter adapter_b_;
BleV2Medium ble_a(adapter_a_);
BleV2Medium ble_b(adapter_b_);
Uuid service_uuid(1234, 5678);
std::string service_id(kServiceIDA);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
CountDownLatch found_latch(1);
@@ -92,14 +92,13 @@ TEST_P(BleV2MediumTest, CanConnectToService) {
// Assemble regular advertisement data
BleAdvertisementData advertising_data;
advertising_data.is_extended_advertisement = false;
advertising_data.service_data = {
{std::string(kCopresenceServiceUuid), advertisement_bytes}};
advertising_data.service_data = {{service_uuid, advertisement_bytes}};
(ble_b.StartAdvertising(advertising_data, {.tx_power_level = kTxPowerLevel,
.is_connectable = true}));
BleV2Peripheral discovered_peripheral;
ble_a.StartScanning(
{std::string(kCopresenceServiceUuid)}, kTxPowerLevel,
service_uuid, kTxPowerLevel,
{
.advertisement_found_cb =
[&found_latch, &discovered_peripheral](
@@ -147,8 +146,9 @@ TEST_P(BleV2MediumTest, CanCancelConnect) {
env_.Start();
BluetoothAdapter adapter_a_;
BluetoothAdapter adapter_b_;
BleV2Medium ble_a{adapter_a_};
BleV2Medium ble_b{adapter_b_};
BleV2Medium ble_a(adapter_a_);
BleV2Medium ble_b(adapter_b_);
Uuid service_uuid(1234, 5678);
std::string service_id(kServiceIDA);
ByteArray advertisement_bytes((std::string(kAdvertisementString)));
CountDownLatch found_latch(1);
@@ -160,14 +160,13 @@ TEST_P(BleV2MediumTest, CanCancelConnect) {
// Assemble regular advertisement data.
BleAdvertisementData advertising_data;
advertising_data.is_extended_advertisement = false;
advertising_data.service_data = {
{std::string(kCopresenceServiceUuid), advertisement_bytes}};
advertising_data.service_data = {{service_uuid, advertisement_bytes}};
(ble_b.StartAdvertising(advertising_data, {.tx_power_level = kTxPowerLevel,
.is_connectable = true}));
BleV2Peripheral discovered_peripheral;
ble_a.StartScanning(
{std::string(kCopresenceServiceUuid)}, kTxPowerLevel,
service_uuid, kTxPowerLevel,
{
.advertisement_found_cb =
[&found_latch, &discovered_peripheral](
@@ -240,11 +239,12 @@ TEST_F(BleV2MediumTest, CanStartFastScanningAndFastAdvertising) {
BluetoothAdapter adapter_b;
BleV2Medium ble_a(adapter_a);
BleV2Medium ble_b(adapter_b);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
Uuid service_uuid(1234, 5678);
ByteArray advertisement_bytes((std::string(kAdvertisementString)));
CountDownLatch found_latch(1);
EXPECT_TRUE(ble_a.StartScanning(
{std::string(kCopresenceServiceUuid)}, kTxPowerLevel,
service_uuid, kTxPowerLevel,
{
.advertisement_found_cb =
[&found_latch](BleV2Peripheral peripheral,
@@ -256,16 +256,14 @@ TEST_F(BleV2MediumTest, CanStartFastScanningAndFastAdvertising) {
// Fail to start extended advertisement due to g3 Ble medium does not support.
BleAdvertisementData advertising_data;
advertising_data.is_extended_advertisement = true;
advertising_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_bytes});
advertising_data.service_data.insert({service_uuid, advertisement_bytes});
EXPECT_FALSE(ble_b.StartAdvertising(
advertising_data,
{.tx_power_level = kTxPowerLevel, .is_connectable = true}));
// Succeed to start regular advertisement.
advertising_data.is_extended_advertisement = false;
advertising_data.service_data = {
{std::string(kCopresenceServiceUuid), advertisement_bytes}};
advertising_data.service_data = {{service_uuid, advertisement_bytes}};
EXPECT_TRUE(ble_b.StartAdvertising(
advertising_data,
{.tx_power_level = kTxPowerLevel, .is_connectable = true}));
@@ -282,12 +280,13 @@ TEST_F(BleV2MediumTest, CanStartScanningAndAdvertising) {
BluetoothAdapter adapter_b;
BleV2Medium ble_a(adapter_a);
BleV2Medium ble_b(adapter_b);
Uuid service_uuid(1234, 5678);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
ByteArray advertisement_header_bytes{std::string(kAdvertisementHeaderString)};
CountDownLatch found_latch(1);
EXPECT_TRUE(ble_a.StartScanning(
{std::string(kCopresenceServiceUuid)}, kTxPowerLevel,
service_uuid, kTxPowerLevel,
{
.advertisement_found_cb =
[&found_latch](BleV2Peripheral peripheral,
@@ -299,16 +298,14 @@ TEST_F(BleV2MediumTest, CanStartScanningAndAdvertising) {
// Fail to start extended advertisement due to g3 Ble medium does not support.
BleAdvertisementData advertising_data;
advertising_data.is_extended_advertisement = true;
advertising_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_bytes});
advertising_data.service_data.insert({service_uuid, advertisement_bytes});
EXPECT_FALSE(ble_b.StartAdvertising(
advertising_data,
{.tx_power_level = kTxPowerLevel, .is_connectable = true}));
// Succeed to start regular advertisement.
advertising_data.is_extended_advertisement = false;
advertising_data.service_data = {
{std::string(kCopresenceServiceUuid), advertisement_header_bytes}};
advertising_data.service_data = {{service_uuid, advertisement_header_bytes}};
EXPECT_TRUE(ble_b.StartAdvertising(
advertising_data,
{.tx_power_level = kTxPowerLevel, .is_connectable = true}));
@@ -323,7 +320,8 @@ TEST_F(BleV2MediumTest, CanStartGattServer) {
env_.Start();
BluetoothAdapter adapter;
BleV2Medium ble(adapter);
std::string characteristic_uuid = "characteristic_uuid";
Uuid service_uuid(1234, 5678);
Uuid characteristic_uuid(5678, 1234);
std::unique_ptr<GattServer> gatt_server =
ble.StartGattServer(/*ServerGattConnectionCallback=*/{});
@@ -336,9 +334,8 @@ TEST_F(BleV2MediumTest, CanStartGattServer) {
GattCharacteristic::Property::kRead};
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<GattCharacteristic> gatt_characteristic =
gatt_server->CreateCharacteristic(std::string(kCopresenceServiceUuid),
characteristic_uuid, permissions,
properties);
gatt_server->CreateCharacteristic(service_uuid, characteristic_uuid,
permissions, properties);
ASSERT_TRUE(gatt_characteristic.has_value());
@@ -358,7 +355,8 @@ TEST_F(BleV2MediumTest, GattClientConnectToGattServerWorks) {
BluetoothAdapter adapter_b;
BleV2Medium ble_a(adapter_a);
BleV2Medium ble_b(adapter_b);
std::string characteristic_uuid = "characteristic_uuid";
Uuid service_uuid(1234, 5678);
Uuid characteristic_uuid(5678, 1234);
// Start GattServer
std::unique_ptr<GattServer> gatt_server =
@@ -373,9 +371,8 @@ TEST_F(BleV2MediumTest, GattClientConnectToGattServerWorks) {
// Add characteristic and its value.
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<GattCharacteristic> server_characteristic =
gatt_server->CreateCharacteristic(std::string(kCopresenceServiceUuid),
characteristic_uuid, permissions,
properties);
gatt_server->CreateCharacteristic(service_uuid, characteristic_uuid,
permissions, properties);
ASSERT_TRUE(server_characteristic.has_value());
ByteArray server_value("any");
EXPECT_TRUE(
@@ -391,14 +388,12 @@ TEST_F(BleV2MediumTest, GattClientConnectToGattServerWorks) {
ASSERT_NE(gatt_client, nullptr);
// Discover service.
EXPECT_TRUE(
gatt_client->DiscoverService(std::string(kCopresenceServiceUuid)));
EXPECT_TRUE(gatt_client->DiscoverService(service_uuid));
// Discover characteristic.
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<GattCharacteristic> client_characteristic =
gatt_client->GetCharacteristic(std::string(kCopresenceServiceUuid),
characteristic_uuid);
gatt_client->GetCharacteristic(service_uuid, characteristic_uuid);
ASSERT_TRUE(client_characteristic.has_value());
// Can read the characteristic value.
+1
View File
@@ -72,6 +72,7 @@ cc_library(
"//connections/implementation/proto:offline_wire_formats_cc_proto",
"//internal/platform:base",
"//internal/platform:cancellation_flag",
"//internal/platform:uuid",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/strings",
+11 -8
View File
@@ -25,6 +25,7 @@
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "internal/platform/uuid.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/exception.h"
@@ -75,7 +76,7 @@ struct BleAdvertisementData {
// iOS : 16 bit service UUID (type=0x03) + LocalName data (type=0x08)
// Windows: Service data (type=0x16)
// Android: 16 bit service UUID (type=0x03) + Service data (type=0x16)
absl::flat_hash_map<std::string, location::nearby::ByteArray> service_data;
absl::flat_hash_map<Uuid, location::nearby::ByteArray> service_data;
};
// Opaque wrapper over a BLE peripheral. Must be able to uniquely identify a
@@ -110,8 +111,8 @@ struct GattCharacteristic {
kLast,
};
std::string uuid;
std::string service_uuid;
Uuid uuid;
Uuid service_uuid;
// Hashable
template <typename H>
@@ -136,7 +137,7 @@ class GattClient {
// Returns whether or not discovery finished successfully.
//
// This function should block until discovery has finished.
virtual bool DiscoverService(const std::string& service_uuid) = 0;
virtual bool DiscoverService(const Uuid& service_uuid) = 0;
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#getService(java.util.UUID)
// https://developer.android.com/reference/android/bluetooth/BluetoothGattService.html#getCharacteristic(java.util.UUID)
@@ -148,12 +149,13 @@ class GattClient {
//
// It is okay for duplicate services to exist, as long as the specified
// characteristic UUID is unique among all services of the same UUID.
// NOLINTNEXTLINE(google3-legacy-absl-backports)
virtual absl::optional<GattCharacteristic> GetCharacteristic(
absl::string_view service_uuid,
absl::string_view characteristic_uuid) = 0;
const Uuid& service_uuid, const Uuid& characteristic_uuid) = 0;
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#readCharacteristic(android.bluetooth.BluetoothGattCharacteristic)
// https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic.html#getValue()
// NOLINTNEXTLINE(google3-legacy-absl-backports)
virtual absl::optional<ByteArray> ReadCharacteristic(
const GattCharacteristic& characteristic) = 0;
@@ -188,8 +190,9 @@ class GattServer {
// write to this descriptor and subscribe for characteristic changes. For
// more information about this descriptor, please go to:
// https://www.bluetooth.com/specifications/Gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.Gatt.client_characteristic_configuration.xml
// NOLINTNEXTLINE(google3-legacy-absl-backports)
virtual absl::optional<GattCharacteristic> CreateCharacteristic(
absl::string_view service_uuid, absl::string_view characteristic_uuid,
const Uuid& service_uuid, const Uuid& characteristic_uuid,
const std::vector<GattCharacteristic::Permission>& permissions,
const std::vector<GattCharacteristic::Property>& properties) = 0;
@@ -317,7 +320,7 @@ class BleMedium {
// HIGH:
// - Scan window = ~4096ms
// - Scan interval = ~4096ms
virtual bool StartScanning(const std::string& service_uuid,
virtual bool StartScanning(const Uuid& service_uuid,
TxPowerLevel tx_power_level,
ScanCallback callback) = 0;
@@ -74,6 +74,7 @@ cc_library(
"//internal/platform:cancellation_flag",
"//internal/platform:logging",
"//internal/platform:test_util",
"//internal/platform:uuid",
"//internal/platform/implementation:comm",
"//internal/platform/implementation/shared:count_down_latch",
"@com_google_absl//absl/base:core_headers",
+21 -18
View File
@@ -242,7 +242,7 @@ bool BleV2Medium::StopAdvertising() {
return true;
}
bool BleV2Medium::StartScanning(const std::string& service_uuid,
bool BleV2Medium::StartScanning(const Uuid& service_uuid,
TxPowerLevel tx_power_level,
ScanCallback callback) {
NEARBY_LOGS(INFO) << "G3 Ble StartScanning";
@@ -280,12 +280,11 @@ bool BleV2Medium::IsExtendedAdvertisementsAvailable() {
std::optional<api::ble_v2::GattCharacteristic>
BleV2Medium::GattServer::CreateCharacteristic(
absl::string_view service_uuid, absl::string_view characteristic_uuid,
const Uuid& service_uuid, const Uuid& characteristic_uuid,
const std::vector<api::ble_v2::GattCharacteristic::Permission>& permissions,
const std::vector<api::ble_v2::GattCharacteristic::Property>& properties) {
api::ble_v2::GattCharacteristic characteristic = {
.uuid = std::string(characteristic_uuid),
.service_uuid = std::string(service_uuid)};
.uuid = characteristic_uuid, .service_uuid = service_uuid};
return characteristic;
}
@@ -294,7 +293,8 @@ bool BleV2Medium::GattServer::UpdateCharacteristic(
const location::nearby::ByteArray& value) {
NEARBY_LOGS(INFO)
<< "G3 Ble GattServer UpdateCharacteristic, characteristic=("
<< characteristic.service_uuid << "," << characteristic.uuid
<< characteristic.service_uuid.Get16BitAsString() << ","
<< std::string(characteristic.uuid)
<< "), value = " << absl::BytesToHexString(value.data());
MediumEnvironment::Instance().InsertBleV2MediumGattCharacteristics(
characteristic, value);
@@ -306,41 +306,43 @@ void BleV2Medium::GattServer::Stop() {
MediumEnvironment::Instance().ClearBleV2MediumGattCharacteristics();
}
bool BleV2Medium::GattClient::DiscoverService(const std::string& service_uuid) {
bool BleV2Medium::GattClient::DiscoverService(const Uuid& service_uuid) {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << "G3 Ble GattClient DiscoverService, service_uuid"
<< service_uuid;
NEARBY_LOGS(INFO) << "G3 Ble GattClient DiscoverService, service_uuid="
<< service_uuid.Get16BitAsString();
if (!is_connection_alive_) {
return false;
}
// Search if the service exists.
return MediumEnvironment::Instance().ContainsBleV2MediumGattCharacteristics(
service_uuid, "");
service_uuid, /*characteristic_uuid=*/{});
}
std::optional<api::ble_v2::GattCharacteristic>
BleV2Medium::GattClient::GetCharacteristic(
absl::string_view service_uuid, absl::string_view characteristic_uuid) {
BleV2Medium::GattClient::GetCharacteristic(const Uuid& service_uuid,
const Uuid& characteristic_uuid) {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << "G3 Ble GattClient GetCharacteristic, service_uuid="
<< service_uuid
<< ", characteristic_uuid=" << characteristic_uuid;
<< service_uuid.Get16BitAsString()
<< ", characteristic_uuid="
<< std::string(characteristic_uuid);
if (!is_connection_alive_) {
return std::nullopt;
}
// Search gatt_characteristic by uuid and if found return the
// gatt_characteristic.
api::ble_v2::GattCharacteristic characteristic = {};
api::ble_v2::GattCharacteristic characteristic;
if (MediumEnvironment::Instance().ContainsBleV2MediumGattCharacteristics(
service_uuid, characteristic_uuid)) {
characteristic = {.uuid = std::string(characteristic_uuid),
.service_uuid = std::string(service_uuid)};
characteristic = {.uuid = characteristic_uuid,
.service_uuid = service_uuid};
}
NEARBY_LOGS(INFO)
<< "G3 Ble GattClient GetCharacteristic, found characteristic=("
<< characteristic.service_uuid << "," << characteristic.uuid << ")";
<< characteristic.service_uuid.Get16BitAsString() << ","
<< std::string(characteristic.uuid) << ")";
return characteristic;
}
@@ -356,7 +358,8 @@ std::optional<ByteArray> BleV2Medium::GattClient::ReadCharacteristic(
MediumEnvironment::Instance().ReadBleV2MediumGattCharacteristics(
characteristic);
NEARBY_LOGS(INFO) << "G3 Ble ReadCharacteristic, characteristic=("
<< characteristic.service_uuid << "," << characteristic.uuid
<< characteristic.service_uuid.Get16BitAsString() << ","
<< std::string(characteristic.uuid)
<< "), value = " << absl::BytesToHexString(value.data());
return std::move(value);
}
+5 -5
View File
@@ -25,6 +25,7 @@
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/g3/bluetooth_adapter.h"
#include "internal/platform/implementation/g3/pipe.h"
#include "internal/platform/uuid.h"
namespace location {
namespace nearby {
@@ -160,7 +161,7 @@ class BleV2Medium : public api::ble_v2::BleMedium {
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopAdvertising() override ABSL_LOCKS_EXCLUDED(mutex_);
bool StartScanning(const std::string& service_uuid,
bool StartScanning(const Uuid& service_uuid,
api::ble_v2::TxPowerLevel tx_power_level,
ScanCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
@@ -199,7 +200,7 @@ class BleV2Medium : public api::ble_v2::BleMedium {
class GattServer : public api::ble_v2::GattServer {
public:
std::optional<api::ble_v2::GattCharacteristic> CreateCharacteristic(
absl::string_view service_uuid, absl::string_view characteristic_uuid,
const Uuid& service_uuid, const Uuid& characteristic_uuid,
const std::vector<api::ble_v2::GattCharacteristic::Permission>&
permissions,
const std::vector<api::ble_v2::GattCharacteristic::Property>&
@@ -215,11 +216,10 @@ class BleV2Medium : public api::ble_v2::BleMedium {
// A concrete implemenation for GattClient.
class GattClient : public api::ble_v2::GattClient {
public:
bool DiscoverService(const std::string& service_uuid) override;
bool DiscoverService(const Uuid& service_uuid) override;
std::optional<api::ble_v2::GattCharacteristic> GetCharacteristic(
absl::string_view service_uuid,
absl::string_view characteristic_uuid) override;
const Uuid& service_uuid, const Uuid& characteristic_uuid) override;
std::optional<ByteArray> ReadCharacteristic(
const api::ble_v2::GattCharacteristic& characteristic) override;
@@ -106,7 +106,7 @@ bool BleV2Medium::StartAdvertising(const BleAdvertisementData& advertising_data,
// (AD type 0x16) Service Data
DataWriter data_writer;
auto it = advertising_data.service_data.begin();
const std::string& service_uuid = it->first;
const std::string& service_uuid = it->first.Get16BitAsString();
const ByteArray& service_bytes = it->second;
if (service_uuid.size() < 2) {
@@ -184,7 +184,7 @@ bool BleV2Medium::StopAdvertising() {
return true;
}
bool BleV2Medium::StartScanning(const std::string& service_uuid,
bool BleV2Medium::StartScanning(const Uuid& service_uuid,
TxPowerLevel tx_power_level,
ScanCallback callback) {
NEARBY_LOGS(INFO) << "Windows Ble StartScanning";
@@ -50,7 +50,7 @@ class BleV2Medium : public api::ble_v2::BleMedium {
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopAdvertising() override ABSL_LOCKS_EXCLUDED(mutex_);
bool StartScanning(const std::string& service_uuid,
bool StartScanning(const Uuid& service_uuid,
api::ble_v2::TxPowerLevel tx_power_level,
ScanCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
@@ -56,7 +56,7 @@ TEST(BleV2Medium, DISABLED_StartScanning) {
BluetoothAdapter bluetoothAdapter;
BleV2Medium blev2_medium(bluetoothAdapter);
std::string service_uuid;
Uuid service_uuid;
api::ble_v2::BleMedium::ScanCallback callback;
callback.advertisement_found_cb =
@@ -78,7 +78,7 @@ TEST(BleV2Medium, DISABLED_StartScanning) {
TEST(BleV2Medium, DISABLED_StopScanning) {
BluetoothAdapter bluetoothAdapter;
BleV2Medium blev2_medium(bluetoothAdapter);
std::string service_uuid;
Uuid service_uuid;
api::ble_v2::BleMedium::ScanCallback callback;
callback.advertisement_found_cb =
+8 -7
View File
@@ -555,8 +555,8 @@ void MediumEnvironment::UpdateBleV2MediumForAdvertising(
}
void MediumEnvironment::UpdateBleV2MediumForScanning(
bool enabled, const std::string& scanning_service_uuid,
BleScanCallback callback, api::ble_v2::BleMedium& medium) {
bool enabled, const Uuid& scanning_service_uuid, BleScanCallback callback,
api::ble_v2::BleMedium& medium) {
if (!enabled_) return;
RunOnMediumEnvironmentThread(
[this, &medium, scanning_service_uuid = scanning_service_uuid,
@@ -591,7 +591,8 @@ void MediumEnvironment::UpdateBleV2MediumForScanning(
<< "G3 UpdateBleV2MediumForScanning, found other medium="
<< remote_medium
<< ", remote_medium_context=" << &remote_context
<< ", scanning_service_uuid=" << scanning_service_uuid
<< ", scanning_service_uuid="
<< scanning_service_uuid.Get16BitAsString()
<< ". Ready to call OnBleV2PeripheralStateChanged.";
OnBleV2PeripheralStateChanged(enabled, context,
remote_context.advertisement_data,
@@ -615,21 +616,21 @@ void MediumEnvironment::InsertBleV2MediumGattCharacteristics(
}
bool MediumEnvironment::ContainsBleV2MediumGattCharacteristics(
absl::string_view service_uuid, absl::string_view characteristic_uuid) {
const Uuid& service_uuid, const Uuid& characteristic_uuid) {
if (!enabled_) return false;
bool found_characteristic = false;
CountDownLatch latch(1);
RunOnMediumEnvironmentThread([this, &latch, &service_uuid,
&characteristic_uuid, &found_characteristic]() {
for (const auto& item : gatt_advertisement_bytes_) {
if (service_uuid == item.first.service_uuid) {
if (characteristic_uuid.empty()) {
if (item.first.service_uuid == service_uuid) {
if (characteristic_uuid.IsEmpty()) {
// Found the service uuid and no need to search characteristic
// uuid.
found_characteristic = true;
break;
}
if (characteristic_uuid == item.first.uuid) {
if (item.first.uuid == characteristic_uuid) {
found_characteristic = true;
break;
}
+4 -4
View File
@@ -231,7 +231,7 @@ class MediumEnvironment {
// The `callback` argument should be non-empty if `enabled` is true or empty
// if `enabled` is false.
void UpdateBleV2MediumForScanning(bool enabled,
const std::string& scanning_service_uuid,
const Uuid& scanning_service_uuid,
BleScanCallback callback,
api::ble_v2::BleMedium& medium);
@@ -244,8 +244,8 @@ class MediumEnvironment {
// Check if `service_uuid` and `characteristic_uuid` exists in the map.
//
// `characteristic_uuid` can be empty and to check `service_uuid` only.
bool ContainsBleV2MediumGattCharacteristics(
absl::string_view service_uuid, absl::string_view characteristic_uuid);
bool ContainsBleV2MediumGattCharacteristics(const Uuid& service_uuid,
const Uuid& characteristic_uuid);
// Reads the BLE GATT characteristic value. If the GATT characteristic is not
// existed, return empty byte array.
@@ -333,7 +333,7 @@ class MediumEnvironment {
BleScanCallback scan_callback = {};
api::ble_v2::BlePeripheral* ble_peripheral = nullptr;
api::ble_v2::BleAdvertisementData advertisement_data;
std::string scanning_service_uuid = {};
Uuid scanning_service_uuid;
bool advertising = false;
};
+115
View File
@@ -0,0 +1,115 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/uuid.h"
#include <iomanip>
#include <sstream>
#include <string>
#include "absl/strings/escaping.h"
#include "internal/platform/implementation/crypto.h"
namespace location {
namespace nearby {
namespace {
std::ostream& write_hex(std::ostream& os, absl::string_view data) {
for (const auto b : data) {
os << std::setfill('0') << std::setw(2) << std::hex << std::uppercase
<< (static_cast<unsigned int>(b) & 0x0ff);
}
return os;
}
} // namespace
Uuid::Uuid(absl::string_view data) {
// Based on the Java counterpart at
// http://androidxref.com/8.0.0_r4/xref/libcore/ojluni/src/main/java/java/util/UUID.java#162.
std::string md5_data(Crypto::Md5(data));
md5_data[6] &= 0x0f; // Clear version.
md5_data[6] |= 0x30; // Set to version 3.
md5_data[8] &= 0x3f; // Clear variant.
md5_data[8] |= 0x80; // Set to IETF variant.
std::uint64_t msb = 0;
std::uint64_t lsb = 0;
for (int i = 0; i < 8; i++) {
msb = (msb << 8) | (md5_data[i] & 0xff);
}
for (int i = 8; i < 16; i++) {
lsb = (lsb << 8) | (md5_data[i] & 0xff);
}
most_sig_bits_ = msb;
least_sig_bits_ = lsb;
}
Uuid::operator std::string() const { return ToCanonicalString(data()); }
std::string Uuid::Get16BitAsString() const {
std::ostringstream sixteen_bit_string;
char data = static_cast<char>((most_sig_bits_ >> 40) & 0x0ff);
write_hex(sixteen_bit_string, absl::string_view(&data, 1));
data = static_cast<char>((most_sig_bits_ >> 32) & 0x0ff);
write_hex(sixteen_bit_string, absl::string_view(&data, 1));
return sixteen_bit_string.str();
}
std::array<char, 16> Uuid::data() const {
std::array<char, 16> data;
data[0] = (most_sig_bits_ >> 56) & 0x0ff;
data[1] = (most_sig_bits_ >> 48) & 0x0ff;
data[2] = (most_sig_bits_ >> 40) & 0x0ff;
data[3] = (most_sig_bits_ >> 32) & 0x0ff;
data[4] = (most_sig_bits_ >> 24) & 0x0ff;
data[5] = (most_sig_bits_ >> 16) & 0x0ff;
data[6] = (most_sig_bits_ >> 8) & 0x0ff;
data[7] = (most_sig_bits_ >> 0) & 0x0ff;
data[8] = (least_sig_bits_ >> 56) & 0x0ff;
data[9] = (least_sig_bits_ >> 48) & 0x0ff;
data[10] = (least_sig_bits_ >> 40) & 0x0ff;
data[11] = (least_sig_bits_ >> 32) & 0x0ff;
data[12] = (least_sig_bits_ >> 24) & 0x0ff;
data[13] = (least_sig_bits_ >> 16) & 0x0ff;
data[14] = (least_sig_bits_ >> 8) & 0x0ff;
data[15] = (least_sig_bits_ >> 0) & 0x0ff;
return data;
}
std::string Uuid::ToCanonicalString(const std::array<char, 16>& data) const {
// Based on the Java counterpart at
// http://androidxref.com/8.0.0_r4/xref/libcore/ojluni/src/main/java/java/util/UUID.java#375.
std::ostringstream md5_hex;
std::string uuid_string(data.data(), data.size());
write_hex(md5_hex, absl::string_view(&uuid_string[0], 4));
md5_hex << "-";
write_hex(md5_hex, absl::string_view(&uuid_string[4], 2));
md5_hex << "-";
write_hex(md5_hex, absl::string_view(&uuid_string[6], 2));
md5_hex << "-";
write_hex(md5_hex, absl::string_view(&uuid_string[8], 2));
md5_hex << "-";
write_hex(md5_hex, absl::string_view(&uuid_string[10], 6));
return md5_hex.str();
}
bool Uuid::operator==(const Uuid& rhs) const {
return GetMostSigBits() == rhs.GetMostSigBits() &&
GetLeastSigBits() == rhs.GetLeastSigBits();
}
} // namespace nearby
} // namespace location
+80
View File
@@ -0,0 +1,80 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_UUID_H_
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_UUID_H_
#include <cstdint>
#include <string>
#include "absl/strings/string_view.h"
namespace location {
namespace nearby {
// A type 3 name-based
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based))
// UUID.
//
// https://developer.android.com/reference/java/util/UUID.html
class Uuid final {
public:
Uuid() = default;
// Constructs a type 3 (name based) UUID based on the input string.
explicit Uuid(absl::string_view data);
// Constructs a new UUID using the specified most_sig_bits for the most
// significant 64 bits of the UUID and least_sig_bits for the least
// significant 64 bits of the UUID.
constexpr Uuid(std::uint64_t most_sig_bits, std::uint64_t least_sig_bits)
: most_sig_bits_(most_sig_bits), least_sig_bits_(least_sig_bits) {}
// Returns a 16-size char array representing this UUID.
std::array<char, 16> data() const;
// Returns the canonical textual representation
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of the
// UUID.
explicit operator std::string() const;
// Get ABCD fom xxxxABCD-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx
//
// This is needed because Android only support UUID 16 bits in service data
// section in advertising data
std::string Get16BitAsString() const;
std::uint64_t GetMostSigBits() const { return most_sig_bits_; }
std::uint64_t GetLeastSigBits() const { return least_sig_bits_; }
// Hashable
bool operator==(const Uuid &rhs) const;
template <typename H>
friend H AbslHashValue(H h, const Uuid &b) {
return H::combine(std::move(h), b.most_sig_bits_, b.least_sig_bits_);
}
// Returns true if both most_sig_bits_ and least_sig_bits_ are zero.
bool IsEmpty() const { return most_sig_bits_ == 0 && least_sig_bits_ == 0; }
private:
std::string ToCanonicalString(const std::array<char, 16>& data) const;
std::uint64_t most_sig_bits_{0};
std::uint64_t least_sig_bits_{0};
};
} // namespace nearby
} // namespace location
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_UUID_H_
+114
View File
@@ -0,0 +1,114 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/uuid.h"
#include <string>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "internal/platform/crypto.h"
#include "internal/platform/logging.h"
namespace location {
namespace nearby {
namespace {
using ::testing::StrCaseEq;
constexpr absl::string_view kString{"some string"};
constexpr std::uint64_t kCopresenceServiceUuidMsb = 0x0000FEF300001000;
constexpr std::uint64_t kCopresenceServiceUuidLsb = 0x800000805F9B34FB;
TEST(UuidTest, ConstructorWorks) {
Uuid uuid_1;
EXPECT_TRUE(uuid_1.IsEmpty());
Uuid uuid_2("test");
EXPECT_FALSE(uuid_2.IsEmpty());
Uuid uuid_3(1234, 5678);
EXPECT_FALSE(uuid_3.IsEmpty());
}
TEST(UuidTest, CreateFromStringWithMd5) {
Uuid uuid(kString);
std::string uuid_str(uuid);
std::array<char, 16> uuid_data = uuid.data();
std::string md5_data(Crypto::Md5(kString));
NEARBY_LOGS(INFO) << "MD5-based UUID: " << uuid_str;
uuid_data[6] = 0;
uuid_data[8] = 0;
md5_data[6] = 0;
md5_data[8] = 0;
EXPECT_EQ(std::string(uuid_data.data(), uuid_data.size()), md5_data);
}
TEST(UuidTest, CreateFromBinaryCanOutputString) {
Uuid uuid(kCopresenceServiceUuidMsb, kCopresenceServiceUuidLsb);
std::array<char, 16> uuid_data = uuid.data();
std::string uuid_str(uuid);
NEARBY_LOGS(INFO) << "UUID: " << uuid_str;
EXPECT_EQ(uuid_data[0], (kCopresenceServiceUuidMsb >> 56) & 0xFF);
EXPECT_EQ(uuid_data[1], (kCopresenceServiceUuidMsb >> 48) & 0xFF);
EXPECT_EQ(uuid_data[2], (kCopresenceServiceUuidMsb >> 40) & 0xFF);
EXPECT_EQ(uuid_data[3], (kCopresenceServiceUuidMsb >> 32) & 0xFF);
EXPECT_EQ(uuid_data[4], (kCopresenceServiceUuidMsb >> 24) & 0xFF);
EXPECT_EQ(uuid_data[5], (kCopresenceServiceUuidMsb >> 16) & 0xFF);
EXPECT_EQ(uuid_data[6], (kCopresenceServiceUuidMsb >> 8) & 0xFF);
EXPECT_EQ(uuid_data[7], (kCopresenceServiceUuidMsb >> 0) & 0xFF);
EXPECT_EQ(uuid_data[8], (kCopresenceServiceUuidLsb >> 56) & 0xFF);
EXPECT_EQ(uuid_data[9], (kCopresenceServiceUuidLsb >> 48) & 0xFF);
EXPECT_EQ(uuid_data[10], (kCopresenceServiceUuidLsb >> 40) & 0xFF);
EXPECT_EQ(uuid_data[11], (kCopresenceServiceUuidLsb >> 32) & 0xFF);
EXPECT_EQ(uuid_data[12], (kCopresenceServiceUuidLsb >> 24) & 0xFF);
EXPECT_EQ(uuid_data[13], (kCopresenceServiceUuidLsb >> 16) & 0xFF);
EXPECT_EQ(uuid_data[14], (kCopresenceServiceUuidLsb >> 8) & 0xFF);
EXPECT_EQ(uuid_data[15], (kCopresenceServiceUuidLsb >> 0) & 0xFF);
EXPECT_THAT(uuid_str, StrCaseEq("0000FEF3-0000-1000-8000-00805F9B34FB"));
EXPECT_THAT(uuid.Get16BitAsString(), StrCaseEq("FEF3"));
}
TEST(UuidTest, ComparisonEqualWorksForMsbAndLsb) {
Uuid uuid_1(kCopresenceServiceUuidMsb, kCopresenceServiceUuidLsb);
Uuid uuid_2(kCopresenceServiceUuidMsb, kCopresenceServiceUuidLsb);
EXPECT_EQ(uuid_1, uuid_2);
Uuid uuid_3(1234, 5678);
Uuid uuid_4(8765, 4321);
EXPECT_FALSE(uuid_3 == uuid_4);
}
TEST(UuidTest, ComparisonEqualWorksForString) {
Uuid uuid_1("uuid");
Uuid uuid_2("uuid");
EXPECT_EQ(uuid_1, uuid_2);
Uuid uuid_3("foo");
Uuid uuid_4("loo");
EXPECT_FALSE(uuid_3 == uuid_4);
}
} // namespace
} // namespace nearby
} // namespace location