mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Add WlanClient class.
PiperOrigin-RevId: 825864006
This commit is contained in:
committed by
Copybara-Service
parent
88f37eeb88
commit
dc963d93bf
@@ -145,10 +145,6 @@ cc_library(
|
||||
"network_info.h",
|
||||
],
|
||||
compatible_with = ["//buildenv/target:non_prod"],
|
||||
linkopts = [
|
||||
"iphlpapi.lib",
|
||||
"ole32.lib",
|
||||
],
|
||||
tags = ["windows"],
|
||||
visibility = [
|
||||
"//:__subpackages__",
|
||||
@@ -161,6 +157,39 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "scoped_wlan_memory",
|
||||
hdrs = [
|
||||
"scoped_wlan_memory.h",
|
||||
],
|
||||
compatible_with = ["//buildenv/target:non_prod"],
|
||||
tags = ["windows"],
|
||||
visibility = [
|
||||
"//:__subpackages__",
|
||||
"//location/nearby:__subpackages__",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "wlan_client",
|
||||
srcs = [
|
||||
"wlan_client.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"wlan_client.h",
|
||||
],
|
||||
compatible_with = ["//buildenv/target:non_prod"],
|
||||
tags = ["windows"],
|
||||
visibility = [
|
||||
"//:__subpackages__",
|
||||
"//location/nearby:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
":scoped_wlan_memory",
|
||||
"//internal/platform:logging",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "windows",
|
||||
srcs = [
|
||||
@@ -256,9 +285,11 @@ cc_library(
|
||||
deps = [
|
||||
":crypto", # build_cleaner: keep
|
||||
":network_info",
|
||||
":scoped_wlan_memory",
|
||||
":socket_address",
|
||||
":string_utils",
|
||||
":types",
|
||||
":wlan_client",
|
||||
"//connections/implementation/flags:connections_flags",
|
||||
"//connections/implementation/mediums:utils",
|
||||
"//connections/implementation/mediums/ble:ble_advertisement_header",
|
||||
@@ -451,6 +482,7 @@ cc_test(
|
||||
],
|
||||
deps = [
|
||||
":network_info",
|
||||
"//sharing/internal/impl/windows:platform_windows_libs",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
@@ -469,3 +501,33 @@ cc_test(
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "scoped_wlan_memory_test",
|
||||
size = "small",
|
||||
timeout = "short",
|
||||
srcs = [
|
||||
"scoped_wlan_memory_test.cc",
|
||||
],
|
||||
deps = [
|
||||
":scoped_wlan_memory",
|
||||
"//sharing/internal/impl/windows:platform_windows_libs",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "wlan_client_test",
|
||||
size = "small",
|
||||
timeout = "short",
|
||||
srcs = [
|
||||
"wlan_client_test.cc",
|
||||
],
|
||||
deps = [
|
||||
":wlan_client",
|
||||
"//sharing/internal/impl/windows:platform_windows_libs",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_SCOPED_WLAN_MEMORY_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_SCOPED_WLAN_MEMORY_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <wlanapi.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
|
||||
// Smart pointer class for memory allocated by the WLAN API.
|
||||
template <typename T>
|
||||
class ScopedWlanMemory {
|
||||
public:
|
||||
explicit ScopedWlanMemory(T* ptr = nullptr) : ptr_(ptr) {}
|
||||
~ScopedWlanMemory() {
|
||||
Reset();
|
||||
}
|
||||
ScopedWlanMemory& operator=(ScopedWlanMemory<T>&& other) {
|
||||
Reset(other.Release());
|
||||
return *this;
|
||||
}
|
||||
T* operator->() { return ptr_; }
|
||||
T* get() { return ptr_; }
|
||||
|
||||
// Returns a pointer to the managed object and releases the ownership.
|
||||
ABSL_MUST_USE_RESULT T* Release() { return std::exchange(ptr_, nullptr); }
|
||||
|
||||
// Used as an output parameter for functions that return a pointer as an
|
||||
// output parameter.
|
||||
// If the current managed object is not null, it will be freed.
|
||||
T** OutParam() {
|
||||
Reset();
|
||||
return &ptr_;
|
||||
}
|
||||
|
||||
// Swaps a new pointer into this instance. Frees the old pointer if it is not
|
||||
// null.
|
||||
void Reset(T* new_ptr = nullptr) {
|
||||
if (ptr_ != nullptr) {
|
||||
::WlanFreeMemory(ptr_);
|
||||
}
|
||||
ptr_ = new_ptr;
|
||||
}
|
||||
explicit operator bool() const { return ptr_ != nullptr; }
|
||||
|
||||
private:
|
||||
T* ptr_;
|
||||
};
|
||||
|
||||
} // namespace nearby::windows
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_SCOPED_WLAN_MEMORY_H_
|
||||
@@ -0,0 +1,97 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/platform/implementation/windows/scoped_wlan_memory.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <wlanapi.h>
|
||||
#include <utility>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
namespace {
|
||||
|
||||
TEST(ScopedWlanMemoryTest, Empty) {
|
||||
ScopedWlanMemory<WLAN_AVAILABLE_NETWORK_LIST> wlan_list;
|
||||
EXPECT_EQ(wlan_list.get(), nullptr);
|
||||
}
|
||||
|
||||
TEST(ScopedWlanMemoryTest, Reset) {
|
||||
ScopedWlanMemory<WLAN_INTERFACE_INFO_LIST> wlan_list;
|
||||
EXPECT_EQ(wlan_list.get(), nullptr);
|
||||
WLAN_INTERFACE_INFO_LIST* wlan_list_ptr =
|
||||
reinterpret_cast<WLAN_INTERFACE_INFO_LIST*>(
|
||||
::WlanAllocateMemory(sizeof(WLAN_INTERFACE_INFO_LIST)));
|
||||
wlan_list.Reset(wlan_list_ptr);
|
||||
EXPECT_EQ(wlan_list.get(), wlan_list_ptr);
|
||||
wlan_list.Reset();
|
||||
EXPECT_EQ(wlan_list.get(), nullptr);
|
||||
}
|
||||
|
||||
TEST(ScopedWlanMemoryTest, ConstructWithPointer) {
|
||||
WLAN_INTERFACE_INFO_LIST* wlan_list_ptr =
|
||||
reinterpret_cast<WLAN_INTERFACE_INFO_LIST*>(
|
||||
::WlanAllocateMemory(sizeof(WLAN_INTERFACE_INFO_LIST)));
|
||||
ScopedWlanMemory<WLAN_INTERFACE_INFO_LIST> wlan_list(wlan_list_ptr);
|
||||
EXPECT_EQ(wlan_list.get(), wlan_list_ptr);
|
||||
}
|
||||
|
||||
TEST(ScopedWlanMemoryTest, PointerAccess) {
|
||||
WLAN_INTERFACE_INFO_LIST* wlan_list_ptr =
|
||||
reinterpret_cast<WLAN_INTERFACE_INFO_LIST*>(
|
||||
::WlanAllocateMemory(sizeof(WLAN_INTERFACE_INFO_LIST)));
|
||||
wlan_list_ptr->dwIndex = 9834;
|
||||
ScopedWlanMemory<WLAN_INTERFACE_INFO_LIST> wlan_list(wlan_list_ptr);
|
||||
EXPECT_EQ(wlan_list->dwIndex, 9834);
|
||||
}
|
||||
|
||||
void TestFunc(WLAN_INTERFACE_INFO_LIST** wlan_list_ptr) {
|
||||
*wlan_list_ptr = reinterpret_cast<WLAN_INTERFACE_INFO_LIST*>(
|
||||
::WlanAllocateMemory(sizeof(WLAN_INTERFACE_INFO_LIST)));
|
||||
(*wlan_list_ptr)->dwIndex = 9834;
|
||||
}
|
||||
|
||||
TEST(ScopedWlanMemoryTest, OutParam) {
|
||||
ScopedWlanMemory<WLAN_INTERFACE_INFO_LIST> wlan_list;
|
||||
TestFunc(wlan_list.OutParam());
|
||||
EXPECT_EQ(wlan_list->dwIndex, 9834);
|
||||
}
|
||||
|
||||
TEST(ScopedWlanMemoryTest, MoveAssignment) {
|
||||
WLAN_INTERFACE_INFO_LIST* wlan_list_ptr =
|
||||
reinterpret_cast<WLAN_INTERFACE_INFO_LIST*>(
|
||||
::WlanAllocateMemory(sizeof(WLAN_INTERFACE_INFO_LIST)));
|
||||
ScopedWlanMemory<WLAN_INTERFACE_INFO_LIST> wlan_list(wlan_list_ptr);
|
||||
EXPECT_EQ(wlan_list.get(), wlan_list_ptr);
|
||||
ScopedWlanMemory<WLAN_INTERFACE_INFO_LIST> wlan_list2;
|
||||
|
||||
wlan_list2 = std::move(wlan_list);
|
||||
|
||||
EXPECT_EQ(wlan_list2.get(), wlan_list_ptr);
|
||||
}
|
||||
|
||||
TEST(ScopedWlanMemoryTest, Release) {
|
||||
WLAN_INTERFACE_INFO_LIST* wlan_list_ptr =
|
||||
reinterpret_cast<WLAN_INTERFACE_INFO_LIST*>(
|
||||
::WlanAllocateMemory(sizeof(WLAN_INTERFACE_INFO_LIST)));
|
||||
ScopedWlanMemory<WLAN_INTERFACE_INFO_LIST> wlan_list(wlan_list_ptr);
|
||||
EXPECT_EQ(wlan_list.get(), wlan_list_ptr);
|
||||
|
||||
EXPECT_EQ(wlan_list.Release(), wlan_list_ptr);
|
||||
EXPECT_EQ(wlan_list.get(), nullptr);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby::windows
|
||||
@@ -103,6 +103,7 @@ class WifiMedium : public api::WifiMedium {
|
||||
// Since the WiFi interface capability won't change in the connection session,
|
||||
// we only need to query it once at the beginning
|
||||
void InitCapability();
|
||||
bool GetWifiInformation();
|
||||
std::string InternalGetWifiIpAddress();
|
||||
std::string InternalGetEthernetIpAddress();
|
||||
void FillupEthernetParams();
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
@@ -37,6 +38,7 @@
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/windows/network_info.h"
|
||||
#include "internal/platform/implementation/windows/string_utils.h"
|
||||
#include "internal/platform/implementation/windows/wlan_client.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
@@ -84,17 +86,10 @@ std::string ReasonCodeToString(DWORD reason_code) {
|
||||
|
||||
WifiHotspotNative::WifiHotspotNative()
|
||||
: network_info_(NetworkInfo::GetNetworkInfo()) {
|
||||
// Open WLAN handle
|
||||
DWORD negotiated_version;
|
||||
DWORD result = WlanOpenHandle(/*dwClientVersion=*/2, /*pReserved=*/nullptr,
|
||||
/*pdwNegotiatedVersion=*/&negotiated_version,
|
||||
/*phClientHandle=*/&wifi_);
|
||||
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(ERROR) << "Failed to open WLAN handle.";
|
||||
if (!wlan_client_.Initialize()) {
|
||||
LOG(ERROR) << "Failed to initialize WLAN client.";
|
||||
return;
|
||||
}
|
||||
|
||||
VLOG(1) << "WifiHotspotNative created successfully.";
|
||||
GUID interface_guid = GetInterfaceGuid();
|
||||
if (interface_guid != GUID_NULL) {
|
||||
@@ -103,11 +98,6 @@ WifiHotspotNative::WifiHotspotNative()
|
||||
}
|
||||
|
||||
WifiHotspotNative::~WifiHotspotNative() {
|
||||
if (wifi_ != nullptr) {
|
||||
WlanCloseHandle(wifi_, nullptr);
|
||||
wifi_ = nullptr;
|
||||
}
|
||||
|
||||
VLOG(1) << "WifiHotspotNative destroyed successfully.";
|
||||
}
|
||||
|
||||
@@ -143,9 +133,8 @@ bool WifiHotspotNative::DisconnectWifiNetwork() {
|
||||
return false;
|
||||
}
|
||||
absl::MutexLock lock(mutex_);
|
||||
DWORD result = WlanDisconnect(
|
||||
/*hClientHandle=*/wifi_, /*pInterfaceGuid=*/&interface_guid,
|
||||
/*pReserved=*/nullptr);
|
||||
DWORD result = WlanDisconnect(wlan_client_.GetHandle(), &interface_guid,
|
||||
/*pReserved=*/nullptr);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(ERROR) << "Failed to disconnect WLAN profile with error: " << result;
|
||||
} else {
|
||||
@@ -229,29 +218,18 @@ std::wstring WifiHotspotNative::BuildWlanProfile(absl::string_view ssid,
|
||||
}
|
||||
|
||||
GUID WifiHotspotNative::GetInterfaceGuid() const {
|
||||
if (wifi_ == nullptr) {
|
||||
if (wlan_client_.GetHandle() == nullptr) {
|
||||
return GUID_NULL;
|
||||
}
|
||||
|
||||
// Find WLAN interface, only support one interface for now.
|
||||
PWLAN_INTERFACE_INFO_LIST interfaces = nullptr;
|
||||
DWORD result =
|
||||
WlanEnumInterfaces(/*hClientHandle=*/wifi_, /*pReserved=*/nullptr,
|
||||
/*ppInterfaceList=*/&interfaces);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(ERROR) << "Failed to enum WLAN interfaces.";
|
||||
return GUID_NULL;
|
||||
}
|
||||
|
||||
if (interfaces->dwNumberOfItems == 0) {
|
||||
std::vector<WlanClient::InterfaceInfo> interfaces =
|
||||
wlan_client_.GetInterfaceInfos();
|
||||
if (interfaces.empty()) {
|
||||
LOG(ERROR) << "No WLAN interfaces found.";
|
||||
WlanFreeMemory(interfaces);
|
||||
return GUID_NULL;
|
||||
}
|
||||
|
||||
GUID interface_guid = interfaces->InterfaceInfo[0].InterfaceGuid;
|
||||
WlanFreeMemory(interfaces);
|
||||
return interface_guid;
|
||||
return interfaces[0].guid;
|
||||
}
|
||||
|
||||
bool WifiHotspotNative::ConnectToWifiNetworkInternal(
|
||||
@@ -261,8 +239,8 @@ bool WifiHotspotNative::ConnectToWifiNetworkInternal(
|
||||
return false;
|
||||
}
|
||||
WlanNotificationContext context = {
|
||||
.wifi_hotspot_native = *this,
|
||||
.connecting_profile_name = profile_name,
|
||||
.wifi_hotspot_native = *this,
|
||||
.connecting_profile_name = profile_name,
|
||||
};
|
||||
if (!RegisterWlanNotificationCallback(&context)) {
|
||||
LOG(ERROR) << "Failed to register WLAN notification callback.";
|
||||
@@ -279,9 +257,8 @@ bool WifiHotspotNative::ConnectToWifiNetworkInternal(
|
||||
parameters.dot11BssType = dot11_BSS_type_infrastructure;
|
||||
parameters.dwFlags = 0;
|
||||
|
||||
DWORD result =
|
||||
WlanConnect(/*hClientHandle=*/wifi_, /*pInterfaceGuid=*/&interface_guid,
|
||||
/*pConnectionParameters=*/¶meters, /*pReserved=*/nullptr);
|
||||
DWORD result = WlanConnect(wlan_client_.GetHandle(), &interface_guid,
|
||||
¶meters, /*pReserved=*/nullptr);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(ERROR) << "Failed to connect to WLAN profile "
|
||||
<< string_utils::WideStringToString(profile_name);
|
||||
@@ -311,10 +288,9 @@ bool WifiHotspotNative::ConnectToWifiNetworkInternal(
|
||||
bool WifiHotspotNative::RegisterWlanNotificationCallback(
|
||||
WlanNotificationContext* absl_nonnull context) {
|
||||
DWORD result = WlanRegisterNotification(
|
||||
/*hClientHandle=*/wifi_, /*dwNotifSource=*/WLAN_NOTIFICATION_SOURCE_ACM,
|
||||
/*bIgnoreDuplicate=*/TRUE,
|
||||
/*funcCallback=*/WifiHotspotNative::WlanNotificationCallback,
|
||||
/*pCallbackContext=*/context, /*pReserved=*/nullptr,
|
||||
wlan_client_.GetHandle(), WLAN_NOTIFICATION_SOURCE_ACM,
|
||||
/*bIgnoreDuplicate=*/TRUE, WifiHotspotNative::WlanNotificationCallback,
|
||||
context, /*pReserved=*/nullptr,
|
||||
/*pdwPrevNotifSource=*/nullptr);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(ERROR) << "Failed to register WLAN notification with error: " << result;
|
||||
@@ -326,7 +302,7 @@ bool WifiHotspotNative::RegisterWlanNotificationCallback(
|
||||
|
||||
bool WifiHotspotNative::UnregisterWlanNotificationCallback() {
|
||||
DWORD result = WlanRegisterNotification(
|
||||
/*hClientHandle=*/wifi_, /*dwNotifSource=*/WLAN_NOTIFICATION_SOURCE_NONE,
|
||||
wlan_client_.GetHandle(), WLAN_NOTIFICATION_SOURCE_NONE,
|
||||
/*bIgnoreDuplicate=*/TRUE,
|
||||
/*funcCallback=*/nullptr, /*pCallbackContext=*/nullptr,
|
||||
/*pReserved=*/nullptr, /*pdwPrevNotifSource=*/nullptr);
|
||||
@@ -339,15 +315,16 @@ bool WifiHotspotNative::UnregisterWlanNotificationCallback() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiHotspotNative::SetWlanProfile(
|
||||
GUID interface_guid, absl::string_view ssid, absl::string_view password) {
|
||||
bool WifiHotspotNative::SetWlanProfile(GUID interface_guid,
|
||||
absl::string_view ssid,
|
||||
absl::string_view password) {
|
||||
std::wstring profile = BuildWlanProfile(ssid, password);
|
||||
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);
|
||||
DWORD result =
|
||||
WlanSetProfile(wlan_client_.GetHandle(), &interface_guid,
|
||||
WLAN_PROFILE_USER, profile.data(),
|
||||
/*strAllUserProfileSecurity=*/nullptr, /*bOverwrite=*/TRUE,
|
||||
/*pReserved=*/nullptr, /*pdwReasonCode*/ &reason);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(ERROR) << "Failed to set WLAN profile with error: " << result;
|
||||
if (result == ERROR_BAD_PROFILE) {
|
||||
@@ -367,8 +344,9 @@ bool WifiHotspotNative::SetWlanProfile(
|
||||
}
|
||||
|
||||
bool WifiHotspotNative::RemoveCreatedWlanProfile(GUID interface_guid) {
|
||||
return RemoveWlanProfile(interface_guid,
|
||||
string_utils::StringToWideString(std::string(kHotspotProfileName)));
|
||||
return RemoveWlanProfile(
|
||||
interface_guid,
|
||||
string_utils::StringToWideString(std::string(kHotspotProfileName)));
|
||||
}
|
||||
|
||||
bool WifiHotspotNative::RemoveWlanProfile(GUID interface_guid,
|
||||
@@ -376,9 +354,8 @@ bool WifiHotspotNative::RemoveWlanProfile(GUID interface_guid,
|
||||
if (profile_name.empty()) {
|
||||
return false;
|
||||
}
|
||||
DWORD result = WlanDeleteProfile(
|
||||
/*hClientHandle=*/wifi_, /*pInterfaceGuid=*/&interface_guid,
|
||||
/*strProfileName=*/profile_name.data(), /*pReserved=*/nullptr);
|
||||
DWORD result = WlanDeleteProfile(wlan_client_.GetHandle(), &interface_guid,
|
||||
profile_name.data(), /*pReserved=*/nullptr);
|
||||
|
||||
if (result != ERROR_SUCCESS && result != ERROR_NOT_FOUND) {
|
||||
LOG(ERROR) << "Failed to remove WLAN profile "
|
||||
@@ -387,8 +364,7 @@ bool WifiHotspotNative::RemoveWlanProfile(GUID interface_guid,
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(INFO) << "WLAN profile "
|
||||
<< string_utils::WideStringToString(profile_name)
|
||||
LOG(INFO) << "WLAN profile " << string_utils::WideStringToString(profile_name)
|
||||
<< " removed successfully.";
|
||||
return true;
|
||||
}
|
||||
@@ -403,9 +379,8 @@ bool WifiHotspotNative::RestoreWifiProfile() {
|
||||
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);
|
||||
DWORD result = WlanDisconnect(wlan_client_.GetHandle(), &interface_guid,
|
||||
/*pReserved=*/nullptr);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(ERROR) << "Failed to disconnect WLAN with error: " << result;
|
||||
} else {
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/implementation/windows/network_info.h"
|
||||
#include "internal/platform/implementation/windows/wlan_client.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
|
||||
@@ -87,7 +88,7 @@ class WifiHotspotNative {
|
||||
NetworkInfo& network_info_;
|
||||
mutable absl::Mutex mutex_;
|
||||
|
||||
HANDLE wifi_ = nullptr;
|
||||
WlanClient wlan_client_;
|
||||
std::unique_ptr<CountDownLatch> connect_latch_;
|
||||
std::wstring backup_profile_name_;
|
||||
};
|
||||
|
||||
@@ -15,12 +15,15 @@
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "internal/platform/implementation/wifi.h"
|
||||
#include "internal/platform/implementation/wifi_utils.h"
|
||||
#include "internal/platform/implementation/windows/scoped_wlan_memory.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/implementation/windows/wifi.h"
|
||||
#include "internal/platform/implementation/windows/wlan_client.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "winrt/Windows.Security.Authorization.AppCapabilityAccess.h"
|
||||
|
||||
@@ -28,6 +31,7 @@ namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
namespace {
|
||||
using ::nearby::windows::ScopedWlanMemory;
|
||||
using winrt::Windows::Security::Authorization::AppCapabilityAccess::
|
||||
AppCapability;
|
||||
using winrt::Windows::Security::Authorization::AppCapabilityAccess::
|
||||
@@ -40,93 +44,101 @@ constexpr int kUseEthernet = -2;
|
||||
|
||||
WifiMedium::WifiMedium() { InitCapability(); }
|
||||
|
||||
PWLAN_INTERFACE_INFO_LIST EnumInterface(PHANDLE client_handle) {
|
||||
DWORD client_version = 2;
|
||||
DWORD negotiated_version = 0;
|
||||
DWORD result = 0;
|
||||
|
||||
/* variables used for WlanEnumInterfaces */
|
||||
PWLAN_INTERFACE_INFO_LIST p_intf_list = nullptr;
|
||||
|
||||
result = WlanOpenHandle(client_version, nullptr, &negotiated_version,
|
||||
client_handle);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(INFO) << "WlanOpenHandle failed with error: " << result;
|
||||
return p_intf_list;
|
||||
}
|
||||
|
||||
result = WlanEnumInterfaces(*client_handle, nullptr, &p_intf_list);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(INFO) << "WlanEnumInterfaces failed with error: " << result;
|
||||
}
|
||||
return p_intf_list;
|
||||
}
|
||||
|
||||
bool WifiMedium::IsInterfaceValid() const { return wifi_interface_valid_; }
|
||||
|
||||
void WifiMedium::InitCapability() {
|
||||
HANDLE client_handle = nullptr;
|
||||
|
||||
/* variables used for WlanEnumInterfaces */
|
||||
PWLAN_INTERFACE_INFO_LIST p_intf_list = nullptr;
|
||||
PWLAN_INTERFACE_INFO p_intf_info = nullptr;
|
||||
PWLAN_INTERFACE_CAPABILITY p_intf_capability = nullptr;
|
||||
|
||||
wifi_capability_.supports_5_ghz = false;
|
||||
wifi_capability_.supports_6_ghz = false;
|
||||
wifi_interface_valid_ = false;
|
||||
|
||||
p_intf_list = EnumInterface(&client_handle);
|
||||
if (!client_handle) {
|
||||
LOG(INFO)
|
||||
<< "Client Handle is null, wifi maybe not supported on this device.";
|
||||
WlanClient wlan_client;
|
||||
if (!wlan_client.Initialize()) {
|
||||
return;
|
||||
}
|
||||
if (!p_intf_list) {
|
||||
WlanCloseHandle(client_handle, nullptr);
|
||||
return;
|
||||
}
|
||||
wifi_interface_valid_ = true;
|
||||
|
||||
for (int i = 0; i < (int)p_intf_list->dwNumberOfItems; i++) {
|
||||
p_intf_info = (WLAN_INTERFACE_INFO*)&p_intf_list->InterfaceInfo[i];
|
||||
if (WlanGetInterfaceCapability(client_handle, &p_intf_info->InterfaceGuid,
|
||||
nullptr,
|
||||
&p_intf_capability) != ERROR_SUCCESS) {
|
||||
std::vector<WlanClient::InterfaceInfo> interface_infos =
|
||||
wlan_client.GetInterfaceInfos();
|
||||
for (const auto& interface_info : interface_infos) {
|
||||
ScopedWlanMemory<WLAN_INTERFACE_CAPABILITY> intf_capability;
|
||||
wifi_interface_valid_ = true;
|
||||
if (WlanGetInterfaceCapability(
|
||||
wlan_client.GetHandle(), &interface_info.guid, nullptr,
|
||||
intf_capability.OutParam()) != ERROR_SUCCESS) {
|
||||
LOG(INFO) << "Get Capability failed";
|
||||
WlanFreeMemory(p_intf_list);
|
||||
p_intf_list = nullptr;
|
||||
WlanCloseHandle(client_handle, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int j = 0; j < p_intf_capability->dwNumberOfSupportedPhys; j++) {
|
||||
if (p_intf_capability->dot11PhyTypes[j] == dot11_phy_type_ofdm)
|
||||
for (int j = 0; j < intf_capability->dwNumberOfSupportedPhys; j++) {
|
||||
if (intf_capability->dot11PhyTypes[j] == dot11_phy_type_ofdm)
|
||||
wifi_capability_.supports_5_ghz = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WlanFreeMemory(p_intf_capability);
|
||||
p_intf_capability = nullptr;
|
||||
WlanFreeMemory(p_intf_list);
|
||||
p_intf_list = nullptr;
|
||||
WlanCloseHandle(client_handle, nullptr);
|
||||
bool WifiMedium::GetWifiInformation() {
|
||||
WlanClient wlan_client;
|
||||
if (!wlan_client.Initialize()) {
|
||||
return false;
|
||||
}
|
||||
bool result = false;
|
||||
for (const auto& interface_info : wlan_client.GetInterfaceInfos()) {
|
||||
if (!interface_info.connected) {
|
||||
continue;
|
||||
}
|
||||
LOG(INFO) << "Found connected WiFi interface";
|
||||
wifi_information_.is_connected = true;
|
||||
|
||||
DWORD result = 0;
|
||||
DWORD channel_size;
|
||||
ScopedWlanMemory<ULONG> channel;
|
||||
result = WlanQueryInterface(wlan_client.GetHandle(), &interface_info.guid,
|
||||
wlan_intf_opcode_channel_number, nullptr,
|
||||
&channel_size,
|
||||
reinterpret_cast<PVOID*>(channel.OutParam()),
|
||||
/*pWlanOpcodeValueType=*/nullptr);
|
||||
if (result != ERROR_SUCCESS || channel.get() == nullptr) {
|
||||
LOG(INFO) << "WlanQueryInterface channel error = " << result;
|
||||
return false;
|
||||
}
|
||||
wifi_information_.ap_frequency = WifiUtils::ConvertChannelToFrequencyMhz(
|
||||
*channel.get(), api::WifiBandType::kUnknown);
|
||||
LOG(INFO) << "Channel: " << (channel.get() == nullptr ? 0 : *channel.get())
|
||||
<< "; ap_frequency: " << wifi_information_.ap_frequency;
|
||||
|
||||
ScopedWlanMemory<WLAN_CONNECTION_ATTRIBUTES> connect_info;
|
||||
DWORD connect_info_size;
|
||||
result = WlanQueryInterface(
|
||||
wlan_client.GetHandle(), &interface_info.guid,
|
||||
wlan_intf_opcode_current_connection, nullptr, &connect_info_size,
|
||||
reinterpret_cast<PVOID*>(connect_info.OutParam()),
|
||||
/*pWlanOpcodeValueType=*/nullptr);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(INFO) << "WlanQueryInterface current AP error = " << result;
|
||||
return false;
|
||||
}
|
||||
|
||||
wifi_information_.ssid.assign(
|
||||
reinterpret_cast<const char*>(
|
||||
connect_info->wlanAssociationAttributes.dot11Ssid.ucSSID),
|
||||
connect_info->wlanAssociationAttributes.dot11Ssid.uSSIDLength);
|
||||
LOG(INFO) << "wifi ssid is: " << wifi_information_.ssid
|
||||
<< "; length is:" << wifi_information_.ssid.length();
|
||||
|
||||
char str_tmp[kMacAddrLen];
|
||||
strncpy(str_tmp,
|
||||
reinterpret_cast<const char*>(
|
||||
connect_info->wlanAssociationAttributes.dot11Bssid),
|
||||
kMacAddrLen);
|
||||
wifi_information_.bssid = absl::StrFormat(
|
||||
"%02llx:%02llx:%02llx:%02llx:%02llx:%02llx", str_tmp[0], str_tmp[1],
|
||||
str_tmp[2], str_tmp[3], str_tmp[4], str_tmp[5]);
|
||||
LOG(INFO) << "wifi bssid is: " << wifi_information_.bssid;
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO(b/259414512): the return type should be optional.
|
||||
api::WifiInformation& WifiMedium::GetInformation() {
|
||||
HANDLE client_handle = nullptr;
|
||||
PWLAN_AVAILABLE_NETWORK_LIST pWLAN_AVAILABLE_NETWORK_LIST = nullptr;
|
||||
DWORD result = 0;
|
||||
DWORD connect_info_size = sizeof(WLAN_CONNECTION_ATTRIBUTES);
|
||||
WLAN_OPCODE_VALUE_TYPE op_code_value_type = wlan_opcode_value_type_invalid;
|
||||
|
||||
/* variables used for WlanEnumInterfaces */
|
||||
PWLAN_INTERFACE_INFO_LIST p_intf_list = nullptr;
|
||||
PWLAN_INTERFACE_INFO p_intf_info = nullptr;
|
||||
PWLAN_CONNECTION_ATTRIBUTES p_connect_info = nullptr;
|
||||
ULONG* channel = nullptr;
|
||||
|
||||
wifi_information_.is_connected = false;
|
||||
wifi_information_.ap_frequency = kDefaultApFreq;
|
||||
wifi_information_.ssid.clear();
|
||||
@@ -144,86 +156,10 @@ api::WifiInformation& WifiMedium::GetInformation() {
|
||||
return wifi_information_;
|
||||
}
|
||||
|
||||
p_intf_list = EnumInterface(&client_handle);
|
||||
if (!client_handle) {
|
||||
LOG(INFO) << "Client Handle is nullptr";
|
||||
if (!GetWifiInformation()) {
|
||||
FillupEthernetParams();
|
||||
return wifi_information_;
|
||||
}
|
||||
if (!p_intf_list) {
|
||||
LOG(INFO) << "WlanEnumInterfaces failed with error: ";
|
||||
WlanCloseHandle(client_handle, nullptr);
|
||||
FillupEthernetParams();
|
||||
return wifi_information_;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)p_intf_list->dwNumberOfItems; i++) {
|
||||
p_intf_info = (WLAN_INTERFACE_INFO*)&p_intf_list->InterfaceInfo[i];
|
||||
if (p_intf_info->isState == wlan_interface_state_connected) {
|
||||
LOG(INFO) << "Found connected WiFi interface No: " << i;
|
||||
wifi_information_.is_connected = true;
|
||||
|
||||
DWORD channel_size;
|
||||
result = WlanQueryInterface(client_handle, &p_intf_info->InterfaceGuid,
|
||||
wlan_intf_opcode_channel_number, nullptr,
|
||||
&channel_size, (PVOID*)&channel,
|
||||
&op_code_value_type);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(INFO) << "WlanQueryInterface channel error = " << result;
|
||||
WlanFreeMemory(p_intf_list);
|
||||
p_intf_list = nullptr;
|
||||
WlanCloseHandle(client_handle, nullptr);
|
||||
FillupEthernetParams();
|
||||
return wifi_information_;
|
||||
}
|
||||
wifi_information_.ap_frequency = WifiUtils::ConvertChannelToFrequencyMhz(
|
||||
*channel, api::WifiBandType::kUnknown);
|
||||
LOG(INFO) << "Channel: " << (channel == nullptr ? 0 : *channel)
|
||||
<< "; ap_frequency: " << wifi_information_.ap_frequency;
|
||||
WlanFreeMemory(channel);
|
||||
channel = nullptr;
|
||||
|
||||
result = WlanQueryInterface(client_handle, &p_intf_info->InterfaceGuid,
|
||||
wlan_intf_opcode_current_connection, nullptr,
|
||||
&connect_info_size, (PVOID*)&p_connect_info,
|
||||
&op_code_value_type);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(INFO) << "WlanQueryInterface current AP error = " << result;
|
||||
WlanFreeMemory(p_intf_list);
|
||||
p_intf_list = nullptr;
|
||||
WlanCloseHandle(client_handle, nullptr);
|
||||
FillupEthernetParams();
|
||||
return wifi_information_;
|
||||
}
|
||||
|
||||
wifi_information_.ssid.resize(
|
||||
p_connect_info->wlanAssociationAttributes.dot11Ssid.uSSIDLength);
|
||||
std::memcpy(
|
||||
wifi_information_.ssid.data(),
|
||||
reinterpret_cast<const char*>(
|
||||
p_connect_info->wlanAssociationAttributes.dot11Ssid.ucSSID),
|
||||
wifi_information_.ssid.size());
|
||||
LOG(INFO) << "wifi ssid is: " << wifi_information_.ssid
|
||||
<< "; length is:" << wifi_information_.ssid.length();
|
||||
|
||||
char str_tmp[kMacAddrLen];
|
||||
strncpy(str_tmp,
|
||||
reinterpret_cast<const char*>(
|
||||
p_connect_info->wlanAssociationAttributes.dot11Bssid),
|
||||
kMacAddrLen);
|
||||
wifi_information_.bssid = absl::StrFormat(
|
||||
"%02llx:%02llx:%02llx:%02llx:%02llx:%02llx", str_tmp[0], str_tmp[1],
|
||||
str_tmp[2], str_tmp[3], str_tmp[4], str_tmp[5]);
|
||||
LOG(INFO) << "wifi bssid is: " << wifi_information_.bssid;
|
||||
}
|
||||
}
|
||||
|
||||
WlanFreeMemory(p_connect_info);
|
||||
p_connect_info = nullptr;
|
||||
WlanFreeMemory(p_intf_list);
|
||||
p_intf_list = nullptr;
|
||||
WlanCloseHandle(client_handle, nullptr);
|
||||
|
||||
if (wifi_information_.is_connected) {
|
||||
wifi_information_.ip_address_dot_decimal = InternalGetWifiIpAddress();
|
||||
wifi_information_.ip_address_4_bytes = ipaddr_dotdecimal_to_4bytes_string(
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/platform/implementation/windows/wlan_client.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <wlanapi.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "internal/platform/implementation/windows/scoped_wlan_memory.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
|
||||
WlanClient::~WlanClient() {
|
||||
if (wifi_ != nullptr) {
|
||||
WlanCloseHandle(wifi_, /*pReserved=*/nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool WlanClient::Initialize() {
|
||||
if (wifi_ != nullptr) {
|
||||
return true;
|
||||
}
|
||||
DWORD client_version = 2;
|
||||
DWORD negotiated_version = 0;
|
||||
DWORD result = 0;
|
||||
|
||||
result = WlanOpenHandle(client_version, /*pReserved=*/nullptr,
|
||||
&negotiated_version, &wifi_);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
return true;
|
||||
}
|
||||
LOG(INFO) << "WlanOpenHandle failed with error: " << result;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<WlanClient::InterfaceInfo> WlanClient::PopulateInterfaceInfos(
|
||||
PWLAN_INTERFACE_INFO_LIST interfaces) const {
|
||||
if (interfaces == nullptr) {
|
||||
return {};
|
||||
}
|
||||
std::vector<InterfaceInfo> interface_infos;
|
||||
for (int i = 0; i < interfaces->dwNumberOfItems; ++i) {
|
||||
bool connected =
|
||||
interfaces->InterfaceInfo[i].isState == wlan_interface_state_connected;
|
||||
bool ready =
|
||||
interfaces->InterfaceInfo[i].isState != wlan_interface_state_not_ready;
|
||||
interface_infos.push_back(
|
||||
{connected, ready, interfaces->InterfaceInfo[i].InterfaceGuid});
|
||||
}
|
||||
return interface_infos;
|
||||
}
|
||||
|
||||
std::vector<WlanClient::InterfaceInfo> WlanClient::GetInterfaceInfos() const {
|
||||
if (wifi_ == nullptr) {
|
||||
LOG(ERROR) << "WlanClient is not initialized.";
|
||||
return {};
|
||||
}
|
||||
ScopedWlanMemory<WLAN_INTERFACE_INFO_LIST> interfaces;
|
||||
DWORD result =
|
||||
WlanEnumInterfaces(wifi_, /*pReserved=*/nullptr, interfaces.OutParam());
|
||||
if (result != ERROR_SUCCESS) {
|
||||
LOG(ERROR) << "Failed to enum WLAN interfaces.";
|
||||
return {};
|
||||
}
|
||||
return PopulateInterfaceInfos(interfaces.get());
|
||||
}
|
||||
|
||||
} // namespace nearby::windows
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_WLAN_CLIENT_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_WLAN_CLIENT_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <wlanapi.h>
|
||||
#include <coguid.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace nearby::windows {
|
||||
|
||||
// A wrapper for Windows wlan client handle and some APIs.
|
||||
class WlanClient {
|
||||
public:
|
||||
struct InterfaceInfo {
|
||||
// Whether the interface is connected to an AP.
|
||||
bool connected = false;
|
||||
// Whether the interface is ready to use.
|
||||
bool ready = false;
|
||||
// Interface GUID of the WLAN interface.
|
||||
GUID guid = GUID_NULL;
|
||||
};
|
||||
|
||||
WlanClient() = default;
|
||||
~WlanClient();
|
||||
|
||||
// Initializes the wlan client handle. Returns true if successful.
|
||||
// If the client has already been initialized, this is a no-op.
|
||||
bool Initialize();
|
||||
|
||||
// Returns the wlan client handle.
|
||||
// If the client has not been initialized, this returns nullptr.
|
||||
HANDLE GetHandle() const { return wifi_; }
|
||||
|
||||
// Returns the state of all WLAN interfaces.
|
||||
// If the client has not been initialized, this returns an empty vector.
|
||||
std::vector<InterfaceInfo> GetInterfaceInfos() const;
|
||||
|
||||
private:
|
||||
friend class WlanClientTest;
|
||||
|
||||
std::vector<InterfaceInfo> PopulateInterfaceInfos(
|
||||
PWLAN_INTERFACE_INFO_LIST interfaces) const;
|
||||
|
||||
HANDLE wifi_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace nearby::windows
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_WLAN_CLIENT_H_
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/platform/implementation/windows/wlan_client.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
|
||||
class WlanClientTest : public ::testing::Test {
|
||||
protected:
|
||||
std::vector<WlanClient::InterfaceInfo> PopulateInterfaceInfos(
|
||||
PWLAN_INTERFACE_INFO_LIST interfaces) const {
|
||||
return wlan_client_.PopulateInterfaceInfos(interfaces);
|
||||
}
|
||||
|
||||
WlanClient wlan_client_;
|
||||
};
|
||||
|
||||
TEST_F(WlanClientTest, Initialize) {
|
||||
// Forge machines don't have wifi.
|
||||
EXPECT_FALSE(wlan_client_.Initialize());
|
||||
EXPECT_EQ(wlan_client_.GetHandle(), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(WlanClientTest, PopulateInterfaceInfos) {
|
||||
int num_of_items = 3;
|
||||
PWLAN_INTERFACE_INFO_LIST interfaces =
|
||||
reinterpret_cast<PWLAN_INTERFACE_INFO_LIST>(
|
||||
::WlanAllocateMemory(sizeof(WLAN_INTERFACE_INFO_LIST) +
|
||||
num_of_items * sizeof(WLAN_INTERFACE_INFO)));
|
||||
interfaces->dwNumberOfItems = num_of_items;
|
||||
interfaces->InterfaceInfo[0].isState = wlan_interface_state_connected;
|
||||
interfaces->InterfaceInfo[1].isState = wlan_interface_state_not_ready;
|
||||
interfaces->InterfaceInfo[2].isState = wlan_interface_state_disconnected;
|
||||
std::vector<WlanClient::InterfaceInfo> interface_infos =
|
||||
PopulateInterfaceInfos(interfaces);
|
||||
EXPECT_EQ(interface_infos.size(), 3);
|
||||
EXPECT_TRUE(interface_infos[0].connected);
|
||||
EXPECT_TRUE(interface_infos[0].ready);
|
||||
EXPECT_FALSE(interface_infos[1].connected);
|
||||
EXPECT_FALSE(interface_infos[1].ready);
|
||||
EXPECT_FALSE(interface_infos[2].connected);
|
||||
EXPECT_TRUE(interface_infos[2].ready);
|
||||
::WlanFreeMemory(interfaces);
|
||||
}
|
||||
|
||||
} // namespace nearby::windows
|
||||
Reference in New Issue
Block a user