From 4f2f9146cb389b638fb794798eb996abb58da379 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 7 Nov 2025 17:05:35 -0800 Subject: [PATCH] Add address candidates to WifiHotspotCredentials. PiperOrigin-RevId: 829628783 --- connections/implementation/BUILD | 1 + .../implementation/mediums/wifi_hotspot.cc | 4 +- .../implementation/mediums/wifi_hotspot.h | 2 +- .../mediums/wifi_hotspot_test.cc | 20 ++++--- .../wifi_hotspot_bwu_handler.cc | 30 +++++++++-- .../implementation/wifi_hotspot_bwu_test.cc | 10 ++++ internal/platform/BUILD | 1 + .../apple/Tests/GNCWifiHotspotMediumTest.mm | 20 ++++--- .../implementation/apple/wifi_hotspot.h | 2 +- .../implementation/apple/wifi_hotspot.mm | 29 ++++------- internal/platform/implementation/g3/BUILD | 1 + .../implementation/g3/wifi_hotspot.cc | 36 ++++++++----- .../platform/implementation/g3/wifi_hotspot.h | 2 +- .../platform/implementation/wifi_hotspot.h | 10 ++-- .../implementation/windows/wifi_hotspot.h | 2 +- .../windows/wifi_hotspot_medium.cc | 11 ++-- internal/platform/wifi_credential.h | 52 +++++++++++++------ internal/platform/wifi_hotspot.cc | 10 ++-- internal/platform/wifi_hotspot.h | 2 +- internal/platform/wifi_hotspot_test.cc | 36 +++++++------ 20 files changed, 175 insertions(+), 106 deletions(-) diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index 4c9c19af..7900afb0 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -265,6 +265,7 @@ cc_test( "//internal/platform:logging", "//internal/platform:test_util", "//internal/platform:types", + "//internal/platform/flags:platform_flags", "//internal/platform/implementation/g3", # build_cleaner: keep "//internal/proto/analytics:connections_log_cc_proto", "//proto:connections_enums_cc_proto", diff --git a/connections/implementation/mediums/wifi_hotspot.cc b/connections/implementation/mediums/wifi_hotspot.cc index 3df55dc2..9e98e8f3 100644 --- a/connections/implementation/mediums/wifi_hotspot.cc +++ b/connections/implementation/mediums/wifi_hotspot.cc @@ -256,7 +256,7 @@ bool WifiHotspot::IsAcceptingConnectionsLocked(const std::string& service_id) { } ErrorOr WifiHotspot::Connect( - const std::string& service_id, const std::string& ip_address, int port, + const std::string& service_id, const ServiceAddress& service_address, CancellationFlag* cancellation_flag) { MutexLock lock(&mutex_); if (service_id.empty()) { @@ -294,7 +294,7 @@ ErrorOr WifiHotspot::Connect( OperationResultCode:: CLIENT_CANCELLATION_CANCEL_WIFI_HOTSPOT_OUTGOING_CONNECTION)}; } - socket = medium_.ConnectToService(ip_address, port, cancellation_flag); + socket = medium_.ConnectToService(service_address, cancellation_flag); if (socket.IsValid()) { break; } diff --git a/connections/implementation/mediums/wifi_hotspot.h b/connections/implementation/mediums/wifi_hotspot.h index 6cfb6b60..92bcf45b 100644 --- a/connections/implementation/mediums/wifi_hotspot.h +++ b/connections/implementation/mediums/wifi_hotspot.h @@ -75,7 +75,7 @@ class WifiHotspot { // Returns socket instance. On success, WifiHotspotSocket.IsValid() return // true. ErrorOr Connect(const std::string& service_id, - const std::string& ip_address, int port, + const ServiceAddress& service_address, CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_); diff --git a/connections/implementation/mediums/wifi_hotspot_test.cc b/connections/implementation/mediums/wifi_hotspot_test.cc index 07e6413c..ab31e1fd 100644 --- a/connections/implementation/mediums/wifi_hotspot_test.cc +++ b/connections/implementation/mediums/wifi_hotspot_test.cc @@ -46,9 +46,7 @@ constexpr FeatureFlags kTestCases[] = { constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; constexpr absl::string_view kSsid{"Direct-357a2d8c"}; constexpr absl::string_view kPassword{"12345678"}; -constexpr absl::string_view kIp = "123.234.23.1"; constexpr int kFrequency = 2412; -constexpr const size_t kPort = 20; class WifiHotspotTest : public testing::TestWithParam { protected: @@ -100,7 +98,6 @@ TEST_P(WifiHotspotTest, CanStartHotspotThatOtherConnect) { env_.SetFeatureFlags(feature_flags); std::string service_id(kServiceID); - std::string ip(kIp); auto wifi_hotspot_a = std::make_unique(); auto wifi_hotspot_b = std::make_unique(); @@ -117,14 +114,17 @@ TEST_P(WifiHotspotTest, CanStartHotspotThatOtherConnect) { WifiHotspotSocket socket_client; EXPECT_FALSE(socket_client.IsValid()); + ServiceAddress service_address = { + .address = {123, 234, 23, 1}, + .port = 20, + }; CancellationFlag flag; ErrorOr socket_result = - wifi_hotspot_b->Connect(service_id, ip, kPort, &flag); + wifi_hotspot_b->Connect(service_id, service_address, &flag); EXPECT_TRUE(socket_result.has_error()); - socket_result = - wifi_hotspot_b->Connect(service_id, hotspot_credentials->GetGateway(), - hotspot_credentials->GetPort(), &flag); + socket_result = wifi_hotspot_b->Connect( + service_id, hotspot_credentials->GetAddressCandidates().back(), &flag); EXPECT_TRUE(socket_result.has_value()); EXPECT_TRUE(socket_result.value().IsValid()); @@ -137,7 +137,6 @@ TEST_P(WifiHotspotTest, CanStartHotspotThatOtherCanCancelConnect) { env_.SetFeatureFlags(feature_flags); std::string service_id(kServiceID); - std::string ip(kIp); auto wifi_hotspot_a = std::make_unique(); auto wifi_hotspot_b = std::make_unique(); @@ -155,9 +154,8 @@ TEST_P(WifiHotspotTest, CanStartHotspotThatOtherCanCancelConnect) { EXPECT_FALSE(socket_client.IsValid()); CancellationFlag flag(true); - ErrorOr socket_result = - wifi_hotspot_b->Connect(service_id, hotspot_credentials->GetGateway(), - hotspot_credentials->GetPort(), &flag); + ErrorOr socket_result = wifi_hotspot_b->Connect( + service_id, hotspot_credentials->GetAddressCandidates().back(), &flag); // If FeatureFlag is disabled, Cancelled is false as no-op. if (!feature_flags.enable_cancellation_flag) { diff --git a/connections/implementation/wifi_hotspot_bwu_handler.cc b/connections/implementation/wifi_hotspot_bwu_handler.cc index 0967f272..46440175 100644 --- a/connections/implementation/wifi_hotspot_bwu_handler.cc +++ b/connections/implementation/wifi_hotspot_bwu_handler.cc @@ -14,10 +14,18 @@ #include "connections/implementation/wifi_hotspot_bwu_handler.h" +#if !defined(_WIN32) +#include +#include +#include +#endif + #include +#include #include #include #include +#include #include "absl/functional/bind_front.h" #include "connections/implementation/base_bwu_handler.h" @@ -39,6 +47,20 @@ namespace connections { namespace { using ::location::nearby::proto::connections::OperationResultCode; + +std::vector GatewayToAddressBytes(const std::string& gateway) { + std::vector address_bytes; + // Gateway address is IPv4 only. + uint32_t address_int = inet_addr(gateway.c_str()); + if (address_int == INADDR_NONE) { + LOG(ERROR) << "Invalid gateway address"; + return address_bytes; + } + address_bytes.resize(4); + std::memcpy(address_bytes.data(), + reinterpret_cast(&address_int), 4); + return address_bytes; +} } // namespace WifiHotspotBwuHandler::WifiHotspotBwuHandler( @@ -143,9 +165,12 @@ WifiHotspotBwuHandler::CreateUpgradedEndpointChannel( OperationResultCode::CONNECTIVITY_WIFI_HOTSPOT_INVALID_CREDENTIAL)}; } + ServiceAddress service_address; + service_address.address = + GatewayToAddressBytes(hotspot_credentials.GetGateway()); + service_address.port = hotspot_credentials.GetPort(); ErrorOr socket_result = wifi_hotspot_medium_.Connect( - service_id, hotspot_credentials.GetGateway(), - hotspot_credentials.GetPort(), client->GetCancellationFlag(endpoint_id)); + service_id, service_address, client->GetCancellationFlag(endpoint_id)); if (socket_result.has_error()) { LOG(ERROR) << "WifiHotspotBwuHandler failed to connect to the WifiHotspot service(" @@ -153,7 +178,6 @@ WifiHotspotBwuHandler::CreateUpgradedEndpointChannel( << hotspot_credentials.GetPort() << ") for endpoint " << endpoint_id; return {Error(socket_result.error().operation_result_code().value())}; } - VLOG(1) << "WifiHotspotBwuHandler successfully connected to WifiHotspot service (" << hotspot_credentials.GetGateway() << ":" diff --git a/connections/implementation/wifi_hotspot_bwu_test.cc b/connections/implementation/wifi_hotspot_bwu_test.cc index e6443631..125e4028 100644 --- a/connections/implementation/wifi_hotspot_bwu_test.cc +++ b/connections/implementation/wifi_hotspot_bwu_test.cc @@ -26,10 +26,12 @@ #include "connections/implementation/mediums/mediums.h" #include "connections/implementation/offline_frames.h" #include "connections/implementation/wifi_hotspot_bwu_handler.h" +#include "internal/flags/nearby_flags.h" #include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/exception.h" #include "internal/platform/expected.h" +#include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" #include "internal/platform/single_thread_executor.h" @@ -51,6 +53,14 @@ class WifiHotspotTest : public testing::Test { protected: WifiHotspotTest() { env_.Start(); } ~WifiHotspotTest() override { env_.Stop(); } + void SetUp() override { + nearby::NearbyFlags::GetInstance().OverrideInt64FlagValue( + platform::config_package_nearby::nearby_platform_feature:: + kWifiHotspotConnectionIntervalMillis, 1); + } + void TearDown() override { + nearby::NearbyFlags::GetInstance().ResetOverridedValues(); + } MediumEnvironment& env_{MediumEnvironment::Instance()}; }; diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 5ead94ba..2d0d6cfb 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -70,6 +70,7 @@ cc_library( "//connections:partners", ], deps = [ + "//internal/platform/implementation:wifi_utils", "//proto:connections_enums_cc_proto", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/container:flat_hash_map", diff --git a/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm b/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm index 40cd82eb..90389fb1 100644 --- a/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCWifiHotspotMediumTest.mm @@ -47,6 +47,7 @@ const char kIPAddress[] = "192.168.1.2"; GNCHotspotMedium *_medium; CLLocationManagerFake *_fakeLocationManager; std::unique_ptr _hotspotMedium; + nearby::ServiceAddress _service_address; } - (void)setUp { @@ -57,6 +58,10 @@ const char kIPAddress[] = "192.168.1.2"; _fakeLocationManager = [[CLLocationManagerFake alloc] init]; _medium.locationManager = _fakeLocationManager; _hotspotMedium = std::make_unique(_medium); + _service_address = { + .address = {static_cast(192), static_cast(168), 1, 2}, + .port = 1234, + }; } - (void)tearDown { @@ -82,9 +87,8 @@ const char kIPAddress[] = "192.168.1.2"; - (void)testConnectToService { nearby::CancellationFlag cancellationFlag; - std::unique_ptr socket = - _hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag); + _hotspotMedium->ConnectToService(_service_address, &cancellationFlag); XCTAssertTrue(socket != nullptr); XCTAssertEqualObjects(_fakeNWFramework.connectedToHost.dottedRepresentation, @@ -96,7 +100,7 @@ const char kIPAddress[] = "192.168.1.2"; - (void)testInputStreamRead { nearby::CancellationFlag cancellationFlag; std::unique_ptr socket = - _hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag); + _hotspotMedium->ConnectToService(_service_address, &cancellationFlag); GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject; NSData *data = [@"TestData" dataUsingEncoding:NSUTF8StringEncoding]; fakeSocket.dataToRead = data; @@ -111,7 +115,7 @@ const char kIPAddress[] = "192.168.1.2"; - (void)testInputStreamClose { nearby::CancellationFlag cancellationFlag; std::unique_ptr socket = - _hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag); + _hotspotMedium->ConnectToService(_service_address, &cancellationFlag); GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject; nearby::Exception closeResult = socket->GetInputStream().Close(); @@ -123,7 +127,7 @@ const char kIPAddress[] = "192.168.1.2"; - (void)testOutputStreamWrite { nearby::CancellationFlag cancellationFlag; std::unique_ptr socket = - _hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag); + _hotspotMedium->ConnectToService(_service_address, &cancellationFlag); GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject; NSData *data = [@"TestData" dataUsingEncoding:NSUTF8StringEncoding]; nearby::ByteArray byteArray(reinterpret_cast(data.bytes), data.length); @@ -137,7 +141,7 @@ const char kIPAddress[] = "192.168.1.2"; - (void)testSocketClose { nearby::CancellationFlag cancellationFlag; std::unique_ptr socket = - _hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag); + _hotspotMedium->ConnectToService(_service_address, &cancellationFlag); GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject; nearby::Exception closeResult = socket->Close(); @@ -149,7 +153,7 @@ const char kIPAddress[] = "192.168.1.2"; - (void)testOutputStreamFlush { nearby::CancellationFlag cancellationFlag; std::unique_ptr socket = - _hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag); + _hotspotMedium->ConnectToService(_service_address, &cancellationFlag); nearby::Exception flushResult = socket->GetOutputStream().Flush(); @@ -159,7 +163,7 @@ const char kIPAddress[] = "192.168.1.2"; - (void)testOutputStreamClose { nearby::CancellationFlag cancellationFlag; std::unique_ptr socket = - _hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag); + _hotspotMedium->ConnectToService(_service_address, &cancellationFlag); GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject; nearby::Exception closeResult = socket->GetOutputStream().Close(); diff --git a/internal/platform/implementation/apple/wifi_hotspot.h b/internal/platform/implementation/apple/wifi_hotspot.h index 5678b377..325008e4 100644 --- a/internal/platform/implementation/apple/wifi_hotspot.h +++ b/internal/platform/implementation/apple/wifi_hotspot.h @@ -120,7 +120,7 @@ class WifiHotspotMedium : public api::WifiHotspotMedium { * otherwise. */ std::unique_ptr ConnectToService( - absl::string_view ip_address, int port, CancellationFlag* cancellation_flag) override; + const ServiceAddress& service_address, CancellationFlag* cancellation_flag) override; // IOS is not supporting WifiHotspot Server yet. bool StartWifiHotspot(HotspotCredentials* hotspot_credentials) override { return false; } diff --git a/internal/platform/implementation/apple/wifi_hotspot.mm b/internal/platform/implementation/apple/wifi_hotspot.mm index b4611aaa..d2236f88 100644 --- a/internal/platform/implementation/apple/wifi_hotspot.mm +++ b/internal/platform/implementation/apple/wifi_hotspot.mm @@ -139,26 +139,19 @@ bool WifiHotspotMedium::DisconnectWifiHotspot() { } std::unique_ptr WifiHotspotMedium::ConnectToService( - absl::string_view ip_address, int port, CancellationFlag* cancellation_flag) { + const ServiceAddress& service_address, CancellationFlag* cancellation_flag) { NSError* error = nil; GNCIPv4Address* host; - if (ip_address.size() == 4) { - // 4 bytes IP address format. - NSData* host_ip_address = [NSData dataWithBytes:ip_address.data() length:ip_address.size()]; - host = [GNCIPv4Address addressFromData:host_ip_address]; - } else { - // Dot-decimal IP address format. - // Convert the dot-decimal IP address string to a network byte order integer. - struct in_addr host_ip_address; - host_ip_address.s_addr = inet_addr(ip_address.data()); - - if (host_ip_address.s_addr == INADDR_NONE) { - GNCLoggerError(@"Invalid IP address: %.*s\n", (int)ip_address.size(), ip_address.data()); - return nil; - } - host = [GNCIPv4Address addressFromFourByteInt:host_ip_address.s_addr]; + // Only supports IPv4 address. + if (service_address.address.size() != 4) { + GNCLoggerError(@"Invalid IP address size: %lu", service_address.address.size()); + return nullptr; } + // 4 bytes IP address format. + NSData* host_ip_address = [NSData dataWithBytes:service_address.address.data() + length:service_address.address.size()]; + host = [GNCIPv4Address addressFromData:host_ip_address]; GNCLoggerInfo(@"Connect to Hotspot host server: %@", [host dottedRepresentation]); // Setup cancel listener @@ -181,14 +174,14 @@ std::unique_ptr WifiHotspotMedium::ConnectToService( } GNCNWFrameworkSocket* socket = [medium_ connectToHost:host - port:port + port:service_address.port cancelSource:cancellation_source error:&error]; if (socket != nil) { return std::make_unique(socket); } if (error != nil) { - GNCLoggerError(@"Error connecting to %@:%d: %@", host, port, error); + GNCLoggerError(@"Error connecting to %@:%d: %@", host, service_address.port, error); } return nil; } diff --git a/internal/platform/implementation/g3/BUILD b/internal/platform/implementation/g3/BUILD index c2b56807..8bdea2ea 100644 --- a/internal/platform/implementation/g3/BUILD +++ b/internal/platform/implementation/g3/BUILD @@ -110,6 +110,7 @@ cc_library( "//internal/platform:types", "//internal/platform:uuid", "//internal/platform/implementation:comm", + "//internal/platform/implementation:wifi_utils", "//internal/proto:credential_cc_proto", "//third_party/webrtc/files/stable/webrtc/api:create_modular_peer_connection_factory", "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api", diff --git a/internal/platform/implementation/g3/wifi_hotspot.cc b/internal/platform/implementation/g3/wifi_hotspot.cc index de71771c..bd3e7179 100644 --- a/internal/platform/implementation/g3/wifi_hotspot.cc +++ b/internal/platform/implementation/g3/wifi_hotspot.cc @@ -14,9 +14,11 @@ #include "internal/platform/implementation/g3/wifi_hotspot.h" +#include #include #include #include +#include #include "absl/log/check.h" #include "absl/strings/str_cat.h" @@ -27,6 +29,7 @@ #include "internal/platform/cancellation_flag_listener.h" #include "internal/platform/exception.h" #include "internal/platform/implementation/wifi_hotspot.h" +#include "internal/platform/implementation/wifi_utils.h" #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" #include "internal/platform/prng.h" @@ -113,8 +116,14 @@ Exception WifiHotspotServerSocket::DoClose() { void WifiHotspotServerSocket::PopulateHotspotCredentials( HotspotCredentials& hotspot_credentials) { absl::MutexLock lock(mutex_); - hotspot_credentials.SetGateway(ip_address_); - hotspot_credentials.SetPort(port_); + std::vector service_addresses = { + { + .port = static_cast(port_), + }, + }; + service_addresses.back().address.assign(ip_address_.begin(), + ip_address_.end()); + hotspot_credentials.SetAddressCandidates(std::move(service_addresses)); } // Code for WifiHotspotMedium @@ -199,15 +208,20 @@ bool WifiHotspotMedium::DisconnectWifiHotspot() { } std::unique_ptr WifiHotspotMedium::ConnectToService( - absl::string_view ip_address, int port, + const ServiceAddress& service_address, CancellationFlag* cancellation_flag) { - std::string socket_name = WifiHotspotServerSocket::GetName(ip_address, port); + std::string ip_address = std::string(service_address.address.data(), + service_address.address.size()); + std::string socket_name = + WifiHotspotServerSocket::GetName(ip_address, service_address.port); LOG(INFO) << "G3 WifiHotspot ConnectToService [self]: medium=" << this << ", ip address + port=" << socket_name; // First, find an instance of remote medium, that exposed this service. auto& env = MediumEnvironment::Instance(); - auto* remote_medium = - static_cast(env.GetWifiHotspotMedium({}, ip_address)); + auto* remote_medium = static_cast( + env.GetWifiHotspotMedium({}, WifiUtils::GetHumanReadableIpAddress( + {service_address.address.data(), + service_address.address.size()}))); if (remote_medium == nullptr) { return {}; } @@ -260,20 +274,14 @@ WifiHotspotMedium::ListenForService(int port) { auto& env = MediumEnvironment::Instance(); auto server_socket = std::make_unique(); - std::string dot_decimal_ip; std::string ip_address = env.GetFakeIPAddress(); if (ip_address.empty()) return nullptr; - for (auto byte : ip_address) { - absl::StrAppend(&dot_decimal_ip, absl::StrFormat("%d", byte), "."); - } - dot_decimal_ip.pop_back(); - - server_socket->SetIPAddress(dot_decimal_ip); + server_socket->SetIPAddress(ip_address); int port_to_use = port == 0 ? env.GetFakePort() : port; server_socket->SetPort(port_to_use); std::string socket_name = - WifiHotspotServerSocket::GetName(dot_decimal_ip, port_to_use); + WifiHotspotServerSocket::GetName(ip_address, port_to_use); server_socket->SetCloseNotifier([this, socket_name]() { absl::MutexLock lock(mutex_); server_sockets_.erase(socket_name); diff --git a/internal/platform/implementation/g3/wifi_hotspot.h b/internal/platform/implementation/g3/wifi_hotspot.h index 6fde38ae..75f83276 100644 --- a/internal/platform/implementation/g3/wifi_hotspot.h +++ b/internal/platform/implementation/g3/wifi_hotspot.h @@ -144,7 +144,7 @@ class WifiHotspotMedium : public api::WifiHotspotMedium { // Discoverer connects to server socket std::unique_ptr ConnectToService( - absl::string_view ip_address, int port, + const ServiceAddress& service_address, CancellationFlag* cancellation_flag) override; // Advertiser starts to listen on server socket diff --git a/internal/platform/implementation/wifi_hotspot.h b/internal/platform/implementation/wifi_hotspot.h index ea658f40..2354105d 100644 --- a/internal/platform/implementation/wifi_hotspot.h +++ b/internal/platform/implementation/wifi_hotspot.h @@ -15,9 +15,13 @@ #ifndef PLATFORM_API_WIFI_HOTSPOT_H_ #define PLATFORM_API_WIFI_HOTSPOT_H_ -#include +#include +#include +#include +#include #include "internal/platform/cancellation_flag.h" +#include "internal/platform/exception.h" #include "internal/platform/input_stream.h" #include "internal/platform/output_stream.h" #include "internal/platform/wifi_credential.h" @@ -82,7 +86,7 @@ class WifiHotspotMedium { // On success, returns a new WifiHotspotSocket. // On error, returns nullptr. virtual std::unique_ptr ConnectToService( - absl::string_view ip_address, int port, + const ServiceAddress& service_address, CancellationFlag* cancellation_flag) = 0; // Listens for incoming connection. @@ -108,7 +112,7 @@ class WifiHotspotMedium { virtual bool DisconnectWifiHotspot() = 0; // Returns the port range as a pair of min and max port. - virtual absl::optional> + virtual std::optional> GetDynamicPortRange() = 0; }; diff --git a/internal/platform/implementation/windows/wifi_hotspot.h b/internal/platform/implementation/windows/wifi_hotspot.h index bf3bef11..c6b4c34a 100644 --- a/internal/platform/implementation/windows/wifi_hotspot.h +++ b/internal/platform/implementation/windows/wifi_hotspot.h @@ -69,7 +69,7 @@ class WifiHotspotMedium : public api::WifiHotspotMedium { // Discoverer connects to server socket std::unique_ptr ConnectToService( - absl::string_view ip_address, int port, + const ServiceAddress& service_address, CancellationFlag* cancellation_flag) override; // Advertiser starts to listen on server socket diff --git a/internal/platform/implementation/windows/wifi_hotspot_medium.cc b/internal/platform/implementation/windows/wifi_hotspot_medium.cc index 9cfa61f6..67b54c8f 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_medium.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_medium.cc @@ -81,13 +81,12 @@ bool WifiHotspotMedium::IsInterfaceValid() const { } std::unique_ptr WifiHotspotMedium::ConnectToService( - absl::string_view ip_address, int port, + const ServiceAddress& service_address, CancellationFlag* cancellation_flag) { LOG(WARNING) << __func__ << " : Connect to remote service."; - if (ip_address.empty() || port == 0) { - LOG(ERROR) << "no valid service address and port to connect: " - << "ip_address = " << ip_address << ", port = " << port; + if (service_address.address.empty() || service_address.port == 0) { + LOG(ERROR) << "no valid service address and port to connect."; return nullptr; } @@ -95,8 +94,8 @@ std::unique_ptr WifiHotspotMedium::ConnectToService( platform::config_package_nearby::nearby_platform_feature:: kEnableIpv6DualStack); SocketAddress server_address(dual_stack); - if (!server_address.FromString(server_address, std::string(ip_address), - port)) { + if (!server_address.FromBytes(server_address, service_address.address, + service_address.port)) { LOG(ERROR) << "no valid service address and port to connect."; return nullptr; } diff --git a/internal/platform/wifi_credential.h b/internal/platform/wifi_credential.h index 4b9cc16f..76bb7d6c 100644 --- a/internal/platform/wifi_credential.h +++ b/internal/platform/wifi_credential.h @@ -15,12 +15,23 @@ #ifndef PLATFORM_BASE_WIFI_CREDENTIAL_H_ #define PLATFORM_BASE_WIFI_CREDENTIAL_H_ +#include #include +#include +#include #include "proto/connections_enums.pb.h" +#include "internal/platform/implementation/wifi_utils.h" namespace nearby { +struct ServiceAddress { + // IP address in MSB-first order. + // IPv4 address is 4 bytes, and IPv6 address is 16 bytes. + std::vector address; + uint16_t port; +}; + // Credentials for the currently-hosted Wifi hotspot (if any) // Class HotspotCredentials is copyable & movable class HotspotCredentials { @@ -41,40 +52,51 @@ class HotspotCredentials { std::string GetPassword() const { return password_; } void SetPassword(const std::string& password) { password_ = password; } + // Get/Set Gateway and Port have been superceded by Get/SetAddressCandidates. + // Gets IP Address in string format. // This is the IP address at which the service is provided. - std::string GetGateway() const { return gateway_; } + std::string GetGateway() const { + if (gateway_.empty() && !address_candidates_.empty()) { + return WifiUtils::GetHumanReadableIpAddress( + {reinterpret_cast( + address_candidates_.back().address.data()), + address_candidates_.back().address.size()}); + } + return gateway_; + } void SetGateway(const std::string& gateway) { gateway_ = gateway; } // Gets the Port number - int GetPort() const { return port_; } + int GetPort() const { + if (port_ == 0 && !address_candidates_.empty()) { + return address_candidates_.back().port; + } + return port_; + } + // Set port_ void SetPort(const int port) { port_ = port; } + std::vector GetAddressCandidates() const { + return address_candidates_; + } + void SetAddressCandidates(std::vector address_candidates) { + address_candidates_ = std::move(address_candidates); + } + // Gets the Frequency int GetFrequency() const { return frequency_; } // Set frequency_ void SetFrequency(int frequency) { frequency_ = frequency; } - // Gets the Band - location::nearby::proto::connections::ConnectionBand GetBand() const { - return band_; - } - - // Gets the Technology - location::nearby::proto::connections::ConnectionTechnology GetTechnology() - const { - return technology_; - } - private: std::string ssid_; std::string password_; std::string gateway_; int port_ = 0; int frequency_ = -1; - location::nearby::proto::connections::ConnectionBand band_; - location::nearby::proto::connections::ConnectionTechnology technology_; + std::vector address_candidates_; }; // Credentials for the currently-hosted WifiDirect GO (if any) diff --git a/internal/platform/wifi_hotspot.cc b/internal/platform/wifi_hotspot.cc index 3daf644c..2a7a8b28 100644 --- a/internal/platform/wifi_hotspot.cc +++ b/internal/platform/wifi_hotspot.cc @@ -14,19 +14,19 @@ #include "internal/platform/wifi_hotspot.h" -#include "absl/strings/string_view.h" #include "internal/platform/cancellation_flag.h" #include "internal/platform/logging.h" +#include "internal/platform/wifi_credential.h" namespace nearby { WifiHotspotSocket WifiHotspotMedium::ConnectToService( - absl::string_view ip_address, int port, + const ServiceAddress& service_address, CancellationFlag* cancellation_flag) { - LOG(INFO) << "WifiHotspotMedium::ConnectToService: ip address=" << ip_address - << ", port=" << port; + LOG(INFO) << "WifiHotspotMedium::ConnectToService: port=" + << service_address.port; return WifiHotspotSocket( - impl_->ConnectToService(ip_address, port, cancellation_flag)); + impl_->ConnectToService(service_address, cancellation_flag)); } } // namespace nearby diff --git a/internal/platform/wifi_hotspot.h b/internal/platform/wifi_hotspot.h index 981b7598..d5e2b1f2 100644 --- a/internal/platform/wifi_hotspot.h +++ b/internal/platform/wifi_hotspot.h @@ -156,7 +156,7 @@ class WifiHotspotMedium { // Returns a new WifiHotspotSocket by ip address and port. // On Success, WifiHotspotSocket::IsValid()returns true. - WifiHotspotSocket ConnectToService(absl::string_view ip_address, int port, + WifiHotspotSocket ConnectToService(const ServiceAddress& service_address, CancellationFlag* cancellation_flag); // Returns a new WifiHotspotServerSocket. diff --git a/internal/platform/wifi_hotspot_test.cc b/internal/platform/wifi_hotspot_test.cc index e7375e78..cdae41e1 100644 --- a/internal/platform/wifi_hotspot_test.cc +++ b/internal/platform/wifi_hotspot_test.cc @@ -51,8 +51,6 @@ constexpr FeatureFlags kTestCases[] = { constexpr absl::string_view kSsid = "Direct-357a2d8c"; constexpr absl::string_view kPassword = "b592f7d3"; -constexpr absl::string_view kIp = "123.234.23.1"; -constexpr const size_t kPort = 20; constexpr int kFrequency = 2412; constexpr absl::string_view kData = "ABCD"; constexpr const size_t kChunkSize = 10; @@ -141,8 +139,6 @@ TEST_P(WifiHotspotMediumTest, CanStartHotspotThatOtherConnect) { WifiHotspotServerSocket server_socket = wifi_hotspot_a->ListenForService(); EXPECT_TRUE(server_socket.IsValid()); server_socket.PopulateHotspotCredentials(*wifi_hotspot_a->GetCredential()); - std::string hotspot_a_ip = wifi_hotspot_a->GetCredential()->GetGateway(); - int hotspot_a_port = wifi_hotspot_a->GetCredential()->GetPort(); WifiHotspotSocket socket_a; WifiHotspotSocket socket_b; @@ -153,12 +149,17 @@ TEST_P(WifiHotspotMediumTest, CanStartHotspotThatOtherConnect) { CancellationFlag flag; SingleThreadExecutor server_executor; SingleThreadExecutor client_executor; - client_executor.Execute([&wifi_hotspot_b, &socket_b, hotspot_a_ip, - hotspot_a_port, &server_socket, &flag]() { - socket_b = wifi_hotspot_b->ConnectToService(kIp, kPort, &flag); + client_executor.Execute([&wifi_hotspot_b, &socket_b, &wifi_hotspot_a, + &server_socket, &flag]() { + ServiceAddress service_address = { + .address = {123, 234, 23, 1}, + .port = 20, + }; + socket_b = wifi_hotspot_b->ConnectToService(service_address, &flag); EXPECT_FALSE(socket_b.IsValid()); - socket_b = - wifi_hotspot_b->ConnectToService(hotspot_a_ip, hotspot_a_port, &flag); + socket_b = wifi_hotspot_b->ConnectToService( + wifi_hotspot_a->GetCredential()->GetAddressCandidates().back(), + &flag); if (!socket_b.IsValid()) { server_socket.Close(); } @@ -208,8 +209,6 @@ TEST_P(WifiHotspotMediumTest, CanStartHotspotThatOtherCanCancelConnect) { WifiHotspotServerSocket server_socket = wifi_hotspot_a->ListenForService(); EXPECT_TRUE(server_socket.IsValid()); server_socket.PopulateHotspotCredentials(*wifi_hotspot_a->GetCredential()); - std::string hotspot_a_ip = wifi_hotspot_a->GetCredential()->GetGateway(); - int hotspot_a_port = wifi_hotspot_a->GetCredential()->GetPort(); WifiHotspotSocket socket_a; WifiHotspotSocket socket_b; @@ -220,12 +219,17 @@ TEST_P(WifiHotspotMediumTest, CanStartHotspotThatOtherCanCancelConnect) { CancellationFlag flag(true); SingleThreadExecutor server_executor; SingleThreadExecutor client_executor; - client_executor.Execute([&wifi_hotspot_b, &socket_b, hotspot_a_ip, - hotspot_a_port, &server_socket, &flag]() { - socket_b = wifi_hotspot_b->ConnectToService(kIp, kPort, &flag); + client_executor.Execute([&wifi_hotspot_b, &socket_b, &wifi_hotspot_a, + &server_socket, &flag]() { + ServiceAddress service_address = { + .address = {123, 234, 23, 1}, + .port = 20, + }; + socket_b = wifi_hotspot_b->ConnectToService(service_address, &flag); EXPECT_FALSE(socket_b.IsValid()); - socket_b = - wifi_hotspot_b->ConnectToService(hotspot_a_ip, hotspot_a_port, &flag); + socket_b = wifi_hotspot_b->ConnectToService( + wifi_hotspot_a->GetCredential()->GetAddressCandidates().back(), + &flag); if (!socket_b.IsValid()) { server_socket.Close(); }