[Nearby Windows][Hotspot] Fix the issue that the Hotspot profile is not deleted correctly in client side after the Hotspot connection.

PiperOrigin-RevId: 675771020
This commit is contained in:
hai007
2024-09-17 17:38:03 -07:00
committed by Copybara-Service
parent 161676afc5
commit 601ca32370
2 changed files with 100 additions and 53 deletions
@@ -21,13 +21,21 @@
#include <wlanapi.h>
// Standard C/C++ headers
#include <cstdint>
#include <deque>
#include <exception>
#include <memory>
#include <optional>
#include <string>
#include <utility>
// Nearby connections headers
#include "absl/base/thread_annotations.h"
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/implementation/cancelable.h"
#include "internal/platform/implementation/wifi_hotspot.h"
#include "internal/platform/implementation/windows/scheduled_executor.h"
#include "internal/platform/implementation/windows/submittable_executor.h"
@@ -45,6 +53,7 @@
#include "internal/platform/implementation/windows/generated/winrt/Windows.Security.Cryptography.h"
#include "internal/platform/implementation/windows/generated/winrt/Windows.Storage.Streams.h"
#include "internal/platform/implementation/windows/generated/winrt/base.h"
#include "internal/platform/wifi_credential.h"
namespace nearby {
namespace windows {
@@ -293,6 +302,10 @@ class WifiHotspotMedium : public api::WifiHotspotMedium {
// Implemented the disconnection to WiFi hotspot, and used to avoid deadlock.
bool InternalDisconnectWifiHotspot();
// Restore the WiFi connection after disconnect from the Hotspot
void RestoreWifiConnection();
// Delete the network profile of the WiFi hotspot
bool DeleteNetworkProfile(winrt::hstring ssid);
bool IsIdle() { return medium_status_ == kMediumStatusIdle; }
// Advertiser is accepting connection on server socket
@@ -301,7 +314,6 @@ class WifiHotspotMedium : public api::WifiHotspotMedium {
bool IsBeaconing() { return (medium_status_ & kMediumStatusBeaconing) != 0; }
// Discoverer is connected with the Hotspot
bool IsConnected() { return (medium_status_ & kMediumStatusConnected) != 0; }
void RestoreWifiConnection();
WiFiDirectAdvertisementPublisher publisher_{nullptr};
WiFiDirectConnectionListener listener_{nullptr};
@@ -318,7 +330,8 @@ class WifiHotspotMedium : public api::WifiHotspotMedium {
winrt::event_token connection_requested_token_;
WiFiAdapter wifi_adapter_{nullptr};
WiFiAvailableNetwork wifi_connected_network_{nullptr};
WiFiAvailableNetwork wifi_original_network_{nullptr};
winrt::hstring wifi_connected_hotspot_ssid_ = winrt::hstring(L"");
// Gets error message from exception pointer
std::string GetErrorMessage(std::exception_ptr eptr);
@@ -17,19 +17,18 @@
#include <cstdint>
#include <exception>
#include <memory>
#include <string>
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "internal/flags/nearby_flags.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/feature_flags.h"
#include "internal/platform/flags/nearby_platform_feature_flags.h"
#include "internal/platform/implementation/windows/wifi_intel.h"
// Nearby connections headers
#include "internal/flags/nearby_flags.h"
#include "internal/platform/cancellation_flag_listener.h"
#include "internal/platform/implementation/windows/utils.h"
#include "internal/platform/logging.h"
#include "internal/platform/implementation/windows/wifi_intel.h"
#include "internal/platform/cancellation_flag_listener.h"
#include "internal/platform/wifi_utils.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace windows {
@@ -410,8 +409,15 @@ bool WifiHotspotMedium::ConnectWifiHotspot(
absl::MutexLock lock(&mutex_);
try {
if (!wifi_connected_hotspot_ssid_.empty()) {
NEARBY_LOGS(INFO) << "Before connecting to Hotspot, Delete the previous "
"Hotspot profile with SSID: "
<< winrt::to_string(wifi_connected_hotspot_ssid_);
DeleteNetworkProfile(wifi_connected_hotspot_ssid_);
wifi_connected_hotspot_ssid_ = winrt::hstring(L"");
}
if (IsConnected()) {
NEARBY_LOGS(WARNING) << "Already connected to AP, disconnect first.";
NEARBY_LOGS(WARNING) << "Already connected to Hotspot, disconnect first.";
InternalDisconnectWifiHotspot();
}
@@ -461,7 +467,7 @@ bool WifiHotspotMedium::ConnectWifiHotspot(
// almost guarantee to find the Hotspot
wifi_adapter_.ScanAsync().get();
wifi_connected_network_ = nullptr;
wifi_original_network_ = nullptr;
int64_t wifi_hotspot_max_scans = NearbyFlags::GetInstance().GetInt64Flag(
platform::config_package_nearby::nearby_platform_feature::
kWifiHotspotScanMaxRetries);
@@ -470,9 +476,9 @@ bool WifiHotspotMedium::ConnectWifiHotspot(
for (i = 0; i < wifi_hotspot_max_scans; i++) {
for (const auto& network :
wifi_adapter_.NetworkReport().AvailableNetworks()) {
if (!wifi_connected_network_ && !ssid.empty() &&
if (!wifi_original_network_ && !ssid.empty() &&
(winrt::to_string(network.Ssid()) == ssid)) {
wifi_connected_network_ = network;
wifi_original_network_ = network;
NEARBY_LOGS(INFO) << "Save the current connected network: " << ssid;
} else if (!nearby_softap && winrt::to_string(network.Ssid()) ==
hotspot_credentials_->GetSSID()) {
@@ -480,7 +486,8 @@ bool WifiHotspotMedium::ConnectWifiHotspot(
<< "Found Nearby SSID: " << winrt::to_string(network.Ssid());
nearby_softap = network;
}
if (nearby_softap && (ssid.empty() || wifi_connected_network_)) break;
if (nearby_softap && (ssid.empty() || wifi_original_network_))
break;
}
if (nearby_softap) break;
NEARBY_LOGS(INFO) << "Scan ... ";
@@ -541,12 +548,15 @@ bool WifiHotspotMedium::ConnectWifiHotspot(
if (ip_address.empty()) {
NEARBY_LOGS(INFO) << "Failed to get IP address from hotspot.";
RestoreWifiConnection();
DeleteNetworkProfile(nearby_softap.Ssid());
return false;
}
NEARBY_LOGS(INFO) << "Got IP address " << ip_address << " from hotspot.";
std::string last_ssid = hotspot_credentials_->GetSSID();
wifi_connected_hotspot_ssid_ = nearby_softap.Ssid();
medium_status_ |= kMediumStatusConnected;
NEARBY_LOGS(INFO) << "Connected to hotspot: " << last_ssid;
@@ -566,7 +576,7 @@ bool WifiHotspotMedium::ConnectWifiHotspot(
}
void WifiHotspotMedium::RestoreWifiConnection() {
if (!wifi_connected_network_ && wifi_adapter_) {
if (!wifi_original_network_ && wifi_adapter_) {
wifi_adapter_.Disconnect();
return;
}
@@ -579,7 +589,7 @@ void WifiHotspotMedium::RestoreWifiConnection() {
ssid = winrt::to_string(
profile.WlanConnectionProfileDetails().GetConnectedSsid());
if (!ssid.empty() &&
(winrt::to_string(wifi_connected_network_.Ssid()) == ssid)) {
(winrt::to_string(wifi_original_network_.Ssid()) == ssid)) {
NEARBY_LOGS(INFO) << "Already conneted to the previous WIFI network "
<< ssid << "! Skip restoration.";
return;
@@ -591,7 +601,7 @@ void WifiHotspotMedium::RestoreWifiConnection() {
NEARBY_LOGS(INFO) << "Disconnected to current network.";
auto connect_result = wifi_adapter_
.ConnectAsync(wifi_connected_network_,
.ConnectAsync(wifi_original_network_,
WiFiReconnectionKind::Automatic)
.get();
@@ -601,9 +611,9 @@ void WifiHotspotMedium::RestoreWifiConnection() {
<< static_cast<int>(connect_result.ConnectionStatus());
} else {
NEARBY_LOGS(INFO) << "Restored the previous WIFI connection: "
<< winrt::to_string(wifi_connected_network_.Ssid());
<< winrt::to_string(wifi_original_network_.Ssid());
}
wifi_connected_network_ = nullptr;
wifi_original_network_ = nullptr;
}
}
@@ -632,44 +642,16 @@ bool WifiHotspotMedium::InternalDisconnectWifiHotspot() {
}
if (wifi_adapter_) {
// Gets connected WiFi profile.
auto profile =
wifi_adapter_.NetworkAdapter().GetConnectedProfileAsync().get();
// Disconnect to the WiFi connection through the WiFi adapter.
RestoreWifiConnection();
wifi_adapter_ = nullptr;
// Try to remove the WiFi profile
if (profile != nullptr && profile.CanDelete() &&
profile.IsWlanConnectionProfile()) {
std::string ssid = winrt::to_string(
profile.WlanConnectionProfileDetails().GetConnectedSsid());
auto profile_delete_status = profile.TryDeleteAsync().get();
switch (profile_delete_status) {
case ConnectionProfileDeleteStatus::Success:
NEARBY_LOGS(INFO)
<< "WiFi profile with SSID:" << ssid << " is deleted.";
break;
case ConnectionProfileDeleteStatus::DeniedBySystem:
NEARBY_LOGS(ERROR)
<< "Failed to delete WiFi profile with SSID:" << ssid
<< " due to denied by system.";
break;
case ConnectionProfileDeleteStatus::DeniedByUser:
NEARBY_LOGS(ERROR)
<< "Failed to delete WiFi profile with SSID:" << ssid
<< " due to denied by user.";
break;
case ConnectionProfileDeleteStatus::UnknownError:
NEARBY_LOGS(ERROR)
<< "Failed to delete WiFi profile with SSID:" << ssid
<< " due to unknonw error.";
break;
default:
break;
}
if (!wifi_connected_hotspot_ssid_.empty()) {
NEARBY_LOGS(INFO)
<< "Delete the previous connected network profile with SSID: "
<< winrt::to_string(wifi_connected_hotspot_ssid_);
DeleteNetworkProfile(wifi_connected_hotspot_ssid_);
wifi_connected_hotspot_ssid_ = winrt::hstring(L"");
}
}
@@ -677,6 +659,58 @@ bool WifiHotspotMedium::InternalDisconnectWifiHotspot() {
return true;
}
bool WifiHotspotMedium::DeleteNetworkProfile(winrt::hstring ssid) {
bool result = false;
ConnectionProfile profile{nullptr};
auto connections = NetworkInformation::GetConnectionProfiles();
auto ssid_string = winrt::to_string(ssid);
if (ssid_string.empty()) {
NEARBY_LOGS(INFO) << "SSID is empty. No need to delete the network profile";
return true;
}
NEARBY_LOGS(INFO) << "Search profile with SSID: " << ssid_string;
for (const auto& connection_profile : connections) {
if (connection_profile.ProfileName() == ssid) {
NEARBY_LOGS(INFO) << "Found the network profile with SSID: "
<< ssid_string;
profile = connection_profile;
break;
}
}
if (profile == nullptr) {
NEARBY_LOGS(INFO) << "No network profile found with SSID: " << ssid_string;
return result;
}
if (profile != nullptr && profile.CanDelete() &&
profile.IsWlanConnectionProfile()) {
auto profile_delete_status = profile.TryDeleteAsync().get();
switch (profile_delete_status) {
case ConnectionProfileDeleteStatus::Success:
NEARBY_LOGS(INFO) << "WiFi profile with SSID:" << ssid_string
<< " is deleted.";
result = true;
break;
case ConnectionProfileDeleteStatus::DeniedBySystem:
NEARBY_LOGS(ERROR) << "Failed to delete WiFi profile with SSID:"
<< ssid_string << " due to denied by system.";
break;
case ConnectionProfileDeleteStatus::DeniedByUser:
NEARBY_LOGS(ERROR) << "Failed to delete WiFi profile with SSID:"
<< ssid_string << " due to denied by user.";
break;
case ConnectionProfileDeleteStatus::UnknownError:
NEARBY_LOGS(ERROR) << "Failed to delete WiFi profile with SSID:"
<< ssid_string << " due to unknonw error.";
break;
default:
break;
}
}
return result;
}
std::string WifiHotspotMedium::GetErrorMessage(std::exception_ptr eptr) {
try {
if (eptr) {