mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Wi-Fi Direct Service Implementation(7)
PiperOrigin-RevId: 834584965
This commit is contained in:
@@ -105,7 +105,11 @@ BwuManager::BwuManager(
|
||||
}
|
||||
if (config_.allow_upgrade_to.All(false)) {
|
||||
config_.allow_upgrade_to.web_rtc = true;
|
||||
config_.allow_upgrade_to.wifi_direct = true;
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnableWifiDirect)) {
|
||||
config_.allow_upgrade_to.wifi_direct = true;
|
||||
}
|
||||
config_.allow_upgrade_to.wifi_lan = true;
|
||||
config_.allow_upgrade_to.wifi_hotspot = true;
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
|
||||
@@ -84,6 +84,9 @@ CreateWifiHotspotCredentials() {
|
||||
class BwuManagerTest : public ::testing::Test {
|
||||
protected:
|
||||
BwuManagerTest() {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::kEnableWifiDirect,
|
||||
true);
|
||||
// Set up fake BWU handlers for WebRTC and WifiLAN.
|
||||
absl::flat_hash_map<Medium, std::unique_ptr<BwuHandler>> handlers;
|
||||
auto fake_web_rtc = std::make_unique<FakeBwuHandler>(Medium::WEB_RTC);
|
||||
@@ -202,6 +205,9 @@ class BwuManagerTest : public ::testing::Test {
|
||||
};
|
||||
|
||||
TEST(BwuManagerBaseTest, AllowToUpgradeMedium) {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::kEnableWifiDirect,
|
||||
true);
|
||||
ClientProxy client;
|
||||
EndpointChannelManager ecm;
|
||||
EndpointManager em(&ecm);
|
||||
@@ -915,9 +921,10 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_WifiDirect) {
|
||||
CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH);
|
||||
|
||||
ByteArray bytes = parser::ForBwuWifiDirectPathAvailable(
|
||||
/*ssid=*/"Direct-12345678", /*password=*/"87654321", /*port=*/2143,
|
||||
/*ssid=*/"", /*password=*/"", /*port=*/2143,
|
||||
/*frequency=*/2412, /*supports_disabling_encryption=*/false,
|
||||
/*gateway=*/"123.234.23.1");
|
||||
/*gateway=*/"123.234.23.1", /*service_name=*/"NC-WifiDirectTest",
|
||||
/*pin=*/"b592f7d3");
|
||||
frame.ParseFromString(std::string(bytes));
|
||||
|
||||
::nearby::connections::V1Frame* v1_frame = frame.mutable_v1();
|
||||
|
||||
@@ -175,9 +175,10 @@ class FakeBwuHandler : public BaseBwuHandler {
|
||||
}
|
||||
case location::nearby::proto::connections::WIFI_DIRECT:
|
||||
return parser::ForBwuWifiDirectPathAvailable(
|
||||
/*ssid=*/"Direct-12345678", /*password=*/"87654321", /*port=*/2143,
|
||||
/*ssid=*/"", /*password=*/"", /*port=*/2143,
|
||||
/*frequency=*/2412, /*supports_disabling_encryption=*/false,
|
||||
/*gateway=*/"123.234.23.1");
|
||||
/*gateway=*/"123.234.23.1", /*service_name=*/"NC-WifiDirectTest",
|
||||
/*pin=*/"b592f7d3");
|
||||
case location::nearby::proto::connections::UNKNOWN_MEDIUM:
|
||||
case location::nearby::proto::connections::MDNS:
|
||||
case location::nearby::proto::connections::BLE:
|
||||
|
||||
@@ -103,6 +103,9 @@ constexpr auto kEnableScanningForInstantOnLost =
|
||||
// Stop BLE_V2 scanning when upgrading to WIFI Hotspot or WFD.
|
||||
constexpr auto kEnableStopBleScanningOnWifiUpgrade =
|
||||
flags::Flag<bool>(kConfigPackage, "45687902", false);
|
||||
// When true, enable Wi-Fi Direct in Nearby connections SDK.
|
||||
constexpr auto kEnableWifiDirect =
|
||||
flags::Flag<bool>(kConfigPackage, "45741157", false);
|
||||
// by default, enable Wi-Fi Hotspot client.
|
||||
constexpr auto kEnableWifiHotspotClient =
|
||||
flags::Flag<bool>(kConfigPackage, "45648734", true);
|
||||
@@ -120,7 +123,6 @@ constexpr auto kSafeToDisconnectVersion =
|
||||
// When true, use stable endpoint ID.
|
||||
constexpr auto kUseStableEndpointId =
|
||||
flags::Flag<bool>(kConfigPackage, "45639298", false);
|
||||
|
||||
} // namespace nearby_connections_feature
|
||||
} // namespace config_package_nearby
|
||||
} // namespace connections
|
||||
|
||||
@@ -16,6 +16,13 @@
|
||||
|
||||
#include "connections/implementation/mediums/awdl.h"
|
||||
#include "connections/implementation/mediums/ble.h"
|
||||
#include "connections/implementation/mediums/bluetooth_classic.h"
|
||||
#include "connections/implementation/mediums/bluetooth_radio.h"
|
||||
#include "connections/implementation/mediums/webrtc.h"
|
||||
#include "connections/implementation/mediums/wifi.h"
|
||||
#include "connections/implementation/mediums/wifi_direct.h"
|
||||
#include "connections/implementation/mediums/wifi_hotspot.h"
|
||||
#include "connections/implementation/mediums/wifi_lan.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Google LLC
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
namespace {
|
||||
using ::location::nearby::proto::connections::OperationResultCode;
|
||||
} // namespace
|
||||
@@ -102,14 +101,14 @@ bool WifiDirect::IsConnectedToGO() {
|
||||
return is_connected_to_go_;
|
||||
}
|
||||
|
||||
bool WifiDirect::ConnectWifiDirect(const std::string& ssid,
|
||||
const std::string& password) {
|
||||
bool WifiDirect::ConnectWifiDirect(
|
||||
const WifiDirectCredentials& wifi_direct_credentials) {
|
||||
MutexLock lock(&mutex_);
|
||||
if (is_connected_to_go_) {
|
||||
LOG(INFO) << "No need to connect to GO because it is already connected.";
|
||||
return true;
|
||||
}
|
||||
is_connected_to_go_ = medium_.ConnectWifiDirect(ssid, password);
|
||||
is_connected_to_go_ = medium_.ConnectWifiDirect(wifi_direct_credentials);
|
||||
return is_connected_to_go_;
|
||||
}
|
||||
|
||||
@@ -135,10 +134,7 @@ WifiDirectCredentials* WifiDirect::GetCredentials(
|
||||
<< ". Use default credentials";
|
||||
return crendential;
|
||||
}
|
||||
crendential->SetGateway(it->second.GetIPAddress());
|
||||
crendential->SetIPAddress(it->second.GetIPAddress());
|
||||
crendential->SetPort(it->second.GetPort());
|
||||
|
||||
it->second.PopulateWifiDirectCredentials(*crendential);
|
||||
return crendential;
|
||||
}
|
||||
|
||||
@@ -168,7 +164,7 @@ bool WifiDirect::StartAcceptingConnections(
|
||||
}
|
||||
|
||||
// "port=0" to let the platform to select an available port for the socket
|
||||
WifiDirectServerSocket server_socket = medium_.ListenForService(/*port=*/0);
|
||||
WifiDirectServerSocket server_socket = medium_.ListenForService();
|
||||
if (!server_socket.IsValid()) {
|
||||
LOG(INFO)
|
||||
<< "Failed to start to listen on WifiDirect GO server for service_id="
|
||||
@@ -258,8 +254,6 @@ ErrorOr<WifiDirectSocket> WifiDirect::Connect(
|
||||
const std::string& service_id, const std::string& ip_address, int port,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
MutexLock lock(&mutex_);
|
||||
// Socket to return. To allow for NRVO to work, it has to be a single object.
|
||||
WifiDirectSocket socket;
|
||||
|
||||
if (service_id.empty()) {
|
||||
LOG(INFO) << "Refusing to create client WifiDirect socket because "
|
||||
@@ -281,6 +275,8 @@ ErrorOr<WifiDirectSocket> WifiDirect::Connect(
|
||||
CLIENT_CANCELLATION_CANCEL_WIFI_DIRECT_OUTGOING_CONNECTION)};
|
||||
}
|
||||
|
||||
// Socket to return. To allow for NRVO to work, it has to be a single object.
|
||||
WifiDirectSocket socket;
|
||||
socket = medium_.ConnectToService(ip_address, port, cancellation_flag);
|
||||
if (!socket.IsValid()) {
|
||||
LOG(INFO) << "Failed to Connect via WifiDirect Server [service_id="
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Google LLC
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/expected.h"
|
||||
#include "internal/platform/multi_thread_executor.h"
|
||||
@@ -51,7 +52,7 @@ class WifiDirect {
|
||||
|
||||
// If WifiDirect Group Owner started
|
||||
bool IsGOStarted() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
// Start WifiDirect Group Owner. Returns true if AutoGO is successfully
|
||||
// Start WifiDirect Group Owner. Returns true if WifiDirect GO is successfully
|
||||
// started.
|
||||
bool StartWifiDirect() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
// Stop WifiDirect Group Owner
|
||||
@@ -60,7 +61,7 @@ class WifiDirect {
|
||||
// If WifiDirect Group Client connects to Group Owner
|
||||
bool IsConnectedToGO() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
// WifiDirect Group Client request to connect to the Group Owner
|
||||
bool ConnectWifiDirect(const std::string& ssid, const std::string& password)
|
||||
bool ConnectWifiDirect(const WifiDirectCredentials& wifi_direct_credentials)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
// WifiDirect Group Client request to disconnect from the Group Owner
|
||||
bool DisconnectWifiDirect() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
@@ -118,7 +119,6 @@ class WifiDirect {
|
||||
absl::flat_hash_map<std::string, WifiDirectServerSocket> server_sockets_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
// Copyright 2020 Google LLC
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/expected.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
#include "internal/platform/wifi_direct.h"
|
||||
@@ -42,8 +43,8 @@ constexpr FeatureFlags kTestCases[] = {
|
||||
};
|
||||
|
||||
constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"};
|
||||
constexpr absl::string_view kSsid{"Direct-357a2d8c"};
|
||||
constexpr absl::string_view kPassword{"12345678"};
|
||||
constexpr absl::string_view kServiceName{"NC-WifiDirectTest"};
|
||||
constexpr absl::string_view kPin{"12345678"};
|
||||
constexpr absl::string_view kIp = "123.234.23.1";
|
||||
constexpr const size_t kPort = 20;
|
||||
|
||||
@@ -85,11 +86,14 @@ TEST_F(WifiDirectTest, CanStartStopGO) {
|
||||
}
|
||||
|
||||
TEST_F(WifiDirectTest, GCCanConnectDisconnectGO) {
|
||||
std::string ssid(kSsid);
|
||||
std::string password(kPassword);
|
||||
WifiDirectCredentials wifi_direct_credentials;
|
||||
std::string service_name(kServiceName);
|
||||
std::string pin(kPin);
|
||||
wifi_direct_credentials.SetServiceName(service_name);
|
||||
wifi_direct_credentials.SetPin(pin);
|
||||
WifiDirect wifi_direct_a;
|
||||
|
||||
EXPECT_FALSE(wifi_direct_a.ConnectWifiDirect(ssid, password));
|
||||
EXPECT_FALSE(wifi_direct_a.ConnectWifiDirect(wifi_direct_credentials));
|
||||
EXPECT_TRUE(wifi_direct_a.DisconnectWifiDirect());
|
||||
}
|
||||
|
||||
@@ -110,9 +114,7 @@ TEST_P(WifiDirectTest, CanStartGOThatOtherConnect) {
|
||||
WifiDirectCredentials* wifi_direct_credentials =
|
||||
wifi_direct_a.GetCredentials(service_id);
|
||||
|
||||
EXPECT_TRUE(
|
||||
wifi_direct_b.ConnectWifiDirect(wifi_direct_credentials->GetSSID(),
|
||||
wifi_direct_credentials->GetPassword()));
|
||||
EXPECT_TRUE(wifi_direct_b.ConnectWifiDirect(*wifi_direct_credentials));
|
||||
EXPECT_TRUE(wifi_direct_b.IsConnectedToGO());
|
||||
|
||||
WifiDirectSocket socket_client;
|
||||
@@ -150,9 +152,7 @@ TEST_P(WifiDirectTest, CanStartGOThatOtherCanCancelConnect) {
|
||||
WifiDirectCredentials* wifi_direct_credentials =
|
||||
wifi_direct_a.GetCredentials(service_id);
|
||||
|
||||
EXPECT_TRUE(
|
||||
wifi_direct_b.ConnectWifiDirect(wifi_direct_credentials->GetSSID(),
|
||||
wifi_direct_credentials->GetPassword()));
|
||||
EXPECT_TRUE(wifi_direct_b.ConnectWifiDirect(*wifi_direct_credentials));
|
||||
|
||||
WifiDirectSocket socket_client;
|
||||
EXPECT_FALSE(socket_client.IsValid());
|
||||
@@ -180,10 +180,12 @@ TEST_F(WifiDirectTest, CanStartGOTheOtherFailConnect) {
|
||||
|
||||
EXPECT_TRUE(wifi_direct_a.StartWifiDirect());
|
||||
|
||||
std::string ssid(kSsid);
|
||||
std::string password(kPassword);
|
||||
|
||||
EXPECT_FALSE(wifi_direct_b.ConnectWifiDirect(ssid, password));
|
||||
WifiDirectCredentials wifi_direct_credentials;
|
||||
std::string service_name(kServiceName);
|
||||
std::string pin(kPin);
|
||||
wifi_direct_credentials.SetServiceName(service_name);
|
||||
wifi_direct_credentials.SetPin(pin);
|
||||
EXPECT_FALSE(wifi_direct_b.ConnectWifiDirect(wifi_direct_credentials));
|
||||
EXPECT_TRUE(wifi_direct_b.DisconnectWifiDirect());
|
||||
EXPECT_TRUE(wifi_direct_a.StopWifiDirect());
|
||||
}
|
||||
|
||||
@@ -369,7 +369,9 @@ ByteArray ForBwuWifiDirectPathAvailable(const std::string& ssid,
|
||||
std::int32_t port,
|
||||
std::int32_t frequency,
|
||||
bool supports_disabling_encryption,
|
||||
const std::string& gateway) {
|
||||
const std::string& gateway,
|
||||
const std::string& service_name,
|
||||
const std::string& pin) {
|
||||
OfflineFrame frame;
|
||||
|
||||
frame.set_version(OfflineFrame::V1);
|
||||
@@ -390,6 +392,8 @@ ByteArray ForBwuWifiDirectPathAvailable(const std::string& ssid,
|
||||
wifi_direct_credentials->set_port(port);
|
||||
wifi_direct_credentials->set_frequency(frequency);
|
||||
wifi_direct_credentials->set_gateway(gateway);
|
||||
wifi_direct_credentials->set_service_name(service_name);
|
||||
wifi_direct_credentials->set_pin(pin);
|
||||
|
||||
return ToBytes(std::move(frame));
|
||||
}
|
||||
|
||||
@@ -94,7 +94,9 @@ ByteArray ForBwuWifiDirectPathAvailable(const std::string& ssid,
|
||||
std::int32_t port,
|
||||
std::int32_t frequency,
|
||||
bool supports_disabling_encryption,
|
||||
const std::string& gateway);
|
||||
const std::string& gateway,
|
||||
const std::string& service_name,
|
||||
const std::string& pin);
|
||||
ByteArray ForBwuBluetoothPathAvailable(const std::string& service_id,
|
||||
MacAddress mac_address);
|
||||
ByteArray ForBwuWebrtcPathAvailable(
|
||||
|
||||
@@ -536,11 +536,13 @@ TEST(OfflineFramesTest, CanGenerateBwuWifiDirectPathAvailable) {
|
||||
upgrade_path_info: <
|
||||
medium: WIFI_DIRECT
|
||||
wifi_direct_credentials: <
|
||||
ssid: "DIRECT-A0-0123456789AB"
|
||||
password: "password"
|
||||
ssid: ""
|
||||
password: ""
|
||||
port: 1000
|
||||
frequency: 2412
|
||||
gateway: "192.168.1.1"
|
||||
service_name: "NC-WifiDirectTest"
|
||||
pin: "b592f7d3"
|
||||
>
|
||||
supports_disabling_encryption: false
|
||||
supports_client_introduction_ack: true
|
||||
@@ -548,7 +550,8 @@ TEST(OfflineFramesTest, CanGenerateBwuWifiDirectPathAvailable) {
|
||||
>
|
||||
>)pb";
|
||||
ByteArray bytes = ForBwuWifiDirectPathAvailable(
|
||||
"DIRECT-A0-0123456789AB", "password", 1000, 2412, false, "192.168.1.1");
|
||||
"", "", 1000, 2412, false, "192.168.1.1",
|
||||
"NC-WifiDirectTest", "b592f7d3");
|
||||
auto response = FromBytes(bytes);
|
||||
ASSERT_TRUE(response.ok());
|
||||
OfflineFrame message = response.result();
|
||||
|
||||
@@ -68,6 +68,8 @@ constexpr absl::string_view kWifiDirectSsidPatternString{
|
||||
constexpr int kWifiDirectSsidMaxLength = 32;
|
||||
constexpr int kWifiPasswordSsidMinLength = 8;
|
||||
constexpr int kWifiPasswordSsidMaxLength = 64;
|
||||
constexpr int kWifiDirectPinMinLength = 4;
|
||||
constexpr int kWifiDirectPinMaxLength = 16;
|
||||
|
||||
inline bool WithinRange(int value, int min, int max) {
|
||||
return value >= min && value < max;
|
||||
@@ -282,25 +284,36 @@ Exception EnsureValidBandwidthUpgradeWifiAwarePathAvailableFrame(
|
||||
|
||||
Exception EnsureValidBandwidthUpgradeWifiDirectPathAvailableFrame(
|
||||
const WifiDirectCredentials& wifi_direct_credentials) {
|
||||
const std::regex ssid_pattern(
|
||||
std::string(kWifiDirectSsidPatternString).c_str());
|
||||
if (!wifi_direct_credentials.has_ssid() ||
|
||||
!(wifi_direct_credentials.ssid().length() < kWifiDirectSsidMaxLength &&
|
||||
std::regex_match(wifi_direct_credentials.ssid(), ssid_pattern)))
|
||||
return {Exception::kInvalidProtocolBuffer};
|
||||
|
||||
if (!wifi_direct_credentials.has_password() ||
|
||||
!WithinRange(wifi_direct_credentials.password().length(),
|
||||
kWifiPasswordSsidMinLength, kWifiPasswordSsidMaxLength))
|
||||
return {Exception::kInvalidProtocolBuffer};
|
||||
|
||||
if (!wifi_direct_credentials.has_frequency() ||
|
||||
wifi_direct_credentials.frequency() < -1)
|
||||
return {Exception::kInvalidProtocolBuffer};
|
||||
|
||||
const std::regex ssid_pattern(
|
||||
std::string(kWifiDirectSsidPatternString).c_str());
|
||||
bool ssid_valid =
|
||||
wifi_direct_credentials.has_ssid() &&
|
||||
wifi_direct_credentials.ssid().length() < kWifiDirectSsidMaxLength &&
|
||||
std::regex_match(wifi_direct_credentials.ssid(), ssid_pattern);
|
||||
bool password_valid =
|
||||
wifi_direct_credentials.has_password() &&
|
||||
WithinRange(wifi_direct_credentials.password().length(),
|
||||
kWifiPasswordSsidMinLength, kWifiPasswordSsidMaxLength);
|
||||
bool service_name_valid =
|
||||
wifi_direct_credentials.has_service_name() &&
|
||||
wifi_direct_credentials.service_name().length() <
|
||||
kWifiDirectSsidMaxLength;
|
||||
bool pin_valid =
|
||||
wifi_direct_credentials.has_pin() &&
|
||||
WithinRange(wifi_direct_credentials.pin().length(),
|
||||
kWifiDirectPinMinLength, kWifiDirectPinMaxLength);
|
||||
|
||||
if ((ssid_valid && password_valid) || (service_name_valid && pin_valid))
|
||||
return {Exception::kSuccess};
|
||||
|
||||
return {Exception::kInvalidProtocolBuffer};
|
||||
|
||||
// For backwards compatibility reasons, no other fields should be null-checked
|
||||
// for this frame. Parameter checking (eg. must be within this range) is fine.
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
Exception EnsureValidBandwidthUpgradeBluetoothPathAvailableFrame(
|
||||
|
||||
@@ -51,6 +51,8 @@ constexpr absl::string_view kPassword = "password";
|
||||
constexpr absl::string_view kWifiHotspotGateway = "0.0.0.0";
|
||||
constexpr absl::string_view kWifiDirectSsid = "DIRECT-A0-0123456789AB";
|
||||
constexpr absl::string_view kWifiDirectPassword = "WIFIDIRECT123456";
|
||||
constexpr absl::string_view kWifiDirectServiceName = "NC-WifiDirectTest";
|
||||
constexpr absl::string_view kWifiDirectPin = "b592f7d3";
|
||||
constexpr absl::string_view kGateway = "192.168.1.1";
|
||||
constexpr int kWifiDirectFrequency = 2412;
|
||||
constexpr int kPort = 1000;
|
||||
@@ -726,8 +728,8 @@ TEST(OfflineFramesValidatorTest, ValidatesAsOkBandwidthUpgradeWifiDirect) {
|
||||
|
||||
ByteArray bytes = ForBwuWifiDirectPathAvailable(
|
||||
std::string(kWifiDirectSsid), std::string(kWifiDirectPassword), kPort,
|
||||
kWifiDirectFrequency, kSupportsDisablingEncryption,
|
||||
std::string(kGateway));
|
||||
kWifiDirectFrequency, kSupportsDisablingEncryption, std::string(kGateway),
|
||||
std::string(kWifiDirectServiceName), std::string(kWifiDirectPin));
|
||||
offline_frame.ParseFromString(std::string(bytes));
|
||||
|
||||
auto ret_value = EnsureValidOfflineFrame(offline_frame);
|
||||
@@ -743,7 +745,8 @@ TEST(OfflineFramesValidatorTest,
|
||||
// Anything less than -1 is invalid
|
||||
ByteArray bytes = ForBwuWifiDirectPathAvailable(
|
||||
std::string(kWifiDirectSsid), std::string(kWifiDirectPassword), kPort, -2,
|
||||
kSupportsDisablingEncryption, std::string(kGateway));
|
||||
kSupportsDisablingEncryption, std::string(kGateway),
|
||||
std::string(kWifiDirectServiceName), std::string(kWifiDirectPin));
|
||||
offline_frame_1.ParseFromString(std::string(bytes));
|
||||
|
||||
auto ret_value = EnsureValidOfflineFrame(offline_frame_1);
|
||||
@@ -753,7 +756,8 @@ TEST(OfflineFramesValidatorTest,
|
||||
// But -1 itself is not invalid
|
||||
bytes = ForBwuWifiDirectPathAvailable(
|
||||
std::string(kWifiDirectSsid), std::string(kWifiDirectPassword), kPort, -1,
|
||||
kSupportsDisablingEncryption, std::string(kGateway));
|
||||
kSupportsDisablingEncryption, std::string(kGateway),
|
||||
std::string(kWifiDirectServiceName), std::string(kWifiDirectPin));
|
||||
offline_frame_2.ParseFromString(std::string(bytes));
|
||||
|
||||
ret_value = EnsureValidOfflineFrame(offline_frame_2);
|
||||
@@ -767,10 +771,12 @@ TEST(OfflineFramesValidatorTest,
|
||||
OfflineFrame offline_frame_2;
|
||||
|
||||
std::string wifi_direct_ssid{"DIRECT-A*-0123456789AB"};
|
||||
std::string wifi_direct_pin_wrong_length = "abc";
|
||||
ByteArray bytes = ForBwuWifiDirectPathAvailable(
|
||||
wifi_direct_ssid, std::string(kWifiDirectPassword), kPort,
|
||||
kWifiDirectFrequency, kSupportsDisablingEncryption,
|
||||
std::string(kGateway));
|
||||
std::string(kGateway), std::string(kWifiDirectServiceName),
|
||||
wifi_direct_pin_wrong_length);
|
||||
offline_frame_1.ParseFromString(std::string(bytes));
|
||||
|
||||
auto ret_value = EnsureValidOfflineFrame(offline_frame_1);
|
||||
@@ -779,10 +785,14 @@ TEST(OfflineFramesValidatorTest,
|
||||
|
||||
std::string wifi_direct_ssid_wrong_length =
|
||||
std::string{kWifiDirectSsid} + "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
|
||||
std::string wifi_direct_service_name_wrong_length =
|
||||
std::string{kWifiDirectServiceName} +
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
|
||||
bytes = ForBwuWifiDirectPathAvailable(
|
||||
wifi_direct_ssid_wrong_length, std::string(kWifiDirectPassword), kPort,
|
||||
kWifiDirectFrequency, kSupportsDisablingEncryption,
|
||||
std::string(kGateway));
|
||||
std::string(kGateway), wifi_direct_service_name_wrong_length,
|
||||
std::string(kWifiDirectPin));
|
||||
offline_frame_2.ParseFromString(std::string(bytes));
|
||||
|
||||
ret_value = EnsureValidOfflineFrame(offline_frame_2);
|
||||
@@ -796,10 +806,12 @@ TEST(OfflineFramesValidatorTest,
|
||||
OfflineFrame offline_frame_2;
|
||||
|
||||
std::string short_wifi_direct_password{"Test"};
|
||||
std::string short_wifi_direct_pin{"abc"};
|
||||
ByteArray bytes = ForBwuWifiDirectPathAvailable(
|
||||
std::string(kWifiDirectSsid), short_wifi_direct_password, kPort,
|
||||
kWifiDirectFrequency, kSupportsDisablingEncryption,
|
||||
std::string(kGateway));
|
||||
std::string(kGateway), std::string(kWifiDirectServiceName),
|
||||
short_wifi_direct_pin);
|
||||
offline_frame_1.ParseFromString(std::string(bytes));
|
||||
|
||||
auto ret_value = EnsureValidOfflineFrame(offline_frame_1);
|
||||
@@ -809,10 +821,14 @@ TEST(OfflineFramesValidatorTest,
|
||||
std::string long_wifi_direct_password =
|
||||
std::string{kWifiDirectSsid} +
|
||||
"AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789";
|
||||
std::string long_wifi_direct_pin =
|
||||
std::string{kWifiDirectPin} +
|
||||
"AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789";
|
||||
bytes = ForBwuWifiDirectPathAvailable(
|
||||
std::string(kWifiDirectSsid), long_wifi_direct_password, kPort,
|
||||
kWifiDirectFrequency, kSupportsDisablingEncryption,
|
||||
std::string(kGateway));
|
||||
std::string(kGateway), std::string(kWifiDirectServiceName),
|
||||
long_wifi_direct_pin);
|
||||
offline_frame_2.ParseFromString(std::string(bytes));
|
||||
|
||||
ret_value = EnsureValidOfflineFrame(offline_frame_2);
|
||||
|
||||
@@ -49,9 +49,13 @@ P2pPointToPointPcpHandler::GetConnectionMediumsByPriority() {
|
||||
if (mediums_->GetWifiLan().IsAvailable()) {
|
||||
mediums.push_back(location::nearby::proto::connections::WIFI_LAN);
|
||||
}
|
||||
if (mediums_->GetWifi().IsAvailable() &&
|
||||
mediums_->GetWifiDirect().IsGCAvailable()) {
|
||||
mediums.push_back(location::nearby::proto::connections::WIFI_DIRECT);
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
config_package_nearby::nearby_connections_feature::
|
||||
kEnableWifiDirect)) {
|
||||
if (mediums_->GetWifi().IsAvailable() &&
|
||||
mediums_->GetWifiDirect().IsGCAvailable()) {
|
||||
mediums.push_back(location::nearby::proto::connections::WIFI_DIRECT);
|
||||
}
|
||||
}
|
||||
if (mediums_->GetWifi().IsAvailable() &&
|
||||
mediums_->GetWifiHotspot().IsClientAvailable()) {
|
||||
|
||||
@@ -83,6 +83,12 @@ constexpr BooleanMediumSelector kTestCases[] = {
|
||||
.wifi_lan = true,
|
||||
.wifi_hotspot = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
.wifi_lan = true,
|
||||
.wifi_direct = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
@@ -100,6 +106,9 @@ class P2pPointToPointPcpHandlerTest
|
||||
LOG(INFO) << "SetUp: begin";
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::kEnableAwdl, true);
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::kEnableWifiDirect,
|
||||
true);
|
||||
if (advertising_options_.allowed.ble) {
|
||||
LOG(INFO) << "SetUp: BLE enabled";
|
||||
}
|
||||
|
||||
@@ -44,10 +44,6 @@ P2pStarPcpHandler::GetConnectionMediumsByPriority() {
|
||||
if (mediums_->GetWifiLan().IsAvailable()) {
|
||||
mediums.push_back(location::nearby::proto::connections::WIFI_LAN);
|
||||
}
|
||||
if (mediums_->GetWifi().IsAvailable() &&
|
||||
mediums_->GetWifiDirect().IsGCAvailable()) {
|
||||
mediums.push_back(location::nearby::proto::connections::WIFI_DIRECT);
|
||||
}
|
||||
if (mediums_->GetWifi().IsAvailable() &&
|
||||
mediums_->GetWifiHotspot().IsClientAvailable()) {
|
||||
mediums.push_back(location::nearby::proto::connections::WIFI_HOTSPOT);
|
||||
|
||||
@@ -329,10 +329,16 @@ message BandwidthUpgradeNegotiationFrame {
|
||||
// Windows only supports WifiDirect with Service Discovey. Its
|
||||
// credentials is the service_name/pin.
|
||||
optional string service_name = 7;
|
||||
// The pin is exactly 8 digits. The first 7 digits are the PIN. The last 1
|
||||
// digit is a checksum calculated using a specific algorithm (CRC-8). The
|
||||
// WifiDirect spec requires that pin is exactly 8 digits. The first 7
|
||||
// digits are the PIN. The last 1 digit is a checksum calculated using a
|
||||
// specific algorithm (CRC-8). However, the Windows WinRT
|
||||
// WiFiDirectServiceAdvertiser::ConnectAsync() that we use does NOT
|
||||
// enforce the CRC-8 checksum for a WPS PIN because: 1. The ConnectAsync
|
||||
// PIN is NOT necessarily a WPS PIN. 2. WPS PIN validation is performed by
|
||||
// the Wi-Fi driver/firmware. 3. WFDS connections often bypass or replace
|
||||
// WPS PIN authentication
|
||||
// pin is exchanged in the connection handshake stage, but we create and
|
||||
// save it beforw starting GO, so we can send it to GC side for
|
||||
// save it before starting GO, so we can send it to GC side for
|
||||
// authentication.
|
||||
optional string pin = 8;
|
||||
}
|
||||
|
||||
@@ -1431,6 +1431,9 @@ TEST(ServiceControllerRouterCheckHpRealtekDeviceTest,
|
||||
|
||||
TEST(ServiceControllerRouterCheckHpRealtekDeviceTest,
|
||||
notHPRealtekDevice_defaultBwuConfig) {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
config_package_nearby::nearby_connections_feature::kEnableWifiDirect,
|
||||
true);
|
||||
ServiceControllerRouter router(
|
||||
absl::AnyInvocable<bool()>{[]() { return false; }});
|
||||
auto service_controller = router.GetServiceController();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Google LLC
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -41,12 +41,14 @@ namespace {
|
||||
using ::location::nearby::connections::BandwidthUpgradeNegotiationFrame;
|
||||
using ::location::nearby::proto::connections::OperationResultCode;
|
||||
} // namespace
|
||||
|
||||
WifiDirectBwuHandler::WifiDirectBwuHandler(
|
||||
Mediums& mediums, IncomingConnectionCallback incoming_connection_callback)
|
||||
: BaseBwuHandler(std::move(incoming_connection_callback)),
|
||||
mediums_(mediums) {}
|
||||
|
||||
// Called by BWU initiator. Set up WifiDirect upgraded medium for this
|
||||
// endpoint, and returns an upgrade path info (ServiceName, Pin for Wifi WPS,
|
||||
// Gateway used as IPAddress, Port) for remote party to perform connection.
|
||||
ByteArray WifiDirectBwuHandler::HandleInitializeUpgradedMediumForEndpoint(
|
||||
ClientProxy* client, const std::string& upgrade_service_id,
|
||||
const std::string& endpoint_id) {
|
||||
@@ -82,19 +84,29 @@ ByteArray WifiDirectBwuHandler::HandleInitializeUpgradedMediumForEndpoint(
|
||||
wifi_direct_medium_.GetCredentials(upgrade_service_id);
|
||||
std::string ssid = wifi_direct_crendential->GetSSID();
|
||||
std::string password = wifi_direct_crendential->GetPassword();
|
||||
std::string service_name = wifi_direct_crendential->GetServiceName();
|
||||
std::string pin = wifi_direct_crendential->GetPin();
|
||||
std::string gateway = wifi_direct_crendential->GetGateway();
|
||||
int port = wifi_direct_crendential->GetPort();
|
||||
int freq = wifi_direct_crendential->GetFrequency();
|
||||
|
||||
LOG(INFO) << "Start WifiDirect GO with SSID: " << ssid
|
||||
<< ", Password: " << masker::Mask(password) << ", Port: " << port
|
||||
<< ", Gateway: " << gateway << ", Frequency: " << freq;
|
||||
if (ssid.empty()) {
|
||||
LOG(INFO) << "Start WifiDirect GO with ServiceName: " << service_name
|
||||
<< ", pin: " << masker::Mask(pin) << ", Port: " << port
|
||||
<< ", Gateway: " << gateway << ", Frequency: " << freq;
|
||||
} else {
|
||||
LOG(INFO) << "Start WifiDirect GO with SSID: " << ssid
|
||||
<< ", Password: " << masker::Mask(password)
|
||||
<< ", Port: " << port << ", Gateway: " << gateway
|
||||
<< ", Frequency: " << freq;
|
||||
}
|
||||
|
||||
bool disabling_encryption =
|
||||
(client->GetAdvertisingOptions().strategy == Strategy::kP2pPointToPoint);
|
||||
return parser::ForBwuWifiDirectPathAvailable(
|
||||
ssid, password, port, freq,
|
||||
/* supports_disabling_encryption */ disabling_encryption, gateway);
|
||||
/* supports_disabling_encryption */ disabling_encryption, gateway,
|
||||
service_name, pin);
|
||||
}
|
||||
|
||||
void WifiDirectBwuHandler::HandleRevertInitiatorStateForService(
|
||||
@@ -124,14 +136,34 @@ WifiDirectBwuHandler::CreateUpgradedEndpointChannel(
|
||||
|
||||
const std::string& ssid = upgrade_path_info_credentials.ssid();
|
||||
const std::string& password = upgrade_path_info_credentials.password();
|
||||
const std::string& service_name =
|
||||
upgrade_path_info_credentials.service_name();
|
||||
const std::string& pin = upgrade_path_info_credentials.pin();
|
||||
std::int32_t port = upgrade_path_info_credentials.port();
|
||||
const std::string& gateway = upgrade_path_info_credentials.gateway();
|
||||
std::int32_t freq = upgrade_path_info_credentials.frequency();
|
||||
|
||||
LOG(INFO) << "Received WifiDirect credential SSID: " << ssid
|
||||
<< ", Password:" << masker::Mask(password) << ", Port:" << port
|
||||
<< ", Gateway:" << gateway;
|
||||
WifiDirectCredentials wifi_direct_credentials;
|
||||
wifi_direct_credentials.SetSSID(ssid);
|
||||
wifi_direct_credentials.SetPassword(password);
|
||||
wifi_direct_credentials.SetServiceName(service_name);
|
||||
wifi_direct_credentials.SetPin(pin);
|
||||
wifi_direct_credentials.SetPort(port);
|
||||
wifi_direct_credentials.SetGateway(gateway);
|
||||
wifi_direct_credentials.SetFrequency(freq);
|
||||
|
||||
if (!wifi_direct_medium_.ConnectWifiDirect(ssid, password)) {
|
||||
if (ssid.empty()) {
|
||||
LOG(INFO) << "Received WifiDirect credential ServiceName: " << service_name
|
||||
<< ", pin: " << masker::Mask(pin) << ", Port: " << port
|
||||
<< ", Gateway: " << gateway << ", Frequency: " << freq;
|
||||
} else {
|
||||
LOG(INFO) << "Received WifiDirect credential SSID: " << ssid
|
||||
<< ", Password: " << masker::Mask(password)
|
||||
<< ", Port: " << port << ", Gateway: " << gateway
|
||||
<< ", Frequency: " << freq;
|
||||
}
|
||||
|
||||
if (!wifi_direct_medium_.ConnectWifiDirect(wifi_direct_credentials)) {
|
||||
LOG(ERROR) << "Connect to WifiDiret GO failed";
|
||||
return {Error(
|
||||
OperationResultCode::CONNECTIVITY_WIFI_DIRECT_INVALID_CREDENTIAL)};
|
||||
@@ -148,7 +180,7 @@ WifiDirectBwuHandler::CreateUpgradedEndpointChannel(
|
||||
|
||||
VLOG(1)
|
||||
<< "WifiDirectBwuHandler successfully connected to WifiDirect service ("
|
||||
<< port << ") while upgrading endpoint " << endpoint_id;
|
||||
<< gateway << ":" << port << ") while upgrading endpoint " << endpoint_id;
|
||||
|
||||
// Create a new WifiDirectEndpointChannel.
|
||||
return {std::make_unique<WifiDirectEndpointChannel>(
|
||||
@@ -168,6 +200,5 @@ void WifiDirectBwuHandler::OnIncomingWifiDirectConnection(
|
||||
});
|
||||
NotifyOnIncomingConnection(client, std::move(connection));
|
||||
}
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Google LLC
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -23,12 +23,10 @@
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/endpoint_channel.h"
|
||||
#include "connections/implementation/mediums/mediums.h"
|
||||
#include "connections/implementation/mediums/wifi.h"
|
||||
#include "connections/implementation/mediums/wifi_direct.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/expected.h"
|
||||
#include "internal/platform/wifi_direct.h"
|
||||
#include "utility"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
@@ -89,7 +87,6 @@ class WifiDirectBwuHandler : public BaseBwuHandler {
|
||||
WifiDirectSocket socket);
|
||||
|
||||
Mediums& mediums_;
|
||||
Wifi& wifi_medium_ = mediums_.GetWifi();
|
||||
WifiDirect& wifi_direct_medium_ = mediums_.GetWifiDirect();
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Google LLC
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/expected.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/platform/single_thread_executor.h"
|
||||
@@ -85,18 +84,12 @@ TEST_F(WifiDirectTest, WFDGOBWUInit_GCCreateEndpointChannel) {
|
||||
mutable_connection) {
|
||||
LOG(INFO) << "Server socket connection accept call back, Socket name: "
|
||||
<< mutable_connection->socket->ToString();
|
||||
std::shared_ptr<BwuHandler::IncomingSocketConnection> connection(
|
||||
mutable_connection.release());
|
||||
accept_latch.CountDown();
|
||||
EXPECT_TRUE(end_latch.Await(kWaitDuration).result());
|
||||
|
||||
connection->channel->Close();
|
||||
connection->socket->Close();
|
||||
});
|
||||
|
||||
SingleThreadExecutor wfd_go_executor;
|
||||
wfd_go_executor.Execute([&wfd_go_bwu_handler, &wifi_direct_go, &upgrade_frame,
|
||||
&start_latch]() {
|
||||
wfd_go_executor.Execute([&]() {
|
||||
ByteArray upgrade_path_available_frame =
|
||||
wfd_go_bwu_handler->InitializeUpgradedMediumForEndpoint(
|
||||
&wifi_direct_go, std::string(kServiceID), std::string(kEndpointID));
|
||||
|
||||
@@ -118,6 +118,7 @@ class FeatureFlags {
|
||||
std::uint32_t connection_max_frame_length = 1048576;
|
||||
std::uint32_t blocking_queue_stream_queue_capacity = 10;
|
||||
bool support_web_rtc_non_cellular_medium = false;
|
||||
std::uint32_t wifi_direct_default_port = 63034;
|
||||
};
|
||||
|
||||
static const FeatureFlags& GetInstance() {
|
||||
|
||||
@@ -19,12 +19,14 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/log/check.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/logging.h"
|
||||
@@ -110,6 +112,14 @@ Exception WifiDirectServerSocket::DoClose() {
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
void WifiDirectServerSocket::PopulateWifiDirectCredentials(
|
||||
WifiDirectCredentials& wifi_direct_credentials) {
|
||||
absl::MutexLock lock(mutex_);
|
||||
wifi_direct_credentials.SetGateway(ip_address_);
|
||||
wifi_direct_credentials.SetPort(port_);
|
||||
}
|
||||
|
||||
|
||||
// Code for WifiDirectMedium
|
||||
WifiDirectMedium::WifiDirectMedium() {
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
@@ -125,13 +135,13 @@ bool WifiDirectMedium::StartWifiDirect(
|
||||
WifiDirectCredentials* wifi_direct_credentials) {
|
||||
absl::MutexLock lock(mutex_);
|
||||
|
||||
std::string ssid = absl::StrCat("DIRECT-", Prng().NextUint32());
|
||||
wifi_direct_credentials->SetSSID(ssid);
|
||||
std::string password = absl::StrFormat("%08x", Prng().NextUint32());
|
||||
wifi_direct_credentials->SetPassword(password);
|
||||
std::string service_name = absl::StrCat("NC-", Prng().NextUint32());
|
||||
wifi_direct_credentials->SetServiceName(service_name);
|
||||
std::string pin = absl::StrFormat("%04x", Prng().NextUint32());
|
||||
wifi_direct_credentials->SetPin(pin);
|
||||
|
||||
LOG(INFO) << "G3 StartWifiDirect GO: ssid=" << ssid
|
||||
<< ", password:" << password;
|
||||
LOG(INFO) << "G3 StartWifiDirect GO: service_name:" << service_name
|
||||
<< ", pin:" << pin;
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, wifi_direct_credentials,
|
||||
@@ -152,24 +162,24 @@ bool WifiDirectMedium::StopWifiDirect() {
|
||||
}
|
||||
|
||||
bool WifiDirectMedium::ConnectWifiDirect(
|
||||
WifiDirectCredentials* wifi_direct_credentials) {
|
||||
const WifiDirectCredentials& wifi_direct_credentials) {
|
||||
absl::MutexLock lock(mutex_);
|
||||
|
||||
LOG(INFO) << "G3 ConnectWifiDirect : ssid="
|
||||
<< wifi_direct_credentials->GetSSID()
|
||||
<< ", password:" << wifi_direct_credentials->GetPassword();
|
||||
LOG(INFO) << "G3 ConnectWifiDirect : service_name:"
|
||||
<< wifi_direct_credentials.GetServiceName()
|
||||
<< ", pin:" << wifi_direct_credentials.GetPin();
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
auto* remote_medium = static_cast<WifiDirectMedium*>(
|
||||
env.GetWifiDirectMedium(wifi_direct_credentials->GetSSID(), {}));
|
||||
env.GetWifiDirectMedium(wifi_direct_credentials.GetServiceName(), ""));
|
||||
if (!remote_medium) {
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, wifi_direct_credentials,
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, &wifi_direct_credentials,
|
||||
/*is_go=*/false,
|
||||
/*enabled=*/false);
|
||||
return false;
|
||||
}
|
||||
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, wifi_direct_credentials,
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, &wifi_direct_credentials,
|
||||
/*is_go=*/false,
|
||||
/*enabled=*/true);
|
||||
return true;
|
||||
@@ -198,7 +208,7 @@ std::unique_ptr<api::WifiDirectSocket> WifiDirectMedium::ConnectToService(
|
||||
auto* remote_medium =
|
||||
static_cast<WifiDirectMedium*>(env.GetWifiDirectMedium({}, ip_address));
|
||||
if (remote_medium == nullptr) {
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
WifiDirectServerSocket* server_socket = nullptr;
|
||||
@@ -214,21 +224,32 @@ std::unique_ptr<api::WifiDirectSocket> WifiDirectMedium::ConnectToService(
|
||||
LOG(ERROR) << "G3 WifiDirect Failed to find WifiDirect Server "
|
||||
"socket: socket_name="
|
||||
<< socket_name;
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
if (cancellation_flag->Cancelled()) {
|
||||
LOG(ERROR) << "G3 WifiDirect Connect: Has been cancelled: socket_name="
|
||||
<< socket_name;
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
CancellationFlagListener listener(cancellation_flag, [&server_socket]() {
|
||||
LOG(INFO) << "G3 WifiDirect Cancel Connect.";
|
||||
if (server_socket != nullptr) {
|
||||
server_socket->Close();
|
||||
}
|
||||
});
|
||||
|
||||
auto socket = std::make_unique<WifiDirectSocket>();
|
||||
// Finally, Request to connect to this socket.
|
||||
|
||||
server_socket->Connect(*socket);
|
||||
LOG(INFO) << "G3 WifiDirect GC ConnectToService: connected: socket="
|
||||
if (!server_socket->Connect(*socket)) {
|
||||
LOG(ERROR) << "G3 WifiDirect Failed to connect to existing WifiDirect "
|
||||
"Server socket: name="
|
||||
<< socket_name;
|
||||
return {};
|
||||
}
|
||||
LOG(INFO) << "G3 WifiDirect ConnectToService: connected: socket="
|
||||
<< socket.get();
|
||||
return socket;
|
||||
}
|
||||
@@ -247,9 +268,10 @@ std::unique_ptr<api::WifiDirectServerSocket> WifiDirectMedium::ListenForService(
|
||||
dot_decimal_ip.pop_back();
|
||||
|
||||
server_socket->SetIPAddress(dot_decimal_ip);
|
||||
server_socket->SetPort(port == 0 ? env.GetFakePort() : port);
|
||||
std::string socket_name = WifiDirectServerSocket::GetName(
|
||||
server_socket->GetIPAddress(), server_socket->GetPort());
|
||||
int port_to_use = port == 0 ? env.GetFakePort() : port;
|
||||
server_socket->SetPort(port_to_use);
|
||||
std::string socket_name =
|
||||
WifiDirectServerSocket::GetName(dot_decimal_ip, port_to_use);
|
||||
server_socket->SetCloseNotifier([this, socket_name]() {
|
||||
absl::MutexLock lock(mutex_);
|
||||
server_sockets_.erase(socket_name);
|
||||
|
||||
@@ -15,17 +15,26 @@
|
||||
#ifndef PLATFORM_IMPL_G3_WIFI_DIRECT_H_
|
||||
#define PLATFORM_IMPL_G3_WIFI_DIRECT_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/g3/multi_thread_executor.h"
|
||||
#include "internal/platform/implementation/g3/socket_base.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
@@ -112,6 +121,12 @@ class WifiDirectServerSocket : public api::WifiDirectServerSocket {
|
||||
// Calls close_notifier if it was previously set, and marks socket as closed.
|
||||
Exception Close() override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Populates the provided `wifi_direct_credentials` with the IP address
|
||||
// and port of this server socket.
|
||||
void PopulateWifiDirectCredentials(
|
||||
WifiDirectCredentials& wifi_direct_credentials) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
// Retrieves IP addresses from local machine
|
||||
std::vector<std::string> GetIpAddresses() const;
|
||||
@@ -158,7 +173,7 @@ class WifiDirectMedium : public api::WifiDirectMedium {
|
||||
bool StopWifiDirect() override;
|
||||
// Discoverer connects to the WiFiDirect GO
|
||||
bool ConnectWifiDirect(
|
||||
WifiDirectCredentials* wifi_direct_credentials) override;
|
||||
const WifiDirectCredentials& wifi_direct_credentials) override;
|
||||
// Discoverer disconnects from the WiFiDirect GO
|
||||
bool DisconnectWifiDirect() override;
|
||||
|
||||
|
||||
@@ -15,11 +15,15 @@
|
||||
#ifndef PLATFORM_API_WIFI_DIRECT_H_
|
||||
#define PLATFORM_API_WIFI_DIRECT_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
@@ -67,6 +71,11 @@ class WifiDirectServerSocket {
|
||||
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
virtual Exception Close() = 0;
|
||||
|
||||
// Populates the WifiDirect credentials with the server socket's service
|
||||
// addresses and ports.
|
||||
virtual void PopulateWifiDirectCredentials(
|
||||
WifiDirectCredentials& wifi_direct_credentials) = 0;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the WifiLan medium.
|
||||
@@ -104,7 +113,7 @@ class WifiDirectMedium {
|
||||
|
||||
// Client device connect to a softAP with specified credential.
|
||||
virtual bool ConnectWifiDirect(
|
||||
WifiDirectCredentials* wifi_direct_credentials) = 0;
|
||||
const WifiDirectCredentials& wifi_direct_credentials) = 0;
|
||||
virtual bool DisconnectWifiDirect() = 0;
|
||||
|
||||
// Returns the port range as a pair of min and max port.
|
||||
|
||||
@@ -74,8 +74,8 @@
|
||||
#include "internal/platform/implementation/windows/string_utils.h"
|
||||
#include "internal/platform/implementation/windows/submittable_executor.h"
|
||||
#include "internal/platform/implementation/windows/timer.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/implementation/windows/wifi.h"
|
||||
#include "internal/platform/implementation/windows/wifi_direct.h"
|
||||
#include "internal/platform/implementation/windows/wifi_hotspot.h"
|
||||
#include "internal/platform/implementation/windows/wifi_lan.h"
|
||||
#include "internal/platform/logging.h"
|
||||
@@ -284,7 +284,7 @@ ImplementationPlatform::CreateWifiHotspotMedium() {
|
||||
|
||||
std::unique_ptr<WifiDirectMedium>
|
||||
ImplementationPlatform::CreateWifiDirectMedium() {
|
||||
return nullptr;
|
||||
return std::make_unique<windows::WifiDirectMedium>();
|
||||
}
|
||||
|
||||
// TODO(b/261663238) replace with real implementation.
|
||||
|
||||
@@ -29,18 +29,20 @@
|
||||
// Nearby connections headers
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/implementation/windows/nearby_client_socket.h"
|
||||
#include "internal/platform/implementation/windows/nearby_server_socket.h"
|
||||
#include "internal/platform/implementation/windows/socket_address.h"
|
||||
#include "internal/platform/implementation/windows/submittable_executor.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
// WinRT headers
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Enumeration.h"
|
||||
@@ -78,10 +80,10 @@ using ::winrt::Windows::Foundation::AsyncStatus;
|
||||
using ::winrt::Windows::Foundation::IInspectable;
|
||||
|
||||
// WifiDirectSocket wraps the socket functions to read and write stream.
|
||||
// In WiFi HOTSPOT, A WifiDirectSocket will be passed to
|
||||
// On WiFiDirect GO serverside, a WifiDirectSocket will be passed to
|
||||
// StartAcceptingConnections's callback when Winsock Server Socket receives a
|
||||
// new connection. When call API to connect to remote WiFi Hotspot service, also
|
||||
// will return a WifiDirectSocket to caller.
|
||||
// new connection. When client side call API to connect to remote WiFi
|
||||
// WifiDirect GO service, it will return a WifiDirectServiceSocket to caller.
|
||||
class WifiDirectSocket : public api::WifiDirectSocket {
|
||||
public:
|
||||
WifiDirectSocket();
|
||||
@@ -113,42 +115,6 @@ class WifiDirectSocket : public api::WifiDirectSocket {
|
||||
}
|
||||
|
||||
private:
|
||||
// A simple wrapper to handle input stream of socket
|
||||
class SocketInputStream : public InputStream {
|
||||
public:
|
||||
explicit SocketInputStream(NearbyClientSocket* absl_nonnull client_socket)
|
||||
: client_socket_(client_socket) {}
|
||||
~SocketInputStream() override = default;
|
||||
|
||||
ExceptionOr<ByteArray> Read(std::int64_t size) override {
|
||||
return client_socket_->Read(size);
|
||||
}
|
||||
ExceptionOr<size_t> Skip(size_t offset) override {
|
||||
return client_socket_->Skip(offset);
|
||||
}
|
||||
Exception Close() override { return client_socket_->Close(); }
|
||||
|
||||
private:
|
||||
NearbyClientSocket* absl_nonnull const client_socket_;
|
||||
};
|
||||
|
||||
// A simple wrapper to handle output stream of socket
|
||||
class SocketOutputStream : public OutputStream {
|
||||
public:
|
||||
explicit SocketOutputStream(NearbyClientSocket* absl_nonnull client_socket)
|
||||
: client_socket_(client_socket) {}
|
||||
~SocketOutputStream() override = default;
|
||||
|
||||
Exception Write(const ByteArray& data) override {
|
||||
return client_socket_->Write(data);
|
||||
}
|
||||
Exception Flush() override { return client_socket_->Flush(); }
|
||||
Exception Close() override { return client_socket_->Close(); }
|
||||
|
||||
private:
|
||||
NearbyClientSocket* absl_nonnull const client_socket_;
|
||||
};
|
||||
|
||||
absl_nonnull std::unique_ptr<NearbyClientSocket> client_socket_;
|
||||
SocketInputStream input_stream_;
|
||||
SocketOutputStream output_stream_;
|
||||
@@ -158,15 +124,14 @@ class WifiDirectSocket : public api::WifiDirectSocket {
|
||||
// server socket accepts connection from clients.
|
||||
class WifiDirectServerSocket : public api::WifiDirectServerSocket {
|
||||
public:
|
||||
explicit WifiDirectServerSocket(int port = 0);
|
||||
WifiDirectServerSocket(const WifiDirectServerSocket&) = default;
|
||||
WifiDirectServerSocket(WifiDirectServerSocket&&) = default;
|
||||
WifiDirectServerSocket() = default;
|
||||
~WifiDirectServerSocket() override;
|
||||
WifiDirectServerSocket& operator=(const WifiDirectServerSocket&) = default;
|
||||
WifiDirectServerSocket(WifiDirectServerSocket&&) = default;
|
||||
WifiDirectServerSocket& operator=(WifiDirectServerSocket&&) = default;
|
||||
|
||||
std::string GetIPAddress() const override;
|
||||
int GetPort() const override;
|
||||
|
||||
int GetPort() const override { return server_socket_.GetPort(); }
|
||||
|
||||
// Blocks until either:
|
||||
// - at least one incoming connection request is available, or
|
||||
@@ -179,83 +144,69 @@ class WifiDirectServerSocket : public api::WifiDirectServerSocket {
|
||||
// Called by the server side of a connection before passing ownership of
|
||||
// WifiDirectServerSocker to user, to track validity of a pointer to
|
||||
// this server socket.
|
||||
void SetCloseNotifier(absl::AnyInvocable<void()> notifier);
|
||||
void SetCloseNotifier(absl::AnyInvocable<void()> notifier) {
|
||||
server_socket_.SetCloseNotifier(std::move(notifier));
|
||||
}
|
||||
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
Exception Close() override;
|
||||
|
||||
// Binds to local port
|
||||
bool Listen(bool dual_stack, std::string& ip_address);
|
||||
// Populates the provided `wifi_direct_credentials` with the IP address
|
||||
// and port of this server socket.
|
||||
void PopulateWifiDirectCredentials(
|
||||
WifiDirectCredentials& wifi_direct_credentials) override;
|
||||
|
||||
NearbyServerSocket server_socket_;
|
||||
void SetIPAddress(std::string ip_address);
|
||||
|
||||
// Binds to local port
|
||||
bool Listen(int port, bool dual_stack);
|
||||
|
||||
private:
|
||||
// Retrieves hotspot IP address from local machine
|
||||
// Retrieves WifiDirect GO IP address from local machine
|
||||
std::string GetWifiDirectIpAddress() const;
|
||||
|
||||
const int port_;
|
||||
mutable absl::Mutex mutex_;
|
||||
|
||||
// Close notifier
|
||||
absl::AnyInvocable<void()> close_notifier_ = nullptr;
|
||||
absl::CondVar is_listen_ready_;
|
||||
bool is_listen_started_ ABSL_GUARDED_BY(mutex_) = false;
|
||||
|
||||
// IP addresses of the server socket.
|
||||
std::string wifi_direct_ipaddr_ = {};
|
||||
bool closed_ = false;
|
||||
NearbyServerSocket server_socket_;
|
||||
};
|
||||
|
||||
class WifiDirectDiscovered {
|
||||
public:
|
||||
explicit WifiDirectDiscovered(const DeviceInformation& device_info);
|
||||
|
||||
~WifiDirectDiscovered() = default;
|
||||
WifiDirectDiscovered(WifiDirectDiscovered&&) = default;
|
||||
WifiDirectDiscovered& operator=(WifiDirectDiscovered&&) = default;
|
||||
|
||||
std::string GetId() { return id_; }
|
||||
DeviceInformation GetDeviceInformation() {
|
||||
return windows_wifi_direct_device_;
|
||||
}
|
||||
|
||||
private:
|
||||
DeviceInformation windows_wifi_direct_device_;
|
||||
|
||||
// Once the device is lost, we can no longer access it's id.
|
||||
std::string id_;
|
||||
|
||||
// Once the device is lost, we can no longer access it's mac address.
|
||||
// std::string name_;
|
||||
};
|
||||
|
||||
class WifiDirectMedium {
|
||||
class WifiDirectMedium : public api::WifiDirectMedium {
|
||||
public:
|
||||
WifiDirectMedium();
|
||||
~WifiDirectMedium();
|
||||
~WifiDirectMedium() override;
|
||||
// WifiDirectMedium is neither copyable nor movable.
|
||||
WifiDirectMedium(const WifiDirectMedium&) = delete;
|
||||
WifiDirectMedium& operator=(const WifiDirectMedium&) = delete;
|
||||
|
||||
// If the WiFi Adaptor supports to start WifiDirect Service GO.
|
||||
bool IsInterfaceValid() const;
|
||||
bool IsInterfaceValid() const override;
|
||||
|
||||
// Discoverer connects to server socket
|
||||
std::unique_ptr<api::WifiDirectSocket> ConnectToService(
|
||||
absl::string_view ip_address, int port,
|
||||
CancellationFlag* cancellation_flag);
|
||||
CancellationFlag* cancellation_flag) override;
|
||||
|
||||
// Advertiser starts to listen on server socket
|
||||
std::unique_ptr<api::WifiDirectServerSocket> ListenForService(int port);
|
||||
std::unique_ptr<api::WifiDirectServerSocket> ListenForService(
|
||||
int port) override;
|
||||
|
||||
// Starts to advertising
|
||||
bool StartWifiDirect();
|
||||
// Stops to advertising
|
||||
bool StopWifiDirect();
|
||||
// Connects to a WifiDirect
|
||||
bool ConnectWifiDirect();
|
||||
// Disconnects from a WifiDirect
|
||||
bool DisconnectWifiDirect();
|
||||
// Advertiser start WiFiDirect GO with specific Credentials.
|
||||
bool StartWifiDirect(WifiDirectCredentials* wifi_direct_credentials) override;
|
||||
// Advertiser stop the current WiFiDirect GO.
|
||||
bool StopWifiDirect() override;
|
||||
// Discoverer connects to the WifiDirect GO as GC.
|
||||
bool ConnectWifiDirect(
|
||||
const WifiDirectCredentials& wifi_direct_credentials) override;
|
||||
// Discoverer disconnects from the connected WifiDirect GO.
|
||||
bool DisconnectWifiDirect() override;
|
||||
|
||||
absl::optional<std::pair<std::int32_t, std::int32_t>> GetDynamicPortRange() {
|
||||
absl::optional<std::pair<std::int32_t, std::int32_t>> GetDynamicPortRange()
|
||||
override {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
@@ -263,7 +214,7 @@ class WifiDirectMedium {
|
||||
enum Value : char {
|
||||
kMediumStatusIdle = 0,
|
||||
kMediumStatusAccepting = (1 << 0),
|
||||
kMediumStatusServiceStarted = (1 << 1),
|
||||
kMediumStatusGOStarted = (1 << 1),
|
||||
kMediumStatusConnecting = (1 << 2),
|
||||
kMediumStatusConnected = (1 << 3),
|
||||
};
|
||||
@@ -273,9 +224,9 @@ class WifiDirectMedium {
|
||||
bool IsIdle() { return medium_status_ == kMediumStatusIdle; }
|
||||
// Advertiser is accepting connection on server socket
|
||||
bool IsAccepting() { return (medium_status_ & kMediumStatusAccepting) != 0; }
|
||||
// Advertiser started WifiDirect
|
||||
bool IsServiceStarted() {
|
||||
return (medium_status_ & kMediumStatusServiceStarted) != 0;
|
||||
// Advertiser started WifiDirect GO
|
||||
bool IsGOStarted() {
|
||||
return (medium_status_ & kMediumStatusGOStarted) != 0;
|
||||
}
|
||||
// Discoverer is connecting with the WifiDirect
|
||||
bool IsConnecting() {
|
||||
@@ -326,6 +277,9 @@ class WifiDirectMedium {
|
||||
IInspectable inspectable);
|
||||
fire_and_forget Watcher_DeviceStopped(DeviceWatcher sender,
|
||||
IInspectable inspectable);
|
||||
|
||||
WifiDirectCredentials* credentials_go_ = nullptr;
|
||||
WifiDirectCredentials credentials_gc_;
|
||||
std::string ip_address_local_;
|
||||
std::string ip_address_remote_;
|
||||
|
||||
@@ -334,12 +288,6 @@ class WifiDirectMedium {
|
||||
// Keep the server socket listener pointer
|
||||
WifiDirectServerSocket* server_socket_ptr_ ABSL_GUARDED_BY(mutex_) = nullptr;
|
||||
SubmittableExecutor listener_executor_;
|
||||
|
||||
absl::flat_hash_map<winrt::hstring, std::unique_ptr<WifiDirectDiscovered>>
|
||||
discovered_devices_by_id_;
|
||||
|
||||
absl::flat_hash_map<winrt::hstring, std::unique_ptr<WifiDirectDiscovered>>
|
||||
connection_requested_devices_by_id_;
|
||||
};
|
||||
|
||||
} // namespace nearby::windows
|
||||
|
||||
@@ -19,24 +19,25 @@
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#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"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
constexpr std::wstring_view kServiceName = L"QuickShare";
|
||||
constexpr std::wstring_view kPin = L"1234";
|
||||
constexpr int kWaitingForConnectionTimeoutSeconds = 90; // seconds
|
||||
} // namespace
|
||||
|
||||
@@ -193,11 +194,12 @@ std::unique_ptr<api::WifiDirectSocket> WifiDirectMedium::ConnectToService(
|
||||
// Advertiser starts to listen on server socket
|
||||
std::unique_ptr<api::WifiDirectServerSocket> WifiDirectMedium::ListenForService(
|
||||
int port) {
|
||||
LOG(INFO) << "WifiDirectMedium::ListenForService";
|
||||
LOG(INFO) << __func__
|
||||
<< " :Start to listen connection from WiFiDirect client.";
|
||||
|
||||
absl::MutexLock lock(mutex_);
|
||||
if (!IsServiceStarted()) {
|
||||
LOG(WARNING) << "WifiDirect service is not started, skip.";
|
||||
if (!IsGOStarted()) {
|
||||
LOG(WARNING) << "WifiDirect GO is not started, skip.";
|
||||
return nullptr;
|
||||
}
|
||||
// check current status
|
||||
@@ -207,14 +209,14 @@ std::unique_ptr<api::WifiDirectServerSocket> WifiDirectMedium::ListenForService(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto server_socket = std::make_unique<WifiDirectServerSocket>(port);
|
||||
auto server_socket = std::make_unique<WifiDirectServerSocket>();
|
||||
server_socket_ptr_ = server_socket.get();
|
||||
|
||||
// Start to listen on server socket in a separate thread. Before GC
|
||||
// connects to GO, GO doesn't have IP address. BWU calls this API right away
|
||||
// after it starts GO, we need to spin out the following logic to another
|
||||
// thread to avoid blocking BWU sending out of band upgrade frame to GC.
|
||||
listener_executor_.Execute([this]() mutable {
|
||||
listener_executor_.Execute([this, port]() mutable {
|
||||
absl::MutexLock lock(mutex_);
|
||||
bool dual_stack = NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
@@ -239,9 +241,12 @@ std::unique_ptr<api::WifiDirectServerSocket> WifiDirectMedium::ListenForService(
|
||||
LOG(INFO) << "IP address is ready.";
|
||||
}
|
||||
}
|
||||
|
||||
server_socket_ptr_->SetIPAddress(ip_address_local_);
|
||||
if (port == 0) {
|
||||
port = FeatureFlags::GetInstance().GetFlags().wifi_direct_default_port;
|
||||
}
|
||||
if (server_socket_ptr_ &&
|
||||
server_socket_ptr_->Listen(dual_stack, ip_address_local_)) {
|
||||
server_socket_ptr_->Listen(port, dual_stack)) {
|
||||
medium_status_ |= kMediumStatusAccepting;
|
||||
|
||||
// Setup close notifier after listen started.
|
||||
@@ -267,17 +272,27 @@ std::unique_ptr<api::WifiDirectServerSocket> WifiDirectMedium::ListenForService(
|
||||
return server_socket;
|
||||
}
|
||||
|
||||
bool WifiDirectMedium::StartWifiDirect() {
|
||||
bool WifiDirectMedium::StartWifiDirect(
|
||||
WifiDirectCredentials* wifi_direct_credentials) {
|
||||
LOG(INFO) << "WifiDirectMedium::StartWifiDirect";
|
||||
|
||||
absl::MutexLock lock(mutex_);
|
||||
if (IsServiceStarted()) {
|
||||
LOG(WARNING) << "Already started WifiDirect service, skip.";
|
||||
if (IsGOStarted()) {
|
||||
LOG(WARNING) << "Already started WifiDirect GO, skip.";
|
||||
return true;
|
||||
}
|
||||
|
||||
credentials_go_ = wifi_direct_credentials;
|
||||
Prng prng;
|
||||
std::string pin = absl::StrFormat("%04x", prng.NextUint32());
|
||||
credentials_go_->SetPin(pin);
|
||||
|
||||
std::string service_name = "NC-" + std::to_string(prng.NextUint32());
|
||||
credentials_go_->SetServiceName(service_name);
|
||||
LOG(INFO) << "service_name:pin " << service_name << ":" << pin;
|
||||
|
||||
// Create Advertiser object
|
||||
advertiser_ = WiFiDirectServiceAdvertiser(kServiceName);
|
||||
advertiser_ = WiFiDirectServiceAdvertiser(winrt::to_hstring(service_name));
|
||||
advertisement_status_changed_token_ = advertiser_.AdvertisementStatusChanged(
|
||||
{this, &WifiDirectMedium::OnAdvertisementStatusChanged});
|
||||
auto_accept_session_connected_token_ = advertiser_.AutoAcceptSessionConnected(
|
||||
@@ -290,7 +305,7 @@ bool WifiDirectMedium::StartWifiDirect() {
|
||||
advertiser_.ServiceStatus(WiFiDirectServiceStatus::Available);
|
||||
// Config Methods
|
||||
WiFiDirectServiceConfigurationMethod config_method;
|
||||
if (kPin.empty()) {
|
||||
if (pin.empty()) {
|
||||
config_method = WiFiDirectServiceConfigurationMethod::Default; // NOLINT
|
||||
} else {
|
||||
config_method = WiFiDirectServiceConfigurationMethod::PinDisplay;
|
||||
@@ -306,7 +321,7 @@ bool WifiDirectMedium::StartWifiDirect() {
|
||||
WiFiDirectServiceAdvertisementStatus::Created) ||
|
||||
(advertiser_.AdvertisementStatus() ==
|
||||
WiFiDirectServiceAdvertisementStatus::Started)) {
|
||||
medium_status_ |= kMediumStatusServiceStarted;
|
||||
medium_status_ |= kMediumStatusGOStarted;
|
||||
return true;
|
||||
}
|
||||
LOG(ERROR) << "Start WifiDirect GO failed.";
|
||||
@@ -331,7 +346,7 @@ bool WifiDirectMedium::StartWifiDirect() {
|
||||
bool WifiDirectMedium::StopWifiDirect() {
|
||||
LOG(INFO) << "WifiDirectMedium::StopWifiDirect";
|
||||
absl::MutexLock lock(mutex_);
|
||||
if (!IsServiceStarted()) {
|
||||
if (!IsGOStarted()) {
|
||||
LOG(WARNING) << "Cannot stop Service because no Service is started.";
|
||||
return true;
|
||||
}
|
||||
@@ -348,9 +363,11 @@ bool WifiDirectMedium::StopWifiDirect() {
|
||||
device_info_ = nullptr;
|
||||
session_ = nullptr;
|
||||
}
|
||||
medium_status_ &= (~kMediumStatusServiceStarted);
|
||||
medium_status_ &= (~kMediumStatusGOStarted);
|
||||
medium_status_ &= (~kMediumStatusConnected);
|
||||
server_socket_ptr_ = nullptr;
|
||||
ip_address_local_.clear();
|
||||
ip_address_remote_.clear();
|
||||
listener_executor_.Shutdown();
|
||||
return true;
|
||||
} catch (std::exception exception) {
|
||||
@@ -465,10 +482,12 @@ fire_and_forget WifiDirectMedium::OnSessionRequested(
|
||||
|
||||
absl::MutexLock lock(mutex_);
|
||||
WiFiDirectServiceSession session = nullptr;
|
||||
if (kPin.empty()) {
|
||||
auto pin = credentials_go_->GetPin();
|
||||
if (pin.empty()) {
|
||||
session = advertiser_.ConnectAsync(device_info_).get(); // NOLINT
|
||||
} else {
|
||||
session = advertiser_.ConnectAsync(device_info_, kPin).get();
|
||||
session = advertiser_.ConnectAsync(device_info_, winrt::to_hstring(pin))
|
||||
.get();
|
||||
}
|
||||
LOG(INFO) << "GO: TryEnqueue: Wait for ConnectAsync finish";
|
||||
if (!session) {
|
||||
@@ -519,7 +538,8 @@ fire_and_forget WifiDirectMedium::OnSessionRequested(
|
||||
}
|
||||
}
|
||||
|
||||
bool WifiDirectMedium::ConnectWifiDirect() {
|
||||
bool WifiDirectMedium::ConnectWifiDirect(
|
||||
const WifiDirectCredentials& credentials) {
|
||||
LOG(INFO) << "WifiDirectMedium::ConnectWifiDirect";
|
||||
absl::MutexLock lock(mutex_);
|
||||
if (IsConnecting()) {
|
||||
@@ -533,10 +553,9 @@ bool WifiDirectMedium::ConnectWifiDirect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
discovered_devices_by_id_.clear();
|
||||
connection_requested_devices_by_id_.clear();
|
||||
|
||||
winrt::hstring device_selector = WiFiDirectService::GetSelector(kServiceName);
|
||||
credentials_gc_ = credentials;
|
||||
winrt::hstring device_selector = WiFiDirectService::GetSelector(
|
||||
winrt::to_hstring(credentials_gc_.GetServiceName()));
|
||||
const winrt::param::iterable<winrt::hstring> requested_properties =
|
||||
winrt::single_threaded_vector<winrt::hstring>({
|
||||
winrt::to_hstring("System.Devices.WiFiDirectServices.ServiceAddress"),
|
||||
@@ -590,7 +609,8 @@ fire_and_forget WifiDirectMedium::Watcher_DeviceAdded(
|
||||
service_.PreferGroupOwnerMode(false);
|
||||
|
||||
WiFiDirectServiceSession session = nullptr;
|
||||
if (kPin.empty()) {
|
||||
auto pin = credentials_gc_.GetPin();
|
||||
if (pin.empty()) {
|
||||
session = service_.ConnectAsync().get(); // NOLINT
|
||||
} else {
|
||||
auto prov_info = co_await service_.GetProvisioningInfoAsync(
|
||||
@@ -605,7 +625,7 @@ fire_and_forget WifiDirectMedium::Watcher_DeviceAdded(
|
||||
<< ConfigMethodToString(
|
||||
prov_info.SelectedConfigurationMethod());
|
||||
|
||||
session = service_.ConnectAsync(kPin).get();
|
||||
session = service_.ConnectAsync(winrt::to_hstring(pin)).get();
|
||||
}
|
||||
|
||||
if (!session) {
|
||||
@@ -702,7 +722,9 @@ bool WifiDirectMedium::DisconnectWifiDirect() {
|
||||
device_watcher_ = nullptr;
|
||||
service_ = nullptr;
|
||||
session_ = nullptr;
|
||||
return true;
|
||||
ip_address_local_.clear();
|
||||
ip_address_remote_.clear();
|
||||
return true;
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Stop WifiDirect GC failed. Exception: "
|
||||
<< exception.what();
|
||||
|
||||
@@ -20,21 +20,20 @@
|
||||
#include <utility>
|
||||
|
||||
// Nearby connections headers
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#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/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/wifi_credential.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
|
||||
WifiDirectServerSocket::WifiDirectServerSocket(int port) : port_(port) {}
|
||||
namespace {
|
||||
constexpr int kWaitingForServerSocketReadyTimeoutSeconds = 90; // seconds
|
||||
} // namespace
|
||||
|
||||
WifiDirectServerSocket::~WifiDirectServerSocket() { Close(); }
|
||||
|
||||
@@ -42,9 +41,29 @@ std::string WifiDirectServerSocket::GetIPAddress() const {
|
||||
return wifi_direct_ipaddr_;
|
||||
}
|
||||
|
||||
int WifiDirectServerSocket::GetPort() const { return server_socket_.GetPort(); }
|
||||
void WifiDirectServerSocket::SetIPAddress(std::string ip_address) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
if (ip_address.empty()) {
|
||||
return;
|
||||
}
|
||||
wifi_direct_ipaddr_ = ip_address;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiDirectSocket> WifiDirectServerSocket::Accept() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
if (!is_listen_started_) {
|
||||
LOG(INFO) << __func__
|
||||
<< ": Server socket is not started, wait for server socket is "
|
||||
"ready.";
|
||||
is_listen_ready_.WaitWithTimeout(
|
||||
&mutex_, absl::Seconds(kWaitingForServerSocketReadyTimeoutSeconds));
|
||||
if (!is_listen_started_) {
|
||||
LOG(INFO) << __func__
|
||||
<< ": Server socket failed to start within timeout.";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto client_socket = server_socket_.Accept();
|
||||
if (client_socket == nullptr) {
|
||||
return nullptr;
|
||||
@@ -54,9 +73,16 @@ std::unique_ptr<api::WifiDirectSocket> WifiDirectServerSocket::Accept() {
|
||||
return std::make_unique<WifiDirectSocket>(std::move(client_socket));
|
||||
}
|
||||
|
||||
void WifiDirectServerSocket::SetCloseNotifier(
|
||||
absl::AnyInvocable<void()> notifier) {
|
||||
close_notifier_ = std::move(notifier);
|
||||
void WifiDirectServerSocket::PopulateWifiDirectCredentials(
|
||||
WifiDirectCredentials& wifi_direct_credentials) {
|
||||
wifi_direct_credentials.SetGateway(wifi_direct_ipaddr_);
|
||||
if (GetPort() != 0) {
|
||||
wifi_direct_credentials.SetPort(GetPort());
|
||||
} else {
|
||||
wifi_direct_credentials.SetPort(FeatureFlags::GetInstance()
|
||||
.GetFlags()
|
||||
.wifi_direct_default_port);
|
||||
}
|
||||
}
|
||||
|
||||
Exception WifiDirectServerSocket::Close() {
|
||||
@@ -64,35 +90,31 @@ Exception WifiDirectServerSocket::Close() {
|
||||
if (closed_) {
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
wifi_direct_ipaddr_.clear();
|
||||
is_listen_started_ = false;
|
||||
server_socket_.Close();
|
||||
closed_ = true;
|
||||
|
||||
if (close_notifier_ != nullptr) {
|
||||
close_notifier_();
|
||||
}
|
||||
|
||||
LOG(INFO) << __func__ << ": Close completed succesfully.";
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
bool WifiDirectServerSocket::Listen(bool dual_stack, std::string& ip_address) {
|
||||
// Get current IP addresses of the device.
|
||||
if (ip_address.empty()) {
|
||||
return false;
|
||||
}
|
||||
wifi_direct_ipaddr_ = ip_address;
|
||||
LOG(INFO) << "Listen wifi_direct on IP:port " << ip_address << ":" << port_;
|
||||
bool WifiDirectServerSocket::Listen(int port, bool dual_stack) {
|
||||
LOG(INFO) << "Listen wifi_direct on IP:port " << wifi_direct_ipaddr_ << ":"
|
||||
<< port;
|
||||
SocketAddress address(dual_stack);
|
||||
if (!SocketAddress::FromString(address, ip_address, port_)) {
|
||||
LOG(ERROR) << "Failed to parse wifi_direct IP address: " << ip_address
|
||||
<< " and port: " << port_;
|
||||
if (!SocketAddress::FromString(address, wifi_direct_ipaddr_, port)) {
|
||||
LOG(ERROR) << "Failed to parse wifi_direct IP address.";
|
||||
return false;
|
||||
}
|
||||
if (!server_socket_.Listen(address)) {
|
||||
LOG(ERROR) << "Failed to listen socket.";
|
||||
return false;
|
||||
}
|
||||
LOG(INFO) << "Notify the server socket is started.";
|
||||
absl::MutexLock lock(&mutex_);
|
||||
is_listen_started_ = true;
|
||||
is_listen_ready_.SignalAll();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
@@ -35,9 +36,11 @@ TEST(WifiDirectMedium, DISABLED_StartWifiDirect) {
|
||||
|
||||
if (run_test) {
|
||||
winrt::init_apartment();
|
||||
WifiDirectCredentials credentials;
|
||||
WifiDirectMedium wifi_direct_medium;
|
||||
|
||||
EXPECT_TRUE(wifi_direct_medium.StartWifiDirect());
|
||||
EXPECT_TRUE(wifi_direct_medium.IsInterfaceValid());
|
||||
EXPECT_TRUE(wifi_direct_medium.StartWifiDirect(&credentials));
|
||||
|
||||
while (true) {
|
||||
LOG(INFO) << "Enter \"s\" to stop test:";
|
||||
@@ -60,8 +63,19 @@ TEST(WifiDirectMedium, DISABLED_ConnectWifiDirect) {
|
||||
std::cin >> run_test;
|
||||
|
||||
if (run_test) {
|
||||
WifiDirectCredentials credentials;
|
||||
WifiDirectMedium wifi_direct_medium;
|
||||
EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect());
|
||||
|
||||
LOG(INFO) << "Enter WifiDirect Service Name to be connected: ";
|
||||
std::string service_name;
|
||||
std::cin >> service_name;
|
||||
LOG(INFO) << "Enter pin: ";
|
||||
std::string pin;
|
||||
std::cin >> pin;
|
||||
credentials.SetServiceName(service_name);
|
||||
credentials.SetPin(pin);
|
||||
|
||||
EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect(credentials));
|
||||
|
||||
absl::SleepFor(absl::Seconds(2));
|
||||
while (true) {
|
||||
@@ -86,9 +100,12 @@ TEST(WifiDirectMedium, DISABLED_WifiDirectServerStartListen) {
|
||||
|
||||
if (run_test) {
|
||||
winrt::init_apartment();
|
||||
WifiDirectCredentials credentials;
|
||||
WifiDirectMedium wifi_direct_medium;
|
||||
|
||||
EXPECT_TRUE(wifi_direct_medium.StartWifiDirect());
|
||||
EXPECT_TRUE(wifi_direct_medium.IsInterfaceValid());
|
||||
EXPECT_TRUE(wifi_direct_medium.StartWifiDirect(&credentials));
|
||||
|
||||
absl::SleepFor(absl::Seconds(1));
|
||||
std::unique_ptr<api::WifiDirectServerSocket> server_socket =
|
||||
wifi_direct_medium.ListenForService(/*port=*/1234);
|
||||
@@ -121,9 +138,19 @@ TEST(WifiDirectMedium, DISABLED_WifiDirectConnectToServiceServer) {
|
||||
|
||||
if (run_test) {
|
||||
winrt::init_apartment();
|
||||
WifiDirectCredentials credentials;
|
||||
WifiDirectMedium wifi_direct_medium;
|
||||
|
||||
EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect());
|
||||
LOG(INFO) << "Enter WifiDirect Service Name to be connected: ";
|
||||
std::string service_name;
|
||||
std::cin >> service_name;
|
||||
LOG(INFO) << "Enter pin: ";
|
||||
std::string pin;
|
||||
std::cin >> pin;
|
||||
credentials.SetServiceName(service_name);
|
||||
credentials.SetPin(pin);
|
||||
|
||||
EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect(credentials));
|
||||
absl::SleepFor(absl::Seconds(1));
|
||||
std::unique_ptr<api::WifiDirectSocket> client_socket =
|
||||
wifi_direct_medium.ConnectToService(
|
||||
|
||||
@@ -958,15 +958,15 @@ void MediumEnvironment::RegisterWifiDirectMedium(
|
||||
}
|
||||
|
||||
api::WifiDirectMedium* MediumEnvironment::GetWifiDirectMedium(
|
||||
absl::string_view ssid, absl::string_view ip_address) {
|
||||
absl::string_view service_name, absl::string_view ip_address) {
|
||||
MutexLock lock(&mutex_);
|
||||
for (auto& medium_info : wifi_direct_mediums_) {
|
||||
auto* medium_found = medium_info.first;
|
||||
auto& info = medium_info.second;
|
||||
if (info.is_go && info.is_active) {
|
||||
if ((info.wifi_direct_credentials->GetSSID() == ssid) ||
|
||||
if ((info.wifi_direct_credentials->GetServiceName() == service_name) ||
|
||||
(!ip_address.empty() &&
|
||||
(info.wifi_direct_credentials->GetIPAddress() == ip_address))) {
|
||||
(info.wifi_direct_credentials->GetGateway() == ip_address))) {
|
||||
LOG(INFO) << "Found Remote WifiDirect medium=" << medium_found;
|
||||
return medium_found;
|
||||
}
|
||||
@@ -995,8 +995,9 @@ void MediumEnvironment::UpdateWifiDirectMediumForStartOrConnect(
|
||||
if (wifi_direct_credentials) {
|
||||
LOG(INFO) << "Update WifiDirect medium for GO: this=" << this
|
||||
<< "; medium=" << &medium << role_status
|
||||
<< "; ssid=" << wifi_direct_credentials->GetSSID()
|
||||
<< "; password=" << wifi_direct_credentials->GetPassword();
|
||||
<< "; service_name="
|
||||
<< wifi_direct_credentials->GetServiceName()
|
||||
<< "; pin=" << wifi_direct_credentials->GetPin();
|
||||
} else {
|
||||
LOG(INFO) << "Reset WifiDirect medium for GO: this=" << this
|
||||
<< "; medium=" << &medium << role_status;
|
||||
@@ -1031,7 +1032,8 @@ void MediumEnvironment::UnregisterWifiDirectMedium(
|
||||
if (!enabled_) return;
|
||||
RunOnMediumEnvironmentThread([this, &medium]() {
|
||||
MutexLock lock(&mutex_);
|
||||
wifi_direct_mediums_.extract(&medium);
|
||||
auto item = wifi_direct_mediums_.extract(&medium);
|
||||
if (item.empty()) return;
|
||||
LOG(INFO) << "Unregistered WifiDirect medium:" << &medium;
|
||||
});
|
||||
}
|
||||
@@ -1064,6 +1066,7 @@ api::WifiHotspotMedium* MediumEnvironment::GetWifiHotspotMedium(
|
||||
}
|
||||
}
|
||||
|
||||
LOG(INFO) << "Can't find WifiHotspot medium!";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@ class MediumEnvironment {
|
||||
|
||||
// Returns WifiDirect medium that matches ssid or IP address with the role of
|
||||
// the Medium. Returns nullptr if not found.
|
||||
api::WifiDirectMedium* GetWifiDirectMedium(absl::string_view ssid,
|
||||
api::WifiDirectMedium* GetWifiDirectMedium(absl::string_view service_name,
|
||||
absl::string_view ip_address);
|
||||
|
||||
// Updates credential and Medium role(GO or GC) to indicate the current
|
||||
|
||||
@@ -90,6 +90,16 @@ class WifiDirectCredentials {
|
||||
std::string GetPassword() const { return password_; }
|
||||
void SetPassword(const std::string& password) { password_ = password; }
|
||||
|
||||
// Get/Set Service Name.
|
||||
std::string GetServiceName() const { return service_name_; }
|
||||
void SetServiceName(const std::string& service_name) {
|
||||
service_name_ = service_name;
|
||||
}
|
||||
|
||||
// Get/Set Pin.
|
||||
std::string GetPin() const { return pin_; }
|
||||
void SetPin(const std::string& pin) { pin_ = pin; }
|
||||
|
||||
// Gets IP Address, which is in byte sequence, in network order. For example,
|
||||
// for "192.168.1.1", it'll be byte(129)+byte(168)+byte(1)+byte(1). Now only
|
||||
// ipv4 is supported.
|
||||
@@ -121,8 +131,15 @@ class WifiDirectCredentials {
|
||||
}
|
||||
|
||||
private:
|
||||
// There are 2 types of WifiDirectAuthType.
|
||||
// 1. Without Service Discovery: the credentials are ssid/password.
|
||||
// 2. With Service Discovery: the credentials are service_name/pin.
|
||||
// Android supports type 1 and 2 in the future, but Windows only supports the
|
||||
// second type.
|
||||
std::string ssid_;
|
||||
std::string password_;
|
||||
std::string service_name_;
|
||||
std::string pin_;
|
||||
std::string ip_address_;
|
||||
std::string gateway_ = "0.0.0.0";
|
||||
int port_ = 0;
|
||||
|
||||
@@ -15,14 +15,24 @@
|
||||
#ifndef PLATFORM_PUBLIC_WIFI_DIRECT_H_
|
||||
#define PLATFORM_PUBLIC_WIFI_DIRECT_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/platform.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
#include "internal/platform/mutex_lock.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
@@ -99,16 +109,11 @@ class WifiDirectServerSocket final {
|
||||
std::unique_ptr<api::WifiDirectServerSocket> socket)
|
||||
: impl_(std::move(socket)) {}
|
||||
|
||||
// Returns ip address.
|
||||
std::string GetIPAddress() const {
|
||||
CHECK(impl_);
|
||||
return impl_->GetIPAddress();
|
||||
}
|
||||
|
||||
// Returns port.
|
||||
int GetPort() const {
|
||||
CHECK(impl_);
|
||||
return impl_->GetPort();
|
||||
// Populates the WifiDirect credentials with the server socket's service
|
||||
// addresses and ports.
|
||||
void PopulateWifiDirectCredentials(
|
||||
WifiDirectCredentials& wifi_direct_credentials) {
|
||||
impl_->PopulateWifiDirectCredentials(wifi_direct_credentials);
|
||||
}
|
||||
|
||||
// Blocks until either:
|
||||
@@ -158,8 +163,8 @@ class WifiDirectMedium {
|
||||
|
||||
// Returns a new WifiDirectServerSocket.
|
||||
// On Success, WifiDirectServerSocket::IsValid() returns true.
|
||||
WifiDirectServerSocket ListenForService(int port = 0) {
|
||||
return WifiDirectServerSocket(impl_->ListenForService(port));
|
||||
WifiDirectServerSocket ListenForService() {
|
||||
return WifiDirectServerSocket(impl_->ListenForService(/*port=*/0));
|
||||
}
|
||||
|
||||
// Returns the port range as a pair of min and max port.
|
||||
@@ -173,11 +178,10 @@ class WifiDirectMedium {
|
||||
}
|
||||
bool StopWifiDirect() { return impl_->StopWifiDirect(); }
|
||||
|
||||
bool ConnectWifiDirect(absl::string_view ssid, absl::string_view password) {
|
||||
bool ConnectWifiDirect(const WifiDirectCredentials& wifi_direct_credentials) {
|
||||
MutexLock lock(&mutex_);
|
||||
wifi_direct_credentials_.SetSSID(std::string(ssid));
|
||||
wifi_direct_credentials_.SetPassword(std::string(password));
|
||||
return impl_->ConnectWifiDirect(&wifi_direct_credentials_);
|
||||
wifi_direct_credentials_ = wifi_direct_credentials;
|
||||
return impl_->ConnectWifiDirect(wifi_direct_credentials_);
|
||||
}
|
||||
bool DisconnectWifiDirect() { return impl_->DisconnectWifiDirect(); }
|
||||
|
||||
|
||||
@@ -14,12 +14,22 @@
|
||||
|
||||
#include "internal/platform/wifi_direct.h"
|
||||
|
||||
#include <memory>
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/single_thread_executor.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace {
|
||||
@@ -35,22 +45,37 @@ constexpr FeatureFlags kTestCases[] = {
|
||||
},
|
||||
};
|
||||
|
||||
constexpr absl::string_view kSsid = "Direct-357a2d8c";
|
||||
constexpr absl::string_view kPassword = "b592f7d3";
|
||||
constexpr absl::string_view kServiceName = "NC-WifiDirectTest";
|
||||
constexpr absl::string_view kPin = "b592f7d3";
|
||||
constexpr absl::string_view kIp = "123.234.23.1";
|
||||
constexpr const size_t kPort = 20;
|
||||
constexpr absl::string_view kData = "ABCD";
|
||||
constexpr const size_t kChunkSize = 10;
|
||||
constexpr absl::Duration kWaitDuration = absl::Milliseconds(100);
|
||||
|
||||
TEST(WifiDirectCredentialsTest, SetGetServiceName) {
|
||||
std::string service_name(kServiceName);
|
||||
WifiDirectCredentials wifi_direct_credentials;
|
||||
wifi_direct_credentials.SetServiceName(service_name);
|
||||
|
||||
EXPECT_EQ(wifi_direct_credentials.GetServiceName(), kServiceName);
|
||||
}
|
||||
|
||||
TEST(WifiDirectCredentialsTest, SetGetPin) {
|
||||
std::string pin(kPin);
|
||||
WifiDirectCredentials wifi_direct_credentials;
|
||||
wifi_direct_credentials.SetPin(pin);
|
||||
|
||||
EXPECT_EQ(wifi_direct_credentials.GetPin(), kPin);
|
||||
}
|
||||
|
||||
|
||||
class WifiDirectMediumTest : public testing::TestWithParam<FeatureFlags> {
|
||||
protected:
|
||||
WifiDirectMediumTest() { env_.Start(); }
|
||||
~WifiDirectMediumTest() override {
|
||||
absl::SleepFor(kWaitDuration);
|
||||
EXPECT_TRUE(env_.IsWifiDirectMediumsEmpty());
|
||||
WifiDirectMediumTest() {
|
||||
env_.Stop();
|
||||
env_.Start();
|
||||
}
|
||||
~WifiDirectMediumTest() override { env_.Stop(); }
|
||||
|
||||
MediumEnvironment& env_{MediumEnvironment::Instance()};
|
||||
};
|
||||
@@ -70,7 +95,7 @@ TEST_F(WifiDirectMediumTest, ConstructorDestructorWorks) {
|
||||
EXPECT_NE(&wifi_direct_a.GetImpl(), &wifi_direct_b.GetImpl());
|
||||
}
|
||||
|
||||
TEST_F(WifiDirectMediumTest, CanStartStopDirect) {
|
||||
TEST_F(WifiDirectMediumTest, CanStartStopWifiDirect) {
|
||||
WifiDirectMedium wifi_direct_a;
|
||||
|
||||
ASSERT_TRUE(wifi_direct_a.IsInterfaceValid());
|
||||
@@ -82,11 +107,14 @@ TEST_F(WifiDirectMediumTest, CanStartStopDirect) {
|
||||
EXPECT_TRUE(wifi_direct_a.StopWifiDirect());
|
||||
}
|
||||
|
||||
TEST_F(WifiDirectMediumTest, CanConnectDisconnectDirect) {
|
||||
TEST_F(WifiDirectMediumTest, CanConnectDisconnectWifiDirect) {
|
||||
WifiDirectMedium wifi_direct_a;
|
||||
WifiDirectCredentials credentials;
|
||||
credentials.SetServiceName(std::string(kServiceName));
|
||||
credentials.SetPin(std::string(kPin));
|
||||
|
||||
ASSERT_TRUE(wifi_direct_a.IsInterfaceValid());
|
||||
EXPECT_FALSE(wifi_direct_a.ConnectWifiDirect(kSsid, kPassword));
|
||||
EXPECT_FALSE(wifi_direct_a.ConnectWifiDirect(credentials));
|
||||
EXPECT_TRUE(wifi_direct_a.DisconnectWifiDirect());
|
||||
}
|
||||
|
||||
@@ -102,17 +130,17 @@ TEST_P(WifiDirectMediumTest, CanStartDirectGOThatOtherCanConnect) {
|
||||
WifiDirectCredentials* wifi_direct_credentials =
|
||||
wifi_direct_a.GetCredential();
|
||||
auto* medium_a =
|
||||
env_.GetWifiDirectMedium(wifi_direct_credentials->GetSSID(), {});
|
||||
env_.GetWifiDirectMedium(wifi_direct_credentials->GetServiceName(), {});
|
||||
EXPECT_NE(medium_a, nullptr);
|
||||
EXPECT_TRUE(
|
||||
wifi_direct_b.ConnectWifiDirect(wifi_direct_credentials->GetSSID(),
|
||||
wifi_direct_credentials->GetPassword()));
|
||||
EXPECT_TRUE(wifi_direct_b.ConnectWifiDirect(*wifi_direct_credentials));
|
||||
|
||||
WifiDirectServerSocket server_socket = wifi_direct_a.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
auto ip_addr = server_socket.GetIPAddress();
|
||||
EXPECT_FALSE(absl::EndsWith(ip_addr, "."));
|
||||
wifi_direct_credentials->SetIPAddress(ip_addr);
|
||||
server_socket.PopulateWifiDirectCredentials(*wifi_direct_credentials);
|
||||
std::string wifi_direct_a_ip_addr = wifi_direct_credentials->GetGateway();
|
||||
EXPECT_FALSE(absl::EndsWith(wifi_direct_a_ip_addr, "."));
|
||||
int wifi_direct_a_port = wifi_direct_credentials->GetPort();
|
||||
EXPECT_NE(wifi_direct_a_port, 0);
|
||||
|
||||
WifiDirectSocket socket_a;
|
||||
WifiDirectSocket socket_b;
|
||||
@@ -124,14 +152,16 @@ TEST_P(WifiDirectMediumTest, CanStartDirectGOThatOtherCanConnect) {
|
||||
SingleThreadExecutor server_executor;
|
||||
SingleThreadExecutor client_executor;
|
||||
client_executor.Execute(
|
||||
[&wifi_direct_b, &socket_b, &server_socket, &flag]() {
|
||||
[&wifi_direct_b, &socket_b, &server_socket, wifi_direct_a_ip_addr,
|
||||
wifi_direct_a_port, &flag]() {
|
||||
socket_b = wifi_direct_b.ConnectToService(kIp, kPort, &flag);
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
socket_b = wifi_direct_b.ConnectToService(
|
||||
server_socket.GetIPAddress(), kPort, &flag);
|
||||
wifi_direct_a_ip_addr, kPort, &flag);
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
|
||||
socket_b = wifi_direct_b.ConnectToService(
|
||||
server_socket.GetIPAddress(), server_socket.GetPort(), &flag);
|
||||
wifi_direct_a_ip_addr, wifi_direct_a_port, &flag);
|
||||
if (!socket_b.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
@@ -163,7 +193,7 @@ TEST_P(WifiDirectMediumTest, CanStartDirectGOThatOtherCanConnect) {
|
||||
EXPECT_TRUE(wifi_direct_b.DisconnectWifiDirect());
|
||||
EXPECT_TRUE(wifi_direct_a.StopWifiDirect());
|
||||
auto* medium_b =
|
||||
env_.GetWifiDirectMedium(wifi_direct_credentials->GetSSID(), {});
|
||||
env_.GetWifiDirectMedium(wifi_direct_credentials->GetServiceName(), {});
|
||||
EXPECT_EQ(medium_b, nullptr);
|
||||
}
|
||||
|
||||
@@ -178,13 +208,13 @@ TEST_P(WifiDirectMediumTest, CanStartDirectGOThatOtherCanCancelConnect) {
|
||||
EXPECT_TRUE(wifi_direct_a.StartWifiDirect());
|
||||
WifiDirectCredentials* wifi_direct_credentials =
|
||||
wifi_direct_a.GetCredential();
|
||||
EXPECT_TRUE(
|
||||
wifi_direct_b.ConnectWifiDirect(wifi_direct_credentials->GetSSID(),
|
||||
wifi_direct_credentials->GetPassword()));
|
||||
EXPECT_TRUE(wifi_direct_b.ConnectWifiDirect(*wifi_direct_credentials));
|
||||
|
||||
WifiDirectServerSocket server_socket = wifi_direct_a.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
wifi_direct_credentials->SetIPAddress(server_socket.GetIPAddress());
|
||||
server_socket.PopulateWifiDirectCredentials(*wifi_direct_credentials);
|
||||
std::string wifi_direct_a_ip_addr = wifi_direct_credentials->GetGateway();
|
||||
int wifi_direct_a_port = wifi_direct_credentials->GetPort();
|
||||
|
||||
WifiDirectSocket socket_a;
|
||||
WifiDirectSocket socket_b;
|
||||
@@ -197,11 +227,12 @@ TEST_P(WifiDirectMediumTest, CanStartDirectGOThatOtherCanCancelConnect) {
|
||||
SingleThreadExecutor server_executor;
|
||||
SingleThreadExecutor client_executor;
|
||||
client_executor.Execute(
|
||||
[&wifi_direct_b, &socket_b, &server_socket, &flag]() {
|
||||
[&wifi_direct_b, &socket_b, &server_socket, wifi_direct_a_ip_addr,
|
||||
wifi_direct_a_port, &flag]() {
|
||||
socket_b = wifi_direct_b.ConnectToService(kIp, kPort, &flag);
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
socket_b = wifi_direct_b.ConnectToService(
|
||||
server_socket.GetIPAddress(), server_socket.GetPort(), &flag);
|
||||
wifi_direct_a_ip_addr, wifi_direct_a_port, &flag);
|
||||
if (!socket_b.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
@@ -225,8 +256,8 @@ TEST_P(WifiDirectMediumTest, CanStartDirectGOThatOtherCanCancelConnect) {
|
||||
server_socket.Close();
|
||||
{
|
||||
CancellationFlag flag(true);
|
||||
socket_c = wifi_direct_b.ConnectToService(server_socket.GetIPAddress(),
|
||||
server_socket.GetPort(), &flag);
|
||||
socket_c = wifi_direct_b.ConnectToService(wifi_direct_a_ip_addr,
|
||||
wifi_direct_a_port, &flag);
|
||||
EXPECT_FALSE(socket_c.IsValid());
|
||||
}
|
||||
|
||||
@@ -241,8 +272,11 @@ TEST_F(WifiDirectMediumTest, CanStartDirectGOThatOtherFailConnect) {
|
||||
ASSERT_TRUE(wifi_direct_a.IsInterfaceValid());
|
||||
ASSERT_TRUE(wifi_direct_b.IsInterfaceValid());
|
||||
EXPECT_TRUE(wifi_direct_a.StartWifiDirect());
|
||||
WifiDirectCredentials wifi_direct_credentials;
|
||||
wifi_direct_credentials.SetServiceName(std::string(kServiceName));
|
||||
wifi_direct_credentials.SetPin(std::string(kPin));
|
||||
|
||||
EXPECT_FALSE(wifi_direct_b.ConnectWifiDirect(kSsid, kPassword));
|
||||
EXPECT_FALSE(wifi_direct_b.ConnectWifiDirect(wifi_direct_credentials));
|
||||
EXPECT_TRUE(wifi_direct_b.DisconnectWifiDirect());
|
||||
|
||||
EXPECT_TRUE(wifi_direct_a.StopWifiDirect());
|
||||
|
||||
Reference in New Issue
Block a user