From ed4e00cbfba36eb264e013ea93e72320f3e9f1c1 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Tue, 7 Oct 2025 15:28:51 -0700 Subject: [PATCH] Refactor hotspot to keep profile name in hotspot_native. PiperOrigin-RevId: 816404349 --- .../implementation/windows/wifi_hotspot.h | 1 - .../windows/wifi_hotspot_medium.cc | 39 +---- .../windows/wifi_hotspot_native.cc | 136 +++++++++--------- .../windows/wifi_hotspot_native.h | 20 +-- 4 files changed, 82 insertions(+), 114 deletions(-) diff --git a/internal/platform/implementation/windows/wifi_hotspot.h b/internal/platform/implementation/windows/wifi_hotspot.h index 359ff197..2d5913f9 100644 --- a/internal/platform/implementation/windows/wifi_hotspot.h +++ b/internal/platform/implementation/windows/wifi_hotspot.h @@ -276,7 +276,6 @@ class WifiHotspotMedium : public api::WifiHotspotMedium { // connects Wi-Fi hotspot using native API. WifiHotspotNative wifi_hotspot_native_; - std::optional connected_hotspot_profile_name_; }; } // namespace windows diff --git a/internal/platform/implementation/windows/wifi_hotspot_medium.cc b/internal/platform/implementation/windows/wifi_hotspot_medium.cc index 26fc7982..1c3be547 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_medium.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_medium.cc @@ -41,8 +41,7 @@ #include "internal/platform/logging.h" #include "internal/platform/wifi_credential.h" -namespace nearby { -namespace windows { +namespace nearby::windows { namespace { using ::winrt::Windows::Devices::WiFiDirect:: WiFiDirectAdvertisementPublisherStatus; @@ -387,13 +386,7 @@ bool WifiHotspotMedium::ConnectWifiHotspot( wifi_hotspot_native_.DisconnectWifiNetwork(); } - connected_hotspot_profile_name_ = - wifi_hotspot_native_.GetConnectedProfileName(); - if (connected_hotspot_profile_name_.has_value()) { - LOG(INFO) << "Connected to Hotspot profile: " - << string_utils::WideStringToString( - *connected_hotspot_profile_name_); - } + wifi_hotspot_native_.BackupWifiProfile(); // Initialize Intel PIE scan if it is installed. bool intel_wifi_started = false; @@ -436,10 +429,7 @@ bool WifiHotspotMedium::ConnectWifiHotspot( if (!connected) { LOG(INFO) << "Failed to connect to Hotspot."; - if (connected_hotspot_profile_name_.has_value()) { - wifi_hotspot_native_.ConnectToWifiNetwork( - connected_hotspot_profile_name_->c_str()); - } + wifi_hotspot_native_.RestoreWifiProfile(); return false; } @@ -479,13 +469,7 @@ bool WifiHotspotMedium::ConnectWifiHotspot( if (ip_address.empty()) { LOG(INFO) << "Failed to get IP address from hotspot."; - if (connected_hotspot_profile_name_.has_value()) { - wifi_hotspot_native_.ConnectToWifiNetwork( - *connected_hotspot_profile_name_); - } else { - wifi_hotspot_native_.DisconnectWifiNetwork(); - } - + wifi_hotspot_native_.RestoreWifiProfile(); return false; } @@ -512,17 +496,7 @@ bool WifiHotspotMedium::DisconnectWifiHotspot() { return true; } - if (connected_hotspot_profile_name_.has_value()) { - if (!wifi_hotspot_native_.ConnectToWifiNetwork( - *connected_hotspot_profile_name_)) { - LOG(ERROR) << __func__ << ": Failed to connect to hotspot profile."; - } - } else { - if (!wifi_hotspot_native_.DisconnectWifiNetwork()) { - LOG(ERROR) << __func__ << ": Failed to disconnect hotspot."; - } - } - + wifi_hotspot_native_.RestoreWifiProfile(); medium_status_ &= (~kMediumStatusConnected); LOG(INFO) << __func__ << ": Disconnected to hotspot successfully."; return true; @@ -540,5 +514,4 @@ std::string WifiHotspotMedium::GetErrorMessage(std::exception_ptr eptr) { } } -} // namespace windows -} // namespace nearby +} // namespace nearby::windows diff --git a/internal/platform/implementation/windows/wifi_hotspot_native.cc b/internal/platform/implementation/windows/wifi_hotspot_native.cc index 023261f2..1e55cfe1 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_native.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_native.cc @@ -22,6 +22,7 @@ // clang-format on #include +#include #include #include #include @@ -36,8 +37,7 @@ #include "internal/platform/logging.h" #include "internal/platform/wifi_credential.h" -namespace nearby { -namespace windows { +namespace nearby::windows { namespace { constexpr absl::Duration kConnectTimeout = absl::Seconds(15); @@ -83,7 +83,10 @@ WifiHotspotNative::WifiHotspotNative() { } VLOG(1) << "WifiHotspotNative created successfully."; - RemoveCreatedWlanProfile(); + GUID interface_guid = GetInterfaceGuid(); + if (interface_guid != GUID_NULL) { + RemoveCreatedWlanProfile(interface_guid); + } } WifiHotspotNative::~WifiHotspotNative() { @@ -98,19 +101,20 @@ WifiHotspotNative::~WifiHotspotNative() { bool WifiHotspotNative::ConnectToWifiNetwork( HotspotCredentials* hotspot_credentials) { absl::MutexLock lock(&mutex_); - - if (GetInterfaceGuid() == GUID_NULL) { + GUID interface_guid = GetInterfaceGuid(); + if (interface_guid == GUID_NULL) { LOG(ERROR) << "No available WLAN Interface to use."; return false; } - - if (!SetWlanProfile(hotspot_credentials)) { + if (!SetWlanProfile(interface_guid, hotspot_credentials)) { LOG(ERROR) << "Failed to set WLAN profile."; return false; } if (!ConnectToWifiNetworkInternal( + interface_guid, string_utils::StringToWideString(std::string(kHotspotProfileName)))) { + RemoveCreatedWlanProfile(interface_guid); return false; } @@ -118,23 +122,6 @@ bool WifiHotspotNative::ConnectToWifiNetwork( return true; } -bool WifiHotspotNative::ConnectToWifiNetwork(const std::wstring& profile_name) { - absl::MutexLock lock(&mutex_); - - if (GetInterfaceGuid() == GUID_NULL) { - LOG(ERROR) << "No available WLAN Interface to use."; - return false; - } - - if (!ConnectToWifiNetworkInternal(profile_name)) { - return false; - } - - RemoveCreatedWlanProfile(); - LOG(ERROR) << "Connect to Wifi network successfully."; - return true; -} - bool WifiHotspotNative::DisconnectWifiNetwork() { absl::MutexLock lock(&mutex_); @@ -143,34 +130,17 @@ bool WifiHotspotNative::DisconnectWifiNetwork() { LOG(ERROR) << "No available WLAN Interface to use."; return false; } - - std::optional connected_profile_name = - GetConnectedProfileNameInternal(); - if (!connected_profile_name.has_value()) { - LOG(ERROR) << "Not connected to any WLAN network."; - RemoveCreatedWlanProfile(); - return false; - } - DWORD result = WlanDisconnect( /*hClientHandle=*/wifi_, /*pInterfaceGuid=*/&interface_guid, /*pReserved=*/nullptr); if (result != ERROR_SUCCESS) { LOG(ERROR) << "Failed to disconnect WLAN profile with error: " << result; - RemoveCreatedWlanProfile(); - return false; + } else { + LOG(ERROR) << "Disconnect Wifi hotspot successfully."; } - - RemoveCreatedWlanProfile(); - LOG(ERROR) << "Disconnect Wifi hotspot successfully."; return true; } -std::optional WifiHotspotNative::GetConnectedProfileName() const { - absl::MutexLock lock(&mutex_); - return GetConnectedProfileNameInternal(); -} - bool WifiHotspotNative::Scan(absl::string_view ssid) { absl::MutexLock lock(&mutex_); @@ -328,18 +298,12 @@ GUID WifiHotspotNative::GetInterfaceGuid() const { } bool WifiHotspotNative::ConnectToWifiNetworkInternal( - const std::wstring& profile_name) { + GUID interface_guid, const std::wstring& profile_name) { if (profile_name.empty()) { LOG(ERROR) << "Profile name is empty."; return false; } - GUID interface_guid = GetInterfaceGuid(); - if (interface_guid == GUID_NULL) { - LOG(ERROR) << "No available WLAN Interface to use."; - return false; - } - if (!RegisterWlanNotificationCallback()) { LOG(ERROR) << "Failed to register WLAN notification callback."; return false; @@ -411,24 +375,25 @@ bool WifiHotspotNative::UnregisterWlanNotificationCallback() { } bool WifiHotspotNative::SetWlanProfile( - HotspotCredentials* hotspot_credentials) { - DWORD reason = 0; - - GUID interface_guid = GetInterfaceGuid(); - if (interface_guid == GUID_NULL) { - LOG(ERROR) << "No available WLAN Interface to use."; - return false; - } - + GUID interface_guid, HotspotCredentials* hotspot_credentials) { std::wstring profile = BuildWlanProfile(hotspot_credentials->GetSSID(), hotspot_credentials->GetPassword()); + DWORD reason = 0; DWORD result = WlanSetProfile( /*hClientHandle=*/wifi_, /*pInterfaceGuid=*/&interface_guid, /*dwFlags=*/WLAN_PROFILE_USER, /*strProfileXml=*/profile.data(), /*strAllUserProfileSecurity=*/nullptr, /*bOverwrite=*/TRUE, /*pReserved=*/nullptr, /*pdwReasonCode*/ &reason); if (result != ERROR_SUCCESS) { - LOG(ERROR) << "Failed to set WLAN profile with reason" << result; + LOG(ERROR) << "Failed to set WLAN profile with error: " << result; + if (result == ERROR_BAD_PROFILE) { + std::wstring reason_str; + reason_str.resize(100); + WlanReasonCodeToString(reason, reason_str.size(), reason_str.data(), + /*pReserved=*/nullptr); + reason_str.resize(std::wcslen(reason_str.data()) + 1); + LOG(ERROR) << "WLAN profile error: " << reason_str; + } return false; } @@ -437,22 +402,16 @@ bool WifiHotspotNative::SetWlanProfile( return true; } -bool WifiHotspotNative::RemoveCreatedWlanProfile() { - return RemoveWlanProfile( +bool WifiHotspotNative::RemoveCreatedWlanProfile(GUID interface_guid) { + return RemoveWlanProfile(interface_guid, string_utils::StringToWideString(std::string(kHotspotProfileName))); } -bool WifiHotspotNative::RemoveWlanProfile(const std::wstring& profile_name) { +bool WifiHotspotNative::RemoveWlanProfile(GUID interface_guid, + const std::wstring& profile_name) { if (profile_name.empty()) { return false; } - - GUID interface_guid = GetInterfaceGuid(); - if (interface_guid == GUID_NULL) { - LOG(ERROR) << "No available WLAN Interface to use."; - return false; - } - DWORD result = WlanDeleteProfile( /*hClientHandle=*/wifi_, /*pInterfaceGuid=*/&interface_guid, /*strProfileName=*/profile_name.data(), /*pReserved=*/nullptr); @@ -507,5 +466,38 @@ std::optional WifiHotspotNative::GetConnectedProfileNameInternal() return std::nullopt; } -} // namespace windows -} // namespace nearby +bool WifiHotspotNative::BackupWifiProfile() { + absl::MutexLock lock(&mutex_); + std::optional profile_name = GetConnectedProfileNameInternal(); + if (profile_name.has_value()) { + backup_profile_name_ = *profile_name; + return true; + } + backup_profile_name_.clear(); + return false; +} + +bool WifiHotspotNative::RestoreWifiProfile() { + absl::MutexLock lock(&mutex_); + GUID interface_guid = GetInterfaceGuid(); + if (interface_guid == GUID_NULL) { + LOG(ERROR) << "No available WLAN Interface to use."; + return false; + } + RemoveCreatedWlanProfile(interface_guid); + if (backup_profile_name_.empty()) { + LOG(ERROR) << "No backup WLAN profile to restore."; + DWORD result = WlanDisconnect( + /*hClientHandle=*/wifi_, /*pInterfaceGuid=*/&interface_guid, + /*pReserved=*/nullptr); + if (result != ERROR_SUCCESS) { + LOG(ERROR) << "Failed to disconnect WLAN with error: " << result; + } else { + LOG(INFO) << "Disconnect Wifi hotspot successfully."; + } + return false; + } + return ConnectToWifiNetworkInternal(interface_guid, backup_profile_name_); +} + +} // namespace nearby::windows diff --git a/internal/platform/implementation/windows/wifi_hotspot_native.h b/internal/platform/implementation/windows/wifi_hotspot_native.h index 33a3c660..73ba67a4 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_native.h +++ b/internal/platform/implementation/windows/wifi_hotspot_native.h @@ -41,12 +41,10 @@ class WifiHotspotNative { ~WifiHotspotNative(); bool ConnectToWifiNetwork(HotspotCredentials* hotspot_credentials) ABSL_LOCKS_EXCLUDED(mutex_); - bool ConnectToWifiNetwork(const std::wstring& profile_name) - ABSL_LOCKS_EXCLUDED(mutex_); bool DisconnectWifiNetwork() ABSL_LOCKS_EXCLUDED(mutex_); - std::optional GetConnectedProfileName() const - ABSL_LOCKS_EXCLUDED(mutex_); + bool BackupWifiProfile() ABSL_LOCKS_EXCLUDED(mutex_); + bool RestoreWifiProfile() ABSL_LOCKS_EXCLUDED(mutex_); bool Scan(absl::string_view ssid) ABSL_LOCKS_EXCLUDED(mutex_); @@ -59,12 +57,17 @@ class WifiHotspotNative { std::wstring BuildWlanProfile(absl::string_view ssid, absl::string_view password); GUID GetInterfaceGuid() const; - bool ConnectToWifiNetworkInternal(const std::wstring& profile_name); + bool ConnectToWifiNetworkInternal(GUID interface_guid, + const std::wstring& profile_name) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); bool RegisterWlanNotificationCallback(); bool UnregisterWlanNotificationCallback(); - bool SetWlanProfile(HotspotCredentials* hotspot_credentials); - bool RemoveCreatedWlanProfile() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - bool RemoveWlanProfile(const std::wstring& profile_name) + bool SetWlanProfile(GUID interface_guid, + HotspotCredentials* hotspot_credentials) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + bool RemoveCreatedWlanProfile(GUID interface_guid) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + bool RemoveWlanProfile(GUID interface_guid, const std::wstring& profile_name) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); std::optional GetConnectedProfileNameInternal() const; @@ -75,6 +78,7 @@ class WifiHotspotNative { std::string scanning_ssid_; std::unique_ptr connect_latch_; std::unique_ptr scan_latch_; + std::wstring backup_profile_name_ ABSL_GUARDED_BY(mutex_); }; } // namespace windows