mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 07:36:10 -04:00
WIFI Direct implementation (2)
Part 2: Implementation g3 medium/Environment/platform layer unit test PiperOrigin-RevId: 485417100
This commit is contained in:
@@ -23,42 +23,168 @@
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/implementation/g3/wifi_hotspot.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/implementation/wifi_hotspot.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
|
||||
// Code for WifiDirectMedium
|
||||
WifiDirectMedium::WifiDirectMedium() {
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.RegisterWifiDirectMedium(*this);
|
||||
}
|
||||
|
||||
WifiDirectMedium::~WifiDirectMedium() {
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.UnregisterWifiDirectMedium(*this);
|
||||
}
|
||||
|
||||
bool WifiDirectMedium::StartWifiDirect(
|
||||
HotspotCredentials* 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);
|
||||
|
||||
NEARBY_LOGS(INFO) << "G3 StartWifiDirect GO: ssid=" << ssid
|
||||
<< ", password:" << password;
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, wifi_direct_credentials,
|
||||
/*is_go=*/true, /*enabled=*/true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiDirectMedium::StopWifiDirect() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(INFO) << "G3 StopWifiDirect GO";
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, /*credentials*/ nullptr,
|
||||
/*is_go=*/true,
|
||||
/*enabled=*/false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiDirectMedium::ConnectWifiDirect(
|
||||
HotspotCredentials* wifi_direct_credentials) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
|
||||
NEARBY_LOGS(INFO) << "G3 ConnectWifiDirect : ssid="
|
||||
<< wifi_direct_credentials->GetSSID()
|
||||
<< ", password:" << wifi_direct_credentials->GetPassword();
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
auto* remote_medium = static_cast<WifiDirectMedium*>(
|
||||
env.GetWifiDirectMedium(wifi_direct_credentials->GetSSID(), {}));
|
||||
if (!remote_medium) {
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, wifi_direct_credentials,
|
||||
/*is_go=*/false,
|
||||
/*enabled=*/false);
|
||||
return false;
|
||||
}
|
||||
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, wifi_direct_credentials,
|
||||
/*is_go=*/false,
|
||||
/*enabled=*/true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiDirectMedium::DisconnectWifiDirect() { return true; }
|
||||
bool WifiDirectMedium::DisconnectWifiDirect() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
|
||||
NEARBY_LOGS(INFO) << "G3 DisconnectWifiDirect";
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, /*credentials*/ nullptr,
|
||||
/*is_go=*/false,
|
||||
/*enabled=*/false);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiHotspotSocket> WifiDirectMedium::ConnectToService(
|
||||
absl::string_view ip_address, int port,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
return nullptr;
|
||||
std::string socket_name = WifiHotspotServerSocket::GetName(ip_address, port);
|
||||
NEARBY_LOGS(INFO) << "G3 WifiDirect ConnectToService [self]: medium=" << this
|
||||
<< ", ip address + port=" << socket_name;
|
||||
// First, find an instance of remote medium, that exposed this service.
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
auto* remote_medium =
|
||||
static_cast<WifiDirectMedium*>(env.GetWifiDirectMedium({}, ip_address));
|
||||
if (remote_medium == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WifiHotspotServerSocket* server_socket = nullptr;
|
||||
NEARBY_LOGS(INFO) << "G3 WifiDirect ConnectToService [peer]: medium="
|
||||
<< remote_medium
|
||||
<< ", remote ip address + port=" << socket_name;
|
||||
// Then, find our server socket context in this medium.
|
||||
{
|
||||
absl::MutexLock medium_lock(&remote_medium->mutex_);
|
||||
auto item = remote_medium->server_sockets_.find(socket_name);
|
||||
server_socket = item != server_sockets_.end() ? item->second : nullptr;
|
||||
if (server_socket == nullptr) {
|
||||
NEARBY_LOGS(ERROR) << "G3 WifiDirect Failed to find WifiDirect Server "
|
||||
"socket: socket_name="
|
||||
<< socket_name;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (cancellation_flag->Cancelled()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "G3 WifiDirect Connect: Has been cancelled: socket_name="
|
||||
<< socket_name;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto socket = std::make_unique<WifiHotspotSocket>();
|
||||
// Finally, Request to connect to this socket.
|
||||
|
||||
server_socket->Connect(*socket);
|
||||
NEARBY_LOGS(INFO) << "G3 WifiHotspot GC ConnectToService: connected: socket="
|
||||
<< socket.get();
|
||||
return socket;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiHotspotServerSocket>
|
||||
WifiDirectMedium::ListenForService(int port) {
|
||||
return nullptr;
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
auto server_socket = std::make_unique<WifiHotspotServerSocket>();
|
||||
|
||||
std::string dot_decimal_ip;
|
||||
std::string ip_address = env.GetFakeIPAddress();
|
||||
|
||||
for (auto byte : ip_address) {
|
||||
absl::StrAppend(&dot_decimal_ip, absl::StrFormat("%d", byte), ".");
|
||||
}
|
||||
dot_decimal_ip.pop_back();
|
||||
|
||||
server_socket->SetIPAddress(dot_decimal_ip);
|
||||
server_socket->SetPort(port == 0 ? env.GetFakePort() : port);
|
||||
std::string socket_name = WifiHotspotServerSocket::GetName(
|
||||
server_socket->GetIPAddress(), server_socket->GetPort());
|
||||
server_socket->SetCloseNotifier([this, socket_name]() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
server_sockets_.erase(socket_name);
|
||||
});
|
||||
NEARBY_LOGS(INFO) << "G3 WifiDirect GO Adding server socket: medium=" << this
|
||||
<< ", socket_name=" << socket_name;
|
||||
absl::MutexLock lock(&mutex_);
|
||||
server_sockets_.insert({socket_name, server_socket.get()});
|
||||
return server_socket;
|
||||
}
|
||||
|
||||
} // namespace g3
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
@@ -40,8 +40,8 @@ class WifiDirectMedium;
|
||||
// Container of operations that can be performed over the WifiDirect medium.
|
||||
class WifiDirectMedium : public api::WifiDirectMedium {
|
||||
public:
|
||||
WifiDirectMedium() = default;
|
||||
~WifiDirectMedium() override = default;
|
||||
WifiDirectMedium();
|
||||
~WifiDirectMedium() override;
|
||||
|
||||
WifiDirectMedium(const WifiDirectMedium&) = delete;
|
||||
WifiDirectMedium(WifiDirectMedium&&) = delete;
|
||||
|
||||
@@ -71,6 +71,7 @@ void MediumEnvironment::Reset() {
|
||||
wifi_lan_mediums_.clear();
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
wifi_direct_mediums_.clear();
|
||||
wifi_hotspot_mediums_.clear();
|
||||
}
|
||||
use_valid_peer_connection_ = true;
|
||||
@@ -927,6 +928,96 @@ api::WifiLanMedium* MediumEnvironment::GetWifiLanMedium(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MediumEnvironment::RegisterWifiDirectMedium(
|
||||
api::WifiDirectMedium& medium) {
|
||||
if (!enabled_) return;
|
||||
RunOnMediumEnvironmentThread([this, &medium]() {
|
||||
MutexLock lock(&mutex_);
|
||||
wifi_direct_mediums_.insert({&medium, WifiDirectMediumContext{}});
|
||||
NEARBY_LOG(INFO, "Registered: medium=%p", &medium);
|
||||
});
|
||||
}
|
||||
|
||||
api::WifiDirectMedium* MediumEnvironment::GetWifiDirectMedium(
|
||||
absl::string_view ssid, 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) ||
|
||||
(!ip_address.empty() &&
|
||||
(info.wifi_direct_credentials->GetIPAddress() == ip_address))) {
|
||||
NEARBY_LOGS(INFO) << "Found Remote WifiDirect medium=" << medium_found;
|
||||
return medium_found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NEARBY_LOGS(INFO) << "Can't find WifiDirect medium!";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MediumEnvironment::UpdateWifiDirectMediumForStartOrConnect(
|
||||
api::WifiDirectMedium& medium,
|
||||
const HotspotCredentials* wifi_direct_credentials, bool is_go,
|
||||
bool enabled) {
|
||||
if (!enabled_) return;
|
||||
|
||||
CountDownLatch latch(1);
|
||||
RunOnMediumEnvironmentThread(
|
||||
[this, &medium, wifi_direct_credentials = wifi_direct_credentials, is_go,
|
||||
enabled, &latch]() {
|
||||
std::string role_status = absl::StrFormat(
|
||||
"; %s is %s", is_go ? "Group Owner" : "Group Client",
|
||||
is_go ? (enabled ? "Started" : "Stopped")
|
||||
: (enabled ? "Connected" : "Disconneced"));
|
||||
|
||||
if (wifi_direct_credentials) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Update WifiDirect medium for GO: this=" << this
|
||||
<< "; medium=" << &medium << role_status
|
||||
<< "; ssid=" << wifi_direct_credentials->GetSSID()
|
||||
<< "; password=" << wifi_direct_credentials->GetPassword();
|
||||
} else {
|
||||
NEARBY_LOGS(INFO) << "Reset WifiDirect medium for GO: this=" << this
|
||||
<< "; medium=" << &medium << role_status;
|
||||
}
|
||||
|
||||
MutexLock lock(&mutex_);
|
||||
for (auto& medium_info : wifi_direct_mediums_) {
|
||||
auto& local_medium = medium_info.first;
|
||||
auto& info = medium_info.second;
|
||||
if (local_medium == &medium) {
|
||||
NEARBY_LOGS(INFO) << "Found WifiDirect medium=" << &medium;
|
||||
info.is_active = enabled;
|
||||
info.is_go = is_go;
|
||||
if (enabled) {
|
||||
info.wifi_direct_credentials = wifi_direct_credentials;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
latch.CountDown();
|
||||
});
|
||||
latch.Await();
|
||||
}
|
||||
|
||||
bool MediumEnvironment::IsWifiDirectMediumsEmpty() {
|
||||
MutexLock lock(&mutex_);
|
||||
return wifi_direct_mediums_.empty();
|
||||
}
|
||||
|
||||
void MediumEnvironment::UnregisterWifiDirectMedium(
|
||||
api::WifiDirectMedium& medium) {
|
||||
if (!enabled_) return;
|
||||
RunOnMediumEnvironmentThread([this, &medium]() {
|
||||
MutexLock lock(&mutex_);
|
||||
wifi_direct_mediums_.extract(&medium);
|
||||
NEARBY_LOGS(INFO) << "Unregistered WifiDirect medium";
|
||||
});
|
||||
}
|
||||
|
||||
void MediumEnvironment::RegisterWifiHotspotMedium(
|
||||
api::WifiHotspotMedium& medium) {
|
||||
if (!enabled_) return;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
@@ -35,6 +36,7 @@
|
||||
#endif
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/implementation/wifi_hotspot.h"
|
||||
#include "internal/platform/implementation/wifi_lan.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
@@ -309,6 +311,28 @@ class MediumEnvironment {
|
||||
// port, or nullptr.
|
||||
api::WifiLanMedium* GetWifiLanMedium(const std::string& ip_address, int port);
|
||||
|
||||
// Adds medium-related info to allow for start/connect WifiDirect to work.
|
||||
void RegisterWifiDirectMedium(api::WifiDirectMedium& medium);
|
||||
|
||||
// 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,
|
||||
absl::string_view ip_address);
|
||||
|
||||
// Updates credential and Medium role(GO or GC) to indicate the current
|
||||
// medium is exposing Start WifiDirect event.
|
||||
void UpdateWifiDirectMediumForStartOrConnect(
|
||||
api::WifiDirectMedium& medium,
|
||||
const HotspotCredentials* wifi_direct_credentials, bool is_go,
|
||||
bool enabled);
|
||||
|
||||
// For unit test only
|
||||
bool IsWifiDirectMediumsEmpty();
|
||||
|
||||
// Removes medium-related info. This should correspond to device being stopped
|
||||
// or disconnected.
|
||||
void UnregisterWifiDirectMedium(api::WifiDirectMedium& medium);
|
||||
|
||||
// Adds medium-related info to allow for start/connect Hotspot to work.
|
||||
// This provides access to this medium from other mediums, when protocol
|
||||
// expects they should communicate.
|
||||
@@ -367,6 +391,14 @@ class MediumEnvironment {
|
||||
absl::flat_hash_map<std::string, NsdServiceInfo> discovered_services;
|
||||
};
|
||||
|
||||
struct WifiDirectMediumContext {
|
||||
// Set to "true" for Medium act as WifiDirect GO role; "false" for GC role
|
||||
bool is_go = false;
|
||||
// Set "true" when GO is started or GC is connected
|
||||
bool is_active = false;
|
||||
const HotspotCredentials* wifi_direct_credentials;
|
||||
};
|
||||
|
||||
struct WifiHotspotMediumContext {
|
||||
// Set to "true" for Medium act as SoftAP role; "false" for STA role
|
||||
bool is_ap = true;
|
||||
@@ -441,6 +473,9 @@ class MediumEnvironment {
|
||||
wifi_lan_mediums_;
|
||||
|
||||
Mutex mutex_;
|
||||
absl::flat_hash_map<api::WifiDirectMedium*, WifiDirectMediumContext>
|
||||
wifi_direct_mediums_ ABSL_GUARDED_BY(mutex_);
|
||||
|
||||
absl::flat_hash_map<api::WifiHotspotMedium*, WifiHotspotMediumContext>
|
||||
wifi_hotspot_mediums_ ABSL_GUARDED_BY(mutex_);
|
||||
|
||||
|
||||
@@ -18,23 +18,57 @@
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/platform/wifi_hotspot.h"
|
||||
#include "internal/platform/wifi_hotspot_credential.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace {
|
||||
|
||||
using FeatureFlags = FeatureFlags::Flags;
|
||||
|
||||
constexpr FeatureFlags kTestCases[] = {
|
||||
FeatureFlags{
|
||||
.enable_cancellation_flag = true,
|
||||
},
|
||||
FeatureFlags{
|
||||
.enable_cancellation_flag = false,
|
||||
},
|
||||
};
|
||||
|
||||
constexpr absl::string_view kSsid = "Direct-357a2d8c";
|
||||
constexpr absl::string_view kPassword = "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);
|
||||
|
||||
class WifiDirectMediumTest : public ::testing::Test {};
|
||||
class WifiDirectMediumTest : public testing::TestWithParam<FeatureFlags> {
|
||||
protected:
|
||||
WifiDirectMediumTest() {
|
||||
env_.Stop();
|
||||
env_.Start();
|
||||
}
|
||||
~WifiDirectMediumTest() override {
|
||||
absl::SleepFor(kWaitDuration);
|
||||
EXPECT_TRUE(env_.IsWifiDirectMediumsEmpty());
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
MediumEnvironment& env_{MediumEnvironment::Instance()};
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ParametrisedWifiDirectMediumTest, WifiDirectMediumTest,
|
||||
testing::ValuesIn(kTestCases));
|
||||
|
||||
TEST_F(WifiDirectMediumTest, ConstructorDestructorWorks) {
|
||||
auto wifi_direct_a = WifiDirectMedium();
|
||||
auto wifi_direct_b = WifiDirectMedium();
|
||||
WifiDirectMedium wifi_direct_a;
|
||||
WifiDirectMedium wifi_direct_b;
|
||||
|
||||
// Make sure we can create functional mediums.
|
||||
ASSERT_TRUE(wifi_direct_a.IsInterfaceValid());
|
||||
ASSERT_TRUE(wifi_direct_b.IsInterfaceValid());
|
||||
|
||||
@@ -43,29 +77,173 @@ TEST_F(WifiDirectMediumTest, ConstructorDestructorWorks) {
|
||||
}
|
||||
|
||||
TEST_F(WifiDirectMediumTest, CanStartStopDirect) {
|
||||
auto wifi_direct_a = WifiDirectMedium();
|
||||
WifiDirectMedium wifi_direct_a;
|
||||
|
||||
ASSERT_TRUE(wifi_direct_a.IsInterfaceValid());
|
||||
EXPECT_TRUE(wifi_direct_a.StartWifiDirect());
|
||||
EXPECT_EQ(wifi_direct_a.GetDynamicPortRange(), std::nullopt);
|
||||
|
||||
WifiHotspotServerSocket server_socket = wifi_direct_a.ListenForService();
|
||||
EXPECT_FALSE(server_socket.IsValid());
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
server_socket.Close();
|
||||
EXPECT_TRUE(wifi_direct_a.StopWifiDirect());
|
||||
}
|
||||
|
||||
TEST_F(WifiDirectMediumTest, CanConnectDisconnectDirect) {
|
||||
auto wifi_direct_a = WifiDirectMedium();
|
||||
WifiDirectMedium wifi_direct_a;
|
||||
|
||||
ASSERT_TRUE(wifi_direct_a.IsInterfaceValid());
|
||||
EXPECT_TRUE(wifi_direct_a.ConnectWifiDirect(kSsid, kPassword));
|
||||
EXPECT_FALSE(wifi_direct_a.ConnectWifiDirect(kSsid, kPassword));
|
||||
EXPECT_TRUE(wifi_direct_a.DisconnectWifiDirect());
|
||||
}
|
||||
|
||||
TEST_F(WifiDirectMediumTest, CanConnectToService) {
|
||||
auto wifi_direct = WifiDirectMedium();
|
||||
CancellationFlag flag;
|
||||
EXPECT_FALSE(wifi_direct.ConnectToService(kIp, kPort, &flag).IsValid());
|
||||
TEST_P(WifiDirectMediumTest, CanStartDirectGOThatOtherCanConnect) {
|
||||
FeatureFlags feature_flags = GetParam();
|
||||
env_.SetFeatureFlags(feature_flags);
|
||||
WifiDirectMedium wifi_direct_a;
|
||||
WifiDirectMedium wifi_direct_b;
|
||||
|
||||
ASSERT_TRUE(wifi_direct_a.IsInterfaceValid());
|
||||
ASSERT_TRUE(wifi_direct_b.IsInterfaceValid());
|
||||
EXPECT_TRUE(wifi_direct_a.StartWifiDirect());
|
||||
HotspotCredentials* wifi_direct_credentials = wifi_direct_a.GetCredential();
|
||||
auto* medium_a =
|
||||
env_.GetWifiDirectMedium(wifi_direct_credentials->GetSSID(), {});
|
||||
EXPECT_NE(medium_a, nullptr);
|
||||
EXPECT_TRUE(
|
||||
wifi_direct_b.ConnectWifiDirect(wifi_direct_credentials->GetSSID(),
|
||||
wifi_direct_credentials->GetPassword()));
|
||||
|
||||
WifiHotspotServerSocket 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);
|
||||
|
||||
WifiHotspotSocket socket_a;
|
||||
WifiHotspotSocket socket_b;
|
||||
EXPECT_FALSE(socket_a.IsValid());
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
|
||||
{
|
||||
CancellationFlag flag;
|
||||
SingleThreadExecutor server_executor;
|
||||
SingleThreadExecutor client_executor;
|
||||
client_executor.Execute(
|
||||
[&wifi_direct_b, &socket_b, &server_socket, &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);
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
socket_b = wifi_direct_b.ConnectToService(
|
||||
server_socket.GetIPAddress(), server_socket.GetPort(), &flag);
|
||||
if (!socket_b.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
server_executor.Execute([&socket_a, &server_socket]() {
|
||||
socket_a = server_socket.Accept();
|
||||
if (!socket_a.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
EXPECT_TRUE(socket_a.IsValid());
|
||||
EXPECT_TRUE(socket_b.IsValid());
|
||||
InputStream& in_stream = socket_a.GetInputStream();
|
||||
OutputStream& out_stream = socket_b.GetOutputStream();
|
||||
std::string data(kData);
|
||||
EXPECT_TRUE(out_stream.Write(ByteArray(data)).Ok());
|
||||
ExceptionOr<ByteArray> read_data = in_stream.Read(kChunkSize);
|
||||
EXPECT_TRUE(read_data.ok());
|
||||
EXPECT_EQ(std::string(read_data.result()), data);
|
||||
|
||||
socket_a.Close();
|
||||
socket_b.Close();
|
||||
EXPECT_FALSE(out_stream.Write(ByteArray(data)).Ok());
|
||||
read_data = in_stream.Read(kChunkSize);
|
||||
EXPECT_FALSE(read_data.ok());
|
||||
|
||||
server_socket.Close();
|
||||
EXPECT_TRUE(wifi_direct_b.DisconnectWifiDirect());
|
||||
EXPECT_TRUE(wifi_direct_a.StopWifiDirect());
|
||||
auto* medium_b =
|
||||
env_.GetWifiDirectMedium(wifi_direct_credentials->GetSSID(), {});
|
||||
EXPECT_EQ(medium_b, nullptr);
|
||||
}
|
||||
|
||||
TEST_P(WifiDirectMediumTest, CanStartDirectGOThatOtherCanCancelConnect) {
|
||||
FeatureFlags feature_flags = GetParam();
|
||||
env_.SetFeatureFlags(feature_flags);
|
||||
WifiDirectMedium wifi_direct_a;
|
||||
WifiDirectMedium wifi_direct_b;
|
||||
|
||||
ASSERT_TRUE(wifi_direct_a.IsInterfaceValid());
|
||||
ASSERT_TRUE(wifi_direct_b.IsInterfaceValid());
|
||||
EXPECT_TRUE(wifi_direct_a.StartWifiDirect());
|
||||
HotspotCredentials* wifi_direct_credentials = wifi_direct_a.GetCredential();
|
||||
EXPECT_TRUE(
|
||||
wifi_direct_b.ConnectWifiDirect(wifi_direct_credentials->GetSSID(),
|
||||
wifi_direct_credentials->GetPassword()));
|
||||
|
||||
WifiHotspotServerSocket server_socket = wifi_direct_a.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
wifi_direct_credentials->SetIPAddress(server_socket.GetIPAddress());
|
||||
|
||||
WifiHotspotSocket socket_a;
|
||||
WifiHotspotSocket socket_b;
|
||||
EXPECT_FALSE(socket_a.IsValid());
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
|
||||
{
|
||||
CancellationFlag flag(true);
|
||||
SingleThreadExecutor server_executor;
|
||||
SingleThreadExecutor client_executor;
|
||||
client_executor.Execute(
|
||||
[&wifi_direct_b, &socket_b, &server_socket, &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);
|
||||
if (!socket_b.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
server_executor.Execute([&socket_a, &server_socket]() {
|
||||
socket_a = server_socket.Accept();
|
||||
if (!socket_a.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!feature_flags.enable_cancellation_flag) {
|
||||
EXPECT_TRUE(socket_a.IsValid());
|
||||
EXPECT_TRUE(socket_b.IsValid());
|
||||
} else {
|
||||
EXPECT_FALSE(socket_a.IsValid());
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
}
|
||||
|
||||
server_socket.Close();
|
||||
EXPECT_TRUE(wifi_direct_b.DisconnectWifiDirect());
|
||||
EXPECT_TRUE(wifi_direct_a.StopWifiDirect());
|
||||
}
|
||||
|
||||
TEST_F(WifiDirectMediumTest, CanStartDirectGOThatOtherFailConnect) {
|
||||
WifiDirectMedium wifi_direct_a;
|
||||
WifiDirectMedium wifi_direct_b;
|
||||
|
||||
ASSERT_TRUE(wifi_direct_a.IsInterfaceValid());
|
||||
ASSERT_TRUE(wifi_direct_b.IsInterfaceValid());
|
||||
EXPECT_TRUE(wifi_direct_a.StartWifiDirect());
|
||||
|
||||
EXPECT_FALSE(wifi_direct_b.ConnectWifiDirect(kSsid, kPassword));
|
||||
EXPECT_TRUE(wifi_direct_b.DisconnectWifiDirect());
|
||||
|
||||
EXPECT_TRUE(wifi_direct_a.StopWifiDirect());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
Reference in New Issue
Block a user