Wi-Fi Direct Service Implementation(9.3)

PiperOrigin-RevId: 859401498
This commit is contained in:
hai007
2026-01-21 21:19:11 -08:00
committed by Copybara-Service
parent 8c4711711a
commit 0eb177d4b5
4 changed files with 113 additions and 57 deletions
@@ -19,9 +19,12 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <setupapi.h>
#include <devguid.h>
// clang-format on
// Standard C/C++ headers
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <optional>
@@ -351,4 +354,98 @@ std::optional<std::wstring> GetDnsHostName() {
return std::nullopt;
}
bool IsIntelWifiAdapter() {
bool found_intel = false;
LOG(INFO) << "Starting scan for Intel Wi-Fi adapters...";
// 1. Get a handle to all network adapters present in the system
HDEVINFO h_dev_info =
SetupDiGetClassDevsW(&GUID_DEVCLASS_NET, nullptr, nullptr, DIGCF_PRESENT);
// SetupDiDestroyDeviceInfoList needs to be called in the end of this function
if (h_dev_info == INVALID_HANDLE_VALUE) {
LOG(ERROR) << "Failed to get Class Devs handle. Error: " << GetLastError();
return false;
}
SP_DEVINFO_DATA dev_info_data;
dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
// 2. Enumerate through the devices
for (DWORD i = 0; SetupDiEnumDeviceInfo(h_dev_info, i, &dev_info_data); i++) {
// 3. Get the Hardware ID property (contains VEN_XXXX and DEV_XXXX)
DWORD hardware_id_size = 0;
if (!SetupDiGetDeviceRegistryPropertyW(h_dev_info, &dev_info_data,
SPDRP_HARDWAREID, nullptr, nullptr,
0, &hardware_id_size) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
LOG(ERROR) << "Failed to get Hardware ID size. Error: " << GetLastError();
continue;
}
std::wstring hardware_id;
hardware_id.resize((hardware_id_size + sizeof(wchar_t) - 1) /
sizeof(wchar_t));
if (SetupDiGetDeviceRegistryPropertyW(
h_dev_info, &dev_info_data, SPDRP_HARDWAREID, nullptr,
reinterpret_cast<BYTE*>(hardware_id.data()),
hardware_id.size() * sizeof(wchar_t), nullptr)) {
// REG_MULTI_SZ contains multiple null-terminated strings.
// We search the whole buffer for the Intel Vendor ID (8086).
// 4. Check for Intel Vendor ID: 8086
// On you Windows computer, go to "Device Manager" --> "Network adapters"
// --> Right click Wifi device
// --> click "properties" --> click "Details" --> In "Property" dropdown
// list, choose "Hardware ID", then you will see:
// Hardware IDs look like: PCI\VEN_8086&DEV_2723...,
// https://learn.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-pci-devices
// https://learn.microsoft.com/en-us/windows-hardware/drivers/install/inf-models-section
if (hardware_id.find(L"VEN_8086") != // NOLINT - ClangTidy asks to replace
// find() with absl::StrContains(), but
// this is not applicable to wide string
// and will cause compile error.
std::wstring::npos) {
// 5. Ensure it's a Wi-Fi/Wireless device
// We check the description to make sure we aren't flagging an Intel
// Ethernet chip
std::wstring to_log_hw_id = hardware_id;
// Replace all null characters with spaces to avoid truncation.
std::replace(to_log_hw_id.begin(), to_log_hw_id.end(), L'\0', L' ');
LOG(INFO) << " - Hardware ID: "
<< string_utils::WideStringToString(to_log_hw_id);
DWORD desc_buf_size = 0;
if (!SetupDiGetDeviceRegistryPropertyW(h_dev_info, &dev_info_data,
SPDRP_DEVICEDESC, nullptr,
nullptr, 0, &desc_buf_size) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
continue;
}
std::wstring name;
name.resize((desc_buf_size + sizeof(wchar_t) - 1) / sizeof(wchar_t));
if (SetupDiGetDeviceRegistryPropertyW(
h_dev_info, &dev_info_data, SPDRP_DEVICEDESC, nullptr,
reinterpret_cast<BYTE*>(name.data()),
name.size() * sizeof(wchar_t), nullptr)) {
if (name.find(L"Wi-Fi") != // NOLINT - ClangTidy asks to replace
// find() with absl::StrContains(), but
// this is not applicable to wide string
// and will cause compile error.
std::wstring::npos ||
name.find(L"Wireless") != // NOLINT
std::wstring::npos ||
name.find(L"Killer") != // NOLINT
std::wstring::npos) {
LOG(INFO) << "Found Intel Wi-Fi: " << name;
found_intel = true;
break;
}
}
}
}
}
SetupDiDestroyDeviceInfoList(h_dev_info);
return found_intel;
}
} // namespace nearby::windows
@@ -54,6 +54,9 @@ bool is_nearby_uuid_equal_to_winrt_guid(const Uuid& uuid,
// Returns the DNS host name of the computer or std::nullopt if it fails.
std::optional<std::wstring> GetDnsHostName();
// Returns true if the system has an Intel Wi-Fi adapter.
bool IsIntelWifiAdapter();
namespace Constants {
// The Id of the Service Name SDP attribute
const uint16_t SdpServiceNameAttributeId = 0x100;
@@ -174,5 +174,10 @@ TEST(UtilsTests, GetDnsHostName) {
<< nearby::windows::string_utils::WideStringToString(*host_name);
}
TEST(UtilsTests, IsIntelWifiAdapter) {
bool is_intel_wifi_adapter = IsIntelWifiAdapter();
LOG(ERROR) << "is_intel_wifi_adapter: " << is_intel_wifi_adapter;
}
} // namespace windows
} // namespace nearby
@@ -31,6 +31,7 @@
#include "internal/platform/flags/nearby_platform_feature_flags.h"
#include "internal/platform/implementation/wifi_direct.h"
#include "internal/platform/implementation/windows/socket_address.h"
#include "internal/platform/implementation/windows/utils.h"
#include "internal/platform/implementation/windows/wifi_direct.h"
#include "internal/platform/logging.h"
#include "internal/platform/prng.h"
@@ -73,6 +74,12 @@ WifiDirectMedium::~WifiDirectMedium() {
}
bool WifiDirectMedium::IsWifiDirectServiceSupported() {
if (!IsIntelWifiAdapter()) {
LOG(INFO) << "Intel Wifi adapter is not found, WifiDirectService is not "
"supported.";
return false;
}
HANDLE wifi_direct_handle = nullptr;
DWORD negotiated_version = 0;
DWORD result = 0;
@@ -85,63 +92,7 @@ bool WifiDirectMedium::IsWifiDirectServiceSupported() {
}
LOG(INFO) << "WiFi can support WifiDirect";
WFDCloseHandle(wifi_direct_handle);
// Check if device support WinRT WiFiDirectService
bool support_wifi_direct_service = false;
std::string service_name = "NC-validation";
// Create Advertiser object
WiFiDirectServiceAdvertiser advertiser =
WiFiDirectServiceAdvertiser(winrt::to_hstring(service_name));
if (advertiser == nullptr) {
LOG(ERROR) << "Failed to create WiFiDirectServiceAdvertiser";
return false;
}
advertiser.AutoAcceptSession(true);
advertiser.PreferGroupOwnerMode(true);
advertiser.ServiceStatus(WiFiDirectServiceStatus::Available);
// Config Methods
WiFiDirectServiceConfigurationMethod config_method =
WiFiDirectServiceConfigurationMethod::Default; // NOLINT
advertiser.PreferredConfigurationMethods().Clear();
advertiser.PreferredConfigurationMethods().Append(config_method);
try {
advertiser.Start();
LOG(INFO) << "Start WifiDirect GO Status: "
<< (int)advertiser.AdvertisementStatus();
if (advertiser.AdvertisementStatus() ==
WiFiDirectServiceAdvertisementStatus::Created) {
LOG(INFO) << "WinRT WiFiDirectService is supported on this device.";
support_wifi_direct_service = true;
} else if (advertiser.AdvertisementStatus() ==
WiFiDirectServiceAdvertisementStatus::Started) {
LOG(INFO) << "WinRT WiFiDirectService is supported on this device.";
advertiser.Stop();
support_wifi_direct_service = true;
} else {
if (advertiser.AdvertisementStatus() ==
WiFiDirectServiceAdvertisementStatus::Aborted) {
LOG(INFO) << "Failed to start WifiDirect GO with error code: "
<< (int)advertiser.ServiceError();
}
LOG(INFO) << "WinRT WiFiDirectService is not supported on this device.";
support_wifi_direct_service = false;
}
} catch (std::exception exception) {
LOG(ERROR) << __func__ << ": Start WifiDirect GO failed. Exception: "
<< exception.what();
} catch (const winrt::hresult_error& error) {
LOG(ERROR) << __func__ << ": Start WifiDirect GO failed. WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
} catch (...) {
LOG(ERROR) << __func__ << ": Unknown exeption.";
}
advertiser = nullptr;
return support_wifi_direct_service;
return true;
}
bool WifiDirectMedium::IsInterfaceValid() const {