mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
nearbyconnections : Replace WifiLanV2 to WifiLan.
PiperOrigin-RevId: 406033177
This commit is contained in:
committed by
Copybara-Service
parent
94ef1b532b
commit
acf516189b
@@ -78,7 +78,6 @@ cc_library(
|
||||
"bluetooth_classic.cc",
|
||||
"file.cc",
|
||||
"wifi_lan.cc",
|
||||
"wifi_lan_v2.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"ble.h",
|
||||
@@ -86,7 +85,6 @@ cc_library(
|
||||
"bluetooth_classic.h",
|
||||
"webrtc.h",
|
||||
"wifi_lan.h",
|
||||
"wifi_lan_v2.h",
|
||||
],
|
||||
compatible_with = ["//buildenv/target:non_prod"],
|
||||
copts = ["-DCORE_ADAPTER_DLL"],
|
||||
@@ -150,7 +148,6 @@ cc_test(
|
||||
"scheduled_executor_test.cc",
|
||||
"single_thread_executor_test.cc",
|
||||
"wifi_lan_test.cc",
|
||||
"wifi_lan_test_v2.cc",
|
||||
],
|
||||
copts = ["-DCORE_ADAPTER_DLL"],
|
||||
shard_count = 16,
|
||||
|
||||
+99
-115
@@ -14,148 +14,132 @@
|
||||
|
||||
#include "platform/public/wifi_lan.h"
|
||||
|
||||
#include "platform/public/logging.h"
|
||||
#include "platform/public/mutex_lock.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
bool WifiLanMedium::StartAdvertising(const std::string& service_id,
|
||||
const NsdServiceInfo& nsd_service_info) {
|
||||
return impl_->StartAdvertising(service_id, nsd_service_info);
|
||||
bool WifiLanMedium::StartAdvertising(const NsdServiceInfo& nsd_service_info) {
|
||||
return impl_->StartAdvertising(nsd_service_info);
|
||||
}
|
||||
|
||||
bool WifiLanMedium::StopAdvertising(const std::string& service_id) {
|
||||
return impl_->StopAdvertising(service_id);
|
||||
bool WifiLanMedium::StopAdvertising(const NsdServiceInfo& nsd_service_info) {
|
||||
return impl_->StopAdvertising(nsd_service_info);
|
||||
}
|
||||
|
||||
bool WifiLanMedium::StartDiscovery(const std::string& service_id,
|
||||
const std::string& service_type,
|
||||
DiscoveredServiceCallback callback) {
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
discovered_service_callback_ = std::move(callback);
|
||||
services_.clear();
|
||||
if (discovery_callbacks_.contains(service_type)) {
|
||||
NEARBY_LOGS(INFO) << "WifiLan Discovery already start with service_type="
|
||||
<< service_type << "; impl=" << &GetImpl();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return impl_->StartDiscovery(
|
||||
service_id,
|
||||
{
|
||||
.service_discovered_cb =
|
||||
[this](api::WifiLanService& wifi_lan_service,
|
||||
const std::string& service_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
auto pair = services_.emplace(
|
||||
&wifi_lan_service,
|
||||
absl::make_unique<ServiceDiscoveryInfo>());
|
||||
auto& context = *pair.first->second;
|
||||
if (!pair.second) {
|
||||
NEARBY_LOG(INFO,
|
||||
"Discovering (again) service=%p, impl=%p, "
|
||||
"service_info_name=%s",
|
||||
&context.wifi_lan_service, &wifi_lan_service,
|
||||
wifi_lan_service.GetServiceInfo()
|
||||
.GetServiceName()
|
||||
.c_str());
|
||||
return;
|
||||
} else {
|
||||
context.wifi_lan_service = WifiLanService(&wifi_lan_service);
|
||||
NEARBY_LOG(
|
||||
INFO,
|
||||
"Discovering wifi_lan_service=%p, service_info_name=%s",
|
||||
&wifi_lan_service,
|
||||
wifi_lan_service.GetServiceInfo()
|
||||
.GetServiceName()
|
||||
.c_str());
|
||||
}
|
||||
discovered_service_callback_.service_discovered_cb(
|
||||
context.wifi_lan_service, service_id);
|
||||
},
|
||||
.service_lost_cb =
|
||||
[this](api::WifiLanService& wifi_lan_service,
|
||||
const std::string& service_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
if (services_.empty()) return;
|
||||
auto context = services_.find(&wifi_lan_service);
|
||||
if (context == services_.end()) return;
|
||||
NEARBY_LOG(INFO, "Removing wifi_lan_service=%p, impl=%p",
|
||||
&(context->second->wifi_lan_service),
|
||||
&wifi_lan_service);
|
||||
discovered_service_callback_.service_lost_cb(
|
||||
context->second->wifi_lan_service, service_id);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
bool WifiLanMedium::StopDiscovery(const std::string& service_id) {
|
||||
api::WifiLanMedium::DiscoveredServiceCallback api_callback = {
|
||||
.service_discovered_cb =
|
||||
[this](NsdServiceInfo service_info) {
|
||||
MutexLock lock(&mutex_);
|
||||
std::string service_type = service_info.GetServiceType();
|
||||
auto pair = discovery_services_.insert(service_type);
|
||||
if (!pair.second) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Discovering (again) service_info=" << &service_info
|
||||
<< ", service_type=" << service_type
|
||||
<< ", service_name=" << service_info.GetServiceName();
|
||||
return;
|
||||
}
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Adding service_info=" << &service_info
|
||||
<< ", service_type=" << service_type
|
||||
<< ", service_name=" << service_info.GetServiceName();
|
||||
// Callback service found.
|
||||
const auto& it = discovery_callbacks_.find(service_type);
|
||||
if (it != discovery_callbacks_.end()) {
|
||||
std::string service_id = it->second->service_id;
|
||||
DiscoveredServiceCallback medium_callback =
|
||||
it->second->medium_callback;
|
||||
medium_callback.service_discovered_cb(service_info, service_id);
|
||||
} else {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "There is no callback found for service_type="
|
||||
<< service_type;
|
||||
}
|
||||
},
|
||||
.service_lost_cb =
|
||||
[this](NsdServiceInfo service_info) {
|
||||
MutexLock lock(&mutex_);
|
||||
std::string service_type = service_info.GetServiceType();
|
||||
auto item = discovery_services_.extract(service_type);
|
||||
if (item.empty()) return;
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Removing service_info=" << &service_info
|
||||
<< ", service_type=" << service_type
|
||||
<< ", service_info_name=" << service_info.GetServiceName();
|
||||
// Callback service lost.
|
||||
const auto& it = discovery_callbacks_.find(service_type);
|
||||
if (it != discovery_callbacks_.end()) {
|
||||
std::string service_id = it->second->service_id;
|
||||
DiscoveredServiceCallback medium_callback =
|
||||
it->second->medium_callback;
|
||||
medium_callback.service_lost_cb(service_info, service_id);
|
||||
}
|
||||
},
|
||||
};
|
||||
{
|
||||
// Insert callback to the map first no matter it succeeds or not.
|
||||
MutexLock lock(&mutex_);
|
||||
discovered_service_callback_ = {};
|
||||
services_.clear();
|
||||
NEARBY_LOG(INFO, "WifiLan Discovery disabled: impl=%p", &GetImpl());
|
||||
auto pair = discovery_callbacks_.insert(
|
||||
{service_type, absl::make_unique<DiscoveryCallbackInfo>()});
|
||||
auto& context = *pair.first->second;
|
||||
context.medium_callback = std::move(callback);
|
||||
context.service_id = service_id;
|
||||
}
|
||||
return impl_->StopDiscovery(service_id);
|
||||
}
|
||||
|
||||
bool WifiLanMedium::StartAcceptingConnections(
|
||||
const std::string& service_id, AcceptedConnectionCallback callback) {
|
||||
{
|
||||
bool success = impl_->StartDiscovery(service_type, std::move(api_callback));
|
||||
if (!success) {
|
||||
// If failed, then revert back the insertion.
|
||||
MutexLock lock(&mutex_);
|
||||
accepted_connection_callback_ = std::move(callback);
|
||||
discovery_callbacks_.erase(service_type);
|
||||
}
|
||||
return impl_->StartAcceptingConnections(
|
||||
service_id,
|
||||
{
|
||||
.accepted_cb =
|
||||
[this](api::WifiLanSocket& socket,
|
||||
const std::string& service_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
auto pair = sockets_.emplace(
|
||||
&socket, absl::make_unique<AcceptedConnectionInfo>());
|
||||
auto& context = *pair.first->second;
|
||||
if (!pair.second) {
|
||||
NEARBY_LOG(INFO, "Accepting (again) socket=%p, impl=%p",
|
||||
&context.socket, &socket);
|
||||
} else {
|
||||
context.socket = WifiLanSocket(&socket);
|
||||
NEARBY_LOG(INFO, "Accepting socket=%p, impl=%p",
|
||||
&context.socket, &socket);
|
||||
}
|
||||
accepted_connection_callback_.accepted_cb(context.socket,
|
||||
service_id);
|
||||
},
|
||||
});
|
||||
NEARBY_LOGS(INFO) << "WifiLan Discovery started for service_type="
|
||||
<< service_type << ", impl=" << &GetImpl()
|
||||
<< ", success=" << success;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool WifiLanMedium::StopAcceptingConnections(const std::string& service_id) {
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
accepted_connection_callback_ = {};
|
||||
sockets_.clear();
|
||||
NEARBY_LOG(INFO, "WifiLan accepted connection disabled: impl=%p",
|
||||
&GetImpl());
|
||||
bool WifiLanMedium::StopDiscovery(const std::string& service_type) {
|
||||
MutexLock lock(&mutex_);
|
||||
if (!discovery_callbacks_.contains(service_type)) {
|
||||
return false;
|
||||
}
|
||||
return impl_->StopAcceptingConnections(service_id);
|
||||
discovery_callbacks_.erase(service_type);
|
||||
if (discovery_services_.contains(service_type)) {
|
||||
discovery_services_.erase(service_type);
|
||||
}
|
||||
NEARBY_LOGS(INFO) << "WifiLan Discovery disabled for service_type="
|
||||
<< service_type << ", impl=" << &GetImpl();
|
||||
return impl_->StopDiscovery(service_type);
|
||||
}
|
||||
|
||||
WifiLanSocket WifiLanMedium::Connect(WifiLanService& wifi_lan_service,
|
||||
const std::string& service_id,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
NEARBY_LOG(
|
||||
INFO,
|
||||
"WifiLanMedium::Connect: service=%p [impl=%p, service_info_name=%s]",
|
||||
&wifi_lan_service, &wifi_lan_service.GetImpl(),
|
||||
wifi_lan_service.GetServiceInfo().GetServiceName().c_str());
|
||||
return WifiLanSocket(impl_->Connect(wifi_lan_service.GetImpl(), service_id,
|
||||
cancellation_flag));
|
||||
WifiLanSocket WifiLanMedium::ConnectToService(
|
||||
const NsdServiceInfo& remote_service_info,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
NEARBY_LOGS(INFO) << "WifiLanMedium::ConnectToService: remote_service_name="
|
||||
<< remote_service_info.GetServiceName();
|
||||
return WifiLanSocket(
|
||||
impl_->ConnectToService(remote_service_info, cancellation_flag));
|
||||
}
|
||||
|
||||
WifiLanService WifiLanMedium::GetRemoteService(const std::string& ip_address,
|
||||
int port) {
|
||||
return WifiLanService(impl_->GetRemoteService(ip_address, port));
|
||||
}
|
||||
|
||||
std::pair<std::string, int> WifiLanMedium::GetCredentials(
|
||||
const std::string& service_id) {
|
||||
return impl_->GetCredentials(service_id);
|
||||
WifiLanSocket WifiLanMedium::ConnectToService(
|
||||
const std::string& ip_address, int port,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
NEARBY_LOGS(INFO) << "WifiLanMedium::ConnectToService: ip address="
|
||||
<< ip_address << ", port=" << port;
|
||||
return WifiLanSocket(
|
||||
impl_->ConnectToService(ip_address, port, cancellation_flag));
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -23,37 +23,20 @@
|
||||
#include "platform/base/input_stream.h"
|
||||
#include "platform/base/nsd_service_info.h"
|
||||
#include "platform/base/output_stream.h"
|
||||
#include "platform/public/logging.h"
|
||||
#include "platform/public/mutex.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// Opaque wrapper over a WifiLan service which contains |NsdServiceInfo|.
|
||||
class WifiLanService final {
|
||||
public:
|
||||
WifiLanService() = default;
|
||||
WifiLanService(const WifiLanService&) = default;
|
||||
WifiLanService& operator=(const WifiLanService&) = default;
|
||||
explicit WifiLanService(api::WifiLanService* service) : impl_(service) {}
|
||||
~WifiLanService() = default;
|
||||
|
||||
NsdServiceInfo GetServiceInfo() const { return impl_->GetServiceInfo(); }
|
||||
api::WifiLanService& GetImpl() { return *impl_; }
|
||||
bool IsValid() const { return impl_ != nullptr; }
|
||||
|
||||
private:
|
||||
api::WifiLanService* impl_;
|
||||
};
|
||||
|
||||
class WifiLanSocket final {
|
||||
public:
|
||||
WifiLanSocket() = default;
|
||||
WifiLanSocket(const WifiLanSocket&) = default;
|
||||
WifiLanSocket& operator=(const WifiLanSocket&) = default;
|
||||
explicit WifiLanSocket(api::WifiLanSocket* socket) : impl_(socket) {}
|
||||
explicit WifiLanSocket(std::unique_ptr<api::WifiLanSocket> socket)
|
||||
: impl_(socket.release()) {}
|
||||
~WifiLanSocket() = default;
|
||||
explicit WifiLanSocket(std::unique_ptr<api::WifiLanSocket> socket)
|
||||
: impl_(std::move(socket)) {}
|
||||
|
||||
// Returns the InputStream of the WifiLanSocket.
|
||||
// On error, returned stream will report Exception::kIo on any operation.
|
||||
@@ -72,10 +55,6 @@ class WifiLanSocket final {
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
Exception Close() { return impl_->Close(); }
|
||||
|
||||
WifiLanService GetRemoteWifiLanService() {
|
||||
return WifiLanService(impl_->GetRemoteWifiLanService());
|
||||
}
|
||||
|
||||
// Returns true if a socket is usable. If this method returns false,
|
||||
// it is not safe to call any other method.
|
||||
// NOTE(socket validity):
|
||||
@@ -98,84 +77,126 @@ class WifiLanSocket final {
|
||||
std::shared_ptr<api::WifiLanSocket> impl_;
|
||||
};
|
||||
|
||||
class WifiLanServerSocket final {
|
||||
public:
|
||||
WifiLanServerSocket() = default;
|
||||
WifiLanServerSocket(const WifiLanServerSocket&) = default;
|
||||
WifiLanServerSocket& operator=(const WifiLanServerSocket&) = default;
|
||||
~WifiLanServerSocket() = default;
|
||||
explicit WifiLanServerSocket(std::unique_ptr<api::WifiLanServerSocket> socket)
|
||||
: impl_(std::move(socket)) {}
|
||||
|
||||
// Returns ip address.
|
||||
std::string GetIPAddress() { return impl_->GetIPAddress(); }
|
||||
|
||||
// Returns port.
|
||||
int GetPort() { return impl_->GetPort(); }
|
||||
|
||||
// Blocks until either:
|
||||
// - at least one incoming connection request is available, or
|
||||
// - ServerSocket is closed.
|
||||
// On success, returns connected socket, ready to exchange data.
|
||||
// Returns nullptr on error.
|
||||
// Once error is reported, it is permanent, and ServerSocket has to be closed.
|
||||
WifiLanSocket Accept() {
|
||||
std::unique_ptr<api::WifiLanSocket> socket = impl_->Accept();
|
||||
if (!socket) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "WifiLanServerSocket Accept() failed on server socket: " << this;
|
||||
}
|
||||
return WifiLanSocket(std::move(socket));
|
||||
}
|
||||
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
Exception Close() {
|
||||
NEARBY_LOGS(INFO) << "WifiLanServerSocket Closing:: " << this;
|
||||
return impl_->Close();
|
||||
}
|
||||
|
||||
bool IsValid() const { return impl_ != nullptr; }
|
||||
api::WifiLanServerSocket& GetImpl() { return *impl_; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<api::WifiLanServerSocket> impl_;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the WifiLan medium.
|
||||
class WifiLanMedium final {
|
||||
class WifiLanMedium {
|
||||
public:
|
||||
using Platform = api::ImplementationPlatform;
|
||||
|
||||
struct DiscoveredServiceCallback {
|
||||
std::function<void(WifiLanService& wifi_lan_service,
|
||||
const std::string& service_id)>
|
||||
std::function<void(NsdServiceInfo service_info,
|
||||
const std::string& service_type)>
|
||||
service_discovered_cb =
|
||||
DefaultCallback<WifiLanService&, const std::string&>();
|
||||
std::function<void(WifiLanService& wifi_lan_service,
|
||||
const std::string& service_id)>
|
||||
service_lost_cb =
|
||||
DefaultCallback<WifiLanService&, const std::string&>();
|
||||
DefaultCallback<NsdServiceInfo, const std::string&>();
|
||||
std::function<void(NsdServiceInfo service_info,
|
||||
const std::string& service_type)>
|
||||
service_lost_cb = DefaultCallback<NsdServiceInfo, const std::string&>();
|
||||
};
|
||||
|
||||
struct ServiceDiscoveryInfo {
|
||||
WifiLanService wifi_lan_service;
|
||||
};
|
||||
|
||||
struct AcceptedConnectionCallback {
|
||||
std::function<void(WifiLanSocket socket, const std::string& service_id)>
|
||||
accepted_cb = DefaultCallback<WifiLanSocket, const std::string&>();
|
||||
};
|
||||
|
||||
struct AcceptedConnectionInfo {
|
||||
WifiLanSocket socket;
|
||||
struct DiscoveryCallbackInfo {
|
||||
std::string service_id;
|
||||
DiscoveredServiceCallback medium_callback;
|
||||
};
|
||||
|
||||
WifiLanMedium() : impl_(Platform::CreateWifiLanMedium()) {}
|
||||
~WifiLanMedium() = default;
|
||||
|
||||
bool StartAdvertising(const std::string& service_id,
|
||||
const NsdServiceInfo& nsd_service_info);
|
||||
bool StopAdvertising(const std::string& service_id);
|
||||
// Starts WifiLan advertising.
|
||||
//
|
||||
// nsd_service_info - NsdServiceInfo data that's advertised through mDNS
|
||||
// service.
|
||||
// On success if the service is now advertising.
|
||||
// On error if the service cannot start to advertise or the nsd_type in
|
||||
// NsdServiceInfo has been passed previously which StopAdvertising is not
|
||||
// been called.
|
||||
bool StartAdvertising(const NsdServiceInfo& nsd_service_info);
|
||||
|
||||
// Stops WifiLan advertising.
|
||||
//
|
||||
// nsd_service_info - NsdServiceInfo data that's advertised through mDNS
|
||||
// service.
|
||||
// On success if the service stops advertising.
|
||||
// On error if the service cannot stop advertising or the nsd_type in
|
||||
// NsdServiceInfo cannot be found.
|
||||
bool StopAdvertising(const NsdServiceInfo& nsd_service_info);
|
||||
|
||||
// Returns true once the WifiLan discovery has been initiated.
|
||||
bool StartDiscovery(const std::string& service_id,
|
||||
const std::string& service_type,
|
||||
DiscoveredServiceCallback callback);
|
||||
|
||||
// Returns true once WifiLan discovery for service_id is well and truly
|
||||
// stopped; after this returns, there must be no more invocations of the
|
||||
// DiscoveredServiceCallback passed in to StartDiscovery() for service_id.
|
||||
bool StopDiscovery(const std::string& service_id);
|
||||
// Returns true once service_type is associated to existing callback. If the
|
||||
// callback is the last found then WifiLan discovery will be stopped.
|
||||
bool StopDiscovery(const std::string& service_type);
|
||||
|
||||
// Returns true once WifiLan socket connection requests to service_id can be
|
||||
// accepted.
|
||||
bool StartAcceptingConnections(const std::string& service_id,
|
||||
AcceptedConnectionCallback callback);
|
||||
bool StopAcceptingConnections(const std::string& service_id);
|
||||
// Returns a new WifiLanSocket.
|
||||
// On Success, WifiLanSocket::IsValid() returns true.
|
||||
WifiLanSocket ConnectToService(const NsdServiceInfo& remote_service_info,
|
||||
CancellationFlag* cancellation_flag);
|
||||
|
||||
// Returns a new WifiLanSocket. On Success, WifiLanSocket::IsValid()
|
||||
// returns true.
|
||||
WifiLanSocket Connect(WifiLanService& wifi_lan_service,
|
||||
const std::string& service_id,
|
||||
CancellationFlag* cancellation_flag);
|
||||
// Returns a new WifiLanSocket by ip address and port.
|
||||
// On Success, WifiLanSocket::IsValid()returns true.
|
||||
WifiLanSocket ConnectToService(const std::string& ip_address, int port,
|
||||
CancellationFlag* cancellation_flag);
|
||||
|
||||
// Returns a new WifiLanServerSocket.
|
||||
// On Success, WifiLanServerSocket::IsValid() returns true.
|
||||
WifiLanServerSocket ListenForService(int port = 0) {
|
||||
return WifiLanServerSocket(impl_->ListenForService(port));
|
||||
}
|
||||
|
||||
bool IsValid() const { return impl_ != nullptr; }
|
||||
|
||||
api::WifiLanMedium& GetImpl() { return *impl_; }
|
||||
|
||||
WifiLanService GetRemoteService(const std::string& ip_address, int port);
|
||||
|
||||
std::pair<std::string, int> GetCredentials(const std::string& service_id);
|
||||
|
||||
private:
|
||||
Mutex mutex_;
|
||||
std::unique_ptr<api::WifiLanMedium> impl_;
|
||||
absl::flat_hash_map<api::WifiLanService*,
|
||||
std::unique_ptr<ServiceDiscoveryInfo>>
|
||||
services_ ABSL_GUARDED_BY(mutex_);
|
||||
absl::flat_hash_map<api::WifiLanSocket*,
|
||||
std::unique_ptr<AcceptedConnectionInfo>>
|
||||
sockets_ ABSL_GUARDED_BY(mutex_);
|
||||
DiscoveredServiceCallback discovered_service_callback_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
AcceptedConnectionCallback accepted_connection_callback_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
absl::flat_hash_map<std::string, std::unique_ptr<DiscoveryCallbackInfo>>
|
||||
discovery_callbacks_ ABSL_GUARDED_BY(mutex_);
|
||||
absl::flat_hash_set<std::string> discovery_services_ ABSL_GUARDED_BY(mutex_);
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -38,7 +38,9 @@ constexpr FeatureFlags kTestCases[] = {
|
||||
},
|
||||
};
|
||||
|
||||
constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"};
|
||||
constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000);
|
||||
constexpr absl::string_view kServiceId{"service_id"};
|
||||
constexpr absl::string_view kServiceType{"_service.tcp_"};
|
||||
constexpr absl::string_view kServiceInfoName{"Simulated service info name"};
|
||||
constexpr absl::string_view kEndpointName{"Simulated endpoint name"};
|
||||
constexpr absl::string_view kEndpointInfoKey{"n"};
|
||||
@@ -46,71 +48,81 @@ constexpr absl::string_view kEndpointInfoKey{"n"};
|
||||
class WifiLanMediumTest : public ::testing::TestWithParam<FeatureFlags> {
|
||||
protected:
|
||||
using DiscoveredServiceCallback = WifiLanMedium::DiscoveredServiceCallback;
|
||||
using AcceptedConnectionCallback = WifiLanMedium::AcceptedConnectionCallback;
|
||||
|
||||
WifiLanMediumTest() { env_.Stop(); }
|
||||
|
||||
MediumEnvironment& env_{MediumEnvironment::Instance()};
|
||||
};
|
||||
|
||||
TEST_P(WifiLanMediumTest, CanStartAcceptingConnectionsAndConnect) {
|
||||
TEST_P(WifiLanMediumTest, CanConnectToService) {
|
||||
FeatureFlags feature_flags = GetParam();
|
||||
env_.SetFeatureFlags(feature_flags);
|
||||
env_.Start();
|
||||
WifiLanMedium wifi_a;
|
||||
WifiLanMedium wifi_b;
|
||||
std::string service_id(kServiceID);
|
||||
std::string service_info_name{kServiceInfoName};
|
||||
std::string endpoint_info_name{kEndpointName};
|
||||
CountDownLatch found_latch(1);
|
||||
CountDownLatch accepted_latch(1);
|
||||
CancellationFlag flag;
|
||||
WifiLanMedium wifi_lan_a;
|
||||
WifiLanMedium wifi_lan_b;
|
||||
std::string service_id(kServiceId);
|
||||
std::string service_type(kServiceType);
|
||||
std::string service_info_name(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
CountDownLatch discovered_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
|
||||
WifiLanService* discovered_service = nullptr;
|
||||
wifi_a.StartDiscovery(
|
||||
service_id,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&found_latch, &discovered_service](
|
||||
WifiLanService& service, const std::string& service_id) {
|
||||
NEARBY_LOG(INFO, "Service discovered: %s, %p",
|
||||
service.GetServiceInfo().GetServiceName().c_str(),
|
||||
&service);
|
||||
discovered_service = &service;
|
||||
found_latch.CountDown();
|
||||
},
|
||||
});
|
||||
WifiLanServerSocket server_socket = wifi_lan_b.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
nsd_service_info.SetServiceName(service_info_name);
|
||||
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
wifi_b.StartAdvertising(service_id, nsd_service_info);
|
||||
wifi_b.StartAcceptingConnections(
|
||||
service_id,
|
||||
AcceptedConnectionCallback{
|
||||
.accepted_cb = [&accepted_latch](WifiLanSocket socket,
|
||||
const std::string& service_id) {
|
||||
NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s",
|
||||
&socket, service_id.c_str());
|
||||
accepted_latch.CountDown();
|
||||
}});
|
||||
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
|
||||
nsd_service_info.SetServiceType(service_type);
|
||||
nsd_service_info.SetIPAddress(server_socket.GetIPAddress());
|
||||
nsd_service_info.SetPort(server_socket.GetPort());
|
||||
wifi_lan_b.StartAdvertising(nsd_service_info);
|
||||
|
||||
NsdServiceInfo discovered_service_info;
|
||||
wifi_lan_a.StartDiscovery(
|
||||
service_id, service_type,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&discovered_latch, &discovered_service_info](
|
||||
NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
discovered_service_info = service_info;
|
||||
discovered_latch.CountDown();
|
||||
},
|
||||
.service_lost_cb =
|
||||
[&lost_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
lost_latch.CountDown();
|
||||
},
|
||||
});
|
||||
EXPECT_TRUE(discovered_latch.Await(absl::Milliseconds(1000)).result());
|
||||
WifiLanSocket socket_a;
|
||||
WifiLanSocket socket_b;
|
||||
EXPECT_FALSE(socket_a.IsValid());
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
{
|
||||
CancellationFlag flag;
|
||||
SingleThreadExecutor server_executor;
|
||||
SingleThreadExecutor client_executor;
|
||||
client_executor.Execute(
|
||||
[&wifi_a, &socket_a, discovered_service, &service_id, &flag]() {
|
||||
socket_a = wifi_a.Connect(*discovered_service, service_id, &flag);
|
||||
});
|
||||
client_executor.Execute([&wifi_lan_a, &socket_a,
|
||||
discovered_service_info = discovered_service_info,
|
||||
service_type, &server_socket, &flag]() {
|
||||
socket_a = wifi_lan_a.ConnectToService(discovered_service_info, &flag);
|
||||
if (!socket_a.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
server_executor.Execute([&socket_b, &server_socket]() {
|
||||
socket_b = server_socket.Accept();
|
||||
if (!socket_b.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
EXPECT_TRUE(accepted_latch.Await(absl::Milliseconds(1000)).result());
|
||||
EXPECT_TRUE(socket_a.IsValid());
|
||||
wifi_b.StopAcceptingConnections(service_id);
|
||||
wifi_b.StopAdvertising(service_id);
|
||||
wifi_a.StopDiscovery(service_id);
|
||||
EXPECT_TRUE(socket_b.IsValid());
|
||||
server_socket.Close();
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
@@ -118,68 +130,77 @@ TEST_P(WifiLanMediumTest, CanCancelConnect) {
|
||||
FeatureFlags feature_flags = GetParam();
|
||||
env_.SetFeatureFlags(feature_flags);
|
||||
env_.Start();
|
||||
WifiLanMedium wifi_a;
|
||||
WifiLanMedium wifi_b;
|
||||
std::string service_id(kServiceID);
|
||||
std::string service_info_name{kServiceInfoName};
|
||||
std::string endpoint_info_name{kEndpointName};
|
||||
CountDownLatch found_latch(1);
|
||||
CountDownLatch accepted_latch(1);
|
||||
CancellationFlag flag(true);
|
||||
WifiLanMedium wifi_lan_a;
|
||||
WifiLanMedium wifi_lan_b;
|
||||
std::string service_id(kServiceId);
|
||||
std::string service_type(kServiceType);
|
||||
std::string service_info_name(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
CountDownLatch discovered_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
|
||||
WifiLanService* discovered_service = nullptr;
|
||||
wifi_a.StartDiscovery(
|
||||
service_id,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&found_latch, &discovered_service](
|
||||
WifiLanService& service, const std::string& service_id) {
|
||||
NEARBY_LOG(INFO, "Service discovered: %s, %p",
|
||||
service.GetServiceInfo().GetServiceName().c_str(),
|
||||
&service);
|
||||
discovered_service = &service;
|
||||
found_latch.CountDown();
|
||||
},
|
||||
});
|
||||
WifiLanServerSocket server_socket = wifi_lan_b.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
nsd_service_info.SetServiceName(service_info_name);
|
||||
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
wifi_b.StartAdvertising(service_id, nsd_service_info);
|
||||
wifi_b.StartAcceptingConnections(
|
||||
service_id,
|
||||
AcceptedConnectionCallback{
|
||||
.accepted_cb = [&accepted_latch](WifiLanSocket socket,
|
||||
const std::string& service_id) {
|
||||
NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s",
|
||||
&socket, service_id.c_str());
|
||||
accepted_latch.CountDown();
|
||||
}});
|
||||
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
|
||||
nsd_service_info.SetServiceType(service_type);
|
||||
nsd_service_info.SetIPAddress(server_socket.GetIPAddress());
|
||||
nsd_service_info.SetPort(server_socket.GetPort());
|
||||
wifi_lan_b.StartAdvertising(nsd_service_info);
|
||||
|
||||
NsdServiceInfo discovered_service_info;
|
||||
wifi_lan_a.StartDiscovery(
|
||||
service_id, service_type,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&discovered_latch, &discovered_service_info](
|
||||
NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
discovered_service_info = service_info;
|
||||
discovered_latch.CountDown();
|
||||
},
|
||||
.service_lost_cb =
|
||||
[&lost_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
lost_latch.CountDown();
|
||||
},
|
||||
});
|
||||
EXPECT_TRUE(discovered_latch.Await(absl::Milliseconds(1000)).result());
|
||||
WifiLanSocket socket_a;
|
||||
WifiLanSocket 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_a, &socket_a, discovered_service, &service_id, &flag]() {
|
||||
socket_a = wifi_a.Connect(*discovered_service, service_id, &flag);
|
||||
});
|
||||
client_executor.Execute([&wifi_lan_a, &socket_a,
|
||||
discovered_service_info = discovered_service_info,
|
||||
service_type, &server_socket, &flag]() {
|
||||
socket_a = wifi_lan_a.ConnectToService(discovered_service_info, &flag);
|
||||
if (!socket_a.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
server_executor.Execute([&socket_b, &server_socket]() {
|
||||
socket_b = server_socket.Accept();
|
||||
if (!socket_b.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If FeatureFlag is disabled, Cancelled is false as no-op.
|
||||
if (!feature_flags.enable_cancellation_flag) {
|
||||
EXPECT_TRUE(accepted_latch.Await(absl::Milliseconds(1000)).result());
|
||||
EXPECT_TRUE(socket_a.IsValid());
|
||||
EXPECT_TRUE(socket_b.IsValid());
|
||||
} else {
|
||||
EXPECT_FALSE(accepted_latch.Await(absl::Milliseconds(1000)).result());
|
||||
EXPECT_FALSE(socket_a.IsValid());
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
}
|
||||
|
||||
wifi_b.StopAcceptingConnections(service_id);
|
||||
wifi_b.StopAdvertising(service_id);
|
||||
wifi_a.StopDiscovery(service_id);
|
||||
server_socket.Close();
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
@@ -188,117 +209,179 @@ INSTANTIATE_TEST_SUITE_P(ParametrisedWifiLanMediumTest, WifiLanMediumTest,
|
||||
|
||||
TEST_F(WifiLanMediumTest, ConstructorDestructorWorks) {
|
||||
env_.Start();
|
||||
WifiLanMedium wifi_a;
|
||||
WifiLanMedium wifi_b;
|
||||
WifiLanMedium wifi_lan_a;
|
||||
WifiLanMedium wifi_lan_b;
|
||||
|
||||
// Make sure we can create functional mediums.
|
||||
ASSERT_TRUE(wifi_a.IsValid());
|
||||
ASSERT_TRUE(wifi_b.IsValid());
|
||||
ASSERT_TRUE(wifi_lan_a.IsValid());
|
||||
ASSERT_TRUE(wifi_lan_b.IsValid());
|
||||
|
||||
// Make sure we can create 2 distinct mediums.
|
||||
EXPECT_NE(&wifi_a.GetImpl(), &wifi_b.GetImpl());
|
||||
EXPECT_NE(&wifi_lan_a.GetImpl(), &wifi_lan_b.GetImpl());
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanMediumTest, CanStartAdvertising) {
|
||||
env_.Start();
|
||||
WifiLanMedium wifi_a;
|
||||
WifiLanMedium wifi_b;
|
||||
std::string service_id(kServiceID);
|
||||
std::string service_info_name{kServiceInfoName};
|
||||
std::string endpoint_info_name{kEndpointName};
|
||||
CountDownLatch found_latch(1);
|
||||
WifiLanMedium wifi_lan_a;
|
||||
std::string service_type(kServiceType);
|
||||
std::string service_info_name(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
|
||||
WifiLanServerSocket server_socket = wifi_lan_a.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
nsd_service_info.SetServiceName(service_info_name);
|
||||
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
wifi_a.StartAdvertising(service_id, nsd_service_info);
|
||||
nsd_service_info.SetServiceType(service_type);
|
||||
EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info));
|
||||
EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
EXPECT_TRUE(wifi_b.StartDiscovery(
|
||||
service_id, DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&found_latch](WifiLanService& service,
|
||||
const std::string& service_id) {
|
||||
found_latch.CountDown();
|
||||
},
|
||||
}));
|
||||
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
|
||||
EXPECT_TRUE(wifi_a.StopAdvertising(service_id));
|
||||
EXPECT_TRUE(wifi_b.StopDiscovery(service_id));
|
||||
TEST_F(WifiLanMediumTest, CanStartMultipleAdvertising) {
|
||||
env_.Start();
|
||||
WifiLanMedium wifi_lan_a;
|
||||
std::string service_type_1(kServiceType);
|
||||
std::string service_type_2("_service_1.tcp_");
|
||||
std::string service_info_name_1(kServiceInfoName);
|
||||
std::string service_info_name_2(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
|
||||
WifiLanServerSocket server_socket = wifi_lan_a.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info_1;
|
||||
nsd_service_info_1.SetServiceName(service_info_name_1);
|
||||
nsd_service_info_1.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
nsd_service_info_1.SetServiceType(service_type_1);
|
||||
|
||||
NsdServiceInfo nsd_service_info_2;
|
||||
nsd_service_info_2.SetServiceName(service_info_name_2);
|
||||
nsd_service_info_2.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
nsd_service_info_2.SetServiceType(service_type_2);
|
||||
|
||||
EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info_1));
|
||||
EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info_2));
|
||||
EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info_1));
|
||||
EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info_2));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanMediumTest, CanStartDiscovery) {
|
||||
env_.Start();
|
||||
WifiLanMedium wifi_a;
|
||||
WifiLanMedium wifi_b;
|
||||
std::string service_id(kServiceID);
|
||||
std::string service_info_name{kServiceInfoName};
|
||||
std::string endpoint_info_name{kEndpointName};
|
||||
CountDownLatch found_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
WifiLanMedium wifi_lan_a;
|
||||
std::string service_id(kServiceId);
|
||||
std::string service_type(kServiceType);
|
||||
|
||||
wifi_a.StartDiscovery(service_id,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&found_latch](WifiLanService& service,
|
||||
absl::string_view service_id) {
|
||||
found_latch.CountDown();
|
||||
},
|
||||
.service_lost_cb =
|
||||
[&lost_latch](WifiLanService& service,
|
||||
absl::string_view service_id) {
|
||||
lost_latch.CountDown();
|
||||
},
|
||||
});
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
nsd_service_info.SetServiceName(service_info_name);
|
||||
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
EXPECT_TRUE(wifi_b.StartAdvertising(service_id, nsd_service_info));
|
||||
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
|
||||
EXPECT_TRUE(wifi_b.StopAdvertising(service_id));
|
||||
EXPECT_TRUE(lost_latch.Await(absl::Milliseconds(1000)).result());
|
||||
EXPECT_TRUE(wifi_a.StopDiscovery(service_id));
|
||||
EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id, service_type,
|
||||
DiscoveredServiceCallback{}));
|
||||
EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanMediumTest, CanStopDiscovery) {
|
||||
TEST_F(WifiLanMediumTest, CanStartMultipleDiscovery) {
|
||||
env_.Start();
|
||||
WifiLanMedium wifi_a;
|
||||
WifiLanMedium wifi_b;
|
||||
std::string service_id(kServiceID);
|
||||
std::string service_info_name{kServiceInfoName};
|
||||
std::string endpoint_info_name{kEndpointName};
|
||||
CountDownLatch found_latch(1);
|
||||
WifiLanMedium wifi_lan_a;
|
||||
std::string service_id_1(kServiceId);
|
||||
std::string service_id_2("service_id_2");
|
||||
std::string service_type_1(kServiceType);
|
||||
std::string service_type_2("_service_1.tcp_");
|
||||
|
||||
EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id_1, service_type_1,
|
||||
DiscoveredServiceCallback{}));
|
||||
EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id_2, service_type_2,
|
||||
DiscoveredServiceCallback{}));
|
||||
EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type_1));
|
||||
EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type_2));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanMediumTest, CanAdvertiseThatOtherMediumDiscover) {
|
||||
env_.Start();
|
||||
WifiLanMedium wifi_lan_a;
|
||||
WifiLanMedium wifi_lan_b;
|
||||
std::string service_id(kServiceId);
|
||||
std::string service_type(kServiceType);
|
||||
std::string service_info_name(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
CountDownLatch discovered_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
|
||||
wifi_a.StartDiscovery(service_id,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&found_latch](WifiLanService& service,
|
||||
absl::string_view service_id) {
|
||||
found_latch.CountDown();
|
||||
},
|
||||
.service_lost_cb =
|
||||
[&lost_latch](WifiLanService& service,
|
||||
absl::string_view service_id) {
|
||||
lost_latch.CountDown();
|
||||
},
|
||||
});
|
||||
wifi_lan_b.StartDiscovery(
|
||||
service_id, service_type,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&discovered_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
discovered_latch.CountDown();
|
||||
},
|
||||
.service_lost_cb =
|
||||
[&lost_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_id) {
|
||||
lost_latch.CountDown();
|
||||
},
|
||||
});
|
||||
|
||||
WifiLanServerSocket server_socket = wifi_lan_a.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
nsd_service_info.SetServiceName(service_info_name);
|
||||
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
nsd_service_info.SetServiceType(service_type);
|
||||
EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info));
|
||||
EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info));
|
||||
EXPECT_TRUE(lost_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(wifi_lan_b.StopDiscovery(service_type));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
EXPECT_TRUE(wifi_b.StartAdvertising(service_id, nsd_service_info));
|
||||
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
|
||||
EXPECT_TRUE(wifi_a.StopDiscovery(service_id));
|
||||
EXPECT_TRUE(wifi_b.StopAdvertising(service_id));
|
||||
EXPECT_FALSE(lost_latch.Await(absl::Milliseconds(1000)).result());
|
||||
TEST_F(WifiLanMediumTest, CanDiscoverThatOtherMediumAdvertise) {
|
||||
env_.Start();
|
||||
WifiLanMedium wifi_lan_a;
|
||||
WifiLanMedium wifi_lan_b;
|
||||
std::string service_id(kServiceId);
|
||||
std::string service_type(kServiceType);
|
||||
std::string service_info_name(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
CountDownLatch discovered_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
|
||||
wifi_lan_a.StartDiscovery(
|
||||
service_id, service_type,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&discovered_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
discovered_latch.CountDown();
|
||||
},
|
||||
.service_lost_cb =
|
||||
[&lost_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
lost_latch.CountDown();
|
||||
},
|
||||
});
|
||||
|
||||
WifiLanServerSocket server_socket = wifi_lan_a.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
nsd_service_info.SetServiceName(service_info_name);
|
||||
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
nsd_service_info.SetServiceType(service_type);
|
||||
EXPECT_TRUE(wifi_lan_b.StartAdvertising(nsd_service_info));
|
||||
EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(wifi_lan_b.StopAdvertising(nsd_service_info));
|
||||
EXPECT_TRUE(lost_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,389 +0,0 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "platform/base/medium_environment.h"
|
||||
#include "platform/public/count_down_latch.h"
|
||||
#include "platform/public/logging.h"
|
||||
#include "platform/public/wifi_lan_v2.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::Duration kWaitDuration = absl::Milliseconds(1000);
|
||||
constexpr absl::string_view kServiceId{"service_id"};
|
||||
constexpr absl::string_view kServiceType{"_service.tcp_"};
|
||||
constexpr absl::string_view kServiceInfoName{"Simulated service info name"};
|
||||
constexpr absl::string_view kEndpointName{"Simulated endpoint name"};
|
||||
constexpr absl::string_view kEndpointInfoKey{"n"};
|
||||
|
||||
class WifiLanMediumV2Test : public ::testing::TestWithParam<FeatureFlags> {
|
||||
protected:
|
||||
using DiscoveredServiceCallback = WifiLanMediumV2::DiscoveredServiceCallback;
|
||||
|
||||
WifiLanMediumV2Test() { env_.Stop(); }
|
||||
|
||||
MediumEnvironment& env_{MediumEnvironment::Instance()};
|
||||
};
|
||||
|
||||
TEST_P(WifiLanMediumV2Test, CanConnectToService) {
|
||||
FeatureFlags feature_flags = GetParam();
|
||||
env_.SetFeatureFlags(feature_flags);
|
||||
env_.Start();
|
||||
WifiLanMediumV2 wifi_lan_a;
|
||||
WifiLanMediumV2 wifi_lan_b;
|
||||
std::string service_id(kServiceId);
|
||||
std::string service_type(kServiceType);
|
||||
std::string service_info_name(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
CountDownLatch discovered_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
|
||||
WifiLanServerSocketV2 server_socket = wifi_lan_b.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
nsd_service_info.SetServiceName(service_info_name);
|
||||
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
nsd_service_info.SetServiceType(service_type);
|
||||
nsd_service_info.SetIPAddress(server_socket.GetIPAddress());
|
||||
nsd_service_info.SetPort(server_socket.GetPort());
|
||||
wifi_lan_b.StartAdvertising(nsd_service_info);
|
||||
|
||||
NsdServiceInfo discovered_service_info;
|
||||
wifi_lan_a.StartDiscovery(
|
||||
service_id, service_type,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&discovered_latch, &discovered_service_info](
|
||||
NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
discovered_service_info = service_info;
|
||||
discovered_latch.CountDown();
|
||||
},
|
||||
.service_lost_cb =
|
||||
[&lost_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
lost_latch.CountDown();
|
||||
},
|
||||
});
|
||||
EXPECT_TRUE(discovered_latch.Await(absl::Milliseconds(1000)).result());
|
||||
WifiLanSocketV2 socket_a;
|
||||
WifiLanSocketV2 socket_b;
|
||||
EXPECT_FALSE(socket_a.IsValid());
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
{
|
||||
CancellationFlag flag;
|
||||
SingleThreadExecutor server_executor;
|
||||
SingleThreadExecutor client_executor;
|
||||
client_executor.Execute([&wifi_lan_a, &socket_a,
|
||||
discovered_service_info = discovered_service_info,
|
||||
service_type, &server_socket, &flag]() {
|
||||
socket_a = wifi_lan_a.ConnectToService(discovered_service_info, &flag);
|
||||
if (!socket_a.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
server_executor.Execute([&socket_b, &server_socket]() {
|
||||
socket_b = server_socket.Accept();
|
||||
if (!socket_b.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
EXPECT_TRUE(socket_a.IsValid());
|
||||
EXPECT_TRUE(socket_b.IsValid());
|
||||
server_socket.Close();
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_P(WifiLanMediumV2Test, CanCancelConnect) {
|
||||
FeatureFlags feature_flags = GetParam();
|
||||
env_.SetFeatureFlags(feature_flags);
|
||||
env_.Start();
|
||||
WifiLanMediumV2 wifi_lan_a;
|
||||
WifiLanMediumV2 wifi_lan_b;
|
||||
std::string service_id(kServiceId);
|
||||
std::string service_type(kServiceType);
|
||||
std::string service_info_name(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
CountDownLatch discovered_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
|
||||
WifiLanServerSocketV2 server_socket = wifi_lan_b.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
nsd_service_info.SetServiceName(service_info_name);
|
||||
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
nsd_service_info.SetServiceType(service_type);
|
||||
nsd_service_info.SetIPAddress(server_socket.GetIPAddress());
|
||||
nsd_service_info.SetPort(server_socket.GetPort());
|
||||
wifi_lan_b.StartAdvertising(nsd_service_info);
|
||||
|
||||
NsdServiceInfo discovered_service_info;
|
||||
wifi_lan_a.StartDiscovery(
|
||||
service_id, service_type,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&discovered_latch, &discovered_service_info](
|
||||
NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
discovered_service_info = service_info;
|
||||
discovered_latch.CountDown();
|
||||
},
|
||||
.service_lost_cb =
|
||||
[&lost_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
lost_latch.CountDown();
|
||||
},
|
||||
});
|
||||
EXPECT_TRUE(discovered_latch.Await(absl::Milliseconds(1000)).result());
|
||||
WifiLanSocketV2 socket_a;
|
||||
WifiLanSocketV2 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_lan_a, &socket_a,
|
||||
discovered_service_info = discovered_service_info,
|
||||
service_type, &server_socket, &flag]() {
|
||||
socket_a = wifi_lan_a.ConnectToService(discovered_service_info, &flag);
|
||||
if (!socket_a.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
server_executor.Execute([&socket_b, &server_socket]() {
|
||||
socket_b = server_socket.Accept();
|
||||
if (!socket_b.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
// If FeatureFlag is disabled, Cancelled is false as no-op.
|
||||
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();
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ParametrisedWifiLanMediumTest, WifiLanMediumV2Test,
|
||||
::testing::ValuesIn(kTestCases));
|
||||
|
||||
TEST_F(WifiLanMediumV2Test, ConstructorDestructorWorks) {
|
||||
env_.Start();
|
||||
WifiLanMediumV2 wifi_lan_a;
|
||||
WifiLanMediumV2 wifi_lan_b;
|
||||
|
||||
// Make sure we can create functional mediums.
|
||||
ASSERT_TRUE(wifi_lan_a.IsValid());
|
||||
ASSERT_TRUE(wifi_lan_b.IsValid());
|
||||
|
||||
// Make sure we can create 2 distinct mediums.
|
||||
EXPECT_NE(&wifi_lan_a.GetImpl(), &wifi_lan_b.GetImpl());
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanMediumV2Test, CanStartAdvertising) {
|
||||
env_.Start();
|
||||
WifiLanMediumV2 wifi_lan_a;
|
||||
std::string service_type(kServiceType);
|
||||
std::string service_info_name(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
|
||||
WifiLanServerSocketV2 server_socket = wifi_lan_a.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
nsd_service_info.SetServiceName(service_info_name);
|
||||
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
nsd_service_info.SetServiceType(service_type);
|
||||
EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info));
|
||||
EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanMediumV2Test, CanStartMultipleAdvertising) {
|
||||
env_.Start();
|
||||
WifiLanMediumV2 wifi_lan_a;
|
||||
std::string service_type_1(kServiceType);
|
||||
std::string service_type_2("_service_1.tcp_");
|
||||
std::string service_info_name_1(kServiceInfoName);
|
||||
std::string service_info_name_2(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
|
||||
WifiLanServerSocketV2 server_socket = wifi_lan_a.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info_1;
|
||||
nsd_service_info_1.SetServiceName(service_info_name_1);
|
||||
nsd_service_info_1.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
nsd_service_info_1.SetServiceType(service_type_1);
|
||||
|
||||
NsdServiceInfo nsd_service_info_2;
|
||||
nsd_service_info_2.SetServiceName(service_info_name_2);
|
||||
nsd_service_info_2.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
nsd_service_info_2.SetServiceType(service_type_2);
|
||||
|
||||
EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info_1));
|
||||
EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info_2));
|
||||
EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info_1));
|
||||
EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info_2));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanMediumV2Test, CanStartDiscovery) {
|
||||
env_.Start();
|
||||
WifiLanMediumV2 wifi_lan_a;
|
||||
std::string service_id(kServiceId);
|
||||
std::string service_type(kServiceType);
|
||||
|
||||
EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id, service_type,
|
||||
DiscoveredServiceCallback{}));
|
||||
EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanMediumV2Test, CanStartMultipleDiscovery) {
|
||||
env_.Start();
|
||||
WifiLanMediumV2 wifi_lan_a;
|
||||
std::string service_id_1(kServiceId);
|
||||
std::string service_id_2("service_id_2");
|
||||
std::string service_type_1(kServiceType);
|
||||
std::string service_type_2("_service_1.tcp_");
|
||||
|
||||
EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id_1, service_type_1,
|
||||
DiscoveredServiceCallback{}));
|
||||
EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id_2, service_type_2,
|
||||
DiscoveredServiceCallback{}));
|
||||
EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type_1));
|
||||
EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type_2));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanMediumV2Test, CanAdvertiseThatOtherMediumDiscover) {
|
||||
env_.Start();
|
||||
WifiLanMediumV2 wifi_lan_a;
|
||||
WifiLanMediumV2 wifi_lan_b;
|
||||
std::string service_id(kServiceId);
|
||||
std::string service_type(kServiceType);
|
||||
std::string service_info_name(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
CountDownLatch discovered_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
|
||||
wifi_lan_b.StartDiscovery(
|
||||
service_id, service_type,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&discovered_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
discovered_latch.CountDown();
|
||||
},
|
||||
.service_lost_cb =
|
||||
[&lost_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_id) {
|
||||
lost_latch.CountDown();
|
||||
},
|
||||
});
|
||||
|
||||
WifiLanServerSocketV2 server_socket = wifi_lan_a.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
nsd_service_info.SetServiceName(service_info_name);
|
||||
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
nsd_service_info.SetServiceType(service_type);
|
||||
EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info));
|
||||
EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info));
|
||||
EXPECT_TRUE(lost_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(wifi_lan_b.StopDiscovery(service_type));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanMediumV2Test, CanDiscoverThatOtherMediumAdvertise) {
|
||||
env_.Start();
|
||||
WifiLanMediumV2 wifi_lan_a;
|
||||
WifiLanMediumV2 wifi_lan_b;
|
||||
std::string service_id(kServiceId);
|
||||
std::string service_type(kServiceType);
|
||||
std::string service_info_name(kServiceInfoName);
|
||||
std::string endpoint_info_name(kEndpointName);
|
||||
CountDownLatch discovered_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
|
||||
wifi_lan_a.StartDiscovery(
|
||||
service_id, service_type,
|
||||
DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&discovered_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
discovered_latch.CountDown();
|
||||
},
|
||||
.service_lost_cb =
|
||||
[&lost_latch](NsdServiceInfo service_info,
|
||||
const std::string& service_type) {
|
||||
lost_latch.CountDown();
|
||||
},
|
||||
});
|
||||
|
||||
WifiLanServerSocketV2 server_socket = wifi_lan_a.ListenForService();
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
NsdServiceInfo nsd_service_info;
|
||||
nsd_service_info.SetServiceName(service_info_name);
|
||||
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
|
||||
endpoint_info_name);
|
||||
nsd_service_info.SetServiceType(service_type);
|
||||
EXPECT_TRUE(wifi_lan_b.StartAdvertising(nsd_service_info));
|
||||
EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(wifi_lan_b.StopAdvertising(nsd_service_info));
|
||||
EXPECT_TRUE(lost_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -1,146 +0,0 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "platform/public/wifi_lan_v2.h"
|
||||
|
||||
#include "platform/public/mutex_lock.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
bool WifiLanMediumV2::StartAdvertising(const NsdServiceInfo& nsd_service_info) {
|
||||
return impl_->StartAdvertising(nsd_service_info);
|
||||
}
|
||||
|
||||
bool WifiLanMediumV2::StopAdvertising(const NsdServiceInfo& nsd_service_info) {
|
||||
return impl_->StopAdvertising(nsd_service_info);
|
||||
}
|
||||
|
||||
bool WifiLanMediumV2::StartDiscovery(const std::string& service_id,
|
||||
const std::string& service_type,
|
||||
DiscoveredServiceCallback callback) {
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
if (discovery_callbacks_.contains(service_type)) {
|
||||
NEARBY_LOGS(INFO) << "WifiLan Discovery already start with service_type="
|
||||
<< service_type << "; impl=" << &GetImpl();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
api::WifiLanMediumV2::DiscoveredServiceCallback api_callback = {
|
||||
.service_discovered_cb =
|
||||
[this](NsdServiceInfo service_info) {
|
||||
MutexLock lock(&mutex_);
|
||||
std::string service_type = service_info.GetServiceType();
|
||||
auto pair = discovery_services_.insert(service_type);
|
||||
if (!pair.second) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Discovering (again) service_info=" << &service_info
|
||||
<< ", service_type=" << service_type
|
||||
<< ", service_name=" << service_info.GetServiceName();
|
||||
return;
|
||||
}
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Adding service_info=" << &service_info
|
||||
<< ", service_type=" << service_type
|
||||
<< ", service_name=" << service_info.GetServiceName();
|
||||
// Callback service found.
|
||||
const auto& it = discovery_callbacks_.find(service_type);
|
||||
if (it != discovery_callbacks_.end()) {
|
||||
std::string service_id = it->second->service_id;
|
||||
DiscoveredServiceCallback medium_callback =
|
||||
it->second->medium_callback;
|
||||
medium_callback.service_discovered_cb(service_info, service_id);
|
||||
} else {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "There is no callback found for service_type="
|
||||
<< service_type;
|
||||
}
|
||||
},
|
||||
.service_lost_cb =
|
||||
[this](NsdServiceInfo service_info) {
|
||||
MutexLock lock(&mutex_);
|
||||
std::string service_type = service_info.GetServiceType();
|
||||
auto item = discovery_services_.extract(service_type);
|
||||
if (item.empty()) return;
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Removing service_info=" << &service_info
|
||||
<< ", service_type=" << service_type
|
||||
<< ", service_info_name=" << service_info.GetServiceName();
|
||||
// Callback service lost.
|
||||
const auto& it = discovery_callbacks_.find(service_type);
|
||||
if (it != discovery_callbacks_.end()) {
|
||||
std::string service_id = it->second->service_id;
|
||||
DiscoveredServiceCallback medium_callback =
|
||||
it->second->medium_callback;
|
||||
medium_callback.service_lost_cb(service_info, service_id);
|
||||
}
|
||||
},
|
||||
};
|
||||
{
|
||||
// Insert callback to the map first no matter it succeeds or not.
|
||||
MutexLock lock(&mutex_);
|
||||
auto pair = discovery_callbacks_.insert(
|
||||
{service_type, absl::make_unique<DiscoveryCallbackInfo>()});
|
||||
auto& context = *pair.first->second;
|
||||
context.medium_callback = std::move(callback);
|
||||
context.service_id = service_id;
|
||||
}
|
||||
|
||||
bool success = impl_->StartDiscovery(service_type, std::move(api_callback));
|
||||
if (!success) {
|
||||
// If failed, then revert back the insertion.
|
||||
MutexLock lock(&mutex_);
|
||||
discovery_callbacks_.erase(service_type);
|
||||
}
|
||||
NEARBY_LOGS(INFO) << "WifiLan Discovery started for service_type="
|
||||
<< service_type << ", impl=" << &GetImpl()
|
||||
<< ", success=" << success;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool WifiLanMediumV2::StopDiscovery(const std::string& service_type) {
|
||||
MutexLock lock(&mutex_);
|
||||
if (!discovery_callbacks_.contains(service_type)) {
|
||||
return false;
|
||||
}
|
||||
discovery_callbacks_.erase(service_type);
|
||||
if (discovery_services_.contains(service_type)) {
|
||||
discovery_services_.erase(service_type);
|
||||
}
|
||||
NEARBY_LOGS(INFO) << "WifiLan Discovery disabled for service_type="
|
||||
<< service_type << ", impl=" << &GetImpl();
|
||||
return impl_->StopDiscovery(service_type);
|
||||
}
|
||||
|
||||
WifiLanSocketV2 WifiLanMediumV2::ConnectToService(
|
||||
const NsdServiceInfo& remote_service_info,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
NEARBY_LOGS(INFO) << "WifiLanMedium::ConnectToService: remote_service_name="
|
||||
<< remote_service_info.GetServiceName();
|
||||
return WifiLanSocketV2(
|
||||
impl_->ConnectToService(remote_service_info, cancellation_flag));
|
||||
}
|
||||
|
||||
WifiLanSocketV2 WifiLanMediumV2::ConnectToService(
|
||||
const std::string& ip_address, int port,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
NEARBY_LOGS(INFO) << "WifiLanMedium::ConnectToService: ip address="
|
||||
<< ip_address << ", port=" << port;
|
||||
return WifiLanSocketV2(
|
||||
impl_->ConnectToService(ip_address, port, cancellation_flag));
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -1,206 +0,0 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_PUBLIC_WIFI_LAN_V2_H_
|
||||
#define PLATFORM_PUBLIC_WIFI_LAN_V2_H_
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "platform/api/platform.h"
|
||||
#include "platform/api/wifi_lan_v2.h"
|
||||
#include "platform/base/byte_array.h"
|
||||
#include "platform/base/cancellation_flag.h"
|
||||
#include "platform/base/input_stream.h"
|
||||
#include "platform/base/nsd_service_info.h"
|
||||
#include "platform/base/output_stream.h"
|
||||
#include "platform/public/logging.h"
|
||||
#include "platform/public/mutex.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
class WifiLanSocketV2 final {
|
||||
public:
|
||||
WifiLanSocketV2() = default;
|
||||
WifiLanSocketV2(const WifiLanSocketV2&) = default;
|
||||
WifiLanSocketV2& operator=(const WifiLanSocketV2&) = default;
|
||||
~WifiLanSocketV2() = default;
|
||||
explicit WifiLanSocketV2(std::unique_ptr<api::WifiLanSocketV2> socket)
|
||||
: impl_(std::move(socket)) {}
|
||||
|
||||
// Returns the InputStream of the WifiLanSocket.
|
||||
// On error, returned stream will report Exception::kIo on any operation.
|
||||
//
|
||||
// The returned object is not owned by the caller, and can be invalidated once
|
||||
// the WifiLanSocket object is destroyed.
|
||||
InputStream& GetInputStream() { return impl_->GetInputStream(); }
|
||||
|
||||
// Returns the OutputStream of the WifiLanSocket.
|
||||
// On error, returned stream will report Exception::kIo on any operation.
|
||||
//
|
||||
// The returned object is not owned by the caller, and can be invalidated once
|
||||
// the WifiLanSocket object is destroyed.
|
||||
OutputStream& GetOutputStream() { return impl_->GetOutputStream(); }
|
||||
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
Exception Close() { return impl_->Close(); }
|
||||
|
||||
// Returns true if a socket is usable. If this method returns false,
|
||||
// it is not safe to call any other method.
|
||||
// NOTE(socket validity):
|
||||
// Socket created by a default public constructor is not valid, because
|
||||
// it is missing platform implementation.
|
||||
// The only way to obtain a valid socket is through connection, such as
|
||||
// an object returned by WifiLanMedium::Connect
|
||||
// These methods may also return an invalid socket if connection failed for
|
||||
// any reason.
|
||||
bool IsValid() const { return impl_ != nullptr; }
|
||||
|
||||
// Returns reference to platform implementation.
|
||||
// This is used to communicate with platform code, and for debugging purposes.
|
||||
// Returned reference will remain valid for while WifiLanSocket object is
|
||||
// itself valid. Typically WifiLanSocket lifetime matches duration of the
|
||||
// connection, and is controlled by end user, since they hold the instance.
|
||||
api::WifiLanSocketV2& GetImpl() { return *impl_; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<api::WifiLanSocketV2> impl_;
|
||||
};
|
||||
|
||||
class WifiLanServerSocketV2 final {
|
||||
public:
|
||||
WifiLanServerSocketV2() = default;
|
||||
WifiLanServerSocketV2(const WifiLanServerSocketV2&) = default;
|
||||
WifiLanServerSocketV2& operator=(const WifiLanServerSocketV2&) = default;
|
||||
~WifiLanServerSocketV2() = default;
|
||||
explicit WifiLanServerSocketV2(
|
||||
std::unique_ptr<api::WifiLanServerSocketV2> socket)
|
||||
: impl_(std::move(socket)) {}
|
||||
|
||||
// Returns ip address.
|
||||
std::string GetIPAddress() { return impl_->GetIPAddress(); }
|
||||
|
||||
// Returns port.
|
||||
int GetPort() { return impl_->GetPort(); }
|
||||
|
||||
// Blocks until either:
|
||||
// - at least one incoming connection request is available, or
|
||||
// - ServerSocket is closed.
|
||||
// On success, returns connected socket, ready to exchange data.
|
||||
// Returns nullptr on error.
|
||||
// Once error is reported, it is permanent, and ServerSocket has to be closed.
|
||||
WifiLanSocketV2 Accept() {
|
||||
std::unique_ptr<api::WifiLanSocketV2> socket = impl_->Accept();
|
||||
if (!socket) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "WifiLanServerSocket Accept() failed on server socket: " << this;
|
||||
}
|
||||
return WifiLanSocketV2(std::move(socket));
|
||||
}
|
||||
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
Exception Close() {
|
||||
NEARBY_LOGS(INFO) << "WifiLanServerSocket Closing:: " << this;
|
||||
return impl_->Close();
|
||||
}
|
||||
|
||||
bool IsValid() const { return impl_ != nullptr; }
|
||||
api::WifiLanServerSocketV2& GetImpl() { return *impl_; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<api::WifiLanServerSocketV2> impl_;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the WifiLan medium.
|
||||
class WifiLanMediumV2 {
|
||||
public:
|
||||
using Platform = api::ImplementationPlatform;
|
||||
|
||||
struct DiscoveredServiceCallback {
|
||||
std::function<void(NsdServiceInfo service_info,
|
||||
const std::string& service_type)>
|
||||
service_discovered_cb =
|
||||
DefaultCallback<NsdServiceInfo, const std::string&>();
|
||||
std::function<void(NsdServiceInfo service_info,
|
||||
const std::string& service_type)>
|
||||
service_lost_cb = DefaultCallback<NsdServiceInfo, const std::string&>();
|
||||
};
|
||||
|
||||
struct DiscoveryCallbackInfo {
|
||||
std::string service_id;
|
||||
DiscoveredServiceCallback medium_callback;
|
||||
};
|
||||
|
||||
WifiLanMediumV2() : impl_(Platform::CreateWifiLanMediumV2()) {}
|
||||
~WifiLanMediumV2() = default;
|
||||
|
||||
// Starts WifiLan advertising.
|
||||
//
|
||||
// nsd_service_info - NsdServiceInfo data that's advertised through mDNS
|
||||
// service.
|
||||
// On success if the service is now advertising.
|
||||
// On error if the service cannot start to advertise or the nsd_type in
|
||||
// NsdServiceInfo has been passed previously which StopAdvertising is not
|
||||
// been called.
|
||||
bool StartAdvertising(const NsdServiceInfo& nsd_service_info);
|
||||
|
||||
// Stops WifiLan advertising.
|
||||
//
|
||||
// nsd_service_info - NsdServiceInfo data that's advertised through mDNS
|
||||
// service.
|
||||
// On success if the service stops advertising.
|
||||
// On error if the service cannot stop advertising or the nsd_type in
|
||||
// NsdServiceInfo cannot be found.
|
||||
bool StopAdvertising(const NsdServiceInfo& nsd_service_info);
|
||||
|
||||
// Returns true once the WifiLan discovery has been initiated.
|
||||
bool StartDiscovery(const std::string& service_id,
|
||||
const std::string& service_type,
|
||||
DiscoveredServiceCallback callback);
|
||||
|
||||
// Returns true once service_type is associated to existing callback. If the
|
||||
// callback is the last found then WifiLan discovery will be stopped.
|
||||
bool StopDiscovery(const std::string& service_type);
|
||||
|
||||
// Returns a new WifiLanSocket.
|
||||
// On Success, WifiLanSocket::IsValid() returns true.
|
||||
WifiLanSocketV2 ConnectToService(const NsdServiceInfo& remote_service_info,
|
||||
CancellationFlag* cancellation_flag);
|
||||
|
||||
// Returns a new WifiLanSocket by ip address and port.
|
||||
// On Success, WifiLanSocket::IsValid()returns true.
|
||||
WifiLanSocketV2 ConnectToService(const std::string& ip_address, int port,
|
||||
CancellationFlag* cancellation_flag);
|
||||
|
||||
// Returns a new WifiLanServerSocket.
|
||||
// On Success, WifiLanServerSocket::IsValid() returns true.
|
||||
WifiLanServerSocketV2 ListenForService(int port = 0) {
|
||||
return WifiLanServerSocketV2(impl_->ListenForService(port));
|
||||
}
|
||||
|
||||
bool IsValid() const { return impl_ != nullptr; }
|
||||
|
||||
api::WifiLanMediumV2& GetImpl() { return *impl_; }
|
||||
|
||||
private:
|
||||
Mutex mutex_;
|
||||
std::unique_ptr<api::WifiLanMediumV2> impl_;
|
||||
absl::flat_hash_map<std::string, std::unique_ptr<DiscoveryCallbackInfo>>
|
||||
discovery_callbacks_ ABSL_GUARDED_BY(mutex_);
|
||||
absl::flat_hash_set<std::string> discovery_services_ ABSL_GUARDED_BY(mutex_);
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_PUBLIC_WIFI_LAN_V2_H_
|
||||
Reference in New Issue
Block a user