From beaab63d4b5a3100ac8d1982190a94c7592d7fb5 Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Thu, 4 Sep 2025 16:04:36 -0700 Subject: [PATCH] Cleanup blocking socket flag. PiperOrigin-RevId: 803211100 --- .../flags/nearby_platform_feature_flags.h | 8 - .../implementation/windows/wifi_hotspot.h | 103 +---- .../windows/wifi_hotspot_medium.cc | 142 ++----- .../windows/wifi_hotspot_server_socket.cc | 400 ++---------------- .../windows/wifi_hotspot_socket.cc | 335 ++------------- .../implementation/windows/wifi_lan.h | 5 - .../implementation/windows/wifi_lan_medium.cc | 203 ++------- .../windows/wifi_lan_server_socket.cc | 178 ++------ .../implementation/windows/wifi_lan_socket.cc | 224 ++-------- 9 files changed, 180 insertions(+), 1418 deletions(-) diff --git a/internal/platform/flags/nearby_platform_feature_flags.h b/internal/platform/flags/nearby_platform_feature_flags.h index 846a9a21..e226d27d 100644 --- a/internal/platform/flags/nearby_platform_feature_flags.h +++ b/internal/platform/flags/nearby_platform_feature_flags.h @@ -29,10 +29,6 @@ constexpr absl::string_view kConfigPackage = "nearby"; // The Nearby Platform features. namespace nearby_platform_feature { -// Disable/Enable win32 socket implementation for Wi-Fi hotspot. -constexpr auto kEnableHotspotWin32Socket = - flags::Flag(kConfigPackage, "45401992", true); - // The maximum scanning times for available hotspots. constexpr auto kWifiHotspotScanMaxRetries = flags::Flag(kConfigPackage, "45415883", 3); @@ -69,10 +65,6 @@ constexpr auto kEnableNewBluetoothRefactor = constexpr auto kEnableWifiHotspotNativeScan = flags::Flag(kConfigPackage, "45670001", false); -// Enable/Disable blocking socket -constexpr auto kEnableBlockingSocket = - flags::Flag(kConfigPackage, "45672381", false); - // The send buffer size of blocking socket constexpr auto kSocketSendBufferSize = flags::Flag(kConfigPackage, "45673785", 524288); diff --git a/internal/platform/implementation/windows/wifi_hotspot.h b/internal/platform/implementation/windows/wifi_hotspot.h index 95bcf093..2b516528 100644 --- a/internal/platform/implementation/windows/wifi_hotspot.h +++ b/internal/platform/implementation/windows/wifi_hotspot.h @@ -22,7 +22,6 @@ // Standard C/C++ headers #include -#include #include #include #include @@ -37,26 +36,16 @@ #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" // WinRT headers #include "absl/types/optional.h" -#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Enumeration.h" -#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.WiFi.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.WiFiDirect.h" -#include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.Collections.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.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/generated/winrt/Windows.Security.Credentials.h" -#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" @@ -66,58 +55,23 @@ namespace nearby { namespace windows { using ::winrt::fire_and_forget; -using ::winrt::Windows::Devices::WiFiDirect:: - WiFiDirectAdvertisementListenStateDiscoverability; using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectAdvertisementPublisher; -using ::winrt::Windows::Devices::WiFiDirect:: - WiFiDirectAdvertisementPublisherStatus; using ::winrt::Windows::Devices::WiFiDirect:: WiFiDirectAdvertisementPublisherStatusChangedEventArgs; using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectConnectionListener; -using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectConnectionRequest; using ::winrt::Windows::Devices::WiFiDirect:: WiFiDirectConnectionRequestedEventArgs; -using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectConnectionStatus; using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectDevice; -using ::winrt::Windows::Devices::WiFi::WiFiAccessStatus; -using ::winrt::Windows::Devices::WiFi::WiFiAdapter; -using ::winrt::Windows::Devices::WiFi::WiFiAvailableNetwork; -using ::winrt::Windows::Devices::WiFi::WiFiConnectionStatus; -using ::winrt::Windows::Devices::WiFi::WiFiReconnectionKind; - -using ::winrt::Windows::Devices::Enumeration::DeviceInformation; -using ::winrt::Windows::Devices::Enumeration::DeviceInformationPairing; - -using ::winrt::Windows::Storage::Streams::Buffer; -using ::winrt::Windows::Storage::Streams::IInputStream; -using ::winrt::Windows::Storage::Streams::InputStreamOptions; -using ::winrt::Windows::Storage::Streams::IOutputStream; - -using ::winrt::Windows::Security::Credentials::PasswordCredential; -using ::winrt::Windows::Security::Cryptography::CryptographicBuffer; - -using ::winrt::Windows::Networking::HostName; -using ::winrt::Windows::Networking::HostNameType; -using ::winrt::Windows::Networking::Connectivity::ConnectionProfile; -using ::winrt::Windows::Networking::Connectivity::ConnectionProfileDeleteStatus; -using ::winrt::Windows::Networking::Connectivity::NetworkInformation; -using ::winrt::Windows::Networking::Sockets::StreamSocket; -using ::winrt::Windows::Networking::Sockets::StreamSocketListener; -using ::winrt::Windows::Networking::Sockets:: - StreamSocketListenerConnectionReceivedEventArgs; - // WifiHotspotSocket wraps the socket functions to read and write stream. // In WiFi HOTSPOT, A WifiHotspotSocket will be passed to -// StartAcceptingConnections's callback when Winsock Server Socket(or -// StreamSocketListener) receives a new connection. When call API to connect to -// remote WiFi Hotspot service, also will return a WifiHotspotSocket to caller. +// 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 WifiHotspotSocket to caller. class WifiHotspotSocket : public api::WifiHotspotSocket { public: WifiHotspotSocket(); explicit WifiHotspotSocket(std::unique_ptr socket); - explicit WifiHotspotSocket(StreamSocket socket); - explicit WifiHotspotSocket(SOCKET socket); WifiHotspotSocket(const WifiHotspotSocket&) = default; WifiHotspotSocket(WifiHotspotSocket&&) = default; ~WifiHotspotSocket() override; @@ -144,12 +98,9 @@ class WifiHotspotSocket : public api::WifiHotspotSocket { 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 class SocketInputStream : public InputStream { public: - explicit SocketInputStream(IInputStream input_stream); - explicit SocketInputStream(SOCKET socket); explicit SocketInputStream(NearbyClientSocket* client_socket); ~SocketInputStream() override = default; @@ -158,19 +109,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 class SocketOutputStream : public OutputStream { public: - explicit SocketOutputStream(IOutputStream output_stream); - explicit SocketOutputStream(SOCKET socket); explicit SocketOutputStream(NearbyClientSocket* client_socket); ~SocketOutputStream() override = default; @@ -179,20 +123,13 @@ 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 - SOCKET stream_soket_winsock_ = INVALID_SOCKET; - StreamSocket stream_soket_{nullptr}; SocketInputStream input_stream_{nullptr}; SocketOutputStream output_stream_{nullptr}; - bool enable_blocking_socket_ = false; std::unique_ptr client_socket_; }; @@ -211,10 +148,6 @@ class WifiHotspotServerSocket : public api::WifiHotspotServerSocket { int GetPort() const override; void SetPort(int port) { port_ = port; } - StreamSocketListener GetSocketListener() const { - return stream_socket_listener_; - } - // Blocks until either: // - at least one incoming connection request is available, or // - ServerSocket is closed. @@ -234,8 +167,6 @@ 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: @@ -243,36 +174,11 @@ class WifiHotspotServerSocket : public api::WifiHotspotServerSocket { static constexpr int kSocketEventListen = 0; static constexpr int kSocketEventClose = 1; - // The listener is accepting incoming connections - fire_and_forget Listener_ConnectionReceived( - StreamSocketListener listener, - StreamSocketListenerConnectionReceivedEventArgs const& args); - bool SetupServerSocketWinRT(); - bool SetupServerSocketWinSock(); - // Retrieves hotspot IP address from local machine std::string GetHotspotIpAddress() const; - void SocketErrorNotice(absl::string_view reason); - mutable absl::Mutex mutex_; - absl::CondVar cond_; - SubmittableExecutor submittable_executor_; - std::deque pending_sockets_ ABSL_GUARDED_BY(mutex_); - StreamSocketListener stream_socket_listener_{nullptr}; - winrt::event_token listener_event_token_{}; - - std::deque pending_client_sockets_ ABSL_GUARDED_BY(mutex_); - SOCKET listen_socket_ = INVALID_SOCKET; - SOCKET client_socket_ = INVALID_SOCKET; - - // closesocket cannot trigger FD_CLOSE on listener socket. In order to avoid - // blocking in WSAWaitForMultipleEvents, we use a socket event to trigger - // WSAWaitForMultipleEvents safely. - // The socket_events_ has 2 events, the first one is to handle normal socket - // event, and the second one is to handle event to close the socket manually. - WSAEVENT socket_events_[kSocketEventsCount]; // Close notifier absl::AnyInvocable close_notifier_ = nullptr; @@ -369,9 +275,6 @@ class WifiHotspotMedium : public api::WifiHotspotMedium { // Scheduler for timeout. ScheduledExecutor scheduled_executor_; - // Scheduled task for connection timeout. - std::shared_ptr connection_timeout_ = nullptr; - // connects Wi-Fi hotspot using native API. WifiHotspotNative wifi_hotspot_native_; std::optional connected_hotspot_profile_name_; diff --git a/internal/platform/implementation/windows/wifi_hotspot_medium.cc b/internal/platform/implementation/windows/wifi_hotspot_medium.cc index a1b9f92d..3adb07a6 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_medium.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_medium.cc @@ -19,7 +19,6 @@ #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" @@ -32,6 +31,8 @@ #include "internal/platform/implementation/platform.h" #include "internal/platform/implementation/wifi_hotspot.h" #include "internal/platform/implementation/wifi_utils.h" +#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Enumeration.h" +#include "internal/platform/implementation/windows/generated/winrt/Windows.Security.Credentials.h" #include "internal/platform/implementation/windows/string_utils.h" #include "internal/platform/implementation/windows/utils.h" #include "internal/platform/implementation/windows/wifi_hotspot.h" @@ -42,8 +43,13 @@ namespace nearby { namespace windows { namespace { +using ::winrt::Windows::Devices::WiFiDirect:: + WiFiDirectAdvertisementPublisherStatus; +using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectConnectionRequest; +using ::winrt::Windows::Security::Credentials::PasswordCredential; + constexpr absl::string_view kHotspotSsidFileName = "ssid.txt"; -} +} // namespace WifiHotspotMedium::WifiHotspotMedium() { std::string ssid = GetStoredHotspotSsid(); @@ -119,119 +125,41 @@ std::unique_ptr WifiHotspotMedium::ConnectToService( << "ms, connection timeout=" << wifi_hotspot_client_socket_connect_timeout_millis << "ms"; - 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(); + 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(); - // setup cancel listener - std::unique_ptr - connection_cancellation_listener = nullptr; - 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( - cancellation_flag, [socket = wifi_hotspot_socket.get()]() { - LOG(WARNING) << "connect is closed due to it is cancelled."; - socket->Close(); - }); + // setup cancel listener + std::unique_ptr connection_cancellation_listener = + nullptr; + if (cancellation_flag != nullptr) { + if (cancellation_flag->Cancelled()) { + LOG(INFO) << "connect has been cancelled to service " << ipv4_address + << ":" << port; + return nullptr; } - 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; - } - - LOG(INFO) << "connected to remote service " << ipv4_address << ":" - << port; - return wifi_hotspot_socket; + connection_cancellation_listener = + std::make_unique( + cancellation_flag, [socket = wifi_hotspot_socket.get()]() { + LOG(WARNING) << "connect is closed due to it is cancelled."; + socket->Close(); + }); } - 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 - 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( - 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(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; - } - + 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; } - return nullptr; + + 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; } std::unique_ptr diff --git a/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc b/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc index e64691e9..0bf4b04a 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_server_socket.cc @@ -31,6 +31,8 @@ #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.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/utils.h" #include "internal/platform/implementation/windows/wifi_hotspot.h" @@ -39,102 +41,31 @@ namespace nearby { namespace windows { namespace { +using ::winrt::Windows::Networking::Connectivity::NetworkInformation; +using ::winrt::Windows::Networking::HostNameType; using ::winrt::Windows::Networking::Sockets::SocketQualityOfService; } // namespace -WifiHotspotServerSocket::WifiHotspotServerSocket(int port) : port_(port) { - 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(int port) : port_(port) {} WifiHotspotServerSocket::~WifiHotspotServerSocket() { Close(); } std::string WifiHotspotServerSocket::GetIPAddress() const { - if (enable_blocking_socket_) { - return server_socket_.GetIPAddress(); - } else { - 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 {}; - } - } - - return GetHotspotIpAddress(); - } + return server_socket_.GetIPAddress(); } int WifiHotspotServerSocket::GetPort() const { - if (enable_blocking_socket_) { - return server_socket_.GetPort(); - } else { - 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 server_socket_.GetPort(); } std::unique_ptr WifiHotspotServerSocket::Accept() { - if (enable_blocking_socket_) { - auto client_socket = server_socket_.Accept(); - if (client_socket == nullptr) { - return nullptr; - } - - LOG(INFO) << __func__ << ": Accepted a remote connection."; - return std::make_unique(std::move(client_socket)); - } else { - absl::MutexLock lock(&mutex_); - VLOG(1) << __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(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(wifi_hotspot_socket); + auto client_socket = server_socket_.Accept(); + if (client_socket == nullptr) { + return nullptr; } + + LOG(INFO) << __func__ << ": Accepted a remote connection."; + return std::make_unique(std::move(client_socket)); } void WifiHotspotServerSocket::SetCloseNotifier( @@ -145,306 +76,35 @@ void WifiHotspotServerSocket::SetCloseNotifier( Exception WifiHotspotServerSocket::Close() { try { absl::MutexLock lock(&mutex_); - if (enable_blocking_socket_) { - if (closed_) { - return {Exception::kSuccess}; - } + if (closed_) { + return {Exception::kSuccess}; + } - server_socket_.Close(); - closed_ = true; + server_socket_.Close(); + closed_ = true; - if (close_notifier_ != nullptr) { - close_notifier_(); - } - } else { - VLOG(1) << __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_ = {}; - } - } 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_(); - } + if (close_notifier_ != nullptr) { + close_notifier_(); } LOG(INFO) << __func__ << ": Close completed succesfully."; return {Exception::kSuccess}; } catch (std::exception exception) { closed_ = true; - cond_.SignalAll(); LOG(ERROR) << __func__ << ": Exception: " << exception.what(); return {Exception::kIo}; } catch (const winrt::hresult_error &error) { closed_ = true; - cond_.SignalAll(); LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": " << winrt::to_string(error.message()); return {Exception::kIo}; } catch (...) { closed_ = true; - cond_.SignalAll(); LOG(ERROR) << __func__ << ": Unknown exception."; return {Exception::kIo}; } } -fire_and_forget WifiHotspotServerSocket::Listener_ConnectionReceived( - StreamSocketListener listener, - StreamSocketListenerConnectionReceivedEventArgs const &args) { - absl::MutexLock lock(&mutex_); - LOG(INFO) << __func__ << ": Received connection."; - - if (closed_) { - return fire_and_forget{}; - } - - pending_sockets_.push_back(args.Socket()); - cond_.SignalAll(); - return fire_and_forget{}; -} - -bool WifiHotspotServerSocket::SetupServerSocketWinRT() { - // Setup stream socket listener. - stream_socket_listener_ = StreamSocketListener(); - - stream_socket_listener_.Control().QualityOfService( - SocketQualityOfService::LowLatency); - - stream_socket_listener_.Control().KeepAlive(true); - - // Setup socket event of ConnectionReceived. - listener_event_token_ = stream_socket_listener_.ConnectionReceived( - {this, &WifiHotspotServerSocket::Listener_ConnectionReceived}); - - try { - HostName host_name{winrt::to_hstring(hotspot_ipaddr_)}; - stream_socket_listener_ - .BindEndpointAsync(host_name, winrt::to_hstring(port_)) - .get(); - if (port_ == 0) { - port_ = - std::stoi(stream_socket_listener_.Information().LocalPort().c_str()); - } - - return true; - } catch (std::exception exception) { - LOG(ERROR) << __func__ - << ": Cannot accept connection on preferred port. Exception: " - << exception.what(); - } catch (const winrt::hresult_error &error) { - LOG(ERROR) - << __func__ - << ":Cannot accept connection on preferred port. WinRT exception: " - << error.code() << ": " << winrt::to_string(error.message()); - } catch (...) { - LOG(ERROR) << __func__ << ": Unknown exception."; - } - - try { - stream_socket_listener_.BindServiceNameAsync({}).get(); - // need to save the port information. - port_ = - std::stoi(stream_socket_listener_.Information().LocalPort().c_str()); - LOG(INFO) << "Server Socket port: " << port_; - return true; - } catch (std::exception exception) { - LOG(ERROR) << __func__ - << ": Cannot bind to any port. Exception: " << exception.what(); - } catch (const winrt::hresult_error &error) { - LOG(ERROR) << __func__ - << ": Cannot bind to any port. WinRT exception: " << error.code() - << ": " << winrt::to_string(error.message()); - } catch (...) { - LOG(ERROR) << __func__ << ": Unknown exception."; - } - - return false; -} - -void WifiHotspotServerSocket::SocketErrorNotice(absl::string_view reason) { - LOG(WARNING) << "socket error. " << reason - << " failed with error: " << WSAGetLastError(); - for (auto &it : socket_events_) { - if (it != WSA_INVALID_EVENT) { - WSACloseEvent(it); - it = WSA_INVALID_EVENT; - } - } - closesocket(listen_socket_); - WSACleanup(); -} - -bool WifiHotspotServerSocket::SetupServerSocketWinSock() { - WSADATA wsa_data; - int flag = 1; - - int result = WSAStartup(MAKEWORD(2, 2), &wsa_data); - if (result != 0) { - LOG(WARNING) << "WSAStartup failed with error:" << result; - return false; - } - - listen_socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (listen_socket_ == INVALID_SOCKET) { - LOG(WARNING) << "Failed to get socket"; - WSACleanup(); - return false; - } - struct sockaddr_in serv_addr; - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(port_); - serv_addr.sin_addr.s_addr = inet_addr(hotspot_ipaddr_.c_str()); - - unsigned long qos = 1; // NOLINT - ioctlsocket(listen_socket_, SIO_SET_QOS, &qos); - setsockopt(listen_socket_, SOL_SOCKET, SO_KEEPALIVE, (const char *)&flag, - sizeof(flag)); - if (bind(listen_socket_, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == - SOCKET_ERROR) { - SocketErrorNotice("Bind"); - return false; - } - VLOG(1) << "Bind socket successful"; - - int size = sizeof(serv_addr); - memset(&serv_addr, 0, size); - if (getsockname(listen_socket_, (struct sockaddr *)&serv_addr, &size) == - SOCKET_ERROR) { - SocketErrorNotice("Getsockname"); - return false; - } - port_ = ntohs(serv_addr.sin_port); - - socket_events_[kSocketEventListen] = WSACreateEvent(); - if (socket_events_[kSocketEventListen] == WSA_INVALID_EVENT) { - SocketErrorNotice("WSACreateEvent"); - return false; - } - - socket_events_[kSocketEventClose] = WSACreateEvent(); - if (socket_events_[kSocketEventClose] == WSA_INVALID_EVENT) { - SocketErrorNotice("WSACreateEvent"); - return false; - } - - // Associate event types FD_ACCEPT and FD_CLOSE with the listen_socket_ and - // socket_event - if (WSAEventSelect(listen_socket_, socket_events_[kSocketEventListen], - FD_ACCEPT | FD_CLOSE) == SOCKET_ERROR) { - SocketErrorNotice("WSAEventSelect"); - return false; - } - - if (::listen(listen_socket_, SOMAXCONN) == SOCKET_ERROR) { - SocketErrorNotice("Listen"); - return false; - } - LOG(INFO) << "Hotspot Server Socket " << listen_socket_ - << " started to listen on port: " << port_; - - submittable_executor_.Execute([this]() { - DWORD index; - WSANETWORKEVENTS network_events; - // Wait for network events on all sockets - index = WSAWaitForMultipleEvents(kSocketEventsCount, socket_events_, FALSE, - WSA_INFINITE, FALSE); - - VLOG(1) << "Hotspot Server Socket " << listen_socket_ - << " received event index: " << index; - if (index == WSA_WAIT_TIMEOUT || index == WSA_WAIT_FAILED) { - LOG(INFO) << "Hotspot Server Socket timout or failed "; - return false; - } - - index = index - WSA_WAIT_EVENT_0; - if (index == kSocketEventClose) { - // the socket is closed by SDK - LOG(INFO) << "listner socket is closed."; - return false; - } - - // Iterate through all events and enumerate - if (WSAEnumNetworkEvents(listen_socket_, socket_events_[index], - &network_events) == SOCKET_ERROR) { - LOG(INFO) << "Iterate through all events failed"; - return false; - } - if (network_events.lNetworkEvents & FD_CLOSE) { - LOG(INFO) << "Reveived FD_CLOSE event"; - return false; - } - if (network_events.lNetworkEvents & FD_ACCEPT) { - client_socket_ = accept(listen_socket_, nullptr, nullptr); - VLOG(1) << "Reveived FD_ACCEPT event."; - - if (client_socket_ == INVALID_SOCKET) { - return false; - } - - if (WSAEventSelect(listen_socket_, socket_events_[kSocketEventListen], - 0) == SOCKET_ERROR) { - LOG(WARNING) - << "Remove association between listen_socket_ and event failed: " - << WSAGetLastError(); - } - - LOG(INFO) << "Hotspot Server Client Socket created: " << client_socket_; - if (closed_) { - return false; - } - { - absl::MutexLock lock(&mutex_); - pending_client_sockets_.push_back(client_socket_); - cond_.SignalAll(); - } - } - return true; - }); - return true; -} - bool WifiHotspotServerSocket::listen() { // Get current IP addresses of the device. int64_t ip_address_max_retries = NearbyFlags::GetInstance().GetInt64Flag( @@ -473,22 +133,12 @@ bool WifiHotspotServerSocket::listen() { return false; } - if (enable_blocking_socket_) { - if (!server_socket_.Listen(hotspot_ipaddr_, port_)) { - LOG(ERROR) << "Failed to listen socket."; - return false; - } - - return true; - } else { - if (NearbyFlags::GetInstance().GetBoolFlag( - platform::config_package_nearby::nearby_platform_feature:: - kEnableHotspotWin32Socket)) { - return SetupServerSocketWinSock(); - } else { - return SetupServerSocketWinRT(); - } + if (!server_socket_.Listen(hotspot_ipaddr_, port_)) { + LOG(ERROR) << "Failed to listen socket."; + return false; } + + return true; } std::string WifiHotspotServerSocket::GetHotspotIpAddress() const { diff --git a/internal/platform/implementation/windows/wifi_hotspot_socket.cc b/internal/platform/implementation/windows/wifi_hotspot_socket.cc index 7d460980..1b8dc053 100644 --- a/internal/platform/implementation/windows/wifi_hotspot_socket.cc +++ b/internal/platform/implementation/windows/wifi_hotspot_socket.cc @@ -86,31 +86,13 @@ 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(); input_stream_ = SocketInputStream(client_socket_.get()); output_stream_ = SocketOutputStream(client_socket_.get()); } -WifiHotspotSocket::WifiHotspotSocket(StreamSocket socket) { - stream_soket_ = socket; - input_stream_ = SocketInputStream(socket.InputStream()); - output_stream_ = SocketOutputStream(socket.OutputStream()); -} - -WifiHotspotSocket::WifiHotspotSocket(SOCKET socket) { - stream_soket_winsock_ = socket; - input_stream_ = SocketInputStream(socket); - output_stream_ = SocketOutputStream(socket); -} - WifiHotspotSocket::WifiHotspotSocket( std::unique_ptr 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()); @@ -123,335 +105,76 @@ InputStream& WifiHotspotSocket::GetInputStream() { return input_stream_; } OutputStream& WifiHotspotSocket::GetOutputStream() { return output_stream_; } Exception WifiHotspotSocket::Close() { - if (enable_blocking_socket_) { - if (client_socket_ != nullptr) { - return client_socket_->Close(); - } - - return {Exception::kSuccess}; - } 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}; - } + if (client_socket_ != nullptr) { + return client_socket_->Close(); } + + return {Exception::kSuccess}; } 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; - socket_type_ = SocketType::kWinRTSocket; -} - -WifiHotspotSocket::SocketInputStream::SocketInputStream(SOCKET socket) { - 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 WifiHotspotSocket::SocketInputStream::Read( std::int64_t size) { - if (enable_blocking_socket_) { - if (client_socket_ == nullptr) { - LOG(ERROR) << "Failed to read data due to no client socket."; - return {Exception::kIo}; - } - - return client_socket_->Read(size); - } else { - try { - if (socket_type_ == SocketType::kWinRTSocket) { - Buffer buffer = Buffer(size); - - 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(data); - } - - 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(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}; - } + if (client_socket_ == nullptr) { + LOG(ERROR) << "Failed to read data due to no client socket."; + return {Exception::kIo}; } + + return client_socket_->Read(size); } ExceptionOr WifiHotspotSocket::SocketInputStream::Skip(size_t offset) { - if (enable_blocking_socket_) { - if (client_socket_ == nullptr) { - return {Exception::kIo}; - } - - 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)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); - } - - 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(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}; - } + if (client_socket_ == nullptr) { + return {Exception::kIo}; } + + return client_socket_->Skip(offset); } Exception WifiHotspotSocket::SocketInputStream::Close() { - 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}; - } + if (client_socket_ == nullptr) { + return {Exception::kIo}; } + + return client_socket_->Close(); } // SocketOutputStream -WifiHotspotSocket::SocketOutputStream::SocketOutputStream( - IOutputStream output_stream) { - output_stream_ = output_stream; - socket_type_ = SocketType::kWinRTSocket; -} - -WifiHotspotSocket::SocketOutputStream::SocketOutputStream(SOCKET socket) { - 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) { - 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; - } - } - - 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}; - } + if (client_socket_ == nullptr) { + return {Exception::kIo}; } + + return client_socket_->Write(data); } Exception WifiHotspotSocket::SocketOutputStream::Flush() { - 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}; - } + if (client_socket_ == nullptr) { + return {Exception::kIo}; } + + return client_socket_->Flush(); } Exception WifiHotspotSocket::SocketOutputStream::Close() { - 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}; - } + if (client_socket_ == nullptr) { + return {Exception::kIo}; } + + return client_socket_->Close(); } } // namespace windows diff --git a/internal/platform/implementation/windows/wifi_lan.h b/internal/platform/implementation/windows/wifi_lan.h index 1cec735b..585bb928 100644 --- a/internal/platform/implementation/windows/wifi_lan.h +++ b/internal/platform/implementation/windows/wifi_lan.h @@ -142,7 +142,6 @@ class WifiLanSocket : public api::WifiLanSocket { Exception Close() override; private: - bool enable_blocking_socket_ = false; IInputStream input_stream_{nullptr}; Buffer read_buffer_{nullptr}; NearbyClientSocket* client_socket_{nullptr}; @@ -160,7 +159,6 @@ class WifiLanSocket : public api::WifiLanSocket { Exception Close() override; private: - bool enable_blocking_socket_ = false; IOutputStream output_stream_{nullptr}; NearbyClientSocket* client_socket_{nullptr}; }; @@ -170,7 +168,6 @@ class WifiLanSocket : public api::WifiLanSocket { SocketInputStream input_stream_{nullptr}; SocketOutputStream output_stream_{nullptr}; - bool enable_blocking_socket_ = false; std::unique_ptr client_socket_; }; @@ -239,8 +236,6 @@ class WifiLanServerSocket : public api::WifiLanServerSocket { int port_ = 0; bool closed_ = false; - // Flag to enable blocking socket. - bool enable_blocking_socket_ = false; NearbyServerSocket server_socket_; }; diff --git a/internal/platform/implementation/windows/wifi_lan_medium.cc b/internal/platform/implementation/windows/wifi_lan_medium.cc index cbea94b6..4bd07c1a 100644 --- a/internal/platform/implementation/windows/wifi_lan_medium.cc +++ b/internal/platform/implementation/windows/wifi_lan_medium.cc @@ -120,75 +120,18 @@ bool WifiLanMedium::StartAdvertising(const NsdServiceInfo& nsd_service_info) { absl::flat_hash_map text_records = nsd_service_info.GetTxtRecords(); - if (NearbyFlags::GetInstance().GetBoolFlag( - nearby::platform::config_package_nearby::nearby_platform_feature:: - kEnableBlockingSocket)) { - bool result = wifi_lan_mdns_.StartMdnsService( - service_name_, nsd_service_info.GetServiceType(), - nsd_service_info.GetPort(), text_records); + bool result = wifi_lan_mdns_.StartMdnsService( + service_name_, nsd_service_info.GetServiceType(), + nsd_service_info.GetPort(), text_records); - if (result) { - LOG(INFO) << "started to mDNS advertising."; - medium_status_ |= kMediumStatusAdvertising; - return true; - } - - LOG(ERROR) << "failed to start mDNS advertising."; - return false; - - } else { - std::string instance_name = - absl::StrFormat(kMdnsInstanceNameFormat, service_name_, - nsd_service_info.GetServiceType()); - - LOG(INFO) << "mDNS instance name is " << instance_name; - - dnssd_service_instance_ = DnssdServiceInstance{ - string_utils::StringToWideString(instance_name), - nullptr, // let windows use default computer's local name - (uint16_t)nsd_service_info.GetPort()}; - - // Add TextRecords from NsdServiceInfo - auto text_attributes = dnssd_service_instance_.TextAttributes(); - - auto it = text_records.begin(); - while (it != text_records.end()) { - text_attributes.Insert(string_utils::StringToWideString(it->first), - string_utils::StringToWideString(it->second)); - it++; - } - - if (server_socket_ptr == nullptr) { - LOG(ERROR) << "server socket is null."; - return false; - } - - dnssd_regirstraion_result_ = dnssd_service_instance_ - .RegisterStreamSocketListenerAsync( - server_socket_ptr->GetSocketListener()) - .get(); - - if (dnssd_regirstraion_result_.HasInstanceNameChanged()) { - LOG(WARNING) << "advertising instance name was changed due to have " - "same name instance was running."; - // stop the service and return false - StopAdvertising(nsd_service_info); - return false; - } - - if (dnssd_regirstraion_result_.Status() == - DnssdRegistrationStatus::Success) { - LOG(INFO) << "started to advertising."; - medium_status_ |= kMediumStatusAdvertising; - return true; - } - - // Clean up - LOG(ERROR) << "failed to start advertising due to registration failure."; - dnssd_service_instance_ = nullptr; - dnssd_regirstraion_result_ = nullptr; - return false; + if (result) { + LOG(INFO) << "started to mDNS advertising."; + medium_status_ |= kMediumStatusAdvertising; + return true; } + + LOG(ERROR) << "failed to start mDNS advertising."; + return false; } bool WifiLanMedium::StopAdvertising(const NsdServiceInfo& nsd_service_info) { @@ -199,33 +142,19 @@ bool WifiLanMedium::StopAdvertising(const NsdServiceInfo& nsd_service_info) { return false; } - if (NearbyFlags::GetInstance().GetBoolFlag( - nearby::platform::config_package_nearby::nearby_platform_feature:: - kEnableBlockingSocket)) { - // The service may be running under WinRT when the flag is enabled. - dnssd_service_instance_ = nullptr; + // The service may be running under WinRT when the flag is enabled. + dnssd_service_instance_ = nullptr; - bool result = wifi_lan_mdns_.StopMdnsService(); + bool result = wifi_lan_mdns_.StopMdnsService(); - if (result) { - medium_status_ &= (~kMediumStatusAdvertising); - return true; - } - - LOG(ERROR) << "failed to stop mDNS advertising."; - medium_status_ &= (~kMediumStatusAdvertising); - return false; - } else { - // The service may be running under Win32 when the flag is disabled. - wifi_lan_mdns_.StopMdnsService(); - - dnssd_service_instance_ = nullptr; - - LOG(INFO) << "succeeded to stop mDNS advertising for service type =" - << nsd_service_info.GetServiceType(); + if (result) { medium_status_ &= (~kMediumStatusAdvertising); return true; } + + LOG(ERROR) << "failed to stop mDNS advertising."; + medium_status_ &= (~kMediumStatusAdvertising); + return false; } // Returns true once the WifiLan discovery has been initiated. @@ -337,88 +266,28 @@ std::unique_ptr WifiLanMedium::ConnectToService( std::unique_ptr connection_cancellation_listener = nullptr; - if (NearbyFlags::GetInstance().GetBoolFlag( - nearby::platform::config_package_nearby::nearby_platform_feature:: - kEnableBlockingSocket)) { - auto wifi_lan_socket = std::make_unique(); + auto wifi_lan_socket = std::make_unique(); - // setup cancel listener - if (cancellation_flag != nullptr) { - connection_cancellation_listener = - std::make_unique( - cancellation_flag, [socket = wifi_lan_socket.get()]() { - LOG(WARNING) << "connect is closed due to it is cancelled."; - socket->Close(); - }); - } - - bool result = wifi_lan_socket->Connect(ipv4_address, port); - if (!result) { - LOG(ERROR) << "failed to connect to service " << ipv4_address << ":" - << port; - return nullptr; - } - - LOG(INFO) << "connected to remote service " << ipv4_address << ":" << port; - - return wifi_lan_socket; - - } else { - HostName host_name{ - string_utils::StringToWideString(std::string(ipv4_address))}; - winrt::hstring service_name{winrt::to_hstring(port)}; - - StreamSocket socket{}; - - // setup cancel listener - if (cancellation_flag != nullptr) { - connection_cancellation_listener = - std::make_unique( - cancellation_flag, [socket]() { - LOG(WARNING) << "connect is closed due to it is cancelled."; - socket.Close(); - }); - } - - // connection to the service - try { - if (FeatureFlags::GetInstance().GetFlags().enable_connection_timeout) { - connection_timeout_ = scheduled_executor_.Schedule( - [socket]() { - LOG(WARNING) << "connect is closed due to timeout."; - socket.Close(); - }, - kConnectServiceTimeout); - } - - socket.ConnectAsync(host_name, service_name).get(); - - if (connection_timeout_ != nullptr) { - connection_timeout_->Cancel(); - connection_timeout_ = nullptr; - } - - auto wifi_lan_socket = std::make_unique(socket); - - std::string local_address = - winrt::to_string(socket.Information().LocalAddress().DisplayName()); - std::string local_port = - winrt::to_string(socket.Information().LocalPort()); - - LOG(INFO) << "connected to remote service " << ipv4_address << ":" << port - << " with local address " << local_address << ":" << local_port; - return wifi_lan_socket; - } catch (...) { - LOG(ERROR) << "failed to connect remote service " << ipv4_address << ":" - << port; - } - if (connection_timeout_ != nullptr) { - connection_timeout_->Cancel(); - connection_timeout_ = nullptr; - } + // setup cancel listener + if (cancellation_flag != nullptr) { + connection_cancellation_listener = + std::make_unique( + cancellation_flag, [socket = wifi_lan_socket.get()]() { + LOG(WARNING) << "connect is closed due to it is cancelled."; + socket->Close(); + }); + } + bool result = wifi_lan_socket->Connect(ipv4_address, port); + if (!result) { + LOG(ERROR) << "failed to connect to service " << ipv4_address << ":" + << port; return nullptr; } + + LOG(INFO) << "connected to remote service " << ipv4_address << ":" << port; + + return wifi_lan_socket; } std::unique_ptr WifiLanMedium::ListenForService( diff --git a/internal/platform/implementation/windows/wifi_lan_server_socket.cc b/internal/platform/implementation/windows/wifi_lan_server_socket.cc index 320458ee..e1eb8ecd 100644 --- a/internal/platform/implementation/windows/wifi_lan_server_socket.cc +++ b/internal/platform/implementation/windows/wifi_lan_server_socket.cc @@ -40,44 +40,18 @@ using ::winrt::Windows::Networking::Sockets::SocketQualityOfService; } -WifiLanServerSocket::WifiLanServerSocket(int port) : port_(port) { - enable_blocking_socket_ = NearbyFlags::GetInstance().GetBoolFlag( - nearby::platform::config_package_nearby::nearby_platform_feature:: - kEnableBlockingSocket); -} +WifiLanServerSocket::WifiLanServerSocket(int port) : port_(port) {} WifiLanServerSocket::~WifiLanServerSocket() { Close(); } // Returns the first IP address. std::string WifiLanServerSocket::GetIPAddress() const { - if (enable_blocking_socket_) { - return ipaddr_dotdecimal_to_4bytes_string(server_socket_.GetIPAddress()); - } else { - if (stream_socket_listener_ == nullptr) { - LOG(ERROR) << "Failed to get IP address due to no server socket."; - return ""; - } - - if (ip_addresses_.empty()) { - LOG(ERROR) << "Failed to get IP address due to no avaible IP addresses."; - return ""; - } - - return ip_addresses_.front(); - } + return ipaddr_dotdecimal_to_4bytes_string(server_socket_.GetIPAddress()); } // Returns socket port. int WifiLanServerSocket::GetPort() const { - if (enable_blocking_socket_) { - return server_socket_.GetPort(); - } else { - if (stream_socket_listener_ == nullptr) { - return 0; - } - - return std::stoi(stream_socket_listener_.Information().LocalPort().c_str()); - } + return server_socket_.GetPort(); } // Blocks until either: @@ -87,29 +61,14 @@ int WifiLanServerSocket::GetPort() const { // Returns nullptr on error. // Once error is reported, it is permanent, and ServerSocket has to be closed. std::unique_ptr WifiLanServerSocket::Accept() { - if (enable_blocking_socket_) { - auto client_socket = server_socket_.Accept(); - if (client_socket == nullptr) { - return nullptr; - } - - LOG(INFO) << __func__ << ": Accepted a remote connection."; - - return std::make_unique(std::move(client_socket)); - } else { - absl::MutexLock lock(&mutex_); - VLOG(1) << __func__ << ": Accept is called."; - while (!closed_ && pending_sockets_.empty()) { - cond_.Wait(&mutex_); - } - if (closed_) return {}; - - StreamSocket wifi_lan_socket = pending_sockets_.front(); - pending_sockets_.pop_front(); - - LOG(INFO) << __func__ << ": Accepted a remote connection."; - return std::make_unique(wifi_lan_socket); + auto client_socket = server_socket_.Accept(); + if (client_socket == nullptr) { + return nullptr; } + + LOG(INFO) << __func__ << ": Accepted a remote connection."; + + return std::make_unique(std::move(client_socket)); } void WifiLanServerSocket::SetCloseNotifier( @@ -122,41 +81,17 @@ Exception WifiLanServerSocket::Close() { try { absl::MutexLock lock(&mutex_); VLOG(1) << __func__ << ": Close is called."; - if (enable_blocking_socket_) { - if (closed_) { - return {Exception::kSuccess}; - } + if (closed_) { + return {Exception::kSuccess}; + } - LOG(INFO) << __func__ << ": closing blocking socket."; + LOG(INFO) << __func__ << ": closing blocking socket."; - server_socket_.Close(); - closed_ = true; + server_socket_.Close(); + closed_ = true; - if (close_notifier_ != nullptr) { - close_notifier_(); - } - } else { - if (closed_) { - return {Exception::kSuccess}; - } - 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_(); - } + if (close_notifier_ != nullptr) { + close_notifier_(); } LOG(INFO) << __func__ << ": Close completed succesfully."; @@ -181,14 +116,13 @@ Exception WifiLanServerSocket::Close() { } bool WifiLanServerSocket::listen() { - if (enable_blocking_socket_) { - ip_addresses_ = GetIpv4Addresses(); + ip_addresses_ = GetIpv4Addresses(); - if (ip_addresses_.empty()) { - LOG(ERROR) << "failed to start accepting connection without IP " - "addresses configured on computer."; - return false; - } + if (ip_addresses_.empty()) { + LOG(ERROR) << "failed to start accepting connection without IP " + "addresses configured on computer."; + return false; + } // Listen on all interfaces. if (!server_socket_.Listen("", port_)) { @@ -196,69 +130,7 @@ bool WifiLanServerSocket::listen() { return false; } - return true; - } else { - // Get current IP addresses of the device. - ip_addresses_ = Get4BytesIpv4Addresses(); - - if (ip_addresses_.empty()) { - LOG(WARNING) << "failed to start accepting connection without IP " - "addresses configured on computer."; - return false; - } - // Setup stream socket listener. - stream_socket_listener_ = StreamSocketListener(); - - stream_socket_listener_.Control().QualityOfService( - SocketQualityOfService::LowLatency); - - stream_socket_listener_.Control().KeepAlive(true); - - // Setup socket event of ConnectionReceived. - listener_event_token_ = stream_socket_listener_.ConnectionReceived( - {this, &WifiLanServerSocket::Listener_ConnectionReceived}); - - try { - stream_socket_listener_.BindServiceNameAsync(winrt::to_hstring(port_)) - .get(); - if (port_ == 0) { - port_ = std::stoi( - stream_socket_listener_.Information().LocalPort().c_str()); - } - - return true; - } catch (std::exception exception) { - LOG(ERROR) << __func__ - << ": Cannot accept connection on preferred port. Exception: " - << exception.what(); - } catch (const winrt::hresult_error& error) { - LOG(ERROR) - << __func__ - << ": Cannot accept connection on preferred port. WinRT exception: " - << error.code() << ": " << winrt::to_string(error.message()); - } catch (...) { - LOG(ERROR) << __func__ << ": Unknown exception."; - } - - try { - stream_socket_listener_.BindServiceNameAsync({}).get(); - - // Need to save the port information. - port_ = - std::stoi(stream_socket_listener_.Information().LocalPort().c_str()); - return true; - } catch (std::exception exception) { - LOG(ERROR) << __func__ << ": Cannot bind to any port. Exception: " - << exception.what(); - } catch (const winrt::hresult_error& error) { - LOG(ERROR) << __func__ << ": Cannot bind to any port. WinRT exception: " - << error.code() << ": " << winrt::to_string(error.message()); - } catch (...) { - LOG(ERROR) << __func__ << ": Unknown exception."; - } - - return false; - } + return true; } fire_and_forget WifiLanServerSocket::Listener_ConnectionReceived( diff --git a/internal/platform/implementation/windows/wifi_lan_socket.cc b/internal/platform/implementation/windows/wifi_lan_socket.cc index cbd9aaff..9cfec6a9 100644 --- a/internal/platform/implementation/windows/wifi_lan_socket.cc +++ b/internal/platform/implementation/windows/wifi_lan_socket.cc @@ -33,18 +33,12 @@ namespace nearby { namespace windows { WifiLanSocket::WifiLanSocket() { - enable_blocking_socket_ = NearbyFlags::GetInstance().GetBoolFlag( - nearby::platform::config_package_nearby::nearby_platform_feature:: - kEnableBlockingSocket); client_socket_ = std::make_unique(); input_stream_ = SocketInputStream(client_socket_.get()); output_stream_ = SocketOutputStream(client_socket_.get()); } WifiLanSocket::WifiLanSocket(StreamSocket socket) { - enable_blocking_socket_ = NearbyFlags::GetInstance().GetBoolFlag( - nearby::platform::config_package_nearby::nearby_platform_feature:: - kEnableBlockingSocket); stream_soket_ = socket; VLOG(1) << "Socket send buffer size: " << socket.Control().OutboundBufferSizeInBytes(); @@ -56,9 +50,6 @@ WifiLanSocket::WifiLanSocket(StreamSocket socket) { } WifiLanSocket::WifiLanSocket(std::unique_ptr 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()); @@ -71,28 +62,9 @@ InputStream& WifiLanSocket::GetInputStream() { return input_stream_; } OutputStream& WifiLanSocket::GetOutputStream() { return output_stream_; } Exception WifiLanSocket::Close() { - if (enable_blocking_socket_) { - if (client_socket_ != nullptr) { - return client_socket_->Close(); - } - } else { - try { - if (stream_soket_ != nullptr) { - stream_soket_.Close(); - } - } 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}; - } + if (client_socket_ != nullptr) { + return client_socket_->Close(); } - return {Exception::kSuccess}; } @@ -102,215 +74,73 @@ bool WifiLanSocket::Connect(const std::string& ip_address, int port) { // SocketInputStream WifiLanSocket::SocketInputStream::SocketInputStream(IInputStream input_stream) { - enable_blocking_socket_ = NearbyFlags::GetInstance().GetBoolFlag( - nearby::platform::config_package_nearby::nearby_platform_feature:: - kEnableBlockingSocket); input_stream_ = input_stream; } WifiLanSocket::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 WifiLanSocket::SocketInputStream::Read( std::int64_t size) { - if (enable_blocking_socket_) { - if (client_socket_ == nullptr) { - LOG(ERROR) << "Failed to read data due to no client socket."; - return {Exception::kIo}; - } - - return client_socket_->Read(size); - } else { - try { - if (read_buffer_ == nullptr || read_buffer_.Capacity() < size) { - read_buffer_ = Buffer(size); - } - - // Reset the buffer length to 0. - read_buffer_.Length(0); - - auto ibuffer = - input_stream_.ReadAsync(read_buffer_, size, InputStreamOptions::None) - .get(); - - if (ibuffer.Length() != size) { - LOG(WARNING) << "Only read partial of data: [" << ibuffer.Length() - << "/" << size << "]."; - } - - ByteArray data((char*)ibuffer.data(), ibuffer.Length()); - return ExceptionOr(std::move(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}; - } + if (client_socket_ == nullptr) { + LOG(ERROR) << "Failed to read data due to no client socket."; + return {Exception::kIo}; } + + return client_socket_->Read(size); } ExceptionOr WifiLanSocket::SocketInputStream::Skip(size_t offset) { - if (enable_blocking_socket_) { - if (client_socket_ == nullptr) { - return {Exception::kIo}; - } - - return client_socket_->Skip(offset); - } else { - try { - Buffer buffer = Buffer(offset); - - auto ibuffer = - input_stream_.ReadAsync(buffer, offset, InputStreamOptions::None) - .get(); - return ExceptionOr((size_t)ibuffer.Length()); - } 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}; - } + if (client_socket_ == nullptr) { + return {Exception::kIo}; } + + return client_socket_->Skip(offset); } Exception WifiLanSocket::SocketInputStream::Close() { - if (enable_blocking_socket_) { - if (client_socket_ == nullptr) { - return {Exception::kIo}; - } - - return client_socket_->Close(); - } else { - try { - input_stream_.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 exception."; - return {Exception::kIo}; - } + if (client_socket_ == nullptr) { + return {Exception::kIo}; } + + return client_socket_->Close(); } // SocketOutputStream WifiLanSocket::SocketOutputStream::SocketOutputStream( IOutputStream output_stream) { - enable_blocking_socket_ = NearbyFlags::GetInstance().GetBoolFlag( - nearby::platform::config_package_nearby::nearby_platform_feature:: - kEnableBlockingSocket); output_stream_ = output_stream; } WifiLanSocket::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 WifiLanSocket::SocketOutputStream::Write(const ByteArray& data) { - if (enable_blocking_socket_) { - if (client_socket_ == nullptr) { - return {Exception::kIo}; - } - - return client_socket_->Write(data); - } else { - try { - Buffer buffer = Buffer(data.size()); - std::memcpy(buffer.data(), data.data(), data.size()); - buffer.Length(data.size()); - uint32_t wrote_bytes = output_stream_.WriteAsync(buffer).get(); - if (wrote_bytes != data.size()) { - LOG(WARNING) << "Only wrote partial of data:[" << wrote_bytes << "/" - << data.size() << "]."; - } - - 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}; - } + if (client_socket_ == nullptr) { + return {Exception::kIo}; } + + return client_socket_->Write(data); } Exception WifiLanSocket::SocketOutputStream::Flush() { - if (enable_blocking_socket_) { - if (client_socket_ == nullptr) { - return {Exception::kIo}; - } - - return client_socket_->Flush(); - } else { - try { - 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}; - } + if (client_socket_ == nullptr) { + return {Exception::kIo}; } + + return client_socket_->Flush(); } Exception WifiLanSocket::SocketOutputStream::Close() { - if (enable_blocking_socket_) { - if (client_socket_ == nullptr) { - return {Exception::kIo}; - } - - return client_socket_->Close(); - } else { - try { - output_stream_.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 exception."; - return {Exception::kIo}; - } + if (client_socket_ == nullptr) { + return {Exception::kIo}; } + + return client_socket_->Close(); } } // namespace windows