mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Support blocking socket in Wi-Fi hotspot medium
PiperOrigin-RevId: 718006644
This commit is contained in:
committed by
Copybara-Service
parent
d73d1d0515
commit
b0be56bec8
@@ -36,8 +36,11 @@
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/cancelable.h"
|
||||
#include "internal/platform/implementation/wifi_hotspot.h"
|
||||
#include "internal/platform/implementation/windows/nearby_client_socket.h"
|
||||
#include "internal/platform/implementation/windows/nearby_server_socket.h"
|
||||
#include "internal/platform/implementation/windows/scheduled_executor.h"
|
||||
#include "internal/platform/implementation/windows/submittable_executor.h"
|
||||
#include "internal/platform/implementation/windows/wifi_hotspot_native.h"
|
||||
@@ -55,6 +58,8 @@
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Security.Cryptography.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Storage.Streams.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/base.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/wifi_credential.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -109,6 +114,8 @@ using ::winrt::Windows::Networking::Sockets::
|
||||
// remote WiFi Hotspot service, also will return a WifiHotspotSocket to caller.
|
||||
class WifiHotspotSocket : public api::WifiHotspotSocket {
|
||||
public:
|
||||
WifiHotspotSocket();
|
||||
explicit WifiHotspotSocket(std::unique_ptr<NearbyClientSocket> socket);
|
||||
explicit WifiHotspotSocket(StreamSocket socket);
|
||||
explicit WifiHotspotSocket(SOCKET socket);
|
||||
WifiHotspotSocket(const WifiHotspotSocket&) = default;
|
||||
@@ -134,6 +141,8 @@ class WifiHotspotSocket : public api::WifiHotspotSocket {
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
Exception Close() override;
|
||||
|
||||
bool Connect(const std::string& ip_address, int port);
|
||||
|
||||
private:
|
||||
enum class SocketType { kWinRTSocket = 0, kWin32Socket };
|
||||
// A simple wrapper to handle input stream of socket
|
||||
@@ -141,6 +150,7 @@ class WifiHotspotSocket : public api::WifiHotspotSocket {
|
||||
public:
|
||||
explicit SocketInputStream(IInputStream input_stream);
|
||||
explicit SocketInputStream(SOCKET socket);
|
||||
explicit SocketInputStream(NearbyClientSocket* client_socket);
|
||||
~SocketInputStream() override = default;
|
||||
|
||||
ExceptionOr<ByteArray> Read(std::int64_t size) override;
|
||||
@@ -148,10 +158,12 @@ class WifiHotspotSocket : public api::WifiHotspotSocket {
|
||||
Exception Close() override;
|
||||
|
||||
private:
|
||||
bool enable_blocking_socket_ = false;
|
||||
IInputStream input_stream_{nullptr};
|
||||
SOCKET socket_ = INVALID_SOCKET;
|
||||
SocketType socket_type_ = SocketType::kWinRTSocket;
|
||||
ByteArray read_buffer_;
|
||||
NearbyClientSocket* client_socket_{nullptr};
|
||||
};
|
||||
|
||||
// A simple wrapper to handle output stream of socket
|
||||
@@ -159,6 +171,7 @@ class WifiHotspotSocket : public api::WifiHotspotSocket {
|
||||
public:
|
||||
explicit SocketOutputStream(IOutputStream output_stream);
|
||||
explicit SocketOutputStream(SOCKET socket);
|
||||
explicit SocketOutputStream(NearbyClientSocket* client_socket);
|
||||
~SocketOutputStream() override = default;
|
||||
|
||||
Exception Write(const ByteArray& data) override;
|
||||
@@ -166,9 +179,11 @@ class WifiHotspotSocket : public api::WifiHotspotSocket {
|
||||
Exception Close() override;
|
||||
|
||||
private:
|
||||
bool enable_blocking_socket_ = false;
|
||||
IOutputStream output_stream_{nullptr};
|
||||
SOCKET socket_ = INVALID_SOCKET;
|
||||
SocketType socket_type_ = SocketType::kWinRTSocket;
|
||||
NearbyClientSocket* client_socket_{nullptr};
|
||||
};
|
||||
|
||||
// Internal properties
|
||||
@@ -176,6 +191,9 @@ class WifiHotspotSocket : public api::WifiHotspotSocket {
|
||||
StreamSocket stream_soket_{nullptr};
|
||||
SocketInputStream input_stream_{nullptr};
|
||||
SocketOutputStream output_stream_{nullptr};
|
||||
|
||||
bool enable_blocking_socket_ = false;
|
||||
std::unique_ptr<NearbyClientSocket> client_socket_;
|
||||
};
|
||||
|
||||
// WifiHotspotServerSocket provides the support to server socket, this server
|
||||
@@ -216,6 +234,10 @@ class WifiHotspotServerSocket : public api::WifiHotspotServerSocket {
|
||||
// Binds to local port
|
||||
bool listen();
|
||||
|
||||
// Flag to enable blocking socket.
|
||||
bool enable_blocking_socket_ = false;
|
||||
NearbyServerSocket server_socket_;
|
||||
|
||||
private:
|
||||
static constexpr int kSocketEventsCount = 2;
|
||||
static constexpr int kSocketEventListen = 0;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#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/byte_array.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
@@ -97,9 +98,6 @@ std::unique_ptr<api::WifiHotspotSocket> WifiHotspotMedium::ConnectToService(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HostName host_name{winrt::to_hstring(ipv4_address)};
|
||||
winrt::hstring service_name{winrt::to_hstring(port)};
|
||||
|
||||
// Try connecting to the service up to wifi_hotspot_max_connection_retries,
|
||||
// because it may fail first time if DHCP procedure is not finished yet.
|
||||
int64_t wifi_hotspot_max_connection_retries =
|
||||
@@ -120,14 +118,17 @@ std::unique_ptr<api::WifiHotspotSocket> WifiHotspotMedium::ConnectToService(
|
||||
<< ", connection interval=" << wifi_hotspot_retry_interval_millis
|
||||
<< "ms, connection timeout="
|
||||
<< wifi_hotspot_client_socket_connect_timeout_millis << "ms";
|
||||
for (int i = 0; i < wifi_hotspot_max_connection_retries; i++) {
|
||||
try {
|
||||
StreamSocket socket{};
|
||||
// Listener to connect cancellation.
|
||||
std::unique_ptr<CancellationFlagListener>
|
||||
connection_cancellation_listener = nullptr;
|
||||
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
nearby::platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableBlockingSocket)) {
|
||||
LOG(INFO) << "Connect to service " << ipv4_address << ":" << port;
|
||||
for (int i = 0; i < wifi_hotspot_max_connection_retries; ++i) {
|
||||
auto wifi_hotspot_socket = std::make_unique<WifiHotspotSocket>();
|
||||
|
||||
// setup cancel listener
|
||||
std::unique_ptr<CancellationFlagListener>
|
||||
connection_cancellation_listener = nullptr;
|
||||
if (cancellation_flag != nullptr) {
|
||||
if (cancellation_flag->Cancelled()) {
|
||||
LOG(INFO) << "connect has been cancelled to service " << ipv4_address
|
||||
@@ -137,57 +138,100 @@ std::unique_ptr<api::WifiHotspotSocket> WifiHotspotMedium::ConnectToService(
|
||||
|
||||
connection_cancellation_listener =
|
||||
std::make_unique<nearby::CancellationFlagListener>(
|
||||
cancellation_flag, [socket]() {
|
||||
cancellation_flag, [socket = wifi_hotspot_socket.get()]() {
|
||||
LOG(WARNING) << "connect is closed due to it is cancelled.";
|
||||
socket.Close();
|
||||
socket->Close();
|
||||
});
|
||||
}
|
||||
|
||||
if (FeatureFlags::GetInstance().GetFlags().enable_connection_timeout) {
|
||||
connection_timeout_ = scheduled_executor_.Schedule(
|
||||
[socket]() {
|
||||
LOG(WARNING) << "connect is closed due to timeout.";
|
||||
socket.Close();
|
||||
},
|
||||
absl::Milliseconds(
|
||||
wifi_hotspot_client_socket_connect_timeout_millis));
|
||||
bool result = wifi_hotspot_socket->Connect(ipv4_address, port);
|
||||
if (!result) {
|
||||
LOG(WARNING) << "reconnect to service at " << (i + 1) << "th times";
|
||||
Sleep(wifi_hotspot_retry_interval_millis);
|
||||
continue;
|
||||
}
|
||||
|
||||
socket.ConnectAsync(host_name, service_name).get();
|
||||
LOG(INFO) << "connected to remote service " << ipv4_address << ":"
|
||||
<< port;
|
||||
return wifi_hotspot_socket;
|
||||
}
|
||||
|
||||
LOG(ERROR) << "Failed to connect to service " << ipv4_address << ":"
|
||||
<< port;
|
||||
return nullptr;
|
||||
} else {
|
||||
HostName host_name{winrt::to_hstring(ipv4_address)};
|
||||
winrt::hstring service_name{winrt::to_hstring(port)};
|
||||
|
||||
for (int i = 0; i < wifi_hotspot_max_connection_retries; i++) {
|
||||
try {
|
||||
StreamSocket socket{};
|
||||
// Listener to connect cancellation.
|
||||
std::unique_ptr<CancellationFlagListener>
|
||||
connection_cancellation_listener = nullptr;
|
||||
|
||||
// setup cancel listener
|
||||
if (cancellation_flag != nullptr) {
|
||||
if (cancellation_flag->Cancelled()) {
|
||||
LOG(INFO) << "connect has been cancelled to service "
|
||||
<< ipv4_address << ":" << port;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
connection_cancellation_listener =
|
||||
std::make_unique<nearby::CancellationFlagListener>(
|
||||
cancellation_flag, [socket]() {
|
||||
LOG(WARNING) << "connect is closed due to it is cancelled.";
|
||||
socket.Close();
|
||||
});
|
||||
}
|
||||
|
||||
if (FeatureFlags::GetInstance().GetFlags().enable_connection_timeout) {
|
||||
connection_timeout_ = scheduled_executor_.Schedule(
|
||||
[socket]() {
|
||||
LOG(WARNING) << "connect is closed due to timeout.";
|
||||
socket.Close();
|
||||
},
|
||||
absl::Milliseconds(
|
||||
wifi_hotspot_client_socket_connect_timeout_millis));
|
||||
}
|
||||
|
||||
socket.ConnectAsync(host_name, service_name).get();
|
||||
|
||||
if (connection_timeout_ != nullptr) {
|
||||
connection_timeout_->Cancel();
|
||||
connection_timeout_ = nullptr;
|
||||
}
|
||||
|
||||
auto wifi_hotspot_socket = std::make_unique<WifiHotspotSocket>(socket);
|
||||
|
||||
LOG(INFO) << "connected to remote service " << ipv4_address << ":"
|
||||
<< port;
|
||||
return wifi_hotspot_socket;
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << "failed to connect remote service " << ipv4_address << ":"
|
||||
<< port << " for the " << i + 1
|
||||
<< " time. Exception: " << exception.what();
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << "failed to connect remote service " << ipv4_address << ":"
|
||||
<< port << " for the " << i + 1
|
||||
<< " time. WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
} catch (...) {
|
||||
LOG(ERROR) << "failed to connect remote service " << ipv4_address << ":"
|
||||
<< port << " for the " << i + 1
|
||||
<< " time due to unknown reason.";
|
||||
}
|
||||
|
||||
if (connection_timeout_ != nullptr) {
|
||||
connection_timeout_->Cancel();
|
||||
connection_timeout_ = nullptr;
|
||||
}
|
||||
|
||||
auto wifi_hotspot_socket = std::make_unique<WifiHotspotSocket>(socket);
|
||||
|
||||
LOG(INFO) << "connected to remote service " << ipv4_address << ":"
|
||||
<< port;
|
||||
return wifi_hotspot_socket;
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << "failed to connect remote service " << ipv4_address << ":"
|
||||
<< port << " for the " << i + 1
|
||||
<< " time. Exception: " << exception.what();
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << "failed to connect remote service " << ipv4_address << ":"
|
||||
<< port << " for the " << i + 1
|
||||
<< " time. WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
} catch (...) {
|
||||
LOG(ERROR) << "failed to connect remote service " << ipv4_address << ":"
|
||||
<< port << " for the " << i + 1
|
||||
<< " time due to unknown reason.";
|
||||
Sleep(wifi_hotspot_retry_interval_millis);
|
||||
}
|
||||
|
||||
if (connection_timeout_ != nullptr) {
|
||||
connection_timeout_->Cancel();
|
||||
connection_timeout_ = nullptr;
|
||||
}
|
||||
|
||||
Sleep(wifi_hotspot_retry_interval_millis);
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiHotspotServerSocket>
|
||||
@@ -401,10 +445,9 @@ fire_and_forget WifiHotspotMedium::OnConnectionRequested(
|
||||
// We found new connection request comes in during hotspot transfer. In this
|
||||
// case, we should create a new WiFiDirectDevice for it. It will cause
|
||||
// transfer failure if replace the old WiFiDirectDevice with it.
|
||||
auto wifi_direct_device =
|
||||
WiFiDirectDevice::FromIdAsync(
|
||||
connection_request.DeviceInformation().Id())
|
||||
.get();
|
||||
auto wifi_direct_device = WiFiDirectDevice::FromIdAsync(
|
||||
connection_request.DeviceInformation().Id())
|
||||
.get();
|
||||
wifi_direct_devices_.push_back(wifi_direct_device);
|
||||
LOG(INFO) << "Registered the device " << winrt::to_string(device_name)
|
||||
<< " in WLAN-AutoConfig";
|
||||
|
||||
@@ -14,17 +14,23 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
// ABSL headers
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/match.h"
|
||||
|
||||
// Nearby connections headers
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/flags/nearby_platform_feature_flags.h"
|
||||
#include "internal/platform/implementation/wifi_hotspot.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.Sockets.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/implementation/windows/wifi_hotspot.h"
|
||||
@@ -37,78 +43,102 @@ using ::winrt::Windows::Networking::Sockets::SocketQualityOfService;
|
||||
} // namespace
|
||||
|
||||
WifiHotspotServerSocket::WifiHotspotServerSocket(int port) : port_(port) {
|
||||
for (auto &it : socket_events_) {
|
||||
it = WSA_INVALID_EVENT;
|
||||
enable_blocking_socket_ = NearbyFlags::GetInstance().GetBoolFlag(
|
||||
nearby::platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableBlockingSocket);
|
||||
if (!enable_blocking_socket_) {
|
||||
for (auto &it : socket_events_) {
|
||||
it = WSA_INVALID_EVENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WifiHotspotServerSocket::~WifiHotspotServerSocket() { Close(); }
|
||||
|
||||
std::string WifiHotspotServerSocket::GetIPAddress() const {
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableHotspotWin32Socket)) {
|
||||
if (listen_socket_ == INVALID_SOCKET) {
|
||||
return {};
|
||||
}
|
||||
if (enable_blocking_socket_) {
|
||||
return server_socket_.GetIPAddress();
|
||||
} else {
|
||||
if (stream_socket_listener_ == nullptr) {
|
||||
return {};
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableHotspotWin32Socket)) {
|
||||
if (listen_socket_ == INVALID_SOCKET) {
|
||||
return {};
|
||||
}
|
||||
} else {
|
||||
if (stream_socket_listener_ == nullptr) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::string hotspot_ip_address = GetHotspotIpAddress();
|
||||
LOG(INFO) << __func__
|
||||
<< ": Return hotspot IP address: " << hotspot_ip_address;
|
||||
|
||||
return hotspot_ip_address;
|
||||
}
|
||||
|
||||
std::string hotspot_ip_address = GetHotspotIpAddress();
|
||||
LOG(INFO) << __func__
|
||||
<< ": Return hotspot IP address: " << hotspot_ip_address;
|
||||
|
||||
return hotspot_ip_address;
|
||||
}
|
||||
|
||||
int WifiHotspotServerSocket::GetPort() const {
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableHotspotWin32Socket)) {
|
||||
if (listen_socket_ == INVALID_SOCKET) {
|
||||
LOG(WARNING) << __func__ << ": listen_socket_ is invalid.";
|
||||
return 0;
|
||||
}
|
||||
return port_;
|
||||
if (enable_blocking_socket_) {
|
||||
return server_socket_.GetPort();
|
||||
} else {
|
||||
if (stream_socket_listener_ == nullptr) {
|
||||
return 0;
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableHotspotWin32Socket)) {
|
||||
if (listen_socket_ == INVALID_SOCKET) {
|
||||
LOG(WARNING) << __func__ << ": listen_socket_ is invalid.";
|
||||
return 0;
|
||||
}
|
||||
return port_;
|
||||
} else {
|
||||
if (stream_socket_listener_ == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return std::stoi(
|
||||
stream_socket_listener_.Information().LocalPort().c_str());
|
||||
}
|
||||
return std::stoi(stream_socket_listener_.Information().LocalPort().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<api::WifiHotspotSocket> WifiHotspotServerSocket::Accept() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
LOG(INFO) << __func__ << ": Accept is called.";
|
||||
if (enable_blocking_socket_) {
|
||||
auto client_socket = server_socket_.Accept();
|
||||
if (client_socket == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableHotspotWin32Socket)) {
|
||||
while (!closed_ && pending_client_sockets_.empty()) {
|
||||
LOG(INFO) << __func__ << ": Accepted a remote connection.";
|
||||
return std::make_unique<WifiHotspotSocket>(std::move(client_socket));
|
||||
} else {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
LOG(INFO) << __func__ << ": Accept is called.";
|
||||
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableHotspotWin32Socket)) {
|
||||
while (!closed_ && pending_client_sockets_.empty()) {
|
||||
cond_.Wait(&mutex_);
|
||||
}
|
||||
if (closed_) return {};
|
||||
|
||||
SOCKET wifi_hotspot_socket = pending_client_sockets_.front();
|
||||
pending_client_sockets_.pop_front();
|
||||
LOG(INFO) << __func__ << ": Accepted a remote connection.";
|
||||
return std::make_unique<WifiHotspotSocket>(wifi_hotspot_socket);
|
||||
}
|
||||
|
||||
// Code when using WinRT API
|
||||
while (!closed_ && pending_sockets_.empty()) {
|
||||
cond_.Wait(&mutex_);
|
||||
}
|
||||
if (closed_) return {};
|
||||
|
||||
SOCKET wifi_hotspot_socket = pending_client_sockets_.front();
|
||||
pending_client_sockets_.pop_front();
|
||||
StreamSocket wifi_hotspot_socket = pending_sockets_.front();
|
||||
pending_sockets_.pop_front();
|
||||
LOG(INFO) << __func__ << ": Accepted a remote connection.";
|
||||
return std::make_unique<WifiHotspotSocket>(wifi_hotspot_socket);
|
||||
}
|
||||
|
||||
// Code when using WinRT API
|
||||
while (!closed_ && pending_sockets_.empty()) {
|
||||
cond_.Wait(&mutex_);
|
||||
}
|
||||
if (closed_) return {};
|
||||
|
||||
StreamSocket wifi_hotspot_socket = pending_sockets_.front();
|
||||
pending_sockets_.pop_front();
|
||||
LOG(INFO) << __func__ << ": Accepted a remote connection.";
|
||||
return std::make_unique<WifiHotspotSocket>(wifi_hotspot_socket);
|
||||
}
|
||||
|
||||
void WifiHotspotServerSocket::SetCloseNotifier(
|
||||
@@ -119,55 +149,70 @@ void WifiHotspotServerSocket::SetCloseNotifier(
|
||||
Exception WifiHotspotServerSocket::Close() {
|
||||
try {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
LOG(INFO) << __func__ << ": Close is called.";
|
||||
|
||||
if (closed_) {
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableHotspotWin32Socket)) {
|
||||
if (listen_socket_ != INVALID_SOCKET) {
|
||||
LOG(INFO) << ": Close listen_socket_: " << listen_socket_;
|
||||
// Trigger close event manually
|
||||
WSASetEvent(socket_events_[kSocketEventClose]);
|
||||
shutdown(listen_socket_, 2);
|
||||
shutdown(client_socket_, 2);
|
||||
closesocket(listen_socket_);
|
||||
closesocket(client_socket_);
|
||||
for (const auto &pending_socket : pending_client_sockets_) {
|
||||
if (pending_socket != INVALID_SOCKET) closesocket(pending_socket);
|
||||
}
|
||||
submittable_executor_.Shutdown();
|
||||
listen_socket_ = INVALID_SOCKET;
|
||||
client_socket_ = INVALID_SOCKET;
|
||||
for (auto &it : socket_events_) {
|
||||
WSACloseEvent(it);
|
||||
it = WSA_INVALID_EVENT;
|
||||
}
|
||||
WSACleanup();
|
||||
|
||||
pending_client_sockets_ = {};
|
||||
if (enable_blocking_socket_) {
|
||||
if (closed_) {
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
server_socket_.Close();
|
||||
closed_ = true;
|
||||
|
||||
if (close_notifier_ != nullptr) {
|
||||
close_notifier_();
|
||||
}
|
||||
|
||||
LOG(INFO) << __func__ << ": Close completed successfully.";
|
||||
} else {
|
||||
if (stream_socket_listener_ != nullptr) {
|
||||
stream_socket_listener_.ConnectionReceived(listener_event_token_);
|
||||
stream_socket_listener_.Close();
|
||||
stream_socket_listener_ = nullptr;
|
||||
LOG(INFO) << __func__ << ": Close is called.";
|
||||
|
||||
for (const auto &pending_socket : pending_sockets_) {
|
||||
pending_socket.Close();
|
||||
}
|
||||
|
||||
pending_sockets_ = {};
|
||||
if (closed_) {
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
}
|
||||
|
||||
closed_ = true;
|
||||
cond_.SignalAll();
|
||||
if (close_notifier_ != nullptr) {
|
||||
close_notifier_();
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableHotspotWin32Socket)) {
|
||||
if (listen_socket_ != INVALID_SOCKET) {
|
||||
LOG(INFO) << ": Close listen_socket_: " << listen_socket_;
|
||||
// Trigger close event manually
|
||||
WSASetEvent(socket_events_[kSocketEventClose]);
|
||||
shutdown(listen_socket_, 2);
|
||||
shutdown(client_socket_, 2);
|
||||
closesocket(listen_socket_);
|
||||
closesocket(client_socket_);
|
||||
for (const auto &pending_socket : pending_client_sockets_) {
|
||||
if (pending_socket != INVALID_SOCKET) closesocket(pending_socket);
|
||||
}
|
||||
submittable_executor_.Shutdown();
|
||||
listen_socket_ = INVALID_SOCKET;
|
||||
client_socket_ = INVALID_SOCKET;
|
||||
for (auto &it : socket_events_) {
|
||||
WSACloseEvent(it);
|
||||
it = WSA_INVALID_EVENT;
|
||||
}
|
||||
WSACleanup();
|
||||
|
||||
pending_client_sockets_ = {};
|
||||
}
|
||||
} else {
|
||||
if (stream_socket_listener_ != nullptr) {
|
||||
stream_socket_listener_.ConnectionReceived(listener_event_token_);
|
||||
stream_socket_listener_.Close();
|
||||
stream_socket_listener_ = nullptr;
|
||||
|
||||
for (const auto &pending_socket : pending_sockets_) {
|
||||
pending_socket.Close();
|
||||
}
|
||||
|
||||
pending_sockets_ = {};
|
||||
}
|
||||
}
|
||||
|
||||
closed_ = true;
|
||||
cond_.SignalAll();
|
||||
if (close_notifier_ != nullptr) {
|
||||
close_notifier_();
|
||||
}
|
||||
}
|
||||
|
||||
LOG(INFO) << __func__ << ": Close completed succesfully.";
|
||||
@@ -186,7 +231,7 @@ Exception WifiHotspotServerSocket::Close() {
|
||||
} catch (...) {
|
||||
closed_ = true;
|
||||
cond_.SignalAll();
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
}
|
||||
@@ -240,7 +285,7 @@ bool WifiHotspotServerSocket::SetupServerSocketWinRT() {
|
||||
<< ":Cannot accept connection on preferred port. WinRT exception: "
|
||||
<< error.code() << ": " << winrt::to_string(error.message());
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -258,7 +303,7 @@ bool WifiHotspotServerSocket::SetupServerSocketWinRT() {
|
||||
<< ": Cannot bind to any port. WinRT exception: " << error.code()
|
||||
<< ": " << winrt::to_string(error.message());
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -436,12 +481,21 @@ bool WifiHotspotServerSocket::listen() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableHotspotWin32Socket)) {
|
||||
return SetupServerSocketWinSock();
|
||||
if (enable_blocking_socket_) {
|
||||
if (!server_socket_.Listen(hotspot_ipaddr_, port_)) {
|
||||
LOG(ERROR) << "Failed to listen socket.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return SetupServerSocketWinRT();
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableHotspotWin32Socket)) {
|
||||
return SetupServerSocketWinSock();
|
||||
} else {
|
||||
return SetupServerSocketWinRT();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +543,7 @@ std::string WifiHotspotServerSocket::GetHotspotIpAddress() const {
|
||||
<< winrt::to_string(error.message());
|
||||
return {};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,15 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/flags/nearby_platform_feature_flags.h"
|
||||
#include "internal/platform/implementation/windows/nearby_client_socket.h"
|
||||
#include "internal/platform/implementation/windows/wifi_hotspot.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/logging.h"
|
||||
@@ -79,6 +85,15 @@ int send_sync(SOCKET s, const char* buf, int len, int flags) {
|
||||
|
||||
} // namespace
|
||||
|
||||
WifiHotspotSocket::WifiHotspotSocket() {
|
||||
enable_blocking_socket_ = NearbyFlags::GetInstance().GetBoolFlag(
|
||||
nearby::platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableBlockingSocket);
|
||||
client_socket_ = std::make_unique<NearbyClientSocket>();
|
||||
input_stream_ = SocketInputStream(client_socket_.get());
|
||||
output_stream_ = SocketOutputStream(client_socket_.get());
|
||||
}
|
||||
|
||||
WifiHotspotSocket::WifiHotspotSocket(StreamSocket socket) {
|
||||
stream_soket_ = socket;
|
||||
input_stream_ = SocketInputStream(socket.InputStream());
|
||||
@@ -91,48 +106,57 @@ WifiHotspotSocket::WifiHotspotSocket(SOCKET socket) {
|
||||
output_stream_ = SocketOutputStream(socket);
|
||||
}
|
||||
|
||||
WifiHotspotSocket::~WifiHotspotSocket() {
|
||||
try {
|
||||
if (stream_soket_ != nullptr || stream_soket_winsock_ != INVALID_SOCKET) {
|
||||
Close();
|
||||
}
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
}
|
||||
WifiHotspotSocket::WifiHotspotSocket(
|
||||
std::unique_ptr<NearbyClientSocket> socket) {
|
||||
enable_blocking_socket_ = NearbyFlags::GetInstance().GetBoolFlag(
|
||||
nearby::platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableBlockingSocket);
|
||||
client_socket_ = std::move(socket);
|
||||
input_stream_ = SocketInputStream(client_socket_.get());
|
||||
output_stream_ = SocketOutputStream(client_socket_.get());
|
||||
}
|
||||
|
||||
WifiHotspotSocket::~WifiHotspotSocket() { Close(); }
|
||||
|
||||
InputStream& WifiHotspotSocket::GetInputStream() { return input_stream_; }
|
||||
|
||||
OutputStream& WifiHotspotSocket::GetOutputStream() { return output_stream_; }
|
||||
|
||||
Exception WifiHotspotSocket::Close() {
|
||||
try {
|
||||
if (stream_soket_ != nullptr) {
|
||||
stream_soket_.Close();
|
||||
}
|
||||
if (stream_soket_winsock_ != INVALID_SOCKET) {
|
||||
closesocket(stream_soket_winsock_);
|
||||
stream_soket_winsock_ = INVALID_SOCKET;
|
||||
if (enable_blocking_socket_) {
|
||||
if (client_socket_ != nullptr) {
|
||||
return client_socket_->Close();
|
||||
}
|
||||
|
||||
return {Exception::kSuccess};
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
return {Exception::kIo};
|
||||
} else {
|
||||
try {
|
||||
if (stream_soket_ != nullptr) {
|
||||
stream_soket_.Close();
|
||||
}
|
||||
if (stream_soket_winsock_ != INVALID_SOCKET) {
|
||||
closesocket(stream_soket_winsock_);
|
||||
stream_soket_winsock_ = INVALID_SOCKET;
|
||||
}
|
||||
return {Exception::kSuccess};
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool WifiHotspotSocket::Connect(const std::string& ip_address, int port) {
|
||||
return client_socket_->Connect(ip_address, port);
|
||||
}
|
||||
|
||||
WifiHotspotSocket::SocketInputStream::SocketInputStream(
|
||||
IInputStream input_stream) {
|
||||
input_stream_ = input_stream;
|
||||
@@ -144,125 +168,160 @@ WifiHotspotSocket::SocketInputStream::SocketInputStream(SOCKET socket) {
|
||||
socket_type_ = SocketType::kWin32Socket;
|
||||
}
|
||||
|
||||
WifiHotspotSocket::SocketInputStream::SocketInputStream(
|
||||
NearbyClientSocket* client_socket) {
|
||||
enable_blocking_socket_ = NearbyFlags::GetInstance().GetBoolFlag(
|
||||
nearby::platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableBlockingSocket);
|
||||
client_socket_ = client_socket;
|
||||
}
|
||||
|
||||
ExceptionOr<ByteArray> WifiHotspotSocket::SocketInputStream::Read(
|
||||
std::int64_t size) {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
Buffer buffer = Buffer(size);
|
||||
if (enable_blocking_socket_) {
|
||||
if (client_socket_ == nullptr) {
|
||||
LOG(ERROR) << "Failed to read data due to no client socket.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
|
||||
auto ibuffer =
|
||||
input_stream_.ReadAsync(buffer, size, InputStreamOptions::None).get();
|
||||
return client_socket_->Read(size);
|
||||
} else {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
Buffer buffer = Buffer(size);
|
||||
|
||||
if (ibuffer.Length() != size) {
|
||||
LOG(WARNING) << "Only got part of data of needed.";
|
||||
auto ibuffer =
|
||||
input_stream_.ReadAsync(buffer, size, InputStreamOptions::None)
|
||||
.get();
|
||||
|
||||
if (ibuffer.Length() != size) {
|
||||
LOG(WARNING) << "Only got part of data of needed.";
|
||||
}
|
||||
|
||||
ByteArray data((char*)ibuffer.data(), ibuffer.Length());
|
||||
return ExceptionOr<ByteArray>(data);
|
||||
}
|
||||
|
||||
ByteArray data((char*)ibuffer.data(), ibuffer.Length());
|
||||
int result;
|
||||
int count = 0;
|
||||
|
||||
// When socket_type_ == SocketType::kWin32Socket
|
||||
if (size > read_buffer_.size()) {
|
||||
read_buffer_.resize(size);
|
||||
}
|
||||
|
||||
while (count < size) {
|
||||
result =
|
||||
recv_sync(socket_, read_buffer_.data() + count, size - count, 0);
|
||||
if (result == 0) {
|
||||
LOG(WARNING) << "Connection closed.";
|
||||
return {Exception::kIo};
|
||||
} else if (result < 0) {
|
||||
LOG(ERROR) << "recv failed with error: " << WSAGetLastError();
|
||||
return {Exception::kIo};
|
||||
} else {
|
||||
count += result;
|
||||
}
|
||||
}
|
||||
|
||||
ByteArray data(read_buffer_.data(), size);
|
||||
return ExceptionOr<ByteArray>(data);
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
|
||||
int result;
|
||||
int count = 0;
|
||||
|
||||
// When socket_type_ == SocketType::kWin32Socket
|
||||
if (size > read_buffer_.size()) {
|
||||
read_buffer_.resize(size);
|
||||
}
|
||||
|
||||
while (count < size) {
|
||||
result = recv_sync(socket_, read_buffer_.data() + count, size - count, 0);
|
||||
if (result == 0) {
|
||||
LOG(WARNING) << "Connection closed.";
|
||||
return {Exception::kIo};
|
||||
} else if (result < 0) {
|
||||
LOG(ERROR) << "recv failed with error: " << WSAGetLastError();
|
||||
return {Exception::kIo};
|
||||
} else {
|
||||
count += result;
|
||||
}
|
||||
}
|
||||
|
||||
ByteArray data(read_buffer_.data(), size);
|
||||
return ExceptionOr<ByteArray>(data);
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
}
|
||||
|
||||
ExceptionOr<size_t> WifiHotspotSocket::SocketInputStream::Skip(size_t offset) {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
Buffer buffer = Buffer(offset);
|
||||
|
||||
auto ibuffer =
|
||||
input_stream_.ReadAsync(buffer, offset, InputStreamOptions::None)
|
||||
.get();
|
||||
return ExceptionOr<size_t>((size_t)ibuffer.Length());
|
||||
}
|
||||
// When socket_type_ == SocketType::kWin32Socket
|
||||
int result;
|
||||
int count = 0;
|
||||
|
||||
// When socket_type_ == SocketType::kWin32Socket
|
||||
if (offset > read_buffer_.size()) {
|
||||
read_buffer_.resize(offset);
|
||||
if (enable_blocking_socket_) {
|
||||
if (client_socket_ == nullptr) {
|
||||
return {Exception::kIo};
|
||||
}
|
||||
|
||||
while (count < offset) {
|
||||
result =
|
||||
recv_sync(socket_, read_buffer_.data() + count, offset - count, 0);
|
||||
if (result == 0) {
|
||||
LOG(WARNING) << "Connection closed.";
|
||||
return {Exception::kIo};
|
||||
} else if (result < 0) {
|
||||
LOG(ERROR) << "recv failed with error: " << WSAGetLastError();
|
||||
return {Exception::kIo};
|
||||
} else {
|
||||
count += result;
|
||||
return client_socket_->Skip(offset);
|
||||
} else {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
Buffer buffer = Buffer(offset);
|
||||
|
||||
auto ibuffer =
|
||||
input_stream_.ReadAsync(buffer, offset, InputStreamOptions::None)
|
||||
.get();
|
||||
return ExceptionOr<size_t>((size_t)ibuffer.Length());
|
||||
}
|
||||
}
|
||||
// When socket_type_ == SocketType::kWin32Socket
|
||||
int result;
|
||||
int count = 0;
|
||||
|
||||
return ExceptionOr<size_t>(offset);
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
return {Exception::kIo};
|
||||
// When socket_type_ == SocketType::kWin32Socket
|
||||
if (offset > read_buffer_.size()) {
|
||||
read_buffer_.resize(offset);
|
||||
}
|
||||
|
||||
while (count < offset) {
|
||||
result =
|
||||
recv_sync(socket_, read_buffer_.data() + count, offset - count, 0);
|
||||
if (result == 0) {
|
||||
LOG(WARNING) << "Connection closed.";
|
||||
return {Exception::kIo};
|
||||
} else if (result < 0) {
|
||||
LOG(ERROR) << "recv failed with error: " << WSAGetLastError();
|
||||
return {Exception::kIo};
|
||||
} else {
|
||||
count += result;
|
||||
}
|
||||
}
|
||||
|
||||
return ExceptionOr<size_t>(offset);
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Exception WifiHotspotSocket::SocketInputStream::Close() {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
input_stream_.Close();
|
||||
} else {
|
||||
// When socket_type_ == SocketType::kWin32Socket
|
||||
shutdown(socket_, SD_RECEIVE);
|
||||
if (enable_blocking_socket_) {
|
||||
if (client_socket_ == nullptr) {
|
||||
return {Exception::kIo};
|
||||
}
|
||||
|
||||
return client_socket_->Close();
|
||||
} else {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
input_stream_.Close();
|
||||
} else {
|
||||
// When socket_type_ == SocketType::kWin32Socket
|
||||
shutdown(socket_, SD_RECEIVE);
|
||||
}
|
||||
return {Exception::kSuccess};
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
return {Exception::kSuccess};
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,87 +337,120 @@ WifiHotspotSocket::SocketOutputStream::SocketOutputStream(SOCKET socket) {
|
||||
socket_type_ = SocketType::kWin32Socket;
|
||||
}
|
||||
|
||||
WifiHotspotSocket::SocketOutputStream::SocketOutputStream(
|
||||
NearbyClientSocket* client_socket) {
|
||||
enable_blocking_socket_ = NearbyFlags::GetInstance().GetBoolFlag(
|
||||
nearby::platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableBlockingSocket);
|
||||
client_socket_ = client_socket;
|
||||
}
|
||||
|
||||
Exception WifiHotspotSocket::SocketOutputStream::Write(const ByteArray& data) {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
Buffer buffer = Buffer(data.size());
|
||||
std::memcpy(buffer.data(), data.data(), data.size());
|
||||
buffer.Length(data.size());
|
||||
if (enable_blocking_socket_) {
|
||||
if (client_socket_ == nullptr) {
|
||||
return {Exception::kIo};
|
||||
}
|
||||
|
||||
return client_socket_->Write(data);
|
||||
} else {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
Buffer buffer = Buffer(data.size());
|
||||
std::memcpy(buffer.data(), data.data(), data.size());
|
||||
buffer.Length(data.size());
|
||||
|
||||
output_stream_.WriteAsync(buffer).get();
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
int result;
|
||||
int count = 0;
|
||||
|
||||
while (count < data.size()) {
|
||||
result =
|
||||
send_sync(socket_, data.data() + count, data.size() - count, 0);
|
||||
if (result == 0) {
|
||||
LOG(WARNING) << "Connection closed.";
|
||||
return {Exception::kIo};
|
||||
} else if (result < 0) {
|
||||
LOG(ERROR) << "Failed to send data with error: " << WSAGetLastError();
|
||||
return {Exception::kIo};
|
||||
} else {
|
||||
count += result;
|
||||
}
|
||||
}
|
||||
|
||||
output_stream_.WriteAsync(buffer).get();
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
int result;
|
||||
int count = 0;
|
||||
|
||||
while (count < data.size()) {
|
||||
result = send_sync(socket_, data.data() + count, data.size() - count, 0);
|
||||
if (result == 0) {
|
||||
LOG(WARNING) << "Connection closed.";
|
||||
return {Exception::kIo};
|
||||
} else if (result < 0) {
|
||||
LOG(ERROR) << "Failed to send data with error: " << WSAGetLastError();
|
||||
return {Exception::kIo};
|
||||
} else {
|
||||
count += result;
|
||||
}
|
||||
catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
}
|
||||
|
||||
Exception WifiHotspotSocket::SocketOutputStream::Flush() {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
output_stream_.FlushAsync().get();
|
||||
if (enable_blocking_socket_) {
|
||||
if (client_socket_ == nullptr) {
|
||||
return {Exception::kIo};
|
||||
}
|
||||
|
||||
return client_socket_->Flush();
|
||||
} else {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
output_stream_.FlushAsync().get();
|
||||
}
|
||||
return {Exception::kSuccess};
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
return {Exception::kSuccess};
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
}
|
||||
|
||||
Exception WifiHotspotSocket::SocketOutputStream::Close() {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
output_stream_.Close();
|
||||
} else {
|
||||
// When socket_type_ == SocketType::kWin32Socket
|
||||
shutdown(socket_, SD_SEND);
|
||||
if (enable_blocking_socket_) {
|
||||
if (client_socket_ == nullptr) {
|
||||
return {Exception::kIo};
|
||||
}
|
||||
|
||||
return client_socket_->Close();
|
||||
} else {
|
||||
try {
|
||||
if (socket_type_ == SocketType::kWinRTSocket) {
|
||||
output_stream_.Close();
|
||||
} else {
|
||||
// When socket_type_ == SocketType::kWin32Socket
|
||||
shutdown(socket_, SD_SEND);
|
||||
}
|
||||
return {Exception::kSuccess};
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
return {Exception::kSuccess};
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
|
||||
return {Exception::kIo};
|
||||
} catch (const winrt::hresult_error& error) {
|
||||
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
|
||||
<< winrt::to_string(error.message());
|
||||
return {Exception::kIo};
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exeption.";
|
||||
return {Exception::kIo};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user