Add flag for sending hotspot address candidates.

PiperOrigin-RevId: 830628854
This commit is contained in:
Francis Tsui
2025-11-10 15:44:26 -08:00
committed by Copybara-Service
parent e49fe76dc5
commit 438b503f0b
5 changed files with 70 additions and 15 deletions
@@ -53,6 +53,10 @@ constexpr auto kWifiHotspotConnectionIntervalMillis =
constexpr auto kWifiHotspotConnectionTimeoutMillis =
flags::Flag<int64_t>(kConfigPackage, "45415888", 10000);
// Enable/Disable use of address candidates for hotspot upgrade in Windows.
constexpr auto kEnableHotspotAddressCandidates =
flags::Flag<bool>(kConfigPackage, "45739567", false);
// Enable/Disable DHCP renewal when connecting to hotspot.
constexpr auto kEnableHotspotDhcpRenew =
flags::Flag<bool>(kConfigPackage, "45731858", false);
@@ -409,6 +409,14 @@ bool WifiHotspotMedium::ConnectWifiHotspot(
// Make sure IP address is ready.
bool has_address = false;
bool has_ipv6_candidates = false;
for (const auto& address_candidate :
hotspot_credentials.GetAddressCandidates()) {
if (address_candidate.address.size() == 16) {
has_ipv6_candidates = true;
break;
}
}
int64_t ip_address_max_retries = NearbyFlags::GetInstance().GetInt64Flag(
platform::config_package_nearby::nearby_platform_feature::
kWifiHotspotCheckIpMaxRetries);
@@ -425,7 +433,7 @@ bool WifiHotspotMedium::ConnectWifiHotspot(
for (int i = 0; i < ip_address_max_retries; i++) {
LOG(INFO) << "Check IP address at attempt " << i;
if (wifi_hotspot_native_.HasAssignedAddress()) {
if (wifi_hotspot_native_.HasAssignedAddress(has_ipv6_candidates)) {
has_address = true;
break;
}
@@ -393,7 +393,7 @@ bool WifiHotspotNative::RestoreWifiProfile() {
return ConnectToWifiNetworkInternal(interface_guid, backup_profile_name_);
}
bool WifiHotspotNative::HasAssignedAddress() {
bool WifiHotspotNative::HasAssignedAddress(bool include_ipv6) {
if (!network_info_.Refresh()) {
return false;
}
@@ -408,6 +408,11 @@ bool WifiHotspotNative::HasAssignedAddress() {
if (interface.luid.Value != luid.Value) {
continue;
}
if (include_ipv6) {
if (!interface.ipv6_addresses.empty()) {
return true;
}
}
for (const auto& address : interface.ipv4_addresses) {
DCHECK(address.ss_family == AF_INET);
const sockaddr_in* ipv4_address =
@@ -47,8 +47,10 @@ class WifiHotspotNative {
bool RestoreWifiProfile() ABSL_LOCKS_EXCLUDED(mutex_);
// Returns true if the interface has a non local scoped IPv4 address.
bool HasAssignedAddress();
// Returns true if the interface has required IP address assigned.
// If `include_ipv6` is false, check for non local scoped IPv4 address only.
// Otherwise, check for any IPv6 address or non local scoped IPv4 address.
bool HasAssignedAddress(bool include_ipv6);
bool RenewIpv4Address() const;
// Return the interface index of the wifi interface used to connect to the
// hotspot.
@@ -34,6 +34,7 @@
#include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.Collections.h"
#include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.Connectivity.h"
#include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.Sockets.h"
#include "internal/platform/implementation/windows/network_info.h"
#include "internal/platform/implementation/windows/socket_address.h"
#include "internal/platform/implementation/windows/utils.h"
#include "internal/platform/implementation/windows/wifi_hotspot_server_socket.h"
@@ -87,18 +88,53 @@ void WifiHotspotServerSocket::PopulateHotspotCredentials(
"addresses configured on computer.";
return;
}
std::vector<char> hotspot_ipaddr_bytes;
uint32_t address_int = inet_addr(hotspot_ipaddr.c_str());
if (address_int != INADDR_NONE) {
hotspot_ipaddr_bytes.resize(4);
std::memcpy(hotspot_ipaddr_bytes.data(),
reinterpret_cast<char*>(&address_int), 4);
bool use_address_candidates = NearbyFlags::GetInstance().GetBoolFlag(
platform::config_package_nearby::nearby_platform_feature::
kEnableHotspotAddressCandidates);
if (!use_address_candidates) {
std::vector<char> hotspot_ipaddr_bytes;
uint32_t address_int = inet_addr(hotspot_ipaddr.c_str());
if (address_int != INADDR_NONE) {
hotspot_ipaddr_bytes.resize(4);
std::memcpy(hotspot_ipaddr_bytes.data(),
reinterpret_cast<char*>(&address_int), 4);
}
ServiceAddress service_address = {
.address = hotspot_ipaddr_bytes,
.port = static_cast<uint16_t>(GetPort()),
};
hotspot_credentials.SetAddressCandidates({service_address});
return;
}
ServiceAddress service_address = {
.address = hotspot_ipaddr_bytes,
.port = static_cast<uint16_t>(GetPort()),
};
hotspot_credentials.SetAddressCandidates({service_address});
std::vector<ServiceAddress> service_addresses;
for (const auto& interface : NetworkInfo::GetNetworkInfo().GetInterfaces()) {
if (interface.type == InterfaceType::kWifiHotspot) {
LOG(INFO) << "Found Wifi Hotspot interface, index: " << interface.index;
for (const auto& ipaddress : interface.ipv6_addresses) {
const sockaddr_in6* ipv6_address =
reinterpret_cast<const sockaddr_in6*>(&ipaddress);
service_addresses.push_back(ServiceAddress{
.address = std::vector<char>(ipv6_address->sin6_addr.u.Byte,
ipv6_address->sin6_addr.u.Byte + 16),
.port = static_cast<uint16_t>(GetPort()),
});
}
for (const auto& ipaddress : interface.ipv4_addresses) {
const sockaddr_in* ipv4_address =
reinterpret_cast<const sockaddr_in*>(&ipaddress);
service_addresses.push_back(ServiceAddress{
.address = {ipv4_address->sin_addr.S_un.S_un_b.s_b1,
ipv4_address->sin_addr.S_un.S_un_b.s_b2,
ipv4_address->sin_addr.S_un.S_un_b.s_b3,
ipv4_address->sin_addr.S_un.S_un_b.s_b4},
.port = static_cast<uint16_t>(GetPort()),
});
}
break;
}
}
hotspot_credentials.SetAddressCandidates(std::move(service_addresses));
}
bool WifiHotspotServerSocket::Listen(int port, bool dual_stack) {