diff --git a/fastpair/message_stream/medium_test.cc b/fastpair/message_stream/medium_test.cc index 1fb68b49..421baa24 100644 --- a/fastpair/message_stream/medium_test.cc +++ b/fastpair/message_stream/medium_test.cc @@ -86,7 +86,8 @@ TEST_F(MediumTest, ConnectWithNonExistingDeviceFails) { TEST_F(MediumTest, Connect) { FastPairDevice fp_device("model id", "ble address", Protocol::kFastPairRetroactivePairing); - fp_device.set_public_address(provider_.GetMacAddress()); + fp_device.set_public_address( + absl::BytesToHexString(provider_.GetMacAddress())); provider_.DiscoverProvider(seeker_medium_); provider_.EnableProviderRfcomm(); Medium medium = @@ -101,7 +102,8 @@ TEST_F(MediumTest, Connect) { TEST_F(MediumTest, ProviderDisconnectsCallsOnDisconnectCallback) { FastPairDevice fp_device("model id", "ble address", Protocol::kFastPairRetroactivePairing); - fp_device.set_public_address(provider_.GetMacAddress()); + fp_device.set_public_address( + absl::BytesToHexString(provider_.GetMacAddress())); provider_.DiscoverProvider(seeker_medium_); provider_.EnableProviderRfcomm(); Medium medium = @@ -120,7 +122,8 @@ TEST_F(MediumTest, ProviderDisconnectsCallsOnDisconnectCallback) { TEST_F(MediumTest, DisconnectSendFails) { FastPairDevice fp_device("model id", "ble address", Protocol::kFastPairRetroactivePairing); - fp_device.set_public_address(provider_.GetMacAddress()); + fp_device.set_public_address( + absl::BytesToHexString(provider_.GetMacAddress())); provider_.DiscoverProvider(seeker_medium_); provider_.EnableProviderRfcomm(); Medium medium = @@ -145,7 +148,8 @@ TEST_F(MediumTest, SendMessage) { std::string expected_result = absl::HexStringToBytes("030A0003ABCDEF"); FastPairDevice fp_device("model id", "ble address", Protocol::kFastPairRetroactivePairing); - fp_device.set_public_address(provider_.GetMacAddress()); + fp_device.set_public_address( + absl::BytesToHexString(provider_.GetMacAddress())); provider_.DiscoverProvider(seeker_medium_); provider_.EnableProviderRfcomm(); Medium medium = @@ -170,7 +174,8 @@ TEST_F(MediumTest, ReceiveMessage) { std::string input = absl::HexStringToBytes("030A0003ABCDEF"); FastPairDevice fp_device("model id", "ble address", Protocol::kFastPairRetroactivePairing); - fp_device.set_public_address(provider_.GetMacAddress()); + fp_device.set_public_address( + absl::BytesToHexString(provider_.GetMacAddress())); provider_.DiscoverProvider(seeker_medium_); provider_.EnableProviderRfcomm(); Medium medium = @@ -192,7 +197,8 @@ class MediumFuzzTest : public fuzztest::PerIterationFixtureAdapter { void HandlesAnyInput(absl::string_view input) { FastPairDevice fp_device("model id", "ble address", Protocol::kFastPairRetroactivePairing); - fp_device.set_public_address(provider_.GetMacAddress()); + fp_device.set_public_address( + absl::BytesToHexString(provider_.GetMacAddress())); provider_.DiscoverProvider(seeker_medium_); provider_.EnableProviderRfcomm(); Medium medium = Medium( @@ -213,7 +219,8 @@ class MediumFuzzTest : public fuzztest::PerIterationFixtureAdapter { .payload = std::string(payload)}; FastPairDevice fp_device("model id", "ble address", Protocol::kFastPairRetroactivePairing); - fp_device.set_public_address(provider_.GetMacAddress()); + fp_device.set_public_address( + absl::BytesToHexString(provider_.GetMacAddress())); provider_.DiscoverProvider(seeker_medium_); provider_.EnableProviderRfcomm(); Medium medium = Medium( diff --git a/fastpair/message_stream/message_stream_test.cc b/fastpair/message_stream/message_stream_test.cc index 63956fd3..84a74262 100644 --- a/fastpair/message_stream/message_stream_test.cc +++ b/fastpair/message_stream/message_stream_test.cc @@ -109,7 +109,8 @@ class MessageStreamTest : public testing::Test { void SetUp() override { MediumEnvironment::Instance().Start(); - fp_device_.set_public_address(provider_.GetMacAddress()); + fp_device_.set_public_address( + absl::BytesToHexString(provider_.GetMacAddress())); provider_.DiscoverProvider(seeker_medium_); provider_.EnableProviderRfcomm(); } @@ -122,7 +123,7 @@ class MessageStreamTest : public testing::Test { MessageStream message_stream = MessageStream( fp_device_, std::optional(&seeker_medium_), observer_); - CHECK(message_stream.OpenRfcomm().ok()); + CHECK_OK(message_stream.OpenRfcomm()); CHECK(observer_.connection_result_.Get().ok()); CHECK(observer_.connection_result_.Get().GetResult().ok()); return message_stream; diff --git a/internal/platform/bluetooth_classic_test.cc b/internal/platform/bluetooth_classic_test.cc index a5e1c591..1d14dfa9 100644 --- a/internal/platform/bluetooth_classic_test.cc +++ b/internal/platform/bluetooth_classic_test.cc @@ -15,6 +15,8 @@ #include "internal/platform/bluetooth_classic.h" #include +#include +#include #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" @@ -22,6 +24,7 @@ #include "absl/time/time.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/count_down_latch.h" +#include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" #include "internal/platform/single_thread_executor.h" @@ -30,6 +33,8 @@ namespace nearby { namespace { using FeatureFlags = FeatureFlags::Flags; +using PairingError = api::BluetoothPairingCallback::PairingError; +constexpr absl::string_view kPairingPasskKey("123456"); constexpr FeatureFlags kTestCases[] = { FeatureFlags{ @@ -56,6 +61,7 @@ class BluetoothClassicMediumTest adapter_b_->SetStatus(BluetoothAdapter::Status::kEnabled); env_.Sync(); } + ~BluetoothClassicMediumTest() override { env_.Sync(false); adapter_a_->SetStatus(BluetoothAdapter::Status::kDisabled); @@ -377,5 +383,193 @@ TEST_F(BluetoothClassicMediumTest, FailIfDiscovering) { EXPECT_FALSE(bt_a_->StartDiscovery({})); } +TEST_F(BluetoothClassicMediumTest, BluetoothPairingSuccess) { + // Discovered remote device + adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable); + BluetoothDevice* discovered_device = nullptr; + CountDownLatch found_latch(1); + bt_a_->StartDiscovery( + DiscoveryCallback{.device_discovered_cb = [&](BluetoothDevice& device) { + NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str()); + EXPECT_EQ(device.GetName(), adapter_b_->GetName()); + discovered_device = &device; + found_latch.CountDown(); + }}); + adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable); + found_latch.Await(); + + // Create bluetooth pairing instance to handle the pairing process + // with the remote device + auto bluetooth_pairing = bt_a_->CreatePairing(*discovered_device); + EXPECT_TRUE(bluetooth_pairing); + EXPECT_FALSE(bluetooth_pairing->IsPaired()); + + // Configure the remote device's pairing context + api::PairingParams pairing_params; + pairing_params.pairing_type = + api::PairingParams::PairingType::kConfirmPasskey; + pairing_params.passkey = kPairingPasskKey; + env_.ConfigBluetoothPairingContext(&discovered_device->GetImpl(), + pairing_params); + + // Initiates pairing request with remote device + std::string received_passkey; + CountDownLatch paired_latch(1); + CountDownLatch initiated_latch(1); + CountDownLatch error_latch(1); + EXPECT_TRUE(bluetooth_pairing->InitiatePairing({ + .on_paired_cb = [&]() { paired_latch.CountDown(); }, + .on_pairing_error_cb = + [&](api::BluetoothPairingCallback::PairingError error) { + EXPECT_EQ( + error, + api::BluetoothPairingCallback::PairingError::kAuthTimeout); + error_latch.CountDown(); + }, + .on_pairing_initiated_cb = + [&](api::PairingParams pairingParams) { + EXPECT_EQ(pairingParams.passkey, pairing_params.passkey); + EXPECT_EQ(pairingParams.pairing_type, pairing_params.pairing_type); + received_passkey = pairingParams.passkey; + initiated_latch.CountDown(); + }, + })); + initiated_latch.Await(); + + // Mocks pairing success result for the remote device. + EXPECT_TRUE( + env_.SetPairingResult(&discovered_device->GetImpl(), std::nullopt)); + // Finishes pairing with remote device. + EXPECT_TRUE(bluetooth_pairing->FinishPairing(received_passkey)); + paired_latch.Await(); + EXPECT_TRUE(bluetooth_pairing->IsPaired()); + + // Unpairs with remote device. + EXPECT_TRUE(bluetooth_pairing->Unpair()); + EXPECT_FALSE(bluetooth_pairing->IsPaired()); +} + +TEST_F(BluetoothClassicMediumTest, BluetoothPairingFailure) { + // Discovered remote device + adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable); + BluetoothDevice* discovered_device = nullptr; + CountDownLatch found_latch(1); + bt_a_->StartDiscovery( + DiscoveryCallback{.device_discovered_cb = [&](BluetoothDevice& device) { + NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str()); + EXPECT_EQ(device.GetName(), adapter_b_->GetName()); + discovered_device = &device; + found_latch.CountDown(); + }}); + adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable); + found_latch.Await(); + + // Create bluetooth pairing instance to handle the pairing process + // with the remote device + auto bluetooth_pairing = bt_a_->CreatePairing(*discovered_device); + EXPECT_TRUE(bluetooth_pairing); + EXPECT_FALSE(bluetooth_pairing->IsPaired()); + + // Configure the remote device's pairing context + api::PairingParams pairing_params; + pairing_params.pairing_type = + api::PairingParams::PairingType::kConfirmPasskey; + pairing_params.passkey = kPairingPasskKey; + env_.ConfigBluetoothPairingContext(&discovered_device->GetImpl(), + pairing_params); + + // Initiates pairing request with remote device + std::string received_passkey; + CountDownLatch paired_latch(1); + CountDownLatch initiated_latch(1); + CountDownLatch error_latch(1); + EXPECT_TRUE(bluetooth_pairing->InitiatePairing({ + .on_paired_cb = [&]() { paired_latch.CountDown(); }, + .on_pairing_error_cb = + [&](api::BluetoothPairingCallback::PairingError error) { + EXPECT_EQ( + error, + api::BluetoothPairingCallback::PairingError::kAuthTimeout); + error_latch.CountDown(); + }, + .on_pairing_initiated_cb = + [&](api::PairingParams pairingParams) { + EXPECT_EQ(pairingParams.passkey, pairing_params.passkey); + EXPECT_EQ(pairingParams.pairing_type, pairing_params.pairing_type); + received_passkey = pairingParams.passkey; + initiated_latch.CountDown(); + }, + })); + initiated_latch.Await(); + + // Mocks pairing failure result for the remote device. + EXPECT_TRUE(env_.SetPairingResult( + &discovered_device->GetImpl(), + api::BluetoothPairingCallback::PairingError::kAuthTimeout)); + // Finishes pairing with remote device. + EXPECT_TRUE(bluetooth_pairing->FinishPairing(received_passkey)); + error_latch.Await(); + EXPECT_FALSE(bluetooth_pairing->IsPaired()); +} +TEST_F(BluetoothClassicMediumTest, CancelBluetoothPairing) { + // Discovered remote device + adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable); + BluetoothDevice* discovered_device = nullptr; + CountDownLatch found_latch(1); + bt_a_->StartDiscovery( + DiscoveryCallback{.device_discovered_cb = [&](BluetoothDevice& device) { + NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str()); + NEARBY_LOG(INFO, "Device discovered address: %s", + device.GetMacAddress().c_str()); + EXPECT_EQ(device.GetName(), adapter_b_->GetName()); + discovered_device = &device; + found_latch.CountDown(); + }}); + adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable); + found_latch.Await(); + + // Create bluetooth pairing instance to handle the pairing process + // with the remote device + auto bluetooth_pairing = bt_a_->CreatePairing(*discovered_device); + EXPECT_FALSE(bluetooth_pairing->IsPaired()); + + // Configure the remote device's pairing context + api::PairingParams pairing_params; + pairing_params.pairing_type = + api::PairingParams::PairingType::kConfirmPasskey; + pairing_params.passkey = "123456"; + env_.ConfigBluetoothPairingContext(&discovered_device->GetImpl(), + pairing_params); + + // Initiates pairing request with remote device + PairingError received_error = PairingError::kUnknown; + CountDownLatch error_latch(1); + CountDownLatch initiated_latch(1); + EXPECT_TRUE(bluetooth_pairing->InitiatePairing({ + .on_pairing_error_cb = + [&](api::BluetoothPairingCallback::PairingError error) { + received_error = error; + error_latch.CountDown(); + }, + .on_pairing_initiated_cb = + [&](api::PairingParams pairingParams) { + EXPECT_EQ(pairingParams.passkey, pairing_params.passkey); + EXPECT_EQ(pairingParams.pairing_type, pairing_params.pairing_type); + initiated_latch.CountDown(); + }, + })); + initiated_latch.Await(); + + // Cancels the ongoing pairing with remote device. + EXPECT_TRUE(bluetooth_pairing->CancelPairing()); + error_latch.Await(); + EXPECT_EQ(received_error, PairingError::kAuthCanceled); + EXPECT_FALSE(bluetooth_pairing->IsPaired()); + + // Clear Bluetooth devices for pairing + bluetooth_pairing.reset(); + EXPECT_FALSE(env_.SetPairingState(&discovered_device->GetImpl(), false)); +} + } // namespace } // namespace nearby diff --git a/internal/platform/implementation/g3/bluetooth_classic.cc b/internal/platform/implementation/g3/bluetooth_classic.cc index b7732b5e..eebbddc3 100644 --- a/internal/platform/implementation/g3/bluetooth_classic.cc +++ b/internal/platform/implementation/g3/bluetooth_classic.cc @@ -15,8 +15,10 @@ #include "internal/platform/implementation/g3/bluetooth_classic.h" #include +#include #include +#include "absl/strings/escaping.h" #include "absl/synchronization/mutex.h" #include "internal/platform/cancellation_flag_listener.h" #include "internal/platform/implementation/bluetooth_classic.h" @@ -176,6 +178,36 @@ Exception BluetoothServerSocket::DoClose() { return {Exception::kSuccess}; } +BluetoothPairing::BluetoothPairing(api::BluetoothDevice& remote_device) + : remote_device_(remote_device) {} + +BluetoothPairing::~BluetoothPairing() { + MediumEnvironment::Instance().ClearBluetoothDevicesForPairing(); +} + +bool BluetoothPairing::InitiatePairing( + api::BluetoothPairingCallback pairing_cb) { + return MediumEnvironment::Instance().InitiatePairing(&remote_device_, + std::move(pairing_cb)); +} + +bool BluetoothPairing::FinishPairing( + std::optional pin_code) { + return MediumEnvironment::Instance().FinishPairing(&remote_device_); +} + +bool BluetoothPairing::CancelPairing() { + return MediumEnvironment::Instance().CancelPairing(&remote_device_); +} + +bool BluetoothPairing::Unpair() { + return MediumEnvironment::Instance().SetPairingState(&remote_device_, false); +} + +bool BluetoothPairing::IsPaired() { + return MediumEnvironment::Instance().IsPaired(&remote_device_); +} + BluetoothClassicMedium::BluetoothClassicMedium(api::BluetoothAdapter& adapter) // TODO(apolyudov): implement and use downcast<> with static assertions. : adapter_(static_cast(&adapter)) { @@ -273,14 +305,18 @@ BluetoothClassicMedium::ListenForService(const std::string& service_name, std::unique_ptr BluetoothClassicMedium::CreatePairing( api::BluetoothDevice& remote_device) { - // TODO(b/279964840): Add g3 implementation for BluetoothPairing. - return nullptr; + return std::make_unique(remote_device); } api::BluetoothDevice* BluetoothClassicMedium::GetRemoteDevice( const std::string& mac_address) { + std::string bt_mac_address = mac_address; + // Remove the colon delimiters. + bt_mac_address.erase( + std::remove(bt_mac_address.begin(), bt_mac_address.end(), ':'), + bt_mac_address.end()); auto& env = MediumEnvironment::Instance(); - return env.FindBluetoothDevice(mac_address); + return env.FindBluetoothDevice(absl::HexStringToBytes(bt_mac_address)); } void BluetoothClassicMedium::AddObserver( diff --git a/internal/platform/implementation/g3/bluetooth_classic.h b/internal/platform/implementation/g3/bluetooth_classic.h index 966615cd..ca815e19 100644 --- a/internal/platform/implementation/g3/bluetooth_classic.h +++ b/internal/platform/implementation/g3/bluetooth_classic.h @@ -16,6 +16,7 @@ #define PLATFORM_IMPL_G3_BLUETOOTH_CLASSIC_H_ #include +#include #include #include "absl/container/flat_hash_map.h" @@ -169,6 +170,24 @@ class BluetoothServerSocket : public api::BluetoothServerSocket { bool closed_ ABSL_GUARDED_BY(mutex_) = false; }; +// A concrete implementation for BluetoothPairing. +class BluetoothPairing : public api::BluetoothPairing { + public: + explicit BluetoothPairing(api::BluetoothDevice& remote_device); + BluetoothPairing(const BluetoothPairing&) = default; + BluetoothPairing& operator=(const BluetoothPairing&) = default; + ~BluetoothPairing() override; + + bool InitiatePairing(api::BluetoothPairingCallback pairing_cb) override; + bool FinishPairing(std::optional pin_code) override; + bool CancelPairing() override; + bool Unpair() override; + bool IsPaired() override; + + private: + api::BluetoothDevice& remote_device_; +}; + // Container of operations that can be performed over the Bluetooth Classic // medium. class BluetoothClassicMedium : public api::BluetoothClassicMedium { diff --git a/internal/platform/medium_environment.cc b/internal/platform/medium_environment.cc index ead9fcc6..b1077e7b 100644 --- a/internal/platform/medium_environment.cc +++ b/internal/platform/medium_environment.cc @@ -16,10 +16,9 @@ #include #include -#include #include #include -#include +#include #include #include #include @@ -32,6 +31,7 @@ #include "internal/platform/count_down_latch.h" #include "internal/platform/feature_flags.h" #include "internal/platform/implementation/ble_v2.h" +#include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/logging.h" #include "internal/platform/prng.h" @@ -138,7 +138,7 @@ void MediumEnvironment::OnBluetoothAdapterChangedState( } // We don't care if there is an adapter already since all we store is a // pointer. Pointer must remain valid for the duration of a Core session - // (since it is owned by the correspoinding Medium, and mediums lifetime + // (since it is owned by the corresponding Medium, and mediums lifetime // matches Core lifetime). if (enabled) { bluetooth_adapters_.emplace(&adapter, &adapter_device); @@ -562,7 +562,7 @@ void MediumEnvironment::UpdateBleV2MediumForAdvertising( BleV2MediumContext& remote_context = medium_info.second; // Do not send notification to the same medium. if (remote_medium == &medium) continue; - // Do not send notification to the medium that is not scannig. + // Do not send notification to the medium that is not scanning. if (!remote_context.scanning) continue; absl::flat_hash_set remote_scanning_service_uuids; for (auto& element : remote_context.scan_callback_map) { @@ -1216,4 +1216,138 @@ absl::optional MediumEnvironment::GetSimulatedClock() { return absl::nullopt; } +void MediumEnvironment::ConfigBluetoothPairingContext( + api::BluetoothDevice* device, api::PairingParams pairing_params) { + if (!enabled_) return; + CountDownLatch latch(1); + RunOnMediumEnvironmentThread([&]() { + BluetoothPairingContext pairing_context; + pairing_context.pairing_params = std::move(pairing_params); + devices_pairing_contexts_[device] = std::move(pairing_context); + latch.CountDown(); + }); + latch.Await(); +} + +bool MediumEnvironment::SetPairingState(api::BluetoothDevice* device, + bool paired) { + if (!enabled_) return false; + bool updated = false; + CountDownLatch latch(1); + RunOnMediumEnvironmentThread([&]() { + auto it = devices_pairing_contexts_.find(device); + if (it != devices_pairing_contexts_.end()) { + it->second.is_paired = paired; + updated = true; + } + latch.CountDown(); + }); + latch.Await(); + return updated; +} + +bool MediumEnvironment::SetPairingResult( + api::BluetoothDevice* device, + std::optional error) { + if (!enabled_) return false; + bool notified = false; + CountDownLatch latch(1); + RunOnMediumEnvironmentThread([&]() { + auto it = devices_pairing_contexts_.find(device); + if (it != devices_pairing_contexts_.end()) { + it->second.pairing_error = error; + notified = true; + } + latch.CountDown(); + }); + latch.Await(); + return notified; +} + +bool MediumEnvironment::InitiatePairing( + api::BluetoothDevice* remote_device, + api::BluetoothPairingCallback pairing_cb) { + if (!enabled_) return false; + CountDownLatch latch(1); + bool initiated = false; + BluetoothPairingContext* pairing_context = nullptr; + RunOnMediumEnvironmentThread([&]() mutable { + auto it = devices_pairing_contexts_.find(remote_device); + if (it != devices_pairing_contexts_.end()) { + pairing_context = &it->second; + initiated = true; + } + latch.CountDown(); + }); + latch.Await(); + if (!initiated) return false; + pairing_context->pairing_callback = std::move(pairing_cb); + pairing_context->pairing_callback.on_pairing_initiated_cb( + pairing_context->pairing_params); + return true; +} + +bool MediumEnvironment::FinishPairing(api::BluetoothDevice* device) { + if (!enabled_) return false; + bool finshed = false; + CountDownLatch latch(1); + BluetoothPairingContext* pairing_context = nullptr; + RunOnMediumEnvironmentThread([&]() { + auto it = devices_pairing_contexts_.find(device); + if (it != devices_pairing_contexts_.end()) { + finshed = true; + pairing_context = &it->second; + } + latch.CountDown(); + }); + latch.Await(); + if (pairing_context->pairing_error.has_value()) { + pairing_context->pairing_callback.on_pairing_error_cb( + pairing_context->pairing_error.value()); + } else { + pairing_context->is_paired = true; + pairing_context->pairing_callback.on_paired_cb(); + } + return finshed; +} + +bool MediumEnvironment::CancelPairing(api::BluetoothDevice* device) { + if (!enabled_) return false; + bool canceled = false; + CountDownLatch latch(1); + BluetoothPairingContext* pairing_context = nullptr; + RunOnMediumEnvironmentThread([&]() { + auto it = devices_pairing_contexts_.find(device); + if (it != devices_pairing_contexts_.end()) { + canceled = true; + pairing_context = &it->second; + } + latch.CountDown(); + }); + latch.Await(); + if (!canceled) return false; + pairing_context->pairing_callback.on_pairing_error_cb( + api::BluetoothPairingCallback::PairingError::kAuthCanceled); + return true; +} + +bool MediumEnvironment::IsPaired(api::BluetoothDevice* device) { + if (!enabled_) return false; + bool is_paired = false; + CountDownLatch latch(1); + RunOnMediumEnvironmentThread([&]() { + auto it = devices_pairing_contexts_.find(device); + if (it != devices_pairing_contexts_.end()) { + is_paired = it->second.is_paired; + } + latch.CountDown(); + }); + latch.Await(); + return is_paired; +} + +void MediumEnvironment::ClearBluetoothDevicesForPairing() { + if (!enabled_) return; + RunOnMediumEnvironmentThread([&]() { devices_pairing_contexts_.clear(); }); +} } // namespace nearby diff --git a/internal/platform/medium_environment.h b/internal/platform/medium_environment.h index b0865e33..b50db82c 100644 --- a/internal/platform/medium_environment.h +++ b/internal/platform/medium_environment.h @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -384,6 +385,35 @@ class MediumEnvironment { absl::optional GetSimulatedClock(); + // Configures the BluetoothPairingContext for remote BluetoothDevice. + void ConfigBluetoothPairingContext(api::BluetoothDevice* device, + api::PairingParams pairing_params); + + // Sets the current pairing states of remote BluetoothDevice. + bool SetPairingState(api::BluetoothDevice* device, bool paired); + + // Mocks the pairing result for remote BluetoothDevice. + bool SetPairingResult( + api::BluetoothDevice* device, + std::optional error); + + // Requests for pairing with remote BluetoothDevice, + // and registers BluetoothPairingCallback. + bool InitiatePairing(api::BluetoothDevice* remote_device, + api::BluetoothPairingCallback pairing_cb); + + // Finishes pairing for remote BluetoothDevice. + bool FinishPairing(api::BluetoothDevice* device); + + // Cancels ongoing pairing for remote BluetoothDevice. + bool CancelPairing(api::BluetoothDevice* device); + + // Returns the pairing states of remote BluetoothDevice. + bool IsPaired(api::BluetoothDevice* device); + + // Clears the map `devices_pairing_contexts_`. + void ClearBluetoothDevicesForPairing(); + private: struct BluetoothMediumContext { BluetoothDiscoveryCallback callback; @@ -436,6 +466,13 @@ class MediumEnvironment { HotspotCredentials* hotspot_credentials; }; + struct BluetoothPairingContext { + api::PairingParams pairing_params; + api::BluetoothPairingCallback pairing_callback; + bool is_paired = false; + std::optional pairing_error; + }; + // This is a singleton object, for which destructor will never be called. // Constructor will be invoked once from Instance() static method. // Object is create in-place (with a placement new) to guarantee that @@ -488,7 +525,8 @@ class MediumEnvironment { absl::flat_hash_map> subscribed_characteristic_; - + absl::flat_hash_map + devices_pairing_contexts_; #ifndef NO_WEBRTC // Maps peer id to callback for receiving signaling messages. absl::flat_hash_map