Refactor hotspot to keep profile name in hotspot_native.

PiperOrigin-RevId: 816404349
This commit is contained in:
Francis Tsui
2025-10-07 15:30:15 -07:00
committed by Copybara-Service
parent f915b01b75
commit ed4e00cbfb
4 changed files with 82 additions and 114 deletions
@@ -276,7 +276,6 @@ class WifiHotspotMedium : public api::WifiHotspotMedium {
// connects Wi-Fi hotspot using native API.
WifiHotspotNative wifi_hotspot_native_;
std::optional<std::wstring> connected_hotspot_profile_name_;
};
} // namespace windows
@@ -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
@@ -22,6 +22,7 @@
// clang-format on
#include <cstring>
#include <cwchar>
#include <memory>
#include <optional>
#include <string>
@@ -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<std::wstring> 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<std::wstring> 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<std::wstring> WifiHotspotNative::GetConnectedProfileNameInternal()
return std::nullopt;
}
} // namespace windows
} // namespace nearby
bool WifiHotspotNative::BackupWifiProfile() {
absl::MutexLock lock(&mutex_);
std::optional<std::wstring> 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
@@ -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<std::wstring> 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<std::wstring> GetConnectedProfileNameInternal() const;
@@ -75,6 +78,7 @@ class WifiHotspotNative {
std::string scanning_ssid_;
std::unique_ptr<CountDownLatch> connect_latch_;
std::unique_ptr<CountDownLatch> scan_latch_;
std::wstring backup_profile_name_ ABSL_GUARDED_BY(mutex_);
};
} // namespace windows