mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Wi-Fi Direct Service Implementation(7)
PiperOrigin-RevId: 834584965
This commit is contained in:
@@ -19,12 +19,14 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/log/check.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/logging.h"
|
||||
@@ -110,6 +112,14 @@ Exception WifiDirectServerSocket::DoClose() {
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
void WifiDirectServerSocket::PopulateWifiDirectCredentials(
|
||||
WifiDirectCredentials& wifi_direct_credentials) {
|
||||
absl::MutexLock lock(mutex_);
|
||||
wifi_direct_credentials.SetGateway(ip_address_);
|
||||
wifi_direct_credentials.SetPort(port_);
|
||||
}
|
||||
|
||||
|
||||
// Code for WifiDirectMedium
|
||||
WifiDirectMedium::WifiDirectMedium() {
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
@@ -125,13 +135,13 @@ bool WifiDirectMedium::StartWifiDirect(
|
||||
WifiDirectCredentials* wifi_direct_credentials) {
|
||||
absl::MutexLock lock(mutex_);
|
||||
|
||||
std::string ssid = absl::StrCat("DIRECT-", Prng().NextUint32());
|
||||
wifi_direct_credentials->SetSSID(ssid);
|
||||
std::string password = absl::StrFormat("%08x", Prng().NextUint32());
|
||||
wifi_direct_credentials->SetPassword(password);
|
||||
std::string service_name = absl::StrCat("NC-", Prng().NextUint32());
|
||||
wifi_direct_credentials->SetServiceName(service_name);
|
||||
std::string pin = absl::StrFormat("%04x", Prng().NextUint32());
|
||||
wifi_direct_credentials->SetPin(pin);
|
||||
|
||||
LOG(INFO) << "G3 StartWifiDirect GO: ssid=" << ssid
|
||||
<< ", password:" << password;
|
||||
LOG(INFO) << "G3 StartWifiDirect GO: service_name:" << service_name
|
||||
<< ", pin:" << pin;
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, wifi_direct_credentials,
|
||||
@@ -152,24 +162,24 @@ bool WifiDirectMedium::StopWifiDirect() {
|
||||
}
|
||||
|
||||
bool WifiDirectMedium::ConnectWifiDirect(
|
||||
WifiDirectCredentials* wifi_direct_credentials) {
|
||||
const WifiDirectCredentials& wifi_direct_credentials) {
|
||||
absl::MutexLock lock(mutex_);
|
||||
|
||||
LOG(INFO) << "G3 ConnectWifiDirect : ssid="
|
||||
<< wifi_direct_credentials->GetSSID()
|
||||
<< ", password:" << wifi_direct_credentials->GetPassword();
|
||||
LOG(INFO) << "G3 ConnectWifiDirect : service_name:"
|
||||
<< wifi_direct_credentials.GetServiceName()
|
||||
<< ", pin:" << wifi_direct_credentials.GetPin();
|
||||
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
auto* remote_medium = static_cast<WifiDirectMedium*>(
|
||||
env.GetWifiDirectMedium(wifi_direct_credentials->GetSSID(), {}));
|
||||
env.GetWifiDirectMedium(wifi_direct_credentials.GetServiceName(), ""));
|
||||
if (!remote_medium) {
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, wifi_direct_credentials,
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, &wifi_direct_credentials,
|
||||
/*is_go=*/false,
|
||||
/*enabled=*/false);
|
||||
return false;
|
||||
}
|
||||
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, wifi_direct_credentials,
|
||||
env.UpdateWifiDirectMediumForStartOrConnect(*this, &wifi_direct_credentials,
|
||||
/*is_go=*/false,
|
||||
/*enabled=*/true);
|
||||
return true;
|
||||
@@ -198,7 +208,7 @@ std::unique_ptr<api::WifiDirectSocket> WifiDirectMedium::ConnectToService(
|
||||
auto* remote_medium =
|
||||
static_cast<WifiDirectMedium*>(env.GetWifiDirectMedium({}, ip_address));
|
||||
if (remote_medium == nullptr) {
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
WifiDirectServerSocket* server_socket = nullptr;
|
||||
@@ -214,21 +224,32 @@ std::unique_ptr<api::WifiDirectSocket> WifiDirectMedium::ConnectToService(
|
||||
LOG(ERROR) << "G3 WifiDirect Failed to find WifiDirect Server "
|
||||
"socket: socket_name="
|
||||
<< socket_name;
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
if (cancellation_flag->Cancelled()) {
|
||||
LOG(ERROR) << "G3 WifiDirect Connect: Has been cancelled: socket_name="
|
||||
<< socket_name;
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
CancellationFlagListener listener(cancellation_flag, [&server_socket]() {
|
||||
LOG(INFO) << "G3 WifiDirect Cancel Connect.";
|
||||
if (server_socket != nullptr) {
|
||||
server_socket->Close();
|
||||
}
|
||||
});
|
||||
|
||||
auto socket = std::make_unique<WifiDirectSocket>();
|
||||
// Finally, Request to connect to this socket.
|
||||
|
||||
server_socket->Connect(*socket);
|
||||
LOG(INFO) << "G3 WifiDirect GC ConnectToService: connected: socket="
|
||||
if (!server_socket->Connect(*socket)) {
|
||||
LOG(ERROR) << "G3 WifiDirect Failed to connect to existing WifiDirect "
|
||||
"Server socket: name="
|
||||
<< socket_name;
|
||||
return {};
|
||||
}
|
||||
LOG(INFO) << "G3 WifiDirect ConnectToService: connected: socket="
|
||||
<< socket.get();
|
||||
return socket;
|
||||
}
|
||||
@@ -247,9 +268,10 @@ std::unique_ptr<api::WifiDirectServerSocket> WifiDirectMedium::ListenForService(
|
||||
dot_decimal_ip.pop_back();
|
||||
|
||||
server_socket->SetIPAddress(dot_decimal_ip);
|
||||
server_socket->SetPort(port == 0 ? env.GetFakePort() : port);
|
||||
std::string socket_name = WifiDirectServerSocket::GetName(
|
||||
server_socket->GetIPAddress(), server_socket->GetPort());
|
||||
int port_to_use = port == 0 ? env.GetFakePort() : port;
|
||||
server_socket->SetPort(port_to_use);
|
||||
std::string socket_name =
|
||||
WifiDirectServerSocket::GetName(dot_decimal_ip, port_to_use);
|
||||
server_socket->SetCloseNotifier([this, socket_name]() {
|
||||
absl::MutexLock lock(mutex_);
|
||||
server_sockets_.erase(socket_name);
|
||||
|
||||
@@ -15,17 +15,26 @@
|
||||
#ifndef PLATFORM_IMPL_G3_WIFI_DIRECT_H_
|
||||
#define PLATFORM_IMPL_G3_WIFI_DIRECT_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/g3/multi_thread_executor.h"
|
||||
#include "internal/platform/implementation/g3/socket_base.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
@@ -112,6 +121,12 @@ class WifiDirectServerSocket : public api::WifiDirectServerSocket {
|
||||
// Calls close_notifier if it was previously set, and marks socket as closed.
|
||||
Exception Close() override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Populates the provided `wifi_direct_credentials` with the IP address
|
||||
// and port of this server socket.
|
||||
void PopulateWifiDirectCredentials(
|
||||
WifiDirectCredentials& wifi_direct_credentials) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
// Retrieves IP addresses from local machine
|
||||
std::vector<std::string> GetIpAddresses() const;
|
||||
@@ -158,7 +173,7 @@ class WifiDirectMedium : public api::WifiDirectMedium {
|
||||
bool StopWifiDirect() override;
|
||||
// Discoverer connects to the WiFiDirect GO
|
||||
bool ConnectWifiDirect(
|
||||
WifiDirectCredentials* wifi_direct_credentials) override;
|
||||
const WifiDirectCredentials& wifi_direct_credentials) override;
|
||||
// Discoverer disconnects from the WiFiDirect GO
|
||||
bool DisconnectWifiDirect() override;
|
||||
|
||||
|
||||
@@ -15,11 +15,15 @@
|
||||
#ifndef PLATFORM_API_WIFI_DIRECT_H_
|
||||
#define PLATFORM_API_WIFI_DIRECT_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
@@ -67,6 +71,11 @@ class WifiDirectServerSocket {
|
||||
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
virtual Exception Close() = 0;
|
||||
|
||||
// Populates the WifiDirect credentials with the server socket's service
|
||||
// addresses and ports.
|
||||
virtual void PopulateWifiDirectCredentials(
|
||||
WifiDirectCredentials& wifi_direct_credentials) = 0;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the WifiLan medium.
|
||||
@@ -104,7 +113,7 @@ class WifiDirectMedium {
|
||||
|
||||
// Client device connect to a softAP with specified credential.
|
||||
virtual bool ConnectWifiDirect(
|
||||
WifiDirectCredentials* wifi_direct_credentials) = 0;
|
||||
const WifiDirectCredentials& wifi_direct_credentials) = 0;
|
||||
virtual bool DisconnectWifiDirect() = 0;
|
||||
|
||||
// Returns the port range as a pair of min and max port.
|
||||
|
||||
@@ -74,8 +74,8 @@
|
||||
#include "internal/platform/implementation/windows/string_utils.h"
|
||||
#include "internal/platform/implementation/windows/submittable_executor.h"
|
||||
#include "internal/platform/implementation/windows/timer.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/implementation/windows/wifi.h"
|
||||
#include "internal/platform/implementation/windows/wifi_direct.h"
|
||||
#include "internal/platform/implementation/windows/wifi_hotspot.h"
|
||||
#include "internal/platform/implementation/windows/wifi_lan.h"
|
||||
#include "internal/platform/logging.h"
|
||||
@@ -284,7 +284,7 @@ ImplementationPlatform::CreateWifiHotspotMedium() {
|
||||
|
||||
std::unique_ptr<WifiDirectMedium>
|
||||
ImplementationPlatform::CreateWifiDirectMedium() {
|
||||
return nullptr;
|
||||
return std::make_unique<windows::WifiDirectMedium>();
|
||||
}
|
||||
|
||||
// TODO(b/261663238) replace with real implementation.
|
||||
|
||||
@@ -29,18 +29,20 @@
|
||||
// Nearby connections headers
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/implementation/windows/nearby_client_socket.h"
|
||||
#include "internal/platform/implementation/windows/nearby_server_socket.h"
|
||||
#include "internal/platform/implementation/windows/socket_address.h"
|
||||
#include "internal/platform/implementation/windows/submittable_executor.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
// WinRT headers
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Enumeration.h"
|
||||
@@ -78,10 +80,10 @@ using ::winrt::Windows::Foundation::AsyncStatus;
|
||||
using ::winrt::Windows::Foundation::IInspectable;
|
||||
|
||||
// WifiDirectSocket wraps the socket functions to read and write stream.
|
||||
// In WiFi HOTSPOT, A WifiDirectSocket will be passed to
|
||||
// On WiFiDirect GO serverside, a WifiDirectSocket will be passed to
|
||||
// StartAcceptingConnections's callback when Winsock Server Socket receives a
|
||||
// new connection. When call API to connect to remote WiFi Hotspot service, also
|
||||
// will return a WifiDirectSocket to caller.
|
||||
// new connection. When client side call API to connect to remote WiFi
|
||||
// WifiDirect GO service, it will return a WifiDirectServiceSocket to caller.
|
||||
class WifiDirectSocket : public api::WifiDirectSocket {
|
||||
public:
|
||||
WifiDirectSocket();
|
||||
@@ -113,42 +115,6 @@ class WifiDirectSocket : public api::WifiDirectSocket {
|
||||
}
|
||||
|
||||
private:
|
||||
// A simple wrapper to handle input stream of socket
|
||||
class SocketInputStream : public InputStream {
|
||||
public:
|
||||
explicit SocketInputStream(NearbyClientSocket* absl_nonnull client_socket)
|
||||
: client_socket_(client_socket) {}
|
||||
~SocketInputStream() override = default;
|
||||
|
||||
ExceptionOr<ByteArray> Read(std::int64_t size) override {
|
||||
return client_socket_->Read(size);
|
||||
}
|
||||
ExceptionOr<size_t> Skip(size_t offset) override {
|
||||
return client_socket_->Skip(offset);
|
||||
}
|
||||
Exception Close() override { return client_socket_->Close(); }
|
||||
|
||||
private:
|
||||
NearbyClientSocket* absl_nonnull const client_socket_;
|
||||
};
|
||||
|
||||
// A simple wrapper to handle output stream of socket
|
||||
class SocketOutputStream : public OutputStream {
|
||||
public:
|
||||
explicit SocketOutputStream(NearbyClientSocket* absl_nonnull client_socket)
|
||||
: client_socket_(client_socket) {}
|
||||
~SocketOutputStream() override = default;
|
||||
|
||||
Exception Write(const ByteArray& data) override {
|
||||
return client_socket_->Write(data);
|
||||
}
|
||||
Exception Flush() override { return client_socket_->Flush(); }
|
||||
Exception Close() override { return client_socket_->Close(); }
|
||||
|
||||
private:
|
||||
NearbyClientSocket* absl_nonnull const client_socket_;
|
||||
};
|
||||
|
||||
absl_nonnull std::unique_ptr<NearbyClientSocket> client_socket_;
|
||||
SocketInputStream input_stream_;
|
||||
SocketOutputStream output_stream_;
|
||||
@@ -158,15 +124,14 @@ class WifiDirectSocket : public api::WifiDirectSocket {
|
||||
// server socket accepts connection from clients.
|
||||
class WifiDirectServerSocket : public api::WifiDirectServerSocket {
|
||||
public:
|
||||
explicit WifiDirectServerSocket(int port = 0);
|
||||
WifiDirectServerSocket(const WifiDirectServerSocket&) = default;
|
||||
WifiDirectServerSocket(WifiDirectServerSocket&&) = default;
|
||||
WifiDirectServerSocket() = default;
|
||||
~WifiDirectServerSocket() override;
|
||||
WifiDirectServerSocket& operator=(const WifiDirectServerSocket&) = default;
|
||||
WifiDirectServerSocket(WifiDirectServerSocket&&) = default;
|
||||
WifiDirectServerSocket& operator=(WifiDirectServerSocket&&) = default;
|
||||
|
||||
std::string GetIPAddress() const override;
|
||||
int GetPort() const override;
|
||||
|
||||
int GetPort() const override { return server_socket_.GetPort(); }
|
||||
|
||||
// Blocks until either:
|
||||
// - at least one incoming connection request is available, or
|
||||
@@ -179,83 +144,69 @@ class WifiDirectServerSocket : public api::WifiDirectServerSocket {
|
||||
// Called by the server side of a connection before passing ownership of
|
||||
// WifiDirectServerSocker to user, to track validity of a pointer to
|
||||
// this server socket.
|
||||
void SetCloseNotifier(absl::AnyInvocable<void()> notifier);
|
||||
void SetCloseNotifier(absl::AnyInvocable<void()> notifier) {
|
||||
server_socket_.SetCloseNotifier(std::move(notifier));
|
||||
}
|
||||
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
Exception Close() override;
|
||||
|
||||
// Binds to local port
|
||||
bool Listen(bool dual_stack, std::string& ip_address);
|
||||
// Populates the provided `wifi_direct_credentials` with the IP address
|
||||
// and port of this server socket.
|
||||
void PopulateWifiDirectCredentials(
|
||||
WifiDirectCredentials& wifi_direct_credentials) override;
|
||||
|
||||
NearbyServerSocket server_socket_;
|
||||
void SetIPAddress(std::string ip_address);
|
||||
|
||||
// Binds to local port
|
||||
bool Listen(int port, bool dual_stack);
|
||||
|
||||
private:
|
||||
// Retrieves hotspot IP address from local machine
|
||||
// Retrieves WifiDirect GO IP address from local machine
|
||||
std::string GetWifiDirectIpAddress() const;
|
||||
|
||||
const int port_;
|
||||
mutable absl::Mutex mutex_;
|
||||
|
||||
// Close notifier
|
||||
absl::AnyInvocable<void()> close_notifier_ = nullptr;
|
||||
absl::CondVar is_listen_ready_;
|
||||
bool is_listen_started_ ABSL_GUARDED_BY(mutex_) = false;
|
||||
|
||||
// IP addresses of the server socket.
|
||||
std::string wifi_direct_ipaddr_ = {};
|
||||
bool closed_ = false;
|
||||
NearbyServerSocket server_socket_;
|
||||
};
|
||||
|
||||
class WifiDirectDiscovered {
|
||||
public:
|
||||
explicit WifiDirectDiscovered(const DeviceInformation& device_info);
|
||||
|
||||
~WifiDirectDiscovered() = default;
|
||||
WifiDirectDiscovered(WifiDirectDiscovered&&) = default;
|
||||
WifiDirectDiscovered& operator=(WifiDirectDiscovered&&) = default;
|
||||
|
||||
std::string GetId() { return id_; }
|
||||
DeviceInformation GetDeviceInformation() {
|
||||
return windows_wifi_direct_device_;
|
||||
}
|
||||
|
||||
private:
|
||||
DeviceInformation windows_wifi_direct_device_;
|
||||
|
||||
// Once the device is lost, we can no longer access it's id.
|
||||
std::string id_;
|
||||
|
||||
// Once the device is lost, we can no longer access it's mac address.
|
||||
// std::string name_;
|
||||
};
|
||||
|
||||
class WifiDirectMedium {
|
||||
class WifiDirectMedium : public api::WifiDirectMedium {
|
||||
public:
|
||||
WifiDirectMedium();
|
||||
~WifiDirectMedium();
|
||||
~WifiDirectMedium() override;
|
||||
// WifiDirectMedium is neither copyable nor movable.
|
||||
WifiDirectMedium(const WifiDirectMedium&) = delete;
|
||||
WifiDirectMedium& operator=(const WifiDirectMedium&) = delete;
|
||||
|
||||
// If the WiFi Adaptor supports to start WifiDirect Service GO.
|
||||
bool IsInterfaceValid() const;
|
||||
bool IsInterfaceValid() const override;
|
||||
|
||||
// Discoverer connects to server socket
|
||||
std::unique_ptr<api::WifiDirectSocket> ConnectToService(
|
||||
absl::string_view ip_address, int port,
|
||||
CancellationFlag* cancellation_flag);
|
||||
CancellationFlag* cancellation_flag) override;
|
||||
|
||||
// Advertiser starts to listen on server socket
|
||||
std::unique_ptr<api::WifiDirectServerSocket> ListenForService(int port);
|
||||
std::unique_ptr<api::WifiDirectServerSocket> ListenForService(
|
||||
int port) override;
|
||||
|
||||
// Starts to advertising
|
||||
bool StartWifiDirect();
|
||||
// Stops to advertising
|
||||
bool StopWifiDirect();
|
||||
// Connects to a WifiDirect
|
||||
bool ConnectWifiDirect();
|
||||
// Disconnects from a WifiDirect
|
||||
bool DisconnectWifiDirect();
|
||||
// Advertiser start WiFiDirect GO with specific Credentials.
|
||||
bool StartWifiDirect(WifiDirectCredentials* wifi_direct_credentials) override;
|
||||
// Advertiser stop the current WiFiDirect GO.
|
||||
bool StopWifiDirect() override;
|
||||
// Discoverer connects to the WifiDirect GO as GC.
|
||||
bool ConnectWifiDirect(
|
||||
const WifiDirectCredentials& wifi_direct_credentials) override;
|
||||
// Discoverer disconnects from the connected WifiDirect GO.
|
||||
bool DisconnectWifiDirect() override;
|
||||
|
||||
absl::optional<std::pair<std::int32_t, std::int32_t>> GetDynamicPortRange() {
|
||||
absl::optional<std::pair<std::int32_t, std::int32_t>> GetDynamicPortRange()
|
||||
override {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
@@ -263,7 +214,7 @@ class WifiDirectMedium {
|
||||
enum Value : char {
|
||||
kMediumStatusIdle = 0,
|
||||
kMediumStatusAccepting = (1 << 0),
|
||||
kMediumStatusServiceStarted = (1 << 1),
|
||||
kMediumStatusGOStarted = (1 << 1),
|
||||
kMediumStatusConnecting = (1 << 2),
|
||||
kMediumStatusConnected = (1 << 3),
|
||||
};
|
||||
@@ -273,9 +224,9 @@ class WifiDirectMedium {
|
||||
bool IsIdle() { return medium_status_ == kMediumStatusIdle; }
|
||||
// Advertiser is accepting connection on server socket
|
||||
bool IsAccepting() { return (medium_status_ & kMediumStatusAccepting) != 0; }
|
||||
// Advertiser started WifiDirect
|
||||
bool IsServiceStarted() {
|
||||
return (medium_status_ & kMediumStatusServiceStarted) != 0;
|
||||
// Advertiser started WifiDirect GO
|
||||
bool IsGOStarted() {
|
||||
return (medium_status_ & kMediumStatusGOStarted) != 0;
|
||||
}
|
||||
// Discoverer is connecting with the WifiDirect
|
||||
bool IsConnecting() {
|
||||
@@ -326,6 +277,9 @@ class WifiDirectMedium {
|
||||
IInspectable inspectable);
|
||||
fire_and_forget Watcher_DeviceStopped(DeviceWatcher sender,
|
||||
IInspectable inspectable);
|
||||
|
||||
WifiDirectCredentials* credentials_go_ = nullptr;
|
||||
WifiDirectCredentials credentials_gc_;
|
||||
std::string ip_address_local_;
|
||||
std::string ip_address_remote_;
|
||||
|
||||
@@ -334,12 +288,6 @@ class WifiDirectMedium {
|
||||
// Keep the server socket listener pointer
|
||||
WifiDirectServerSocket* server_socket_ptr_ ABSL_GUARDED_BY(mutex_) = nullptr;
|
||||
SubmittableExecutor listener_executor_;
|
||||
|
||||
absl::flat_hash_map<winrt::hstring, std::unique_ptr<WifiDirectDiscovered>>
|
||||
discovered_devices_by_id_;
|
||||
|
||||
absl::flat_hash_map<winrt::hstring, std::unique_ptr<WifiDirectDiscovered>>
|
||||
connection_requested_devices_by_id_;
|
||||
};
|
||||
|
||||
} // namespace nearby::windows
|
||||
|
||||
@@ -19,24 +19,25 @@
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/flags/nearby_platform_feature_flags.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/implementation/windows/socket_address.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/implementation/windows/wifi_direct.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/prng.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
constexpr std::wstring_view kServiceName = L"QuickShare";
|
||||
constexpr std::wstring_view kPin = L"1234";
|
||||
constexpr int kWaitingForConnectionTimeoutSeconds = 90; // seconds
|
||||
} // namespace
|
||||
|
||||
@@ -193,11 +194,12 @@ std::unique_ptr<api::WifiDirectSocket> WifiDirectMedium::ConnectToService(
|
||||
// Advertiser starts to listen on server socket
|
||||
std::unique_ptr<api::WifiDirectServerSocket> WifiDirectMedium::ListenForService(
|
||||
int port) {
|
||||
LOG(INFO) << "WifiDirectMedium::ListenForService";
|
||||
LOG(INFO) << __func__
|
||||
<< " :Start to listen connection from WiFiDirect client.";
|
||||
|
||||
absl::MutexLock lock(mutex_);
|
||||
if (!IsServiceStarted()) {
|
||||
LOG(WARNING) << "WifiDirect service is not started, skip.";
|
||||
if (!IsGOStarted()) {
|
||||
LOG(WARNING) << "WifiDirect GO is not started, skip.";
|
||||
return nullptr;
|
||||
}
|
||||
// check current status
|
||||
@@ -207,14 +209,14 @@ std::unique_ptr<api::WifiDirectServerSocket> WifiDirectMedium::ListenForService(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto server_socket = std::make_unique<WifiDirectServerSocket>(port);
|
||||
auto server_socket = std::make_unique<WifiDirectServerSocket>();
|
||||
server_socket_ptr_ = server_socket.get();
|
||||
|
||||
// Start to listen on server socket in a separate thread. Before GC
|
||||
// connects to GO, GO doesn't have IP address. BWU calls this API right away
|
||||
// after it starts GO, we need to spin out the following logic to another
|
||||
// thread to avoid blocking BWU sending out of band upgrade frame to GC.
|
||||
listener_executor_.Execute([this]() mutable {
|
||||
listener_executor_.Execute([this, port]() mutable {
|
||||
absl::MutexLock lock(mutex_);
|
||||
bool dual_stack = NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
@@ -239,9 +241,12 @@ std::unique_ptr<api::WifiDirectServerSocket> WifiDirectMedium::ListenForService(
|
||||
LOG(INFO) << "IP address is ready.";
|
||||
}
|
||||
}
|
||||
|
||||
server_socket_ptr_->SetIPAddress(ip_address_local_);
|
||||
if (port == 0) {
|
||||
port = FeatureFlags::GetInstance().GetFlags().wifi_direct_default_port;
|
||||
}
|
||||
if (server_socket_ptr_ &&
|
||||
server_socket_ptr_->Listen(dual_stack, ip_address_local_)) {
|
||||
server_socket_ptr_->Listen(port, dual_stack)) {
|
||||
medium_status_ |= kMediumStatusAccepting;
|
||||
|
||||
// Setup close notifier after listen started.
|
||||
@@ -267,17 +272,27 @@ std::unique_ptr<api::WifiDirectServerSocket> WifiDirectMedium::ListenForService(
|
||||
return server_socket;
|
||||
}
|
||||
|
||||
bool WifiDirectMedium::StartWifiDirect() {
|
||||
bool WifiDirectMedium::StartWifiDirect(
|
||||
WifiDirectCredentials* wifi_direct_credentials) {
|
||||
LOG(INFO) << "WifiDirectMedium::StartWifiDirect";
|
||||
|
||||
absl::MutexLock lock(mutex_);
|
||||
if (IsServiceStarted()) {
|
||||
LOG(WARNING) << "Already started WifiDirect service, skip.";
|
||||
if (IsGOStarted()) {
|
||||
LOG(WARNING) << "Already started WifiDirect GO, skip.";
|
||||
return true;
|
||||
}
|
||||
|
||||
credentials_go_ = wifi_direct_credentials;
|
||||
Prng prng;
|
||||
std::string pin = absl::StrFormat("%04x", prng.NextUint32());
|
||||
credentials_go_->SetPin(pin);
|
||||
|
||||
std::string service_name = "NC-" + std::to_string(prng.NextUint32());
|
||||
credentials_go_->SetServiceName(service_name);
|
||||
LOG(INFO) << "service_name:pin " << service_name << ":" << pin;
|
||||
|
||||
// Create Advertiser object
|
||||
advertiser_ = WiFiDirectServiceAdvertiser(kServiceName);
|
||||
advertiser_ = WiFiDirectServiceAdvertiser(winrt::to_hstring(service_name));
|
||||
advertisement_status_changed_token_ = advertiser_.AdvertisementStatusChanged(
|
||||
{this, &WifiDirectMedium::OnAdvertisementStatusChanged});
|
||||
auto_accept_session_connected_token_ = advertiser_.AutoAcceptSessionConnected(
|
||||
@@ -290,7 +305,7 @@ bool WifiDirectMedium::StartWifiDirect() {
|
||||
advertiser_.ServiceStatus(WiFiDirectServiceStatus::Available);
|
||||
// Config Methods
|
||||
WiFiDirectServiceConfigurationMethod config_method;
|
||||
if (kPin.empty()) {
|
||||
if (pin.empty()) {
|
||||
config_method = WiFiDirectServiceConfigurationMethod::Default; // NOLINT
|
||||
} else {
|
||||
config_method = WiFiDirectServiceConfigurationMethod::PinDisplay;
|
||||
@@ -306,7 +321,7 @@ bool WifiDirectMedium::StartWifiDirect() {
|
||||
WiFiDirectServiceAdvertisementStatus::Created) ||
|
||||
(advertiser_.AdvertisementStatus() ==
|
||||
WiFiDirectServiceAdvertisementStatus::Started)) {
|
||||
medium_status_ |= kMediumStatusServiceStarted;
|
||||
medium_status_ |= kMediumStatusGOStarted;
|
||||
return true;
|
||||
}
|
||||
LOG(ERROR) << "Start WifiDirect GO failed.";
|
||||
@@ -331,7 +346,7 @@ bool WifiDirectMedium::StartWifiDirect() {
|
||||
bool WifiDirectMedium::StopWifiDirect() {
|
||||
LOG(INFO) << "WifiDirectMedium::StopWifiDirect";
|
||||
absl::MutexLock lock(mutex_);
|
||||
if (!IsServiceStarted()) {
|
||||
if (!IsGOStarted()) {
|
||||
LOG(WARNING) << "Cannot stop Service because no Service is started.";
|
||||
return true;
|
||||
}
|
||||
@@ -348,9 +363,11 @@ bool WifiDirectMedium::StopWifiDirect() {
|
||||
device_info_ = nullptr;
|
||||
session_ = nullptr;
|
||||
}
|
||||
medium_status_ &= (~kMediumStatusServiceStarted);
|
||||
medium_status_ &= (~kMediumStatusGOStarted);
|
||||
medium_status_ &= (~kMediumStatusConnected);
|
||||
server_socket_ptr_ = nullptr;
|
||||
ip_address_local_.clear();
|
||||
ip_address_remote_.clear();
|
||||
listener_executor_.Shutdown();
|
||||
return true;
|
||||
} catch (std::exception exception) {
|
||||
@@ -465,10 +482,12 @@ fire_and_forget WifiDirectMedium::OnSessionRequested(
|
||||
|
||||
absl::MutexLock lock(mutex_);
|
||||
WiFiDirectServiceSession session = nullptr;
|
||||
if (kPin.empty()) {
|
||||
auto pin = credentials_go_->GetPin();
|
||||
if (pin.empty()) {
|
||||
session = advertiser_.ConnectAsync(device_info_).get(); // NOLINT
|
||||
} else {
|
||||
session = advertiser_.ConnectAsync(device_info_, kPin).get();
|
||||
session = advertiser_.ConnectAsync(device_info_, winrt::to_hstring(pin))
|
||||
.get();
|
||||
}
|
||||
LOG(INFO) << "GO: TryEnqueue: Wait for ConnectAsync finish";
|
||||
if (!session) {
|
||||
@@ -519,7 +538,8 @@ fire_and_forget WifiDirectMedium::OnSessionRequested(
|
||||
}
|
||||
}
|
||||
|
||||
bool WifiDirectMedium::ConnectWifiDirect() {
|
||||
bool WifiDirectMedium::ConnectWifiDirect(
|
||||
const WifiDirectCredentials& credentials) {
|
||||
LOG(INFO) << "WifiDirectMedium::ConnectWifiDirect";
|
||||
absl::MutexLock lock(mutex_);
|
||||
if (IsConnecting()) {
|
||||
@@ -533,10 +553,9 @@ bool WifiDirectMedium::ConnectWifiDirect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
discovered_devices_by_id_.clear();
|
||||
connection_requested_devices_by_id_.clear();
|
||||
|
||||
winrt::hstring device_selector = WiFiDirectService::GetSelector(kServiceName);
|
||||
credentials_gc_ = credentials;
|
||||
winrt::hstring device_selector = WiFiDirectService::GetSelector(
|
||||
winrt::to_hstring(credentials_gc_.GetServiceName()));
|
||||
const winrt::param::iterable<winrt::hstring> requested_properties =
|
||||
winrt::single_threaded_vector<winrt::hstring>({
|
||||
winrt::to_hstring("System.Devices.WiFiDirectServices.ServiceAddress"),
|
||||
@@ -590,7 +609,8 @@ fire_and_forget WifiDirectMedium::Watcher_DeviceAdded(
|
||||
service_.PreferGroupOwnerMode(false);
|
||||
|
||||
WiFiDirectServiceSession session = nullptr;
|
||||
if (kPin.empty()) {
|
||||
auto pin = credentials_gc_.GetPin();
|
||||
if (pin.empty()) {
|
||||
session = service_.ConnectAsync().get(); // NOLINT
|
||||
} else {
|
||||
auto prov_info = co_await service_.GetProvisioningInfoAsync(
|
||||
@@ -605,7 +625,7 @@ fire_and_forget WifiDirectMedium::Watcher_DeviceAdded(
|
||||
<< ConfigMethodToString(
|
||||
prov_info.SelectedConfigurationMethod());
|
||||
|
||||
session = service_.ConnectAsync(kPin).get();
|
||||
session = service_.ConnectAsync(winrt::to_hstring(pin)).get();
|
||||
}
|
||||
|
||||
if (!session) {
|
||||
@@ -702,7 +722,9 @@ bool WifiDirectMedium::DisconnectWifiDirect() {
|
||||
device_watcher_ = nullptr;
|
||||
service_ = nullptr;
|
||||
session_ = nullptr;
|
||||
return true;
|
||||
ip_address_local_.clear();
|
||||
ip_address_remote_.clear();
|
||||
return true;
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Stop WifiDirect GC failed. Exception: "
|
||||
<< exception.what();
|
||||
|
||||
@@ -20,21 +20,20 @@
|
||||
#include <utility>
|
||||
|
||||
// Nearby connections headers
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.Collections.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.Connectivity.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.Sockets.h"
|
||||
#include "internal/platform/implementation/windows/socket_address.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/implementation/windows/wifi_direct.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
|
||||
WifiDirectServerSocket::WifiDirectServerSocket(int port) : port_(port) {}
|
||||
namespace {
|
||||
constexpr int kWaitingForServerSocketReadyTimeoutSeconds = 90; // seconds
|
||||
} // namespace
|
||||
|
||||
WifiDirectServerSocket::~WifiDirectServerSocket() { Close(); }
|
||||
|
||||
@@ -42,9 +41,29 @@ std::string WifiDirectServerSocket::GetIPAddress() const {
|
||||
return wifi_direct_ipaddr_;
|
||||
}
|
||||
|
||||
int WifiDirectServerSocket::GetPort() const { return server_socket_.GetPort(); }
|
||||
void WifiDirectServerSocket::SetIPAddress(std::string ip_address) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
if (ip_address.empty()) {
|
||||
return;
|
||||
}
|
||||
wifi_direct_ipaddr_ = ip_address;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiDirectSocket> WifiDirectServerSocket::Accept() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
if (!is_listen_started_) {
|
||||
LOG(INFO) << __func__
|
||||
<< ": Server socket is not started, wait for server socket is "
|
||||
"ready.";
|
||||
is_listen_ready_.WaitWithTimeout(
|
||||
&mutex_, absl::Seconds(kWaitingForServerSocketReadyTimeoutSeconds));
|
||||
if (!is_listen_started_) {
|
||||
LOG(INFO) << __func__
|
||||
<< ": Server socket failed to start within timeout.";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto client_socket = server_socket_.Accept();
|
||||
if (client_socket == nullptr) {
|
||||
return nullptr;
|
||||
@@ -54,9 +73,16 @@ std::unique_ptr<api::WifiDirectSocket> WifiDirectServerSocket::Accept() {
|
||||
return std::make_unique<WifiDirectSocket>(std::move(client_socket));
|
||||
}
|
||||
|
||||
void WifiDirectServerSocket::SetCloseNotifier(
|
||||
absl::AnyInvocable<void()> notifier) {
|
||||
close_notifier_ = std::move(notifier);
|
||||
void WifiDirectServerSocket::PopulateWifiDirectCredentials(
|
||||
WifiDirectCredentials& wifi_direct_credentials) {
|
||||
wifi_direct_credentials.SetGateway(wifi_direct_ipaddr_);
|
||||
if (GetPort() != 0) {
|
||||
wifi_direct_credentials.SetPort(GetPort());
|
||||
} else {
|
||||
wifi_direct_credentials.SetPort(FeatureFlags::GetInstance()
|
||||
.GetFlags()
|
||||
.wifi_direct_default_port);
|
||||
}
|
||||
}
|
||||
|
||||
Exception WifiDirectServerSocket::Close() {
|
||||
@@ -64,35 +90,31 @@ Exception WifiDirectServerSocket::Close() {
|
||||
if (closed_) {
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
wifi_direct_ipaddr_.clear();
|
||||
is_listen_started_ = false;
|
||||
server_socket_.Close();
|
||||
closed_ = true;
|
||||
|
||||
if (close_notifier_ != nullptr) {
|
||||
close_notifier_();
|
||||
}
|
||||
|
||||
LOG(INFO) << __func__ << ": Close completed succesfully.";
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
bool WifiDirectServerSocket::Listen(bool dual_stack, std::string& ip_address) {
|
||||
// Get current IP addresses of the device.
|
||||
if (ip_address.empty()) {
|
||||
return false;
|
||||
}
|
||||
wifi_direct_ipaddr_ = ip_address;
|
||||
LOG(INFO) << "Listen wifi_direct on IP:port " << ip_address << ":" << port_;
|
||||
bool WifiDirectServerSocket::Listen(int port, bool dual_stack) {
|
||||
LOG(INFO) << "Listen wifi_direct on IP:port " << wifi_direct_ipaddr_ << ":"
|
||||
<< port;
|
||||
SocketAddress address(dual_stack);
|
||||
if (!SocketAddress::FromString(address, ip_address, port_)) {
|
||||
LOG(ERROR) << "Failed to parse wifi_direct IP address: " << ip_address
|
||||
<< " and port: " << port_;
|
||||
if (!SocketAddress::FromString(address, wifi_direct_ipaddr_, port)) {
|
||||
LOG(ERROR) << "Failed to parse wifi_direct IP address.";
|
||||
return false;
|
||||
}
|
||||
if (!server_socket_.Listen(address)) {
|
||||
LOG(ERROR) << "Failed to listen socket.";
|
||||
return false;
|
||||
}
|
||||
LOG(INFO) << "Notify the server socket is started.";
|
||||
absl::MutexLock lock(&mutex_);
|
||||
is_listen_started_ = true;
|
||||
is_listen_ready_.SignalAll();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/implementation/wifi_direct.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
@@ -35,9 +36,11 @@ TEST(WifiDirectMedium, DISABLED_StartWifiDirect) {
|
||||
|
||||
if (run_test) {
|
||||
winrt::init_apartment();
|
||||
WifiDirectCredentials credentials;
|
||||
WifiDirectMedium wifi_direct_medium;
|
||||
|
||||
EXPECT_TRUE(wifi_direct_medium.StartWifiDirect());
|
||||
EXPECT_TRUE(wifi_direct_medium.IsInterfaceValid());
|
||||
EXPECT_TRUE(wifi_direct_medium.StartWifiDirect(&credentials));
|
||||
|
||||
while (true) {
|
||||
LOG(INFO) << "Enter \"s\" to stop test:";
|
||||
@@ -60,8 +63,19 @@ TEST(WifiDirectMedium, DISABLED_ConnectWifiDirect) {
|
||||
std::cin >> run_test;
|
||||
|
||||
if (run_test) {
|
||||
WifiDirectCredentials credentials;
|
||||
WifiDirectMedium wifi_direct_medium;
|
||||
EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect());
|
||||
|
||||
LOG(INFO) << "Enter WifiDirect Service Name to be connected: ";
|
||||
std::string service_name;
|
||||
std::cin >> service_name;
|
||||
LOG(INFO) << "Enter pin: ";
|
||||
std::string pin;
|
||||
std::cin >> pin;
|
||||
credentials.SetServiceName(service_name);
|
||||
credentials.SetPin(pin);
|
||||
|
||||
EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect(credentials));
|
||||
|
||||
absl::SleepFor(absl::Seconds(2));
|
||||
while (true) {
|
||||
@@ -86,9 +100,12 @@ TEST(WifiDirectMedium, DISABLED_WifiDirectServerStartListen) {
|
||||
|
||||
if (run_test) {
|
||||
winrt::init_apartment();
|
||||
WifiDirectCredentials credentials;
|
||||
WifiDirectMedium wifi_direct_medium;
|
||||
|
||||
EXPECT_TRUE(wifi_direct_medium.StartWifiDirect());
|
||||
EXPECT_TRUE(wifi_direct_medium.IsInterfaceValid());
|
||||
EXPECT_TRUE(wifi_direct_medium.StartWifiDirect(&credentials));
|
||||
|
||||
absl::SleepFor(absl::Seconds(1));
|
||||
std::unique_ptr<api::WifiDirectServerSocket> server_socket =
|
||||
wifi_direct_medium.ListenForService(/*port=*/1234);
|
||||
@@ -121,9 +138,19 @@ TEST(WifiDirectMedium, DISABLED_WifiDirectConnectToServiceServer) {
|
||||
|
||||
if (run_test) {
|
||||
winrt::init_apartment();
|
||||
WifiDirectCredentials credentials;
|
||||
WifiDirectMedium wifi_direct_medium;
|
||||
|
||||
EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect());
|
||||
LOG(INFO) << "Enter WifiDirect Service Name to be connected: ";
|
||||
std::string service_name;
|
||||
std::cin >> service_name;
|
||||
LOG(INFO) << "Enter pin: ";
|
||||
std::string pin;
|
||||
std::cin >> pin;
|
||||
credentials.SetServiceName(service_name);
|
||||
credentials.SetPin(pin);
|
||||
|
||||
EXPECT_TRUE(wifi_direct_medium.ConnectWifiDirect(credentials));
|
||||
absl::SleepFor(absl::Seconds(1));
|
||||
std::unique_ptr<api::WifiDirectSocket> client_socket =
|
||||
wifi_direct_medium.ConnectToService(
|
||||
|
||||
Reference in New Issue
Block a user