mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
WIFI Hotspot implementation (4)
Part 4: BWU and client interface part PiperOrigin-RevId: 443700883
This commit is contained in:
@@ -345,6 +345,7 @@ void StartAdvertisingDart(Core *pCore, const char *service_id,
|
||||
? "0000FE2C-0000-1000-8000-00805F9B34FB"
|
||||
: "";
|
||||
advertising_options.allowed.wifi_lan = options_dart.enable_wifi_lan;
|
||||
advertising_options.allowed.wifi_hotspot = options_dart.enable_wifi_hotspot;
|
||||
advertising_options.allowed.web_rtc = options_dart.enable_web_rtc;
|
||||
|
||||
ConnectionListenerW listener;
|
||||
@@ -435,6 +436,7 @@ void RequestConnectionDart(Core *pCore, const char *endpoint_id,
|
||||
connection_options.allowed.bluetooth = options_dart.enable_bluetooth;
|
||||
connection_options.allowed.ble = options_dart.enable_ble;
|
||||
connection_options.allowed.wifi_lan = options_dart.enable_wifi_lan;
|
||||
connection_options.allowed.wifi_hotspot = options_dart.enable_wifi_hotspot;
|
||||
connection_options.allowed.web_rtc = options_dart.enable_web_rtc;
|
||||
|
||||
ConnectionListenerW listener;
|
||||
|
||||
@@ -46,6 +46,7 @@ struct ConnectionOptionsDart {
|
||||
int64_t use_low_power_mode;
|
||||
int64_t discover_fast_advertisements;
|
||||
int64_t enable_wifi_lan;
|
||||
int64_t enable_wifi_hotspot;
|
||||
int64_t enable_nfc;
|
||||
int64_t enable_wifi_aware;
|
||||
int64_t enable_web_rtc;
|
||||
|
||||
@@ -1,77 +1,81 @@
|
||||
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_MEDIUM_SELECTOR_W_H_
|
||||
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_MEDIUM_SELECTOR_W_H_
|
||||
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace location::nearby::windows {
|
||||
|
||||
using MediumW = location::nearby::proto::connections::Medium;
|
||||
|
||||
// Generic type: allows definition of a feature T for every Medium.
|
||||
template <typename T>
|
||||
struct MediumSelectorW {
|
||||
T bluetooth;
|
||||
T ble;
|
||||
T web_rtc;
|
||||
T wifi_lan;
|
||||
|
||||
constexpr MediumSelectorW() = default;
|
||||
constexpr MediumSelectorW(const MediumSelectorW&) = default;
|
||||
constexpr MediumSelectorW& operator=(const MediumSelectorW&) = default;
|
||||
constexpr bool Any(const T& value) const {
|
||||
return bluetooth == value || ble == value || web_rtc == value ||
|
||||
wifi_lan == value;
|
||||
}
|
||||
|
||||
constexpr bool All(const T& value) const {
|
||||
return bluetooth == value && ble == value && web_rtc == value &&
|
||||
wifi_lan == value;
|
||||
}
|
||||
|
||||
constexpr int Count(const T& value) const {
|
||||
int count = 0;
|
||||
if (bluetooth == value) ++count;
|
||||
if (ble == value) ++count;
|
||||
if (wifi_lan == value) ++count;
|
||||
if (web_rtc == value) ++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
constexpr MediumSelectorW& SetAll(const T& value) {
|
||||
bluetooth = value;
|
||||
ble = value;
|
||||
web_rtc = value;
|
||||
wifi_lan = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::vector<MediumW> GetMediums(const T& value) const {
|
||||
std::vector<MediumW> mediums;
|
||||
// Mediums are sorted in order of decreasing preference.
|
||||
if (wifi_lan == value) mediums.push_back(MediumW::WIFI_LAN);
|
||||
if (web_rtc == value) mediums.push_back(MediumW::WEB_RTC);
|
||||
if (bluetooth == value) mediums.push_back(MediumW::BLUETOOTH);
|
||||
if (ble == value) mediums.push_back(MediumW::BLE);
|
||||
return mediums;
|
||||
}
|
||||
};
|
||||
|
||||
// Feature On/Off switch for mediums.
|
||||
using BooleanMediumSelectorW = MediumSelectorW<bool>;
|
||||
|
||||
} // namespace location::nearby::windows
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_MEDIUM_SELECTOR_W_H_
|
||||
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_MEDIUM_SELECTOR_W_H_
|
||||
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_MEDIUM_SELECTOR_W_H_
|
||||
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace location::nearby::windows {
|
||||
|
||||
using MediumW = location::nearby::proto::connections::Medium;
|
||||
|
||||
// Generic type: allows definition of a feature T for every Medium.
|
||||
template <typename T>
|
||||
struct MediumSelectorW {
|
||||
T bluetooth;
|
||||
T ble;
|
||||
T web_rtc;
|
||||
T wifi_lan;
|
||||
T wifi_hotspot;
|
||||
|
||||
constexpr MediumSelectorW() = default;
|
||||
constexpr MediumSelectorW(const MediumSelectorW&) = default;
|
||||
constexpr MediumSelectorW& operator=(const MediumSelectorW&) = default;
|
||||
constexpr bool Any(const T& value) const {
|
||||
return bluetooth == value || ble == value || web_rtc == value ||
|
||||
wifi_lan == value || wifi_hotspot == value;
|
||||
}
|
||||
|
||||
constexpr bool All(const T& value) const {
|
||||
return bluetooth == value && ble == value && web_rtc == value &&
|
||||
wifi_lan == value && wifi_hotspot == value;
|
||||
}
|
||||
|
||||
constexpr int Count(const T& value) const {
|
||||
int count = 0;
|
||||
if (bluetooth == value) ++count;
|
||||
if (ble == value) ++count;
|
||||
if (wifi_lan == value) ++count;
|
||||
if (wifi_hotspot == value) ++count;
|
||||
if (web_rtc == value) ++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
constexpr MediumSelectorW& SetAll(const T& value) {
|
||||
bluetooth = value;
|
||||
ble = value;
|
||||
web_rtc = value;
|
||||
wifi_lan = value;
|
||||
wifi_hotspot = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::vector<MediumW> GetMediums(const T& value) const {
|
||||
std::vector<MediumW> mediums;
|
||||
// Mediums are sorted in order of decreasing preference.
|
||||
if (wifi_lan == value) mediums.push_back(MediumW::WIFI_LAN);
|
||||
if (wifi_hotspot == value) mediums.push_back(MediumW::WIFI_HOTSPOT);
|
||||
if (web_rtc == value) mediums.push_back(MediumW::WEB_RTC);
|
||||
if (bluetooth == value) mediums.push_back(MediumW::BLUETOOTH);
|
||||
if (ble == value) mediums.push_back(MediumW::BLE);
|
||||
return mediums;
|
||||
}
|
||||
};
|
||||
|
||||
// Feature On/Off switch for mediums.
|
||||
using BooleanMediumSelectorW = MediumSelectorW<bool>;
|
||||
|
||||
} // namespace location::nearby::windows
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_MEDIUM_SELECTOR_W_H_
|
||||
|
||||
@@ -67,6 +67,8 @@ cc_library(
|
||||
"service_controller_router.cc",
|
||||
"webrtc_bwu_handler.cc",
|
||||
"webrtc_endpoint_channel.cc",
|
||||
"wifi_hotspot_bwu_handler.cc",
|
||||
"wifi_hotspot_endpoint_channel.cc",
|
||||
"wifi_lan_bwu_handler.cc",
|
||||
"wifi_lan_endpoint_channel.cc",
|
||||
"wifi_lan_service_info.cc",
|
||||
@@ -105,6 +107,8 @@ cc_library(
|
||||
"service_id_constants.h",
|
||||
"webrtc_bwu_handler.h",
|
||||
"webrtc_endpoint_channel.h",
|
||||
"wifi_hotspot_bwu_handler.h",
|
||||
"wifi_hotspot_endpoint_channel.h",
|
||||
"wifi_lan_bwu_handler.h",
|
||||
"wifi_lan_endpoint_channel.h",
|
||||
"wifi_lan_service_info.h",
|
||||
@@ -214,6 +218,7 @@ cc_test(
|
||||
"payload_manager_test.cc",
|
||||
"pcp_manager_test.cc",
|
||||
"service_controller_router_test.cc",
|
||||
"wifi_hotspot_test.cc",
|
||||
"wifi_lan_service_info_test.cc",
|
||||
],
|
||||
defines = ["NO_WEBRTC"],
|
||||
|
||||
@@ -171,6 +171,9 @@ void BasePcpHandler::OptionsAllowed(const BooleanMediumSelector& allowed,
|
||||
if (allowed.wifi_lan) {
|
||||
result << proto::connections::Medium_Name(Medium::WIFI_LAN) << " ";
|
||||
}
|
||||
if (allowed.wifi_hotspot) {
|
||||
result << proto::connections::Medium_Name(Medium::WIFI_HOTSPOT) << " ";
|
||||
}
|
||||
result << "}";
|
||||
}
|
||||
|
||||
@@ -218,6 +221,7 @@ BooleanMediumSelector BasePcpHandler::ComputeIntersectionOfSupportedMediums(
|
||||
mediumSelector.ble = intersection.contains(Medium::BLE);
|
||||
mediumSelector.web_rtc = intersection.contains(Medium::WEB_RTC);
|
||||
mediumSelector.wifi_lan = intersection.contains(Medium::WIFI_LAN);
|
||||
mediumSelector.wifi_hotspot = intersection.contains(Medium::WIFI_HOTSPOT);
|
||||
return mediumSelector;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
#include "connections/implementation/service_id_constants.h"
|
||||
#include "connections/implementation/webrtc_bwu_handler.h"
|
||||
#include "connections/implementation/wifi_hotspot_bwu_handler.h"
|
||||
#include "connections/implementation/wifi_lan_bwu_handler.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
@@ -74,6 +75,7 @@ BwuManager::BwuManager(
|
||||
if (config_.allow_upgrade_to.All(false)) {
|
||||
config_.allow_upgrade_to.web_rtc = true;
|
||||
config_.allow_upgrade_to.wifi_lan = true;
|
||||
config_.allow_upgrade_to.wifi_hotspot = true;
|
||||
}
|
||||
if (!handlers.empty()) {
|
||||
handlers_ = std::move(handlers);
|
||||
@@ -97,6 +99,11 @@ void BwuManager::InitBwuHandlers() {
|
||||
.incoming_connection_cb =
|
||||
absl::bind_front(&BwuManager::OnIncomingConnection, this),
|
||||
};
|
||||
if (config_.allow_upgrade_to.wifi_hotspot) {
|
||||
handlers_.emplace(
|
||||
Medium::WIFI_HOTSPOT,
|
||||
std::make_unique<WifiHotspotBwuHandler>(*mediums_, notifications));
|
||||
}
|
||||
if (config_.allow_upgrade_to.wifi_lan) {
|
||||
handlers_.emplace(Medium::WIFI_LAN, std::make_unique<WifiLanBwuHandler>(
|
||||
*mediums_, notifications));
|
||||
@@ -167,6 +174,21 @@ void BwuManager::InitiateBwuForEndpoint(ClientProxy* client,
|
||||
NEARBY_LOGS(INFO) << "InitiateBwuForEndpoint for endpoint " << endpoint_id
|
||||
<< " with medium "
|
||||
<< proto::connections::Medium_Name(proposed_medium);
|
||||
|
||||
auto channel = channel_manager_->GetChannelForEndpoint(endpoint_id);
|
||||
Medium channel_medium =
|
||||
channel ? channel->GetMedium() : Medium::UNKNOWN_MEDIUM;
|
||||
|
||||
if ((channel_medium == Medium::WIFI_LAN) &&
|
||||
(proposed_medium == Medium::WIFI_HOTSPOT)) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Current medium is WIFI_LAN and proposed upgrade medium is "
|
||||
":WIFI_HOTSPOT. Don't do the BWU because connecting to "
|
||||
"WIFI_HOTSPOT will destroy WIFI_LAN which will lead BWU fail";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SetBwuMediumForEndpoint(endpoint_id, proposed_medium);
|
||||
BwuHandler* handler = GetHandlerForMedium(proposed_medium);
|
||||
if (!handler) {
|
||||
@@ -188,9 +210,6 @@ void BwuManager::InitiateBwuForEndpoint(ClientProxy* client,
|
||||
|
||||
CancelRetryUpgradeAlarm(endpoint_id);
|
||||
|
||||
auto channel = channel_manager_->GetChannelForEndpoint(endpoint_id);
|
||||
Medium channel_medium =
|
||||
channel ? channel->GetMedium() : Medium::UNKNOWN_MEDIUM;
|
||||
client->GetAnalyticsRecorder().OnBandwidthUpgradeStarted(
|
||||
endpoint_id, channel_medium, proposed_medium,
|
||||
proto::connections::INCOMING, client->GetConnectionToken(endpoint_id));
|
||||
@@ -592,10 +611,11 @@ void BwuManager::RunUpgradeProtocol(
|
||||
void BwuManager::ProcessBwuPathAvailableEvent(
|
||||
ClientProxy* client, const string& endpoint_id,
|
||||
const UpgradePathInfo& upgrade_path_info) {
|
||||
Medium medium =
|
||||
parser::UpgradePathInfoMediumToMedium(upgrade_path_info.medium());
|
||||
NEARBY_LOGS(INFO) << "ProcessBwuPathAvailableEvent for endpoint "
|
||||
<< endpoint_id << " medium "
|
||||
<< parser::UpgradePathInfoMediumToMedium(
|
||||
upgrade_path_info.medium());
|
||||
<< proto::connections::Medium_Name(medium);
|
||||
if (in_progress_upgrades_.contains(endpoint_id)) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "BwuManager received a duplicate bandwidth upgrade for endpoint "
|
||||
@@ -787,8 +807,9 @@ void BwuManager::RunUpgradeFailedProtocol(
|
||||
const UpgradePathInfo& upgrade_path_info) {
|
||||
NEARBY_LOGS(INFO) << "RunUpgradeFailedProtocol for endpoint " << endpoint_id
|
||||
<< " medium "
|
||||
<< parser::UpgradePathInfoMediumToMedium(
|
||||
upgrade_path_info.medium());
|
||||
<< proto::connections::Medium_Name(
|
||||
parser::UpgradePathInfoMediumToMedium(
|
||||
upgrade_path_info.medium()));
|
||||
// We attempted to connect to the new medium that the remote device has set up
|
||||
// for us but we failed. We need to let the remote device know so that they
|
||||
// can pick another medium for us to try.
|
||||
@@ -1056,8 +1077,9 @@ void BwuManager::ProcessUpgradeFailureEvent(
|
||||
const UpgradePathInfo& upgrade_info) {
|
||||
NEARBY_LOGS(INFO) << "ProcessUpgradeFailureEvent for endpoint " << endpoint_id
|
||||
<< " from medium: "
|
||||
<< parser::UpgradePathInfoMediumToMedium(
|
||||
upgrade_info.medium());
|
||||
<< proto::connections::Medium_Name(
|
||||
parser::UpgradePathInfoMediumToMedium(
|
||||
upgrade_info.medium()));
|
||||
// The remote device failed to upgrade to the new medium we set up for them.
|
||||
// That's alright! We'll just try the next available medium (if there is one).
|
||||
in_progress_upgrades_.erase(endpoint_id);
|
||||
@@ -1154,6 +1176,9 @@ std::vector<Medium> BwuManager::StripOutUnavailableMediums(
|
||||
for (Medium m : mediums) {
|
||||
bool available = false;
|
||||
switch (m) {
|
||||
case Medium::WIFI_HOTSPOT:
|
||||
available = mediums_->GetWifiHotspot().IsAvailable();
|
||||
break;
|
||||
case Medium::WIFI_LAN:
|
||||
available = mediums_->GetWifiLan().IsAvailable();
|
||||
break;
|
||||
|
||||
@@ -171,14 +171,14 @@ bool WifiHotspot::StartAcceptingConnections(
|
||||
accept_loops_runner_.Execute(
|
||||
"wifi-hotspot-accept",
|
||||
[callback = std::move(callback),
|
||||
server_socket = std::move(owned_server_socket)]() mutable {
|
||||
server_socket = std::move(owned_server_socket), service_id]() mutable {
|
||||
while (true) {
|
||||
WifiHotspotSocket client_socket = server_socket.Accept();
|
||||
if (!client_socket.IsValid()) {
|
||||
server_socket.Close();
|
||||
break;
|
||||
}
|
||||
callback.accepted_cb(std::move(client_socket));
|
||||
callback.accepted_cb(service_id, std::move(client_socket));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ class WifiHotspot {
|
||||
public:
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
struct AcceptedConnectionCallback {
|
||||
std::function<void(WifiHotspotSocket socket)> accepted_cb =
|
||||
DefaultCallback<WifiHotspotSocket>();
|
||||
std::function<void(const std::string& service_id, WifiHotspotSocket socket)>
|
||||
accepted_cb = DefaultCallback<const std::string&, WifiHotspotSocket>();
|
||||
};
|
||||
|
||||
WifiHotspot() : is_hotspot_started_(false), is_connected_to_hotspot_(false) {}
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
|
||||
#include "connections/implementation/offline_frames_validator.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <regex> //NOLINT
|
||||
#include <string>
|
||||
|
||||
#include "connections/implementation/internal_payload.h"
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
#include "connections/implementation/mediums/utils.h"
|
||||
#include "connections/implementation/webrtc_endpoint_channel.h"
|
||||
#include "connections/implementation/wifi_lan_endpoint_channel.h"
|
||||
#include "internal/platform/crypto.h"
|
||||
#include "internal/platform/nsd_service_info.h"
|
||||
#include "internal/platform/types.h"
|
||||
#include "internal/platform/crypto.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace location {
|
||||
@@ -58,6 +58,7 @@ P2pClusterPcpHandler::P2pClusterPcpHandler(
|
||||
bluetooth_medium_(mediums->GetBluetoothClassic()),
|
||||
ble_medium_(mediums->GetBle()),
|
||||
wifi_lan_medium_(mediums->GetWifiLan()),
|
||||
wifi_hotspot_medium_(mediums->GetWifiHotspot()),
|
||||
webrtc_medium_(mediums->GetWebRtc()),
|
||||
injected_bluetooth_device_store_(injected_bluetooth_device_store) {}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define CORE_INTERNAL_P2P_CLUSTER_PCP_HANDLER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "connections/implementation/base_pcp_handler.h"
|
||||
@@ -29,8 +30,8 @@
|
||||
#include "connections/implementation/mediums/bluetooth_classic.h"
|
||||
#include "connections/implementation/mediums/mediums.h"
|
||||
#ifdef NO_WEBRTC
|
||||
#include "connections/implementation/mediums/webrtc_stub.h"
|
||||
#include "connections/implementation/mediums/webrtc_socket_stub.h"
|
||||
#include "connections/implementation/mediums/webrtc_stub.h"
|
||||
#else
|
||||
#include "connections/implementation/mediums/webrtc.h"
|
||||
#include "connections/implementation/mediums/webrtc_socket.h"
|
||||
@@ -38,8 +39,8 @@
|
||||
#include "connections/implementation/pcp.h"
|
||||
#include "connections/implementation/wifi_lan_service_info.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/bluetooth_classic.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/wifi_lan.h"
|
||||
|
||||
namespace location {
|
||||
@@ -197,6 +198,7 @@ class P2pClusterPcpHandler : public BasePcpHandler {
|
||||
BluetoothClassic& bluetooth_medium_;
|
||||
Ble& ble_medium_;
|
||||
WifiLan& wifi_lan_medium_;
|
||||
WifiHotspot& wifi_hotspot_medium_;
|
||||
mediums::WebRtc& webrtc_medium_;
|
||||
InjectedBluetoothDeviceStore& injected_bluetooth_device_store_;
|
||||
std::int64_t bluetooth_classic_discoverer_client_id_{0};
|
||||
|
||||
@@ -28,6 +28,9 @@ P2pPointToPointPcpHandler::P2pPointToPointPcpHandler(
|
||||
std::vector<proto::connections::Medium>
|
||||
P2pPointToPointPcpHandler::GetConnectionMediumsByPriority() {
|
||||
std::vector<proto::connections::Medium> mediums;
|
||||
if (mediums_->GetWifiHotspot().IsAvailable()) {
|
||||
mediums.push_back(proto::connections::WIFI_HOTSPOT);
|
||||
}
|
||||
if (mediums_->GetWifiLan().IsAvailable()) {
|
||||
mediums.push_back(proto::connections::WIFI_LAN);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
@@ -31,6 +33,9 @@ P2pStarPcpHandler::P2pStarPcpHandler(
|
||||
std::vector<proto::connections::Medium>
|
||||
P2pStarPcpHandler::GetConnectionMediumsByPriority() {
|
||||
std::vector<proto::connections::Medium> mediums;
|
||||
if (mediums_->GetWifiHotspot().IsAvailable()) {
|
||||
mediums.push_back(proto::connections::WIFI_HOTSPOT);
|
||||
}
|
||||
if (mediums_->GetWifiLan().IsAvailable()) {
|
||||
mediums.push_back(proto::connections::WIFI_LAN);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
// Copyright 2022 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 "connections/implementation/wifi_hotspot_bwu_handler.h"
|
||||
|
||||
#include <locale>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/functional/bind_front.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/mediums/utils.h"
|
||||
#include "connections/implementation/offline_frames.h"
|
||||
#include "connections/implementation/wifi_hotspot_endpoint_channel.h"
|
||||
#include "internal/platform/wifi_hotspot.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
WifiHotspotBwuHandler::WifiHotspotBwuHandler(Mediums& mediums,
|
||||
BwuNotifications notifications)
|
||||
: BaseBwuHandler(std::move(notifications)), mediums_(mediums) {}
|
||||
|
||||
// Called by BWU initiator. Set up WifiHotspot upgraded medium for this
|
||||
// endpoint, and returns a upgrade path info (SSID, Password, Gateway used as
|
||||
// IPAddress, Port) for remote party to perform connection.
|
||||
ByteArray WifiHotspotBwuHandler::HandleInitializeUpgradedMediumForEndpoint(
|
||||
ClientProxy* client, const std::string& upgrade_service_id,
|
||||
const std::string& endpoint_id) {
|
||||
// Create SoftAP
|
||||
if (!wifi_hotspot_medium_.StartWifiHotspot()) {
|
||||
NEARBY_LOGS(INFO) << "Failed to start Wifi Hotspot!";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!wifi_hotspot_medium_.IsAcceptingConnections(upgrade_service_id)) {
|
||||
if (!wifi_hotspot_medium_.StartAcceptingConnections(
|
||||
upgrade_service_id,
|
||||
{
|
||||
.accepted_cb = absl::bind_front(
|
||||
&WifiHotspotBwuHandler::OnIncomingWifiHotspotConnection,
|
||||
this, client),
|
||||
})) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "WifiHotspotBwuHandler couldn't initiate WifiHotspot upgrade for "
|
||||
<< "service " << upgrade_service_id << " and endpoint " << endpoint_id
|
||||
<< " because it failed to start listening for incoming WifiLan "
|
||||
"connections.";
|
||||
return {};
|
||||
}
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "WifiHotspotBwuHandler successfully started listening for incoming "
|
||||
"WifiHotspot connections while upgrading endpoint "
|
||||
<< endpoint_id;
|
||||
}
|
||||
|
||||
// Note: Credentials are not generated until Medium StartWifiHotspot() is
|
||||
// called and the server socket is created. Be careful moving this codeblock
|
||||
// around.
|
||||
HotspotCredentials* hotspot_crendential =
|
||||
wifi_hotspot_medium_.GetCredentials(upgrade_service_id);
|
||||
std::string ssid = hotspot_crendential->GetSSID();
|
||||
std::string password = hotspot_crendential->GetPassword();
|
||||
std::string gateway = hotspot_crendential->GetGateway();
|
||||
std::int32_t port = hotspot_crendential->GetPort();
|
||||
|
||||
NEARBY_LOGS(INFO) << "Start SoftAP with SSID:" << ssid
|
||||
<< ", Password:" << password << ", Port:" << port
|
||||
<< ", Gateway:" << gateway;
|
||||
|
||||
return parser::ForBwuWifiHotspotPathAvailable(ssid, password, port, gateway,
|
||||
false);
|
||||
}
|
||||
|
||||
void WifiHotspotBwuHandler::HandleRevertInitiatorStateForService(
|
||||
const std::string& upgrade_service_id) {
|
||||
wifi_hotspot_medium_.StopAcceptingConnections(upgrade_service_id);
|
||||
wifi_hotspot_medium_.StopWifiHotspot();
|
||||
wifi_hotspot_medium_.DisconnectWifiHotspot();
|
||||
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "WifiHotspotBwuHandler successfully reverted all states for "
|
||||
<< "upgrade service ID " << upgrade_service_id;
|
||||
}
|
||||
|
||||
// Called by BWU target. Retrieves a new medium info from incoming message,
|
||||
// and establishes connection over WifiHotspot using this info.
|
||||
std::unique_ptr<EndpointChannel>
|
||||
WifiHotspotBwuHandler::CreateUpgradedEndpointChannel(
|
||||
ClientProxy* client, const std::string& service_id,
|
||||
const std::string& endpoint_id, const UpgradePathInfo& upgrade_path_info) {
|
||||
if (!upgrade_path_info.has_wifi_hotspot_credentials()) {
|
||||
NEARBY_LOGS(INFO) << "No Hotspot Credential";
|
||||
return nullptr;
|
||||
}
|
||||
const UpgradePathInfo::WifiHotspotCredentials& upgrade_path_info_credentials =
|
||||
upgrade_path_info.wifi_hotspot_credentials();
|
||||
|
||||
const std::string& ssid = upgrade_path_info_credentials.ssid();
|
||||
const std::string& password = upgrade_path_info_credentials.password();
|
||||
const std::string& gateway = upgrade_path_info_credentials.gateway();
|
||||
std::int32_t port = upgrade_path_info_credentials.port();
|
||||
|
||||
NEARBY_LOGS(INFO) << "Received Hotspot credential SSID: " << ssid
|
||||
<< ", Password:" << password << ", Port:" << port
|
||||
<< ", Gateway:" << gateway;
|
||||
|
||||
if (!wifi_hotspot_medium_.ConnectWifiHotspot(ssid, password)) {
|
||||
NEARBY_LOGS(ERROR) << "Connect to Hotspot failed";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WifiHotspotSocket socket = wifi_hotspot_medium_.Connect(
|
||||
service_id, gateway, port, client->GetCancellationFlag(endpoint_id));
|
||||
if (!socket.IsValid()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "WifiHotspotBwuHandler failed to connect to the WifiHotspot service("
|
||||
<< gateway << ":" << port << ") for endpoint " << endpoint_id;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(VERBOSE)
|
||||
<< "WifiHotspotBwuHandler successfully connected to WifiHotspot service ("
|
||||
<< gateway << ":" << port << ") while upgrading endpoint " << endpoint_id;
|
||||
|
||||
// Create a new WifiHotspotEndpointChannel.
|
||||
auto channel = std::make_unique<WifiHotspotEndpointChannel>(
|
||||
service_id, /*channel_name=*/service_id, socket);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
// Accept Connection Callback.
|
||||
void WifiHotspotBwuHandler::OnIncomingWifiHotspotConnection(
|
||||
ClientProxy* client, const std::string& upgrade_service_id,
|
||||
WifiHotspotSocket socket) {
|
||||
auto channel = std::make_unique<WifiHotspotEndpointChannel>(
|
||||
upgrade_service_id, /*channel_name=*/upgrade_service_id, socket);
|
||||
std::unique_ptr<IncomingSocketConnection> connection(
|
||||
new IncomingSocketConnection{
|
||||
.socket = std::make_unique<WifiHotspotIncomingSocket>(
|
||||
upgrade_service_id, socket),
|
||||
.channel = std::move(channel),
|
||||
});
|
||||
bwu_notifications_.incoming_connection_cb(client, std::move(connection));
|
||||
}
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,79 @@
|
||||
// Copyright 2022 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 CORE_INTERNAL_WIFI_HOTSPOT_BWU_HANDLER_H_
|
||||
#define CORE_INTERNAL_WIFI_HOTSPOT_BWU_HANDLER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "connections/implementation/base_bwu_handler.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_channel_manager.h"
|
||||
#include "connections/implementation/mediums/mediums.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
// Defines the set of methods that need to be implemented to handle the
|
||||
// per-Medium-specific operations needed to upgrade an EndpointChannel.
|
||||
class WifiHotspotBwuHandler : public BaseBwuHandler {
|
||||
public:
|
||||
explicit WifiHotspotBwuHandler(Mediums& mediums,
|
||||
BwuNotifications notifications);
|
||||
|
||||
private:
|
||||
class WifiHotspotIncomingSocket : public BwuHandler::IncomingSocket {
|
||||
public:
|
||||
explicit WifiHotspotIncomingSocket(const std::string& name,
|
||||
WifiHotspotSocket socket)
|
||||
: name_(name), socket_(socket) {}
|
||||
|
||||
std::string ToString() override { return name_; }
|
||||
void Close() override { socket_.Close(); }
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
WifiHotspotSocket socket_;
|
||||
};
|
||||
|
||||
// BwuHandler implementation:
|
||||
std::unique_ptr<EndpointChannel> CreateUpgradedEndpointChannel(
|
||||
ClientProxy* client, const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
const UpgradePathInfo& upgrade_path_info) final;
|
||||
Medium GetUpgradeMedium() const final { return Medium::WIFI_HOTSPOT; }
|
||||
void OnEndpointDisconnect(ClientProxy* client,
|
||||
const std::string& endpoint_id) final {}
|
||||
|
||||
// BaseBwuHandler implementation:
|
||||
ByteArray HandleInitializeUpgradedMediumForEndpoint(
|
||||
ClientProxy* client, const std::string& upgrade_service_id,
|
||||
const std::string& endpoint_id) final;
|
||||
void HandleRevertInitiatorStateForService(
|
||||
const std::string& upgrade_service_id) final;
|
||||
|
||||
void OnIncomingWifiHotspotConnection(ClientProxy* client,
|
||||
const std::string& upgrade_service_id,
|
||||
WifiHotspotSocket socket);
|
||||
|
||||
Mediums& mediums_;
|
||||
WifiHotspot& wifi_hotspot_medium_{mediums_.GetWifiHotspot()};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // CORE_INTERNAL_WIFI_HOTSPOT_BWU_HANDLER_H_
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright 2022 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 "connections/implementation/wifi_hotspot_endpoint_channel.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/wifi_hotspot.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
WifiHotspotEndpointChannel::WifiHotspotEndpointChannel(
|
||||
const std::string& service_id, const std::string& channel_name,
|
||||
WifiHotspotSocket socket)
|
||||
: BaseEndpointChannel(service_id, channel_name, &socket.GetInputStream(),
|
||||
&socket.GetOutputStream()),
|
||||
socket_(std::move(socket)) {}
|
||||
|
||||
proto::connections::Medium WifiHotspotEndpointChannel::GetMedium() const {
|
||||
return proto::connections::Medium::WIFI_HOTSPOT;
|
||||
}
|
||||
|
||||
void WifiHotspotEndpointChannel::CloseImpl() {
|
||||
Exception status = socket_.Close();
|
||||
if (!status.Ok()) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Failed to close underlying socket for WifiHotspotEndpointChannel "
|
||||
<< GetName() << " : exception = " << status.value;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2022 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 CORE_INTERNAL_WIFI_HOTSPOT_ENDPOINT_CHANNEL_H_
|
||||
#define CORE_INTERNAL_WIFI_HOTSPOT_ENDPOINT_CHANNEL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "connections/implementation/base_endpoint_channel.h"
|
||||
#include "internal/platform/wifi_hotspot.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
class WifiHotspotEndpointChannel final : public BaseEndpointChannel {
|
||||
public:
|
||||
// Creates both outgoing and incoming WifiHotspot channels.
|
||||
WifiHotspotEndpointChannel(const std::string& service_id,
|
||||
const std::string& channel_name,
|
||||
WifiHotspotSocket socket);
|
||||
// Not copyable or movable
|
||||
WifiHotspotEndpointChannel(const WifiHotspotEndpointChannel&) = delete;
|
||||
WifiHotspotEndpointChannel& operator=(const WifiHotspotEndpointChannel&) =
|
||||
delete;
|
||||
WifiHotspotEndpointChannel(WifiHotspotEndpointChannel&&) = delete;
|
||||
WifiHotspotEndpointChannel& operator=(WifiHotspotEndpointChannel&&) = delete;
|
||||
|
||||
proto::connections::Medium GetMedium() const override;
|
||||
|
||||
private:
|
||||
void CloseImpl() override;
|
||||
|
||||
WifiHotspotSocket socket_;
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // CORE_INTERNAL_WIFI_HOTSPOT_ENDPOINT_CHANNEL_H_
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright 2022 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 "connections/implementation/wifi_hotspot_bwu_handler.h"
|
||||
#include "connections/implementation/wifi_hotspot_endpoint_channel.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
TEST(WifiHotspotTest, CanCreateBwuHandler) {
|
||||
// TODO(b/227482970): Add test coverage for wifi_hotspot_bwu_handler.cc
|
||||
}
|
||||
|
||||
TEST(WifiHotspotTest, CanInitializeUpgradedMediumForEndpoint) {
|
||||
// TODO(b/227482970): Add test coverage for wifi_hotspot_bwu_handler.cc
|
||||
}
|
||||
|
||||
TEST(WifiHotspotTest, CanRevert) {
|
||||
// TODO(b/227482970): Add test coverage for wifi_hotspot_bwu_handler.cc
|
||||
}
|
||||
|
||||
TEST(WifiHotspotTest, CanCreateUpgradedEndpointChannel) {
|
||||
// TODO(b/227482970): Add test coverage for wifi_hotspot_bwu_handler.cc
|
||||
}
|
||||
|
||||
TEST(WifiHotspotTest, CanOnIncomingWifiHotspotConnection) {
|
||||
// TODO(b/227482970): Add test coverage for wifi_hotspot_bwu_handler.cc
|
||||
}
|
||||
|
||||
TEST(WifiHotspotTest, CanCreateEndpointChannel) {
|
||||
// TODO(b/227482970): Add test coverage for wifi_hotspot_endpoint_channel.cc
|
||||
}
|
||||
|
||||
TEST(WifiHotspotTest, CanGetMedium) {
|
||||
// TODO(b/227482970): Add test coverage for wifi_hotspot_endpoint_channel.cc
|
||||
}
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -29,18 +29,19 @@ struct MediumSelector {
|
||||
T ble;
|
||||
T web_rtc;
|
||||
T wifi_lan;
|
||||
T wifi_hotspot;
|
||||
|
||||
constexpr MediumSelector() = default;
|
||||
constexpr MediumSelector(const MediumSelector&) = default;
|
||||
constexpr MediumSelector& operator=(const MediumSelector&) = default;
|
||||
constexpr bool Any(T value) const {
|
||||
return bluetooth == value || ble == value || web_rtc == value ||
|
||||
wifi_lan == value;
|
||||
wifi_lan == value || wifi_hotspot == value;
|
||||
}
|
||||
|
||||
constexpr bool All(T value) const {
|
||||
return bluetooth == value && ble == value && web_rtc == value &&
|
||||
wifi_lan == value;
|
||||
wifi_lan == value && wifi_hotspot == value;
|
||||
}
|
||||
|
||||
constexpr int Count(T value) const {
|
||||
@@ -48,6 +49,7 @@ struct MediumSelector {
|
||||
if (bluetooth == value) count++;
|
||||
if (ble == value) count++;
|
||||
if (wifi_lan == value) count++;
|
||||
if (wifi_hotspot == value) count++;
|
||||
if (web_rtc == value) count++;
|
||||
return count;
|
||||
}
|
||||
@@ -57,12 +59,14 @@ struct MediumSelector {
|
||||
ble = value;
|
||||
web_rtc = value;
|
||||
wifi_lan = value;
|
||||
wifi_hotspot = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::vector<Medium> GetMediums(T value) const {
|
||||
std::vector<Medium> mediums;
|
||||
// Mediums are sorted in order of decreasing preference.
|
||||
if (wifi_hotspot == value) mediums.push_back(Medium::WIFI_HOTSPOT);
|
||||
if (wifi_lan == value) mediums.push_back(Medium::WIFI_LAN);
|
||||
if (web_rtc == value) mediums.push_back(Medium::WEB_RTC);
|
||||
if (bluetooth == value) mediums.push_back(Medium::BLUETOOTH);
|
||||
|
||||
@@ -20,6 +20,10 @@ namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
namespace {
|
||||
constexpr int kMaxRetries = 3;
|
||||
} // namespace
|
||||
|
||||
WifiHotspotServerSocket::WifiHotspotServerSocket(int port) : port_(port) {}
|
||||
|
||||
WifiHotspotServerSocket::~WifiHotspotServerSocket() { Close(); }
|
||||
@@ -176,7 +180,7 @@ std::vector<std::string> WifiHotspotServerSocket::GetIpAddresses() const {
|
||||
std::string ipv4_s = winrt::to_string(host_name.ToString());
|
||||
|
||||
if (HasEnding(ipv4_s, ".1")) {
|
||||
// std::string ipv4_b_s = ipaddr_dotdecimal_to_4bytes_string(ipv4_s);
|
||||
NEARBY_LOGS(INFO) << "Found Hotspot IP: " << ipv4_s;
|
||||
result.push_back(ipv4_s);
|
||||
}
|
||||
}
|
||||
@@ -185,17 +189,19 @@ std::vector<std::string> WifiHotspotServerSocket::GetIpAddresses() const {
|
||||
}
|
||||
|
||||
std::string WifiHotspotServerSocket::GetHotspotIpAddresses() const {
|
||||
auto host_names = NetworkInformation::GetHostNames();
|
||||
for (auto host_name : host_names) {
|
||||
if (host_name.IPInformation() != nullptr &&
|
||||
host_name.IPInformation().NetworkAdapter() != nullptr &&
|
||||
host_name.Type() == HostNameType::Ipv4) {
|
||||
std::string ipv4_s = winrt::to_string(host_name.ToString());
|
||||
if (HasEnding(ipv4_s, ".1")) {
|
||||
// TODO(b/228541380): replace when we find a better way to identifying
|
||||
// the hotspot address
|
||||
NEARBY_LOGS(INFO) << "Found Hotspot IP: " << ipv4_s;
|
||||
return ipv4_s;
|
||||
for (int i = 0; i < kMaxRetries; i++) {
|
||||
auto host_names = NetworkInformation::GetHostNames();
|
||||
for (auto host_name : host_names) {
|
||||
if (host_name.IPInformation() != nullptr &&
|
||||
host_name.IPInformation().NetworkAdapter() != nullptr &&
|
||||
host_name.Type() == HostNameType::Ipv4) {
|
||||
std::string ipv4_s = winrt::to_string(host_name.ToString());
|
||||
if (HasEnding(ipv4_s, ".1")) {
|
||||
// TODO(b/228541380): replace when we find a better way to identifying
|
||||
// the hotspot address
|
||||
NEARBY_LOGS(INFO) << "Found Hotspot IP: " << ipv4_s;
|
||||
return ipv4_s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user