From 8e048f7be0f2c3b41f6aa7047252cfa54ff85272 Mon Sep 17 00:00:00 2001 From: edwinwu Date: Wed, 25 May 2022 06:35:23 -0700 Subject: [PATCH] [BLE Refactor] Uses Uuid class for those used in Uuid string-form in /medium layer. PiperOrigin-RevId: 450910238 --- Package.swift | 2 +- connections/implementation/mediums/BUILD | 5 +- connections/implementation/mediums/ble_v2.cc | 42 ++++--- connections/implementation/mediums/ble_v2.h | 1 + .../implementation/mediums/ble_v2/BUILD | 2 + .../mediums/ble_v2/ble_utils.cc | 18 ++- .../implementation/mediums/ble_v2/ble_utils.h | 8 +- .../mediums/ble_v2/ble_utils_test.cc | 33 +++-- .../ble_v2/discovered_peripheral_tracker.cc | 25 ++-- .../ble_v2/discovered_peripheral_tracker.h | 10 +- .../discovered_peripheral_tracker_test.cc | 73 ++++++----- .../mediums/bluetooth_classic.cc | 2 +- connections/implementation/mediums/uuid.cc | 87 ------------- connections/implementation/mediums/uuid.h | 57 --------- .../implementation/mediums/uuid_test.cc | 71 ----------- internal/platform/BUILD | 23 ++++ internal/platform/ble_v2.cc | 2 +- internal/platform/ble_v2.h | 10 +- internal/platform/ble_v2_test.cc | 59 ++++----- internal/platform/implementation/BUILD | 1 + internal/platform/implementation/ble_v2.h | 19 +-- internal/platform/implementation/g3/BUILD | 1 + internal/platform/implementation/g3/ble_v2.cc | 39 +++--- internal/platform/implementation/g3/ble_v2.h | 10 +- .../platform/implementation/windows/ble_v2.cc | 4 +- .../platform/implementation/windows/ble_v2.h | 2 +- .../implementation/windows/ble_v2_test.cc | 4 +- internal/platform/medium_environment.cc | 15 +-- internal/platform/medium_environment.h | 8 +- internal/platform/uuid.cc | 115 ++++++++++++++++++ internal/platform/uuid.h | 80 ++++++++++++ internal/platform/uuid_test.cc | 114 +++++++++++++++++ 32 files changed, 546 insertions(+), 396 deletions(-) delete mode 100644 connections/implementation/mediums/uuid.cc delete mode 100644 connections/implementation/mediums/uuid.h delete mode 100644 connections/implementation/mediums/uuid_test.cc create mode 100644 internal/platform/uuid.cc create mode 100644 internal/platform/uuid.h create mode 100644 internal/platform/uuid_test.cc diff --git a/Package.swift b/Package.swift index e4dac8c4..45fd27b3 100644 --- a/Package.swift +++ b/Package.swift @@ -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", diff --git a/connections/implementation/mediums/BUILD b/connections/implementation/mediums/BUILD index 1bf4f9cb..71d3faae 100644 --- a/connections/implementation/mediums/BUILD +++ b/connections/implementation/mediums/BUILD @@ -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", ], diff --git a/connections/implementation/mediums/ble_v2.cc b/connections/implementation/mediums/ble_v2.cc index a3cd1600..6cb4e463 100644 --- a/connections/implementation/mediums/ble_v2.cc +++ b/connections/implementation/mediums/ble_v2.cc @@ -19,6 +19,7 @@ #include #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 properties{ GattCharacteristic::Property::kRead}; + // NOLINTNEXTLINE(google3-legacy-absl-backports) + absl::optional 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 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 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( diff --git a/connections/implementation/mediums/ble_v2.h b/connections/implementation/mediums/ble_v2.h index f58e3105..65699db7 100644 --- a/connections/implementation/mediums/ble_v2.h +++ b/connections/implementation/mediums/ble_v2.h @@ -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" diff --git a/connections/implementation/mediums/ble_v2/BUILD b/connections/implementation/mediums/ble_v2/BUILD index 3a3e38c3..d0f98855 100644 --- a/connections/implementation/mediums/ble_v2/BUILD +++ b/connections/implementation/mediums/ble_v2/BUILD @@ -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", ], ) diff --git a/connections/implementation/mediums/ble_v2/ble_utils.cc b/connections/implementation/mediums/ble_v2/ble_utils.cc index fc383d77..32aa1cba 100644 --- a/connections/implementation/mediums/ble_v2/ble_utils.cc +++ b/connections/implementation/mediums/ble_v2/ble_utils.cc @@ -16,6 +16,8 @@ #include +#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 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 diff --git a/connections/implementation/mediums/ble_v2/ble_utils.h b/connections/implementation/mediums/ble_v2/ble_utils.h index b0cb17a4..eb900003 100644 --- a/connections/implementation/mediums/ble_v2/ble_utils.h +++ b/connections/implementation/mediums/ble_v2/ble_utils.h @@ -18,12 +18,13 @@ #include #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 GenerateAdvertisementUuid(int slot); } // namespace bleutils } // namespace mediums diff --git a/connections/implementation/mediums/ble_v2/ble_utils_test.cc b/connections/implementation/mediums/ble_v2/ble_utils_test.cc index 95950362..60650d89 100644 --- a/connections/implementation/mediums/ble_v2/ble_utils_test.cc +++ b/connections/implementation/mediums/ble_v2/ble_utils_test.cc @@ -16,6 +16,8 @@ #include +#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 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 diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc index 8501e4e0..4f247a75 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc @@ -20,6 +20,7 @@ #include #include +#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 extracted_uuids; + absl::flat_hash_map 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& - pair) { return pair.first == bleutils::kCopresenceServiceUuid; }); - std::string service_uuid; + [](const std::pair& 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& gatt_advertisement_bytes_list, - const std::string& service_uuid) { + const Uuid& service_uuid) { absl::flat_hash_map parsed_gatt_advertisements = ParseRawGattAdvertisements( gatt_advertisement_bytes_list, service_uuid); @@ -353,7 +355,7 @@ BleAdvertisementHeader DiscoveredPeripheralTracker::HandleRawGattAdvertisements( absl::flat_hash_map DiscoveredPeripheralTracker::ParseRawGattAdvertisements( const std::vector& gatt_advertisement_bytes_list, - const std::string& service_uuid) { + const Uuid& service_uuid) { absl::flat_hash_map 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=*/{}); } } diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h index 88127ce0..13e60d4f 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h @@ -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& 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 ParseRawGattAdvertisements( const std::vector& 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`. diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker_test.cc b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker_test.cc index 33c48940..05b92d52 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker_test.cc +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker_test.cc @@ -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); diff --git a/connections/implementation/mediums/bluetooth_classic.cc b/connections/implementation/mediums/bluetooth_classic.cc index 143ee363..fda79ce0 100644 --- a/connections/implementation/mediums/bluetooth_classic.cc +++ b/connections/implementation/mediums/bluetooth_classic.cc @@ -18,9 +18,9 @@ #include #include -#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 { diff --git a/connections/implementation/mediums/uuid.cc b/connections/implementation/mediums/uuid.cc deleted file mode 100644 index b1e58078..00000000 --- a/connections/implementation/mediums/uuid.cc +++ /dev/null @@ -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 -#include - -#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(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((most_sig_bits >> 56) & 0x0ff); - data_[1] = static_cast((most_sig_bits >> 48) & 0x0ff); - data_[2] = static_cast((most_sig_bits >> 40) & 0x0ff); - data_[3] = static_cast((most_sig_bits >> 32) & 0x0ff); - data_[4] = static_cast((most_sig_bits >> 24) & 0x0ff); - data_[5] = static_cast((most_sig_bits >> 16) & 0x0ff); - data_[6] = static_cast((most_sig_bits >> 8) & 0x0ff); - data_[7] = static_cast((most_sig_bits >> 0) & 0x0ff); - - data_[8] = static_cast((least_sig_bits >> 56) & 0x0ff); - data_[9] = static_cast((least_sig_bits >> 48) & 0x0ff); - data_[10] = static_cast((least_sig_bits >> 40) & 0x0ff); - data_[11] = static_cast((least_sig_bits >> 32) & 0x0ff); - data_[12] = static_cast((least_sig_bits >> 24) & 0x0ff); - data_[13] = static_cast((least_sig_bits >> 16) & 0x0ff); - data_[14] = static_cast((least_sig_bits >> 8) & 0x0ff); - data_[15] = static_cast((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 diff --git a/connections/implementation/mediums/uuid.h b/connections/implementation/mediums/uuid.h deleted file mode 100644 index fec9e071..00000000 --- a/connections/implementation/mediums/uuid.h +++ /dev/null @@ -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 -#include - -#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_ diff --git a/connections/implementation/mediums/uuid_test.cc b/connections/implementation/mediums/uuid_test.cc deleted file mode 100644 index b31fd451..00000000 --- a/connections/implementation/mediums/uuid_test.cc +++ /dev/null @@ -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 diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 3831c1bb..02870d32 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -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 diff --git a/internal/platform/ble_v2.cc b/internal/platform/ble_v2.cc index f8f95eca..acf0b4e3 100644 --- a/internal/platform/ble_v2.cc +++ b/internal/platform/ble_v2.cc @@ -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_); diff --git a/internal/platform/ble_v2.h b/internal/platform/ble_v2.h index 11846f36..368f16f4 100644 --- a/internal/platform/ble_v2.h +++ b/internal/platform/ble_v2.h @@ -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 CreateCharacteristic( - const std::string& service_uuid, const std::string& characteristic_uuid, + const Uuid& service_uuid, const Uuid& characteristic_uuid, const std::vector& permissions, const std::vector& @@ -191,14 +192,13 @@ class GattClient final { std::unique_ptr 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 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(); diff --git a/internal/platform/ble_v2_test.cc b/internal/platform/ble_v2_test.cc index a4a9100c..935a71ef 100644 --- a/internal/platform/ble_v2_test.cc +++ b/internal/platform/ble_v2_test.cc @@ -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 gatt_server = ble.StartGattServer(/*ServerGattConnectionCallback=*/{}); @@ -336,9 +334,8 @@ TEST_F(BleV2MediumTest, CanStartGattServer) { GattCharacteristic::Property::kRead}; // NOLINTNEXTLINE(google3-legacy-absl-backports) absl::optional 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 gatt_server = @@ -373,9 +371,8 @@ TEST_F(BleV2MediumTest, GattClientConnectToGattServerWorks) { // Add characteristic and its value. // NOLINTNEXTLINE(google3-legacy-absl-backports) absl::optional 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 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. diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index a7e9818e..3b2d92e9 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -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", diff --git a/internal/platform/implementation/ble_v2.h b/internal/platform/implementation/ble_v2.h index 5d387554..bc1da958 100644 --- a/internal/platform/implementation/ble_v2.h +++ b/internal/platform/implementation/ble_v2.h @@ -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 service_data; + absl::flat_hash_map 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 @@ -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 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 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 CreateCharacteristic( - absl::string_view service_uuid, absl::string_view characteristic_uuid, + const Uuid& service_uuid, const Uuid& characteristic_uuid, const std::vector& permissions, const std::vector& 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; diff --git a/internal/platform/implementation/g3/BUILD b/internal/platform/implementation/g3/BUILD index 0c1226a1..ea1486cc 100644 --- a/internal/platform/implementation/g3/BUILD +++ b/internal/platform/implementation/g3/BUILD @@ -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", diff --git a/internal/platform/implementation/g3/ble_v2.cc b/internal/platform/implementation/g3/ble_v2.cc index d48e7afa..8782dbc8 100644 --- a/internal/platform/implementation/g3/ble_v2.cc +++ b/internal/platform/implementation/g3/ble_v2.cc @@ -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 BleV2Medium::GattServer::CreateCharacteristic( - absl::string_view service_uuid, absl::string_view characteristic_uuid, + const Uuid& service_uuid, const Uuid& characteristic_uuid, const std::vector& permissions, const std::vector& 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 -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 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); } diff --git a/internal/platform/implementation/g3/ble_v2.h b/internal/platform/implementation/g3/ble_v2.h index f7753814..9def4a74 100644 --- a/internal/platform/implementation/g3/ble_v2.h +++ b/internal/platform/implementation/g3/ble_v2.h @@ -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 CreateCharacteristic( - absl::string_view service_uuid, absl::string_view characteristic_uuid, + const Uuid& service_uuid, const Uuid& characteristic_uuid, const std::vector& permissions, const std::vector& @@ -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 GetCharacteristic( - absl::string_view service_uuid, - absl::string_view characteristic_uuid) override; + const Uuid& service_uuid, const Uuid& characteristic_uuid) override; std::optional ReadCharacteristic( const api::ble_v2::GattCharacteristic& characteristic) override; diff --git a/internal/platform/implementation/windows/ble_v2.cc b/internal/platform/implementation/windows/ble_v2.cc index dd91a27f..3c149e03 100644 --- a/internal/platform/implementation/windows/ble_v2.cc +++ b/internal/platform/implementation/windows/ble_v2.cc @@ -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"; diff --git a/internal/platform/implementation/windows/ble_v2.h b/internal/platform/implementation/windows/ble_v2.h index bd19d304..7f429949 100644 --- a/internal/platform/implementation/windows/ble_v2.h +++ b/internal/platform/implementation/windows/ble_v2.h @@ -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_); diff --git a/internal/platform/implementation/windows/ble_v2_test.cc b/internal/platform/implementation/windows/ble_v2_test.cc index f4742efe..b24470e1 100644 --- a/internal/platform/implementation/windows/ble_v2_test.cc +++ b/internal/platform/implementation/windows/ble_v2_test.cc @@ -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 = diff --git a/internal/platform/medium_environment.cc b/internal/platform/medium_environment.cc index 6932b271..c443aa12 100644 --- a/internal/platform/medium_environment.cc +++ b/internal/platform/medium_environment.cc @@ -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; } diff --git a/internal/platform/medium_environment.h b/internal/platform/medium_environment.h index abeef98c..2b186986 100644 --- a/internal/platform/medium_environment.h +++ b/internal/platform/medium_environment.h @@ -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; }; diff --git a/internal/platform/uuid.cc b/internal/platform/uuid.cc new file mode 100644 index 00000000..36951a4c --- /dev/null +++ b/internal/platform/uuid.cc @@ -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 +#include +#include + +#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(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((most_sig_bits_ >> 40) & 0x0ff); + write_hex(sixteen_bit_string, absl::string_view(&data, 1)); + data = static_cast((most_sig_bits_ >> 32) & 0x0ff); + write_hex(sixteen_bit_string, absl::string_view(&data, 1)); + + return sixteen_bit_string.str(); +} + +std::array Uuid::data() const { + std::array 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& 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 diff --git a/internal/platform/uuid.h b/internal/platform/uuid.h new file mode 100644 index 00000000..17f1fe5a --- /dev/null +++ b/internal/platform/uuid.h @@ -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 +#include + +#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 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 + 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& 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_ diff --git a/internal/platform/uuid_test.cc b/internal/platform/uuid_test.cc new file mode 100644 index 00000000..7155b195 --- /dev/null +++ b/internal/platform/uuid_test.cc @@ -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 + +#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 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 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