diff --git a/internal/platform/implementation/windows/BUILD b/internal/platform/implementation/windows/BUILD index 9af770db..cc59bea1 100644 --- a/internal/platform/implementation/windows/BUILD +++ b/internal/platform/implementation/windows/BUILD @@ -152,7 +152,12 @@ cc_library( ], deps = [ ":string_utils", + ":wlan_client", "//internal/platform:logging", + "@com_google_absl//absl/algorithm:container", + "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/base:no_destructor", + "@com_google_absl//absl/strings", "@com_google_absl//absl/synchronization", ], ) diff --git a/internal/platform/implementation/windows/network_info.cc b/internal/platform/implementation/windows/network_info.cc index 06c4a10c..18949379 100644 --- a/internal/platform/implementation/windows/network_info.cc +++ b/internal/platform/implementation/windows/network_info.cc @@ -27,10 +27,12 @@ #include #include +#include "absl/algorithm/container.h" #include "absl/base/no_destructor.h" #include "absl/strings/str_cat.h" #include "absl/synchronization/mutex.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 { @@ -65,6 +67,23 @@ NetworkInfo& NetworkInfo::GetNetworkInfo() { return *kNetworkInfo; } +void NetworkInfo::GetWifiLuids(std::vector& wifi_luids) { + // If `wifi_luids` is not empty, it is assumed to be populated already. + if (!wifi_luids.empty()) { + return; + } + if (!wlan_client_.Initialize()) { + return; + } + auto wlan_interfaces = wlan_client_.GetInterfaceInfos(); + for (const auto& wlan_interface : wlan_interfaces) { + NET_LUID luid; + if (ConvertInterfaceGuidToLuid(&wlan_interface.guid, &luid) == NO_ERROR) { + wifi_luids.push_back(luid.Value); + } + } +} + bool NetworkInfo::Refresh() { static constexpr int kDefaultBufferSize = 15 * 1024; // default to 15K buffer static constexpr int kMaxBufferSize = @@ -98,6 +117,7 @@ bool NetworkInfo::Refresh() { } std::vector result; IP_ADAPTER_ADDRESSES* next_address = addresses; + std::vector wifi_luids; while (next_address != nullptr) { if (next_address->OperStatus != IfOperStatusUp || next_address->IfType == IF_TYPE_SOFTWARE_LOOPBACK || @@ -117,10 +137,21 @@ bool NetworkInfo::Refresh() { << string_utils::WideStringToString(next_address->Description) << ", index: " << next_address->IfIndex; } else if (next_address->IfType == IF_TYPE_IEEE80211) { - it->type = InterfaceType::kWifi; - VLOG(1) << "Found wifi interface: " - << string_utils::WideStringToString(next_address->Description) - << ", index: " << next_address->IfIndex; + // Hotspot interfaces are not available from WlanClient, so if we can't + // find the interface in the list, we assume it's a hotspot interface. + GetWifiLuids(wifi_luids); + if (absl::c_find(wifi_luids, + next_address->Luid.Value) == wifi_luids.end()) { + it->type = InterfaceType::kWifiHotspot; + VLOG(1) << "Found wifi-hotspot interface: " + << string_utils::WideStringToString(next_address->Description) + << ", index: " << next_address->IfIndex; + } else { + it->type = InterfaceType::kWifi; + VLOG(1) << "Found wifi interface: " + << string_utils::WideStringToString(next_address->Description) + << ", index: " << next_address->IfIndex; + } } else { it->type = InterfaceType::kOther; VLOG(1) << "Found other interface: " diff --git a/internal/platform/implementation/windows/network_info.h b/internal/platform/implementation/windows/network_info.h index ec1fc047..eba54982 100644 --- a/internal/platform/implementation/windows/network_info.h +++ b/internal/platform/implementation/windows/network_info.h @@ -25,6 +25,7 @@ #include "absl/base/thread_annotations.h" #include "absl/synchronization/mutex.h" +#include "internal/platform/implementation/windows/wlan_client.h" namespace nearby::windows { @@ -32,6 +33,7 @@ namespace nearby::windows { enum InterfaceType { kEthernet, kWifi, + kWifiHotspot, // Wifi SoftAP interface kOther, }; @@ -61,6 +63,11 @@ class NetworkInfo { bool RenewIpv4Address(NET_LUID luid) const; private: + // Lazily initializes the list of wlan interface LUIDs. If `wifi_luids` is + // not empty, it is assumed to be populated already. + void GetWifiLuids(std::vector& wifi_luids); + + WlanClient wlan_client_; mutable absl::Mutex mutex_; std::vector interfaces_ ABSL_GUARDED_BY(mutex_); };