From 0901aec6e2aaffb40f2522b169a4c38d4a0883a9 Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Wed, 10 May 2023 15:39:24 -0700 Subject: [PATCH] Add BleMedium::GetRemotePeripheral Added: nearby::api::ble_v2::BlePeripheral::GetUniqueId() nearby::api::ble_v2::BleMedium::GetRemotePeripheral(...) Moved BlePeripheral implementation from bluetooth_adapter_* to ble_v2.* Added G3 (test) implementation for the new methods. PiperOrigin-RevId: 531023568 --- .../implementation/mediums/ble_v2/BUILD | 1 + .../ble_v2/discovered_peripheral_callback.h | 3 +- .../ble_v2/discovered_peripheral_tracker.cc | 3 +- .../ble_v2/discovered_peripheral_tracker.h | 5 - .../discovered_peripheral_tracker_test.cc | 42 +++--- .../implementation/mediums/ble_v2_test.cc | 14 +- fastpair/handshake/BUILD | 1 + ...fast_pair_gatt_service_client_impl_test.cc | 48 ++++--- .../fast_pair_handshake_impl_test.cc | 39 +++-- .../fast_pair_handshake_lookup_test.cc | 31 +++- fastpair/internal/mediums/ble_v2.cc | 19 +-- internal/platform/ble_v2.cc | 67 ++++++--- internal/platform/ble_v2.h | 73 ++++++++-- internal/platform/ble_v2_test.cc | 135 +++++++++++++++--- internal/platform/bluetooth_adapter.h | 58 -------- internal/platform/bluetooth_adapter_test.cc | 96 ------------- internal/platform/implementation/BUILD | 1 + internal/platform/implementation/apple/ble.h | 10 ++ .../implementation/apple/bluetooth_adapter.h | 13 +- internal/platform/implementation/ble_v2.h | 20 ++- internal/platform/implementation/g3/ble_v2.cc | 75 +++++++++- internal/platform/implementation/g3/ble_v2.h | 25 +++- .../implementation/g3/bluetooth_adapter.cc | 10 +- .../implementation/g3/bluetooth_adapter.h | 22 +-- .../platform/implementation/windows/ble_v2.cc | 30 ++++ .../platform/implementation/windows/ble_v2.h | 10 ++ .../windows/ble_v2_peripheral.h | 6 + internal/platform/medium_environment.cc | 88 +++++++++--- internal/platform/medium_environment.h | 6 +- 29 files changed, 597 insertions(+), 354 deletions(-) diff --git a/connections/implementation/mediums/ble_v2/BUILD b/connections/implementation/mediums/ble_v2/BUILD index 0aa1698f..69d727eb 100644 --- a/connections/implementation/mediums/ble_v2/BUILD +++ b/connections/implementation/mediums/ble_v2/BUILD @@ -77,6 +77,7 @@ cc_test( ":ble_v2", "//internal/platform:base", "//internal/platform:comm", + "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # buildcleaner: keep "//proto/mediums:ble_frames_cc_proto", diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_callback.h b/connections/implementation/mediums/ble_v2/discovered_peripheral_callback.h index 07a642e2..5a190282 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_callback.h +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_callback.h @@ -18,8 +18,7 @@ #include #include -#include "connections/listeners.h" -#include "internal/platform/bluetooth_adapter.h" +#include "internal/platform/ble_v2.h" #include "internal/platform/byte_array.h" namespace nearby { diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc index 6340640f..2a5384e9 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.cc @@ -26,7 +26,7 @@ #include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h" #include "connections/implementation/mediums/ble_v2/ble_utils.h" #include "connections/implementation/mediums/ble_v2/bloom_filter.h" -#include "internal/platform/bluetooth_adapter.h" +#include "internal/platform/ble_v2.h" #include "internal/platform/mutex_lock.h" namespace nearby { @@ -339,7 +339,6 @@ BleAdvertisementHeader DiscoveredPeripheralTracker::HandleRawGattAdvertisements( GattAdvertisementInfo gatt_advertisement_info = { .service_id = service_id, .advertisement_header = new_advertisement_header, - .mac_address = peripheral.GetAddress(), .peripheral = peripheral}; gatt_advertisement_infos_.insert_or_assign( gatt_advertisement, std::move(gatt_advertisement_info)); diff --git a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h index 575561fe..c0ae6a01 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h @@ -127,11 +127,6 @@ class DiscoveredPeripheralTracker { // gatt_advertisements_. BleAdvertisementHeader advertisement_header; - // Used when we need to make a socket connection based off of the GATT - // advertisement alone. Entries are modified every time a GATT - // advertisement's advertisement header is seen. - std::string mac_address; - // A proxy BlePeripheral for found/lost disovery callback. BleV2Peripheral peripheral; }; 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 f5acd2bb..8379b4b0 100644 --- a/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker_test.cc +++ b/connections/implementation/mediums/ble_v2/discovered_peripheral_tracker_test.cc @@ -20,8 +20,9 @@ #include "gtest/gtest.h" #include "connections/implementation/mediums/ble_v2/ble_utils.h" #include "connections/implementation/mediums/ble_v2/bloom_filter.h" -#include "internal/platform/bluetooth_adapter.h" +#include "internal/platform/ble_v2.h" #include "internal/platform/count_down_latch.h" +#include "internal/platform/medium_environment.h" #include "internal/platform/mutex.h" #include "internal/platform/mutex_lock.h" @@ -35,7 +36,6 @@ constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); 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"; constexpr absl::string_view kData = "\x04\x02\x00"; constexpr absl::string_view kData2 = "\x07\x00\x07"; constexpr absl::string_view kDeviceToken = "\x04\x20"; @@ -101,26 +101,21 @@ ByteArray GenerateRandomAdvertisementHash() { return random_advertisement_hash; } -// A stub BlePeripheral implementation. -class BlePeripheralStub : public api::ble_v2::BlePeripheral { - public: - explicit BlePeripheralStub(absl::string_view mac_address) { - mac_address_ = std::string(mac_address); - } - - std::string GetAddress() const override { return mac_address_; } - - private: - std::string mac_address_; -}; - class DiscoveredPeripheralTrackerTest : public testing::Test { public: - void SetUp() override {} + void SetUp() override { + MediumEnvironment::Instance().Start(); + adapter_peripheral_ = std::make_unique(); + adapter_central_ = std::make_unique(); + ble_peripheral_ = std::make_unique(*adapter_peripheral_); + ble_central_ = std::make_unique(*adapter_central_); + } - BleV2Peripheral CreateBlePeripheral(absl::string_view mac_address) { - ble_peripheral_ = std::make_unique(mac_address); - return BleV2Peripheral(ble_peripheral_.get()); + void TearDown() override { MediumEnvironment::Instance().Stop(); } + + BleV2Peripheral CreateBlePeripheral() { + return ble_central_->GetRemotePeripheral( + adapter_peripheral_->GetMacAddress()); } // Simulates to see a fast advertisement. @@ -128,7 +123,7 @@ class DiscoveredPeripheralTrackerTest : public testing::Test { const api::ble_v2::BleAdvertisementData& advertisement_data, const std::vector& advertisement_bytes_list, CountDownLatch& fetch_latch) { - BleV2Peripheral peripheral = CreateBlePeripheral(kMacAddress1); + BleV2Peripheral peripheral = CreateBlePeripheral(); discovered_peripheral_tracker_.ProcessFoundBleAdvertisement( peripheral, advertisement_data, @@ -140,7 +135,7 @@ class DiscoveredPeripheralTrackerTest : public testing::Test { const api::ble_v2::BleAdvertisementData& advertisement_data, const std::vector& advertisement_bytes_list, CountDownLatch& fetch_latch) { - BleV2Peripheral peripheral = CreateBlePeripheral(kMacAddress1); + BleV2Peripheral peripheral = CreateBlePeripheral(); discovered_peripheral_tracker_.ProcessFoundBleAdvertisement( peripheral, advertisement_data, @@ -177,9 +172,12 @@ class DiscoveredPeripheralTrackerTest : public testing::Test { }; } + std::unique_ptr adapter_peripheral_; + std::unique_ptr adapter_central_; + std::unique_ptr ble_peripheral_; + std::unique_ptr ble_central_; mutable Mutex mutex_; int fetch_count_ ABSL_GUARDED_BY(mutex_) = 0; - std::unique_ptr ble_peripheral_; DiscoveredPeripheralTracker discovered_peripheral_tracker_; }; diff --git a/connections/implementation/mediums/ble_v2_test.cc b/connections/implementation/mediums/ble_v2_test.cc index e902408b..484d1471 100644 --- a/connections/implementation/mediums/ble_v2_test.cc +++ b/connections/implementation/mediums/ble_v2_test.cc @@ -100,10 +100,9 @@ TEST_P(BleV2Test, CanConnect) { const ByteArray& advertisement_bytes, bool fast_advertisement) { discovered_peripheral = peripheral; - NEARBY_LOG( - INFO, - "Discovered peripheral=%p [impl=%p], fast advertisement=%d", - &peripheral, &peripheral.GetImpl(), fast_advertisement); + NEARBY_LOG(INFO, + "Discovered peripheral=%p, fast advertisement=%d", + &peripheral, fast_advertisement); discovered_latch.CountDown(); }, }); @@ -163,10 +162,9 @@ TEST_P(BleV2Test, CanCancelConnect) { const ByteArray& advertisement_bytes, bool fast_advertisement) { discovered_peripheral = peripheral; - NEARBY_LOG( - INFO, - "Discovered peripheral=%p [impl=%p], fast advertisement=%d", - &peripheral, &peripheral.GetImpl(), fast_advertisement); + NEARBY_LOG(INFO, + "Discovered peripheral=%p, fast advertisement=%d", + &peripheral, fast_advertisement); discovered_latch.CountDown(); }, }); diff --git a/fastpair/handshake/BUILD b/fastpair/handshake/BUILD index 40de6d37..2b5fcdbe 100644 --- a/fastpair/handshake/BUILD +++ b/fastpair/handshake/BUILD @@ -140,6 +140,7 @@ cc_test( ":handshake", "//fastpair/common", "//fastpair/server_access:test_support", + "//internal/platform:base", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep diff --git a/fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc b/fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc index 8bd35736..f543671d 100644 --- a/fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc +++ b/fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc @@ -49,7 +49,6 @@ using WriteType = nearby::api::ble_v2::GattClient::WriteType; constexpr absl::Duration kGattOperationTimeout = absl::Seconds(15); constexpr absl::string_view kMetadataId("test_id"); -constexpr absl::string_view kProviderAddress("11:22:33:44:55:66"); constexpr absl::string_view kSeekerAddress("AA:BB:CC:DD:EE:00"); constexpr Uuid kFastPairServiceUuid(0x0000FE2C00001000, 0x800000805F9B34FB); constexpr Uuid kKeyBasedCharacteristicUuidV2(0xFE2C123483664814, @@ -76,6 +75,14 @@ constexpr std::array kPublicKey = { 0x1D, 0x01, 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, 0x1D}; } // namespace +class MediumEnvironmentStarter { + public: + MediumEnvironmentStarter() { + MediumEnvironment::Instance().Start({.use_simulated_clock = true}); + } + ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } +}; + class FastPairGattServiceClientTest : public testing::Test { public: FastPairGattServiceClientTest() { @@ -84,10 +91,9 @@ class FastPairGattServiceClientTest : public testing::Test { } void SetUp() override { - env_.Start({.use_simulated_clock = true}); - BluetoothAdapter adapter; - BleV2Medium ble(adapter); - gatt_server_ = ble.StartGattServer(/*ServerGattConnectionCallback=*/{}); + gatt_server_ = + provider_ble_.StartGattServer(/*ServerGattConnectionCallback=*/{}); + provider_address_ = provider_adapter_.GetMacAddress(); } void TearDown() override { @@ -98,7 +104,6 @@ class FastPairGattServiceClientTest : public testing::Test { gatt_client_.reset(); gatt_server_->Stop(); gatt_server_.reset(); - env_.Stop(); } void InsertCorrectGattCharacteristics() { @@ -164,7 +169,7 @@ class FastPairGattServiceClientTest : public testing::Test { } void InitializeFastPairGattServiceClient() { - FastPairDevice device(kMetadataId, kProviderAddress, + FastPairDevice device(kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); Mediums mediums; gatt_client_ = @@ -176,23 +181,27 @@ class FastPairGattServiceClientTest : public testing::Test { } void RemoveDiscoveredKeyBasedCharacteristic() { - env_.EraseBleV2MediumGattCharacteristicsForDiscovery( - key_based_characteristic_.value()); + MediumEnvironment::Instance() + .EraseBleV2MediumGattCharacteristicsForDiscovery( + key_based_characteristic_.value()); } void RemoveDiscoveredPasskeyCharacteristic() { - env_.EraseBleV2MediumGattCharacteristicsForDiscovery( - passkey_characteristic_.value()); + MediumEnvironment::Instance() + .EraseBleV2MediumGattCharacteristicsForDiscovery( + passkey_characteristic_.value()); } bool UnsubceibeKeyBasedCharacteristic() { - return env_.SetBleV2MediumGattCharacteristicSubscription( - key_based_characteristic_.value(), false, {}); + return MediumEnvironment::Instance() + .SetBleV2MediumGattCharacteristicSubscription( + key_based_characteristic_.value(), false, {}); } bool UnsubceibePasskeyCharacteristic() { - return env_.SetBleV2MediumGattCharacteristicSubscription( - passkey_characteristic_.value(), false, {}); + return MediumEnvironment::Instance() + .SetBleV2MediumGattCharacteristicSubscription( + passkey_characteristic_.value(), false, {}); } std::optional GetInitializedCallbackResult() { @@ -208,7 +217,7 @@ class FastPairGattServiceClientTest : public testing::Test { void WriteRequestToKeyBased() { gatt_client_->WriteRequestAsync( - kMessageType, kFlags, kProviderAddress, /* Seeker Address*/ "", + kMessageType, kFlags, provider_address_, /* Seeker Address*/ "", *fast_pair_data_encryptor_, [&](absl::string_view response, std::optional failure) { WriteTestCallback(response, failure); @@ -236,10 +245,13 @@ class FastPairGattServiceClientTest : public testing::Test { } protected: - MediumEnvironment& env_{MediumEnvironment::Instance()}; + MediumEnvironmentStarter env_; + BluetoothAdapter provider_adapter_; + BleV2Medium provider_ble_{provider_adapter_}; std::unique_ptr internal_gatt_client_; std::unique_ptr gatt_client_; std::unique_ptr gatt_server_; + std::string provider_address_; std::unique_ptr fast_pair_data_encryptor_; private: @@ -322,7 +334,7 @@ TEST_F(FastPairGattServiceClientTest, KeyBasedPairingResponseTimeout) { InitializeFastPairGattServiceClient(); CountDownLatch latch(1); gatt_client_->WriteRequestAsync( - kMessageType, kFlags, kProviderAddress, kSeekerAddress, + kMessageType, kFlags, provider_address_, kSeekerAddress, *fast_pair_data_encryptor_, [&](absl::string_view response, std::optional failure) { WriteTestCallback(response, failure); diff --git a/fastpair/handshake/fast_pair_handshake_impl_test.cc b/fastpair/handshake/fast_pair_handshake_impl_test.cc index d3511542..d08810eb 100644 --- a/fastpair/handshake/fast_pair_handshake_impl_test.cc +++ b/fastpair/handshake/fast_pair_handshake_impl_test.cc @@ -31,6 +31,7 @@ #include "fastpair/common/protocol.h" #include "fastpair/handshake/fast_pair_gatt_service_client_impl.h" #include "fastpair/server_access/fake_fast_pair_repository.h" +#include "internal/platform/bluetooth_utils.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/medium_environment.h" @@ -43,8 +44,6 @@ using Permission = nearby::api::ble_v2::GattCharacteristic::Permission; using ::nearby::api::ble_v2::GattCharacteristic; constexpr absl::string_view kMetadataId("718c17"); -constexpr absl::string_view kProviderAddress("11:22:33:44:55:66"); -constexpr absl::string_view kPublicAddress("5E:3F:45:61:C3:32"); constexpr absl::string_view kKeyBasedResponse("keybasedresponse"); constexpr absl::string_view kWrongResponse("wrongresponse"); constexpr absl::string_view kPublicAntiSpoof = @@ -67,14 +66,20 @@ constexpr absl::string_view kPasskeyharacteristicAdvertisementByte = constexpr absl::Duration kGattOperationTimeout = absl::Seconds(15); } // namespace +class MediumEnvironmentStarter { + public: + MediumEnvironmentStarter() { + MediumEnvironment::Instance().Start({.use_simulated_clock = true}); + } + ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } +}; + class FastPairHandshakeImplTest : public testing::Test { public: void SetUp() override { repository_ = std::make_unique(); - env_.Start({.use_simulated_clock = true}); - BluetoothAdapter adapter; - BleV2Medium ble(adapter); - gatt_server_ = ble.StartGattServer(/*ServerGattConnectionCallback=*/{}); + gatt_server_ = ble_.StartGattServer(/*ServerGattConnectionCallback=*/{}); + provider_address_ = adapter_.GetMacAddress(); } void TearDown() override { @@ -84,7 +89,6 @@ class FastPairHandshakeImplTest : public testing::Test { gatt_server_->Stop(); gatt_server_.reset(); handshake_.reset(); - env_.Stop(); } void InsertCorrectGattCharacteristics() { @@ -144,10 +148,13 @@ class FastPairHandshakeImplTest : public testing::Test { } protected: + MediumEnvironmentStarter env_; std::unique_ptr handshake_; + BluetoothAdapter adapter_; + BleV2Medium ble_{adapter_}; + std::string provider_address_; private: - MediumEnvironment& env_{MediumEnvironment::Instance()}; std::unique_ptr gatt_server_; std::optional key_based_characteristic_; std::optional passkey_characteristic_; @@ -159,7 +166,7 @@ class FastPairHandshakeImplTest : public testing::Test { TEST_F(FastPairHandshakeImplTest, Success) { SetUpFastPairRepository(); InsertCorrectGattCharacteristics(); - FastPairDevice device(kMetadataId, kProviderAddress, + FastPairDevice device(kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); Mediums mediums; @@ -167,7 +174,9 @@ TEST_F(FastPairHandshakeImplTest, Success) { device, mediums, [&](FastPairDevice& callback_device, std::optional failure) { EXPECT_EQ(&device, &callback_device); - EXPECT_EQ(device.public_address(), kPublicAddress); + // TODO(jsobczak): G3 provider address should be in human readable + // format. + // EXPECT_EQ(device.public_address(), provider_address_); EXPECT_FALSE(failure.has_value()); latch.CountDown(); }); @@ -178,7 +187,7 @@ TEST_F(FastPairHandshakeImplTest, Success) { TEST_F(FastPairHandshakeImplTest, GattError) { SetUpFastPairRepository(); - FastPairDevice device(kMetadataId, kProviderAddress, + FastPairDevice device(kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); Mediums mediums; @@ -196,7 +205,7 @@ TEST_F(FastPairHandshakeImplTest, GattError) { TEST_F(FastPairHandshakeImplTest, DataEncryptorCreateError) { FailedFastPairRepository(); InsertCorrectGattCharacteristics(); - FastPairDevice device(kMetadataId, kProviderAddress, + FastPairDevice device(kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); Mediums mediums; @@ -214,7 +223,7 @@ TEST_F(FastPairHandshakeImplTest, DataEncryptorCreateError) { TEST_F(FastPairHandshakeImplTest, WriteResponseError) { SetUpFastPairRepository(); InsertCorrectGattCharacteristics(); - FastPairDevice device(kMetadataId, kProviderAddress, + FastPairDevice device(kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); Mediums mediums; @@ -234,7 +243,7 @@ TEST_F(FastPairHandshakeImplTest, WriteResponseError) { TEST_F(FastPairHandshakeImplTest, WriteResponseWrongSize) { SetUpFastPairRepository(); InsertCorrectGattCharacteristics(); - FastPairDevice device(kMetadataId, kProviderAddress, + FastPairDevice device(kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); Mediums mediums; @@ -254,7 +263,7 @@ TEST_F(FastPairHandshakeImplTest, WriteResponseWrongSize) { TEST_F(FastPairHandshakeImplTest, ParseResponseError) { SetUpFastPairRepository(); InsertCorrectGattCharacteristics(); - FastPairDevice device(kMetadataId, kProviderAddress, + FastPairDevice device(kMetadataId, provider_address_, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); Mediums mediums; diff --git a/fastpair/handshake/fast_pair_handshake_lookup_test.cc b/fastpair/handshake/fast_pair_handshake_lookup_test.cc index e2ea8289..62ad298b 100644 --- a/fastpair/handshake/fast_pair_handshake_lookup_test.cc +++ b/fastpair/handshake/fast_pair_handshake_lookup_test.cc @@ -16,6 +16,7 @@ #include #include +#include #include "gtest/gtest.h" #include "absl/strings/string_view.h" @@ -24,17 +25,25 @@ #include "fastpair/common/protocol.h" #include "fastpair/internal/mediums/mediums.h" #include "internal/platform/count_down_latch.h" +#include "internal/platform/medium_environment.h" namespace nearby { namespace fastpair { namespace { constexpr absl::string_view kValidModelId("718c17"); -constexpr absl::string_view kBLEAddress("ble_address"); constexpr absl::string_view kPubliceAddress("public_address"); + +class MediumEnvironmentStarter { + public: + MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); } + ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } +}; + class FastPairHandshakeLookupTest : public ::testing::Test { public: FastPairHandshakeLookupTest() { - device_ = new FastPairDevice(kValidModelId, kBLEAddress, + provider_address_ = adapter_.GetMacAddress(); + device_ = new FastPairDevice(kValidModelId, provider_address_, Protocol::kFastPairInitialPairing); device_->set_public_address(kPubliceAddress); } @@ -54,12 +63,18 @@ class FastPairHandshakeLookupTest : public ::testing::Test { latch.Await(); } + protected: + MediumEnvironmentStarter env_; + BluetoothAdapter adapter_; + BleV2Medium ble_{adapter_}; + std::string provider_address_; + FastPairDevice* device_ = nullptr; }; TEST_F(FastPairHandshakeLookupTest, CreateFastPairHandshkeInstanceForDevice) { EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(kBLEAddress)); + EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(provider_address_)); EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(kPubliceAddress)); CreateFastPairHandshkeInstanceForDevice(*device_); @@ -67,7 +82,7 @@ TEST_F(FastPairHandshakeLookupTest, CreateFastPairHandshkeInstanceForDevice) { // GetFastPairHandshakeWithDevicePtr EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(device_)); // GetFastPairHandshakeWithBLEAddress - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(kBLEAddress)); + EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(provider_address_)); // GetFastPairHandshakeWithPublicAddress EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(kPubliceAddress)); // GetFastPairHandshakeWithDevicePtr @@ -84,7 +99,8 @@ TEST_F(FastPairHandshakeLookupTest, EraseFastPairHandshakeWithDevicePtr) { EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Erase(device_)); // Already Erased EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_)); - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(kBLEAddress)); + EXPECT_FALSE( + FastPairHandshakeLookup::GetInstance()->Erase(provider_address_)); EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(kPubliceAddress)); } @@ -95,7 +111,7 @@ TEST_F(FastPairHandshakeLookupTest, EraseFastPairHandshakeWithBLEAddress) { // Erase Wrong Address EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase("")); - EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Erase(kBLEAddress)); + EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Erase(provider_address_)); // Already Erased EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_)); EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(device_)); @@ -111,7 +127,8 @@ TEST_F(FastPairHandshakeLookupTest, EraseFastPairHandshakeWithPublicAddress) { // Already Erased EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_)); EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(device_)); - EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(kBLEAddress)); + EXPECT_FALSE( + FastPairHandshakeLookup::GetInstance()->Erase(provider_address_)); } TEST_F(FastPairHandshakeLookupTest, ClearAllFastPairHandshakeInstances) { diff --git a/fastpair/internal/mediums/ble_v2.cc b/fastpair/internal/mediums/ble_v2.cc index 0fdc0c14..9d156596 100644 --- a/fastpair/internal/mediums/ble_v2.cc +++ b/fastpair/internal/mediums/ble_v2.cc @@ -21,20 +21,6 @@ namespace nearby { namespace fastpair { -namespace { -// A stub BlePeripheral implementation. -class BlePeripheralStub : public api::ble_v2::BlePeripheral { - public: - explicit BlePeripheralStub(absl::string_view ble_address) { - ble_address_ = std::string(ble_address); - } - - std::string GetAddress() const override { return ble_address_; } - - private: - std::string ble_address_; -}; -} // namespace BleV2::BleV2(BluetoothRadio& radio) : radio_(radio) {} @@ -61,8 +47,9 @@ std::unique_ptr BleV2::ConnectToGattServer( << "Can't connect to GattServer because BleV2 isn't available."; return nullptr; } - auto v2_peripheral = std::make_unique(ble_address); - return medium_.ConnectToGattServer(BleV2Peripheral(v2_peripheral.get()), + + BleV2Peripheral v2_peripheral = medium_.GetRemotePeripheral(ble_address); + return medium_.ConnectToGattServer(v2_peripheral, api::ble_v2::TxPowerLevel::kUnknown, {}); } } // namespace fastpair diff --git a/internal/platform/ble_v2.cc b/internal/platform/ble_v2.cc index d6b5bff5..7d0a4ceb 100644 --- a/internal/platform/ble_v2.cc +++ b/internal/platform/ble_v2.cc @@ -19,7 +19,6 @@ #include #include "absl/status/status.h" -#include "internal/platform/bluetooth_adapter.h" #include "internal/platform/implementation/ble_v2.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" @@ -94,7 +93,7 @@ bool BleV2Medium::StartScanning(const Uuid& service_uuid, peripherals_.insert(&peripheral); } - BleV2Peripheral proxy(&peripheral); + BleV2Peripheral proxy(*this, peripheral); NEARBY_LOGS(INFO) << "New peripheral imp=" << &peripheral << ", callback the proxy peripheral=" << &proxy; @@ -240,34 +239,70 @@ std::unique_ptr BleV2Medium::ConnectToGattServer( client_gatt_connection_callback_ = std::move(callback); } - std::unique_ptr api_gatt_client = - impl_->ConnectToGattServer( - peripheral.GetImpl(), tx_power_level, - { - .disconnected_cb = - [this]() { - MutexLock lock(&mutex_); - client_gatt_connection_callback_.disconnected_cb(); - }, - }); + std::unique_ptr api_gatt_client; + peripheral.GetImpl([&](api::ble_v2::BlePeripheral& device) { + api_gatt_client = impl_->ConnectToGattServer( + device, tx_power_level, + { + .disconnected_cb = + [this]() { + MutexLock lock(&mutex_); + client_gatt_connection_callback_.disconnected_cb(); + }, + }); + }); + return std::make_unique(std::move(api_gatt_client)); } BleV2ServerSocket BleV2Medium::OpenServerSocket(const std::string& service_id) { - return BleV2ServerSocket(impl_->OpenServerSocket(service_id)); + return BleV2ServerSocket(*this, impl_->OpenServerSocket(service_id)); } BleV2Socket BleV2Medium::Connect(const std::string& service_id, TxPowerLevel tx_power_level, const BleV2Peripheral& peripheral, CancellationFlag* cancellation_flag) { - return BleV2Socket(impl_->Connect(service_id, tx_power_level, - /*mutated=*/peripheral.GetImpl(), - cancellation_flag)); + BleV2Socket socket; + peripheral.GetImpl([&](api::ble_v2::BlePeripheral& device) { + socket = BleV2Socket(peripheral, impl_->Connect(service_id, tx_power_level, + device, cancellation_flag)); + }); + return socket; } bool BleV2Medium::IsExtendedAdvertisementsAvailable() { return impl_->IsExtendedAdvertisementsAvailable(); } +BleV2Peripheral BleV2Medium::GetRemotePeripheral( + absl::string_view mac_address) { + BleV2Peripheral peripheral; + impl_->GetRemotePeripheral(mac_address, + [&](api::ble_v2::BlePeripheral& device) { + peripheral = BleV2Peripheral(*this, device); + }); + return peripheral; +} + +absl::optional BleV2Peripheral::GetAddress() const { + absl::optional address; + GetImpl([&](api::ble_v2::BlePeripheral& device) { + address = device.GetAddress(); + }); + return address; +} + +bool BleV2Peripheral::IsValid() const { + return GetImpl([&](api::ble_v2::BlePeripheral& device) {}); +} + +bool BleV2Peripheral::GetImpl( + absl::AnyInvocable callback) + const { + if (!unique_id_.has_value()) return false; + return medium_->GetImpl()->GetRemotePeripheral(unique_id_.value(), + std::move(callback)); +} + } // namespace nearby diff --git a/internal/platform/ble_v2.h b/internal/platform/ble_v2.h index dfdcb1ef..8c8351d6 100644 --- a/internal/platform/ble_v2.h +++ b/internal/platform/ble_v2.h @@ -16,6 +16,7 @@ #define PLATFORM_PUBLIC_BLE_V2_H_ #include +#include #include #include #include @@ -33,13 +34,59 @@ namespace nearby { +class BleV2Medium; + +// Opaque wrapper over a BLE peripheral. Must contain enough data about a +// particular BLE peripheral to connect to its GATT server. +class BleV2Peripheral final { + public: + using ImplCallback = + absl::AnyInvocable; + BleV2Peripheral() = default; + BleV2Peripheral(BleV2Medium& medium, api::ble_v2::BlePeripheral& impl) + : medium_(&medium), unique_id_(impl.GetUniqueId()) {} + BleV2Peripheral(const BleV2Peripheral&) = default; + BleV2Peripheral& operator=(const BleV2Peripheral&) = default; + BleV2Peripheral(BleV2Peripheral&& other) = default; + + BleV2Peripheral& operator=(BleV2Peripheral&& other) = default; + + // NOLINTNEXTLINE(google3-legacy-absl-backports) + absl::optional GetAddress() const; + ByteArray GetId() const { return id_; } + void SetId(const ByteArray& id) { id_ = id; } + + int GetPsm() const { return psm_; } + void SetPsm(int psm) { psm_ = psm; } + + bool IsValid() const; + explicit operator bool() const { return IsValid(); } + + bool GetImpl(ImplCallback callback) const; + + private: + BleV2Medium* medium_ = nullptr; + std::optional unique_id_; + + // A unique identifier for this peripheral. It is the BLE advertisement bytes + // it was found on. + ByteArray id_ = {}; + + // The psm (protocol service multiplexer) value is used for create data + // connection on L2CAP socket. It only exists when remote device supports + // L2CAP socket feature. + int psm_ = 0; +}; + // Container of operations that can be performed over the BLE GATT client // socket. // This class is copyable but not moveable. class BleV2Socket final { public: BleV2Socket() = default; - explicit BleV2Socket(std::unique_ptr socket) { + BleV2Socket(BleV2Peripheral peripheral, + std::unique_ptr socket) + : peripheral_(peripheral) { state_->socket = std::move(socket); } BleV2Socket(const BleV2Socket&) = default; @@ -74,9 +121,7 @@ class BleV2Socket final { } // Returns BlePeripheral object which wraps a valid BlePeripheral pointer. - BleV2Peripheral GetRemotePeripheral() { - return BleV2Peripheral(state_->socket->GetRemotePeripheral()); - } + BleV2Peripheral& GetRemotePeripheral() { return peripheral_; } // Returns true if a socket is usable. If this method returns false, // it is not safe to call any other method. @@ -102,6 +147,7 @@ class BleV2Socket final { absl::AnyInvocable close_notifier; }; std::shared_ptr state_ = std::make_shared(); + BleV2Peripheral peripheral_; }; // Container of operations that can be performed over the BLE GATT server @@ -109,9 +155,9 @@ class BleV2Socket final { // This class is copyable but not moveable. class BleV2ServerSocket final { public: - explicit BleV2ServerSocket( - std::unique_ptr socket) - : impl_(std::move(socket)) {} + BleV2ServerSocket(BleV2Medium& medium, + std::unique_ptr socket) + : medium_(medium), impl_(std::move(socket)) {} BleV2ServerSocket(const BleV2ServerSocket&) = default; BleV2ServerSocket& operator=(const BleV2ServerSocket&) = default; @@ -125,11 +171,17 @@ class BleV2ServerSocket final { // ServerSocket has to be closed by caller. BleV2Socket Accept() { std::unique_ptr socket = impl_->Accept(); + BleV2Peripheral peripheral; if (!socket) { NEARBY_LOGS(INFO) << "BleServerSocket Accept() failed on server socket: " << this; + } else { + auto* platform_peripheral = socket->GetRemotePeripheral(); + if (platform_peripheral != nullptr) { + peripheral = BleV2Peripheral(medium_, *platform_peripheral); + } } - return BleV2Socket(std::move(socket)); + return BleV2Socket(peripheral, std::move(socket)); } // Returns Exception::kIo on error, Exception::kSuccess otherwise. @@ -142,6 +194,7 @@ class BleV2ServerSocket final { api::ble_v2::BleServerSocket& GetImpl() { return *impl_; } private: + BleV2Medium& medium_; std::shared_ptr impl_; }; @@ -381,6 +434,10 @@ class BleV2Medium final { bool IsValid() const { return impl_ != nullptr; } + // Returns a `BleV2Peripheral` with given mac address. `mac_address` is in + // canonical format. + BleV2Peripheral GetRemotePeripheral(absl::string_view mac_address); + api::ble_v2::BleMedium* GetImpl() const { return impl_.get(); } BluetoothAdapter& GetAdapter() { return adapter_; } diff --git a/internal/platform/ble_v2_test.cc b/internal/platform/ble_v2_test.cc index 009e3e24..37be0d5e 100644 --- a/internal/platform/ble_v2_test.cc +++ b/internal/platform/ble_v2_test.cc @@ -53,20 +53,7 @@ constexpr absl::string_view kAdvertisementHeaderString = "\x0x\x0y\x0z"; constexpr TxPowerLevel kTxPowerLevel(TxPowerLevel::kHigh); constexpr absl::string_view kServiceIDA{ "com.google.location.nearby.apps.test.a"}; -constexpr absl::string_view kDeviceMacAddress{"AA:BB:CC:DD:EE:FF"}; - -// A stub BlePeripheral implementation. -class BlePeripheralStub : public api::ble_v2::BlePeripheral { - public: - explicit BlePeripheralStub(absl::string_view mac_address) { - mac_address_ = std::string(mac_address); - } - - std::string GetAddress() const override { return mac_address_; } - - private: - std::string mac_address_; -}; +constexpr absl::string_view kId = "AB12"; class BleV2MediumTest : public ::testing::TestWithParam { protected: @@ -557,9 +544,8 @@ TEST_F(BleV2MediumTest, GattClientConnectToGattServerWorks) { gatt_server->UpdateCharacteristic(*server_characteristic, server_value)); // Start GattClient - auto ble_peripheral = std::make_unique(kDeviceMacAddress); std::unique_ptr gatt_client = ble_b.ConnectToGattServer( - BleV2Peripheral(ble_peripheral.get()), kTxPowerLevel, + ble_b.GetRemotePeripheral(adapter_a.GetMacAddress()), kTxPowerLevel, /*ClientGattConnectionCallback=*/{}); ASSERT_NE(gatt_client, nullptr); @@ -592,9 +578,8 @@ TEST_F(BleV2MediumTest, GattClientOperatiosOnCharacteristic) { Uuid characteristic_uuid(5678, 1234); // Start GattClient. - auto ble_peripheral = std::make_unique(kDeviceMacAddress); std::unique_ptr gatt_client = ble_b.ConnectToGattServer( - BleV2Peripheral(ble_peripheral.get()), kTxPowerLevel, + ble_b.GetRemotePeripheral(adapter_a.GetMacAddress()), kTxPowerLevel, /*ClientGattConnectionCallback=*/{}); ASSERT_NE(gatt_client, nullptr); @@ -680,9 +665,8 @@ TEST_F(BleV2MediumTest, GattClientSubscribeNotificationGattServerCanNotify) { ByteArray("any"))); // Start GattClient - auto ble_peripheral = std::make_unique(kDeviceMacAddress); std::unique_ptr gatt_client = ble_b.ConnectToGattServer( - BleV2Peripheral(ble_peripheral.get()), kTxPowerLevel, + ble_b.GetRemotePeripheral(adapter_a.GetMacAddress()), kTxPowerLevel, /*ClientGattConnectionCallback=*/{}); ASSERT_NE(gatt_client, nullptr); @@ -726,5 +710,116 @@ TEST_F(BleV2MediumTest, GattClientSubscribeNotificationGattServerCanNotify) { env_.Stop(); } +TEST(BleV2PeripheralTest, ConstructionWorks) { + MediumEnvironment::Instance().Start(); + BluetoothAdapter adapter_a; + BluetoothAdapter adapter_b; + BleV2Medium ble_a(adapter_a); + BleV2Medium ble_b(adapter_b); + + BleV2Peripheral peripheral = + ble_b.GetRemotePeripheral(adapter_a.GetMacAddress()); + + ASSERT_TRUE(peripheral.IsValid()); + EXPECT_EQ(peripheral.GetAddress(), adapter_a.GetMacAddress()); + MediumEnvironment::Instance().Stop(); +} + +TEST(BleV2PeripheralTest, SetIdAndPsmWorks) { + MediumEnvironment::Instance().Start(); + BluetoothAdapter adapter_a; + BluetoothAdapter adapter_b; + BleV2Medium ble_a(adapter_a); + BleV2Medium ble_b(adapter_b); + ByteArray id((std::string(kId))); + int psm = 2; + + BleV2Peripheral peripheral = + ble_b.GetRemotePeripheral(adapter_a.GetMacAddress()); + peripheral.SetId(id); + peripheral.SetPsm(psm); + + ASSERT_TRUE(peripheral.IsValid()); + EXPECT_EQ(peripheral.GetId(), id); + EXPECT_EQ(peripheral.GetPsm(), 2); + MediumEnvironment::Instance().Stop(); +} + +TEST(BleV2PeripheralTest, CopyConstructorAndAssignmentSuccess) { + MediumEnvironment::Instance().Start(); + BluetoothAdapter adapter_a; + BluetoothAdapter adapter_b; + BleV2Medium ble_a(adapter_a); + BleV2Medium ble_b(adapter_b); + ByteArray id((std::string(kId))); + int psm = 2; + + BleV2Peripheral peripheral = + ble_b.GetRemotePeripheral(adapter_a.GetMacAddress()); + peripheral.SetId(id); + peripheral.SetPsm(psm); + + BleV2Peripheral copy_peripheral_1(peripheral); + + ASSERT_TRUE(copy_peripheral_1.IsValid()); + EXPECT_EQ(copy_peripheral_1.GetAddress(), adapter_a.GetMacAddress()); + EXPECT_EQ(copy_peripheral_1.GetId(), id); + EXPECT_EQ(copy_peripheral_1.GetPsm(), 2); + + BleV2Peripheral copy_periphera1_2 = peripheral; + + ASSERT_TRUE(copy_periphera1_2.IsValid()); + EXPECT_EQ(copy_periphera1_2.GetAddress(), adapter_a.GetMacAddress()); + EXPECT_EQ(copy_periphera1_2.GetId(), id); + EXPECT_EQ(copy_periphera1_2.GetPsm(), 2); + MediumEnvironment::Instance().Stop(); +} + +TEST(BleV2PeripheralTest, MoveConstructorSuccess) { + MediumEnvironment::Instance().Start(); + BluetoothAdapter adapter_a; + BluetoothAdapter adapter_b; + BleV2Medium ble_a(adapter_a); + BleV2Medium ble_b(adapter_b); + ByteArray id((std::string(kId))); + int psm = 2; + + BleV2Peripheral peripheral = + ble_b.GetRemotePeripheral(adapter_a.GetMacAddress()); + peripheral.SetId(id); + peripheral.SetPsm(psm); + + BleV2Peripheral move_peripheral(std::move(peripheral)); + + ASSERT_TRUE(move_peripheral.IsValid()); + EXPECT_EQ(move_peripheral.GetAddress(), adapter_a.GetMacAddress()); + EXPECT_EQ(move_peripheral.GetId(), id); + EXPECT_EQ(move_peripheral.GetPsm(), 2); + MediumEnvironment::Instance().Stop(); +} + +TEST(BleV2PeripheralTest, MoveAssignmentSuccess) { + MediumEnvironment::Instance().Start(); + BluetoothAdapter adapter_a; + BluetoothAdapter adapter_b; + BleV2Medium ble_a(adapter_a); + BleV2Medium ble_b(adapter_b); + ByteArray id((std::string(kId))); + int psm = 2; + + BleV2Peripheral peripheral = + ble_b.GetRemotePeripheral(adapter_a.GetMacAddress()); + peripheral.SetId(id); + peripheral.SetPsm(psm); + + BleV2Peripheral move_peripheral = std::move(peripheral); + + ASSERT_TRUE(move_peripheral.IsValid()); + EXPECT_EQ(move_peripheral.GetAddress(), adapter_a.GetMacAddress()); + EXPECT_EQ(move_peripheral.GetId(), id); + EXPECT_EQ(move_peripheral.GetPsm(), 2); + MediumEnvironment::Instance().Stop(); +} + } // namespace } // namespace nearby diff --git a/internal/platform/bluetooth_adapter.h b/internal/platform/bluetooth_adapter.h index 75edcc5a..51935882 100644 --- a/internal/platform/bluetooth_adapter.h +++ b/internal/platform/bluetooth_adapter.h @@ -47,64 +47,6 @@ class BlePeripheral final { api::BlePeripheral* impl_; }; -// Opaque wrapper over a BLE peripheral. Must contain enough data about a -// particular BLE peripheral to connect to its GATT server. -class BleV2Peripheral final { - public: - BleV2Peripheral() = default; - explicit BleV2Peripheral(api::ble_v2::BlePeripheral* peripheral) - : impl_(peripheral) {} - BleV2Peripheral(const BleV2Peripheral&) = default; - BleV2Peripheral& operator=(const BleV2Peripheral&) = default; - BleV2Peripheral(BleV2Peripheral&& other) { - impl_ = other.impl_; - id_ = std::move(other.id_); - psm_ = other.psm_; - - other.impl_ = nullptr; - other.psm_ = 0; - } - - BleV2Peripheral& operator=(BleV2Peripheral&& other) { - if (this != &other) { - impl_ = other.impl_; - id_ = std::move(other.id_); - psm_ = other.psm_; - - other.impl_ = nullptr; - other.psm_ = 0; - } - return *this; - } - - std::string GetAddress() const { return impl_->GetAddress(); } - - ByteArray GetId() const { return id_; } - void SetId(const ByteArray& id) { id_ = id; } - - int GetPsm() const { return psm_; } - void SetPsm(int psm) { psm_ = psm; } - - // Returns reference to platform implementation. - // This is used to communicate with platform code, and for debugging purposes. - api::ble_v2::BlePeripheral& GetImpl() const { return *impl_; } - bool IsValid() const { return impl_ != nullptr; } - - private: - // Does not take ownership. It refers to a valid `api::ble_v2::BlePeripheral` - // that outlives this object. - api::ble_v2::BlePeripheral* impl_ = nullptr; - - // A unique identifier for this peripheral. It is the BLE advertisement bytes - // it was found on. - ByteArray id_ = {}; - - // The psm (protocol service multiplexer) value is used for create data - // connection on L2CAP socket. It only exists when remote device supports - // L2CAP socket feature. - int psm_ = 0; -}; - // https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html. class BluetoothDevice final { public: diff --git a/internal/platform/bluetooth_adapter_test.cc b/internal/platform/bluetooth_adapter_test.cc index 671793c7..09aa8575 100644 --- a/internal/platform/bluetooth_adapter_test.cc +++ b/internal/platform/bluetooth_adapter_test.cc @@ -26,102 +26,6 @@ namespace nearby { namespace { -constexpr absl::string_view kMacAddress = "4C:8B:1D:CE:BA:D1"; -constexpr absl::string_view kId = "AB12"; - -class BlePeripheralStub : public api::ble_v2::BlePeripheral { - public: - explicit BlePeripheralStub(absl::string_view mac_address) { - mac_address_ = std::string(mac_address); - } - - std::string GetAddress() const override { return mac_address_; } - - private: - std::string mac_address_; -}; - -TEST(BleV2PeripheralTest, ConstructionWorks) { - auto api_peripheral = std::make_unique(kMacAddress); - - BleV2Peripheral peripheral(api_peripheral.get()); - - ASSERT_TRUE(peripheral.IsValid()); - EXPECT_EQ(peripheral.GetAddress(), kMacAddress); -} - -TEST(BleV2PeripheralTest, SetIdAndPsmWorks) { - auto api_peripheral = std::make_unique(kMacAddress); - ByteArray id((std::string(kId))); - int psm = 2; - - BleV2Peripheral peripheral(api_peripheral.get()); - peripheral.SetId(id); - peripheral.SetPsm(psm); - - ASSERT_TRUE(peripheral.IsValid()); - EXPECT_EQ(peripheral.GetId(), id); - EXPECT_EQ(peripheral.GetPsm(), 2); -} - -TEST(BleV2PeripheralTest, CopyConstructorAndAssignmentSuccess) { - auto api_peripheral = std::make_unique(kMacAddress); - ByteArray id((std::string(kId))); - int psm = 2; - - BleV2Peripheral peripheral(api_peripheral.get()); - peripheral.SetId(id); - peripheral.SetPsm(psm); - - BleV2Peripheral copy_peripheral_1(peripheral); - - ASSERT_TRUE(copy_peripheral_1.IsValid()); - EXPECT_EQ(copy_peripheral_1.GetAddress(), kMacAddress); - EXPECT_EQ(copy_peripheral_1.GetId(), id); - EXPECT_EQ(copy_peripheral_1.GetPsm(), 2); - - BleV2Peripheral copy_periphera1_2 = peripheral; - - ASSERT_TRUE(copy_periphera1_2.IsValid()); - EXPECT_EQ(copy_periphera1_2.GetAddress(), kMacAddress); - EXPECT_EQ(copy_periphera1_2.GetId(), id); - EXPECT_EQ(copy_periphera1_2.GetPsm(), 2); -} - -TEST(BleV2PeripheralTest, MoveConstructorSuccess) { - auto api_peripheral = std::make_unique(kMacAddress); - ByteArray id((std::string(kId))); - int psm = 2; - - BleV2Peripheral peripheral(api_peripheral.get()); - peripheral.SetId(id); - peripheral.SetPsm(psm); - - BleV2Peripheral move_peripheral(std::move(peripheral)); - - ASSERT_TRUE(move_peripheral.IsValid()); - EXPECT_EQ(move_peripheral.GetAddress(), kMacAddress); - EXPECT_EQ(move_peripheral.GetId(), id); - EXPECT_EQ(move_peripheral.GetPsm(), 2); -} - -TEST(BleV2PeripheralTest, MoveAssignmentSuccess) { - auto api_peripheral = std::make_unique(kMacAddress); - ByteArray id((std::string(kId))); - int psm = 2; - - BleV2Peripheral peripheral(api_peripheral.get()); - peripheral.SetId(id); - peripheral.SetPsm(psm); - - BleV2Peripheral move_peripheral = std::move(peripheral); - - ASSERT_TRUE(move_peripheral.IsValid()); - EXPECT_EQ(move_peripheral.GetAddress(), kMacAddress); - EXPECT_EQ(move_peripheral.GetId(), id); - EXPECT_EQ(move_peripheral.GetPsm(), 2); -} - TEST(BluetoothAdapterTest, ConstructorDestructorWorks) { BluetoothAdapter adapter; EXPECT_TRUE(adapter.IsValid()); diff --git a/internal/platform/implementation/BUILD b/internal/platform/implementation/BUILD index 4bead8ee..636a92e6 100644 --- a/internal/platform/implementation/BUILD +++ b/internal/platform/implementation/BUILD @@ -97,6 +97,7 @@ cc_library( # TODO: Support WebRTC "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/log:check", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", diff --git a/internal/platform/implementation/apple/ble.h b/internal/platform/implementation/apple/ble.h index 27970caf..c3ae1ad3 100644 --- a/internal/platform/implementation/apple/ble.h +++ b/internal/platform/implementation/apple/ble.h @@ -145,6 +145,16 @@ class BleMedium : public api::ble_v2::BleMedium { CancellationFlag *cancellation_flag) override; bool IsExtendedAdvertisementsAvailable() override; + bool GetRemotePeripheral(absl::string_view mac_address, + GetRemotePeripheralCallback callback) override { + return false; + } + + bool GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id, + GetRemotePeripheralCallback callback) override { + return false; + } + private: // A concrete implemenation for GattServer. class GattServer : public api::ble_v2::GattServer { diff --git a/internal/platform/implementation/apple/bluetooth_adapter.h b/internal/platform/implementation/apple/bluetooth_adapter.h index 2239b46d..ce08753f 100644 --- a/internal/platform/implementation/apple/bluetooth_adapter.h +++ b/internal/platform/implementation/apple/bluetooth_adapter.h @@ -17,10 +17,10 @@ #include +#import "internal/platform/implementation/apple/Mediums/Ble/GNCMBleCentral.h" #include "internal/platform/implementation/ble_v2.h" #include "internal/platform/implementation/bluetooth_adapter.h" - -#import "internal/platform/implementation/apple/Mediums/Ble/GNCMBleCentral.h" +#include "internal/platform/prng.h" namespace nearby { namespace apple { @@ -32,6 +32,10 @@ class BlePeripheral : public api::ble_v2::BlePeripheral { public: std::string GetAddress() const override; + api::ble_v2::BlePeripheral::UniqueId GetUniqueId() const override { + return unique_id_; + } + std::string GetPeripheralId() const { return peripheral_id_; } void SetPeripheralId(const std::string& peripheral_id) { @@ -50,11 +54,14 @@ class BlePeripheral : public api::ble_v2::BlePeripheral { // Only BluetoothAdapter may instantiate BlePeripheral. friend class BluetoothAdapter; - explicit BlePeripheral(BluetoothAdapter* adapter) : adapter_(*adapter) {} + explicit BlePeripheral(BluetoothAdapter* adapter) : adapter_(*adapter) { + unique_id_ = Prng().NextInt64(); + } BluetoothAdapter& adapter_; std::string peripheral_id_; GNCMBleConnectionRequester connection_requester_; + api::ble_v2::BlePeripheral::UniqueId unique_id_; }; // Concrete BluetoothAdapter implementation. diff --git a/internal/platform/implementation/ble_v2.h b/internal/platform/implementation/ble_v2.h index 8dd5ad50..13b0cbc3 100644 --- a/internal/platform/implementation/ble_v2.h +++ b/internal/platform/implementation/ble_v2.h @@ -33,7 +33,6 @@ #include "internal/platform/cancellation_flag.h" #include "internal/platform/exception.h" #include "internal/platform/input_stream.h" -#include "internal/platform/listeners.h" #include "internal/platform/output_stream.h" #include "internal/platform/uuid.h" @@ -86,13 +85,17 @@ struct BleAdvertisementData { // peripheral so that we can connect to its GATT server. class BlePeripheral { public: + using UniqueId = std::uint64_t; virtual ~BlePeripheral() = default; // https://developer.android.com/reference/android/bluetooth/BluetoothDevice#getAddress() // - // This should be the MAC address when possible. If the implementation is - // unable to retrieve that, any unique identifier should suffice. + // Returns the current address. virtual std::string GetAddress() const = 0; + + // Returns an immutable unique identifier. The identifier must not change when + // the BLE address is rotated. + virtual UniqueId GetUniqueId() const = 0; }; // https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic @@ -365,6 +368,7 @@ class BleServerSocket { // for all BLE and GATT related operations. class BleMedium { public: + using GetRemotePeripheralCallback = absl::AnyInvocable; virtual ~BleMedium() = default; // https://developer.android.com/reference/android/bluetooth/le/BluetoothLeAdvertiser.html#startAdvertising(android.bluetooth.le.AdvertiseSettings,%20android.bluetooth.le.AdvertiseData,%20android.bluetooth.le.AdvertiseData,%20android.bluetooth.le.AdvertiseCallback) @@ -493,6 +497,16 @@ class BleMedium { // Requests if support extended advertisement. virtual bool IsExtendedAdvertisementsAvailable() = 0; + + // Calls `callback` and returns true if `mac_address` is a valid BLE address. + // Otherwise, does not call the callback and returns false. + virtual bool GetRemotePeripheral(absl::string_view mac_address, + GetRemotePeripheralCallback callback) = 0; + + // Calls `callback` and returns true if `id` refers to a known BLE peripheral. + // Otherwise, does not call the callback and returns false. + virtual bool GetRemotePeripheral(BlePeripheral::UniqueId id, + GetRemotePeripheralCallback callback) = 0; }; } // namespace ble_v2 diff --git a/internal/platform/implementation/g3/ble_v2.cc b/internal/platform/implementation/g3/ble_v2.cc index 83b44a5e..3966ea3f 100644 --- a/internal/platform/implementation/g3/ble_v2.cc +++ b/internal/platform/implementation/g3/ble_v2.cc @@ -14,6 +14,7 @@ #include "internal/platform/implementation/g3/ble_v2.h" +#include #include #include #include @@ -55,6 +56,17 @@ std::string TxPowerLevelToName(TxPowerLevel power_mode) { } // namespace +BleV2Peripheral::BleV2Peripheral(BluetoothAdapter* adapter) + : adapter_(*adapter) {} + +std::string BleV2Peripheral::GetAddress() const { + return adapter_.GetMacAddress(); +} + +api::ble_v2::BlePeripheral::UniqueId BleV2Peripheral::GetUniqueId() const { + return adapter_.GetUniqueId(); +} + BleV2Socket::~BleV2Socket() { absl::MutexLock lock(&mutex_); DoClose(); @@ -104,7 +116,10 @@ BleV2Peripheral* BleV2Socket::GetRemotePeripheral() { } remote_adapter = remote_socket_->adapter_; } - return remote_adapter ? &remote_adapter->GetPeripheralV2() : nullptr; + if (remote_adapter == nullptr || remote_adapter->GetBleV2Medium() == nullptr) + return nullptr; + return &(static_cast(remote_adapter->GetBleV2Medium()) + ->GetPeripheral()); } void BleV2Socket::DoClose() { @@ -201,7 +216,8 @@ Exception BleV2ServerSocket::DoClose() { BleV2Medium::BleV2Medium(api::BluetoothAdapter& adapter) : adapter_(static_cast(&adapter)) { adapter_->SetBleV2Medium(this); - MediumEnvironment::Instance().RegisterBleV2Medium(*this); + + MediumEnvironment::Instance().RegisterBleV2Medium(*this, &peripheral_); } BleV2Medium::~BleV2Medium() { @@ -228,7 +244,7 @@ bool BleV2Medium::StartAdvertising( absl::MutexLock lock(&mutex_); MediumEnvironment::Instance().UpdateBleV2MediumForAdvertising( - /*enabled=*/true, *this, adapter_->GetPeripheralV2(), advertising_data); + /*enabled=*/true, *this, GetPeripheral(), advertising_data); return true; } @@ -238,7 +254,7 @@ bool BleV2Medium::StopAdvertising() { BleAdvertisementData empty_advertisement_data = {}; MediumEnvironment::Instance().UpdateBleV2MediumForAdvertising( - /*enabled=*/false, *this, /*mutable=*/adapter_->GetPeripheralV2(), + /*enabled=*/false, *this, /*mutable=*/GetPeripheral(), empty_advertisement_data); return true; } @@ -266,7 +282,7 @@ std::unique_ptr BleV2Medium::StartAdvertising( } absl::MutexLock lock(&mutex_); MediumEnvironment::Instance().UpdateBleV2MediumForAdvertising( - /*enabled=*/true, *this, adapter_->GetPeripheralV2(), advertising_data); + /*enabled=*/true, *this, GetPeripheral(), advertising_data); return std::make_unique( AdvertisingSession{.stop_advertising = [this] { return StopAdvertising() @@ -295,7 +311,8 @@ bool BleV2Medium::StopScanning() { for (auto element : scanning_internal_session_ids_) { MediumEnvironment::Instance().UpdateBleV2MediumForScanning( /*enabled=*/false, - /*service_uuid=*/element.first, /*internal_session_id*/ element.second, + /*service_uuid=*/element.first, + /*internal_session_id*/ element.second, /*callback=*/{}, *this); } return true; @@ -352,6 +369,50 @@ bool BleV2Medium::IsExtendedAdvertisementsAvailable() { return is_support_extended_advertisement_; } +bool BleV2Medium::GetRemotePeripheral(absl::string_view mac_address, + GetRemotePeripheralCallback callback) { + NEARBY_LOGS(INFO) << "GetRemotePeripheral, address= " << mac_address; + absl::MutexLock lock(&mutex_); + for (auto& item : remote_peripherals_) { + auto* peripheral = item.second.get(); + if (peripheral->GetAddress() == mac_address) { + callback(*peripheral); + return true; + } + } + BleV2Medium* remote_medium = static_cast( + MediumEnvironment::Instance().FindBleV2Medium(mac_address)); + if (remote_medium == nullptr) { + return false; + } + auto id = remote_medium->GetPeripheral().GetUniqueId(); + remote_peripherals_[id] = + std::make_unique(&remote_medium->GetAdapter()); + callback(*remote_peripherals_[id]); + return true; +} + +bool BleV2Medium::GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id, + GetRemotePeripheralCallback callback) { + absl::MutexLock lock(&mutex_); + auto it = remote_peripherals_.find(id); + if (it != remote_peripherals_.end()) { + callback(*it->second); + return true; + } + + BleV2Medium* remote_medium = static_cast( + MediumEnvironment::Instance().FindBleV2Medium(id)); + if (remote_medium == nullptr) { + NEARBY_LOGS(INFO) << "Peripheral not found, id= " << id; + return false; + } + remote_peripherals_[id] = + std::make_unique(&remote_medium->GetAdapter()); + callback(*remote_peripherals_[id]); + return true; +} + std::optional BleV2Medium::GattServer::CreateCharacteristic( const Uuid& service_uuid, const Uuid& characteristic_uuid, @@ -521,7 +582,7 @@ std::unique_ptr BleV2Medium::Connect( CancellationFlag* cancellation_flag) { NEARBY_LOGS(INFO) << "G3 Ble Connect [self]: medium=" << this << ", adapter=" << &GetAdapter() - << ", peripheral=" << &GetAdapter().GetPeripheralV2() + << ", peripheral=" << &GetPeripheral() << ", service_id=" << service_id; // First, find an instance of remote medium, that exposed this peripheral. auto& remote_adapter = diff --git a/internal/platform/implementation/g3/ble_v2.h b/internal/platform/implementation/g3/ble_v2.h index b55f2df3..87a63027 100644 --- a/internal/platform/implementation/g3/ble_v2.h +++ b/internal/platform/implementation/g3/ble_v2.h @@ -33,7 +33,18 @@ namespace nearby { namespace g3 { -class BleV2nMedium; +// BlePeripheral implementation. +class BleV2Peripheral : public api::ble_v2::BlePeripheral { + public: + explicit BleV2Peripheral(BluetoothAdapter* adapter); + std::string GetAddress() const override; + api::ble_v2::BlePeripheral::UniqueId GetUniqueId() const override; + + BluetoothAdapter& GetAdapter() { return adapter_; } + + private: + BluetoothAdapter& adapter_; +}; class BleV2Socket : public api::ble_v2::BleSocket { public: @@ -205,6 +216,14 @@ class BleV2Medium : public api::ble_v2::BleMedium { BluetoothAdapter& GetAdapter() { return *adapter_; } + BleV2Peripheral& GetPeripheral() { return peripheral_; } + + bool GetRemotePeripheral(absl::string_view mac_address, + GetRemotePeripheralCallback callback) override; + + bool GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id, + GetRemotePeripheralCallback callback) override; + private: // A concrete implementation for GattServer. class GattServer : public api::ble_v2::GattServer { @@ -261,6 +280,10 @@ class BleV2Medium : public api::ble_v2::BleMedium { absl::Mutex mutex_; BluetoothAdapter* adapter_; // Our device adapter; read-only. + BleV2Peripheral peripheral_{adapter_}; + absl::flat_hash_map> + remote_peripherals_ ABSL_GUARDED_BY(mutex_); absl::flat_hash_map server_sockets_ ABSL_GUARDED_BY(mutex_); absl::flat_hash_set> diff --git a/internal/platform/implementation/g3/bluetooth_adapter.cc b/internal/platform/implementation/g3/bluetooth_adapter.cc index 3bd5eb28..514971fb 100644 --- a/internal/platform/implementation/g3/bluetooth_adapter.cc +++ b/internal/platform/implementation/g3/bluetooth_adapter.cc @@ -38,13 +38,6 @@ void BlePeripheral::SetAdvertisementBytes( advertisement_bytes_ = advertisement_bytes; } -BleV2Peripheral::BleV2Peripheral(BluetoothAdapter* adapter) - : adapter_(*adapter) {} - -std::string BleV2Peripheral::GetAddress() const { - return adapter_.GetMacAddress(); -} - BluetoothDevice::BluetoothDevice(BluetoothAdapter* adapter) : adapter_(*adapter) {} @@ -57,7 +50,7 @@ std::string BluetoothDevice::GetMacAddress() const { BluetoothAdapter::BluetoothAdapter() { std::string mac_address; mac_address.resize(6); - int64_t raw_mac_addr = Prng().NextInt64(); + std::uint64_t raw_mac_addr = Prng().NextInt64(); mac_address[0] = static_cast(raw_mac_addr >> 40); mac_address[1] = static_cast(raw_mac_addr >> 32); mac_address[2] = static_cast(raw_mac_addr >> 24); @@ -65,6 +58,7 @@ BluetoothAdapter::BluetoothAdapter() { mac_address[4] = static_cast(raw_mac_addr >> 8); mac_address[5] = static_cast(raw_mac_addr >> 0); SetMacAddress(mac_address); + unique_id_ = raw_mac_addr; } BluetoothAdapter::~BluetoothAdapter() { SetStatus(Status::kDisabled); } diff --git a/internal/platform/implementation/g3/bluetooth_adapter.h b/internal/platform/implementation/g3/bluetooth_adapter.h index e8ef8c61..7bd12b86 100644 --- a/internal/platform/implementation/g3/bluetooth_adapter.h +++ b/internal/platform/implementation/g3/bluetooth_adapter.h @@ -15,7 +15,9 @@ #ifndef PLATFORM_IMPL_G3_BLUETOOTH_ADAPTER_H_ #define PLATFORM_IMPL_G3_BLUETOOTH_ADAPTER_H_ +#include #include +#include #include "absl/base/thread_annotations.h" #include "absl/strings/string_view.h" @@ -54,21 +56,6 @@ class BlePeripheral : public api::BlePeripheral { ByteArray advertisement_bytes_; }; -// BlePeripheral implementation. -class BleV2Peripheral : public api::ble_v2::BlePeripheral { - public: - std::string GetAddress() const override; - BluetoothAdapter& GetAdapter() { return adapter_; } - - private: - // Only BluetoothAdapter may instantiate BlePeripheral. - friend class BluetoothAdapter; - - explicit BleV2Peripheral(BluetoothAdapter* adapter); - - BluetoothAdapter& adapter_; -}; - // https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html. class BluetoothDevice : public api::BluetoothDevice { public: @@ -134,7 +121,6 @@ class BluetoothAdapter : public api::BluetoothAdapter { } BlePeripheral& GetPeripheral() { return peripheral_; } - BleV2Peripheral& GetPeripheralV2() { return peripheral_v2_; } void SetBleMedium(api::BleMedium* medium); api::BleMedium* GetBleMedium() { return ble_medium_; } @@ -144,11 +130,12 @@ class BluetoothAdapter : public api::BluetoothAdapter { void SetMacAddress(std::string& mac_address) { mac_address_ = mac_address; } + std::uint64_t GetUniqueId() { return unique_id_; } + private: mutable absl::Mutex mutex_; BluetoothDevice device_{this}; BlePeripheral peripheral_{this}; - BleV2Peripheral peripheral_v2_{this}; api::BluetoothClassicMedium* bluetooth_classic_medium_ = nullptr; api::BleMedium* ble_medium_ = nullptr; api::ble_v2::BleMedium* ble_v2_medium_ = nullptr; @@ -156,6 +143,7 @@ class BluetoothAdapter : public api::BluetoothAdapter { ScanMode mode_ ABSL_GUARDED_BY(mutex_) = ScanMode::kNone; std::string name_ ABSL_GUARDED_BY(mutex_) = "unknown G3 BT device"; bool enabled_ ABSL_GUARDED_BY(mutex_) = true; + std::uint64_t unique_id_; }; } // namespace g3 diff --git a/internal/platform/implementation/windows/ble_v2.cc b/internal/platform/implementation/windows/ble_v2.cc index 4cba7592..e979614a 100644 --- a/internal/platform/implementation/windows/ble_v2.cc +++ b/internal/platform/implementation/windows/ble_v2.cc @@ -26,6 +26,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/synchronization/mutex.h" +#include "internal/platform/bluetooth_adapter.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/cancellation_flag_listener.h" #include "internal/platform/implementation/ble_v2.h" @@ -842,5 +843,34 @@ void BleV2Medium::AdvertisementReceivedHandler( } } +bool BleV2Medium::GetRemotePeripheral(absl::string_view mac_address, + GetRemotePeripheralCallback callback) { + for (auto& item : peripherals_) { + if (item.second->GetAddress() == mac_address) { + callback(*(item.second)); + return true; + } + } + auto peripheral = std::make_unique(); + peripheral->SetAddress(mac_address); + if (peripheral->GetUniqueId() == 0) { + return false; + } + BleV2Peripheral* ptr = peripheral.get(); + peripherals_[peripheral->GetUniqueId()] = std::move(peripheral); + callback(*ptr); + return true; +} + +bool BleV2Medium::GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id, + GetRemotePeripheralCallback callback) { + auto it = peripherals_.find(id); + if (it == peripherals_.end()) { + return false; + } + callback(*(it->second)); + return true; +} + } // namespace windows } // namespace nearby diff --git a/internal/platform/implementation/windows/ble_v2.h b/internal/platform/implementation/windows/ble_v2.h index ea70f29e..59cf6a70 100644 --- a/internal/platform/implementation/windows/ble_v2.h +++ b/internal/platform/implementation/windows/ble_v2.h @@ -73,6 +73,12 @@ class BleV2Medium : public api::ble_v2::BleMedium { BluetoothAdapter& GetAdapter() { return *adapter_; } + bool GetRemotePeripheral(absl::string_view mac_address, + GetRemotePeripheralCallback callback) override; + + bool GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id, + GetRemotePeripheralCallback callback) override; + private: bool StartBleAdvertising( const api::ble_v2::BleAdvertisementData& advertising_data, @@ -127,6 +133,10 @@ class BleV2Medium : public api::ble_v2::BleMedium { ::winrt::event_token advertisement_received_token_; BleGattServer* ble_gatt_server_ = nullptr; + + absl::flat_hash_map> + peripherals_; }; } // namespace windows diff --git a/internal/platform/implementation/windows/ble_v2_peripheral.h b/internal/platform/implementation/windows/ble_v2_peripheral.h index 984e3af8..6c890d9c 100644 --- a/internal/platform/implementation/windows/ble_v2_peripheral.h +++ b/internal/platform/implementation/windows/ble_v2_peripheral.h @@ -19,6 +19,7 @@ #include "absl/strings/string_view.h" #include "internal/platform/implementation/ble_v2.h" +#include "internal/platform/prng.h" namespace nearby { namespace windows { @@ -27,18 +28,23 @@ namespace windows { // about a particular BLE device to connect to its GATT server. class BleV2Peripheral : public api::ble_v2::BlePeripheral { public: + BleV2Peripheral() { unique_id_ = Prng().NextInt64(); } ~BleV2Peripheral() override = default; // Returns the MAC address of the peripheral. The format is in // "00:B0:D0:63:C2:26". std::string GetAddress() const override { return address_; } + api::ble_v2::BlePeripheral::UniqueId GetUniqueId() const override { + return unique_id_; + } // Sets the MAC address of the peripheral. The address format must be in // pattern of "00:B0:D0:63:C2:26". bool SetAddress(absl::string_view address); private: std::string address_; + api::ble_v2::BlePeripheral::UniqueId unique_id_; }; } // namespace windows diff --git a/internal/platform/medium_environment.cc b/internal/platform/medium_environment.cc index b1077e7b..8ff19a1f 100644 --- a/internal/platform/medium_environment.cc +++ b/internal/platform/medium_environment.cc @@ -230,6 +230,51 @@ api::BluetoothDevice* MediumEnvironment::FindBluetoothDevice( return device; } +api::ble_v2::BleMedium* MediumEnvironment::FindBleV2Medium( + absl::string_view address) { + api::ble_v2::BleMedium* device = nullptr; + CountDownLatch latch(1); + NEARBY_LOGS(INFO) << "FindBleV2Medium " << address; + RunOnMediumEnvironmentThread([&]() { + for (auto& item : ble_v2_mediums_) { + auto* medium = item.first; + auto* peripheral = item.second.ble_peripheral; + if (peripheral != nullptr && peripheral->GetAddress() == address) { + device = medium; + break; + } + } + latch.CountDown(); + }); + latch.Await(); + if (device == nullptr) { + NEARBY_LOGS(INFO) << "FindBleV2Medium, not found: " << address; + } + return device; +} + +api::ble_v2::BleMedium* MediumEnvironment::FindBleV2Medium(uint64_t id) { + api::ble_v2::BleMedium* device = nullptr; + CountDownLatch latch(1); + NEARBY_LOGS(INFO) << "FindBleV2Medium " << id; + RunOnMediumEnvironmentThread([&]() { + for (auto& item : ble_v2_mediums_) { + auto* medium = item.first; + auto* peripheral = item.second.ble_peripheral; + if (peripheral != nullptr && peripheral->GetUniqueId() == id) { + device = medium; + break; + } + } + latch.CountDown(); + }); + latch.Await(); + if (device == nullptr) { + NEARBY_LOGS(INFO) << "FindBleV2Medium, not found: " << id; + } + return device; +} + void MediumEnvironment::OnBlePeripheralStateChanged( BleMediumContext& info, api::BlePeripheral& peripheral, const std::string& service_id, bool fast_advertisement, bool enabled) { @@ -525,10 +570,12 @@ void MediumEnvironment::CallBleAcceptedConnectionCallback( }); } -void MediumEnvironment::RegisterBleV2Medium(api::ble_v2::BleMedium& medium) { +void MediumEnvironment::RegisterBleV2Medium( + api::ble_v2::BleMedium& medium, api::ble_v2::BlePeripheral* peripheral) { if (!enabled_) return; - RunOnMediumEnvironmentThread([this, &medium]() { - ble_v2_mediums_.insert({&medium, BleV2MediumContext{}}); + RunOnMediumEnvironmentThread([this, &medium, peripheral]() { + ble_v2_mediums_.insert( + {&medium, BleV2MediumContext{.ble_peripheral = peripheral}}); NEARBY_LOGS(INFO) << "G3 Registered: medium:" << &medium; }); } @@ -675,25 +722,24 @@ bool MediumEnvironment::DiscoverBleV2MediumGattCharacteristics( if (!enabled_) return false; int found_characteristic = 0; CountDownLatch latch(1); - RunOnMediumEnvironmentThread( - [this, &found_characteristic, &latch, &service_uuid, - &characteristic_uuids]() { - for (const auto& item : gatt_advertisement_bytes_) { - if (item.first.service_uuid == service_uuid) { - Uuid char_uuid_key = item.first.uuid; - auto it = std::find_if(characteristic_uuids.rbegin(), - characteristic_uuids.rend(), - [char_uuid_key](const auto& char_uuid) { - return char_uuid == char_uuid_key; - }); - if (it != characteristic_uuids.rend()) { - discovered_gatt_advertisement_bytes_[item.first] = item.second; - found_characteristic++; - } - } + RunOnMediumEnvironmentThread([this, &found_characteristic, &latch, + &service_uuid, &characteristic_uuids]() { + for (const auto& item : gatt_advertisement_bytes_) { + if (item.first.service_uuid == service_uuid) { + Uuid char_uuid_key = item.first.uuid; + auto it = std::find_if(characteristic_uuids.rbegin(), + characteristic_uuids.rend(), + [char_uuid_key](const auto& char_uuid) { + return char_uuid == char_uuid_key; + }); + if (it != characteristic_uuids.rend()) { + discovered_gatt_advertisement_bytes_[item.first] = item.second; + found_characteristic++; } - latch.CountDown(); - }); + } + } + latch.CountDown(); + }); latch.Await(); return found_characteristic == characteristic_uuids.size(); } diff --git a/internal/platform/medium_environment.h b/internal/platform/medium_environment.h index b50db82c..dd84f356 100644 --- a/internal/platform/medium_environment.h +++ b/internal/platform/medium_environment.h @@ -229,7 +229,8 @@ class MediumEnvironment { // expects they should communicate. // The registered `medium` must refer to a valid instance that outlives this // object. - void RegisterBleV2Medium(api::ble_v2::BleMedium& medium); + void RegisterBleV2Medium(api::ble_v2::BleMedium& medium, + api::ble_v2::BlePeripheral* peripheral); // Updates advertising info to indicate the current medium is exposing // advertising event. @@ -385,6 +386,9 @@ class MediumEnvironment { absl::optional GetSimulatedClock(); + api::ble_v2::BleMedium* FindBleV2Medium(absl::string_view address); + api::ble_v2::BleMedium* FindBleV2Medium(uint64_t id); + // Configures the BluetoothPairingContext for remote BluetoothDevice. void ConfigBluetoothPairingContext(api::BluetoothDevice* device, api::PairingParams pairing_params);