mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Implementation g3 medium/Environment/platform layer unit test for WIFI Hotspot
PiperOrigin-RevId: 443304661
This commit is contained in:
@@ -55,6 +55,7 @@ cc_library(
|
||||
"ble_v2.cc",
|
||||
"bluetooth_adapter.cc",
|
||||
"bluetooth_classic.cc",
|
||||
"wifi_hotspot.cc",
|
||||
"wifi_lan.cc",
|
||||
],
|
||||
hdrs = [
|
||||
@@ -62,6 +63,7 @@ cc_library(
|
||||
"ble_v2.h",
|
||||
"bluetooth_adapter.h",
|
||||
"bluetooth_classic.h",
|
||||
"wifi_hotspot.h",
|
||||
"wifi_lan.h",
|
||||
],
|
||||
defines = ["NO_WEBRTC"],
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "internal/platform/implementation/g3/scheduled_executor.h"
|
||||
#include "internal/platform/implementation/g3/single_thread_executor.h"
|
||||
#include "internal/platform/implementation/g3/wifi_lan.h"
|
||||
#include "internal/platform/implementation/g3/wifi_hotspot.h"
|
||||
#include "internal/platform/implementation/shared/file.h"
|
||||
#include "internal/platform/implementation/wifi.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
@@ -212,7 +213,7 @@ std::unique_ptr<WifiLanMedium> ImplementationPlatform::CreateWifiLanMedium() {
|
||||
|
||||
std::unique_ptr<WifiHotspotMedium>
|
||||
ImplementationPlatform::CreateWifiHotspotMedium() {
|
||||
return nullptr;
|
||||
return std::make_unique<g3::WifiHotspotMedium>();
|
||||
}
|
||||
|
||||
#ifndef NO_WEBRTC
|
||||
|
||||
@@ -0,0 +1,342 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/platform/implementation/g3/wifi_hotspot.h"
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/implementation/wifi_hotspot.h"
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/platform/nsd_service_info.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
|
||||
// Code for WifiHotspotSocket
|
||||
WifiHotspotSocket::~WifiHotspotSocket() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
DoClose();
|
||||
}
|
||||
|
||||
void WifiHotspotSocket::Connect(WifiHotspotSocket& other) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
remote_socket_ = &other;
|
||||
input_ = other.output_;
|
||||
}
|
||||
|
||||
InputStream& WifiHotspotSocket::GetInputStream() {
|
||||
auto* remote_socket = GetRemoteSocket();
|
||||
CHECK(remote_socket != nullptr);
|
||||
return remote_socket->GetLocalInputStream();
|
||||
}
|
||||
|
||||
OutputStream& WifiHotspotSocket::GetOutputStream() {
|
||||
return GetLocalOutputStream();
|
||||
}
|
||||
|
||||
WifiHotspotSocket* WifiHotspotSocket::GetRemoteSocket() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return remote_socket_;
|
||||
}
|
||||
|
||||
bool WifiHotspotSocket::IsConnected() const {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return IsConnectedLocked();
|
||||
}
|
||||
|
||||
bool WifiHotspotSocket::IsClosed() const {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return closed_;
|
||||
}
|
||||
|
||||
Exception WifiHotspotSocket::Close() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
DoClose();
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
void WifiHotspotSocket::DoClose() {
|
||||
if (!closed_) {
|
||||
remote_socket_ = nullptr;
|
||||
output_->GetOutputStream().Close();
|
||||
output_->GetInputStream().Close();
|
||||
input_->GetOutputStream().Close();
|
||||
input_->GetInputStream().Close();
|
||||
closed_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool WifiHotspotSocket::IsConnectedLocked() const { return input_ != nullptr; }
|
||||
|
||||
InputStream& WifiHotspotSocket::GetLocalInputStream() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return output_->GetInputStream();
|
||||
}
|
||||
|
||||
OutputStream& WifiHotspotSocket::GetLocalOutputStream() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return output_->GetOutputStream();
|
||||
}
|
||||
|
||||
// Code for WifiHotspotServerSocket
|
||||
std::string WifiHotspotServerSocket::GetName(absl::string_view ip_address,
|
||||
int port) {
|
||||
return absl::StrCat(ip_address, ":", port);
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiHotspotSocket> WifiHotspotServerSocket::Accept() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
while (!closed_ && pending_sockets_.empty()) {
|
||||
cond_.Wait(&mutex_);
|
||||
}
|
||||
// whether or not we were running in the wait loop, return early if closed.
|
||||
if (closed_) return {};
|
||||
auto* remote_socket =
|
||||
pending_sockets_.extract(pending_sockets_.begin()).value();
|
||||
CHECK(remote_socket);
|
||||
|
||||
auto local_socket = std::make_unique<WifiHotspotSocket>();
|
||||
local_socket->Connect(*remote_socket);
|
||||
remote_socket->Connect(*local_socket);
|
||||
cond_.SignalAll();
|
||||
return local_socket;
|
||||
}
|
||||
|
||||
bool WifiHotspotServerSocket::Connect(WifiHotspotSocket& socket) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
if (closed_) return false;
|
||||
if (socket.IsConnected()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "Failed to connect to WifiHotspot server socket: already connected";
|
||||
return true; // already connected.
|
||||
}
|
||||
// add client socket to the pending list
|
||||
pending_sockets_.insert(&socket);
|
||||
cond_.SignalAll();
|
||||
while (!socket.IsConnected()) {
|
||||
cond_.Wait(&mutex_);
|
||||
if (closed_) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WifiHotspotServerSocket::SetCloseNotifier(std::function<void()> notifier) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
close_notifier_ = std::move(notifier);
|
||||
}
|
||||
|
||||
WifiHotspotServerSocket::~WifiHotspotServerSocket() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
DoClose();
|
||||
}
|
||||
|
||||
Exception WifiHotspotServerSocket::Close() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return DoClose();
|
||||
}
|
||||
|
||||
Exception WifiHotspotServerSocket::DoClose() {
|
||||
bool should_notify = !closed_;
|
||||
closed_ = true;
|
||||
if (should_notify) {
|
||||
cond_.SignalAll();
|
||||
if (close_notifier_) {
|
||||
auto notifier = std::move(close_notifier_);
|
||||
mutex_.Unlock();
|
||||
// Notifier may contain calls to public API, and may cause deadlock, if
|
||||
// mutex_ is held during the call.
|
||||
notifier();
|
||||
mutex_.Lock();
|
||||
}
|
||||
}
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
// Code for WifiHotspotMedium
|
||||
WifiHotspotMedium::WifiHotspotMedium() {
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.RegisterWifiHotspotMedium(*this);
|
||||
}
|
||||
|
||||
WifiHotspotMedium::~WifiHotspotMedium() {
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.UnregisterWifiHotspotMedium(*this);
|
||||
}
|
||||
|
||||
bool WifiHotspotMedium::StartWifiHotspot(
|
||||
HotspotCredentials* hotspot_credentials) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
|
||||
std::string ssid = absl::StrCat("DIRECT-", Prng().NextUint32());
|
||||
hotspot_credentials->SetSSID(ssid);
|
||||
std::string password = absl::StrFormat("%08x", Prng().NextUint32());
|
||||
hotspot_credentials->SetPassword(password);
|
||||
|
||||
NEARBY_LOGS(INFO) << "G3 StartWifiHotspot: ssid=" << ssid
|
||||
<< ", password:" << password;
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.UpdateWifiHotspotMediumForStartOrConnect(*this, hotspot_credentials,
|
||||
/*is_ap=*/true, /*enabled=*/true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiHotspotMedium::StopWifiHotspot() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(INFO) << "G3 StopWifiHotspot";
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.UpdateWifiHotspotMediumForStartOrConnect(*this, /*credentials*/nullptr,
|
||||
/*is_ap=*/true,
|
||||
/*enabled=*/false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiHotspotMedium::ConnectWifiHotspot(
|
||||
HotspotCredentials* hotspot_credentials) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
|
||||
NEARBY_LOGS(INFO) << "G3 ConnectWifiHotspot: ssid="
|
||||
<< hotspot_credentials->GetSSID()
|
||||
<< ", password:" << hotspot_credentials->GetPassword();
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
auto* remote_medium = static_cast<WifiHotspotMedium*>(
|
||||
env.GetWifiHotspotMedium(hotspot_credentials->GetSSID(), {}));
|
||||
if (!remote_medium) {
|
||||
env.UpdateWifiHotspotMediumForStartOrConnect(*this, hotspot_credentials,
|
||||
/*is_ap=*/false, /*enabled=*/false);
|
||||
return false;
|
||||
}
|
||||
|
||||
env.UpdateWifiHotspotMediumForStartOrConnect(*this, hotspot_credentials,
|
||||
/*is_ap=*/false, /*enabled=*/true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiHotspotMedium::DisconnectWifiHotspot() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
|
||||
NEARBY_LOGS(INFO) << "G3 DisconnectWifiHotspot";
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.UpdateWifiHotspotMediumForStartOrConnect(*this, /*credentials*/nullptr,
|
||||
/*is_ap=*/false, /*enabled=*/false);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiHotspotSocket> WifiHotspotMedium::ConnectToService(
|
||||
absl::string_view ip_address, int port,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
std::string socket_name = WifiHotspotServerSocket::GetName(ip_address, port);
|
||||
NEARBY_LOGS(INFO) << "G3 WifiHotspot 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<WifiHotspotMedium*>(
|
||||
env.GetWifiHotspotMedium({}, ip_address));
|
||||
if (remote_medium == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
WifiHotspotServerSocket* server_socket = nullptr;
|
||||
NEARBY_LOGS(INFO) << "G3 WifiHotspot 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 WifiHotspot Failed to find WifiHotspot Server "
|
||||
"socket: socket_name="
|
||||
<< socket_name;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
if (cancellation_flag->Cancelled()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "G3 WifiHotspot Connect: Has been cancelled: socket_name="
|
||||
<< socket_name;
|
||||
return {};
|
||||
}
|
||||
|
||||
CancellationFlagListener listener(cancellation_flag, [&server_socket]() {
|
||||
NEARBY_LOGS(INFO) << "G3 WifiHotspot Cancel Connect.";
|
||||
if (server_socket != nullptr) {
|
||||
server_socket->Close();
|
||||
}
|
||||
});
|
||||
|
||||
auto socket = std::make_unique<WifiHotspotSocket>();
|
||||
// Finally, Request to connect to this socket.
|
||||
if (!server_socket->Connect(*socket)) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "G3 WifiHotspot Failed to connect to existing WifiHotspot "
|
||||
"Server socket: name="
|
||||
<< socket_name;
|
||||
return {};
|
||||
}
|
||||
NEARBY_LOGS(INFO) << "G3 WifiHotspot ConnectToService: connected: socket="
|
||||
<< socket.get();
|
||||
return socket;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiHotspotServerSocket>
|
||||
WifiHotspotMedium::ListenForService(int port) {
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
auto server_socket = std::make_unique<WifiHotspotServerSocket>();
|
||||
|
||||
std::string dot_decimal_ip;
|
||||
std::string ip_address = env.GetFakeIPAddress();
|
||||
if (ip_address.empty())
|
||||
return nullptr;
|
||||
|
||||
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 WifiHotspot 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
|
||||
@@ -0,0 +1,226 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef PLATFORM_IMPL_G3_WIFI_HOTSPOT_H_
|
||||
#define PLATFORM_IMPL_G3_WIFI_HOTSPOT_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/implementation/wifi_hotspot.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/implementation/g3/multi_thread_executor.h"
|
||||
#include "internal/platform/implementation/g3/pipe.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
|
||||
class WifiHotspotMedium;
|
||||
|
||||
class WifiHotspotSocket : public api::WifiHotspotSocket {
|
||||
public:
|
||||
WifiHotspotSocket() = default;
|
||||
~WifiHotspotSocket() override;
|
||||
WifiHotspotSocket(const WifiHotspotSocket&) = default;
|
||||
WifiHotspotSocket(WifiHotspotSocket&&) = default;
|
||||
WifiHotspotSocket& operator=(const WifiHotspotSocket&) = default;
|
||||
WifiHotspotSocket& operator=(WifiHotspotSocket&&) = default;
|
||||
|
||||
// Connect to another WifiHotspotSocket, to form a functional low-level
|
||||
// channel. from this point on, and until Close is called, connection exists.
|
||||
void Connect(WifiHotspotSocket& other) ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns the InputStream of the WifiHotspotSocket.
|
||||
// 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 WifiHotspotSocket object is destroyed.
|
||||
InputStream& GetInputStream() override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns the OutputStream of the WifiHotspotSocket.
|
||||
// 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 WifiHotspotSocket object is destroyed.
|
||||
OutputStream& GetOutputStream() override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns address of a remote WifiHotspotSocket or nullptr.
|
||||
WifiHotspotSocket* GetRemoteSocket() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns true if connection exists to the (possibly closed) remote socket.
|
||||
bool IsConnected() const ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns true if socket is closed.
|
||||
bool IsClosed() const ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
Exception Close() override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
void DoClose() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
// Returns true if connection exists to the (possibly closed) remote socket.
|
||||
bool IsConnectedLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
// Returns InputStream of our side of a connection.
|
||||
// This is what the remote side is supposed to read from.
|
||||
// This is a helper for GetInputStream() method.
|
||||
InputStream& GetLocalInputStream() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns OutputStream of our side of a connection.
|
||||
// This is what the local size is supposed to write to.
|
||||
// This is a helper for GetOutputStream() method.
|
||||
OutputStream& GetLocalOutputStream() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Output pipe is initialized by constructor, it remains always valid, until
|
||||
// it is closed. it represents output part of a local socket. Input part of a
|
||||
// local socket comes from the peer socket, after connection.
|
||||
std::shared_ptr<Pipe> output_{new Pipe};
|
||||
std::shared_ptr<Pipe> input_;
|
||||
mutable absl::Mutex mutex_;
|
||||
WifiHotspotSocket* remote_socket_ ABSL_GUARDED_BY(mutex_) = nullptr;
|
||||
bool closed_ ABSL_GUARDED_BY(mutex_) = false;
|
||||
};
|
||||
|
||||
// WifiHotspotServerSocket provides the support to server socket, this server
|
||||
// socket accepts connection from clients.
|
||||
class WifiHotspotServerSocket : public api::WifiHotspotServerSocket {
|
||||
public:
|
||||
~WifiHotspotServerSocket() override;
|
||||
|
||||
static std::string GetName(absl::string_view ip_address, int port);
|
||||
|
||||
std::string GetIPAddress() const override ABSL_LOCKS_EXCLUDED(mutex_) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return ip_address_;
|
||||
}
|
||||
|
||||
void SetIPAddress(const std::string& ip_address) ABSL_LOCKS_EXCLUDED(mutex_) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
ip_address_ = ip_address;
|
||||
}
|
||||
|
||||
int GetPort() const override ABSL_LOCKS_EXCLUDED(mutex_) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return port_;
|
||||
}
|
||||
|
||||
void SetPort(int port) ABSL_LOCKS_EXCLUDED(mutex_) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
port_ = port;
|
||||
}
|
||||
|
||||
// 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.
|
||||
std::unique_ptr<api::WifiHotspotSocket> Accept() override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Blocks until either:
|
||||
// - connection is available, or
|
||||
// - server socket is closed, or
|
||||
// - error happens.
|
||||
//
|
||||
// Called by the client side of a connection.
|
||||
// Returns true, if socket is successfully connected.
|
||||
bool Connect(WifiHotspotSocket& socket) ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Called by the server side of a connection before passing ownership of
|
||||
// WifiHotspotServerSocker to user, to track validity of a pointer to this
|
||||
// server socket.
|
||||
void SetCloseNotifier(std::function<void()> notifier)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
// Calls close_notifier if it was previously set, and marks socket as closed.
|
||||
Exception Close() override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
// Retrieves IP addresses from local machine
|
||||
std::vector<std::string> GetIpAddresses() const;
|
||||
std::string GetHotspotIpAddresses() const;
|
||||
|
||||
Exception DoClose() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
mutable absl::Mutex mutex_;
|
||||
std::string ip_address_ ABSL_GUARDED_BY(mutex_);
|
||||
int port_ ABSL_GUARDED_BY(mutex_);
|
||||
absl::CondVar cond_;
|
||||
absl::flat_hash_set<WifiHotspotSocket*> pending_sockets_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
std::function<void()> close_notifier_ ABSL_GUARDED_BY(mutex_);
|
||||
bool closed_ ABSL_GUARDED_BY(mutex_) = false;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the WifiHotspot medium.
|
||||
class WifiHotspotMedium : public api::WifiHotspotMedium {
|
||||
public:
|
||||
WifiHotspotMedium();
|
||||
~WifiHotspotMedium() override;
|
||||
|
||||
WifiHotspotMedium(const WifiHotspotMedium&) = delete;
|
||||
WifiHotspotMedium(WifiHotspotMedium&&) = delete;
|
||||
WifiHotspotMedium& operator=(const WifiHotspotMedium&) = delete;
|
||||
WifiHotspotMedium& operator=(WifiHotspotMedium&&) = delete;
|
||||
|
||||
// Discoverer connects to server socket
|
||||
std::unique_ptr<api::WifiHotspotSocket> ConnectToService(
|
||||
absl::string_view ip_address, int port,
|
||||
CancellationFlag* cancellation_flag) override;
|
||||
|
||||
// Advertiser starts to listen on server socket
|
||||
std::unique_ptr<api::WifiHotspotServerSocket> ListenForService(
|
||||
int port) override;
|
||||
|
||||
// Advertiser start WIFI Hotspot with specific Crendentials
|
||||
bool StartWifiHotspot(HotspotCredentials* hotspot_credentials) override;
|
||||
// Advertiser stop the current WIFI Hotspot
|
||||
bool StopWifiHotspot() override;
|
||||
// Discoverer connects to the Hotspot
|
||||
bool ConnectWifiHotspot(HotspotCredentials* hotspot_credentials) override;
|
||||
// Discoverer disconnects from the Hotspot
|
||||
bool DisconnectWifiHotspot() override;
|
||||
|
||||
std::optional<std::pair<std::int32_t, std::int32_t>> GetDynamicPortRange()
|
||||
override {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
// Gets error message from exception pointer
|
||||
// std::string GetErrorMessage(std::exception_ptr eptr);
|
||||
|
||||
// Protects to access some members
|
||||
absl::Mutex mutex_;
|
||||
|
||||
absl::flat_hash_map<std::string, WifiHotspotServerSocket*> server_sockets_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
};
|
||||
|
||||
|
||||
} // namespace g3
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_IMPL_G3_WIFI_HOTSPOT_H_
|
||||
Reference in New Issue
Block a user