WIFI Hotspot implementation (4)

Part 4: BWU and client interface part

PiperOrigin-RevId: 443700883
This commit is contained in:
hai007
2022-04-22 10:32:12 -07:00
committed by Copybara-Service
parent 60e896ad37
commit ec2d3ae1aa
20 changed files with 571 additions and 107 deletions
@@ -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;
+81 -77
View File
@@ -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_
+5
View File
@@ -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;
}
+34 -9
View File
@@ -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
+6 -2
View File
@@ -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;
}
}
}
}