diff --git a/cpp/core/internal/mediums/webrtc/signaling_frames_test.cc b/cpp/core/internal/mediums/webrtc/signaling_frames_test.cc index 3e468d23..4cc4df2e 100644 --- a/cpp/core/internal/mediums/webrtc/signaling_frames_test.cc +++ b/cpp/core/internal/mediums/webrtc/signaling_frames_test.cc @@ -96,7 +96,7 @@ TEST(SignalingFramesTest, EncodeValidOffer) { TEST(SignalingFramesTest, DecodeValidOffer) { location::nearby::mediums::WebRtcSignalingFrame frame; - proto2::TextFormat::ParseFromString(kOfferProto, &frame); + proto2::TextFormat::ParseFromStringPiece(kOfferProto, &frame); Ptr decoded_offer = DecodeOffer(frame); EXPECT_EQ(webrtc::SdpType::kOffer, decoded_offer->GetType()); @@ -120,7 +120,7 @@ TEST(SignalingFramesTest, EncodeValidAnswer) { TEST(SignalingFramesTest, DecodeValidAnswer) { location::nearby::mediums::WebRtcSignalingFrame frame; - proto2::TextFormat::ParseFromString(kAnswerProto, &frame); + proto2::TextFormat::ParseFromStringPiece(kAnswerProto, &frame); Ptr decoded_answer = DecodeAnswer(frame); EXPECT_EQ(webrtc::SdpType::kAnswer, decoded_answer->GetType()); @@ -163,7 +163,7 @@ TEST(SignalingFramesTest, DecodeValidIceCandidates) { std::vector encoded_candidates_vec; location::nearby::mediums::WebRtcSignalingFrame frame; - proto2::TextFormat::ParseFromString(kIceCandidatesProto, &frame); + proto2::TextFormat::ParseFromStringPiece(kIceCandidatesProto, &frame); std::vector> decoded_candidates = DecodeIceCandidates(frame); diff --git a/cpp/core_v2/internal/base_pcp_handler.cc b/cpp/core_v2/internal/base_pcp_handler.cc index 44f6779d..12fdb676 100644 --- a/cpp/core_v2/internal/base_pcp_handler.cc +++ b/cpp/core_v2/internal/base_pcp_handler.cc @@ -9,6 +9,7 @@ #include "core_v2/internal/offline_frames.h" #include "core_v2/internal/pcp_handler.h" #include "core_v2/options.h" +#include "platform_v2/base/bluetooth_utils.h" #include "platform_v2/public/logging.h" #include "platform_v2/public/system_clock.h" #include "securegcm/d2d_connection_context_v1.h" @@ -29,11 +30,13 @@ constexpr absl::Duration BasePcpHandler::kRejectedConnectionCloseDelay; BasePcpHandler::BasePcpHandler(Mediums* mediums, EndpointManager* endpoint_manager, - EndpointChannelManager* channel_manager, Pcp pcp) + EndpointChannelManager* channel_manager, + BwuManager* bwu_manager, Pcp pcp) : mediums_(mediums), endpoint_manager_(endpoint_manager), channel_manager_(channel_manager), - pcp_(pcp) {} + pcp_(pcp), + bwu_manager_(bwu_manager) {} BasePcpHandler::~BasePcpHandler() { NEARBY_LOGS(INFO) << "BasePcpHandler: going down; strategy=" @@ -63,23 +66,23 @@ Status BasePcpHandler::StartAdvertising(ClientProxy* client, const ConnectionRequestInfo& info) { Future response; ConnectionOptions advertising_options = options.CompatibleOptions(); - RunOnPcpHandlerThread( - [this, client, &service_id, &info, &advertising_options, &response]() { - auto result = StartAdvertisingImpl( - client, service_id, client->GetLocalEndpointId(), - info.endpoint_info, advertising_options); - if (!result.status.Ok()) { - response.Set(result.status); - return; - } + RunOnPcpHandlerThread([this, client, &service_id, &info, &advertising_options, + &response]() { + auto result = + StartAdvertisingImpl(client, service_id, client->GetLocalEndpointId(), + info.endpoint_info, advertising_options); + if (!result.status.Ok()) { + response.Set(result.status); + return; + } - // Now that we've succeeded, mark the client as advertising. - advertising_options_ = advertising_options; - advertising_listener_ = info.listener; - client->StartedAdvertising(service_id, GetStrategy(), info.listener, - absl::MakeSpan(result.mediums)); - response.Set({Status::kSuccess}); - }); + // Now that we've succeeded, mark the client as advertising. + advertising_options_ = advertising_options; + advertising_listener_ = info.listener; + client->StartedAdvertising(service_id, GetStrategy(), info.listener, + absl::MakeSpan(result.mediums)); + response.Set({Status::kSuccess}); + }); return WaitForResult( absl::StrCat("StartAdvertising(", std::string(info.endpoint_info), ")"), client->GetClientId(), &response); @@ -232,8 +235,8 @@ void BasePcpHandler::OnEncryptionSuccessRunnable( .raw_authentication_token = raw_auth_token, .is_incoming_connection = connection_info.is_incoming, }, - connection_info.options, - std::move(connection_info.channel), connection_info.listener); + connection_info.options, std::move(connection_info.channel), + connection_info.listener); if (connection_info.result != nullptr) { NEARBY_LOG(INFO, "Connection established; Finalising future OK"); @@ -318,14 +321,20 @@ Status BasePcpHandler::RequestConnection(ClientProxy* client, OnEndpointFound(client, webrtc_endpoint); } - auto endpoints = GetDiscoveredEndpoints(endpoint_id); + auto discovered_endpoints = GetDiscoveredEndpoints(endpoint_id); std::unique_ptr channel; ConnectImplResult connect_impl_result; - // TODO(b/156634369): add GetRemoteBluetoothMacAddressEndpoint here for - // valid remote mac address. + auto remote_bluetooth_mac_address = + BluetoothUtils::ToString(options.remote_bluetooth_mac_address); + if (!remote_bluetooth_mac_address.empty()) { + auto additional_endpoint = GetRemoteBluetoothMacAddressEndpoint( + endpoint_id, remote_bluetooth_mac_address, discovered_endpoints); + if (additional_endpoint != nullptr) + discovered_endpoints.push_back(additional_endpoint.get()); + } - for (auto connect_endpoint : endpoints) { + for (auto connect_endpoint : discovered_endpoints) { connect_impl_result = ConnectImpl(client, connect_endpoint); if (connect_impl_result.status.Ok()) { channel = std::move(connect_impl_result.endpoint_channel); @@ -611,10 +620,6 @@ Status BasePcpHandler::RejectConnection(ClientProxy* client, client->GetClientId(), &response); } -// proto::connections::Medium BasePcpHandler::GetBandwidthUpgradeMedium() { -// return bandwidth_upgrade_medium_.Get(); -//} - void BasePcpHandler::OnIncomingFrame(OfflineFrame& frame, const std::string& endpoint_id, ClientProxy* client, @@ -928,7 +933,7 @@ void BasePcpHandler::ProcessTieBreakLoss( void BasePcpHandler::InitiateBandwidthUpgrade( ClientProxy* client, const std::string& endpoint_id, - const std::vector& supported_mediums) { + const std::vector& supported_mediums) { // When we successfully connect to a remote endpoint and a bandwidth upgrade // medium has not yet been decided, we'll pick the highest bandwidth medium // supported by both us and the remote endpoint. Once we pick a medium, all @@ -938,16 +943,14 @@ void BasePcpHandler::InitiateBandwidthUpgrade( // way to prevent mediums, like Wifi Hotspot, from interfering with active // connections (although it's suboptimal for bandwidth throughput). When all // endpoints disconnect, we reset the bandwidth upgrade medium. - if (bandwidth_upgrade_medium_.Get() == - proto::connections::Medium::UNKNOWN_MEDIUM) { - bandwidth_upgrade_medium_.Set(ChooseBestUpgradeMedium(supported_mediums)); + Medium bwu_medium = bwu_medium_.Get(); + if (bwu_medium == Medium::UNKNOWN_MEDIUM) { + bwu_medium = ChooseBestUpgradeMedium(supported_mediums); + bwu_medium_.Set(bwu_medium); } - if (AutoUpgradeBandwidth() && (bandwidth_upgrade_medium_.Get() != - proto::connections::Medium::UNKNOWN_MEDIUM)) { - // TODO(apolyudov): Bring bandwidth upgrade back, when it is ready. - // bandwidth_upgrade_->InitiateBandwidthUpgradeForEndpoint( - // client, endpoint_id, bandwidth_upgrade_medium_.Get()); + if (AutoUpgradeBandwidth() && bwu_medium != Medium::UNKNOWN_MEDIUM) { + bwu_manager_->InitiateBwuForEndpoint(client, endpoint_id, bwu_medium); } } @@ -975,6 +978,55 @@ proto::connections::Medium BasePcpHandler::ChooseBestUpgradeMedium( return proto::connections::Medium::UNKNOWN_MEDIUM; } +std::unique_ptr +BasePcpHandler::GetRemoteBluetoothMacAddressEndpoint( + std::string endpoint_id, std::string remote_bluetooth_mac_address, + std::vector endpoints) { + if (!discovery_options_.allowed.bluetooth) { + return nullptr; + } + + if (endpoints.empty()) { + NEARBY_LOGS(INFO) + << "Cannot append remote Bluetooth MAC Address, because endpointId " + << endpoint_id << " has not been discovered"; + return nullptr; + } + + for (auto endpoint : endpoints) { + if (endpoint->medium == proto::connections::Medium::BLUETOOTH) { + NEARBY_LOGS(INFO) + << "Cannot append remote Bluetooth MAC Address, because the " + "endpoint has already been found over Bluetooth."; + return nullptr; + } + } + + auto remote_bluetooth_device = + mediums_->GetBluetoothClassic().GetRemoteDevice( + remote_bluetooth_mac_address); + if (!remote_bluetooth_device.IsValid()) { + NEARBY_LOGS(INFO) + << "Cannot append remote Bluetooth MAC Address, because a valid " + "Bluetooth device could not be derived."; + return nullptr; + } + + auto bluetooth_endpoint = + std::make_unique(BluetoothEndpoint{ + { + endpoint_id, + endpoints[0]->endpoint_info, + endpoints[0]->service_id, + proto::connections::Medium::BLUETOOTH, + }, + remote_bluetooth_device, + }); + NEARBY_LOGS(INFO) << "Appended remote Bluetooth device " + << remote_bluetooth_mac_address; + return bluetooth_endpoint; +} + void BasePcpHandler::EvaluateConnectionResult(ClientProxy* client, const std::string& endpoint_id, bool can_close_immediately) { diff --git a/cpp/core_v2/internal/base_pcp_handler.h b/cpp/core_v2/internal/base_pcp_handler.h index d9ee3f92..262d92cb 100644 --- a/cpp/core_v2/internal/base_pcp_handler.h +++ b/cpp/core_v2/internal/base_pcp_handler.h @@ -6,6 +6,7 @@ #include #include +#include "core_v2/internal/bwu_manager.h" #include "core_v2/internal/client_proxy.h" #include "core_v2/internal/encryption_runner.h" #include "core_v2/internal/endpoint_channel_manager.h" @@ -81,7 +82,8 @@ class BasePcpHandler : public PcpHandler, // TODO(apolyudov): Add SecureRandom. BasePcpHandler(Mediums* mediums, EndpointManager* endpoint_manager, - EndpointChannelManager* channel_manager, Pcp pcp); + EndpointChannelManager* channel_manager, + BwuManager* bwu_manager, Pcp pcp); ~BasePcpHandler() override; BasePcpHandler(BasePcpHandler&&) = delete; BasePcpHandler& operator=(BasePcpHandler&&) = delete; @@ -90,8 +92,7 @@ class BasePcpHandler : public PcpHandler, // Notifies ConnectionListener (info.listener) in case of any event. // See // https://source.corp.google.com/piper///depot/google3/core_v2/listeners.h;l=78 - Status StartAdvertising(ClientProxy* client, - const std::string& service_id, + Status StartAdvertising(ClientProxy* client, const std::string& service_id, const ConnectionOptions& options, const ConnectionRequestInfo& info) override; @@ -102,8 +103,7 @@ class BasePcpHandler : public PcpHandler, // Starts discovery of endpoints that may be advertising. // Updates ClientProxy state once discovery started. // DiscoveryListener will get called in case of any event. - Status StartDiscovery(ClientProxy* client, - const std::string& service_id, + Status StartDiscovery(ClientProxy* client, const std::string& service_id, const ConnectionOptions& options, const DiscoveryListener& listener) override; @@ -113,16 +113,14 @@ class BasePcpHandler : public PcpHandler, // Requests a newly discovered remote endpoint it to form a connection. // Updates state on ClientProxy. - Status RequestConnection(ClientProxy* client, - const std::string& endpoint_id, + Status RequestConnection(ClientProxy* client, const std::string& endpoint_id, const ConnectionRequestInfo& info, const ConnectionOptions& options) override; // Called by either party to accept connection on their part. // Until both parties call it, connection will not reach a data phase. // Updates state in ClientProxy. - Status AcceptConnection(ClientProxy* client, - const std::string& endpoint_id, + Status AcceptConnection(ClientProxy* client, const std::string& endpoint_id, const PayloadListener& payload_listener) override; // Called by either party to reject connection on their part. @@ -139,12 +137,12 @@ class BasePcpHandler : public PcpHandler, // Called when an endpoint disconnects while we're waiting for both sides to // approve/reject the connection. // @EndpointManagerThread - void OnEndpointDisconnect(ClientProxy* client, - const std::string& endpoint_id, + void OnEndpointDisconnect(ClientProxy* client, const std::string& endpoint_id, CountDownLatch* barrier) override; Pcp GetPcp() const override { return pcp_; } Strategy GetStrategy() const override { return strategy_; } + Medium GetBwuMedium() const { return bwu_medium_.Get(); } void DisconnectFromEndpointManager(); protected: @@ -227,8 +225,7 @@ class BasePcpHandler : public PcpHandler, std::shared_ptr endpoint); // @PcpHandlerThread - void OnEndpointLost(ClientProxy* client, - const DiscoveredEndpoint& endpoint); + void OnEndpointLost(ClientProxy* client, const DiscoveredEndpoint& endpoint); Exception OnIncomingConnection( ClientProxy* client, const ByteArray& remote_endpoint_info, @@ -270,8 +267,8 @@ class BasePcpHandler : public PcpHandler, // Returns a vector of discovered endpoints, sorted in order of decreasing // preference. - std::vector - GetDiscoveredEndpoints(const std::string& endpoint_id); + std::vector GetDiscoveredEndpoints( + const std::string& endpoint_id); mediums::PeerId CreatePeerIdFromAdvertisement(const string& service_id, const string& endpoint_id, @@ -402,6 +399,11 @@ class BasePcpHandler : public PcpHandler, proto::connections::Medium ChooseBestUpgradeMedium( const std::vector& supported_mediums); + std::unique_ptr + GetRemoteBluetoothMacAddressEndpoint( + std::string endpoint_id, std::string remote_bluetooth_mac_address, + std::vector endpoints); + void ProcessPreConnectionInitiationFailure(const std::string& endpoint_id, EndpointChannel* channel, Status status, @@ -429,8 +431,7 @@ class BasePcpHandler : public PcpHandler, Status WaitForResult(const std::string& method_name, std::int64_t client_id, Future* future); - AtomicReference bandwidth_upgrade_medium_{ - proto::connections::Medium::UNKNOWN_MEDIUM}; + AtomicReference bwu_medium_{Medium::UNKNOWN_MEDIUM}; ScheduledExecutor alarm_executor_; SingleThreadExecutor serial_executor_; @@ -472,6 +473,7 @@ class BasePcpHandler : public PcpHandler, Strategy strategy_{PcpToStrategy(pcp_)}; Prng prng_; EncryptionRunner encryption_runner_; + BwuManager* bwu_manager_; EndpointManager::FrameProcessor::Handle handle_ = nullptr; }; diff --git a/cpp/core_v2/internal/base_pcp_handler_test.cc b/cpp/core_v2/internal/base_pcp_handler_test.cc index 1a580067..e939fda2 100644 --- a/cpp/core_v2/internal/base_pcp_handler_test.cc +++ b/cpp/core_v2/internal/base_pcp_handler_test.cc @@ -4,6 +4,7 @@ #include #include "core_v2/internal/base_endpoint_channel.h" +#include "core_v2/internal/bwu_manager.h" #include "core_v2/internal/client_proxy.h" #include "core_v2/internal/encryption_runner.h" #include "core_v2/internal/offline_frames.h" @@ -76,8 +77,9 @@ class MockPcpHandler : public BasePcpHandler { public: using DiscoveredEndpoint = BasePcpHandler::DiscoveredEndpoint; - MockPcpHandler(Mediums* m, EndpointManager* em, EndpointChannelManager* ecm) - : BasePcpHandler(m, em, ecm, Pcp::kP2pCluster) {} + MockPcpHandler(Mediums* m, EndpointManager* em, EndpointChannelManager* ecm, + BwuManager* bwu) + : BasePcpHandler(m, em, ecm, bwu, Pcp::kP2pCluster) {} // Expose protected inner types of a base type for mocking. using BasePcpHandler::ConnectImplResult; @@ -367,7 +369,8 @@ TEST_P(BasePcpHandlerTest, ConstructorDestructorWorks) { Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&m, &em, &ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); SUCCEED(); } @@ -376,7 +379,8 @@ TEST_P(BasePcpHandlerTest, StartAdvertisingChangesState) { Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&m, &em, &ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartAdvertising(&client, &pcp_handler); } @@ -385,7 +389,8 @@ TEST_P(BasePcpHandlerTest, StopAdvertisingChangesState) { Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&m, &em, &ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartAdvertising(&client, &pcp_handler); EXPECT_CALL(pcp_handler, StopAdvertisingImpl(&client)).Times(1); EXPECT_TRUE(client.IsAdvertising()); @@ -398,7 +403,8 @@ TEST_P(BasePcpHandlerTest, StartDiscoveryChangesState) { Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&m, &em, &ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); } @@ -407,7 +413,8 @@ TEST_P(BasePcpHandlerTest, StopDiscoveryChangesState) { Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&m, &em, &ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); EXPECT_CALL(pcp_handler, StopDiscoveryImpl(&client)).Times(1); EXPECT_TRUE(client.IsDiscovering()); @@ -421,7 +428,8 @@ TEST_P(BasePcpHandlerTest, RequestConnectionChangesState) { Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&m, &em, &ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); auto mediums = pcp_handler.GetDiscoveryMediums(); auto connect_medium = mediums[mediums.size() - 1]; @@ -444,7 +452,8 @@ TEST_P(BasePcpHandlerTest, AcceptConnectionChangesState) { Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&m, &em, &ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); auto mediums = pcp_handler.GetDiscoveryMediums(); auto connect_medium = mediums[mediums.size() - 1]; @@ -471,7 +480,8 @@ TEST_P(BasePcpHandlerTest, RejectConnectionChangesState) { Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&m, &em, &ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); auto mediums = pcp_handler.GetDiscoveryMediums(); auto connect_medium = mediums[mediums.size() - 1]; @@ -494,7 +504,8 @@ TEST_P(BasePcpHandlerTest, OnIncomingFrameChangesState) { Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&m, &em, &ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); auto mediums = pcp_handler.GetDiscoveryMediums(); auto connect_medium = mediums[mediums.size() - 1]; @@ -530,7 +541,8 @@ TEST_P(BasePcpHandlerTest, DestructorIsCalledOnProtocolEndpoint) { Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&m, &em, &ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); auto mediums = pcp_handler.GetDiscoveryMediums(); auto connect_medium = mediums[mediums.size() - 1]; @@ -569,7 +581,8 @@ TEST_P(BasePcpHandlerTest, MultipleMediumsProduceSingleEndpointLostEvent) { Mediums m; EndpointChannelManager ecm; EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&m, &em, &ecm); + BwuManager bwu(m, em, ecm, {}, {}); + MockPcpHandler pcp_handler(&m, &em, &ecm, &bwu); StartDiscovery(&client, &pcp_handler); auto mediums = pcp_handler.GetDiscoveryMediums(); auto connect_medium = mediums[mediums.size() - 1]; diff --git a/cpp/core_v2/internal/base_pcp_handler_test.cc.orig b/cpp/core_v2/internal/base_pcp_handler_test.cc.orig deleted file mode 100644 index c9009413..00000000 --- a/cpp/core_v2/internal/base_pcp_handler_test.cc.orig +++ /dev/null @@ -1,538 +0,0 @@ -#include "core_v2/internal/base_pcp_handler.h" - -#include -#include - -#include "core_v2/internal/base_endpoint_channel.h" -#include "core_v2/internal/client_proxy.h" -#include "core_v2/internal/encryption_runner.h" -#include "core_v2/internal/offline_frames.h" -#include "core_v2/listeners.h" -#include "core_v2/options.h" -#include "core_v2/params.h" -#include "proto/connections/offline_wire_formats.pb.h" -#include "platform_v2/base/byte_array.h" -#include "platform_v2/public/count_down_latch.h" -#include "platform_v2/public/pipe.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/time/time.h" - -namespace location { -namespace nearby { -namespace connections { -namespace { - -using ::location::nearby::proto::connections::Medium; -using ::testing::_; -using ::testing::AtLeast; -using ::testing::Invoke; -using ::testing::MockFunction; -using ::testing::Return; -using ::testing::StrictMock; - -constexpr BooleanMediumSelector kTestCases[] = { - BooleanMediumSelector{}, - BooleanMediumSelector{ - .bluetooth = true, - }, - BooleanMediumSelector{ - .wifi_lan = true, - }, - BooleanMediumSelector{ - .bluetooth = true, - .wifi_lan = true, - }, -}; - -class MockEndpointChannel : public BaseEndpointChannel { - public: - explicit MockEndpointChannel(Pipe* reader, Pipe* writer) - : BaseEndpointChannel("channel", &reader->GetInputStream(), - &writer->GetOutputStream()) {} - - ExceptionOr DoRead() { return BaseEndpointChannel::Read(); } - Exception DoWrite(const ByteArray& data) { - return BaseEndpointChannel::Write(data); - } - absl::Time DoGetLastReadTimestamp() { - return BaseEndpointChannel::GetLastReadTimestamp(); - } - - MOCK_METHOD(ExceptionOr, Read, (), (override)); - MOCK_METHOD(Exception, Write, (const ByteArray& data), (override)); - MOCK_METHOD(void, CloseImpl, (), (override)); - MOCK_METHOD(proto::connections::Medium, GetMedium, (), (const override)); - MOCK_METHOD(std::string, GetType, (), (const override)); - MOCK_METHOD(std::string, GetName, (), (const override)); - MOCK_METHOD(bool, IsPaused, (), (const override)); - MOCK_METHOD(void, Pause, (), (override)); - MOCK_METHOD(void, Resume, (), (override)); - MOCK_METHOD(absl::Time, GetLastReadTimestamp, (), (const override)); -}; - -class MockPcpHandler : public BasePcpHandler { - public: - using DiscoveredEndpoint = BasePcpHandler::DiscoveredEndpoint; - - MockPcpHandler(EndpointManager* em, EndpointChannelManager* ecm) - : BasePcpHandler(em, ecm, Pcp::kP2pCluster) {} - - // Expose protected inner types of a base type for mocking. - using BasePcpHandler::ConnectImplResult; - using BasePcpHandler::DiscoveredEndpoint; - using BasePcpHandler::StartOperationResult; - - MOCK_METHOD(Strategy, GetStrategy, (), (const override)); - MOCK_METHOD(Pcp, GetPcp, (), (const override)); - - MOCK_METHOD(bool, HasOutgoingConnections, (ClientProxy * client), - (const, override)); - MOCK_METHOD(bool, HasIncomingConnections, (ClientProxy * client), - (const, override)); - - MOCK_METHOD(bool, CanSendOutgoingConnection, (ClientProxy * client), - (const, override)); - MOCK_METHOD(bool, CanReceiveIncomingConnection, (ClientProxy * client), - (const, override)); - - MOCK_METHOD(StartOperationResult, StartAdvertisingImpl, - (ClientProxy * client, const string& service_id, - const string& local_endpoint_id, - const string& local_endpoint_name, - const ConnectionOptions& options), - (override)); - MOCK_METHOD(Status, StopAdvertisingImpl, (ClientProxy * client), (override)); - MOCK_METHOD(StartOperationResult, StartDiscoveryImpl, - (ClientProxy * client, const string& service_id, - const ConnectionOptions& options), - (override)); - MOCK_METHOD(Status, StopDiscoveryImpl, (ClientProxy * client), (override)); - MOCK_METHOD(ConnectImplResult, ConnectImpl, - (ClientProxy * client, DiscoveredEndpoint* endpoint), (override)); - MOCK_METHOD(proto::connections::Medium, GetDefaultUpgradeMedium, (), - (override)); - - std::vector GetConnectionMediumsByPriority() - override { - return GetDiscoveryMediums(); - } - - // Mock adapters for protected non-virtual methods of a base class. - void OnEndpointFound(ClientProxy* client, - std::shared_ptr endpoint) { - BasePcpHandler::OnEndpointFound(client, std::move(endpoint)); - } - void OnEndpointLost(ClientProxy* client, const DiscoveredEndpoint& endpoint) { - BasePcpHandler::OnEndpointLost(client, endpoint); - } - - std::vector GetDiscoveryMediums() { - std::vector mediums; - auto allowed = - BasePcpHandler::GetDiscoveryOptions().CompatibleOptions().allowed; - // Mediums are sorted in order of decreasing preference. - if (allowed.wifi_lan) - mediums.push_back(proto::connections::Medium::WIFI_LAN); - if (allowed.web_rtc) mediums.push_back(proto::connections::Medium::WEB_RTC); - if (allowed.bluetooth) - mediums.push_back(proto::connections::Medium::BLUETOOTH); - return mediums; - } - - std::vector GetDiscoveredEndpoints( - const std::string& endpoint_id) { - return BasePcpHandler::GetDiscoveredEndpoints(endpoint_id); - } -}; - -class MockContext { - public: - explicit MockContext(std::atomic_int* destroyed = nullptr) { - destroyed_ = destroyed; - } - MockContext(MockContext&&) = default; - MockContext& operator=(MockContext&&) = default; - - ~MockContext() { - if (destroyed_) (*destroyed_)++; - } - - private: - Swapper destroyed_{nullptr}; -}; - -struct MockDiscoveredEndpoint : public MockPcpHandler::DiscoveredEndpoint { - MockDiscoveredEndpoint(DiscoveredEndpoint endpoint, MockContext context) - : DiscoveredEndpoint(std::move(endpoint)), context(std::move(context)) {} - - MockContext context; -}; - -class BasePcpHandlerTest - : public ::testing::TestWithParam { - protected: - struct MockConnectionListener { - StrictMock> - initiated_cb; - StrictMock> accepted_cb; - StrictMock> - rejected_cb; - StrictMock> - disconnected_cb; - StrictMock> - bandwidth_changed_cb; - }; - struct MockDiscoveryListener { - StrictMock> - endpoint_found_cb; - StrictMock> - endpoint_lost_cb; - StrictMock< - MockFunction> - endpoint_distance_changed_cb; - }; - - void StartAdvertising(ClientProxy* client, MockPcpHandler* pcp_handler, - BooleanMediumSelector allowed = GetParam()) { - std::string service_id{"service"}; - ConnectionOptions options{ - .strategy = Strategy::kP2pCluster, - .allowed = allowed, - .auto_upgrade_bandwidth = true, - .enforce_topology_constraints = true, - }; - ConnectionRequestInfo info{ - .name = "remote_endpoint_name", - .listener = connection_listener_, - }; - EXPECT_CALL(*pcp_handler, - StartAdvertisingImpl(client, service_id, _, info.name, _)) - .WillOnce(Return(MockPcpHandler::StartOperationResult{ - .status = {Status::kSuccess}, - .mediums = {Medium::BLE}, - })); - EXPECT_EQ(pcp_handler->StartAdvertising(client, service_id, options, info), - Status{Status::kSuccess}); - EXPECT_TRUE(client->IsAdvertising()); - } - - void StartDiscovery(ClientProxy* client, MockPcpHandler* pcp_handler, - BooleanMediumSelector allowed = GetParam()) { - std::string service_id{"service"}; - ConnectionOptions options{ - .strategy = Strategy::kP2pCluster, - .allowed = allowed, - .auto_upgrade_bandwidth = true, - .enforce_topology_constraints = true, - }; - EXPECT_CALL(*pcp_handler, StartDiscoveryImpl(client, service_id, _)) - .WillOnce(Return(MockPcpHandler::StartOperationResult{ - .status = {Status::kSuccess}, - .mediums = {Medium::BLE}, - })); - EXPECT_EQ(pcp_handler->StartDiscovery(client, service_id, options, - discovery_listener_), - Status{Status::kSuccess}); - EXPECT_TRUE(client->IsDiscovering()); - } - - std::pair, - std::unique_ptr> - SetupConnection(Pipe& pipe_a, Pipe& pipe_b) { // NOLINT - auto channel_a = std::make_unique(&pipe_b, &pipe_a); - auto channel_b = std::make_unique(&pipe_a, &pipe_b); - // On initiator (A) side, we drop the first write, since this is a - // connection establishment packet, and we don't have the peer entity, just - // the peer channel. The rest of the exchange must happen for the benefit of - // DH key exchange. - EXPECT_CALL(*channel_a, Read()) - .WillRepeatedly(Invoke( - [channel = channel_a.get()]() { return channel->DoRead(); })); - EXPECT_CALL(*channel_a, Write(_)) - .WillOnce(Return(Exception{Exception::kSuccess})) - .WillRepeatedly( - Invoke([channel = channel_a.get()](const ByteArray& data) { - return channel->DoWrite(data); - })); - EXPECT_CALL(*channel_a, GetMedium).WillRepeatedly(Return(Medium::BLE)); - EXPECT_CALL(*channel_a, GetLastReadTimestamp) - .WillRepeatedly(Return(absl::Now())); - EXPECT_CALL(*channel_a, IsPaused).WillRepeatedly(Return(false)); - EXPECT_CALL(*channel_b, Read()) - .WillRepeatedly(Invoke( - [channel = channel_b.get()]() { return channel->DoRead(); })); - EXPECT_CALL(*channel_b, Write(_)) - .WillRepeatedly( - Invoke([channel = channel_b.get()](const ByteArray& data) { - return channel->DoWrite(data); - })); - EXPECT_CALL(*channel_b, GetMedium).WillRepeatedly(Return(Medium::BLE)); - EXPECT_CALL(*channel_b, GetLastReadTimestamp) - .WillRepeatedly(Return(absl::Now())); - EXPECT_CALL(*channel_b, IsPaused).WillRepeatedly(Return(false)); - return std::make_pair(std::move(channel_a), std::move(channel_b)); - } - - void RequestConnection(const std::string& endpoint_id, - std::unique_ptr channel_a, - MockEndpointChannel* channel_b, ClientProxy* client, - MockPcpHandler* pcp_handler, - std::atomic_int* flag = nullptr) { - ConnectionRequestInfo info{ - .name = "ABCD", - .listener = connection_listener_, - }; - EXPECT_CALL(mock_discovery_listener_.endpoint_found_cb, Call); - EXPECT_CALL(*pcp_handler, CanSendOutgoingConnection) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*pcp_handler, GetStrategy) - .WillRepeatedly(Return(Strategy::kP2pCluster)); - EXPECT_CALL(mock_connection_listener_.initiated_cb, Call).Times(1); - // Simulate successful discovery. - auto encryption_runner = std::make_unique(); - auto allowed_mediums = pcp_handler->GetDiscoveryMediums(); - - EXPECT_CALL(*pcp_handler, ConnectImpl) - .WillOnce(Invoke([&channel_a, medium = allowed_mediums[0]]( - ClientProxy* client, - MockPcpHandler::DiscoveredEndpoint* endpoint) { - return MockPcpHandler::ConnectImplResult{ - .medium = medium, - .status = {Status::kSuccess}, - .endpoint_channel = std::move(channel_a), - }; - })); - - for (const auto& medium : allowed_mediums) { - pcp_handler->OnEndpointFound( - client, - std::make_shared(MockDiscoveredEndpoint{ - { - endpoint_id, - info.name, - "service", - medium, - }, - MockContext{flag}, - })); - } - auto other_client = std::make_unique(); - - // Run peer crypto in advance, if channel_b is provided. - // Otherwise stay in not-encrypted state. - if (channel_b != nullptr) { - encryption_runner->StartServer(other_client.get(), endpoint_id, channel_b, - {}); - } - EXPECT_EQ(pcp_handler->RequestConnection(client, endpoint_id, info), - Status{Status::kSuccess}); - NEARBY_LOG(INFO, "Stopping Encryption Runner"); - } - - Pipe pipe_a_; - Pipe pipe_b_; - MockConnectionListener mock_connection_listener_; - MockDiscoveryListener mock_discovery_listener_; - ConnectionListener connection_listener_{ - .initiated_cb = mock_connection_listener_.initiated_cb.AsStdFunction(), - .accepted_cb = mock_connection_listener_.accepted_cb.AsStdFunction(), - .rejected_cb = mock_connection_listener_.rejected_cb.AsStdFunction(), - .disconnected_cb = - mock_connection_listener_.disconnected_cb.AsStdFunction(), - .bandwidth_changed_cb = - mock_connection_listener_.bandwidth_changed_cb.AsStdFunction(), - }; - DiscoveryListener discovery_listener_{ - .endpoint_found_cb = - mock_discovery_listener_.endpoint_found_cb.AsStdFunction(), - .endpoint_lost_cb = - mock_discovery_listener_.endpoint_lost_cb.AsStdFunction(), - .endpoint_distance_changed_cb = - mock_discovery_listener_.endpoint_distance_changed_cb.AsStdFunction(), - }; -}; - -TEST_P(BasePcpHandlerTest, ConstructorDestructorWorks) { - EndpointChannelManager ecm; - EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&em, &ecm); - SUCCEED(); -} - -TEST_P(BasePcpHandlerTest, StartAdvertisingChangesState) { - ClientProxy client; - EndpointChannelManager ecm; - EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&em, &ecm); - StartAdvertising(&client, &pcp_handler); -} - -TEST_P(BasePcpHandlerTest, StopAdvertisingChangesState) { - ClientProxy client; - EndpointChannelManager ecm; - EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&em, &ecm); - StartAdvertising(&client, &pcp_handler); - EXPECT_CALL(pcp_handler, StopAdvertisingImpl(&client)).Times(1); - EXPECT_TRUE(client.IsAdvertising()); - pcp_handler.StopAdvertising(&client); - EXPECT_FALSE(client.IsAdvertising()); -} - -TEST_P(BasePcpHandlerTest, StartDiscoveryChangesState) { - ClientProxy client; - EndpointChannelManager ecm; - EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&em, &ecm); - StartDiscovery(&client, &pcp_handler); -} - -TEST_P(BasePcpHandlerTest, StopDiscoveryChangesState) { - ClientProxy client; - EndpointChannelManager ecm; - EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&em, &ecm); - StartDiscovery(&client, &pcp_handler); - EXPECT_CALL(pcp_handler, StopDiscoveryImpl(&client)).Times(1); - EXPECT_TRUE(client.IsDiscovering()); - pcp_handler.StopDiscovery(&client); - EXPECT_FALSE(client.IsDiscovering()); -} - -TEST_P(BasePcpHandlerTest, RequestConnectionChangesState) { - std::string endpoint_id{"1234"}; - ClientProxy client; - EndpointChannelManager ecm; - EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&em, &ecm); - StartDiscovery(&client, &pcp_handler); - auto channel_pair = SetupConnection(pipe_a_, pipe_b_); - auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; - EXPECT_CALL(*channel_a, CloseImpl).Times(1); - EXPECT_CALL(*channel_b, CloseImpl).Times(1); - EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); - RequestConnection(endpoint_id, std::move(channel_a), channel_b.get(), &client, - &pcp_handler); - NEARBY_LOG(INFO, "RequestConnection complete"); - channel_b->Close(); - pcp_handler.DisconnectFromEndpointManager(); -} - -TEST_P(BasePcpHandlerTest, AcceptConnectionChangesState) { - std::string endpoint_id{"1234"}; - ClientProxy client; - EndpointChannelManager ecm; - EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&em, &ecm); - StartDiscovery(&client, &pcp_handler); - auto channel_pair = SetupConnection(pipe_a_, pipe_b_); - auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; - EXPECT_CALL(*channel_a, CloseImpl).Times(1); - EXPECT_CALL(*channel_b, CloseImpl).Times(1); - RequestConnection(endpoint_id, std::move(channel_a), channel_b.get(), &client, - &pcp_handler); - NEARBY_LOG(INFO, "Attempting to accept connection: id=%s", - endpoint_id.c_str()); - EXPECT_EQ(pcp_handler.AcceptConnection(&client, endpoint_id, {}), - Status{Status::kSuccess}); - EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); - NEARBY_LOGS(INFO) << "Closing connection: id=" << endpoint_id; - channel_b->Close(); - pcp_handler.DisconnectFromEndpointManager(); -} - -TEST_P(BasePcpHandlerTest, RejectConnectionChangesState) { - std::string endpoint_id{"1234"}; - ClientProxy client; - EndpointChannelManager ecm; - EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&em, &ecm); - StartDiscovery(&client, &pcp_handler); - auto channel_pair = SetupConnection(pipe_a_, pipe_b_); - auto& channel_b = channel_pair.second; - EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(1); - RequestConnection(endpoint_id, std::move(channel_pair.first), channel_b.get(), - &client, &pcp_handler); - NEARBY_LOGS(INFO) << "Attempting to reject connection: id=" << endpoint_id; - EXPECT_EQ(pcp_handler.RejectConnection(&client, endpoint_id), - Status{Status::kSuccess}); - NEARBY_LOGS(INFO) << "Closing connection: id=" << endpoint_id; - channel_b->Close(); - pcp_handler.DisconnectFromEndpointManager(); -} - -TEST_P(BasePcpHandlerTest, OnIncomingFrameChangesState) { - std::string endpoint_id{"1234"}; - ClientProxy client; - EndpointChannelManager ecm; - EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&em, &ecm); - StartDiscovery(&client, &pcp_handler); - auto channel_pair = SetupConnection(pipe_a_, pipe_b_); - auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; - EXPECT_CALL(*channel_a, CloseImpl).Times(1); - EXPECT_CALL(*channel_b, CloseImpl).Times(1); - RequestConnection(endpoint_id, std::move(channel_a), channel_b.get(), &client, - &pcp_handler); - NEARBY_LOGS(INFO) << "Attempting to accept connection: id=" << endpoint_id; - EXPECT_CALL(mock_connection_listener_.accepted_cb, Call).Times(1); - EXPECT_CALL(mock_connection_listener_.disconnected_cb, Call) - .Times(AtLeast(0)); - EXPECT_EQ(pcp_handler.AcceptConnection(&client, endpoint_id, {}), - Status{Status::kSuccess}); - NEARBY_LOG(INFO, "Simulating remote accept: id=%s", endpoint_id.c_str()); - auto frame = - parser::FromBytes(parser::ForConnectionResponse(Status::kSuccess)); - pcp_handler.OnIncomingFrame(frame.result(), endpoint_id, &client, - Medium::BLE); - NEARBY_LOGS(INFO) << "Closing connection: id=" << endpoint_id; - channel_b->Close(); - pcp_handler.DisconnectFromEndpointManager(); -} - -TEST_P(BasePcpHandlerTest, DestructorIsCalledOnProtocolEndpoint) { - std::atomic_int destroyed_flag = 0; - int mediums_count = 0; - { - std::string endpoint_id{"1234"}; - ClientProxy client; - EndpointChannelManager ecm; - EndpointManager em(&ecm); - MockPcpHandler pcp_handler(&em, &ecm); - StartDiscovery(&client, &pcp_handler); - auto channel_pair = SetupConnection(pipe_a_, pipe_b_); - auto& channel_a = channel_pair.first; - auto& channel_b = channel_pair.second; - EXPECT_CALL(*channel_a, CloseImpl).Times(1); - EXPECT_CALL(*channel_b, CloseImpl).Times(1); - RequestConnection(endpoint_id, std::move(channel_a), channel_b.get(), - &client, &pcp_handler, &destroyed_flag); - mediums_count = pcp_handler.GetDiscoveryMediums().size(); - NEARBY_LOG(INFO, "Attempting to accept connection: id=%s", - endpoint_id.c_str()); - EXPECT_EQ(pcp_handler.AcceptConnection(&client, endpoint_id, {}), - Status{Status::kSuccess}); - EXPECT_CALL(mock_connection_listener_.rejected_cb, Call).Times(AtLeast(0)); - NEARBY_LOG(INFO, "Closing connection: id=%s", endpoint_id.c_str()); - channel_b->Close(); - pcp_handler.DisconnectFromEndpointManager(); - } - EXPECT_EQ(destroyed_flag.load(), mediums_count); -} - -INSTANTIATE_TEST_SUITE_P(ParameterizedBasePcpHandlerTest, BasePcpHandlerTest, - ::testing::ValuesIn(kTestCases)); - -} // namespace -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/cpp/core_v2/internal/bwu_manager.cc b/cpp/core_v2/internal/bwu_manager.cc index 4564dce1..9ab910fe 100644 --- a/cpp/core_v2/internal/bwu_manager.cc +++ b/cpp/core_v2/internal/bwu_manager.cc @@ -4,6 +4,7 @@ #include "core_v2/internal/bwu_handler.h" #include "core_v2/internal/offline_frames.h" +#include "core_v2/internal/webrtc_bwu_handler.h" #include "platform_v2/base/byte_array.h" #include "platform_v2/public/count_down_latch.h" #include "proto/connections_enums.pb.h" @@ -52,7 +53,11 @@ void BwuManager::InitBwuHandlers() { .incoming_connection_cb = absl::bind_front(&BwuManager::OnIncomingConnection, this), }; - // TODO(apolyudov): inject instances of supported upgrade medium handlers. + if (config_.allow_upgrade_to.web_rtc) { + handlers_.emplace(Medium::WEB_RTC, + std::make_unique( + *mediums_, *channel_manager_, notifications)); + } } void BwuManager::Shutdown() { @@ -90,12 +95,17 @@ void BwuManager::Shutdown() { } // This is the point on the Initiator side where the -// currentBwuMedium is set. +// medium_ is set. void BwuManager::InitiateBwuForEndpoint(ClientProxy* client, - const std::string& endpoint_id) { - RunOnBwuManagerThread([this, client, endpoint_id]() { - auto* handler = SetCurrentBwuHandler(ChooseBestUpgradeMedium( - client->GetUpgradeMediums(endpoint_id).GetMediums(true))); + const std::string& endpoint_id, + Medium new_medium) { + RunOnBwuManagerThread([this, client, endpoint_id, new_medium]() { + Medium proposed_medium = ChooseBestUpgradeMedium( + client->GetUpgradeMediums(endpoint_id).GetMediums(true)); + if (new_medium != Medium::UNKNOWN_MEDIUM) { + proposed_medium = new_medium; + } + auto* handler = SetCurrentBwuHandler(proposed_medium); if (!handler) return; diff --git a/cpp/core_v2/internal/bwu_manager.h b/cpp/core_v2/internal/bwu_manager.h index 150f49d5..b97d7138 100644 --- a/cpp/core_v2/internal/bwu_manager.h +++ b/cpp/core_v2/internal/bwu_manager.h @@ -65,7 +65,8 @@ class BwuManager : public EndpointManager::FrameProcessor { // Function initiates the bandwidth upgrade and sends an // UPGRADE_PATH_AVAILABLE OfflineFrame. void InitiateBwuForEndpoint(ClientProxy* client_proxy, - const std::string& endpoint_id); + const std::string& endpoint_id, + Medium new_medium = Medium::UNKNOWN_MEDIUM); // == EndpointManager::FrameProcessor interface ==. // This is the point on the inbound BWU protocol where the handler_ is set. diff --git a/cpp/core_v2/internal/mediums/ble.cc b/cpp/core_v2/internal/mediums/ble.cc index d0ab8b16..f8c7cf8f 100644 --- a/cpp/core_v2/internal/mediums/ble.cc +++ b/cpp/core_v2/internal/mediums/ble.cc @@ -106,6 +106,7 @@ bool Ble::IsAdvertisingLocked(const std::string& service_id) { } bool Ble::StartScanning(const std::string& service_id, + const std::string& fast_advertisement_service_uuid, DiscoveredPeripheralCallback callback) { MutexLock lock(&mutex_); @@ -133,7 +134,8 @@ bool Ble::StartScanning(const std::string& service_id, return false; } - if (!medium_.StartScanning(service_id, callback)) { + if (!medium_.StartScanning(service_id, fast_advertisement_service_uuid, + callback)) { NEARBY_LOGS(INFO) << "Failed to start scan of BLE services."; return false; } diff --git a/cpp/core_v2/internal/mediums/ble.h b/cpp/core_v2/internal/mediums/ble.h index 42c1cd9c..1a6b7643 100644 --- a/cpp/core_v2/internal/mediums/ble.h +++ b/cpp/core_v2/internal/mediums/ble.h @@ -45,6 +45,7 @@ class Ble { // range through a callback. Returns true, if scanning mode was enabled, // false otherwise. bool StartScanning(const std::string& service_id, + const std::string& fast_advertisement_service_uuid, DiscoveredPeripheralCallback callback) ABSL_LOCKS_EXCLUDED(mutex_); diff --git a/cpp/core_v2/internal/mediums/ble_test.cc b/cpp/core_v2/internal/mediums/ble_test.cc index 6a2d43f0..15e24d8f 100644 --- a/cpp/core_v2/internal/mediums/ble_test.cc +++ b/cpp/core_v2/internal/mediums/ble_test.cc @@ -18,7 +18,7 @@ namespace { constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; constexpr absl::string_view kAdvertisementString{"\x0a\x0b\x0c\x0d"}; -constexpr absl::string_view kFastAdvertisementServiceUuid{"\xff\xfe"}; +constexpr absl::string_view kFastAdvertisementServiceUuid{"\xf3\xfe"}; class BleTest : public ::testing::Test { protected: @@ -61,6 +61,7 @@ TEST_F(BleTest, CanStartAdvertising) { ble_b.StartScanning( service_id, + fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&found_latch]( @@ -95,6 +96,7 @@ TEST_F(BleTest, CanStartDiscovery) { EXPECT_TRUE(ble_a.StartScanning( service_id, + fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&accept_latch]( @@ -139,6 +141,7 @@ TEST_F(BleTest, CanStartAcceptingConnectionsAndConnect) { BlePeripheral discovered_peripheral; ble_b.StartScanning( service_id, + fast_advertisement_service_uuid, { .peripheral_discovered_cb = [&found_latch, &discovered_peripheral]( diff --git a/cpp/core_v2/internal/mediums/bluetooth_classic.cc b/cpp/core_v2/internal/mediums/bluetooth_classic.cc index b6620e96..15dad66c 100644 --- a/cpp/core_v2/internal/mediums/bluetooth_classic.cc +++ b/cpp/core_v2/internal/mediums/bluetooth_classic.cc @@ -368,10 +368,10 @@ BluetoothSocket BluetoothClassic::Connect(BluetoothDevice& bluetooth_device, return socket; } -BluetoothDevice BluetoothClassic::FindRemoteDevice( +BluetoothDevice BluetoothClassic::GetRemoteDevice( const std::string& mac_address) { MutexLock lock(&mutex_); - return medium_.FindRemoteDevice(mac_address); + return medium_.GetRemoteDevice(mac_address); } std::string BluetoothClassic::GetMacAddress() const { diff --git a/cpp/core_v2/internal/mediums/bluetooth_classic.h b/cpp/core_v2/internal/mediums/bluetooth_classic.h index 3ed3a33a..29ae73e5 100644 --- a/cpp/core_v2/internal/mediums/bluetooth_classic.h +++ b/cpp/core_v2/internal/mediums/bluetooth_classic.h @@ -102,7 +102,7 @@ class BluetoothClassic { std::string GetMacAddress() const ABSL_LOCKS_EXCLUDED(mutex_); - BluetoothDevice FindRemoteDevice(const std::string& mac_address) + BluetoothDevice GetRemoteDevice(const std::string& mac_address) ABSL_LOCKS_EXCLUDED(mutex_); private: diff --git a/cpp/core_v2/internal/mediums/webrtc/connection_flow.cc b/cpp/core_v2/internal/mediums/webrtc/connection_flow.cc index 3cb4e4ca..86af87ec 100644 --- a/cpp/core_v2/internal/mediums/webrtc/connection_flow.cc +++ b/cpp/core_v2/internal/mediums/webrtc/connection_flow.cc @@ -233,8 +233,8 @@ bool ConnectionFlow::InitPeerConnection(WebRtcMedium& webrtc_medium) { Future success_future; webrtc_medium.CreatePeerConnection( &peer_connection_observer_, - [this, &success_future]( - rtc::scoped_refptr peer_connection) { + [this, success_future](rtc::scoped_refptr + peer_connection) mutable { if (!peer_connection) { success_future.Set(false); return; @@ -329,8 +329,7 @@ bool ConnectionFlow::CloseLocked() { state_ = State::kEnded; data_channel_future_.SetException({Exception::kInterrupted}); - if (peer_connection_) - peer_connection_->Close(); + if (peer_connection_) peer_connection_->Close(); data_channel_observer_.reset(); NEARBY_LOG(INFO, "Closed WebRTC connection."); diff --git a/cpp/core_v2/internal/offline_service_controller.h b/cpp/core_v2/internal/offline_service_controller.h index 03ebbc33..7b6a1c5a 100644 --- a/cpp/core_v2/internal/offline_service_controller.h +++ b/cpp/core_v2/internal/offline_service_controller.h @@ -67,9 +67,10 @@ class OfflineServiceController : public ServiceController { EndpointChannelManager channel_manager_; EndpointManager endpoint_manager_{&channel_manager_}; PayloadManager payload_manager_{endpoint_manager_}; - PcpManager pcp_manager_{mediums_, channel_manager_, endpoint_manager_}; BwuManager bwu_manager_{ mediums_, endpoint_manager_, channel_manager_, {}, {}}; + PcpManager pcp_manager_{mediums_, channel_manager_, endpoint_manager_, + bwu_manager_}; }; } // namespace connections diff --git a/cpp/core_v2/internal/offline_service_controller.h.orig b/cpp/core_v2/internal/offline_service_controller.h.orig deleted file mode 100644 index 97517fa7..00000000 --- a/cpp/core_v2/internal/offline_service_controller.h.orig +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef CORE_V2_INTERNAL_OFFLINE_SERVICE_CONTROLLER_H_ -#define CORE_V2_INTERNAL_OFFLINE_SERVICE_CONTROLLER_H_ - -#include -#include -#include - -#include "core_v2/internal/client_proxy.h" -#include "core_v2/internal/endpoint_channel_manager.h" -#include "core_v2/internal/endpoint_manager.h" -#include "core_v2/internal/mediums/mediums.h" -#include "core_v2/internal/payload_manager.h" -#include "core_v2/internal/pcp_manager.h" -#include "core_v2/internal/service_controller.h" -#include "core_v2/listeners.h" -#include "core_v2/options.h" -#include "core_v2/payload.h" -#include "core_v2/status.h" - -namespace location { -namespace nearby { -namespace connections { - -class OfflineServiceController : public ServiceController { - public: - OfflineServiceController() = default; - ~OfflineServiceController() override; - - Status StartAdvertising(ClientProxy* client, - const std::string& service_id, - const ConnectionOptions& options, - const ConnectionRequestInfo& info) override; - void StopAdvertising(ClientProxy* client) override; - - Status StartDiscovery(ClientProxy* client, - const std::string& service_id, - const ConnectionOptions& options, - const DiscoveryListener& listener) override; - void StopDiscovery(ClientProxy* client) override; - - Status RequestConnection(ClientProxy* client, - const std::string& endpoint_id, - const ConnectionRequestInfo& info, - const ConnectionOptions& options) override; - Status AcceptConnection(ClientProxy* client, - const std::string& endpoint_id, - const PayloadListener& listener) override; - Status RejectConnection(ClientProxy* client, - const std::string& endpoint_id) override; - - void InitiateBandwidthUpgrade(ClientProxy* client, - const std::string& endpoint_id) override; - - void SendPayload(ClientProxy* client, - const std::vector& endpoint_ids, - Payload payload) override; - Status CancelPayload(ClientProxy* client, - Payload::Id payload_id) override; - - void DisconnectFromEndpoint(ClientProxy* client, - const std::string& endpoint_id) override; - - void Stop(); - - private: - // Note that the order of declaration of these is crucial, because we depend - // on the destructors running (strictly) in the reverse order; a deviation - // from that will lead to crashes at runtime. - AtomicBoolean stop_{false}; - Mediums mediums_; - EndpointChannelManager channel_manager_; - EndpointManager endpoint_manager_{&channel_manager_}; - PayloadManager payload_manager_{endpoint_manager_}; - PcpManager pcp_manager_{mediums_, channel_manager_, endpoint_manager_}; -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_V2_INTERNAL_OFFLINE_SERVICE_CONTROLLER_H_ diff --git a/cpp/core_v2/internal/p2p_cluster_pcp_handler.cc b/cpp/core_v2/internal/p2p_cluster_pcp_handler.cc index a4f07de8..116a04fd 100644 --- a/cpp/core_v2/internal/p2p_cluster_pcp_handler.cc +++ b/cpp/core_v2/internal/p2p_cluster_pcp_handler.cc @@ -4,6 +4,7 @@ #include "core_v2/internal/ble_advertisement.h" #include "core_v2/internal/ble_endpoint_channel.h" #include "core_v2/internal/bluetooth_endpoint_channel.h" +#include "core_v2/internal/bwu_manager.h" #include "core_v2/internal/mediums/utils.h" #include "core_v2/internal/mediums/webrtc/webrtc_socket_wrapper.h" #include "core_v2/internal/webrtc_endpoint_channel.h" @@ -23,10 +24,22 @@ ByteArray P2pClusterPcpHandler::GenerateHash(const std::string& source, return Utils::Sha256Hash(source, size); } +bool P2pClusterPcpHandler::ShouldAdvertiseBluetoothMacOverBle( + PowerLevel power_level) { + return power_level == PowerLevel::kHighPower; +} + +bool P2pClusterPcpHandler::ShouldAcceptBluetoothConnections( + const ConnectionOptions& options) { + return options.enable_bluetooth_listening; +} + P2pClusterPcpHandler::P2pClusterPcpHandler( Mediums* mediums, EndpointManager* endpoint_manager, - EndpointChannelManager* endpoint_channel_manager, Pcp pcp) - : BasePcpHandler(mediums, endpoint_manager, endpoint_channel_manager, pcp), + EndpointChannelManager* endpoint_channel_manager, BwuManager* bwu_manager, + Pcp pcp) + : BasePcpHandler(mediums, endpoint_manager, endpoint_channel_manager, + bwu_manager, pcp), bluetooth_radio_(mediums->GetBluetoothRadio()), bluetooth_medium_(mediums->GetBluetoothClassic()), ble_medium_(mediums->GetBle()), @@ -131,10 +144,12 @@ Status P2pClusterPcpHandler::StopAdvertisingImpl(ClientProxy* client) { bluetooth_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId()); ble_medium_.StopAdvertising(client->GetAdvertisingServiceId()); + ble_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId()); webrtc_medium_.StopAcceptingConnections(); wifi_lan_medium_.StopAdvertising(client->GetAdvertisingServiceId()); + wifi_lan_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId()); return {Status::kSuccess}; } @@ -311,12 +326,11 @@ void P2pClusterPcpHandler::BlePeripheralDiscoveredHandler( return; } - // Parse the Ble advertisement bytes. + // Parse the BLE advertisement bytes. BleAdvertisement advertisement( - fast_advertisement, - peripheral.GetAdvertisementBytes(service_id)); + fast_advertisement, peripheral.GetAdvertisementBytes(service_id)); - // Make sure the Ble advertisement points to a valid + // Make sure the BLE advertisement points to a valid // endpoint we're discovering. if (!IsRecognizedBleEndpoint(service_id, advertisement)) return; @@ -343,7 +357,34 @@ void P2pClusterPcpHandler::BlePeripheralDiscoveredHandler( peripheral, })); - // TODO(b/156632928): Check for Bluetooth device with remote mac address. + // Make sure we can connect to this device via Classic Bluetooth. + std::string remote_bluetooth_mac_address = + advertisement.GetBluetoothMacAddress(); + if (remote_bluetooth_mac_address.empty()) { + NEARBY_LOGS(INFO) + << "No Bluetooth Classic MAC address found in advertisement"; + return; + } + + BluetoothDevice remote_bluetooth_device = + bluetooth_medium_.GetRemoteDevice(remote_bluetooth_mac_address); + if (!remote_bluetooth_device.IsValid()) { + NEARBY_LOGS(INFO) << "A valid Bluetooth device could not be derived from " + "the MAC address " + << remote_bluetooth_mac_address; + return; + } + + OnEndpointFound(client, + std::make_shared(BluetoothEndpoint{ + { + advertisement.GetEndpointId(), + advertisement.GetEndpointInfo(), + service_id, + proto::connections::Medium::BLUETOOTH, + }, + remote_bluetooth_device, + })); }); } @@ -547,7 +588,7 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( .peripheral_lost_cb = absl::bind_front( &P2pClusterPcpHandler::BlePeripheralLostHandler, this, client), }, - client, service_id); + client, service_id, options.fast_advertisement_service_uuid); if (ble_medium != proto::connections::UNKNOWN_MEDIUM) { NEARBY_LOG(INFO, "P2pClusterPcpHandler::StartDiscoveryImpl: Ble added"); mediums_started_successfully.push_back(ble_medium); @@ -753,51 +794,90 @@ proto::connections::Medium P2pClusterPcpHandler::StartBleAdvertising( const std::string& local_endpoint_id, const ByteArray& local_endpoint_info, const ConnectionOptions& options) { bool fast_advertisement = !options.fast_advertisement_service_uuid.empty(); + PowerLevel power_level = + options.low_power ? PowerLevel::kLowPower : PowerLevel::kHighPower; // Start listening for connections before advertising in case a connection - // request comes in very quickly. + // request comes in very quickly. BLE allows connecting over BLE itself, as + // well as advertising the Bluetooth MAC address to allow connecting over + // Bluetooth Classic. NEARBY_LOGS(INFO) << "P2pClusterPcpHandler::StartBleAdvertising: service_id=" << service_id << ": start"; - if (ble_medium_.IsAcceptingConnections(service_id)) { - NEARBY_LOGS(ERROR) << "Ble is already accepting connections for service_id=" - << service_id; - return proto::connections::UNKNOWN_MEDIUM; - } + if (!ble_medium_.IsAcceptingConnections(service_id)) { + if (!bluetooth_radio_.Enable() || + !ble_medium_.StartAcceptingConnections( + service_id, {.accepted_cb = [this, client, local_endpoint_info]( + BleSocket socket, + const std::string& service_id) { + if (!socket.IsValid()) { + NEARBY_LOG(ERROR, "Invalid socket in accept callback: name=%s", + std::string(local_endpoint_info).c_str()); + return; + } + RunOnPcpHandlerThread([this, client, local_endpoint_info, + service_id, + socket = std::move(socket)]() mutable { + std::string remote_peripheral_name = + socket.GetRemotePeripheral().GetName(); + auto channel = absl::make_unique( + remote_peripheral_name, socket); + ByteArray remote_peripheral_info = + socket.GetRemotePeripheral().GetAdvertisementBytes( + service_id); - NEARBY_LOGS(INFO) << "P2pClusterPcpHandler::StartBleAdvertising: service_id=" - << service_id << ": invoking"; - if (!bluetooth_radio_.Enable() || - !ble_medium_.StartAcceptingConnections( - service_id, - {.accepted_cb = [this, client, local_endpoint_info]( - BleSocket socket, const std::string& service_id) { - if (!socket.IsValid()) { - NEARBY_LOG(ERROR, "Invalid socket in accept callback: name=%s", - std::string(local_endpoint_info).c_str()); - return; - } - RunOnPcpHandlerThread([this, client, local_endpoint_info, - service_id, - socket = std::move(socket)]() mutable { - std::string remote_peripheral_name = - socket.GetRemotePeripheral().GetName(); - auto channel = absl::make_unique( - remote_peripheral_name, socket); - ByteArray remote_peripheral_info = - socket.GetRemotePeripheral().GetAdvertisementBytes( - service_id); - - OnIncomingConnection(client, remote_peripheral_info, - std::move(channel), - proto::connections::Medium::BLE); - }); - }})) { + OnIncomingConnection(client, remote_peripheral_info, + std::move(channel), + proto::connections::Medium::BLE); + }); + }})) { + NEARBY_LOGS(ERROR) + << "Ble failed to start accepting connections for service_id=" + << service_id; + return proto::connections::UNKNOWN_MEDIUM; + } NEARBY_LOGS(ERROR) - << "Ble failed to start accepting connections for service_id=" + << "Ble succeed to start accepting connections for service_id=" << service_id; - return proto::connections::UNKNOWN_MEDIUM; } - // TODO(b/156632928): Should check for Bluetooth connection here + + if (ShouldAdvertiseBluetoothMacOverBle(power_level) || + ShouldAcceptBluetoothConnections(options)) { + if (bluetooth_medium_.IsAvailable() && + !bluetooth_medium_.IsAcceptingConnections(service_id)) { + if (!bluetooth_radio_.Enable() || + !bluetooth_medium_.StartAcceptingConnections( + service_id, {.accepted_cb = [this, client, local_endpoint_info]( + BluetoothSocket socket) { + if (!socket.IsValid()) { + NEARBY_LOG(ERROR, + "Invalid socket in accept callback: name=%s", + std::string(local_endpoint_info).c_str()); + return; + } + RunOnPcpHandlerThread([this, client, local_endpoint_info, + socket = std::move(socket)]() mutable { + std::string remote_device_name = + socket.GetRemoteDevice().GetName(); + auto channel = absl::make_unique( + remote_device_name, socket); + ByteArray remote_device_info{remote_device_name}; + + OnIncomingConnection(client, remote_device_info, + std::move(channel), + proto::connections::Medium::BLUETOOTH); + }); + }})) { + NEARBY_LOGS(ERROR) + << "BT failed to start accepting connections for service_id=" + << service_id; + ble_medium_.StopAcceptingConnections(service_id); + return proto::connections::UNKNOWN_MEDIUM; + } + NEARBY_LOGS(ERROR) + << "BT succeed to start accepting connections for service_id=" + << service_id; + } + } NEARBY_LOG(INFO, "P2pClusterPcpHandler::StartBleAdvertising: service=%s: " @@ -814,8 +894,10 @@ proto::connections::Medium P2pClusterPcpHandler::StartBleAdvertising( } else { const ByteArray service_id_hash = GenerateHash(service_id, BleAdvertisement::kServiceIdHashLength); - // TODO(b/156632928): Should advertise Bluetooth MacAddress Over Ble std::string bluetooth_mac_address; + if (bluetooth_medium_.IsAvailable() && + ShouldAdvertiseBluetoothMacOverBle(power_level)) + bluetooth_mac_address = bluetooth_medium_.GetMacAddress(); advertisement_bytes = ByteArray(BleAdvertisement( kBleAdvertisementVersion, GetPcp(), service_id_hash, local_endpoint_id, @@ -852,9 +934,11 @@ proto::connections::Medium P2pClusterPcpHandler::StartBleAdvertising( proto::connections::Medium P2pClusterPcpHandler::StartBleScanning( BleDiscoveredPeripheralCallback callback, ClientProxy* client, - const std::string& service_id) { + const std::string& service_id, + const std::string& fast_advertisement_service_uuid) { if (bluetooth_radio_.Enable() && - ble_medium_.StartScanning(service_id, std::move(callback))) { + ble_medium_.StartScanning(service_id, fast_advertisement_service_uuid, + std::move(callback))) { NEARBY_LOGS(INFO) << "P2pClusterPcpHandler::StartBleScanning: ok"; return proto::connections::BLE; } else { diff --git a/cpp/core_v2/internal/p2p_cluster_pcp_handler.h b/cpp/core_v2/internal/p2p_cluster_pcp_handler.h index b276a3f9..687075c4 100644 --- a/cpp/core_v2/internal/p2p_cluster_pcp_handler.h +++ b/cpp/core_v2/internal/p2p_cluster_pcp_handler.h @@ -7,6 +7,7 @@ #include "core_v2/internal/base_pcp_handler.h" #include "core_v2/internal/ble_advertisement.h" #include "core_v2/internal/bluetooth_device_name.h" +#include "core_v2/internal/bwu_manager.h" #include "core_v2/internal/client_proxy.h" #include "core_v2/internal/endpoint_channel_manager.h" #include "core_v2/internal/endpoint_manager.h" @@ -38,6 +39,7 @@ class P2pClusterPcpHandler : public BasePcpHandler { public: P2pClusterPcpHandler(Mediums* mediums, EndpointManager* endpoint_manager, EndpointChannelManager* channel_manager, + BwuManager* bwu_manager, Pcp pcp = Pcp::kP2pCluster); ~P2pClusterPcpHandler() override = default; @@ -117,6 +119,9 @@ class P2pClusterPcpHandler : public BasePcpHandler { WifiLanServiceInfo::Version::kV1; static ByteArray GenerateHash(const std::string& source, size_t size); + static bool ShouldAdvertiseBluetoothMacOverBle(PowerLevel power_level); + static bool ShouldAcceptBluetoothConnections( + const ConnectionOptions& options); // Bluetooth bool IsRecognizedBluetoothEndpoint(const std::string& name_string, @@ -155,7 +160,8 @@ class P2pClusterPcpHandler : public BasePcpHandler { const ByteArray& local_endpoint_info, const ConnectionOptions& options); proto::connections::Medium StartBleScanning( BleDiscoveredPeripheralCallback callback, ClientProxy* client, - const std::string& service_id); + const std::string& service_id, + const std::string& fast_advertisement_service_uuid); BasePcpHandler::ConnectImplResult BleConnectImpl(ClientProxy* client, BleEndpoint* endpoint); diff --git a/cpp/core_v2/internal/p2p_cluster_pcp_handler_test.cc b/cpp/core_v2/internal/p2p_cluster_pcp_handler_test.cc index 51bce6df..8ac6064b 100644 --- a/cpp/core_v2/internal/p2p_cluster_pcp_handler_test.cc +++ b/cpp/core_v2/internal/p2p_cluster_pcp_handler_test.cc @@ -2,6 +2,7 @@ #include +#include "core_v2/internal/bwu_manager.h" #include "core_v2/options.h" #include "platform_v2/base/medium_environment.h" #include "platform_v2/public/count_down_latch.h" @@ -61,7 +62,8 @@ TEST_P(P2pClusterPcpHandlerTest, CanConstructOne) { Mediums mediums; EndpointChannelManager ecm; EndpointManager em(&ecm); - P2pClusterPcpHandler handler(&mediums, &em, &ecm); + BwuManager bwu(mediums, em, ecm, {}, {}); + P2pClusterPcpHandler handler(&mediums, &em, &ecm, &bwu); env_.Stop(); } @@ -73,8 +75,10 @@ TEST_P(P2pClusterPcpHandlerTest, CanConstructMultiple) { EndpointChannelManager ecm_b; EndpointManager em_a(&ecm_a); EndpointManager em_b(&ecm_b); - P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a); - P2pClusterPcpHandler handler_b(&mediums_b, &em_b, &ecm_b); + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, {}); + BwuManager bwu_b(mediums_b, em_b, ecm_b, {}, {}); + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a); + P2pClusterPcpHandler handler_b(&mediums_b, &em_b, &ecm_b, &bwu_b); env_.Stop(); } @@ -84,7 +88,8 @@ TEST_P(P2pClusterPcpHandlerTest, CanAdvertise) { Mediums mediums_a; EndpointChannelManager ecm_a; EndpointManager em_a(&ecm_a); - P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a); + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, {}); + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a); EXPECT_EQ( handler_a.StartAdvertising(&client_a_, service_id_, options_, {.endpoint_info = ByteArray{endpoint_name}}), @@ -101,8 +106,10 @@ TEST_P(P2pClusterPcpHandlerTest, CanDiscover) { EndpointChannelManager ecm_b; EndpointManager em_a(&ecm_a); EndpointManager em_b(&ecm_b); - P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a); - P2pClusterPcpHandler handler_b(&mediums_b, &em_b, &ecm_b); + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, {}); + BwuManager bwu_b(mediums_b, em_b, ecm_b, {}, {}); + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a); + P2pClusterPcpHandler handler_b(&mediums_b, &em_b, &ecm_b, &bwu_b); CountDownLatch latch(1); EXPECT_EQ( handler_a.StartAdvertising(&client_a_, service_id_, options_, @@ -141,8 +148,12 @@ TEST_P(P2pClusterPcpHandlerTest, CanConnect) { EndpointChannelManager ecm_b; EndpointManager em_a(&ecm_a); EndpointManager em_b(&ecm_b); - P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a); - P2pClusterPcpHandler handler_b(&mediums_b, &em_b, &ecm_b); + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, + {.allow_upgrade_to = {.bluetooth = true}}); + BwuManager bwu_b(mediums_b, em_b, ecm_b, {}, + {.allow_upgrade_to = {.bluetooth = true}}); + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a); + P2pClusterPcpHandler handler_b(&mediums_b, &em_b, &ecm_b, &bwu_b); CountDownLatch discover_latch(1); CountDownLatch connect_latch(2); struct DiscoveredInfo { @@ -207,6 +218,8 @@ TEST_P(P2pClusterPcpHandlerTest, CanConnect) { }, options_); EXPECT_TRUE(connect_latch.Await(absl::Milliseconds(1000)).result()); + bwu_a.Shutdown(); + bwu_b.Shutdown(); env_.Stop(); } diff --git a/cpp/core_v2/internal/p2p_point_to_point_pcp_handler.cc b/cpp/core_v2/internal/p2p_point_to_point_pcp_handler.cc index c3525bdd..0b09d8bd 100644 --- a/cpp/core_v2/internal/p2p_point_to_point_pcp_handler.cc +++ b/cpp/core_v2/internal/p2p_point_to_point_pcp_handler.cc @@ -6,8 +6,9 @@ namespace connections { P2pPointToPointPcpHandler::P2pPointToPointPcpHandler( Mediums& mediums, EndpointManager& endpoint_manager, - EndpointChannelManager& channel_manager, Pcp pcp) - : P2pStarPcpHandler(mediums, endpoint_manager, channel_manager, pcp) {} + EndpointChannelManager& channel_manager, BwuManager& bwu_manager, Pcp pcp) + : P2pStarPcpHandler(mediums, endpoint_manager, channel_manager, bwu_manager, + pcp) {} std::vector P2pPointToPointPcpHandler::GetConnectionMediumsByPriority() { diff --git a/cpp/core_v2/internal/p2p_point_to_point_pcp_handler.h b/cpp/core_v2/internal/p2p_point_to_point_pcp_handler.h index cd9cb39b..4b09ab3c 100644 --- a/cpp/core_v2/internal/p2p_point_to_point_pcp_handler.h +++ b/cpp/core_v2/internal/p2p_point_to_point_pcp_handler.h @@ -22,6 +22,7 @@ class P2pPointToPointPcpHandler : public P2pStarPcpHandler { public: P2pPointToPointPcpHandler(Mediums& mediums, EndpointManager& endpoint_manager, EndpointChannelManager& channel_manager, + BwuManager& bwu_manager, Pcp pcp = Pcp::kP2pPointToPoint); protected: diff --git a/cpp/core_v2/internal/p2p_star_pcp_handler.cc b/cpp/core_v2/internal/p2p_star_pcp_handler.cc index acb45e38..45a20d14 100644 --- a/cpp/core_v2/internal/p2p_star_pcp_handler.cc +++ b/cpp/core_v2/internal/p2p_star_pcp_handler.cc @@ -9,9 +9,9 @@ namespace connections { P2pStarPcpHandler::P2pStarPcpHandler(Mediums& mediums, EndpointManager& endpoint_manager, EndpointChannelManager& channel_manager, - Pcp pcp) - : P2pClusterPcpHandler(&mediums, &endpoint_manager, &channel_manager, pcp) { -} + BwuManager& bwu_manager, Pcp pcp) + : P2pClusterPcpHandler(&mediums, &endpoint_manager, &channel_manager, + &bwu_manager, pcp) {} std::vector P2pStarPcpHandler::GetConnectionMediumsByPriority() { diff --git a/cpp/core_v2/internal/p2p_star_pcp_handler.h b/cpp/core_v2/internal/p2p_star_pcp_handler.h index 203bfcf5..c1418ffd 100644 --- a/cpp/core_v2/internal/p2p_star_pcp_handler.h +++ b/cpp/core_v2/internal/p2p_star_pcp_handler.h @@ -25,6 +25,7 @@ class P2pStarPcpHandler : public P2pClusterPcpHandler { public: P2pStarPcpHandler(Mediums& mediums, EndpointManager& endpoint_manager, EndpointChannelManager& channel_manager, + BwuManager& bwu_manager, Pcp pcp = Pcp::kP2pStar); protected: diff --git a/cpp/core_v2/internal/pcp_manager.cc b/cpp/core_v2/internal/pcp_manager.cc index c3c62aee..3a537547 100644 --- a/cpp/core_v2/internal/pcp_manager.cc +++ b/cpp/core_v2/internal/pcp_manager.cc @@ -11,14 +11,15 @@ namespace connections { PcpManager::PcpManager(Mediums& mediums, EndpointChannelManager& channel_manager, - EndpointManager& endpoint_manager) { + EndpointManager& endpoint_manager, + BwuManager& bwu_manager) { handlers_[Pcp::kP2pCluster] = std::make_unique( - &mediums, &endpoint_manager, &channel_manager); + &mediums, &endpoint_manager, &channel_manager, &bwu_manager); handlers_[Pcp::kP2pStar] = std::make_unique( - mediums, endpoint_manager, channel_manager); + mediums, endpoint_manager, channel_manager, bwu_manager); handlers_[Pcp::kP2pPointToPoint] = std::make_unique(mediums, endpoint_manager, - channel_manager); + channel_manager, bwu_manager); } void PcpManager::DisconnectFromEndpointManager() { diff --git a/cpp/core_v2/internal/pcp_manager.h b/cpp/core_v2/internal/pcp_manager.h index ddeb4107..bb4d9991 100644 --- a/cpp/core_v2/internal/pcp_manager.h +++ b/cpp/core_v2/internal/pcp_manager.h @@ -4,6 +4,7 @@ #include #include "core_v2/internal/base_pcp_handler.h" +#include "core_v2/internal/bwu_manager.h" #include "core_v2/internal/client_proxy.h" #include "core_v2/internal/endpoint_channel_manager.h" #include "core_v2/internal/endpoint_manager.h" @@ -29,7 +30,7 @@ namespace connections { class PcpManager { public: PcpManager(Mediums& mediums, EndpointChannelManager& channel_manager, - EndpointManager& endpoint_manager); + EndpointManager& endpoint_manager, BwuManager& bwu_manager); ~PcpManager(); Status StartAdvertising(ClientProxy* client, const string& service_id, diff --git a/cpp/core_v2/internal/simulation_user.h b/cpp/core_v2/internal/simulation_user.h index 4674be0d..2b48353c 100644 --- a/cpp/core_v2/internal/simulation_user.h +++ b/cpp/core_v2/internal/simulation_user.h @@ -3,6 +3,7 @@ #include +#include "core_v2/internal/bwu_manager.h" #include "core_v2/internal/client_proxy.h" #include "core_v2/internal/endpoint_channel_manager.h" #include "core_v2/internal/endpoint_manager.h" @@ -130,7 +131,8 @@ class SimulationUser { ClientProxy client_; EndpointChannelManager ecm_; EndpointManager em_{&ecm_}; - PcpManager mgr_{mediums_, ecm_, em_}; + BwuManager bwu_{mediums_, em_, ecm_, {}, {}}; + PcpManager mgr_{mediums_, ecm_, em_, bwu_}; PayloadManager pm_{em_}; }; diff --git a/cpp/core_v2/options.h b/cpp/core_v2/options.h index 6e0b0a66..94c72f39 100644 --- a/cpp/core_v2/options.h +++ b/cpp/core_v2/options.h @@ -65,6 +65,13 @@ struct MediumSelector { // Feature On/Off switch for mediums. using BooleanMediumSelector = MediumSelector; +// Represents the various power levels that can be used, on mediums that support +// it. +enum class PowerLevel { + kHighPower = 0, + kLowPower = 1, +}; + // Connection Options: used for both Advertising and Discovery. // All fields are mutable, to make the type copy-assignable. struct ConnectionOptions { @@ -72,6 +79,8 @@ struct ConnectionOptions { BooleanMediumSelector allowed{BooleanMediumSelector().SetAll(true)}; bool auto_upgrade_bandwidth; bool enforce_topology_constraints; + bool low_power; + bool enable_bluetooth_listening; ByteArray remote_bluetooth_mac_address; std::string fast_advertisement_service_uuid; // Verify if ConnectionOptions is in a not-initialized (Empty) state. diff --git a/cpp/platform/BUILD b/cpp/platform/BUILD index 2e9bcb30..1ee1d0df 100644 --- a/cpp/platform/BUILD +++ b/cpp/platform/BUILD @@ -61,7 +61,6 @@ cc_library( visibility = [ "//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__", "//core:__subpackages__", - "//platform_v2/base:__pkg__", ], deps = [ "//absl/base", diff --git a/cpp/platform/impl/ios/BUILD b/cpp/platform/impl/ios/BUILD deleted file mode 100644 index a75790f9..00000000 --- a/cpp/platform/impl/ios/BUILD +++ /dev/null @@ -1,9 +0,0 @@ -objc_library( - name = "ios", - visibility = [ - "//googlemac/iPhone/Nearby/HelloSetup:__subpackages__", - ], - deps = [ - "//googlemac/iPhone/Shared/Nearby/Connections:Platform", - ], -) diff --git a/cpp/platform_v2/api/ble.h b/cpp/platform_v2/api/ble.h index 548aeb45..608574cf 100644 --- a/cpp/platform_v2/api/ble.h +++ b/cpp/platform_v2/api/ble.h @@ -75,6 +75,7 @@ class BleMedium { // Returns true once the BLE scan has been initiated. virtual bool StartScanning(const std::string& service_id, + const std::string& fast_advertisement_service_uuid, DiscoveredPeripheralCallback callback) = 0; // Returns true once BLE scanning for service_id is well and truly stopped; diff --git a/cpp/platform_v2/api/bluetooth_classic.h b/cpp/platform_v2/api/bluetooth_classic.h index 6dddd606..5b334830 100644 --- a/cpp/platform_v2/api/bluetooth_classic.h +++ b/cpp/platform_v2/api/bluetooth_classic.h @@ -136,7 +136,7 @@ class BluetoothClassicMedium { virtual std::unique_ptr ListenForService( const std::string& service_name, const std::string& service_uuid) = 0; - virtual BluetoothDevice* FindRemoteDevice(const std::string& mac_address) = 0; + virtual BluetoothDevice* GetRemoteDevice(const std::string& mac_address) = 0; }; } // namespace api diff --git a/cpp/platform_v2/api/platform.h b/cpp/platform_v2/api/platform.h index 2b5ca406..eee8bfad 100644 --- a/cpp/platform_v2/api/platform.h +++ b/cpp/platform_v2/api/platform.h @@ -42,7 +42,7 @@ class ImplementationPlatform { // - synchronization primitives: // - mutex (regular, and recursive) // - condition variable (must work with regular mutex only) - // - Future : to synchronize on Callable schduled to execute. + // - Future : to synchronize on Callable scheduled to execute. // - CountDownLatch : to ensure at least N threads are waiting. // - file I/O // - Logging @@ -58,8 +58,7 @@ class ImplementationPlatform { // Supports enums and integers up to 32-bit. // Does not use locking, if platform supports 32-bit atimics natively. // Does not use dynamic memory allocations in operations. - static std::unique_ptr - CreateAtomicUint32(std::uint32_t value); + static std::unique_ptr CreateAtomicUint32(std::uint32_t value); static std::unique_ptr CreateCountDownLatch( std::int32_t count); diff --git a/cpp/platform_v2/base/medium_environment.cc b/cpp/platform_v2/base/medium_environment.cc index 21d72fd7..daa06267 100644 --- a/cpp/platform_v2/base/medium_environment.cc +++ b/cpp/platform_v2/base/medium_environment.cc @@ -340,10 +340,12 @@ void MediumEnvironment::UpdateBleMediumForAdvertising( void MediumEnvironment::UpdateBleMediumForScanning( api::BleMedium& medium, const std::string& service_id, + const std::string& fast_advertisement_service_uuid, BleDiscoveredPeripheralCallback callback, bool enabled) { if (!enabled_) return; RunOnMediumEnvironmentThread( - [this, &medium, service_id, callback = std::move(callback), enabled]() { + [this, &medium, service_id, fast_advertisement_service_uuid, + callback = std::move(callback), enabled]() { auto item = ble_mediums_.find(&medium); if (item == ble_mediums_.end()) { NEARBY_LOG(INFO, @@ -353,10 +355,12 @@ void MediumEnvironment::UpdateBleMediumForScanning( } auto& context = item->second; context.discovery_callback = std::move(callback); - NEARBY_LOG(INFO, - "Update Ble medium for scanning: this=%p; medium=%p; " - "service_id=%s; enabled=%d ;", - this, &medium, service_id.c_str(), enabled); + NEARBY_LOG( + INFO, + "Update Ble medium for scanning: this=%p; medium=%p; " + "service_id=%s; fast_advertisement_service_uuid=%s; enabled=%d ;", + this, &medium, service_id.c_str(), + fast_advertisement_service_uuid.c_str(), enabled); for (auto& medium_info : ble_mediums_) { auto& local_medium = medium_info.first; auto& info = medium_info.second; diff --git a/cpp/platform_v2/base/medium_environment.h b/cpp/platform_v2/base/medium_environment.h index 875de81a..826189d1 100644 --- a/cpp/platform_v2/base/medium_environment.h +++ b/cpp/platform_v2/base/medium_environment.h @@ -151,10 +151,10 @@ class MediumEnvironment { // This should be called when discoverable state changes. // with user-specified callback when discovery is enabled, and with default // (empty) callback otherwise. - void UpdateBleMediumForScanning(api::BleMedium& medium, - const std::string& service_id, - BleDiscoveredPeripheralCallback callback, - bool enabled); + void UpdateBleMediumForScanning( + api::BleMedium& medium, const std::string& service_id, + const std::string& fast_advertisement_service_uuid, + BleDiscoveredPeripheralCallback callback, bool enabled); // Updates Accepted connection callback info to allow for dispatch of // advertising events. diff --git a/cpp/platform_v2/impl/g3/ble.cc b/cpp/platform_v2/impl/g3/ble.cc index c7bfa041..316d64fc 100644 --- a/cpp/platform_v2/impl/g3/ble.cc +++ b/cpp/platform_v2/impl/g3/ble.cc @@ -252,11 +252,15 @@ bool BleMedium::StopAdvertising(const std::string& service_id) { return true; } -bool BleMedium::StartScanning(const std::string& service_id, - DiscoveredPeripheralCallback callback) { +bool BleMedium::StartScanning( + const std::string& service_id, + const std::string& fast_advertisement_service_uuid, + DiscoveredPeripheralCallback callback) { NEARBY_LOGS(INFO) << "G3 Ble StartScanning: service_id=" << service_id; auto& env = MediumEnvironment::Instance(); - env.UpdateBleMediumForScanning(*this, service_id, std::move(callback), true); + env.UpdateBleMediumForScanning(*this, service_id, + fast_advertisement_service_uuid, + std::move(callback), true); { absl::MutexLock lock(&mutex_); scanning_info_.service_id = service_id; @@ -277,7 +281,7 @@ bool BleMedium::StopScanning(const std::string& service_id) { } auto& env = MediumEnvironment::Instance(); - env.UpdateBleMediumForScanning(*this, service_id, {}, false); + env.UpdateBleMediumForScanning(*this, service_id, {}, {}, false); return true; } diff --git a/cpp/platform_v2/impl/g3/ble.h b/cpp/platform_v2/impl/g3/ble.h index 6bdacb09..9822200d 100644 --- a/cpp/platform_v2/impl/g3/ble.h +++ b/cpp/platform_v2/impl/g3/ble.h @@ -146,6 +146,7 @@ class BleMedium : public api::BleMedium { // Returns true once the Ble scanning has been initiated. bool StartScanning(const std::string& service_id, + const std::string& fast_advertisement_service_uuid, DiscoveredPeripheralCallback callback) override ABSL_LOCKS_EXCLUDED(mutex_); diff --git a/cpp/platform_v2/impl/g3/bluetooth_classic.cc b/cpp/platform_v2/impl/g3/bluetooth_classic.cc index a0c040d3..36403954 100644 --- a/cpp/platform_v2/impl/g3/bluetooth_classic.cc +++ b/cpp/platform_v2/impl/g3/bluetooth_classic.cc @@ -240,7 +240,7 @@ BluetoothClassicMedium::ListenForService(const std::string& service_name, return socket; } -api::BluetoothDevice* BluetoothClassicMedium::FindRemoteDevice( +api::BluetoothDevice* BluetoothClassicMedium::GetRemoteDevice( const std::string& mac_address) { auto& env = MediumEnvironment::Instance(); return env.FindBluetoothDevice(mac_address); diff --git a/cpp/platform_v2/impl/g3/bluetooth_classic.h b/cpp/platform_v2/impl/g3/bluetooth_classic.h index 8d199863..0aa92c53 100644 --- a/cpp/platform_v2/impl/g3/bluetooth_classic.h +++ b/cpp/platform_v2/impl/g3/bluetooth_classic.h @@ -207,7 +207,7 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium { const std::string& service_name, const std::string& service_uuid) override ABSL_LOCKS_EXCLUDED(mutex_); - api::BluetoothDevice* FindRemoteDevice( + api::BluetoothDevice* GetRemoteDevice( const std::string& mac_address) override; private: diff --git a/cpp/platform_v2/public/ble.cc b/cpp/platform_v2/public/ble.cc index 43a81d1b..db8ab6b5 100644 --- a/cpp/platform_v2/public/ble.cc +++ b/cpp/platform_v2/public/ble.cc @@ -17,8 +17,10 @@ bool BleMedium::StopAdvertising(const std::string& service_id) { return impl_->StopAdvertising(service_id); } -bool BleMedium::StartScanning(const std::string& service_id, - DiscoveredPeripheralCallback callback) { +bool BleMedium::StartScanning( + const std::string& service_id, + const std::string& fast_advertisement_service_uuid, + DiscoveredPeripheralCallback callback) { { MutexLock lock(&mutex_); discovered_peripheral_callback_ = std::move(callback); @@ -26,6 +28,7 @@ bool BleMedium::StartScanning(const std::string& service_id, } return impl_->StartScanning( service_id, + fast_advertisement_service_uuid, { .peripheral_discovered_cb = [this](api::BlePeripheral& peripheral, diff --git a/cpp/platform_v2/public/ble.h b/cpp/platform_v2/public/ble.h index 948903af..ca9bedbb 100644 --- a/cpp/platform_v2/public/ble.h +++ b/cpp/platform_v2/public/ble.h @@ -106,6 +106,7 @@ class BleMedium final { // Returns true once the BLE scan has been initiated. bool StartScanning(const std::string& service_id, + const std::string& fast_advertisement_service_uuid, DiscoveredPeripheralCallback callback); // Returns true once BLE scanning for service_id is well and truly stopped; diff --git a/cpp/platform_v2/public/ble_test.cc b/cpp/platform_v2/public/ble_test.cc index 2af0c3de..41f6d091 100644 --- a/cpp/platform_v2/public/ble_test.cc +++ b/cpp/platform_v2/public/ble_test.cc @@ -15,7 +15,7 @@ namespace { constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; constexpr absl::string_view kAdvertisementString{"\x0a\x0b\x0c\x0d"}; -constexpr absl::string_view kFastAdvertisementServiceUuid{"\xff\xfe"}; +constexpr absl::string_view kFastAdvertisementServiceUuid{"\xf3\xfe"}; class BleMediumTest : public ::testing::Test { protected: @@ -59,6 +59,7 @@ TEST_F(BleMediumTest, CanStartAdvertising) { EXPECT_TRUE(ble_b.StartScanning( service_id, + fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&found_latch]( @@ -85,6 +86,7 @@ TEST_F(BleMediumTest, CanStartScanning) { ble_a.StartScanning( service_id, + fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&found_latch]( @@ -119,6 +121,7 @@ TEST_F(BleMediumTest, CanStopDiscovery) { ble_a.StartScanning( service_id, + fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&found_latch]( @@ -154,6 +157,7 @@ TEST_F(BleMediumTest, CanStartAcceptingConnectionsAndConnect) { BlePeripheral* discovered_peripheral = nullptr; ble_a.StartScanning( service_id, + fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&found_latch, &discovered_peripheral]( diff --git a/cpp/platform_v2/public/bluetooth_classic.h b/cpp/platform_v2/public/bluetooth_classic.h index d8bf989d..8d073f6b 100644 --- a/cpp/platform_v2/public/bluetooth_classic.h +++ b/cpp/platform_v2/public/bluetooth_classic.h @@ -188,8 +188,8 @@ class BluetoothClassicMedium final { api::BluetoothClassicMedium& GetImpl() { return *impl_; } BluetoothAdapter& GetAdapter() { return adapter_; } std::string GetMacAddress() const { return adapter_.GetMacAddress(); } - BluetoothDevice FindRemoteDevice(const std::string& mac_address) { - return BluetoothDevice(impl_->FindRemoteDevice(mac_address)); + BluetoothDevice GetRemoteDevice(const std::string& mac_address) { + return BluetoothDevice(impl_->GetRemoteDevice(mac_address)); } private: diff --git a/proto/connections/offline_wire_formats.proto b/proto/connections/offline_wire_formats.proto index c7169827..9cd1728d 100644 --- a/proto/connections/offline_wire_formats.proto +++ b/proto/connections/offline_wire_formats.proto @@ -81,8 +81,19 @@ message ConnectionResponseFrame { // // - ConnectionsStatusCodes.STATUS_OK // - ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED. - optional int32 status = 1; + optional int32 status = 1 [deprecated = true]; optional bytes handshake_data = 2; + + // Used to replace the status integer parameter with a meaningful enum item. + // Map ConnectionsStatusCodes.STATUS_OK to ACCEPT and + // ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED to REJECT. + // Flag: connection_replace_status_with_response_connectionResponseFrame + enum ResponseStatus { + UNKNOWN_RESPONSE_STATUS = 0; + ACCEPT = 1; + REJECT = 2; + } + optional ResponseStatus response = 3; } message PayloadTransferFrame { diff --git a/proto/discovery_enums.proto b/proto/discovery_enums.proto index a3ca8c3e..cc095756 100644 --- a/proto/discovery_enums.proto +++ b/proto/discovery_enums.proto @@ -11,7 +11,7 @@ option java_package = "com.google.location.nearby.proto"; option java_outer_classname = "DiscoveryEnums"; option go_api_flag = "OPEN_TO_OPAQUE_HYBRID"; // See http://go/go-api-flag. -// NEXT ID: 132 +// NEXT ID: 133 enum DiscoveryEvent { UNKNOWN_DISCOVERY_EVENT = 0; @@ -395,6 +395,10 @@ enum DiscoveryEvent { // User has seen a low battery notification. FAST_PAIR_LOW_BATTERY_NOTIFICATION_SHOWN = 131; + // Connection Tracker Manager (Baymax) recovered the connection of the + // companion app. + FAST_PAIR_CONNECTION_TRACKER_RECOVER_COMPANION_APP = 132; + // Deprecated. reserved 65, 67 to 72; } diff --git a/proto/error_code_enums.proto b/proto/error_code_enums.proto index 9296a49b..6ea1f745 100644 --- a/proto/error_code_enums.proto +++ b/proto/error_code_enums.proto @@ -408,4 +408,9 @@ enum Description { SOCKET_NOT_BOUND = 141; INVALID_REMOTE_ADDRESS = 142; SOCKET_ALREADY_BOUND = 143; + HOTSPOT_NOT_STARTED = 144; + WEBRTC_ALREADY_INITIALIZED = 145; + INVALID_WEBRTC_STATE = 146; + NULL_DATA_CHANNEL = 147; + CREATE_OFFER_FAILED = 148; }