From 0575cbd15530b7fd188fec8f444cc94f071910ca Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Fri, 31 Jan 2025 14:38:27 -0800 Subject: [PATCH] Make sure got IP from hotspot PiperOrigin-RevId: 721907499 --- .../implementation/mediums/wifi_hotspot.cc | 8 +-- .../implementation/mediums/wifi_hotspot.h | 4 +- .../mediums/wifi_hotspot_test.cc | 27 ++++----- .../wifi_hotspot_bwu_handler.cc | 55 +++++++++++-------- .../platform/implementation/windows/utils.cc | 33 +++++++++++ .../platform/implementation/windows/utils.h | 4 +- .../windows/wifi_hotspot_medium.cc | 20 ++++++- internal/platform/wifi_hotspot.cc | 8 ++- internal/platform/wifi_hotspot.h | 12 ++-- internal/platform/wifi_hotspot_test.cc | 26 +++++---- 10 files changed, 123 insertions(+), 74 deletions(-) diff --git a/connections/implementation/mediums/wifi_hotspot.cc b/connections/implementation/mediums/wifi_hotspot.cc index caaa0cac..8157bc6f 100644 --- a/connections/implementation/mediums/wifi_hotspot.cc +++ b/connections/implementation/mediums/wifi_hotspot.cc @@ -100,17 +100,15 @@ bool WifiHotspot::IsConnectedToHotspot() { return is_connected_to_hotspot_; } -bool WifiHotspot::ConnectWifiHotspot(const std::string& ssid, - const std::string& password, - int frequency) { +bool WifiHotspot::ConnectWifiHotspot( + const HotspotCredentials& hotspot_credentials) { MutexLock lock(&mutex_); if (is_connected_to_hotspot_) { NEARBY_LOGS(INFO) << "No need to connect to Hotspot because it is already connected."; return true; } - is_connected_to_hotspot_ = - medium_.ConnectWifiHotspot(ssid, password, frequency); + is_connected_to_hotspot_ = medium_.ConnectWifiHotspot(hotspot_credentials); return is_connected_to_hotspot_; } diff --git a/connections/implementation/mediums/wifi_hotspot.h b/connections/implementation/mediums/wifi_hotspot.h index dca7fcd8..6cfb6b60 100644 --- a/connections/implementation/mediums/wifi_hotspot.h +++ b/connections/implementation/mediums/wifi_hotspot.h @@ -53,8 +53,8 @@ class WifiHotspot { bool StopWifiHotspot() ABSL_LOCKS_EXCLUDED(mutex_); bool IsConnectedToHotspot() ABSL_LOCKS_EXCLUDED(mutex_); - bool ConnectWifiHotspot(const std::string& ssid, const std::string& password, - int frequency) ABSL_LOCKS_EXCLUDED(mutex_); + bool ConnectWifiHotspot(const HotspotCredentials& hotspot_credentials) + ABSL_LOCKS_EXCLUDED(mutex_); bool DisconnectWifiHotspot() ABSL_LOCKS_EXCLUDED(mutex_); // Starts a worker thread, creates a WifiHotspot socket, associates it with a diff --git a/connections/implementation/mediums/wifi_hotspot_test.cc b/connections/implementation/mediums/wifi_hotspot_test.cc index 48455d03..07e6413c 100644 --- a/connections/implementation/mediums/wifi_hotspot_test.cc +++ b/connections/implementation/mediums/wifi_hotspot_test.cc @@ -56,9 +56,7 @@ class WifiHotspotTest : public testing::TestWithParam { env_.Stop(); env_.Start(); } - ~WifiHotspotTest() override{ - env_.Stop(); - } + ~WifiHotspotTest() override { env_.Stop(); } MediumEnvironment& env_{MediumEnvironment::Instance()}; }; @@ -89,10 +87,11 @@ TEST_F(WifiHotspotTest, CanStartStopHotspot) { TEST_F(WifiHotspotTest, CanConnectDisconnectHotspot) { auto wifi_hotspot_a = std::make_unique(); - std::string ssid(kSsid); - std::string password(kPassword); + HotspotCredentials hotspot_credentials; + hotspot_credentials.SetSSID(std::string(kSsid)); + hotspot_credentials.SetPassword(std::string(kPassword)); - EXPECT_FALSE(wifi_hotspot_a->ConnectWifiHotspot(ssid, password, kFrequency)); + EXPECT_FALSE(wifi_hotspot_a->ConnectWifiHotspot(hotspot_credentials)); EXPECT_TRUE(wifi_hotspot_a->DisconnectWifiHotspot()); } @@ -113,9 +112,7 @@ TEST_P(WifiHotspotTest, CanStartHotspotThatOtherConnect) { HotspotCredentials* hotspot_credentials = wifi_hotspot_a->GetCredentials(service_id); - EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot( - hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword(), - hotspot_credentials->GetFrequency())); + EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot(*hotspot_credentials)); WifiHotspotSocket socket_client; EXPECT_FALSE(socket_client.IsValid()); @@ -152,9 +149,7 @@ TEST_P(WifiHotspotTest, CanStartHotspotThatOtherCanCancelConnect) { HotspotCredentials* hotspot_credentials = wifi_hotspot_a->GetCredentials(service_id); - EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot( - hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword(), - hotspot_credentials->GetFrequency())); + EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot(*hotspot_credentials)); WifiHotspotSocket socket_client; EXPECT_FALSE(socket_client.IsValid()); @@ -183,10 +178,10 @@ TEST_F(WifiHotspotTest, CanStartHotspotTheOtherFailConnect) { EXPECT_TRUE(wifi_hotspot_a->StartWifiHotspot()); - std::string ssid(kSsid); - std::string password(kPassword); - - EXPECT_FALSE(wifi_hotspot_b->ConnectWifiHotspot(ssid, password, kFrequency)); + HotspotCredentials hotspot_credentials; + hotspot_credentials.SetSSID(std::string(kSsid)); + hotspot_credentials.SetPassword(std::string(kPassword)); + EXPECT_FALSE(wifi_hotspot_b->ConnectWifiHotspot(hotspot_credentials)); EXPECT_TRUE(wifi_hotspot_b->DisconnectWifiHotspot()); EXPECT_TRUE(wifi_hotspot_a->StopWifiHotspot()); diff --git a/connections/implementation/wifi_hotspot_bwu_handler.cc b/connections/implementation/wifi_hotspot_bwu_handler.cc index 48c033f5..6bf20a56 100644 --- a/connections/implementation/wifi_hotspot_bwu_handler.cc +++ b/connections/implementation/wifi_hotspot_bwu_handler.cc @@ -53,7 +53,7 @@ ByteArray WifiHotspotBwuHandler::HandleInitializeUpgradedMediumForEndpoint( const std::string& endpoint_id) { // Create SoftAP if (!wifi_hotspot_medium_.StartWifiHotspot()) { - NEARBY_LOGS(INFO) << "Failed to start Wifi Hotspot!"; + LOG(INFO) << "Failed to start Wifi Hotspot!"; return {}; } @@ -63,14 +63,14 @@ ByteArray WifiHotspotBwuHandler::HandleInitializeUpgradedMediumForEndpoint( absl::bind_front( &WifiHotspotBwuHandler::OnIncomingWifiHotspotConnection, this, client))) { - NEARBY_LOGS(ERROR) + LOG(ERROR) << "WifiHotspotBwuHandler couldn't initiate WifiHotspot upgrade for " << "service " << upgrade_service_id << " and endpoint " << endpoint_id << " because it failed to start listening for incoming WifiLan " "connections."; return {}; } - NEARBY_LOGS(INFO) + LOG(INFO) << "WifiHotspotBwuHandler successfully started listening for incoming " "WifiHotspot connections while upgrading endpoint " << endpoint_id; @@ -87,9 +87,9 @@ ByteArray WifiHotspotBwuHandler::HandleInitializeUpgradedMediumForEndpoint( std::int32_t port = hotspot_crendential->GetPort(); std::int32_t frequency = hotspot_crendential->GetFrequency(); - NEARBY_LOGS(INFO) << "Start SoftAP with SSID:" << ssid - << ", Password:" << password << ", Port:" << port - << ", Gateway:" << gateway << ", Frequency:" << frequency; + LOG(INFO) << "Start SoftAP with SSID:" << ssid << ", Password:" << password + << ", Port:" << port << ", Gateway:" << gateway + << ", Frequency:" << frequency; bool disabling_encryption = (client->GetAdvertisingOptions().strategy == Strategy::kP2pPointToPoint); @@ -104,9 +104,8 @@ void WifiHotspotBwuHandler::HandleRevertInitiatorStateForService( wifi_hotspot_medium_.StopWifiHotspot(); wifi_hotspot_medium_.DisconnectWifiHotspot(); - NEARBY_LOGS(INFO) - << "WifiHotspotBwuHandler successfully reverted all states for " - << "upgrade service ID " << upgrade_service_id; + LOG(INFO) << "WifiHotspotBwuHandler successfully reverted all states for " + << "upgrade service ID " << upgrade_service_id; } // Called by BWU target. Retrieves a new medium info from incoming message, @@ -116,41 +115,49 @@ WifiHotspotBwuHandler::CreateUpgradedEndpointChannel( ClientProxy* client, const std::string& service_id, const std::string& endpoint_id, const UpgradePathInfo& upgrade_path_info) { if (!upgrade_path_info.has_wifi_hotspot_credentials()) { - NEARBY_LOGS(INFO) << "No Hotspot Credential"; + LOG(INFO) << "No Hotspot Credential"; return {Error( OperationResultCode::CONNECTIVITY_WIFI_HOTSPOT_INVALID_CREDENTIAL)}; } const UpgradePathInfo::WifiHotspotCredentials& upgrade_path_info_credentials = upgrade_path_info.wifi_hotspot_credentials(); - const std::string& ssid = upgrade_path_info_credentials.ssid(); - const std::string& password = upgrade_path_info_credentials.password(); - const std::string& gateway = upgrade_path_info_credentials.gateway(); - std::int32_t port = upgrade_path_info_credentials.port(); - std::int32_t frequency = upgrade_path_info_credentials.frequency(); + HotspotCredentials hotspot_credentials; + hotspot_credentials.SetSSID(upgrade_path_info_credentials.ssid()); + hotspot_credentials.SetPassword(upgrade_path_info_credentials.password()); + hotspot_credentials.SetGateway(upgrade_path_info_credentials.gateway()); + hotspot_credentials.SetPort(upgrade_path_info_credentials.port()); + hotspot_credentials.SetFrequency(upgrade_path_info_credentials.frequency()); - NEARBY_LOGS(INFO) << "Received Hotspot credential SSID: " << ssid - << ", Password:" << password << ", Port:" << port - << ", Gateway:" << gateway << ", Frequency:" << frequency; + LOG(INFO) << "Received Hotspot credential SSID: " + << hotspot_credentials.GetSSID() + << ", Password:" << hotspot_credentials.GetPassword() + << ", Port:" << hotspot_credentials.GetPort() + << ", Gateway:" << hotspot_credentials.GetGateway() + << ", Frequency:" << hotspot_credentials.GetFrequency(); - if (!wifi_hotspot_medium_.ConnectWifiHotspot(ssid, password, frequency)) { - NEARBY_LOGS(ERROR) << "Connect to Hotspot failed"; + if (!wifi_hotspot_medium_.ConnectWifiHotspot(hotspot_credentials)) { + LOG(ERROR) << "Connect to Hotspot failed"; return {Error( OperationResultCode::CONNECTIVITY_WIFI_HOTSPOT_INVALID_CREDENTIAL)}; } ErrorOr socket_result = wifi_hotspot_medium_.Connect( - service_id, gateway, port, client->GetCancellationFlag(endpoint_id)); + service_id, hotspot_credentials.GetGateway(), + hotspot_credentials.GetPort(), client->GetCancellationFlag(endpoint_id)); if (socket_result.has_error()) { - NEARBY_LOGS(ERROR) + LOG(ERROR) << "WifiHotspotBwuHandler failed to connect to the WifiHotspot service(" - << gateway << ":" << port << ") for endpoint " << endpoint_id; + << hotspot_credentials.GetGateway() << ":" + << hotspot_credentials.GetPort() << ") for endpoint " << endpoint_id; return {Error(socket_result.error().operation_result_code().value())}; } NEARBY_VLOG(1) << "WifiHotspotBwuHandler successfully connected to WifiHotspot service (" - << gateway << ":" << port << ") while upgrading endpoint " << endpoint_id; + << hotspot_credentials.GetGateway() << ":" + << hotspot_credentials.GetPort() << ") while upgrading endpoint " + << endpoint_id; // Create a new WifiHotspotEndpointChannel. auto channel = std::make_unique( diff --git a/internal/platform/implementation/windows/utils.cc b/internal/platform/implementation/windows/utils.cc index b3826678..8672d6a8 100644 --- a/internal/platform/implementation/windows/utils.cc +++ b/internal/platform/implementation/windows/utils.cc @@ -172,6 +172,39 @@ std::vector Get4BytesIpv4Addresses() { return result; } +std::vector GetWifiIpv4Addresses() { + std::vector result; + + try { + auto host_names = NetworkInformation::GetHostNames(); + for (const auto& host_name : host_names) { + if (host_name.IPInformation() != nullptr && + host_name.IPInformation().NetworkAdapter() != nullptr && + host_name.Type() == HostNameType::Ipv4) { + NetworkAdapter adapter = host_name.IPInformation().NetworkAdapter(); + if (adapter.NetworkItem().GetNetworkTypes() == NetworkTypes::None) { + // If we're not connected to a network, we don't want to add this + // address. + continue; + } + if (adapter.IanaInterfaceType() == Constants::kInterfaceTypeWifi) { + result.push_back(winrt::to_string(host_name.ToString())); + } + } + } + } catch (std::exception exception) { + LOG(ERROR) << __func__ << ": Cannot get IPv4 addresses. Exception : " + << exception.what(); + } catch (const winrt::hresult_error& error) { + LOG(ERROR) << __func__ << ": Cannot get IPv4 addresses. WinRT exception: " + << error.code() << ": " << winrt::to_string(error.message()); + } catch (...) { + LOG(ERROR) << __func__ << ": Unknown exeption."; + } + + return result; +} + Uuid winrt_guid_to_nearby_uuid(const ::winrt::guid& guid) { int64_t data1 = guid.Data1; int64_t data2 = guid.Data2; diff --git a/internal/platform/implementation/windows/utils.h b/internal/platform/implementation/windows/utils.h index 61d6f5e6..e0dd5b42 100644 --- a/internal/platform/implementation/windows/utils.h +++ b/internal/platform/implementation/windows/utils.h @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -44,6 +45,7 @@ ByteArray Sha256(absl::string_view input, size_t size); // Reads the IPv4 addresses std::vector GetIpv4Addresses(); std::vector Get4BytesIpv4Addresses(); +std::vector GetWifiIpv4Addresses(); // Help methods to convert between Uuid and winrt::guid Uuid winrt_guid_to_nearby_uuid(const ::winrt::guid& guid); @@ -51,7 +53,7 @@ winrt::guid nearby_uuid_to_winrt_guid(Uuid uuid); // Check whether Uuid and guid is the same value. bool is_nearby_uuid_equal_to_winrt_guid(const Uuid& uuid, - const ::winrt::guid& guid); + const ::winrt::guid& guid); namespace Constants { // The Id of the Service Name SDP attribute diff --git a/internal/platform/implementation/windows/wifi_hotspot_medium.cc b/internal/platform/implementation/windows/wifi_hotspot_medium.cc index 408acdcf..b8a7702a 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_medium.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_medium.cc @@ -718,18 +718,32 @@ bool WifiHotspotMedium::ConnectWifiHotspotWithNative( // Make sure IP address is ready. std::string ip_address; - int64_t ip_address_max_retries = 20; - int64_t ip_address_retry_interval_millis = 500; + int64_t ip_address_max_retries = NearbyFlags::GetInstance().GetInt64Flag( + platform::config_package_nearby::nearby_platform_feature:: + kWifiHotspotCheckIpMaxRetries); + int64_t ip_address_retry_interval_millis = + NearbyFlags::GetInstance().GetInt64Flag( + platform::config_package_nearby::nearby_platform_feature:: + kWifiHotspotCheckIpIntervalMillis); LOG(INFO) << "maximum IP check retries=" << ip_address_max_retries << ", IP check interval=" << ip_address_retry_interval_millis << "ms"; for (int i = 0; i < ip_address_max_retries; i++) { LOG(INFO) << "Check IP address at attempt " << i; - std::vector ip_addresses = GetIpv4Addresses(); + std::vector ip_addresses = GetWifiIpv4Addresses(); + if (ip_addresses.empty()) { Sleep(ip_address_retry_interval_millis); continue; } + + // Need to filter out the APIPA address("169.254.x.x"). + if (ip_addresses[0].starts_with("169.254.")) { + LOG(WARNING) << "Got APIPA address " << ip_addresses[0]; + Sleep(ip_address_retry_interval_millis); + continue; + } + ip_address = ip_addresses[0]; break; } diff --git a/internal/platform/wifi_hotspot.cc b/internal/platform/wifi_hotspot.cc index 91d5f82d..3daf644c 100644 --- a/internal/platform/wifi_hotspot.cc +++ b/internal/platform/wifi_hotspot.cc @@ -14,15 +14,17 @@ #include "internal/platform/wifi_hotspot.h" -#include "internal/platform/mutex_lock.h" +#include "absl/strings/string_view.h" +#include "internal/platform/cancellation_flag.h" +#include "internal/platform/logging.h" namespace nearby { WifiHotspotSocket WifiHotspotMedium::ConnectToService( absl::string_view ip_address, int port, CancellationFlag* cancellation_flag) { - NEARBY_LOGS(INFO) << "WifiHotspotMedium::ConnectToService: ip address=" - << ip_address << ", port=" << port; + LOG(INFO) << "WifiHotspotMedium::ConnectToService: ip address=" << ip_address + << ", port=" << port; return WifiHotspotSocket( impl_->ConnectToService(ip_address, port, cancellation_flag)); } diff --git a/internal/platform/wifi_hotspot.h b/internal/platform/wifi_hotspot.h index 187d50da..dd04de55 100644 --- a/internal/platform/wifi_hotspot.h +++ b/internal/platform/wifi_hotspot.h @@ -21,6 +21,7 @@ #include #include +#include "absl/base/thread_annotations.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "internal/platform/cancellation_flag.h" @@ -183,19 +184,14 @@ class WifiHotspotMedium { } bool StopWifiHotspot() { return impl_->StopWifiHotspot(); } - bool ConnectWifiHotspot(const std::string& ssid, - const std::string& password, int frequency) { + bool ConnectWifiHotspot(const HotspotCredentials& hotspot_credentials) { MutexLock lock(&mutex_); - hotspot_credentials_.SetSSID(ssid); - hotspot_credentials_.SetPassword(password); - hotspot_credentials_.SetFrequency(frequency); + hotspot_credentials_ = hotspot_credentials; return impl_->ConnectWifiHotspot(&hotspot_credentials_); } bool DisconnectWifiHotspot() { return impl_->DisconnectWifiHotspot(); } - HotspotCredentials* GetCredential() { - return &hotspot_credentials_; - } + HotspotCredentials* GetCredential() { return &hotspot_credentials_; } bool IsInterfaceValid() const { CHECK(impl_); diff --git a/internal/platform/wifi_hotspot_test.cc b/internal/platform/wifi_hotspot_test.cc index 262f3098..e2839488 100644 --- a/internal/platform/wifi_hotspot_test.cc +++ b/internal/platform/wifi_hotspot_test.cc @@ -14,12 +14,15 @@ #include "internal/platform/wifi_hotspot.h" +#include #include +#include #include #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" +#include "absl/strings/string_view.h" #include "absl/time/clock.h" #include "internal/platform/byte_array.h" #include "internal/platform/cancellation_flag.h" @@ -29,6 +32,7 @@ #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" #include "internal/platform/output_stream.h" +#include "internal/platform/single_thread_executor.h" #include "internal/platform/wifi_credential.h" namespace nearby { @@ -112,11 +116,12 @@ TEST_F(WifiHotspotMediumTest, CanStartStopHotspot) { TEST_F(WifiHotspotMediumTest, CanConnectDisconnectHotspot) { auto wifi_hotspot_a = std::make_unique(); - std::string ssid(kSsid); - std::string password(kPassword); + HotspotCredentials hotspot_credentials; + hotspot_credentials.SetSSID(std::string(kSsid)); + hotspot_credentials.SetPassword(std::string(kPassword)); ASSERT_TRUE(wifi_hotspot_a->IsInterfaceValid()); - EXPECT_FALSE(wifi_hotspot_a->ConnectWifiHotspot(ssid, password, kFrequency)); + EXPECT_FALSE(wifi_hotspot_a->ConnectWifiHotspot(hotspot_credentials)); EXPECT_TRUE(wifi_hotspot_a->DisconnectWifiHotspot()); wifi_hotspot_a.reset(); } @@ -131,9 +136,7 @@ TEST_P(WifiHotspotMediumTest, CanStartHotspotThatOtherConnect) { ASSERT_TRUE(wifi_hotspot_b->IsInterfaceValid()); EXPECT_TRUE(wifi_hotspot_a->StartWifiHotspot()); HotspotCredentials* hotspot_credentials = wifi_hotspot_a->GetCredential(); - EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot( - hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword(), - hotspot_credentials->GetFrequency())); + EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot(*hotspot_credentials)); WifiHotspotServerSocket server_socket = wifi_hotspot_a->ListenForService(); EXPECT_TRUE(server_socket.IsValid()); @@ -198,9 +201,7 @@ TEST_P(WifiHotspotMediumTest, CanStartHotspotThatOtherCanCancelConnect) { ASSERT_TRUE(wifi_hotspot_b->IsInterfaceValid()); EXPECT_TRUE(wifi_hotspot_a->StartWifiHotspot()); HotspotCredentials* hotspot_credentials = wifi_hotspot_a->GetCredential(); - EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot( - hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword(), - hotspot_credentials->GetFrequency())); + EXPECT_TRUE(wifi_hotspot_b->ConnectWifiHotspot(*hotspot_credentials)); WifiHotspotServerSocket server_socket = wifi_hotspot_a->ListenForService(); EXPECT_TRUE(server_socket.IsValid()); @@ -256,10 +257,11 @@ TEST_F(WifiHotspotMediumTest, CanStartHotspotTheOtherFailConnect) { ASSERT_TRUE(wifi_hotspot_b->IsInterfaceValid()); EXPECT_TRUE(wifi_hotspot_a->StartWifiHotspot()); - std::string ssid(kSsid); - std::string password(kPassword); + HotspotCredentials hotspot_credentials; + hotspot_credentials.SetSSID(std::string(kSsid)); + hotspot_credentials.SetPassword(std::string(kPassword)); - EXPECT_FALSE(wifi_hotspot_b->ConnectWifiHotspot(ssid, password, kFrequency)); + EXPECT_FALSE(wifi_hotspot_b->ConnectWifiHotspot(hotspot_credentials)); EXPECT_TRUE(wifi_hotspot_b->DisconnectWifiHotspot()); EXPECT_TRUE(wifi_hotspot_a->StopWifiHotspot());