diff --git a/cpp/core/internal/BUILD b/cpp/core/internal/BUILD index 17a10f2c..9247f02e 100644 --- a/cpp/core/internal/BUILD +++ b/cpp/core/internal/BUILD @@ -43,9 +43,7 @@ cc_library( "webrtc_bwu_handler.cc", "webrtc_endpoint_channel.cc", "wifi_lan_bwu_handler.cc", - "wifi_lan_bwu_handler_v2.cc", "wifi_lan_endpoint_channel.cc", - "wifi_lan_endpoint_channel_v2.cc", "wifi_lan_service_info.cc", ], hdrs = [ @@ -82,9 +80,7 @@ cc_library( "webrtc_bwu_handler.h", "webrtc_endpoint_channel.h", "wifi_lan_bwu_handler.h", - "wifi_lan_bwu_handler_v2.h", "wifi_lan_endpoint_channel.h", - "wifi_lan_endpoint_channel_v2.h", "wifi_lan_service_info.h", ], compatible_with = ["//buildenv/target:non_prod"], diff --git a/cpp/core/internal/base_pcp_handler.h b/cpp/core/internal/base_pcp_handler.h index 1b075667..896d03c4 100644 --- a/cpp/core/internal/base_pcp_handler.h +++ b/cpp/core/internal/base_pcp_handler.h @@ -199,16 +199,8 @@ class BasePcpHandler : public PcpHandler, }; struct WifiLanEndpoint : public DiscoveredEndpoint { - WifiLanEndpoint(DiscoveredEndpoint endpoint, WifiLanService service) - : DiscoveredEndpoint(std::move(endpoint)), - wifi_lan_service(std::move(service)) {} - - WifiLanService wifi_lan_service; - }; - - struct WifiLanV2Endpoint : public DiscoveredEndpoint { - WifiLanV2Endpoint(DiscoveredEndpoint endpoint, - const NsdServiceInfo& service_info) + WifiLanEndpoint(DiscoveredEndpoint endpoint, + const NsdServiceInfo& service_info) : DiscoveredEndpoint(std::move(endpoint)), service_info(service_info) {} NsdServiceInfo service_info; diff --git a/cpp/core/internal/mediums/BUILD b/cpp/core/internal/mediums/BUILD index 8eb15e40..7f530723 100644 --- a/cpp/core/internal/mediums/BUILD +++ b/cpp/core/internal/mediums/BUILD @@ -24,7 +24,6 @@ cc_library( "uuid.cc", "webrtc.cc", "wifi_lan.cc", - "wifi_lan_v2.cc", ], hdrs = [ "ble.h", @@ -36,7 +35,6 @@ cc_library( "uuid.h", "webrtc.h", "wifi_lan.h", - "wifi_lan_v2.h", ], compatible_with = ["//buildenv/target:non_prod"], visibility = [ @@ -104,7 +102,6 @@ cc_test( "lost_entity_tracker_test.cc", "uuid_test.cc", "wifi_lan_test.cc", - "wifi_lan_test_v2.cc", ], shard_count = 16, deps = [ diff --git a/cpp/core/internal/mediums/mediums.cc b/cpp/core/internal/mediums/mediums.cc index 25135de0..8b0b3100 100644 --- a/cpp/core/internal/mediums/mediums.cc +++ b/cpp/core/internal/mediums/mediums.cc @@ -26,8 +26,6 @@ Ble& Mediums::GetBle() { return ble_; } WifiLan& Mediums::GetWifiLan() { return wifi_lan_; } -WifiLanV2& Mediums::GetWifiLanV2() { return wifi_lan_v2_; } - mediums::WebRtc& Mediums::GetWebRtc() { return webrtc_; } } // namespace connections diff --git a/cpp/core/internal/mediums/mediums.h b/cpp/core/internal/mediums/mediums.h index d47b9b42..4c6127eb 100644 --- a/cpp/core/internal/mediums/mediums.h +++ b/cpp/core/internal/mediums/mediums.h @@ -20,7 +20,6 @@ #include "core/internal/mediums/bluetooth_radio.h" #include "core/internal/mediums/webrtc.h" #include "core/internal/mediums/wifi_lan.h" -#include "core/internal/mediums/wifi_lan_v2.h" namespace location { namespace nearby { @@ -44,9 +43,6 @@ class Mediums { // Returns a handle to the Wifi-Lan medium. WifiLan& GetWifiLan(); - // Returns a handle to the Wifi-Lan medium. - WifiLanV2& GetWifiLanV2(); - // Returns a handle to the WebRtc medium. mediums::WebRtc& GetWebRtc(); @@ -63,7 +59,6 @@ class Mediums { BluetoothClassic bluetooth_classic_{bluetooth_radio_}; Ble ble_{bluetooth_radio_}; WifiLan wifi_lan_; - WifiLanV2 wifi_lan_v2_; mediums::WebRtc webrtc_; }; diff --git a/cpp/core/internal/mediums/wifi_lan.cc b/cpp/core/internal/mediums/wifi_lan.cc index c94b410d..b901d8ec 100644 --- a/cpp/core/internal/mediums/wifi_lan.cc +++ b/cpp/core/internal/mediums/wifi_lan.cc @@ -27,6 +27,24 @@ namespace location { namespace nearby { namespace connections { +WifiLan::~WifiLan() { + // Destructor is not taking locks, but methods it is calling are. + while (!discovering_info_.service_ids.empty()) { + StopDiscovery(*discovering_info_.service_ids.begin()); + } + while (!server_sockets_.empty()) { + StopAcceptingConnections(server_sockets_.begin()->first); + } + while (!advertising_info_.nsd_service_infos.empty()) { + StopAdvertising(advertising_info_.nsd_service_infos.begin()->first); + } + + // All the AcceptLoopRunnable objects in here should already have gotten an + // opportunity to shut themselves down cleanly in the calls to + // StopAcceptingConnections() above. + accept_loops_runner_.Shutdown(); +} + bool WifiLan::IsAvailable() const { MutexLock lock(&mutex_); @@ -39,6 +57,12 @@ bool WifiLan::StartAdvertising(const std::string& service_id, NsdServiceInfo& nsd_service_info) { MutexLock lock(&mutex_); + if (!IsAvailableLocked()) { + NEARBY_LOGS(INFO) + << "Can't turn on WifiLan advertising. WifiLan is not available."; + return false; + } + if (!nsd_service_info.IsValid()) { NEARBY_LOGS(INFO) << "Refusing to turn on WifiLan advertising. nsd_service_info is not " @@ -52,27 +76,36 @@ bool WifiLan::StartAdvertising(const std::string& service_id, return false; } - if (!IsAvailableLocked()) { - NEARBY_LOG(INFO, - "Can't turn on WifiLan advertising. WifiLan is not available."); + if (!IsAcceptingConnectionsLocked(service_id)) { + NEARBY_LOGS(INFO) + << "Failed to turn on WifiLan advertising with nsd_service_info=" + << &nsd_service_info + << ", service_name=" << nsd_service_info.GetServiceName() + << ", service_id=" << service_id + << ". Should accept connections before advertising."; return false; } nsd_service_info.SetServiceType(GenerateServiceType(service_id)); - if (!medium_.StartAdvertising(service_id, nsd_service_info)) { + const auto& it = server_sockets_.find(service_id); + if (it != server_sockets_.end()) { + nsd_service_info.SetIPAddress(it->second.GetIPAddress()); + nsd_service_info.SetPort(it->second.GetPort()); + } + if (!medium_.StartAdvertising(nsd_service_info)) { NEARBY_LOGS(INFO) - << "Failed to turn on WifiLan advertising with wifi_lan_service=" + << "Failed to turn on WifiLan advertising with nsd_service_info=" << &nsd_service_info - << ", service_info_name=" << nsd_service_info.GetServiceName() + << ", service_name=" << nsd_service_info.GetServiceName() << ", service_id=" << service_id; return false; } - NEARBY_LOGS(INFO) << "Turned on WifiLan advertising with wifi_lan_service=" - << &nsd_service_info << ", service_info_name=" - << nsd_service_info.GetServiceName() + NEARBY_LOGS(INFO) << "Turned on WifiLan advertising with nsd_service_info=" + << &nsd_service_info + << ", service_name=" << nsd_service_info.GetServiceName() << ", service_id=" << service_id; - advertising_info_.Add(service_id); + advertising_info_.Add(service_id, std::move(nsd_service_info)); return true; } @@ -80,15 +113,17 @@ bool WifiLan::StopAdvertising(const std::string& service_id) { MutexLock lock(&mutex_); if (!IsAdvertisingLocked(service_id)) { - NEARBY_LOG(INFO, "Can't turn off WifiLan advertising; it is already off"); + NEARBY_LOGS(INFO) + << "Can't turn off WifiLan advertising; it is already off"; return false; } - NEARBY_LOG(INFO, "Turned off WifiLan advertising with service_id=%s", - service_id.c_str()); - bool ret = medium_.StopAdvertising(service_id); + NEARBY_LOGS(INFO) << "Turned off WifiLan advertising with service_id=" + << service_id; + bool ret = + medium_.StopAdvertising(*advertising_info_.GetServiceInfo(service_id)); // Reset our bundle of advertising state to mark that we're no longer - // advertising. + // advertising for specific service_id. advertising_info_.Remove(service_id); return ret; } @@ -108,33 +143,33 @@ bool WifiLan::StartDiscovery(const std::string& service_id, MutexLock lock(&mutex_); if (service_id.empty()) { - NEARBY_LOG(INFO, - "Refusing to start WifiLan discovering with empty service_id."); + NEARBY_LOGS(INFO) + << "Refusing to start WifiLan discovering with empty service_id."; return false; } if (!IsAvailableLocked()) { - NEARBY_LOG( - INFO, - "Can't discover WifiLan services because WifiLan isn't available."); + NEARBY_LOGS(INFO) + << "Can't discover WifiLan services because WifiLan isn't available."; return false; } if (IsDiscoveringLocked(service_id)) { - NEARBY_LOG( - INFO, - "Refusing to start discovery of WifiLan services because another " - "discovery is already in-progress."); + NEARBY_LOGS(INFO) + << "Refusing to start discovery of WifiLan services because another " + "discovery is already in-progress."; return false; } - if (!medium_.StartDiscovery(service_id, callback)) { - NEARBY_LOG(INFO, "Failed to start discovery of WifiLan services."); + std::string service_type = GenerateServiceType(service_id); + bool ret = medium_.StartDiscovery(service_id, service_type, callback); + if (!ret) { + NEARBY_LOGS(INFO) << "Failed to start discovery of WifiLan services."; return false; } - NEARBY_LOG(INFO, "Turned on WifiLan discovering with service_id=%s", - service_id.c_str()); + NEARBY_LOGS(INFO) << "Turned on WifiLan discovering with service_id=" + << service_id; // Mark the fact that we're currently performing a WifiLan discovering. discovering_info_.Add(service_id); return true; @@ -144,22 +179,22 @@ bool WifiLan::StopDiscovery(const std::string& service_id) { MutexLock lock(&mutex_); if (!IsDiscoveringLocked(service_id)) { - NEARBY_LOG(INFO, - "Can't turn off WifiLan discovering because we never started " - "discovering."); + NEARBY_LOGS(INFO) + << "Can't turn off WifiLan discovering because we never started " + "discovering."; return false; } - NEARBY_LOG(INFO, "Turned off WifiLan discovering with service_id=%s", - service_id.c_str()); - bool ret = medium_.StopDiscovery(service_id); - discovering_info_.Clear(); + std::string service_type = GenerateServiceType(service_id); + NEARBY_LOGS(INFO) << "Turned off WifiLan discovering with service_id=" + << service_id << ", service_type=" << service_type; + bool ret = medium_.StopDiscovery(service_type); + discovering_info_.Remove(service_id); return ret; } bool WifiLan::IsDiscovering(const std::string& service_id) { MutexLock lock(&mutex_); - return IsDiscoveringLocked(service_id); } @@ -172,87 +207,129 @@ bool WifiLan::StartAcceptingConnections(const std::string& service_id, MutexLock lock(&mutex_); if (service_id.empty()) { - NEARBY_LOG(INFO, - "Refusing to start accepting WifiLan connections with empty " - "service_id."); + NEARBY_LOGS(INFO) << "Refusing to start accepting WifiLan connections; " + "service_id is empty."; return false; } if (!IsAvailableLocked()) { - NEARBY_LOG(INFO, - "Can't start accepting WifiLan connections for %s because " - "WifiLan isn't available.", - service_id.c_str()); + NEARBY_LOGS(INFO) + << "Can't start accepting WifiLan connections [service_id=" + << service_id << "]; WifiLan not available."; return false; } if (IsAcceptingConnectionsLocked(service_id)) { - NEARBY_LOG(INFO, - "Refusing to start accepting WifiLan connections for %s because " - "another WifiLan service socket is already in-progress.", - service_id.c_str()); + NEARBY_LOGS(INFO) + << "Refusing to start accepting WifiLan connections [service=" + << service_id + << "]; WifiLan server is already in-progress with the same name."; return false; } - if (!medium_.StartAcceptingConnections(service_id, callback)) { - NEARBY_LOG(INFO, "Failed to accept connections callback for %s.", - service_id.c_str()); + // We can generate an exact port here on server socket; now we just assign 0 + // to let platform medium decide it. + int port = 0; + WifiLanServerSocket server_socket = medium_.ListenForService(port); + if (!server_socket.IsValid()) { + NEARBY_LOGS(INFO) + << "Failed to start accepting WifiLan connections for service_id=" + << service_id; return false; } - accepting_connections_info_.Add(service_id); + // Mark the fact that there's an in-progress WifiLan server accepting + // connections. + auto owned_server_socket = + server_sockets_.insert({service_id, std::move(server_socket)}) + .first->second; + + // Start the accept loop on a dedicated thread - this stays alive and + // listening for new incoming connections until StopAcceptingConnections() is + // invoked. + accept_loops_runner_.Execute( + "wifi-lan-accept", + [callback = std::move(callback), + server_socket = std::move(owned_server_socket), service_id]() mutable { + while (true) { + WifiLanSocket client_socket = server_socket.Accept(); + if (!client_socket.IsValid()) { + server_socket.Close(); + break; + } + callback.accepted_cb(std::move(client_socket)); + } + }); + return true; } bool WifiLan::StopAcceptingConnections(const std::string& service_id) { MutexLock lock(&mutex_); - if (!IsAcceptingConnectionsLocked(service_id)) { - NEARBY_LOG(INFO, - "Can't stop accepting WifiLan connections because it was never " - "started."); + if (service_id.empty()) { + NEARBY_LOGS(INFO) << "Unable to stop accepting WifiLan connections because " + "the service_id is empty."; return false; } - bool ret = medium_.StopAcceptingConnections(service_id); - // Reset our bundle of accepting connections state to mark that we're no - // longer accepting connections. - accepting_connections_info_.Remove(service_id); - return ret; + const auto& it = server_sockets_.find(service_id); + if (it == server_sockets_.end()) { + NEARBY_LOGS(INFO) << "Can't stop accepting WifiLan connections for " + << service_id << " because it was never started."; + return false; + } + + // Closing the WifiLanServerSocket will kick off the suicide of the thread + // in accept_loops_thread_pool_ that blocks on WifiLanServerSocket.accept(). + // That may take some time to complete, but there's no particular reason to + // wait around for it. + auto item = server_sockets_.extract(it); + + // Store a handle to the WifiLanServerSocket, so we can use it after + // removing the entry from server_sockets_; making it scoped + // is a bonus that takes care of deallocation before we leave this method. + WifiLanServerSocket& listening_socket = item.mapped(); + + // Regardless of whether or not we fail to close the existing + // WifiLanServerSocket, remove it from server_sockets_ so that it + // frees up this service for another round. + + // Finally, close the WifiLanServerSocket. + if (!listening_socket.Close().Ok()) { + NEARBY_LOGS(INFO) << "Failed to close WifiLan server socket for service_id=" + << service_id; + return false; + } + + return true; } bool WifiLan::IsAcceptingConnections(const std::string& service_id) { MutexLock lock(&mutex_); - return IsAcceptingConnectionsLocked(service_id); } bool WifiLan::IsAcceptingConnectionsLocked(const std::string& service_id) { - return accepting_connections_info_.Existed(service_id); + return server_sockets_.find(service_id) != server_sockets_.end(); } -WifiLanSocket WifiLan::Connect(WifiLanService& wifi_lan_service, - const std::string& service_id, +WifiLanSocket WifiLan::Connect(const std::string& service_id, + const NsdServiceInfo& service_info, CancellationFlag* cancellation_flag) { MutexLock lock(&mutex_); - NEARBY_LOGS(INFO) << "WifiLan::Connect: wifi_lan_service=" - << &wifi_lan_service << ", service_info_name=" - << wifi_lan_service.GetServiceInfo().GetServiceName() - << ", service_id=" << service_id; // Socket to return. To allow for NRVO to work, it has to be a single object. WifiLanSocket socket; if (service_id.empty()) { - NEARBY_LOG(INFO, - "Refusing to create WifiLan socket with empty service_id."); + NEARBY_LOGS(INFO) << "Refusing to create client WifiLan socket because " + "service_id is empty."; return socket; } if (!IsAvailableLocked()) { - NEARBY_LOG(INFO, - "Can't create client WifiLan socket [service_id=%s]; WifiLan " - "isn't available.", - service_id.c_str()); + NEARBY_LOGS(INFO) << "Can't create client WifiLan socket [service_id=" + << service_id << "]; WifiLan isn't available."; return socket; } @@ -261,25 +338,57 @@ WifiLanSocket WifiLan::Connect(WifiLanService& wifi_lan_service, return socket; } - socket = medium_.Connect(wifi_lan_service, service_id, cancellation_flag); + socket = medium_.ConnectToService(service_info, cancellation_flag); if (!socket.IsValid()) { - NEARBY_LOG(INFO, "Failed to Connect via WifiLan [service_id=%s]", - service_id.c_str()); + NEARBY_LOGS(INFO) << "Failed to Connect via WifiLan [service_id=" + << service_id << "]"; } return socket; } -WifiLanService WifiLan::GetRemoteWifiLanService(const std::string& ip_address, - int port) { +WifiLanSocket WifiLan::Connect(const std::string& service_id, + const std::string& ip_address, int port, + CancellationFlag* cancellation_flag) { MutexLock lock(&mutex_); - return medium_.GetRemoteService(ip_address, port); + // Socket to return. To allow for NRVO to work, it has to be a single object. + WifiLanSocket socket; + + if (service_id.empty()) { + NEARBY_LOGS(INFO) << "Refusing to create client WifiLan socket because " + "service_id is empty."; + return socket; + } + + if (!IsAvailableLocked()) { + NEARBY_LOGS(INFO) << "Can't create client WifiLan socket [service_id=" + << service_id << "]; WifiLan isn't available."; + return socket; + } + + if (cancellation_flag->Cancelled()) { + NEARBY_LOGS(INFO) << "Can't create client WifiLan socket due to cancel."; + return socket; + } + + socket = medium_.ConnectToService(ip_address, port, cancellation_flag); + if (!socket.IsValid()) { + NEARBY_LOGS(INFO) << "Failed to Connect via WifiLan [service_id=" + << service_id << "]"; + } + + return socket; } std::pair WifiLan::GetCredentials( const std::string& service_id) { MutexLock lock(&mutex_); - return medium_.GetCredentials(service_id); + const auto& it = server_sockets_.find(service_id); + if (it == server_sockets_.end()) { + return std::pair(); + } + return std::pair(it->second.GetIPAddress(), + it->second.GetPort()); } std::string WifiLan::GenerateServiceType(const std::string& service_id) { diff --git a/cpp/core/internal/mediums/wifi_lan.h b/cpp/core/internal/mediums/wifi_lan.h index ea7df0a6..dc5300f7 100644 --- a/cpp/core/internal/mediums/wifi_lan.h +++ b/cpp/core/internal/mediums/wifi_lan.h @@ -22,6 +22,7 @@ #include "absl/container/flat_hash_set.h" #include "platform/base/byte_array.h" #include "platform/base/cancellation_flag.h" +#include "platform/base/nsd_service_info.h" #include "platform/public/multi_thread_executor.h" #include "platform/public/mutex.h" #include "platform/public/wifi_lan.h" @@ -33,33 +34,42 @@ namespace connections { class WifiLan { public: using DiscoveredServiceCallback = WifiLanMedium::DiscoveredServiceCallback; - using AcceptedConnectionCallback = WifiLanMedium::AcceptedConnectionCallback; + + // Callback that is invoked when a new connection is accepted. + struct AcceptedConnectionCallback { + std::function accepted_cb = + DefaultCallback(); + }; + + WifiLan() = default; + ~WifiLan(); // Returns true, if WifiLan communications are supported by a platform. bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_); // Sets custom service info name, endpoint info name in NsdServiceInfo and // then enables WifiLan advertising. - // Returns true, if name is successfully set, and false otherwise. + // Returns true, if NsdServiceInfo is successfully set, and false otherwise. bool StartAdvertising(const std::string& service_id, NsdServiceInfo& nsd_service_info) ABSL_LOCKS_EXCLUDED(mutex_); - // Disables WifiLan advertising, and restores service info name to - // what they were before the call to StartAdvertising(). + // Disables WifiLan advertising. + // Returns false if no successful call StartAdvertising() was previously + // made, otherwise returns true. bool StopAdvertising(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); bool IsAdvertising(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); - // Enables WifiLan discovery mode. Will report any discoverable services in - // range through a callback. Returns true, if discovery mode was enabled, - // false otherwise. + // Enables WifiLan discovery. Will report any discoverable services + // through a callback. + // Returns true, if discovery was enabled, false otherwise. bool StartDiscovery(const std::string& service_id, DiscoveredServiceCallback callback) ABSL_LOCKS_EXCLUDED(mutex_); - // Disables WifiLan discovery mode. + // Disables WifiLan discovery. bool StopDiscovery(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); bool IsDiscovering(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); @@ -81,36 +91,55 @@ class WifiLan { // another service with StartAcceptingConnections() using the same service_id. // Blocks until connection is established, or server-side is terminated. // Returns socket instance. On success, WifiLanSocket.IsValid() return true. - WifiLanSocket Connect(WifiLanService& wifi_lan_service, - const std::string& service_id, + WifiLanSocket Connect(const std::string& service_id, + const NsdServiceInfo& service_info, CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_); - WifiLanService GetRemoteWifiLanService(const std::string& ip_address, - int port) ABSL_LOCKS_EXCLUDED(mutex_); + // Establishes connection to WifiLan service by ip address and port for + // bandwidth upgradation. + // Returns socket instance. On success, WifiLanSocket.IsValid() return true. + WifiLanSocket Connect(const std::string& service_id, + const std::string& ip_address, int port, + CancellationFlag* cancellation_flag) + ABSL_LOCKS_EXCLUDED(mutex_); + // Gets ip address + port for remote services on the network to identify and + // connect to this service. + // + // Credential is for the currently-hosted Wifi ServerSocket (if any). std::pair GetCredentials(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); private: struct AdvertisingInfo { - bool Empty() const { return service_ids.empty(); } - void Clear() { service_ids.clear(); } - void Add(const std::string& service_id) { service_ids.emplace(service_id); } + bool Empty() const { return nsd_service_infos.empty(); } + void Clear() { nsd_service_infos.clear(); } + void Add(const std::string& service_id, + const NsdServiceInfo& nsd_service_info) { + nsd_service_infos.insert({service_id, nsd_service_info}); + } void Remove(const std::string& service_id) { - service_ids.erase(service_id); + nsd_service_infos.erase(service_id); } bool Existed(const std::string& service_id) const { - return service_ids.contains(service_id); + return nsd_service_infos.contains(service_id); + } + NsdServiceInfo* GetServiceInfo(const std::string& service_id) { + const auto& it = nsd_service_infos.find(service_id); + if (it == nsd_service_infos.end()) { + return nullptr; + } + return &it->second; } - absl::flat_hash_set service_ids; + absl::flat_hash_map nsd_service_infos; }; struct DiscoveringInfo { bool Empty() const { return service_ids.empty(); } void Clear() { service_ids.clear(); } - void Add(const std::string& service_id) { service_ids.emplace(service_id); } + void Add(const std::string& service_id) { service_ids.insert(service_id); } void Remove(const std::string& service_id) { service_ids.erase(service_id); } @@ -121,19 +150,7 @@ class WifiLan { absl::flat_hash_set service_ids; }; - struct AcceptingConnectionsInfo { - bool Empty() const { return service_ids.empty(); } - void Clear() { service_ids.clear(); } - void Add(const std::string& service_id) { service_ids.emplace(service_id); } - void Remove(const std::string& service_id) { - service_ids.erase(service_id); - } - bool Existed(const std::string& service_id) const { - return service_ids.contains(service_id); - } - - absl::flat_hash_set service_ids; - }; + static constexpr int kMaxConcurrentAcceptLoops = 5; // Same as IsAvailable(), but must be called with mutex_ held. bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); @@ -157,7 +174,17 @@ class WifiLan { WifiLanMedium medium_ ABSL_GUARDED_BY(mutex_); AdvertisingInfo advertising_info_ ABSL_GUARDED_BY(mutex_); DiscoveringInfo discovering_info_ ABSL_GUARDED_BY(mutex_); - AcceptingConnectionsInfo accepting_connections_info_ ABSL_GUARDED_BY(mutex_); + + // A thread pool dedicated to running all the accept loops from + // StartAcceptingConnections(). + MultiThreadExecutor accept_loops_runner_{kMaxConcurrentAcceptLoops}; + + // A map of service_id -> ServerSocket. If map is non-empty, we + // are currently listening for incoming connections. + // WifiLanServerSocket instances are used from accept_loops_runner_, + // and thus require pointer stability. + absl::flat_hash_map server_sockets_ + ABSL_GUARDED_BY(mutex_); }; } // namespace connections diff --git a/cpp/core/internal/mediums/wifi_lan_test.cc b/cpp/core/internal/mediums/wifi_lan_test.cc index a7ed2ed4..4640363b 100644 --- a/cpp/core/internal/mediums/wifi_lan_test.cc +++ b/cpp/core/internal/mediums/wifi_lan_test.cc @@ -20,6 +20,7 @@ #include "gtest/gtest.h" #include "absl/strings/string_view.h" #include "platform/base/medium_environment.h" +#include "platform/base/nsd_service_info.h" #include "platform/public/count_down_latch.h" #include "platform/public/logging.h" #include "platform/public/wifi_lan.h" @@ -42,9 +43,8 @@ constexpr FeatureFlags kTestCases[] = { constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; -constexpr absl::string_view kServiceInfoName{ - "Simulated WifiLan service encrypted string #1"}; -constexpr absl::string_view kEndpointName{"Simulated endpoint name"}; +constexpr absl::string_view kServiceInfoName{"ServiceInfoName"}; +constexpr absl::string_view kEndpointName{"EndpointName"}; constexpr absl::string_view kEndpointInfoKey{"n"}; class WifiLanTest : public ::testing::TestWithParam { @@ -56,54 +56,59 @@ class WifiLanTest : public ::testing::TestWithParam { MediumEnvironment& env_{MediumEnvironment::Instance()}; }; -TEST_P(WifiLanTest, CanStartAcceptingConnectionsAndConnect) { +TEST_P(WifiLanTest, CanConnect) { FeatureFlags feature_flags = GetParam(); env_.SetFeatureFlags(feature_flags); env_.Start(); - WifiLan wifi_lan_a; - WifiLan wifi_lan_b; + WifiLan wifi_lan_client; + WifiLan wifi_lan_server; std::string service_id(kServiceID); - std::string service_info_name{kServiceInfoName}; - std::string endpoint_info_name{kEndpointName}; - CountDownLatch found_latch(1); + std::string service_info_name(kServiceInfoName); + std::string endpoint_info_name(kEndpointName); + CountDownLatch discovered_latch(1); CountDownLatch accept_latch(1); + WifiLanSocket socket_for_server; + EXPECT_TRUE(wifi_lan_server.StartAcceptingConnections( + service_id, + { + .accepted_cb = + [&socket_for_server, &accept_latch](WifiLanSocket socket) { + socket_for_server = std::move(socket); + accept_latch.CountDown(); + }, + })); + NsdServiceInfo nsd_service_info; nsd_service_info.SetServiceName(service_info_name); nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), endpoint_info_name); - wifi_lan_a.StartAdvertising(service_id, nsd_service_info); - wifi_lan_a.StartAcceptingConnections( - service_id, - { - .accepted_cb = [&accept_latch]( - WifiLanSocket socket, - absl::string_view) { accept_latch.CountDown(); }, - }); - WifiLanService discovered_service; - wifi_lan_b.StartDiscovery( + wifi_lan_server.StartAdvertising(service_id, nsd_service_info); + + NsdServiceInfo discovered_service_info; + wifi_lan_client.StartDiscovery( service_id, { .service_discovered_cb = - [&found_latch, &discovered_service]( - WifiLanService& service, absl::string_view service_id) { - discovered_service = service; - NEARBY_LOG(INFO, "Discovered service=%p [impl=%p]", &service, - &service.GetImpl()); - found_latch.CountDown(); + [&discovered_latch, &discovered_service_info]( + NsdServiceInfo service_info, const std::string& service_id) { + NEARBY_LOGS(INFO) + << "Discovered service_info=" << &service_info; + discovered_service_info = service_info; + discovered_latch.CountDown(); }, }); + discovered_latch.Await(kWaitDuration).result(); + ASSERT_TRUE(discovered_service_info.IsValid()); - EXPECT_TRUE(found_latch.Await(kWaitDuration).result()); - ASSERT_TRUE(discovered_service.IsValid()); CancellationFlag flag; - WifiLanSocket socket = - wifi_lan_b.Connect(discovered_service, service_id, &flag); + WifiLanSocket socket_for_client = + wifi_lan_client.Connect(service_id, discovered_service_info, &flag); EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(socket.IsValid()); - wifi_lan_b.StopDiscovery(service_id); - wifi_lan_a.StopAcceptingConnections(service_id); - wifi_lan_a.StopAdvertising(service_id); + EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); + EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); + EXPECT_TRUE(socket_for_server.IsValid()); + EXPECT_TRUE(socket_for_client.IsValid()); env_.Stop(); } @@ -111,56 +116,64 @@ TEST_P(WifiLanTest, CanCancelConnect) { FeatureFlags feature_flags = GetParam(); env_.SetFeatureFlags(feature_flags); env_.Start(); - WifiLan wifi_lan_a; - WifiLan wifi_lan_b; + WifiLan wifi_lan_client; + WifiLan wifi_lan_server; std::string service_id(kServiceID); - std::string service_info_name{kServiceInfoName}; - std::string endpoint_info_name{kEndpointName}; - CountDownLatch found_latch(1); + std::string service_info_name(kServiceInfoName); + std::string endpoint_info_name(kEndpointName); + CountDownLatch discovered_latch(1); CountDownLatch accept_latch(1); + WifiLanSocket socket_for_server; + EXPECT_TRUE(wifi_lan_server.StartAcceptingConnections( + service_id, + { + .accepted_cb = + [&socket_for_server, &accept_latch](WifiLanSocket socket) { + socket_for_server = std::move(socket); + accept_latch.CountDown(); + }, + })); + NsdServiceInfo nsd_service_info; nsd_service_info.SetServiceName(service_info_name); nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), endpoint_info_name); - wifi_lan_a.StartAdvertising(service_id, nsd_service_info); - wifi_lan_a.StartAcceptingConnections( - service_id, - { - .accepted_cb = [&accept_latch]( - WifiLanSocket socket, - absl::string_view) { accept_latch.CountDown(); }, - }); - WifiLanService discovered_service; - wifi_lan_b.StartDiscovery( + wifi_lan_server.StartAdvertising(service_id, nsd_service_info); + + NsdServiceInfo discovered_service_info; + wifi_lan_client.StartDiscovery( service_id, { .service_discovered_cb = - [&found_latch, &discovered_service]( - WifiLanService& service, absl::string_view service_id) { - discovered_service = service; - NEARBY_LOG(INFO, "Discovered service=%p [impl=%p]", &service, - &service.GetImpl()); - found_latch.CountDown(); + [&discovered_latch, &discovered_service_info]( + NsdServiceInfo service_info, const std::string& service_id) { + NEARBY_LOGS(INFO) + << "Discovered service_info=" << &service_info; + discovered_service_info = service_info; + discovered_latch.CountDown(); }, }); + EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); + ASSERT_TRUE(discovered_service_info.IsValid()); - EXPECT_TRUE(found_latch.Await(kWaitDuration).result()); - ASSERT_TRUE(discovered_service.IsValid()); CancellationFlag flag(true); - WifiLanSocket socket = - wifi_lan_b.Connect(discovered_service, service_id, &flag); + WifiLanSocket socket_for_client = + wifi_lan_client.Connect(service_id, discovered_service_info, &flag); // If FeatureFlag is disabled, Cancelled is false as no-op. if (!feature_flags.enable_cancellation_flag) { EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(socket.IsValid()); + EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); + EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); + EXPECT_TRUE(socket_for_server.IsValid()); + EXPECT_TRUE(socket_for_client.IsValid()); } else { EXPECT_FALSE(accept_latch.Await(kWaitDuration).result()); - EXPECT_FALSE(socket.IsValid()); + EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); + EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); + EXPECT_FALSE(socket_for_server.IsValid()); + EXPECT_FALSE(socket_for_client.IsValid()); } - wifi_lan_b.StopDiscovery(service_id); - wifi_lan_a.StopAcceptingConnections(service_id); - wifi_lan_a.StopAdvertising(service_id); env_.Stop(); } @@ -181,42 +194,127 @@ TEST_F(WifiLanTest, CanConstructValidObject) { TEST_F(WifiLanTest, CanStartAdvertising) { env_.Start(); WifiLan wifi_lan_a; - WifiLan wifi_lan_b; std::string service_id(kServiceID); - std::string service_info_name{kServiceInfoName}; - std::string endpoint_info_name{kEndpointName}; - CountDownLatch found_latch(1); + std::string service_info_name(kServiceInfoName); + std::string endpoint_info_name(kEndpointName); - wifi_lan_b.StartDiscovery( - service_id, DiscoveredServiceCallback{ - .service_discovered_cb = - [&found_latch](WifiLanService& service, - absl::string_view service_id) { - found_latch.CountDown(); - }, - }); + EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id, {})); NsdServiceInfo nsd_service_info; nsd_service_info.SetServiceName(service_info_name); nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), endpoint_info_name); EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id, nsd_service_info)); - EXPECT_TRUE(found_latch.Await(kWaitDuration).result()); EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id)); - EXPECT_TRUE(wifi_lan_b.StopDiscovery(service_id)); + env_.Stop(); +} + +TEST_F(WifiLanTest, CanStartMultipleAdvertising) { + env_.Start(); + WifiLan wifi_lan_a; + std::string service_id_1(kServiceID); + std::string service_id_2("com.google.location.nearby.apps.test_1"); + std::string service_info_name_1(kServiceInfoName); + std::string service_info_name_2("ServiceInfoName_1"); + std::string endpoint_info_name(kEndpointName); + + EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id_1, {})); + EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id_2, {})); + + NsdServiceInfo nsd_service_info_1; + nsd_service_info_1.SetServiceName(service_info_name_1); + nsd_service_info_1.SetTxtRecord(std::string(kEndpointInfoKey), + endpoint_info_name); + NsdServiceInfo nsd_service_info_2; + nsd_service_info_2.SetServiceName(service_info_name_2); + nsd_service_info_2.SetTxtRecord(std::string(kEndpointInfoKey), + endpoint_info_name); + EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id_1, nsd_service_info_1)); + EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id_2, nsd_service_info_2)); + EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id_1)); + EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id_2)); + EXPECT_TRUE(wifi_lan_a.StopAcceptingConnections(service_id_1)); + EXPECT_TRUE(wifi_lan_a.StopAcceptingConnections(service_id_2)); env_.Stop(); } TEST_F(WifiLanTest, CanStartDiscovery) { + env_.Start(); + WifiLan wifi_lan_a; + std::string service_id(kServiceID); + + EXPECT_TRUE( + wifi_lan_a.StartDiscovery(service_id, DiscoveredServiceCallback{})); + EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id)); + env_.Stop(); +} + +TEST_F(WifiLanTest, CanStartMultipleDiscovery) { + env_.Start(); + WifiLan wifi_lan_a; + std::string service_id_1(kServiceID); + std::string service_id_2("com.google.location.nearby.apps.test_1"); + + EXPECT_TRUE( + wifi_lan_a.StartDiscovery(service_id_1, DiscoveredServiceCallback{})); + + EXPECT_TRUE( + wifi_lan_a.StartDiscovery(service_id_2, DiscoveredServiceCallback{})); + EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id_1)); + EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id_2)); + env_.Stop(); +} + +TEST_F(WifiLanTest, CanAdvertiseThatOtherMediumDiscover) { env_.Start(); WifiLan wifi_lan_a; WifiLan wifi_lan_b; std::string service_id(kServiceID); - std::string service_info_name{kServiceInfoName}; - std::string endpoint_info_name{kEndpointName}; - CountDownLatch accept_latch(1); + std::string service_info_name(kServiceInfoName); + std::string endpoint_info_name(kEndpointName); + CountDownLatch discovered_latch(1); CountDownLatch lost_latch(1); + wifi_lan_b.StartDiscovery( + service_id, DiscoveredServiceCallback{ + .service_discovered_cb = + [&discovered_latch](NsdServiceInfo service_info, + const std::string& service_id) { + discovered_latch.CountDown(); + }, + .service_lost_cb = + [&lost_latch](NsdServiceInfo service_info, + const std::string& service_id) { + lost_latch.CountDown(); + }, + }); + + EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id, {})); + + NsdServiceInfo nsd_service_info; + nsd_service_info.SetServiceName(service_info_name); + nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), + endpoint_info_name); + EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id, nsd_service_info)); + EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id)); + EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(wifi_lan_b.StopDiscovery(service_id)); + env_.Stop(); +} + +TEST_F(WifiLanTest, CanDiscoverThatOtherMediumAdvertise) { + env_.Start(); + WifiLan wifi_lan_a; + WifiLan wifi_lan_b; + std::string service_id(kServiceID); + std::string service_info_name(kServiceInfoName); + std::string endpoint_info_name(kEndpointName); + CountDownLatch discovered_latch(1); + CountDownLatch lost_latch(1); + + EXPECT_TRUE(wifi_lan_b.StartAcceptingConnections(service_id, {})); + NsdServiceInfo nsd_service_info; nsd_service_info.SetServiceName(service_info_name); nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), @@ -224,20 +322,20 @@ TEST_F(WifiLanTest, CanStartDiscovery) { wifi_lan_b.StartAdvertising(service_id, nsd_service_info); EXPECT_TRUE(wifi_lan_a.StartDiscovery( - service_id, { + service_id, DiscoveredServiceCallback{ .service_discovered_cb = - [&accept_latch](WifiLanService& service, - const std::string& service_id) { - accept_latch.CountDown(); + [&discovered_latch](NsdServiceInfo service_info, + const std::string& service_id) { + discovered_latch.CountDown(); }, .service_lost_cb = - [&lost_latch](WifiLanService& service, + [&lost_latch](NsdServiceInfo service_info, const std::string& service_id) { lost_latch.CountDown(); }, })); - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - wifi_lan_b.StopAdvertising(service_id); + EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(wifi_lan_b.StopAdvertising(service_id)); EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id)); env_.Stop(); diff --git a/cpp/core/internal/mediums/wifi_lan_test_v2.cc b/cpp/core/internal/mediums/wifi_lan_test_v2.cc deleted file mode 100644 index cfa163e8..00000000 --- a/cpp/core/internal/mediums/wifi_lan_test_v2.cc +++ /dev/null @@ -1,344 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "core/internal/mediums/wifi_lan_v2.h" -#include "platform/base/medium_environment.h" -#include "platform/base/nsd_service_info.h" -#include "platform/public/count_down_latch.h" -#include "platform/public/logging.h" -#include "platform/public/wifi_lan_v2.h" - -namespace location { -namespace nearby { -namespace connections { -namespace { - -using FeatureFlags = FeatureFlags::Flags; - -constexpr FeatureFlags kTestCases[] = { - FeatureFlags{ - .enable_cancellation_flag = true, - }, - FeatureFlags{ - .enable_cancellation_flag = false, - }, -}; - -constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); -constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; -constexpr absl::string_view kServiceInfoName{"ServiceInfoName"}; -constexpr absl::string_view kEndpointName{"EndpointName"}; -constexpr absl::string_view kEndpointInfoKey{"n"}; - -class WifiLanV2Test : public ::testing::TestWithParam { - protected: - using DiscoveredServiceCallback = WifiLanMediumV2::DiscoveredServiceCallback; - - WifiLanV2Test() { env_.Stop(); } - - MediumEnvironment& env_{MediumEnvironment::Instance()}; -}; - -TEST_P(WifiLanV2Test, CanConnect) { - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - env_.Start(); - WifiLanV2 wifi_lan_client; - WifiLanV2 wifi_lan_server; - std::string service_id(kServiceID); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch accept_latch(1); - - WifiLanSocketV2 socket_for_server; - EXPECT_TRUE(wifi_lan_server.StartAcceptingConnections( - service_id, - { - .accepted_cb = - [&socket_for_server, &accept_latch](WifiLanSocketV2 socket) { - socket_for_server = std::move(socket); - accept_latch.CountDown(); - }, - })); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - wifi_lan_server.StartAdvertising(service_id, nsd_service_info); - - NsdServiceInfo discovered_service_info; - wifi_lan_client.StartDiscovery( - service_id, - { - .service_discovered_cb = - [&discovered_latch, &discovered_service_info]( - NsdServiceInfo service_info, const std::string& service_id) { - NEARBY_LOGS(INFO) - << "Discovered service_info=" << &service_info; - discovered_service_info = service_info; - discovered_latch.CountDown(); - }, - }); - discovered_latch.Await(kWaitDuration).result(); - ASSERT_TRUE(discovered_service_info.IsValid()); - - CancellationFlag flag; - WifiLanSocketV2 socket_for_client = - wifi_lan_client.Connect(service_id, discovered_service_info, &flag); - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); - EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); - EXPECT_TRUE(socket_for_server.IsValid()); - EXPECT_TRUE(socket_for_client.IsValid()); - env_.Stop(); -} - -TEST_P(WifiLanV2Test, CanCancelConnect) { - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - env_.Start(); - WifiLanV2 wifi_lan_client; - WifiLanV2 wifi_lan_server; - std::string service_id(kServiceID); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch accept_latch(1); - - WifiLanSocketV2 socket_for_server; - EXPECT_TRUE(wifi_lan_server.StartAcceptingConnections( - service_id, - { - .accepted_cb = - [&socket_for_server, &accept_latch](WifiLanSocketV2 socket) { - socket_for_server = std::move(socket); - accept_latch.CountDown(); - }, - })); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - wifi_lan_server.StartAdvertising(service_id, nsd_service_info); - - NsdServiceInfo discovered_service_info; - wifi_lan_client.StartDiscovery( - service_id, - { - .service_discovered_cb = - [&discovered_latch, &discovered_service_info]( - NsdServiceInfo service_info, const std::string& service_id) { - NEARBY_LOGS(INFO) - << "Discovered service_info=" << &service_info; - discovered_service_info = service_info; - discovered_latch.CountDown(); - }, - }); - EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); - ASSERT_TRUE(discovered_service_info.IsValid()); - - CancellationFlag flag(true); - WifiLanSocketV2 socket_for_client = - wifi_lan_client.Connect(service_id, discovered_service_info, &flag); - // If FeatureFlag is disabled, Cancelled is false as no-op. - if (!feature_flags.enable_cancellation_flag) { - EXPECT_TRUE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); - EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); - EXPECT_TRUE(socket_for_server.IsValid()); - EXPECT_TRUE(socket_for_client.IsValid()); - } else { - EXPECT_FALSE(accept_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_server.StopAcceptingConnections(service_id)); - EXPECT_TRUE(wifi_lan_server.StopAdvertising(service_id)); - EXPECT_FALSE(socket_for_server.IsValid()); - EXPECT_FALSE(socket_for_client.IsValid()); - } - env_.Stop(); -} - -INSTANTIATE_TEST_SUITE_P(ParametrisedWifiLanTest, WifiLanV2Test, - ::testing::ValuesIn(kTestCases)); - -TEST_F(WifiLanV2Test, CanConstructValidObject) { - env_.Start(); - WifiLanV2 wifi_lan_a; - WifiLanV2 wifi_lan_b; - std::string service_id(kServiceID); - - EXPECT_TRUE(wifi_lan_a.IsAvailable()); - EXPECT_TRUE(wifi_lan_b.IsAvailable()); - env_.Stop(); -} - -TEST_F(WifiLanV2Test, CanStartAdvertising) { - env_.Start(); - WifiLanV2 wifi_lan_a; - std::string service_id(kServiceID); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - - EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id, {})); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id, nsd_service_info)); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id)); - env_.Stop(); -} - -TEST_F(WifiLanV2Test, CanStartMultipleAdvertising) { - env_.Start(); - WifiLanV2 wifi_lan_a; - std::string service_id_1(kServiceID); - std::string service_id_2("com.google.location.nearby.apps.test_1"); - std::string service_info_name_1(kServiceInfoName); - std::string service_info_name_2("ServiceInfoName_1"); - std::string endpoint_info_name(kEndpointName); - - EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id_1, {})); - EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id_2, {})); - - NsdServiceInfo nsd_service_info_1; - nsd_service_info_1.SetServiceName(service_info_name_1); - nsd_service_info_1.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - NsdServiceInfo nsd_service_info_2; - nsd_service_info_2.SetServiceName(service_info_name_2); - nsd_service_info_2.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id_1, nsd_service_info_1)); - EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id_2, nsd_service_info_2)); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id_1)); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id_2)); - env_.Stop(); -} - -TEST_F(WifiLanV2Test, CanStartDiscovery) { - env_.Start(); - WifiLanV2 wifi_lan_a; - std::string service_id(kServiceID); - - EXPECT_TRUE( - wifi_lan_a.StartDiscovery(service_id, DiscoveredServiceCallback{})); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id)); - env_.Stop(); -} - -TEST_F(WifiLanV2Test, CanStartMultipleDiscovery) { - env_.Start(); - WifiLanV2 wifi_lan_a; - std::string service_id_1(kServiceID); - std::string service_id_2("com.google.location.nearby.apps.test_1"); - - EXPECT_TRUE( - wifi_lan_a.StartDiscovery(service_id_1, DiscoveredServiceCallback{})); - - EXPECT_TRUE( - wifi_lan_a.StartDiscovery(service_id_2, DiscoveredServiceCallback{})); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id_1)); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id_2)); - env_.Stop(); -} - -TEST_F(WifiLanV2Test, CanAdvertiseThatOtherMediumDiscover) { - env_.Start(); - WifiLanV2 wifi_lan_a; - WifiLanV2 wifi_lan_b; - std::string service_id(kServiceID); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch lost_latch(1); - - wifi_lan_b.StartDiscovery( - service_id, DiscoveredServiceCallback{ - .service_discovered_cb = - [&discovered_latch](NsdServiceInfo service_info, - const std::string& service_id) { - discovered_latch.CountDown(); - }, - .service_lost_cb = - [&lost_latch](NsdServiceInfo service_info, - const std::string& service_id) { - lost_latch.CountDown(); - }, - }); - - EXPECT_TRUE(wifi_lan_a.StartAcceptingConnections(service_id, {})); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id, nsd_service_info)); - EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id)); - EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_b.StopDiscovery(service_id)); - env_.Stop(); -} - -TEST_F(WifiLanV2Test, CanDiscoverThatOtherMediumAdvertise) { - env_.Start(); - WifiLanV2 wifi_lan_a; - WifiLanV2 wifi_lan_b; - std::string service_id(kServiceID); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch lost_latch(1); - - EXPECT_TRUE(wifi_lan_b.StartAcceptingConnections(service_id, {})); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - wifi_lan_b.StartAdvertising(service_id, nsd_service_info); - - EXPECT_TRUE(wifi_lan_a.StartDiscovery( - service_id, DiscoveredServiceCallback{ - .service_discovered_cb = - [&discovered_latch](NsdServiceInfo service_info, - const std::string& service_id) { - discovered_latch.CountDown(); - }, - .service_lost_cb = - [&lost_latch](NsdServiceInfo service_info, - const std::string& service_id) { - lost_latch.CountDown(); - }, - })); - EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_b.StopAdvertising(service_id)); - EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id)); - env_.Stop(); -} - -} // namespace -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/cpp/core/internal/mediums/wifi_lan_v2.cc b/cpp/core/internal/mediums/wifi_lan_v2.cc deleted file mode 100644 index 8358cb16..00000000 --- a/cpp/core/internal/mediums/wifi_lan_v2.cc +++ /dev/null @@ -1,409 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "core/internal/mediums/wifi_lan_v2.h" - -#include -#include -#include - -#include "absl/strings/str_format.h" -#include "core/internal/mediums/utils.h" -#include "platform/public/logging.h" -#include "platform/public/mutex_lock.h" - -namespace location { -namespace nearby { -namespace connections { - -WifiLanV2::~WifiLanV2() { - // Destructor is not taking locks, but methods it is calling are. - while (!discovering_info_.service_ids.empty()) { - StopDiscovery(*discovering_info_.service_ids.begin()); - } - while (!server_sockets_.empty()) { - StopAcceptingConnections(server_sockets_.begin()->first); - } - while (!advertising_info_.nsd_service_infos.empty()) { - StopAdvertising(advertising_info_.nsd_service_infos.begin()->first); - } - - // All the AcceptLoopRunnable objects in here should already have gotten an - // opportunity to shut themselves down cleanly in the calls to - // StopAcceptingConnections() above. - accept_loops_runner_.Shutdown(); -} - -bool WifiLanV2::IsAvailable() const { - MutexLock lock(&mutex_); - - return IsAvailableLocked(); -} - -bool WifiLanV2::IsAvailableLocked() const { return medium_.IsValid(); } - -bool WifiLanV2::StartAdvertising(const std::string& service_id, - NsdServiceInfo& nsd_service_info) { - MutexLock lock(&mutex_); - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) - << "Can't turn on WifiLan advertising. WifiLan is not available."; - return false; - } - - if (!nsd_service_info.IsValid()) { - NEARBY_LOGS(INFO) - << "Refusing to turn on WifiLan advertising. nsd_service_info is not " - "valid."; - return false; - } - - if (IsAdvertisingLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Failed to WifiLan advertise because we're already advertising."; - return false; - } - - if (!IsAcceptingConnectionsLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Failed to turn on WifiLan advertising with nsd_service_info=" - << &nsd_service_info - << ", service_name=" << nsd_service_info.GetServiceName() - << ", service_id=" << service_id - << ". Should accept connections before advertising."; - return false; - } - - nsd_service_info.SetServiceType(GenerateServiceType(service_id)); - const auto& it = server_sockets_.find(service_id); - if (it != server_sockets_.end()) { - nsd_service_info.SetIPAddress(it->second.GetIPAddress()); - nsd_service_info.SetPort(it->second.GetPort()); - } - if (!medium_.StartAdvertising(nsd_service_info)) { - NEARBY_LOGS(INFO) - << "Failed to turn on WifiLan advertising with nsd_service_info=" - << &nsd_service_info - << ", service_name=" << nsd_service_info.GetServiceName() - << ", service_id=" << service_id; - return false; - } - - NEARBY_LOGS(INFO) << "Turned on WifiLan advertising with nsd_service_info=" - << &nsd_service_info - << ", service_name=" << nsd_service_info.GetServiceName() - << ", service_id=" << service_id; - advertising_info_.Add(service_id, std::move(nsd_service_info)); - return true; -} - -bool WifiLanV2::StopAdvertising(const std::string& service_id) { - MutexLock lock(&mutex_); - - if (!IsAdvertisingLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Can't turn off WifiLan advertising; it is already off"; - return false; - } - - NEARBY_LOGS(INFO) << "Turned off WifiLan advertising with service_id=" - << service_id; - bool ret = - medium_.StopAdvertising(*advertising_info_.GetServiceInfo(service_id)); - // Reset our bundle of advertising state to mark that we're no longer - // advertising for specific service_id. - advertising_info_.Remove(service_id); - return ret; -} - -bool WifiLanV2::IsAdvertising(const std::string& service_id) { - MutexLock lock(&mutex_); - - return IsAdvertisingLocked(service_id); -} - -bool WifiLanV2::IsAdvertisingLocked(const std::string& service_id) { - return advertising_info_.Existed(service_id); -} - -bool WifiLanV2::StartDiscovery(const std::string& service_id, - DiscoveredServiceCallback callback) { - MutexLock lock(&mutex_); - - if (service_id.empty()) { - NEARBY_LOGS(INFO) - << "Refusing to start WifiLan discovering with empty service_id."; - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) - << "Can't discover WifiLan services because WifiLan isn't available."; - return false; - } - - if (IsDiscoveringLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Refusing to start discovery of WifiLan services because another " - "discovery is already in-progress."; - return false; - } - - std::string service_type = GenerateServiceType(service_id); - bool ret = medium_.StartDiscovery(service_id, service_type, callback); - if (!ret) { - NEARBY_LOGS(INFO) << "Failed to start discovery of WifiLan services."; - return false; - } - - NEARBY_LOGS(INFO) << "Turned on WifiLan discovering with service_id=" - << service_id; - // Mark the fact that we're currently performing a WifiLan discovering. - discovering_info_.Add(service_id); - return true; -} - -bool WifiLanV2::StopDiscovery(const std::string& service_id) { - MutexLock lock(&mutex_); - - if (!IsDiscoveringLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Can't turn off WifiLan discovering because we never started " - "discovering."; - return false; - } - - std::string service_type = GenerateServiceType(service_id); - NEARBY_LOGS(INFO) << "Turned off WifiLan discovering with service_id=" - << service_id << ", service_type=" << service_type; - bool ret = medium_.StopDiscovery(service_type); - discovering_info_.Remove(service_id); - return ret; -} - -bool WifiLanV2::IsDiscovering(const std::string& service_id) { - MutexLock lock(&mutex_); - return IsDiscoveringLocked(service_id); -} - -bool WifiLanV2::IsDiscoveringLocked(const std::string& service_id) { - return discovering_info_.Existed(service_id); -} - -bool WifiLanV2::StartAcceptingConnections(const std::string& service_id, - AcceptedConnectionCallback callback) { - MutexLock lock(&mutex_); - - if (service_id.empty()) { - NEARBY_LOGS(INFO) << "Refusing to start accepting WifiLan connections; " - "service_id is empty."; - return false; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) - << "Can't start accepting WifiLan connections [service_id=" - << service_id << "]; WifiLan not available."; - return false; - } - - if (IsAcceptingConnectionsLocked(service_id)) { - NEARBY_LOGS(INFO) - << "Refusing to start accepting WifiLan connections [service=" - << service_id - << "]; WifiLan server is already in-progress with the same name."; - return false; - } - - // We can generate an exact port here on server socket; now we just assign 0 - // to let platform medium decide it. - int port = 0; - WifiLanServerSocketV2 server_socket = medium_.ListenForService(port); - if (!server_socket.IsValid()) { - NEARBY_LOGS(INFO) - << "Failed to start accepting WifiLan connections for service_id=" - << service_id; - return false; - } - - // Mark the fact that there's an in-progress WifiLan server accepting - // connections. - auto owned_server_socket = - server_sockets_.insert({service_id, std::move(server_socket)}) - .first->second; - - // Start the accept loop on a dedicated thread - this stays alive and - // listening for new incoming connections until StopAcceptingConnections() is - // invoked. - accept_loops_runner_.Execute( - "wifi-lan-accept", - [callback = std::move(callback), - server_socket = std::move(owned_server_socket), service_id]() mutable { - while (true) { - WifiLanSocketV2 client_socket = server_socket.Accept(); - if (!client_socket.IsValid()) { - server_socket.Close(); - break; - } - callback.accepted_cb(std::move(client_socket)); - } - }); - - return true; -} - -bool WifiLanV2::StopAcceptingConnections(const std::string& service_id) { - MutexLock lock(&mutex_); - - if (service_id.empty()) { - NEARBY_LOGS(INFO) << "Unable to stop accepting WifiLan connections because " - "the service_id is empty."; - return false; - } - - const auto& it = server_sockets_.find(service_id); - if (it == server_sockets_.end()) { - NEARBY_LOGS(INFO) << "Can't stop accepting WifiLan connections for " - << service_id << " because it was never started."; - return false; - } - - // Closing the WifiLanServerSocket will kick off the suicide of the thread - // in accept_loops_thread_pool_ that blocks on WifiLanServerSocket.accept(). - // That may take some time to complete, but there's no particular reason to - // wait around for it. - auto item = server_sockets_.extract(it); - - // Store a handle to the WifiLanServerSocket, so we can use it after - // removing the entry from server_sockets_; making it scoped - // is a bonus that takes care of deallocation before we leave this method. - WifiLanServerSocketV2& listening_socket = item.mapped(); - - // Regardless of whether or not we fail to close the existing - // WifiLanServerSocket, remove it from server_sockets_ so that it - // frees up this service for another round. - - // Finally, close the WifiLanServerSocket. - if (!listening_socket.Close().Ok()) { - NEARBY_LOGS(INFO) << "Failed to close WifiLan server socket for service_id=" - << service_id; - return false; - } - - return true; -} - -bool WifiLanV2::IsAcceptingConnections(const std::string& service_id) { - MutexLock lock(&mutex_); - return IsAcceptingConnectionsLocked(service_id); -} - -bool WifiLanV2::IsAcceptingConnectionsLocked(const std::string& service_id) { - return server_sockets_.find(service_id) != server_sockets_.end(); -} - -WifiLanSocketV2 WifiLanV2::Connect(const std::string& service_id, - const NsdServiceInfo& service_info, - CancellationFlag* cancellation_flag) { - MutexLock lock(&mutex_); - // Socket to return. To allow for NRVO to work, it has to be a single object. - WifiLanSocketV2 socket; - - if (service_id.empty()) { - NEARBY_LOGS(INFO) << "Refusing to create client WifiLan socket because " - "service_id is empty."; - return socket; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) << "Can't create client WifiLan socket [service_id=" - << service_id << "]; WifiLan isn't available."; - return socket; - } - - if (cancellation_flag->Cancelled()) { - NEARBY_LOGS(INFO) << "Can't create client WifiLan socket due to cancel."; - return socket; - } - - socket = medium_.ConnectToService(service_info, cancellation_flag); - if (!socket.IsValid()) { - NEARBY_LOGS(INFO) << "Failed to Connect via WifiLan [service_id=" - << service_id << "]"; - } - - return socket; -} - -WifiLanSocketV2 WifiLanV2::Connect(const std::string& service_id, - const std::string& ip_address, int port, - CancellationFlag* cancellation_flag) { - MutexLock lock(&mutex_); - // Socket to return. To allow for NRVO to work, it has to be a single object. - WifiLanSocketV2 socket; - - if (service_id.empty()) { - NEARBY_LOGS(INFO) << "Refusing to create client WifiLan socket because " - "service_id is empty."; - return socket; - } - - if (!IsAvailableLocked()) { - NEARBY_LOGS(INFO) << "Can't create client WifiLan socket [service_id=" - << service_id << "]; WifiLan isn't available."; - return socket; - } - - if (cancellation_flag->Cancelled()) { - NEARBY_LOGS(INFO) << "Can't create client WifiLan socket due to cancel."; - return socket; - } - - socket = medium_.ConnectToService(ip_address, port, cancellation_flag); - if (!socket.IsValid()) { - NEARBY_LOGS(INFO) << "Failed to Connect via WifiLan [service_id=" - << service_id << "]"; - } - - return socket; -} - -std::pair WifiLanV2::GetCredentials( - const std::string& service_id) { - MutexLock lock(&mutex_); - const auto& it = server_sockets_.find(service_id); - if (it == server_sockets_.end()) { - return std::pair(); - } - return std::pair(it->second.GetIPAddress(), - it->second.GetPort()); -} - -std::string WifiLanV2::GenerateServiceType(const std::string& service_id) { - std::string service_id_hash_string; - - const ByteArray service_id_hash = Utils::Sha256Hash( - service_id, NsdServiceInfo::kTypeFromServiceIdHashLength); - for (auto byte : std::string(service_id_hash)) { - absl::StrAppend(&service_id_hash_string, absl::StrFormat("%02X", byte)); - } - - return absl::StrFormat(NsdServiceInfo::kNsdTypeFormat, - service_id_hash_string); -} - -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/cpp/core/internal/mediums/wifi_lan_v2.h b/cpp/core/internal/mediums/wifi_lan_v2.h deleted file mode 100644 index 119ce152..00000000 --- a/cpp/core/internal/mediums/wifi_lan_v2.h +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef CORE_INTERNAL_MEDIUMS_WIFI_LAN_V2_H_ -#define CORE_INTERNAL_MEDIUMS_WIFI_LAN_V2_H_ - -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/container/flat_hash_set.h" -#include "platform/base/byte_array.h" -#include "platform/base/cancellation_flag.h" -#include "platform/base/nsd_service_info.h" -#include "platform/public/multi_thread_executor.h" -#include "platform/public/mutex.h" -#include "platform/public/wifi_lan_v2.h" - -namespace location { -namespace nearby { -namespace connections { - -class WifiLanV2 { - public: - using DiscoveredServiceCallback = WifiLanMediumV2::DiscoveredServiceCallback; - - // Callback that is invoked when a new connection is accepted. - struct AcceptedConnectionCallback { - std::function accepted_cb = - DefaultCallback(); - }; - - WifiLanV2() = default; - ~WifiLanV2(); - - // Returns true, if WifiLan communications are supported by a platform. - bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_); - - // Sets custom service info name, endpoint info name in NsdServiceInfo and - // then enables WifiLan advertising. - // Returns true, if NsdServiceInfo is successfully set, and false otherwise. - bool StartAdvertising(const std::string& service_id, - NsdServiceInfo& nsd_service_info) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Disables WifiLan advertising. - // Returns false if no successful call StartAdvertising() was previously - // made, otherwise returns true. - bool StopAdvertising(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - bool IsAdvertising(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); - - // Enables WifiLan discovery. Will report any discoverable services - // through a callback. - // Returns true, if discovery was enabled, false otherwise. - bool StartDiscovery(const std::string& service_id, - DiscoveredServiceCallback callback) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Disables WifiLan discovery. - bool StopDiscovery(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); - - bool IsDiscovering(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); - - // Starts a worker thread, creates a WifiLan socket, associates it with a - // service id. - bool StartAcceptingConnections(const std::string& service_id, - AcceptedConnectionCallback callback) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Closes socket corresponding to a service id. - bool StopAcceptingConnections(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - bool IsAcceptingConnections(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Establishes connection to WifiLan service that was might be started on - // another service with StartAcceptingConnections() using the same service_id. - // Blocks until connection is established, or server-side is terminated. - // Returns socket instance. On success, WifiLanSocket.IsValid() return true. - WifiLanSocketV2 Connect(const std::string& service_id, - const NsdServiceInfo& service_info, - CancellationFlag* cancellation_flag) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Establishes connection to WifiLan service by ip address and port for - // bandwidth upgradation. - // Returns socket instance. On success, WifiLanSocket.IsValid() return true. - WifiLanSocketV2 Connect(const std::string& service_id, - const std::string& ip_address, int port, - CancellationFlag* cancellation_flag) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Gets ip address + port for remote services on the network to identify and - // connect to this service. - // - // Credential is for the currently-hosted Wifi ServerSocket (if any). - std::pair GetCredentials(const std::string& service_id) - ABSL_LOCKS_EXCLUDED(mutex_); - - private: - struct AdvertisingInfo { - bool Empty() const { return nsd_service_infos.empty(); } - void Clear() { nsd_service_infos.clear(); } - void Add(const std::string& service_id, - const NsdServiceInfo& nsd_service_info) { - nsd_service_infos.insert({service_id, nsd_service_info}); - } - void Remove(const std::string& service_id) { - nsd_service_infos.erase(service_id); - } - bool Existed(const std::string& service_id) const { - return nsd_service_infos.contains(service_id); - } - NsdServiceInfo* GetServiceInfo(const std::string& service_id) { - const auto& it = nsd_service_infos.find(service_id); - if (it == nsd_service_infos.end()) { - return nullptr; - } - return &it->second; - } - - absl::flat_hash_map nsd_service_infos; - }; - - struct DiscoveringInfo { - bool Empty() const { return service_ids.empty(); } - void Clear() { service_ids.clear(); } - void Add(const std::string& service_id) { service_ids.insert(service_id); } - void Remove(const std::string& service_id) { - service_ids.erase(service_id); - } - bool Existed(const std::string& service_id) const { - return service_ids.contains(service_id); - } - - absl::flat_hash_set service_ids; - }; - - static constexpr int kMaxConcurrentAcceptLoops = 5; - - // Same as IsAvailable(), but must be called with mutex_ held. - bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Same as IsAdvertising(), but must be called with mutex_ held. - bool IsAdvertisingLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Same as IsDiscovering(), but must be called with mutex_ held. - bool IsDiscoveringLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Same as IsAcceptingConnections(), but must be called with mutex_ held. - bool IsAcceptingConnectionsLocked(const std::string& service_id) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Generates mDNS type. - std::string GenerateServiceType(const std::string& service_id); - - mutable Mutex mutex_; - WifiLanMediumV2 medium_ ABSL_GUARDED_BY(mutex_); - AdvertisingInfo advertising_info_ ABSL_GUARDED_BY(mutex_); - DiscoveringInfo discovering_info_ ABSL_GUARDED_BY(mutex_); - - // A thread pool dedicated to running all the accept loops from - // StartAcceptingConnections(). - MultiThreadExecutor accept_loops_runner_{kMaxConcurrentAcceptLoops}; - - // A map of service_id -> ServerSocket. If map is non-empty, we - // are currently listening for incoming connections. - // WifiLanServerSocket instances are used from accept_loops_runner_, - // and thus require pointer stability. - absl::flat_hash_map server_sockets_ - ABSL_GUARDED_BY(mutex_); -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_MEDIUMS_WIFI_LAN_H_ diff --git a/cpp/core/internal/p2p_cluster_pcp_handler.cc b/cpp/core/internal/p2p_cluster_pcp_handler.cc index 7f174ce1..1bcc5999 100644 --- a/cpp/core/internal/p2p_cluster_pcp_handler.cc +++ b/cpp/core/internal/p2p_cluster_pcp_handler.cc @@ -25,7 +25,6 @@ #include "core/internal/mediums/webrtc_socket_wrapper.h" #include "core/internal/webrtc_endpoint_channel.h" #include "core/internal/wifi_lan_endpoint_channel.h" -#include "core/internal/wifi_lan_endpoint_channel_v2.h" #include "platform/base/nsd_service_info.h" #include "platform/base/types.h" #include "platform/public/crypto.h" @@ -60,7 +59,6 @@ P2pClusterPcpHandler::P2pClusterPcpHandler( bluetooth_medium_(mediums->GetBluetoothClassic()), ble_medium_(mediums->GetBle()), wifi_lan_medium_(mediums->GetWifiLan()), - wifi_lan_medium_v2_(mediums->GetWifiLanV2()), webrtc_medium_(mediums->GetWebRtc()), injected_bluetooth_device_store_(injected_bluetooth_device_store) {} @@ -70,9 +68,6 @@ P2pClusterPcpHandler::P2pClusterPcpHandler( std::vector P2pClusterPcpHandler::GetConnectionMediumsByPriority() { std::vector mediums; - if (wifi_lan_medium_v2_.IsAvailable()) { - mediums.push_back(proto::connections::MDNS); - } if (wifi_lan_medium_.IsAvailable()) { mediums.push_back(proto::connections::WIFI_LAN); } @@ -100,17 +95,6 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl( WebRtcState web_rtc_state{WebRtcState::kUnconnectable}; - if (options.allowed.wifi_lan_v2) { - proto::connections::Medium wifi_lan_medium = - StartWifiLanV2Advertising(client, service_id, local_endpoint_id, - local_endpoint_info, web_rtc_state); - if (wifi_lan_medium != proto::connections::UNKNOWN_MEDIUM) { - NEARBY_LOGS(INFO) - << "P2pClusterPcpHandler::StartAdvertisingImpl: WifiLan added"; - mediums_started_successfully.push_back(wifi_lan_medium); - } - } - if (options.allowed.wifi_lan) { proto::connections::Medium wifi_lan_medium = StartWifiLanAdvertising(client, service_id, local_endpoint_id, @@ -184,10 +168,6 @@ Status P2pClusterPcpHandler::StopAdvertisingImpl(ClientProxy* client) { wifi_lan_medium_.StopAdvertising(client->GetAdvertisingServiceId()); wifi_lan_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId()); - wifi_lan_medium_v2_.StopAdvertising(client->GetAdvertisingServiceId()); - wifi_lan_medium_v2_.StopAcceptingConnections( - client->GetAdvertisingServiceId()); - return {Status::kSuccess}; } @@ -555,126 +535,6 @@ void P2pClusterPcpHandler::BlePeripheralLostHandler( } bool P2pClusterPcpHandler::IsRecognizedWifiLanEndpoint( - const std::string& service_id, - const WifiLanServiceInfo& service_info) const { - if (!service_info.IsValid()) { - NEARBY_LOGS(INFO) - << "WifiLanServiceInfo doesn't conform to the format, discarding."; - return false; - } - - if (service_info.GetPcp() != GetPcp()) { - NEARBY_LOGS(INFO) << "WifiLanServiceInfo doesn't match on Pcp; expected " - << PcpToStrategy(GetPcp()).GetName() << ", found " - << PcpToStrategy(service_info.GetPcp()).GetName(); - return false; - } - - ByteArray expected_service_id_hash = - GenerateHash(service_id, WifiLanServiceInfo::kServiceIdHashLength); - - if (service_info.GetServiceIdHash() != expected_service_id_hash) { - NEARBY_LOGS(INFO) - << "WifiLanServiceInfo doesn't match on expected service_id_hash; " - "expected " - << absl::BytesToHexString(expected_service_id_hash.data()) << ", found " - << absl::BytesToHexString(service_info.GetServiceIdHash().data()); - return false; - } - - return true; -} - -void P2pClusterPcpHandler::WifiLanServiceDiscoveredHandler( - ClientProxy* client, WifiLanService& wifi_lan_service, - const std::string& service_id) { - RunOnPcpHandlerThread( - "p2p-wifi-service-discovered", - [this, client, service_id, &wifi_lan_service]() - RUN_ON_PCP_HANDLER_THREAD() { - // Make sure we are still discovering before proceeding. - if (!client->IsDiscovering()) { - NEARBY_LOGS(WARNING) - << "Skipping discovery of NsdServiceInfo " - << wifi_lan_service.GetServiceInfo().GetServiceName() - << " because we are no longer discovering."; - return; - } - - // Parse the WifiLanServiceInfo. - WifiLanServiceInfo service_info(wifi_lan_service.GetServiceInfo()); - - // Make sure the WifiLan service name points to a valid - // endpoint we're discovering. - if (!IsRecognizedWifiLanEndpoint(service_id, service_info)) return; - - // Report the discovered endpoint to the client. - NEARBY_LOGS(INFO) - << "Found NsdServiceInfo " - << wifi_lan_service.GetServiceInfo().GetServiceName() - << " (with endpoint_id=" << service_info.GetEndpointId() - << "and endpoint_info=" - << absl::BytesToHexString(service_info.GetEndpointInfo().data()) - << ")."; - OnEndpointFound(client, - std::make_shared(WifiLanEndpoint{ - { - service_info.GetEndpointId(), - service_info.GetEndpointInfo(), - service_id, - proto::connections::Medium::WIFI_LAN, - service_info.GetWebRtcState(), - }, - wifi_lan_service, - })); - }); -} - -void P2pClusterPcpHandler::WifiLanServiceLostHandler( - ClientProxy* client, WifiLanService& wifi_lan_service, - const std::string& service_id) { - NsdServiceInfo nsd_service_info = wifi_lan_service.GetServiceInfo(); - NEARBY_LOG(INFO, - "WifiLan: [LOST, SCHED] wifi_lan_service=%p, service_info_name=%s", - &wifi_lan_service, nsd_service_info.GetServiceName().c_str()); - RunOnPcpHandlerThread( - "p2p-wifi-service-lost", - [this, client, service_id, nsd_service_info]() - RUN_ON_PCP_HANDLER_THREAD() { - // Make sure we are still discovering before proceeding. - if (!client->IsDiscovering()) { - NEARBY_LOGS(WARNING) << "Ignoring lost NsdServiceInfo " - << nsd_service_info.GetServiceName() - << " because we are no longer " - "discovering."; - return; - } - - // Parse the WifiLanServiceInfo. - WifiLanServiceInfo service_info(nsd_service_info); - - // Make sure the WifiLan service name points to a valid - // endpoint we're discovering. - if (!IsRecognizedWifiLanEndpoint(service_id, service_info)) return; - - // Report the lost endpoint to the client. - NEARBY_LOGS(INFO) - << "Lost NsdServiceInfo " << nsd_service_info.GetServiceName() - << " (with endpoint_id=" << service_info.GetEndpointId() - << " and endpoint_info=" - << absl::BytesToHexString(service_info.GetEndpointInfo().data()) - << ")."; - OnEndpointLost(client, DiscoveredEndpoint{ - service_info.GetEndpointId(), - service_info.GetEndpointInfo(), - service_id, - proto::connections::Medium::WIFI_LAN, - WebRtcState::kUndefined, - }); - }); -} - -bool P2pClusterPcpHandler::IsRecognizedWifiLanV2Endpoint( const std::string& service_id, const WifiLanServiceInfo& wifi_lan_service_info) const { if (!wifi_lan_service_info.IsValid()) { @@ -707,7 +567,7 @@ bool P2pClusterPcpHandler::IsRecognizedWifiLanV2Endpoint( return true; } -void P2pClusterPcpHandler::WifiLanV2ServiceDiscoveredHandler( +void P2pClusterPcpHandler::WifiLanServiceDiscoveredHandler( ClientProxy* client, NsdServiceInfo service_info, const std::string& service_id) { RunOnPcpHandlerThread( @@ -725,7 +585,7 @@ void P2pClusterPcpHandler::WifiLanV2ServiceDiscoveredHandler( WifiLanServiceInfo wifi_lan_service_info(service_info); // Make sure the WifiLan service name points to a valid // endpoint we're discovering. - if (!IsRecognizedWifiLanV2Endpoint(service_id, wifi_lan_service_info)) { + if (!IsRecognizedWifiLanEndpoint(service_id, wifi_lan_service_info)) { return; } @@ -739,12 +599,12 @@ void P2pClusterPcpHandler::WifiLanV2ServiceDiscoveredHandler( wifi_lan_service_info.GetEndpointInfo().data()) << ")."; OnEndpointFound(client, - std::make_shared(WifiLanV2Endpoint{ + std::make_shared(WifiLanEndpoint{ { wifi_lan_service_info.GetEndpointId(), wifi_lan_service_info.GetEndpointInfo(), service_id, - proto::connections::Medium::MDNS, + proto::connections::Medium::WIFI_LAN, wifi_lan_service_info.GetWebRtcState(), }, service_info, @@ -752,7 +612,7 @@ void P2pClusterPcpHandler::WifiLanV2ServiceDiscoveredHandler( }); } -void P2pClusterPcpHandler::WifiLanV2ServiceLostHandler( +void P2pClusterPcpHandler::WifiLanServiceLostHandler( ClientProxy* client, NsdServiceInfo service_info, const std::string& service_id) { NEARBY_LOGS(INFO) << "WifiLan: [LOST, SCHED] service_info=" << &service_info @@ -774,7 +634,7 @@ void P2pClusterPcpHandler::WifiLanV2ServiceLostHandler( // Make sure the WifiLan service name points to a valid // endpoint we're discovering. - if (!IsRecognizedWifiLanV2Endpoint(service_id, wifi_lan_service_info)) + if (!IsRecognizedWifiLanEndpoint(service_id, wifi_lan_service_info)) return; // Report the lost endpoint to the client. @@ -808,24 +668,6 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( std::vector mediums_started_successfully; - if (options.allowed.wifi_lan_v2) { - proto::connections::Medium wifi_lan_medium = StartWifiLanV2Discovery( - { - .service_discovered_cb = absl::bind_front( - &P2pClusterPcpHandler::WifiLanV2ServiceDiscoveredHandler, this, - client), - .service_lost_cb = absl::bind_front( - &P2pClusterPcpHandler::WifiLanV2ServiceLostHandler, this, - client), - }, - client, service_id); - if (wifi_lan_medium != proto::connections::UNKNOWN_MEDIUM) { - NEARBY_LOGS(INFO) - << "P2pClusterPcpHandler::StartDiscoveryImpl: WifiLan added"; - mediums_started_successfully.push_back(wifi_lan_medium); - } - } - if (options.allowed.wifi_lan) { proto::connections::Medium wifi_lan_medium = StartWifiLanDiscovery( { @@ -899,7 +741,6 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( Status P2pClusterPcpHandler::StopDiscoveryImpl(ClientProxy* client) { wifi_lan_medium_.StopDiscovery(client->GetDiscoveryServiceId()); - wifi_lan_medium_v2_.StopDiscovery(client->GetDiscoveryServiceId()); if (client->GetClientId() == bluetooth_classic_discoverer_client_id_) { bluetooth_medium_.StopDiscovery(); bluetooth_classic_discoverer_client_id_ = 0; @@ -969,13 +810,6 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::ConnectImpl( } break; } - case proto::connections::Medium::MDNS: { - auto* wifi_lan_endpoint = down_cast(endpoint); - if (wifi_lan_endpoint) { - return WifiLanV2ConnectImpl(client, wifi_lan_endpoint); - } - break; - } case proto::connections::Medium::WEB_RTC: { break; } @@ -1376,14 +1210,13 @@ proto::connections::Medium P2pClusterPcpHandler::StartWifiLanAdvertising( WebRtcState web_rtc_state) { // Start listening for connections before advertising in case a connection // request comes in very quickly. - NEARBY_LOG(INFO, - "P2pClusterPcpHandler::StartWifiLanAdvertising: service=%s: start", - service_id.c_str()); + NEARBY_LOGS(INFO) << "P2pClusterPcpHandler::StartWifiLanAdvertising: service=" + << service_id << ": start"; if (!wifi_lan_medium_.IsAcceptingConnections(service_id)) { if (!wifi_lan_medium_.StartAcceptingConnections( - service_id, {.accepted_cb = [this, client, local_endpoint_info]( - WifiLanSocket socket, - const std::string& service_id) { + service_id, + {.accepted_cb = [this, client, local_endpoint_info, + local_endpoint_id](WifiLanSocket socket) { if (!socket.IsValid()) { NEARBY_LOGS(WARNING) << "Invalid socket in accept callback(" @@ -1393,22 +1226,18 @@ proto::connections::Medium P2pClusterPcpHandler::StartWifiLanAdvertising( } RunOnPcpHandlerThread( "p2p-wifi-on-incoming-connection", - [this, client, local_endpoint_info, - socket = std::move(socket)]() - RUN_ON_PCP_HANDLER_THREAD() mutable { - std::string remote_service_info_name = - socket.GetRemoteWifiLanService() - .GetServiceInfo() - .GetServiceName(); - auto channel = - absl::make_unique( - remote_service_info_name, socket); - ByteArray remote_service_info{remote_service_info_name}; + [this, client, local_endpoint_id, local_endpoint_info, + socket = std::move( + socket)]() RUN_ON_PCP_HANDLER_THREAD() mutable { + std::string remote_service_name = local_endpoint_id; + auto channel = absl::make_unique( + remote_service_name, socket); + ByteArray remote_service_name_byte{remote_service_name}; - OnIncomingConnection( - client, remote_service_info, std::move(channel), - proto::connections::Medium::WIFI_LAN); - }); + OnIncomingConnection(client, remote_service_name_byte, + std::move(channel), + proto::connections::Medium::WIFI_LAN); + }); }})) { NEARBY_LOGS(WARNING) << "In StartWifiLanAdvertising(" @@ -1419,12 +1248,12 @@ proto::connections::Medium P2pClusterPcpHandler::StartWifiLanAdvertising( << service_id; return proto::connections::UNKNOWN_MEDIUM; } - NEARBY_LOGS(INFO) - << "In StartWifiLanAdvertising(" - << absl::BytesToHexString(local_endpoint_info.data()) - << "), client=" << client->GetClientId() - << " started listening for incoming WifiLan connections to service_id=" - << service_id; + NEARBY_LOGS(INFO) << "In StartWifiLanAdvertising(" + << absl::BytesToHexString(local_endpoint_info.data()) + << "), client=" << client->GetClientId() + << " started listening for incoming WifiLan connections " + "to service_id = " + << service_id; } // Generate a WifiLanServiceInfo with which to become WifiLan discoverable. @@ -1438,7 +1267,7 @@ proto::connections::Medium P2pClusterPcpHandler::StartWifiLanAdvertising( local_endpoint_info, ByteArray{}, web_rtc_state}; - NsdServiceInfo nsd_service_info{service_info}; + NsdServiceInfo nsd_service_info(service_info); if (!nsd_service_info.IsValid()) { NEARBY_LOGS(WARNING) << "In StartWifiLanAdvertising(" << absl::BytesToHexString(local_endpoint_info.data()) @@ -1499,165 +1328,10 @@ proto::connections::Medium P2pClusterPcpHandler::StartWifiLanDiscovery( BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::WifiLanConnectImpl( ClientProxy* client, WifiLanEndpoint* endpoint) { - NEARBY_LOGS(VERBOSE) << "Client " << client->GetClientId() - << " is attempting to connect to endpoint(id=" - << endpoint->endpoint_id << ") over WifiLan."; - WifiLanService& wifi_lan_service = endpoint->wifi_lan_service; - - WifiLanSocket wifi_lan_socket = wifi_lan_medium_.Connect( - wifi_lan_service, endpoint->service_id, - client->GetCancellationFlag(endpoint->endpoint_id)); - if (!wifi_lan_socket.IsValid()) { - NEARBY_LOGS(ERROR) - << "In WifiLanConnectImpl(), failed to connect to service " - << wifi_lan_service.GetServiceInfo().GetServiceName() - << " for endpoint(id=" << endpoint->endpoint_id << ")."; - return BasePcpHandler::ConnectImplResult{ - .status = {Status::kWifiLanError}, - }; - } - - auto channel = absl::make_unique( - endpoint->endpoint_id, wifi_lan_socket); - NEARBY_LOGS(VERBOSE) << "Client " << client->GetClientId() - << " created WifiLan endpoint channel to endpoint(id=" - << endpoint->endpoint_id << ")."; - return BasePcpHandler::ConnectImplResult{ - .medium = proto::connections::Medium::WIFI_LAN, - .status = {Status::kSuccess}, - .endpoint_channel = std::move(channel), - }; -} - -proto::connections::Medium P2pClusterPcpHandler::StartWifiLanV2Advertising( - ClientProxy* client, const std::string& service_id, - const std::string& local_endpoint_id, const ByteArray& local_endpoint_info, - WebRtcState web_rtc_state) { - // Start listening for connections before advertising in case a connection - // request comes in very quickly. - NEARBY_LOGS(INFO) << "P2pClusterPcpHandler::StartWifiLanAdvertising: service=" - << service_id << ": start"; - if (!wifi_lan_medium_v2_.IsAcceptingConnections(service_id)) { - if (!wifi_lan_medium_v2_.StartAcceptingConnections( - service_id, - {.accepted_cb = [this, client, local_endpoint_info, - local_endpoint_id](WifiLanSocketV2 socket) { - if (!socket.IsValid()) { - NEARBY_LOGS(WARNING) - << "Invalid socket in accept callback(" - << absl::BytesToHexString(local_endpoint_info.data()) - << "), client=" << client->GetClientId(); - return; - } - RunOnPcpHandlerThread( - "p2p-wifi-on-incoming-connection", - [this, client, local_endpoint_id, local_endpoint_info, - socket = std::move(socket)]() - RUN_ON_PCP_HANDLER_THREAD() mutable { - std::string remote_service_name = local_endpoint_id; - auto channel = - absl::make_unique( - remote_service_name, socket); - ByteArray remote_service_name_byte{remote_service_name}; - - OnIncomingConnection(client, remote_service_name_byte, - std::move(channel), - proto::connections::Medium::MDNS); - }); - }})) { - NEARBY_LOGS(WARNING) - << "In StartWifiLanAdvertising(" - << absl::BytesToHexString(local_endpoint_info.data()) - << "), client=" << client->GetClientId() - << " failed to start listening for incoming WifiLan connections " - "to service_id=" - << service_id; - return proto::connections::UNKNOWN_MEDIUM; - } - NEARBY_LOGS(INFO) << "In StartWifiLanAdvertising(" - << absl::BytesToHexString(local_endpoint_info.data()) - << "), client=" << client->GetClientId() - << " started listening for incoming WifiLan connections " - "to service_id = " - << service_id; - } - - // Generate a WifiLanServiceInfo with which to become WifiLan discoverable. - // TODO(b/169550050): Implement UWBAddress. - const ByteArray service_id_hash = - GenerateHash(service_id, WifiLanServiceInfo::kServiceIdHashLength); - WifiLanServiceInfo service_info{kWifiLanServiceInfoVersion, - GetPcp(), - local_endpoint_id, - service_id_hash, - local_endpoint_info, - ByteArray{}, - web_rtc_state}; - NsdServiceInfo nsd_service_info(service_info); - if (!nsd_service_info.IsValid()) { - NEARBY_LOGS(WARNING) << "In StartWifiLanAdvertising(" - << absl::BytesToHexString(local_endpoint_info.data()) - << "), client=" << client->GetClientId() - << " failed to generate WifiLanServiceInfo {version=" - << static_cast(kWifiLanServiceInfoVersion) - << ", pcp=" << PcpToStrategy(GetPcp()).GetName() - << ", endpoint_id=" << local_endpoint_id - << ", service_id_hash=" - << absl::BytesToHexString(service_id_hash.data()) - << ", endpoint_info=" - << absl::BytesToHexString(local_endpoint_info.data()) - << "}."; - wifi_lan_medium_v2_.StopAcceptingConnections(service_id); - return proto::connections::UNKNOWN_MEDIUM; - } - NEARBY_LOGS(INFO) << "In StartWifiLanAdvertising(" - << absl::BytesToHexString(local_endpoint_info.data()) - << "), client=" << client->GetClientId() - << " generated WifiLanServiceInfo " - << nsd_service_info.GetServiceName() - << " with service_id=" << service_id; - - if (!wifi_lan_medium_v2_.StartAdvertising(service_id, nsd_service_info)) { - NEARBY_LOGS(INFO) << "In StartWifiLanAdvertising(" - << absl::BytesToHexString(local_endpoint_info.data()) - << "), client=" << client->GetClientId() - << " couldn't advertise with WifiLanServiceInfo " - << nsd_service_info.GetServiceName(); - wifi_lan_medium_v2_.StopAcceptingConnections(service_id); - return proto::connections::UNKNOWN_MEDIUM; - } - NEARBY_LOGS(INFO) << "In StartWifiLanAdvertising(" - << absl::BytesToHexString(local_endpoint_info.data()) - << "), client=" << client->GetClientId() - << " advertised with WifiLanServiceInfo " - << nsd_service_info.GetServiceName(); - return proto::connections::MDNS; -} - -proto::connections::Medium P2pClusterPcpHandler::StartWifiLanV2Discovery( - WifiLanV2DiscoveredServiceCallback callback, ClientProxy* client, - const std::string& service_id) { - if (wifi_lan_medium_v2_.StartDiscovery(service_id, std::move(callback))) { - NEARBY_LOGS(INFO) << "In StartWifiLanDiscovery(), client=" - << client->GetClientId() - << " started scanning for Wifi devices for service_id=" - << service_id; - return proto::connections::MDNS; - } else { - NEARBY_LOGS(INFO) << "In StartWifiLanDiscovery(), client=" - << client->GetClientId() - << " couldn't start scanning on Wifi for service_id=" - << service_id; - return proto::connections::UNKNOWN_MEDIUM; - } -} - -BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::WifiLanV2ConnectImpl( - ClientProxy* client, WifiLanV2Endpoint* endpoint) { NEARBY_LOGS(INFO) << "Client " << client->GetClientId() << " is attempting to connect to endpoint(id=" << endpoint->endpoint_id << ") over WifiLan."; - WifiLanSocketV2 socket = wifi_lan_medium_v2_.Connect( + WifiLanSocket socket = wifi_lan_medium_.Connect( endpoint->service_id, endpoint->service_info, client->GetCancellationFlag(endpoint->endpoint_id)); NEARBY_LOGS(ERROR) << "In WifiLanConnectImpl(), connect to service " @@ -1673,13 +1347,13 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::WifiLanV2ConnectImpl( }; } - auto channel = absl::make_unique( - endpoint->endpoint_id, socket); + auto channel = + absl::make_unique(endpoint->endpoint_id, socket); NEARBY_LOGS(INFO) << "Client " << client->GetClientId() << " created WifiLan endpoint channel to endpoint(id=" << endpoint->endpoint_id << ")."; return BasePcpHandler::ConnectImplResult{ - .medium = proto::connections::Medium::MDNS, + .medium = proto::connections::Medium::WIFI_LAN, .status = {Status::kSuccess}, .endpoint_channel = std::move(channel), }; diff --git a/cpp/core/internal/p2p_cluster_pcp_handler.h b/cpp/core/internal/p2p_cluster_pcp_handler.h index 4257d7ce..6fe0178b 100644 --- a/cpp/core/internal/p2p_cluster_pcp_handler.h +++ b/cpp/core/internal/p2p_cluster_pcp_handler.h @@ -108,8 +108,6 @@ class P2pClusterPcpHandler : public BasePcpHandler { BluetoothClassic::DiscoveredDeviceCallback; using BleDiscoveredPeripheralCallback = Ble::DiscoveredPeripheralCallback; using WifiLanDiscoveredServiceCallback = WifiLan::DiscoveredServiceCallback; - using WifiLanV2DiscoveredServiceCallback = - WifiLanV2::DiscoveredServiceCallback; static constexpr BluetoothDeviceName::Version kBluetoothDeviceNameVersion = BluetoothDeviceName::Version::kV1; @@ -173,11 +171,12 @@ class P2pClusterPcpHandler : public BasePcpHandler { // WifiLan bool IsRecognizedWifiLanEndpoint( const std::string& service_id, - const WifiLanServiceInfo& service_info) const; + const WifiLanServiceInfo& wifi_lan_service_info) const; void WifiLanServiceDiscoveredHandler(ClientProxy* client, - WifiLanService& service, + NsdServiceInfo service_info, const std::string& service_id); - void WifiLanServiceLostHandler(ClientProxy* client, WifiLanService& service, + void WifiLanServiceLostHandler(ClientProxy* client, + NsdServiceInfo service_info, const std::string& service_id); proto::connections::Medium StartWifiLanAdvertising( ClientProxy* client, const std::string& service_id, @@ -189,31 +188,10 @@ class P2pClusterPcpHandler : public BasePcpHandler { BasePcpHandler::ConnectImplResult WifiLanConnectImpl( ClientProxy* client, WifiLanEndpoint* endpoint); - // WifiLanV2 - bool IsRecognizedWifiLanV2Endpoint( - const std::string& service_id, - const WifiLanServiceInfo& wifi_lan_service_info) const; - void WifiLanV2ServiceDiscoveredHandler(ClientProxy* client, - NsdServiceInfo service_info, - const std::string& service_id); - void WifiLanV2ServiceLostHandler(ClientProxy* client, - NsdServiceInfo service_info, - const std::string& service_id); - proto::connections::Medium StartWifiLanV2Advertising( - ClientProxy* client, const std::string& service_id, - const std::string& local_endpoint_id, - const ByteArray& local_endpoint_info, WebRtcState web_rtc_state); - proto::connections::Medium StartWifiLanV2Discovery( - WifiLanV2DiscoveredServiceCallback callback, ClientProxy* client, - const std::string& service_id); - BasePcpHandler::ConnectImplResult WifiLanV2ConnectImpl( - ClientProxy* client, WifiLanV2Endpoint* endpoint); - BluetoothRadio& bluetooth_radio_; BluetoothClassic& bluetooth_medium_; Ble& ble_medium_; WifiLan& wifi_lan_medium_; - WifiLanV2& wifi_lan_medium_v2_; mediums::WebRtc& webrtc_medium_; InjectedBluetoothDeviceStore& injected_bluetooth_device_store_; std::int64_t bluetooth_classic_discoverer_client_id_{0}; diff --git a/cpp/core/internal/wifi_lan_bwu_handler.cc b/cpp/core/internal/wifi_lan_bwu_handler.cc index 04157cfb..9b8eeedb 100644 --- a/cpp/core/internal/wifi_lan_bwu_handler.cc +++ b/cpp/core/internal/wifi_lan_bwu_handler.cc @@ -46,30 +46,6 @@ ByteArray WifiLanBwuHandler::InitializeUpgradedMediumForEndpoint( // stop the advertising yet. std::string upgrade_service_id = Utils::WrapUpgradeServiceId(service_id); - if (!wifi_lan_medium_.IsAcceptingConnections(upgrade_service_id)) { - if (!wifi_lan_medium_.StartAcceptingConnections( - upgrade_service_id, - { - .accepted_cb = absl::bind_front( - &WifiLanBwuHandler::OnIncomingWifiLanConnection, this, - client), - })) { - NEARBY_LOG(ERROR, - "WifiLanBwuHandler couldn't initiate the WifiLan upgrade for " - "endpoint %s because it failed to start listening for " - "incoming WifiLan connections.", - endpoint_id.c_str()); - return {}; - } - NEARBY_LOGS(INFO) - << "WifiLanBwuHandler successfully started listening for incoming " - "WifiLan connections while upgrading endpoint " - << endpoint_id; - } - - // cache service ID to revert - active_service_ids_.emplace(upgrade_service_id); - auto credential = wifi_lan_medium_.GetCredentials(upgrade_service_id); auto ip_address = credential.first; auto port = credential.second; @@ -82,6 +58,31 @@ ByteArray WifiLanBwuHandler::InitializeUpgradedMediumForEndpoint( return {}; } + if (!wifi_lan_medium_.IsAcceptingConnections(upgrade_service_id)) { + if (!wifi_lan_medium_.StartAcceptingConnections( + upgrade_service_id, + { + .accepted_cb = absl::bind_front( + &WifiLanBwuHandler::OnIncomingWifiLanConnection, this, + client, service_id), + })) { + NEARBY_LOGS(ERROR) + << "WifiLanBwuHandler couldn't initiate the WifiLan upgrade for " + "endpoint " + << endpoint_id + << " because it failed to start listening for " + "incoming WifiLan connections."; + return {}; + } + NEARBY_LOGS(INFO) + << "WifiLanBwuHandler successfully started listening for incoming " + "WifiLan connections while upgrading endpoint " + << endpoint_id; + } + + // cache service ID to revert + active_service_ids_.insert(upgrade_service_id); + return parser::ForBwuWifiLanPathAvailable(ip_address, port); } @@ -103,34 +104,45 @@ WifiLanBwuHandler::CreateUpgradedEndpointChannel( if (!upgrade_path_info.has_wifi_lan_socket()) { return nullptr; } - const UpgradePathInfo::WifiLanSocket& wifi_lan_socket = + const UpgradePathInfo::WifiLanSocket& upgrade_path_info_socket = upgrade_path_info.wifi_lan_socket(); - if (!wifi_lan_socket.has_ip_address() || !wifi_lan_socket.has_wifi_port()) { + if (!upgrade_path_info_socket.has_ip_address() || + !upgrade_path_info_socket.has_wifi_port()) { + NEARBY_LOG(ERROR, "WifiLanBwuHandler failed to parse UpgradePathInfo."); return nullptr; } - const std::string& ip_address = wifi_lan_socket.ip_address(); - std::int32_t port = wifi_lan_socket.wifi_port(); + const std::string& ip_address = upgrade_path_info_socket.ip_address(); + std::int32_t port = upgrade_path_info_socket.wifi_port(); + + NEARBY_LOGS(VERBOSE) << "WifiLanBwuHandler is attempting to connect to " + "available WifiLan service (" + << ip_address << ":" << port << ") for endpoint " + << endpoint_id; - WifiLanService wifi_lan_service = - wifi_lan_medium_.GetRemoteWifiLanService(ip_address, port); - if (!wifi_lan_service.IsValid()) { - return nullptr; - } WifiLanSocket socket = wifi_lan_medium_.Connect( - wifi_lan_service, service_id, client->GetCancellationFlag(endpoint_id)); + service_id, ip_address, port, client->GetCancellationFlag(endpoint_id)); if (!socket.IsValid()) { + NEARBY_LOGS(ERROR) + << "WifiLanBwuHandler failed to connect to the WifiLan service (" + << ip_address << ":" << port << ") for endpoint " << endpoint_id; return nullptr; } + NEARBY_LOGS(VERBOSE) + << "WifiLanBwuHandler successfully connected to WifiLan service (" + << ip_address << ":" << port << ") while upgrading endpoint " + << endpoint_id; + // Create a new WifiLanEndpointChannel. - auto channel = std::make_unique(service_id, socket); + auto channel = absl::make_unique(service_id, socket); if (channel == nullptr) { + NEARBY_LOGS(ERROR) << "WifiLanBwuHandler failed to create WifiLan endpoint " + "channel to the WifiLan service (" + << ip_address << ":" << port << ") for endpoint " + << endpoint_id; socket.Close(); - NEARBY_LOG(ERROR, - "WifiLanBwuHandler failed to create new EndpointChannel for " - "outgoing socket %p, aborting upgrade.", - &socket.GetImpl()); + return nullptr; } return channel; @@ -138,16 +150,14 @@ WifiLanBwuHandler::CreateUpgradedEndpointChannel( // Accept Connection Callback. void WifiLanBwuHandler::OnIncomingWifiLanConnection( - ClientProxy* client, WifiLanSocket socket, - const std::string& upgrade_service_id) { - std::string service_id = Utils::UnwrapUpgradeServiceId(upgrade_service_id); - auto channel = std::make_unique(service_id, socket); - auto wifi_lan_socket = - std::make_unique(service_id, socket); + ClientProxy* client, const std::string& service_id, WifiLanSocket socket) { + auto channel = absl::make_unique(service_id, socket); std::unique_ptr connection( - new IncomingSocketConnection{std::move(wifi_lan_socket), - std::move(channel)}); - + new IncomingSocketConnection{ + .socket = + absl::make_unique(service_id, socket), + .channel = std::move(channel), + }); bwu_notifications_.incoming_connection_cb(client, std::move(connection)); } diff --git a/cpp/core/internal/wifi_lan_bwu_handler.h b/cpp/core/internal/wifi_lan_bwu_handler.h index 17f71463..c16fbe74 100644 --- a/cpp/core/internal/wifi_lan_bwu_handler.h +++ b/cpp/core/internal/wifi_lan_bwu_handler.h @@ -49,8 +49,9 @@ class WifiLanBwuHandler : public BaseBwuHandler { void OnEndpointDisconnect(ClientProxy* client, const std::string& endpoint_id) override {} - void OnIncomingWifiLanConnection(ClientProxy* client, WifiLanSocket socket, - const std::string& upgrade_service_id); + void OnIncomingWifiLanConnection(ClientProxy* client, + const std::string& service_id, + WifiLanSocket socket); class WifiLanIncomingSocket : public BwuHandler::IncomingSocket { public: diff --git a/cpp/core/internal/wifi_lan_bwu_handler_v2.cc b/cpp/core/internal/wifi_lan_bwu_handler_v2.cc deleted file mode 100644 index 2ed36bc5..00000000 --- a/cpp/core/internal/wifi_lan_bwu_handler_v2.cc +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "core/internal/wifi_lan_bwu_handler_v2.h" - -#include -#include - -#include "absl/functional/bind_front.h" -#include "core/internal/client_proxy.h" -#include "core/internal/mediums/utils.h" -#include "core/internal/offline_frames.h" -#include "core/internal/wifi_lan_endpoint_channel_v2.h" -#include "platform/public/wifi_lan_v2.h" - -namespace location { -namespace nearby { -namespace connections { - -WifiLanV2BwuHandler::WifiLanV2BwuHandler( - Mediums& mediums, EndpointChannelManager& channel_manager, - BwuNotifications notifications) - : BaseBwuHandler(channel_manager, std::move(notifications)), - mediums_(mediums) {} - -// Called by BWU initiator. Set up WifiLan upgraded medium for this endpoint, -// and returns a upgrade path info (ip address, port) for remote party to -// perform discovery. -ByteArray WifiLanV2BwuHandler::InitializeUpgradedMediumForEndpoint( - ClientProxy* client, const std::string& service_id, - const std::string& endpoint_id) { - // Use wrapped service ID to avoid have the same ID with the one for - // startAdvertising. Otherwise, the listening request would be ignored because - // the medium already start accepting the connection because the client not - // stop the advertising yet. - std::string upgrade_service_id = Utils::WrapUpgradeServiceId(service_id); - - auto credential = wifi_lan_medium_.GetCredentials(upgrade_service_id); - auto ip_address = credential.first; - auto port = credential.second; - if (ip_address.empty()) { - NEARBY_LOGS(INFO) - << "WifiLanBwuHandler couldn't initiate the wifi_lan upgrade for " - "endpoint " - << endpoint_id - << " because the wifi_lan ip address were unable to be obtained."; - return {}; - } - - if (!wifi_lan_medium_.IsAcceptingConnections(upgrade_service_id)) { - if (!wifi_lan_medium_.StartAcceptingConnections( - upgrade_service_id, - { - .accepted_cb = absl::bind_front( - &WifiLanV2BwuHandler::OnIncomingWifiLanConnection, this, - client, service_id), - })) { - NEARBY_LOGS(ERROR) - << "WifiLanBwuHandler couldn't initiate the WifiLan upgrade for " - "endpoint " - << endpoint_id - << " because it failed to start listening for " - "incoming WifiLan connections."; - return {}; - } - NEARBY_LOGS(INFO) - << "WifiLanBwuHandler successfully started listening for incoming " - "WifiLan connections while upgrading endpoint " - << endpoint_id; - } - - // cache service ID to revert - active_service_ids_.insert(upgrade_service_id); - - return parser::ForBwuWifiLanPathAvailable(ip_address, port); -} - -void WifiLanV2BwuHandler::Revert() { - for (const std::string& service_id : active_service_ids_) { - wifi_lan_medium_.StopAcceptingConnections(service_id); - } - active_service_ids_.clear(); - - NEARBY_LOG(INFO, "WifiLanBwuHandler successfully reverted all states."); -} - -// Called by BWU target. Retrieves a new medium info from incoming message, -// and establishes connection over WifiLan using this info. -std::unique_ptr -WifiLanV2BwuHandler::CreateUpgradedEndpointChannel( - ClientProxy* client, const std::string& service_id, - const std::string& endpoint_id, const UpgradePathInfo& upgrade_path_info) { - if (!upgrade_path_info.has_wifi_lan_socket()) { - return nullptr; - } - const UpgradePathInfo::WifiLanSocket& upgrade_path_info_socket = - upgrade_path_info.wifi_lan_socket(); - if (!upgrade_path_info_socket.has_ip_address() || - !upgrade_path_info_socket.has_wifi_port()) { - NEARBY_LOG(ERROR, "WifiLanBwuHandler failed to parse UpgradePathInfo."); - return nullptr; - } - - const std::string& ip_address = upgrade_path_info_socket.ip_address(); - std::int32_t port = upgrade_path_info_socket.wifi_port(); - - NEARBY_LOGS(VERBOSE) << "WifiLanBwuHandler is attempting to connect to " - "available WifiLan service (" - << ip_address << ":" << port << ") for endpoint " - << endpoint_id; - - WifiLanSocketV2 socket = wifi_lan_medium_.Connect( - service_id, ip_address, port, client->GetCancellationFlag(endpoint_id)); - if (!socket.IsValid()) { - NEARBY_LOGS(ERROR) - << "WifiLanBwuHandler failed to connect to the WifiLan service (" - << ip_address << ":" << port << ") for endpoint " << endpoint_id; - return nullptr; - } - - NEARBY_LOGS(VERBOSE) - << "WifiLanBwuHandler successfully connected to WifiLan service (" - << ip_address << ":" << port << ") while upgrading endpoint " - << endpoint_id; - - // Create a new WifiLanEndpointChannel. - auto channel = - absl::make_unique(service_id, socket); - if (channel == nullptr) { - NEARBY_LOGS(ERROR) << "WifiLanBwuHandler failed to create WifiLan endpoint " - "channel to the WifiLan service (" - << ip_address << ":" << port << ") for endpoint " - << endpoint_id; - socket.Close(); - return nullptr; - } - - return channel; -} - -// Accept Connection Callback. -void WifiLanV2BwuHandler::OnIncomingWifiLanConnection( - ClientProxy* client, const std::string& service_id, - WifiLanSocketV2 socket) { - auto channel = - absl::make_unique(service_id, socket); - std::unique_ptr connection( - new IncomingSocketConnection{ - .socket = - absl::make_unique(service_id, socket), - .channel = std::move(channel), - }); - bwu_notifications_.incoming_connection_cb(client, std::move(connection)); -} - -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/cpp/core/internal/wifi_lan_bwu_handler_v2.h b/cpp/core/internal/wifi_lan_bwu_handler_v2.h deleted file mode 100644 index 5474eaac..00000000 --- a/cpp/core/internal/wifi_lan_bwu_handler_v2.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef CORE_INTERNAL_WIFI_LAN_BWU_HANDLER_H_ -#define CORE_INTERNAL_WIFI_LAN_BWU_HANDLER_H_ - -#include "core/internal/base_bwu_handler.h" -#include "core/internal/client_proxy.h" -#include "core/internal/endpoint_channel_manager.h" -#include "core/internal/mediums/mediums.h" - -namespace location { -namespace nearby { -namespace connections { - -// Defines the set of methods that need to be implemented to handle the -// per-Medium-specific operations needed to upgrade an EndpointChannel. -class WifiLanV2BwuHandler : public BaseBwuHandler { - public: - WifiLanV2BwuHandler(Mediums& mediums, EndpointChannelManager& channel_manager, - BwuNotifications notifications); - ~WifiLanV2BwuHandler() override = default; - - private: - ByteArray InitializeUpgradedMediumForEndpoint( - ClientProxy* client, const std::string& service_id, - const std::string& endpoint_id) override; - - void Revert() override; - - std::unique_ptr CreateUpgradedEndpointChannel( - ClientProxy* client, const std::string& service_id, - const std::string& endpoint_id, - const UpgradePathInfo& upgrade_path_info) override; - - Medium GetUpgradeMedium() const override { return Medium::MDNS; } - - void OnEndpointDisconnect(ClientProxy* client, - const std::string& endpoint_id) override {} - - void OnIncomingWifiLanConnection(ClientProxy* client, - const std::string& service_id, - WifiLanSocketV2 socket); - - class WifiLanV2IncomingSocket : public BwuHandler::IncomingSocket { - public: - explicit WifiLanV2IncomingSocket(const std::string& name, - WifiLanSocketV2 socket) - : name_(name), socket_(socket) {} - ~WifiLanV2IncomingSocket() override = default; - - std::string ToString() override { return name_; } - void Close() override { socket_.Close(); } - - private: - std::string name_; - WifiLanSocketV2 socket_; - }; - - Mediums& mediums_; - WifiLanV2& wifi_lan_medium_{mediums_.GetWifiLanV2()}; - absl::flat_hash_set active_service_ids_; -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_WIFI_LAN_BWU_HANDLER_H_ diff --git a/cpp/core/internal/wifi_lan_endpoint_channel.cc b/cpp/core/internal/wifi_lan_endpoint_channel.cc index ef8be69b..ec7503ef 100644 --- a/cpp/core/internal/wifi_lan_endpoint_channel.cc +++ b/cpp/core/internal/wifi_lan_endpoint_channel.cc @@ -23,34 +23,18 @@ namespace location { namespace nearby { namespace connections { -namespace { - -OutputStream* GetOutputStreamOrNull(WifiLanSocket& socket) { - if (socket.GetRemoteWifiLanService().IsValid()) - return &socket.GetOutputStream(); - return nullptr; -} - -InputStream* GetInputStreamOrNull(WifiLanSocket& socket) { - if (socket.GetRemoteWifiLanService().IsValid()) - return &socket.GetInputStream(); - return nullptr; -} - -} // namespace - WifiLanEndpointChannel::WifiLanEndpointChannel(const std::string& channel_name, WifiLanSocket socket) - : BaseEndpointChannel(channel_name, GetInputStreamOrNull(socket), - GetOutputStreamOrNull(socket)), - wifi_lan_socket_(std::move(socket)) {} + : BaseEndpointChannel(channel_name, &socket.GetInputStream(), + &socket.GetOutputStream()), + socket_(std::move(socket)) {} proto::connections::Medium WifiLanEndpointChannel::GetMedium() const { return proto::connections::Medium::WIFI_LAN; } void WifiLanEndpointChannel::CloseImpl() { - auto status = wifi_lan_socket_.Close(); + auto status = socket_.Close(); if (!status.Ok()) { NEARBY_LOGS(INFO) << "Failed to close underlying socket for WifiLanEndpointChannel " diff --git a/cpp/core/internal/wifi_lan_endpoint_channel.h b/cpp/core/internal/wifi_lan_endpoint_channel.h index 673b3b00..e7c79f9c 100644 --- a/cpp/core/internal/wifi_lan_endpoint_channel.h +++ b/cpp/core/internal/wifi_lan_endpoint_channel.h @@ -32,7 +32,7 @@ class WifiLanEndpointChannel final : public BaseEndpointChannel { private: void CloseImpl() override; - WifiLanSocket wifi_lan_socket_; + WifiLanSocket socket_; }; } // namespace connections diff --git a/cpp/core/internal/wifi_lan_endpoint_channel_v2.cc b/cpp/core/internal/wifi_lan_endpoint_channel_v2.cc deleted file mode 100644 index 837d3233..00000000 --- a/cpp/core/internal/wifi_lan_endpoint_channel_v2.cc +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "core/internal/wifi_lan_endpoint_channel_v2.h" - -#include - -#include "platform/public/logging.h" -#include "platform/public/wifi_lan_v2.h" - -namespace location { -namespace nearby { -namespace connections { - -WifiLanEndpointChannelV2::WifiLanEndpointChannelV2( - const std::string& channel_name, WifiLanSocketV2 socket) - : BaseEndpointChannel(channel_name, &socket.GetInputStream(), - &socket.GetOutputStream()), - socket_(std::move(socket)) {} - -proto::connections::Medium WifiLanEndpointChannelV2::GetMedium() const { - return proto::connections::Medium::WIFI_LAN; -} - -void WifiLanEndpointChannelV2::CloseImpl() { - auto status = socket_.Close(); - if (!status.Ok()) { - NEARBY_LOGS(INFO) - << "Failed to close underlying socket for WifiLanEndpointChannel " - << GetName() << " : exception = " << status.value; - } -} - -} // namespace connections -} // namespace nearby -} // namespace location diff --git a/cpp/core/internal/wifi_lan_endpoint_channel_v2.h b/cpp/core/internal/wifi_lan_endpoint_channel_v2.h deleted file mode 100644 index cd389e04..00000000 --- a/cpp/core/internal/wifi_lan_endpoint_channel_v2.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef CORE_INTERNAL_WIFI_LAN_ENDPOINT_CHANNEL_V2_H_ -#define CORE_INTERNAL_WIFI_LAN_ENDPOINT_CHANNEL_V2_H_ - -#include "core/internal/base_endpoint_channel.h" -#include "platform/public/wifi_lan_v2.h" - -namespace location { -namespace nearby { -namespace connections { - -class WifiLanEndpointChannelV2 final : public BaseEndpointChannel { - public: - // Creates both outgoing and incoming WifiLan channels. - WifiLanEndpointChannelV2(const std::string& channel_name, - WifiLanSocketV2 socket); - - proto::connections::Medium GetMedium() const override; - - private: - void CloseImpl() override; - - WifiLanSocketV2 socket_; -}; - -} // namespace connections -} // namespace nearby -} // namespace location - -#endif // CORE_INTERNAL_WIFI_LAN_ENDPOINT_CHANNEL_V2_H_ diff --git a/cpp/core/options.h b/cpp/core/options.h index 908ce1ed..ff1ca03b 100644 --- a/cpp/core/options.h +++ b/cpp/core/options.h @@ -32,19 +32,18 @@ struct MediumSelector { T ble; T web_rtc; T wifi_lan; - T wifi_lan_v2; constexpr MediumSelector() = default; constexpr MediumSelector(const MediumSelector&) = default; constexpr MediumSelector& operator=(const MediumSelector&) = default; constexpr bool Any(T value) const { return bluetooth == value || ble == value || web_rtc == value || - wifi_lan == value || wifi_lan_v2; + wifi_lan == value; } constexpr bool All(T value) const { return bluetooth == value && ble == value && web_rtc == value && - wifi_lan == value && wifi_lan_v2 == value; + wifi_lan == value; } constexpr int Count(T value) const { @@ -52,7 +51,6 @@ struct MediumSelector { if (bluetooth == value) count++; if (ble == value) count++; if (wifi_lan == value) count++; - if (wifi_lan_v2 == value) count++; if (web_rtc == value) count++; return count; } @@ -62,14 +60,12 @@ struct MediumSelector { ble = value; web_rtc = value; wifi_lan = value; - wifi_lan_v2 = value; return *this; } std::vector GetMediums(T value) const { std::vector mediums; // Mediums are sorted in order of decreasing preference. - if (wifi_lan_v2 == value) mediums.push_back(Medium::MDNS); if (wifi_lan == value) mediums.push_back(Medium::WIFI_LAN); if (web_rtc == value) mediums.push_back(Medium::WEB_RTC); if (bluetooth == value) mediums.push_back(Medium::BLUETOOTH); @@ -127,7 +123,6 @@ struct DLL_API ConnectionOptions { uint32_t* mediumsSize); }; - // Metadata injected to facilitate out-of-band connections. The medium field is // required, and the other fields are only specified for a specific medium. // Currently, Bluetooth is the only supported medium for out-of-band diff --git a/cpp/platform/api/BUILD b/cpp/platform/api/BUILD index 94d80a7f..61cf51cf 100644 --- a/cpp/platform/api/BUILD +++ b/cpp/platform/api/BUILD @@ -61,7 +61,6 @@ cc_library( "webrtc.h", "wifi.h", "wifi_lan.h", - "wifi_lan_v2.h", ], compatible_with = ["//buildenv/target:non_prod"], visibility = [ diff --git a/cpp/platform/api/platform.h b/cpp/platform/api/platform.h index 5224d0d4..6cf54cae 100644 --- a/cpp/platform/api/platform.h +++ b/cpp/platform/api/platform.h @@ -41,7 +41,6 @@ #include "platform/api/webrtc.h" #include "platform/api/wifi.h" #include "platform/api/wifi_lan.h" -#include "platform/api/wifi_lan_v2.h" #include "platform/base/payload_id.h" namespace location { @@ -102,7 +101,6 @@ class ImplementationPlatform { static std::unique_ptr CreateServerSyncMedium(); static std::unique_ptr CreateWifiMedium(); static std::unique_ptr CreateWifiLanMedium(); - static std::unique_ptr CreateWifiLanMediumV2(); static std::unique_ptr CreateWebRtcMedium(); }; diff --git a/cpp/platform/api/wifi_lan.h b/cpp/platform/api/wifi_lan.h index e7a09f62..9ba40a38 100644 --- a/cpp/platform/api/wifi_lan.h +++ b/cpp/platform/api/wifi_lan.h @@ -17,8 +17,6 @@ #include -#include "absl/strings/string_view.h" -#include "platform/base/byte_array.h" #include "platform/base/cancellation_flag.h" #include "platform/base/input_stream.h" #include "platform/base/listeners.h" @@ -29,19 +27,6 @@ namespace location { namespace nearby { namespace api { -// Opaque wrapper over a WifiLan service which contains |NsdServiceInfo|. -class WifiLanService { - public: - virtual ~WifiLanService() = default; - - // Returns the |NsdServiceInfo| which contains the packed string of - // |WifiLanServiceInfo| and the endpoint info with named key in a TXTRecord - // map. - // The details refer to - // https://developer.android.com/reference/android/net/nsd/NsdServiceInfo.html. - virtual NsdServiceInfo GetServiceInfo() const = 0; -}; - class WifiLanSocket { public: virtual ~WifiLanSocket() = default; @@ -62,10 +47,28 @@ class WifiLanSocket { // Returns Exception::kIo on error, Exception::kSuccess otherwise. virtual Exception Close() = 0; +}; - // Returns valid WifiLanService pointer if there is a connection, and - // nullptr otherwise. - virtual WifiLanService* GetRemoteWifiLanService() = 0; +class WifiLanServerSocket { + public: + virtual ~WifiLanServerSocket() = default; + + // Returns ip address. + virtual std::string GetIPAddress() const = 0; + + // Returns port. + virtual int GetPort() const = 0; + + // Blocks until either: + // - at least one incoming connection request is available, or + // - ServerSocket is closed. + // On success, returns connected socket, ready to exchange data. + // Returns nullptr on error. + // Once error is reported, it is permanent, and ServerSocket has to be closed. + virtual std::unique_ptr Accept() = 0; + + // Returns Exception::kIo on error, Exception::kSuccess otherwise. + virtual Exception Close() = 0; }; // Container of operations that can be performed over the WifiLan medium. @@ -73,59 +76,74 @@ class WifiLanMedium { public: virtual ~WifiLanMedium() = default; - virtual bool StartAdvertising(const std::string& service_id, - const NsdServiceInfo& nsd_service_info) = 0; - virtual bool StopAdvertising(const std::string& service_id) = 0; + // Starts WifiLan advertising. + // + // nsd_service_info - NsdServiceInfo data that's advertised through mDNS + // service. + // On success if the service is now advertising. + // On error if the service cannot start to advertise or the service type in + // NsdServiceInfo has been passed previously which StopAdvertising is not + // been called. + virtual bool StartAdvertising(const NsdServiceInfo& nsd_service_info) = 0; + + // Stops WifiLan advertising. + // + // nsd_service_info - NsdServiceInfo data that's advertised through mDNS + // service. + // On success if the service stops advertising. + // On error if the service cannot stop advertising or the service type in + // NsdServiceInfo cannot be found. + virtual bool StopAdvertising(const NsdServiceInfo& nsd_service_info) = 0; // Callback that is invoked when a discovered service is found or lost. struct DiscoveredServiceCallback { - std::function - service_discovered_cb = - DefaultCallback(); - std::function - service_lost_cb = - DefaultCallback(); + std::function service_discovered_cb = + DefaultCallback(); + std::function service_lost_cb = + DefaultCallback(); }; - // Returns true once the WifiLan discovery has been initiated. - virtual bool StartDiscovery(const std::string& service_id, + // Starts the discovery of nearby WifiLan services. + // + // service_type - mDNS service type. + // callback - the instance of DiscoveredServiceCallback. + // Returns true once the WifiLan discovery has been initiated. The + // service_type is associated with callback. + virtual bool StartDiscovery(const std::string& service_type, DiscoveredServiceCallback callback) = 0; - // Returns true once WifiLan discovery for service_id is well and truly - // stopped; after this returns, there must be no more invocations of the - // DiscoveredServiceCallback passed in to StartDiscovery() for service_id. - virtual bool StopDiscovery(const std::string& service_id) = 0; - - // Callback that is invoked when a new connection is accepted. - struct AcceptedConnectionCallback { - std::function - accepted_cb = DefaultCallback(); - }; - - // Returns true once WifiLan socket connection requests to service_id can be - // accepted. - virtual bool StartAcceptingConnections( - const std::string& service_id, AcceptedConnectionCallback callback) = 0; - virtual bool StopAcceptingConnections(const std::string& service_id) = 0; + // Stops the discovery of nearby WifiLan services. + // + // service_type - The one assigned in StartDiscovery. + // On success if the service_type is matched to the callback and will be + // removed from the list. If list is empty then stops the WifiLan + // discovery service. + // On error if the service_type is not existed, then return immediately. + virtual bool StopDiscovery(const std::string& service_type) = 0; // Connects to a WifiLan service. // On success, returns a new WifiLanSocket. // On error, returns nullptr. - virtual std::unique_ptr Connect( - WifiLanService& wifi_lan_service, const std::string& service_id, + virtual std::unique_ptr ConnectToService( + const NsdServiceInfo& remote_service_info, CancellationFlag* cancellation_flag) = 0; - virtual WifiLanService* GetRemoteService(const std::string& ip_address, - int port) = 0; + // Connects to a WifiLan service by ip address and port. + // On success, returns a new WifiLanSocket. + // On error, returns nullptr. + virtual std::unique_ptr ConnectToService( + const std::string& ip_address, int port, + CancellationFlag* cancellation_flag) = 0; - // Gets ip address + port for remote services on the network to identify and - // connect to this service. + // Listens for incoming connection. // - // Credential is for the currently-hosted Wifi ServerSocket (if any). - virtual std::pair GetCredentials( - const std::string& service_id) = 0; + // port - A port number. + // 0 : use a random port. + // 1~65536 : open a server socket on that exact port. + // On success, returns a new WifiLanServerSocket. + // On error, returns nullptr. + virtual std::unique_ptr ListenForService( + int port = 0) = 0; }; } // namespace api diff --git a/cpp/platform/api/wifi_lan_v2.h b/cpp/platform/api/wifi_lan_v2.h deleted file mode 100644 index 271c05f4..00000000 --- a/cpp/platform/api/wifi_lan_v2.h +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef PLATFORM_API_WIFI_LAN__V2_H_ -#define PLATFORM_API_WIFI_LAN__V2_H_ - -#include - -#include "platform/base/cancellation_flag.h" -#include "platform/base/input_stream.h" -#include "platform/base/listeners.h" -#include "platform/base/nsd_service_info.h" -#include "platform/base/output_stream.h" - -namespace location { -namespace nearby { -namespace api { - -class WifiLanSocketV2 { - public: - virtual ~WifiLanSocketV2() = default; - - // Returns the InputStream of the WifiLanSocket. - // On error, returned stream will report Exception::kIo on any operation. - // - // The returned object is not owned by the caller, and can be invalidated once - // the WifiLanSocket object is destroyed. - virtual InputStream& GetInputStream() = 0; - - // Returns the OutputStream of the WifiLanSocket. - // On error, returned stream will report Exception::kIo on any operation. - // - // The returned object is not owned by the caller, and can be invalidated once - // the WifiLanSocket object is destroyed. - virtual OutputStream& GetOutputStream() = 0; - - // Returns Exception::kIo on error, Exception::kSuccess otherwise. - virtual Exception Close() = 0; -}; - -class WifiLanServerSocketV2 { - public: - virtual ~WifiLanServerSocketV2() = default; - - // Returns ip address. - virtual std::string GetIPAddress() const = 0; - - // Returns port. - virtual int GetPort() const = 0; - - // Blocks until either: - // - at least one incoming connection request is available, or - // - ServerSocket is closed. - // On success, returns connected socket, ready to exchange data. - // Returns nullptr on error. - // Once error is reported, it is permanent, and ServerSocket has to be closed. - virtual std::unique_ptr Accept() = 0; - - // Returns Exception::kIo on error, Exception::kSuccess otherwise. - virtual Exception Close() = 0; -}; - -// Container of operations that can be performed over the WifiLan medium. -class WifiLanMediumV2 { - public: - virtual ~WifiLanMediumV2() = default; - - // Starts WifiLan advertising. - // - // nsd_service_info - NsdServiceInfo data that's advertised through mDNS - // service. - // On success if the service is now advertising. - // On error if the service cannot start to advertise or the service type in - // NsdServiceInfo has been passed previously which StopAdvertising is not - // been called. - virtual bool StartAdvertising(const NsdServiceInfo& nsd_service_info) = 0; - - // Stops WifiLan advertising. - // - // nsd_service_info - NsdServiceInfo data that's advertised through mDNS - // service. - // On success if the service stops advertising. - // On error if the service cannot stop advertising or the service type in - // NsdServiceInfo cannot be found. - virtual bool StopAdvertising(const NsdServiceInfo& nsd_service_info) = 0; - - // Callback that is invoked when a discovered service is found or lost. - struct DiscoveredServiceCallback { - std::function service_discovered_cb = - DefaultCallback(); - std::function service_lost_cb = - DefaultCallback(); - }; - - // Starts the discovery of nearby WifiLan services. - // - // service_type - mDNS service type. - // callback - the instance of DiscoveredServiceCallback. - // Returns true once the WifiLan discovery has been initiated. The - // service_type is associated with callback. - virtual bool StartDiscovery(const std::string& service_type, - DiscoveredServiceCallback callback) = 0; - - // Stops the discovery of nearby WifiLan services. - // - // service_type - The one assigned in StartDiscovery. - // On success if the service_type is matched to the callback and will be - // removed from the list. If list is empty then stops the WifiLan - // discovery service. - // On error if the service_type is not existed, then return immediately. - virtual bool StopDiscovery(const std::string& service_type) = 0; - - // Connects to a WifiLan service. - // On success, returns a new WifiLanSocket. - // On error, returns nullptr. - virtual std::unique_ptr ConnectToService( - const NsdServiceInfo& remote_service_info, - CancellationFlag* cancellation_flag) = 0; - - // Connects to a WifiLan service by ip address and port. - // On success, returns a new WifiLanSocket. - // On error, returns nullptr. - virtual std::unique_ptr ConnectToService( - const std::string& ip_address, int port, - CancellationFlag* cancellation_flag) = 0; - - // Listens for incoming connection. - // - // port - A port number. - // 0 : use a random port. - // 1~65536 : open a server socket on that exact port. - // On success, returns a new WifiLanServerSocket. - // On error, returns nullptr. - virtual std::unique_ptr ListenForService( - int port = 0) = 0; -}; - -} // namespace api -} // namespace nearby -} // namespace location - -#endif // PLATFORM_API_WIFI_LAN__V2_H_ diff --git a/cpp/platform/base/medium_environment.cc b/cpp/platform/base/medium_environment.cc index c70bce0f..b0f527ad 100644 --- a/cpp/platform/base/medium_environment.cc +++ b/cpp/platform/base/medium_environment.cc @@ -62,7 +62,6 @@ void MediumEnvironment::Reset() { webrtc_signaling_message_callback_.clear(); webrtc_signaling_complete_callback_.clear(); wifi_lan_mediums_.clear(); - wifi_lan_mediums_v2_.clear(); use_valid_peer_connection_ = true; peer_connection_latency_ = absl::ZeroDuration(); }); @@ -228,35 +227,7 @@ void MediumEnvironment::OnBlePeripheralStateChanged( } void MediumEnvironment::OnWifiLanServiceStateChanged( - WifiLanMediumContext& info, api::WifiLanService& wifi_lan_service, - const std::string& service_id, bool enabled) { - if (!enabled_) return; - NEARBY_LOGS(INFO) << "G3 OnWifiLanServiceStateChanged [wifi_lan_service impl=" - << &wifi_lan_service << "]; context=" << &info - << "; service_id=" << service_id - << "; notify=" << enable_notifications_.load(); - if (!enable_notifications_) return; - RunOnMediumEnvironmentThread( - [&info, enabled, &wifi_lan_service, service_id]() { - NEARBY_LOGS(INFO) - << "G3 [Run] OnWifiLanServiceStateChanged [wifi_lan_service impl=" - << &wifi_lan_service << "]; context=" << &info - << "; service_id=" << service_id << "; enabled=" << enabled; - auto service_id_context = info.services.find(service_id); - if (service_id_context == info.services.end()) return; - - if (enabled) { - service_id_context->second.discovery_callback.service_discovered_cb( - wifi_lan_service, service_id); - } else { - service_id_context->second.discovery_callback.service_lost_cb( - wifi_lan_service, service_id); - } - }); -} - -void MediumEnvironment::OnWifiLanServiceV2StateChanged( - WifiLanMediumV2Context& info, const NsdServiceInfo& service_info, + WifiLanMediumContext& info, const NsdServiceInfo& service_info, bool enabled) { if (!enabled_) return; std::string service_type = service_info.GetServiceType(); @@ -583,101 +554,6 @@ absl::Duration MediumEnvironment::GetPeerConnectionLatency() { return peer_connection_latency_; } -void MediumEnvironment::RegisterWifiLanMedium(api::WifiLanMedium& medium) { - if (!enabled_) return; - RunOnMediumEnvironmentThread([this, &medium]() { - wifi_lan_mediums_.insert({&medium, WifiLanMediumContext{}}); - NEARBY_LOGS(INFO) << "Registered: medium=" << &medium; - }); -} - -void MediumEnvironment::UpdateWifiLanMediumForAdvertising( - api::WifiLanMedium& medium, api::WifiLanService& wifi_lan_service, - const std::string& service_id, bool enabled) { - if (!enabled_) return; - RunOnMediumEnvironmentThread( - [this, &medium, &wifi_lan_service, service_id, enabled]() { - auto item = wifi_lan_mediums_.find(&medium); - if (item == wifi_lan_mediums_.end()) { - NEARBY_LOGS(INFO) - << "UpdateWifiLanMediumForAdvertising failed. There is no medium " - "registered."; - return; - } - auto& context = item->second; - context.wifi_lan_service = &wifi_lan_service; - auto service_id_context = context.services.find(service_id); - if (service_id_context == context.services.end()) { - WifiLanServiceIdContext id_context{ - .advertising = enabled, - }; - context.services.emplace(service_id, std::move(id_context)); - } else { - service_id_context->second.advertising = enabled; - } - NEARBY_LOGS(INFO) << "Update WifiLan medium for advertising: this=" - << this << "; medium=" << &medium - << "; service_id=" << service_id - << "; wifi_lan_service=" << &wifi_lan_service - << ", service_info_name=" - << wifi_lan_service.GetServiceInfo().GetServiceName() - << "; enabled=" << enabled; - for (auto& medium_info : wifi_lan_mediums_) { - auto& local_medium = medium_info.first; - auto& info = medium_info.second; - // Do not send notification to the same medium. - if (local_medium == &medium) continue; - OnWifiLanServiceStateChanged(info, wifi_lan_service, service_id, - enabled); - } - }); -} - -void MediumEnvironment::UpdateWifiLanMediumForDiscovery( - api::WifiLanMedium& medium, const std::string& service_id, - WifiLanDiscoveredServiceCallback callback, bool enabled) { - if (!enabled_) return; - RunOnMediumEnvironmentThread( - [this, &medium, service_id, callback = std::move(callback), enabled]() { - auto item = wifi_lan_mediums_.find(&medium); - if (item == wifi_lan_mediums_.end()) { - NEARBY_LOGS(INFO) - << "UpdateWifiLanMediumForDiscovery failed. There is no medium " - "registered."; - return; - } - auto& context = item->second; - auto service_id_context = context.services.find(service_id); - if (service_id_context == context.services.end()) { - WifiLanServiceIdContext id_context{ - .discovery_callback = std::move(callback), - }; - context.services.emplace(service_id, std::move(id_context)); - } else { - service_id_context->second.discovery_callback = std::move(callback); - } - NEARBY_LOGS(INFO) << "Update WifiLan medium for discovery: this=" - << this << "; medium=" << &medium - << "; service_id=" << service_id - << "; enabled=" << enabled; - for (auto& medium_info : wifi_lan_mediums_) { - auto& local_medium = medium_info.first; - auto& info = medium_info.second; - // Do not send notification to the same medium. - if (local_medium == &medium) continue; - // Search advertising mediums and send notification. - for (auto& service_id_context : info.services) { - auto& service_id = service_id_context.first; - auto& id_context = service_id_context.second; - if (id_context.advertising && enabled) { - OnWifiLanServiceStateChanged(context, *(info.wifi_lan_service), - service_id, enabled); - } - } - } - }); -} - std::string MediumEnvironment::GetFakeIPAddress() const { std::string ip_address; ip_address.resize(4); @@ -696,99 +572,16 @@ int MediumEnvironment::GetFakePort() const { return port; } -void MediumEnvironment::UpdateWifiLanMediumForAcceptedConnection( - api::WifiLanMedium& medium, const std::string& service_id, - WifiLanAcceptedConnectionCallback callback) { - if (!enabled_) return; - RunOnMediumEnvironmentThread( - [this, &medium, service_id, callback = std::move(callback)]() { - auto item = wifi_lan_mediums_.find(&medium); - if (item == wifi_lan_mediums_.end()) { - NEARBY_LOGS(INFO) - << "Update WifiLan medium failed. There is no medium registered."; - return; - } - auto& context = item->second; - auto service_id_context = context.services.find(service_id); - if (service_id_context == context.services.end()) { - WifiLanServiceIdContext id_context{ - .accepted_connection_callback = std::move(callback), - }; - context.services.emplace(service_id, std::move(id_context)); - } else { - service_id_context->second.accepted_connection_callback = - std::move(callback); - } - NEARBY_LOGS(INFO) - << "Update WifiLan medium for accepted callback: this=" << this - << "; medium=" << &medium << "; service_id=" << service_id; - }); -} - -void MediumEnvironment::UnregisterWifiLanMedium(api::WifiLanMedium& medium) { +void MediumEnvironment::RegisterWifiLanMedium(api::WifiLanMedium& medium) { if (!enabled_) return; RunOnMediumEnvironmentThread([this, &medium]() { - auto item = wifi_lan_mediums_.extract(&medium); - if (item.empty()) return; - NEARBY_LOGS(INFO) << "Unregistered WifiLan medium"; - }); -} - -void MediumEnvironment::CallWifiLanAcceptedConnectionCallback( - api::WifiLanMedium& medium, api::WifiLanSocket& socket, - const std::string& service_id) { - if (!enabled_) return; - RunOnMediumEnvironmentThread( - [this, &medium, &socket, service_id]() { - auto item = wifi_lan_mediums_.find(&medium); - if (item == wifi_lan_mediums_.end()) { - NEARBY_LOGS(INFO) - << "Call AcceptedConnectionCallback failed.. There is no medium " - "registered."; - return; - } - auto& info = item->second; - auto service_id_context = info.services.find(service_id); - if (service_id_context != info.services.end()) { - service_id_context->second.accepted_connection_callback.accepted_cb( - socket, service_id); - } - }); -} - -api::WifiLanService* MediumEnvironment::GetWifiLanService( - const std::string& ip_address, int port) { - api::WifiLanService* remote_wifi_lan_service = nullptr; - CountDownLatch latch(1); - RunOnMediumEnvironmentThread( - [this, &remote_wifi_lan_service, &ip_address, port, &latch]() { - for (auto& item : wifi_lan_mediums_) { - auto* wifi_lan_service = item.second.wifi_lan_service; - if (!wifi_lan_service) continue; - std::string remote_ip_address = - remote_wifi_lan_service->GetServiceInfo().GetIPAddress(); - int remote_port = remote_wifi_lan_service->GetServiceInfo().GetPort(); - if (remote_ip_address == ip_address && remote_port == port) { - remote_wifi_lan_service = wifi_lan_service; - break; - } - } - latch.CountDown(); - }); - latch.Await(); - return remote_wifi_lan_service; -} - -void MediumEnvironment::RegisterWifiLanMediumV2(api::WifiLanMediumV2& medium) { - if (!enabled_) return; - RunOnMediumEnvironmentThread([this, &medium]() { - wifi_lan_mediums_v2_.insert({&medium, WifiLanMediumV2Context{}}); + wifi_lan_mediums_.insert({&medium, WifiLanMediumContext{}}); NEARBY_LOG(INFO, "Registered: medium=%p", &medium); }); } -void MediumEnvironment::UpdateWifiLanMediumV2ForAdvertising( - api::WifiLanMediumV2& medium, const NsdServiceInfo& service_info, +void MediumEnvironment::UpdateWifiLanMediumForAdvertising( + api::WifiLanMedium& medium, const NsdServiceInfo& service_info, bool enabled) { if (!enabled_) return; RunOnMediumEnvironmentThread([this, &medium, service_info = service_info, @@ -799,7 +592,7 @@ void MediumEnvironment::UpdateWifiLanMediumV2ForAdvertising( << "; service_name=" << service_info.GetServiceName() << "; service_type=" << service_type << ", enabled=" << enabled; - for (auto& medium_info : wifi_lan_mediums_v2_) { + for (auto& medium_info : wifi_lan_mediums_) { auto& local_medium = medium_info.first; auto& info = medium_info.second; // Do not send notification to the same medium but update @@ -812,19 +605,19 @@ void MediumEnvironment::UpdateWifiLanMediumV2ForAdvertising( } continue; } - OnWifiLanServiceV2StateChanged(info, service_info, enabled); + OnWifiLanServiceStateChanged(info, service_info, enabled); } }); } -void MediumEnvironment::UpdateWifiLanMediumV2ForDiscovery( - api::WifiLanMediumV2& medium, WifiLanDiscoveredServiceV2Callback callback, +void MediumEnvironment::UpdateWifiLanMediumForDiscovery( + api::WifiLanMedium& medium, WifiLanDiscoveredServiceCallback callback, const std::string& service_type, bool enabled) { if (!enabled_) return; RunOnMediumEnvironmentThread([this, &medium, callback = std::move(callback), service_type, enabled]() { - auto item = wifi_lan_mediums_v2_.find(&medium); - if (item == wifi_lan_mediums_v2_.end()) { + auto item = wifi_lan_mediums_.find(&medium); + if (item == wifi_lan_mediums_.end()) { NEARBY_LOGS(INFO) << "UpdateWifiLanMediumForDiscovery failed. There is no medium " "registered."; @@ -836,7 +629,7 @@ void MediumEnvironment::UpdateWifiLanMediumV2ForDiscovery( << "; medium=" << &medium << "; service_type=" << service_type << "; enabled=" << enabled; - for (auto& medium_info : wifi_lan_mediums_v2_) { + for (auto& medium_info : wifi_lan_mediums_) { auto& local_medium = medium_info.first; auto& info = medium_info.second; // Do not send notification to the same medium. @@ -844,25 +637,24 @@ void MediumEnvironment::UpdateWifiLanMediumV2ForDiscovery( // Search advertising services and send notification. for (auto& advertising_service : info.advertising_services) { auto& service_info = advertising_service.second; - OnWifiLanServiceV2StateChanged(context, service_info, /*enabled=*/true); + OnWifiLanServiceStateChanged(context, service_info, /*enabled=*/true); } } }); } -void MediumEnvironment::UnregisterWifiLanMediumV2( - api::WifiLanMediumV2& medium) { +void MediumEnvironment::UnregisterWifiLanMedium(api::WifiLanMedium& medium) { if (!enabled_) return; RunOnMediumEnvironmentThread([this, &medium]() { - auto item = wifi_lan_mediums_v2_.extract(&medium); + auto item = wifi_lan_mediums_.extract(&medium); if (item.empty()) return; NEARBY_LOGS(INFO) << "Unregistered WifiLan medium"; }); } -api::WifiLanMediumV2* MediumEnvironment::GetWifiLanV2Medium( +api::WifiLanMedium* MediumEnvironment::GetWifiLanMedium( const std::string& ip_address, int port) { - for (auto& medium_info : wifi_lan_mediums_v2_) { + for (auto& medium_info : wifi_lan_mediums_) { auto* medium_found = medium_info.first; auto& info = medium_info.second; for (auto& advertising_service : info.advertising_services) { diff --git a/cpp/platform/base/medium_environment.h b/cpp/platform/base/medium_environment.h index 8f25ec64..3924b6e6 100644 --- a/cpp/platform/base/medium_environment.h +++ b/cpp/platform/base/medium_environment.h @@ -23,9 +23,8 @@ #include "platform/api/ble.h" #include "platform/api/bluetooth_adapter.h" #include "platform/api/bluetooth_classic.h" -#include "platform/api/wifi_lan.h" -#include "platform/api/wifi_lan_v2.h" #include "platform/api/webrtc.h" +#include "platform/api/wifi_lan.h" #include "platform/base/byte_array.h" #include "platform/base/feature_flags.h" #include "platform/base/listeners.h" @@ -63,10 +62,6 @@ class MediumEnvironment { api::WebRtcSignalingMessenger::OnSignalingCompleteCallback; using WifiLanDiscoveredServiceCallback = api::WifiLanMedium::DiscoveredServiceCallback; - using WifiLanAcceptedConnectionCallback = - api::WifiLanMedium::AcceptedConnectionCallback; - using WifiLanDiscoveredServiceV2Callback = - api::WifiLanMediumV2::DiscoveredServiceCallback; MediumEnvironment(const MediumEnvironment&) = delete; MediumEnvironment& operator=(const MediumEnvironment&) = delete; @@ -213,60 +208,16 @@ class MediumEnvironment { // Updates advertising info to indicate the current medium is exposing // advertising event. void UpdateWifiLanMediumForAdvertising(api::WifiLanMedium& medium, - api::WifiLanService& wifi_lan_service, - const std::string& service_id, + const NsdServiceInfo& nsd_service_info, bool enabled); // Updates discovery callback info to allow for dispatch of discovery events. // - // Invokes callback asynchronously when any changes happen to discoverable - // devices, or if the defice is turned off, whether or not it is discoverable, - // if it was ever reported as discoverable. - // // This should be called when discoverable state changes. // with user-specified callback when discovery is enabled, and with default // (empty) callback otherwise. void UpdateWifiLanMediumForDiscovery( - api::WifiLanMedium& medium, const std::string& service_id, - WifiLanDiscoveredServiceCallback callback, bool enabled); - - // Updates Accepted connection callback info to allow for dispatch of - // advertising events. - void UpdateWifiLanMediumForAcceptedConnection( - api::WifiLanMedium& medium, const std::string& service_id, - WifiLanAcceptedConnectionCallback callback); - - // Removes medium-related info. This should correspond to device power off. - void UnregisterWifiLanMedium(api::WifiLanMedium& medium); - - // Call back when advertising has created the server socket and is ready for - // connect. - void CallWifiLanAcceptedConnectionCallback(api::WifiLanMedium& medium, - api::WifiLanSocket& socket, - const std::string& service_id); - - // Returns WifiLan service matching IP address and port, or nullptr. - api::WifiLanService* GetWifiLanService(const std::string& ip_address, - int port); - - // Adds medium-related info to allow for discovery/advertising to work. - // This provides acccess to this medium from other mediums, when protocol - // expects they should communicate. - void RegisterWifiLanMediumV2(api::WifiLanMediumV2& medium); - - // Updates advertising info to indicate the current medium is exposing - // advertising event. - void UpdateWifiLanMediumV2ForAdvertising( - api::WifiLanMediumV2& medium, const NsdServiceInfo& nsd_service_info, - bool enabled); - - // Updates discovery callback info to allow for dispatch of discovery events. - // - // This should be called when discoverable state changes. - // with user-specified callback when discovery is enabled, and with default - // (empty) callback otherwise. - void UpdateWifiLanMediumV2ForDiscovery( - api::WifiLanMediumV2& medium, WifiLanDiscoveredServiceV2Callback callback, + api::WifiLanMedium& medium, WifiLanDiscoveredServiceCallback callback, const std::string& service_type, bool enabled); // Gets Fake IP address for WifiLan medium. @@ -276,12 +227,11 @@ class MediumEnvironment { int GetFakePort() const; // Removes medium-related info. This should correspond to device power off. - void UnregisterWifiLanMediumV2(api::WifiLanMediumV2& medium); + void UnregisterWifiLanMedium(api::WifiLanMedium& medium); // Returns WifiLan medium whose advertising service matching IP address and // port, or nullptr. - api::WifiLanMediumV2* GetWifiLanV2Medium(const std::string& ip_address, - int port); + api::WifiLanMedium* GetWifiLanMedium(const std::string& ip_address, int port); void SetFeatureFlags(const FeatureFlags::Flags& flags); @@ -301,26 +251,14 @@ class MediumEnvironment { bool fast_advertisement = false; }; - struct WifiLanServiceIdContext { - WifiLanDiscoveredServiceCallback discovery_callback; - WifiLanAcceptedConnectionCallback accepted_connection_callback; - bool advertising = false; - }; - struct WifiLanMediumContext { - api::WifiLanService* wifi_lan_service = nullptr; - absl::flat_hash_map services; - }; - - struct WifiLanMediumV2Context { // advertising service type vs NsdServiceInfo map. absl::flat_hash_map advertising_services; // discovered service type vs callback map. - absl::flat_hash_map + absl::flat_hash_map discovered_callbacks; // discovered service vs service type map. - absl::flat_hash_map - discovered_services; + absl::flat_hash_map discovered_services; }; // This is a singleton object, for which destructor will never be called. @@ -342,14 +280,9 @@ class MediumEnvironment { bool fast_advertisement, bool enabled); void OnWifiLanServiceStateChanged(WifiLanMediumContext& info, - api::WifiLanService& wifi_lan_service, - const std::string& service_id, + const NsdServiceInfo& service_info, bool enabled); - void OnWifiLanServiceV2StateChanged(WifiLanMediumV2Context& info, - const NsdServiceInfo& service_info, - bool enabled); - void RunOnMediumEnvironmentThread(std::function runnable); std::atomic_bool enabled_ = true; @@ -378,9 +311,6 @@ class MediumEnvironment { absl::flat_hash_map wifi_lan_mediums_; - absl::flat_hash_map - wifi_lan_mediums_v2_; - bool use_valid_peer_connection_ = true; absl::Duration peer_connection_latency_ = absl::ZeroDuration(); }; diff --git a/cpp/platform/impl/g3/BUILD b/cpp/platform/impl/g3/BUILD index 6a505796..264ee471 100644 --- a/cpp/platform/impl/g3/BUILD +++ b/cpp/platform/impl/g3/BUILD @@ -57,7 +57,6 @@ cc_library( "bluetooth_classic.cc", "webrtc.cc", "wifi_lan.cc", - "wifi_lan_v2.cc", ], hdrs = [ "ble.h", @@ -65,7 +64,6 @@ cc_library( "bluetooth_classic.h", "webrtc.h", "wifi_lan.h", - "wifi_lan_v2.h", ], visibility = ["//visibility:private"], deps = [ diff --git a/cpp/platform/impl/g3/platform.cc b/cpp/platform/impl/g3/platform.cc index 143e20c6..470af01d 100644 --- a/cpp/platform/impl/g3/platform.cc +++ b/cpp/platform/impl/g3/platform.cc @@ -49,7 +49,6 @@ #include "platform/impl/g3/single_thread_executor.h" #include "platform/impl/g3/webrtc.h" #include "platform/impl/g3/wifi_lan.h" -#include "platform/impl/g3/wifi_lan_v2.h" #include "platform/impl/shared/file.h" namespace location { @@ -147,11 +146,6 @@ std::unique_ptr ImplementationPlatform::CreateWifiLanMedium() { return absl::make_unique(); } -std::unique_ptr -ImplementationPlatform::CreateWifiLanMediumV2() { - return absl::make_unique(); -} - std::unique_ptr ImplementationPlatform::CreateWebRtcMedium() { if (MediumEnvironment::Instance().GetEnvironmentConfig().webrtc_enabled) { return absl::make_unique(); diff --git a/cpp/platform/impl/g3/wifi_lan.cc b/cpp/platform/impl/g3/wifi_lan.cc index 29576f55..e2760365 100644 --- a/cpp/platform/impl/g3/wifi_lan.cc +++ b/cpp/platform/impl/g3/wifi_lan.cc @@ -19,13 +19,14 @@ #include #include +#include "absl/strings/escaping.h" +#include "absl/strings/str_format.h" #include "absl/synchronization/mutex.h" #include "platform/api/wifi_lan.h" #include "platform/base/cancellation_flag_listener.h" #include "platform/base/logging.h" #include "platform/base/medium_environment.h" #include "platform/base/nsd_service_info.h" -#include "platform/base/prng.h" namespace location { namespace nearby { @@ -73,20 +74,13 @@ Exception WifiLanSocket::Close() { return {Exception::kSuccess}; } -WifiLanService* WifiLanSocket::GetRemoteWifiLanService() { - absl::MutexLock lock(&mutex_); - return wifi_lan_service_; -} - void WifiLanSocket::DoClose() { if (!closed_) { remote_socket_ = nullptr; output_->GetOutputStream().Close(); output_->GetInputStream().Close(); - if (IsConnectedLocked()) { - input_->GetOutputStream().Close(); - input_->GetInputStream().Close(); - } + input_->GetOutputStream().Close(); + input_->GetInputStream().Close(); closed_ = true; } } @@ -103,19 +97,32 @@ OutputStream& WifiLanSocket::GetLocalOutputStream() { return output_->GetOutputStream(); } -std::unique_ptr WifiLanServerSocket::Accept( - WifiLanService* wifi_lan_service) { - absl::MutexLock lock(&mutex_); - if (closed_) return {}; - while (pending_sockets_.empty()) { - cond_.Wait(&mutex_); - if (closed_) break; +std::string WifiLanServerSocket::GetName(const std::string& ip_address, + int port) { + std::string dot_delimited_string; + if (!ip_address.empty()) { + for (auto byte : ip_address) { + if (!dot_delimited_string.empty()) + absl::StrAppend(&dot_delimited_string, "."); + absl::StrAppend(&dot_delimited_string, absl::StrFormat("%d", byte)); + } } + std::string out = absl::StrCat(dot_delimited_string, ":", port); + return out; +} + +std::unique_ptr WifiLanServerSocket::Accept() { + absl::MutexLock lock(&mutex_); + while (!closed_ && pending_sockets_.empty()) { + cond_.Wait(&mutex_); + } + // whether or not we were running in the wait loop, return early if closed. if (closed_) return {}; auto* remote_socket = pending_sockets_.extract(pending_sockets_.begin()).value(); CHECK(remote_socket); - auto local_socket = std::make_unique(wifi_lan_service); + + auto local_socket = std::make_unique(); local_socket->Connect(*remote_socket); remote_socket->Connect(*local_socket); cond_.SignalAll(); @@ -126,12 +133,12 @@ bool WifiLanServerSocket::Connect(WifiLanSocket& socket) { absl::MutexLock lock(&mutex_); if (closed_) return false; if (socket.IsConnected()) { - NEARBY_LOG(ERROR, - "Failed to connect to WifiLan server socket: already connected"); + NEARBY_LOGS(ERROR) + << "Failed to connect to WifiLan server socket: already connected"; return true; // already connected. } // add client socket to the pending list - pending_sockets_.emplace(&socket); + pending_sockets_.insert(&socket); cond_.SignalAll(); while (!socket.IsConnected()) { cond_.Wait(&mutex_); @@ -173,247 +180,190 @@ Exception WifiLanServerSocket::DoClose() { } WifiLanMedium::WifiLanMedium() { - wifi_lan_service_.SetMedium(this); auto& env = MediumEnvironment::Instance(); env.RegisterWifiLanMedium(*this); } WifiLanMedium::~WifiLanMedium() { - wifi_lan_service_.SetMedium(nullptr); auto& env = MediumEnvironment::Instance(); env.UnregisterWifiLanMedium(*this); - - StopAdvertising(advertising_info_.service_id); - StopDiscovery(discovering_info_.service_id); - - NEARBY_LOG(INFO, "WifiLanMedium dtor advertising_accept_thread_running_ = %d", - acceptance_thread_running_.load()); - // If acceptance thread is still running, wait to finish. - if (acceptance_thread_running_) { - while (acceptance_thread_running_) { - shared::CountDownLatch latch(1); - close_accept_loops_runner_.Execute([&latch]() { latch.CountDown(); }); - latch.Await(); - } - } } -bool WifiLanMedium::StartAdvertising(const std::string& service_id, - const NsdServiceInfo& nsd_service_info) { - NEARBY_LOG(INFO, - "G3 WifiLan StartAdvertising: service_id=%s, nsd_service_info=%p, " - "service_info_name=%s", - service_id.c_str(), &nsd_service_info, - nsd_service_info.GetServiceName().c_str()); - auto& env = MediumEnvironment::Instance(); - NsdServiceInfo local_nsd_service_info{nsd_service_info}; - SetWifiLanService(nsd_service_info); - env.UpdateWifiLanMediumForAdvertising(*this, wifi_lan_service_, service_id, - true); - - absl::MutexLock lock(&mutex_); - if (server_socket_ != nullptr) server_socket_.release(); - server_socket_ = std::make_unique(); - - acceptance_thread_running_.exchange(true); - accept_loops_runner_.Execute([&env, this, service_id]() mutable { - if (!accept_loops_runner_.InShutdown()) { - while (true) { - auto client_socket = server_socket_->Accept(&wifi_lan_service_); - if (client_socket == nullptr) break; - env.CallWifiLanAcceptedConnectionCallback( - *this, *(client_socket.release()), service_id); - } - } - acceptance_thread_running_.exchange(false); - }); - advertising_info_.service_id = service_id; - return true; -} - -bool WifiLanMedium::StopAdvertising(const std::string& service_id) { - NEARBY_LOG(INFO, "G3 WifiLan StopAdvertising: service_id=%s", - service_id.c_str()); +bool WifiLanMedium::StartAdvertising(const NsdServiceInfo& nsd_service_info) { + std::string service_type = nsd_service_info.GetServiceType(); + NEARBY_LOGS(INFO) << "G3 WifiLan StartAdvertising: nsd_service_info=" + << &nsd_service_info + << ", service_name=" << nsd_service_info.GetServiceName() + << ", service_type=" << service_type; { absl::MutexLock lock(&mutex_); - if (advertising_info_.Empty()) { - NEARBY_LOG(INFO, - "G3 WifiLan StopAdvertising: Can't stop advertising because " - "we never started advertising."); + if (advertising_info_.Existed(service_type)) { + NEARBY_LOGS(INFO) + << "G3 WifiLan StartAdvertising: Can't start advertising because " + "service_type=" + << service_type << ", has started already."; return false; } - advertising_info_.Clear(); } - auto& env = MediumEnvironment::Instance(); - env.UpdateWifiLanMediumForAdvertising(*this, wifi_lan_service_, service_id, - false); - accept_loops_runner_.Shutdown(); - if (server_socket_ == nullptr) { - NEARBY_LOGS(ERROR) << "G3 WifiLan StopAdvertising: failed to find WifiLan " - "Server socket: service_id=" - << service_id; - // Fall through for server socket not found. - return true; + env.UpdateWifiLanMediumForAdvertising(*this, nsd_service_info, + /*enabled=*/true); + { + absl::MutexLock lock(&mutex_); + advertising_info_.Add(service_type); } - - if (!server_socket_->Close().Ok()) { - NEARBY_LOG(INFO, - "G3 WifiLan StopAdvertising: Failed to close WifiLan server " - "socket for %s.", - service_id.c_str()); - return false; - } - return true; } -bool WifiLanMedium::StartDiscovery(const std::string& service_id, - DiscoveredServiceCallback callback) { - NEARBY_LOG(INFO, "G3 WifiLan StartDiscovery: service_id=%s", - service_id.c_str()); +bool WifiLanMedium::StopAdvertising(const NsdServiceInfo& nsd_service_info) { + std::string service_type = nsd_service_info.GetServiceType(); + NEARBY_LOGS(INFO) << "G3 WifiLan StopAdvertising: nsd_service_info=" + << &nsd_service_info + << ", service_name=" << nsd_service_info.GetServiceName() + << ", service_type=" << service_type; + { + absl::MutexLock lock(&mutex_); + if (!advertising_info_.Existed(service_type)) { + NEARBY_LOGS(INFO) + << "G3 WifiLan StopAdvertising: Can't stop advertising because " + "we never started advertising for service_type=" + << service_type; + return false; + } + advertising_info_.Remove(service_type); + } auto& env = MediumEnvironment::Instance(); - env.UpdateWifiLanMediumForDiscovery(*this, service_id, std::move(callback), + env.UpdateWifiLanMediumForAdvertising(*this, nsd_service_info, + /*enabled=*/false); + return true; +} + +bool WifiLanMedium::StartDiscovery(const std::string& service_type, + DiscoveredServiceCallback callback) { + NEARBY_LOGS(INFO) << "G3 WifiLan StartDiscovery: service_type=" + << service_type; + { + absl::MutexLock lock(&mutex_); + if (discovering_info_.Existed(service_type)) { + NEARBY_LOGS(INFO) + << "G3 WifiLan StartDiscovery: Can't start discovery because " + "service_type=" + << service_type << " has started already."; + return false; + } + } + auto& env = MediumEnvironment::Instance(); + env.UpdateWifiLanMediumForDiscovery(*this, std::move(callback), service_type, true); { absl::MutexLock lock(&mutex_); - discovering_info_.service_id = service_id; + discovering_info_.Add(service_type); } return true; } -bool WifiLanMedium::StopDiscovery(const std::string& service_id) { - NEARBY_LOG(INFO, "G3 WifiLan StopDiscovery: service_id=%s", - service_id.c_str()); +bool WifiLanMedium::StopDiscovery(const std::string& service_type) { + NEARBY_LOGS(INFO) << "G3 WifiLan StopDiscovery: service_type=" + << service_type; { absl::MutexLock lock(&mutex_); - if (discovering_info_.Empty()) { - NEARBY_LOG(INFO, - "G3 WifiLan StopDiscovery: Can't stop discovering because we " - "never started discovering."); + if (!discovering_info_.Existed(service_type)) { + NEARBY_LOGS(INFO) + << "G3 WifiLan StopDiscovery: Can't stop discovering because we " + "never started discovering."; return false; } - discovering_info_.Clear(); + discovering_info_.Remove(service_type); + } + auto& env = MediumEnvironment::Instance(); + env.UpdateWifiLanMediumForDiscovery(*this, {}, service_type, false); + return true; +} + +std::unique_ptr WifiLanMedium::ConnectToService( + const NsdServiceInfo& remote_service_info, + CancellationFlag* cancellation_flag) { + std::string service_type = remote_service_info.GetServiceType(); + NEARBY_LOGS(INFO) << "G3 WifiLan ConnectToService [self]: medium=" << this + << ", service_type=" << service_type; + return ConnectToService(remote_service_info.GetIPAddress(), + remote_service_info.GetPort(), cancellation_flag); +} + +std::unique_ptr WifiLanMedium::ConnectToService( + const std::string& ip_address, int port, + CancellationFlag* cancellation_flag) { + std::string socket_name = WifiLanServerSocket::GetName(ip_address, port); + NEARBY_LOGS(INFO) << "G3 WifiLan ConnectToService [self]: medium=" << this + << ", ip address + port=" << socket_name; + // First, find an instance of remote medium, that exposed this service. + auto& env = MediumEnvironment::Instance(); + auto* remote_medium = + static_cast(env.GetWifiLanMedium(ip_address, port)); + if (!remote_medium) { + return {}; } - auto& env = MediumEnvironment::Instance(); - env.UpdateWifiLanMediumForDiscovery(*this, service_id, {}, false); - return true; -} - -bool WifiLanMedium::StartAcceptingConnections( - const std::string& service_id, AcceptedConnectionCallback callback) { - NEARBY_LOG(INFO, "G3 WifiLan StartAcceptingConnections: service_id=%s", - service_id.c_str()); - auto& env = MediumEnvironment::Instance(); - env.UpdateWifiLanMediumForAcceptedConnection(*this, service_id, callback); - return true; -} - -bool WifiLanMedium::StopAcceptingConnections(const std::string& service_id) { - NEARBY_LOG(INFO, "G3 WifiLan StopAcceptingConnections: service_id=%s", - service_id.c_str()); - auto& env = MediumEnvironment::Instance(); - env.UpdateWifiLanMediumForAcceptedConnection(*this, service_id, {}); - return true; -} - -std::unique_ptr WifiLanMedium::Connect( - api::WifiLanService& remote_wifi_lan_service, const std::string& service_id, - CancellationFlag* cancellation_flag) { - NEARBY_LOG(INFO, - "G3 WifiLan Connect: medium=%p, wifi_lan_service=%p, " - "service_info_name=%s, service_id=%s", - this, &wifi_lan_service_, - remote_wifi_lan_service.GetServiceInfo().GetServiceName().c_str(), - service_id.c_str()); - // First, find an instance of remote medium, that exposed this service. - auto* remote_medium = - static_cast(remote_wifi_lan_service).GetMedium(); - - if (!remote_medium) return {}; // Can't find medium. Bail out. - - WifiLanServerSocket* remote_server_socket = nullptr; - NEARBY_LOG(INFO, - "G3 WifiLan Connect [peer]: remote_wifi_lan_service=%p, " - "remote_service_info_name=%s, service_id=%s", - &remote_wifi_lan_service, - remote_wifi_lan_service.GetServiceInfo().GetServiceName().c_str(), - service_id.c_str()); + WifiLanServerSocket* server_socket = nullptr; + NEARBY_LOGS(INFO) << "G3 WifiLan ConnectToService [peer]: medium=" + << remote_medium + << ", remote ip address + port=" << socket_name; // Then, find our server socket context in this medium. { absl::MutexLock medium_lock(&remote_medium->mutex_); - remote_server_socket = remote_medium->server_socket_.get(); - if (remote_server_socket == nullptr) { + auto item = remote_medium->server_sockets_.find(socket_name); + server_socket = item != server_sockets_.end() ? item->second : nullptr; + if (server_socket == nullptr) { NEARBY_LOGS(ERROR) - << "G3 WifiLan Connect: Failed to find remote WifiLan Server socket: " - "service_id=" - << service_id; - // Fall through for server socket not found. + << "G3 WifiLan Failed to find WifiLan Server socket: socket_name=" + << socket_name; return {}; } } if (cancellation_flag->Cancelled()) { - NEARBY_LOGS(INFO) << "G3 WifiLan Connect: Has been cancelled: " - "service_id=" - << service_id; + NEARBY_LOGS(ERROR) << "G3 WifiLan Connect: Has been cancelled: socket_name=" + << socket_name; return {}; } - CancellationFlagListener listener(cancellation_flag, [this]() { + CancellationFlagListener listener(cancellation_flag, [&server_socket]() { NEARBY_LOGS(INFO) << "G3 WifiLan Cancel Connect."; - if (server_socket_ != nullptr) server_socket_->Close(); + if (server_socket != nullptr) { + server_socket->Close(); + } }); - WifiLanService wifi_lan_service = - static_cast(remote_wifi_lan_service); - auto socket = std::make_unique(&wifi_lan_service); + auto socket = std::make_unique(); // Finally, Request to connect to this socket. - if (!remote_server_socket->Connect(*socket)) { - NEARBY_LOG(ERROR, - "G3 WifiLan Connect: Failed to connect to existing WifiLan " - "Server socket: service_id=%s", - service_id.c_str()); + if (!server_socket->Connect(*socket)) { + NEARBY_LOGS(ERROR) << "G3 WifiLan Failed to connect to existing WifiLan " + "Server socket: name=" + << socket_name; return {}; } - - NEARBY_LOG(INFO, "G3 WifiLan Connect: connected: socket=%p", socket.get()); + NEARBY_LOGS(INFO) << "G3 WifiLan ConnectToService: connected: socket=" + << socket.get(); return socket; } -api::WifiLanService* WifiLanMedium::GetRemoteService( - const std::string& ip_address, int port) { +std::unique_ptr WifiLanMedium::ListenForService( + int port) { auto& env = MediumEnvironment::Instance(); - return env.GetWifiLanService(ip_address, port); -} - -std::pair WifiLanMedium::GetCredentials( - const std::string& service_id) { - NEARBY_LOGS(INFO) << "G3 WifiLan GetCredential: service_id=" << service_id; - return std::make_pair(wifi_lan_service_.GetServiceInfo().GetIPAddress(), - wifi_lan_service_.GetServiceInfo().GetPort()); -} - -void WifiLanMedium::SetWifiLanService(const NsdServiceInfo& nsd_service_info) { - NsdServiceInfo local_nsd_service_info{nsd_service_info}; - auto credential = GetFakeCredentials(); - local_nsd_service_info.SetIPAddress(credential.first); - local_nsd_service_info.SetPort(credential.second); - wifi_lan_service_.SetServiceInfo(local_nsd_service_info); -} - -std::pair WifiLanMedium::GetFakeCredentials() const { - std::string ip_address; - ip_address.resize(4); - uint32_t raw_ip_addr = Prng().NextUint32(); - uint16_t port = Prng().NextUint32(); - ip_address[0] = static_cast(raw_ip_addr >> 24); - ip_address[1] = static_cast(raw_ip_addr >> 16); - ip_address[2] = static_cast(raw_ip_addr >> 8); - ip_address[3] = static_cast(raw_ip_addr >> 0); - - return std::make_pair(ip_address, port); + auto server_socket = std::make_unique(); + server_socket->SetIPAddress(env.GetFakeIPAddress()); + server_socket->SetPort(port == 0 ? env.GetFakePort() : port); + std::string socket_name = WifiLanServerSocket::GetName( + server_socket->GetIPAddress(), server_socket->GetPort()); + server_socket->SetCloseNotifier([this, socket_name]() { + absl::MutexLock lock(&mutex_); + server_sockets_.erase(socket_name); + }); + NEARBY_LOGS(INFO) << "G3 WifiLan Adding server socket: medium=" << this + << ", socket_name=" << socket_name; + absl::MutexLock lock(&mutex_); + server_sockets_.insert({socket_name, server_socket.get()}); + return server_socket; } } // namespace g3 diff --git a/cpp/platform/impl/g3/wifi_lan.h b/cpp/platform/impl/g3/wifi_lan.h index a2e73f00..8d95c673 100644 --- a/cpp/platform/impl/g3/wifi_lan.h +++ b/cpp/platform/impl/g3/wifi_lan.h @@ -36,34 +36,9 @@ namespace g3 { class WifiLanMedium; -// Opaque wrapper over a WifiLan service which contains |NsdServiceInfo|. -class WifiLanService : public api::WifiLanService { - public: - WifiLanService() = default; - explicit WifiLanService(NsdServiceInfo nsd_service_info) - : nsd_service_info_(std::move(nsd_service_info)) {} - ~WifiLanService() override = default; - - NsdServiceInfo GetServiceInfo() const override { return nsd_service_info_; } - - void SetServiceInfo(NsdServiceInfo nsd_service_info) { - nsd_service_info_ = std::move(nsd_service_info); - } - - WifiLanMedium* GetMedium() { return medium_; } - - void SetMedium(WifiLanMedium* medium) { medium_ = medium; } - - private: - NsdServiceInfo nsd_service_info_; - WifiLanMedium* medium_ = nullptr; -}; - class WifiLanSocket : public api::WifiLanSocket { public: WifiLanSocket() = default; - explicit WifiLanSocket(WifiLanService* wifi_lan_service) - : wifi_lan_service_(wifi_lan_service) {} ~WifiLanSocket() override; // Connect to another WifiLanSocket, to form a functional low-level channel. @@ -89,11 +64,6 @@ class WifiLanSocket : public api::WifiLanSocket { // Returns Exception::kIo on error, Exception::kSuccess otherwise. Exception Close() override ABSL_LOCKS_EXCLUDED(mutex_); - // Returns valid WifiLanService pointer if there is a connection, and - // nullptr otherwise. - WifiLanService* GetRemoteWifiLanService() override - ABSL_LOCKS_EXCLUDED(mutex_); - private: void DoClose() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); @@ -116,14 +86,39 @@ class WifiLanSocket : public api::WifiLanSocket { std::shared_ptr output_{new Pipe}; std::shared_ptr input_; mutable absl::Mutex mutex_; - WifiLanService* wifi_lan_service_; WifiLanSocket* remote_socket_ ABSL_GUARDED_BY(mutex_) = nullptr; bool closed_ ABSL_GUARDED_BY(mutex_) = false; }; -class WifiLanServerSocket { +class WifiLanServerSocket : public api::WifiLanServerSocket { public: - ~WifiLanServerSocket(); + static std::string GetName(const std::string& ip_address, int port); + + ~WifiLanServerSocket() override; + + // Gets ip address. + std::string GetIPAddress() const override ABSL_LOCKS_EXCLUDED(mutex_) { + absl::MutexLock lock(&mutex_); + return ip_address_; + } + + // Sets the ip address. + void SetIPAddress(const std::string& ip_address) ABSL_LOCKS_EXCLUDED(mutex_) { + absl::MutexLock lock(&mutex_); + ip_address_ = ip_address; + } + + // Gets the port. + int GetPort() const override ABSL_LOCKS_EXCLUDED(mutex_) { + absl::MutexLock lock(&mutex_); + return port_; + } + + // Sets the port. + void SetPort(int port) ABSL_LOCKS_EXCLUDED(mutex_) { + absl::MutexLock lock(&mutex_); + port_ = port; + } // Blocks until either: // - at least one incoming connection request is available, or @@ -135,7 +130,7 @@ class WifiLanServerSocket { // Called by the server side of a connection. // Returns WifiLanSocket to the server side. // If not null, returned socket is connected to its remote (client-side) peer. - std::unique_ptr Accept(WifiLanService* service) + std::unique_ptr Accept() override ABSL_LOCKS_EXCLUDED(mutex_); // Blocks until either: @@ -149,18 +144,20 @@ class WifiLanServerSocket { // Called by the server side of a connection before passing ownership of // WifiLanServerSocker to user, to track validity of a pointer to this - // server socket, + // server socket. void SetCloseNotifier(std::function notifier) ABSL_LOCKS_EXCLUDED(mutex_); // Returns Exception::kIo on error, Exception::kSuccess otherwise. // Calls close_notifier if it was previously set, and marks socket as closed. - Exception Close() ABSL_LOCKS_EXCLUDED(mutex_); + Exception Close() override ABSL_LOCKS_EXCLUDED(mutex_); private: Exception DoClose() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - absl::Mutex mutex_; + mutable absl::Mutex mutex_; + std::string ip_address_ ABSL_GUARDED_BY(mutex_); + int port_ ABSL_GUARDED_BY(mutex_); absl::CondVar cond_; absl::flat_hash_set pending_sockets_ ABSL_GUARDED_BY(mutex_); std::function close_notifier_ ABSL_GUARDED_BY(mutex_); @@ -173,81 +170,106 @@ class WifiLanMedium : public api::WifiLanMedium { WifiLanMedium(); ~WifiLanMedium() override; - bool StartAdvertising(const std::string& service_id, - const NsdServiceInfo& nsd_service_info) override - ABSL_LOCKS_EXCLUDED(mutex_); - bool StopAdvertising(const std::string& service_id) override + // Starts WifiLan advertising. + // + // nsd_service_info - NsdServiceInfo data that's advertised through mDNS + // service. + // On success if the service is now advertising. + // On error if the service cannot start to advertise or the service type in + // NsdServiceInfo has been passed previously which StopAdvertising is not + // been called. + bool StartAdvertising(const NsdServiceInfo& nsd_service_info) override ABSL_LOCKS_EXCLUDED(mutex_); - // Returns true once the WifiLan discovery has been initiated. - bool StartDiscovery(const std::string& service_id, + // Stops WifiLan advertising. + // + // nsd_service_info - NsdServiceInfo data that's advertised through mDNS + // service. + // On success if the service stops advertising. + // On error if the service cannot stop advertising or the service type in + // NsdServiceInfo cannot be found. + bool StopAdvertising(const NsdServiceInfo& nsd_service_info) override + ABSL_LOCKS_EXCLUDED(mutex_); + + // Starts the discovery of nearby WifiLan services. + // + // Returns true once the WifiLan discovery has been initiated. The + // service_type is associated with callback. + bool StartDiscovery(const std::string& service_type, DiscoveredServiceCallback callback) override ABSL_LOCKS_EXCLUDED(mutex_); - // Returns true once WifiLan discovery for service_id is well and truly - // stopped; after this returns, there must be no more invocations of the - // DiscoveredServiceCallback passed in to StartDiscovery() for service_id. - bool StopDiscovery(const std::string& service_id) override - ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns true once WifiLan socket connection requests to service_id can be - // accepted. - bool StartAcceptingConnections(const std::string& service_id, - AcceptedConnectionCallback callback) override - ABSL_LOCKS_EXCLUDED(mutex_); - bool StopAcceptingConnections(const std::string& service_id) override - ABSL_LOCKS_EXCLUDED(mutex_); - - // Connects to existing remote WifiLan service. + // Stops the discovery of nearby WifiLan services. // + // service_type - The one assigend in StartDiscovery. + // On success if service_type is matched to the callback and will be removed + // from the list. If list is empty then stops the WifiLan discovery + // service. + // On error if the service_type is not existed, then return immediately. + bool StopDiscovery(const std::string& service_type) override + ABSL_LOCKS_EXCLUDED(mutex_); + + // Connects to a WifiLan service. // On success, returns a new WifiLanSocket. // On error, returns nullptr. - std::unique_ptr Connect( - api::WifiLanService& remote_wifi_lan_service, - const std::string& service_id, + std::unique_ptr ConnectToService( + const NsdServiceInfo& remote_service_info, CancellationFlag* cancellation_flag) override ABSL_LOCKS_EXCLUDED(mutex_); - api::WifiLanService* GetRemoteService(const std::string& ip_address, - int port) override; + // Connects to a WifiLan service by ip address and port. + // On success, returns a new WifiLanSocket. + // On error, returns nullptr. + std::unique_ptr ConnectToService( + const std::string& ip_address, int port, + CancellationFlag* cancellation_flag) override ABSL_LOCKS_EXCLUDED(mutex_); - std::pair GetCredentials( - const std::string& service_id) override ABSL_LOCKS_EXCLUDED(mutex_); + // Listens for incoming connection. + // + // port - A port number. + // 0 : use a random port. + // 1~65536 : open a server socket on that exact port. + // On success, returns a new WifiLanServerSocket. + // On error, returns nullptr. + std::unique_ptr ListenForService(int port) override + ABSL_LOCKS_EXCLUDED(mutex_); private: - static constexpr int kMaxConcurrentAcceptLoops = 5; - struct AdvertisingInfo { - bool Empty() const { return service_id.empty(); } - void Clear() { service_id.clear(); } + bool Empty() const { return service_types.empty(); } + void Clear() { service_types.clear(); } + void Add(const std::string& service_type) { + service_types.insert(service_type); + } + void Remove(const std::string& service_type) { + service_types.erase(service_type); + } + bool Existed(const std::string& service_type) const { + return service_types.contains(service_type); + } - std::string service_id; + absl::flat_hash_set service_types; }; - struct DiscoveringInfo { - bool Empty() const { return service_id.empty(); } - void Clear() { service_id.clear(); } + bool Empty() const { return service_types.empty(); } + void Clear() { service_types.clear(); } + void Add(const std::string& service_type) { + service_types.insert(service_type); + } + void Remove(const std::string& service_type) { + service_types.erase(service_type); + } + bool Existed(const std::string& service_type) const { + return service_types.contains(service_type); + } - std::string service_id; + absl::flat_hash_set service_types; }; - void SetWifiLanService(const NsdServiceInfo& nsd_service_info); - std::pair GetFakeCredentials() const; - absl::Mutex mutex_; - WifiLanService wifi_lan_service_; - - // A thread pool dedicated to running all the accept loops from - // StartAdvertising(). - MultiThreadExecutor accept_loops_runner_{kMaxConcurrentAcceptLoops}; - std::atomic_bool acceptance_thread_running_ = false; - - // A thread pool dedicated to wait to complete the accept_loops_runner_. - MultiThreadExecutor close_accept_loops_runner_{kMaxConcurrentAcceptLoops}; - - // A server socket is established when start advertising. - std::unique_ptr server_socket_; AdvertisingInfo advertising_info_ ABSL_GUARDED_BY(mutex_); DiscoveringInfo discovering_info_ ABSL_GUARDED_BY(mutex_); + absl::flat_hash_map server_sockets_ + ABSL_GUARDED_BY(mutex_); }; } // namespace g3 diff --git a/cpp/platform/impl/g3/wifi_lan_v2.cc b/cpp/platform/impl/g3/wifi_lan_v2.cc deleted file mode 100644 index 00b4bac7..00000000 --- a/cpp/platform/impl/g3/wifi_lan_v2.cc +++ /dev/null @@ -1,371 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/impl/g3/wifi_lan_v2.h" - -#include -#include -#include -#include - -#include "absl/strings/escaping.h" -#include "absl/strings/str_format.h" -#include "absl/synchronization/mutex.h" -#include "platform/api/wifi_lan_v2.h" -#include "platform/base/cancellation_flag_listener.h" -#include "platform/base/logging.h" -#include "platform/base/medium_environment.h" -#include "platform/base/nsd_service_info.h" - -namespace location { -namespace nearby { -namespace g3 { - -WifiLanSocketV2::~WifiLanSocketV2() { - absl::MutexLock lock(&mutex_); - DoClose(); -} - -void WifiLanSocketV2::Connect(WifiLanSocketV2& other) { - absl::MutexLock lock(&mutex_); - remote_socket_ = &other; - input_ = other.output_; -} - -InputStream& WifiLanSocketV2::GetInputStream() { - auto* remote_socket = GetRemoteSocket(); - CHECK(remote_socket != nullptr); - return remote_socket->GetLocalInputStream(); -} - -OutputStream& WifiLanSocketV2::GetOutputStream() { - return GetLocalOutputStream(); -} - -WifiLanSocketV2* WifiLanSocketV2::GetRemoteSocket() { - absl::MutexLock lock(&mutex_); - return remote_socket_; -} - -bool WifiLanSocketV2::IsConnected() const { - absl::MutexLock lock(&mutex_); - return IsConnectedLocked(); -} - -bool WifiLanSocketV2::IsClosed() const { - absl::MutexLock lock(&mutex_); - return closed_; -} - -Exception WifiLanSocketV2::Close() { - absl::MutexLock lock(&mutex_); - DoClose(); - return {Exception::kSuccess}; -} - -void WifiLanSocketV2::DoClose() { - if (!closed_) { - remote_socket_ = nullptr; - output_->GetOutputStream().Close(); - output_->GetInputStream().Close(); - input_->GetOutputStream().Close(); - input_->GetInputStream().Close(); - closed_ = true; - } -} - -bool WifiLanSocketV2::IsConnectedLocked() const { return input_ != nullptr; } - -InputStream& WifiLanSocketV2::GetLocalInputStream() { - absl::MutexLock lock(&mutex_); - return output_->GetInputStream(); -} - -OutputStream& WifiLanSocketV2::GetLocalOutputStream() { - absl::MutexLock lock(&mutex_); - return output_->GetOutputStream(); -} - -std::string WifiLanServerSocketV2::GetName(const std::string& ip_address, - int port) { - std::string dot_delimited_string; - if (!ip_address.empty()) { - for (auto byte : ip_address) { - if (!dot_delimited_string.empty()) - absl::StrAppend(&dot_delimited_string, "."); - absl::StrAppend(&dot_delimited_string, absl::StrFormat("%d", byte)); - } - } - std::string out = absl::StrCat(dot_delimited_string, ":", port); - return out; -} - -std::unique_ptr WifiLanServerSocketV2::Accept() { - absl::MutexLock lock(&mutex_); - while (!closed_ && pending_sockets_.empty()) { - cond_.Wait(&mutex_); - } - // whether or not we were running in the wait loop, return early if closed. - if (closed_) return {}; - auto* remote_socket = - pending_sockets_.extract(pending_sockets_.begin()).value(); - CHECK(remote_socket); - - auto local_socket = std::make_unique(); - local_socket->Connect(*remote_socket); - remote_socket->Connect(*local_socket); - cond_.SignalAll(); - return local_socket; -} - -bool WifiLanServerSocketV2::Connect(WifiLanSocketV2& socket) { - absl::MutexLock lock(&mutex_); - if (closed_) return false; - if (socket.IsConnected()) { - NEARBY_LOGS(ERROR) - << "Failed to connect to WifiLan server socket: already connected"; - return true; // already connected. - } - // add client socket to the pending list - pending_sockets_.insert(&socket); - cond_.SignalAll(); - while (!socket.IsConnected()) { - cond_.Wait(&mutex_); - if (closed_) return false; - } - return true; -} - -void WifiLanServerSocketV2::SetCloseNotifier(std::function notifier) { - absl::MutexLock lock(&mutex_); - close_notifier_ = std::move(notifier); -} - -WifiLanServerSocketV2::~WifiLanServerSocketV2() { - absl::MutexLock lock(&mutex_); - DoClose(); -} - -Exception WifiLanServerSocketV2::Close() { - absl::MutexLock lock(&mutex_); - return DoClose(); -} - -Exception WifiLanServerSocketV2::DoClose() { - bool should_notify = !closed_; - closed_ = true; - if (should_notify) { - cond_.SignalAll(); - if (close_notifier_) { - auto notifier = std::move(close_notifier_); - mutex_.Unlock(); - // Notifier may contain calls to public API, and may cause deadlock, if - // mutex_ is held during the call. - notifier(); - mutex_.Lock(); - } - } - return {Exception::kSuccess}; -} - -WifiLanMediumV2::WifiLanMediumV2() { - auto& env = MediumEnvironment::Instance(); - env.RegisterWifiLanMediumV2(*this); -} - -WifiLanMediumV2::~WifiLanMediumV2() { - auto& env = MediumEnvironment::Instance(); - env.UnregisterWifiLanMediumV2(*this); -} - -bool WifiLanMediumV2::StartAdvertising(const NsdServiceInfo& nsd_service_info) { - std::string service_type = nsd_service_info.GetServiceType(); - NEARBY_LOGS(INFO) << "G3 WifiLan StartAdvertising: nsd_service_info=" - << &nsd_service_info - << ", service_name=" << nsd_service_info.GetServiceName() - << ", service_type=" << service_type; - { - absl::MutexLock lock(&mutex_); - if (advertising_info_.Existed(service_type)) { - NEARBY_LOGS(INFO) - << "G3 WifiLan StartAdvertising: Can't start advertising because " - "service_type=" - << service_type << ", has started already."; - return false; - } - } - auto& env = MediumEnvironment::Instance(); - env.UpdateWifiLanMediumV2ForAdvertising(*this, nsd_service_info, - /*enabled=*/true); - { - absl::MutexLock lock(&mutex_); - advertising_info_.Add(service_type); - } - return true; -} - -bool WifiLanMediumV2::StopAdvertising(const NsdServiceInfo& nsd_service_info) { - std::string service_type = nsd_service_info.GetServiceType(); - NEARBY_LOGS(INFO) << "G3 WifiLan StopAdvertising: nsd_service_info=" - << &nsd_service_info - << ", service_name=" << nsd_service_info.GetServiceName() - << ", service_type=" << service_type; - { - absl::MutexLock lock(&mutex_); - if (!advertising_info_.Existed(service_type)) { - NEARBY_LOGS(INFO) - << "G3 WifiLan StopAdvertising: Can't stop advertising because " - "we never started advertising for service_type=" - << service_type; - return false; - } - advertising_info_.Remove(service_type); - } - auto& env = MediumEnvironment::Instance(); - env.UpdateWifiLanMediumV2ForAdvertising(*this, nsd_service_info, - /*enabled=*/false); - return true; -} - -bool WifiLanMediumV2::StartDiscovery(const std::string& service_type, - DiscoveredServiceCallback callback) { - NEARBY_LOGS(INFO) << "G3 WifiLan StartDiscovery: service_type=" - << service_type; - { - absl::MutexLock lock(&mutex_); - if (discovering_info_.Existed(service_type)) { - NEARBY_LOGS(INFO) - << "G3 WifiLan StartDiscovery: Can't start discovery because " - "service_type=" - << service_type << " has started already."; - return false; - } - } - auto& env = MediumEnvironment::Instance(); - env.UpdateWifiLanMediumV2ForDiscovery(*this, std::move(callback), - service_type, true); - { - absl::MutexLock lock(&mutex_); - discovering_info_.Add(service_type); - } - return true; -} - -bool WifiLanMediumV2::StopDiscovery(const std::string& service_type) { - NEARBY_LOGS(INFO) << "G3 WifiLan StopDiscovery: service_type=" - << service_type; - { - absl::MutexLock lock(&mutex_); - if (!discovering_info_.Existed(service_type)) { - NEARBY_LOGS(INFO) - << "G3 WifiLan StopDiscovery: Can't stop discovering because we " - "never started discovering."; - return false; - } - discovering_info_.Remove(service_type); - } - auto& env = MediumEnvironment::Instance(); - env.UpdateWifiLanMediumV2ForDiscovery(*this, {}, service_type, false); - return true; -} - -std::unique_ptr WifiLanMediumV2::ConnectToService( - const NsdServiceInfo& remote_service_info, - CancellationFlag* cancellation_flag) { - std::string service_type = remote_service_info.GetServiceType(); - NEARBY_LOGS(INFO) << "G3 WifiLan ConnectToService [self]: medium=" << this - << ", service_type=" << service_type; - return ConnectToService(remote_service_info.GetIPAddress(), - remote_service_info.GetPort(), cancellation_flag); -} - -std::unique_ptr WifiLanMediumV2::ConnectToService( - const std::string& ip_address, int port, - CancellationFlag* cancellation_flag) { - std::string socket_name = WifiLanServerSocketV2::GetName(ip_address, port); - NEARBY_LOGS(INFO) << "G3 WifiLan ConnectToService [self]: medium=" << this - << ", ip address + port=" << socket_name; - // First, find an instance of remote medium, that exposed this service. - auto& env = MediumEnvironment::Instance(); - auto* remote_medium = - static_cast(env.GetWifiLanV2Medium(ip_address, port)); - if (!remote_medium) { - return {}; - } - - WifiLanServerSocketV2* server_socket = nullptr; - NEARBY_LOGS(INFO) << "G3 WifiLan ConnectToService [peer]: medium=" - << remote_medium - << ", remote ip address + port=" << socket_name; - // Then, find our server socket context in this medium. - { - absl::MutexLock medium_lock(&remote_medium->mutex_); - auto item = remote_medium->server_sockets_.find(socket_name); - server_socket = item != server_sockets_.end() ? item->second : nullptr; - if (server_socket == nullptr) { - NEARBY_LOGS(ERROR) - << "G3 WifiLan Failed to find WifiLan Server socket: socket_name=" - << socket_name; - return {}; - } - } - - if (cancellation_flag->Cancelled()) { - NEARBY_LOGS(ERROR) << "G3 WifiLan Connect: Has been cancelled: socket_name=" - << socket_name; - return {}; - } - - CancellationFlagListener listener(cancellation_flag, [&server_socket]() { - NEARBY_LOGS(INFO) << "G3 WifiLan Cancel Connect."; - if (server_socket != nullptr) { - server_socket->Close(); - } - }); - - auto socket = std::make_unique(); - // Finally, Request to connect to this socket. - if (!server_socket->Connect(*socket)) { - NEARBY_LOGS(ERROR) << "G3 WifiLan Failed to connect to existing WifiLan " - "Server socket: name=" - << socket_name; - return {}; - } - NEARBY_LOGS(INFO) << "G3 WifiLan ConnectToService: connected: socket=" - << socket.get(); - return socket; -} - -std::unique_ptr WifiLanMediumV2::ListenForService( - int port) { - auto& env = MediumEnvironment::Instance(); - auto server_socket = std::make_unique(); - server_socket->SetIPAddress(env.GetFakeIPAddress()); - server_socket->SetPort(port == 0 ? env.GetFakePort() : port); - std::string socket_name = WifiLanServerSocketV2::GetName( - server_socket->GetIPAddress(), server_socket->GetPort()); - server_socket->SetCloseNotifier([this, socket_name]() { - absl::MutexLock lock(&mutex_); - server_sockets_.erase(socket_name); - }); - NEARBY_LOGS(INFO) << "G3 WifiLan Adding server socket: medium=" << this - << ", socket_name=" << socket_name; - absl::MutexLock lock(&mutex_); - server_sockets_.insert({socket_name, server_socket.get()}); - return server_socket; -} - -} // namespace g3 -} // namespace nearby -} // namespace location diff --git a/cpp/platform/impl/g3/wifi_lan_v2.h b/cpp/platform/impl/g3/wifi_lan_v2.h deleted file mode 100644 index ba7b14f1..00000000 --- a/cpp/platform/impl/g3/wifi_lan_v2.h +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef PLATFORM_IMPL_G3_WIFI_LAN_V2_H_ -#define PLATFORM_IMPL_G3_WIFI_LAN_V2_H_ - -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/container/flat_hash_set.h" -#include "absl/synchronization/mutex.h" -#include "platform/api/wifi_lan_v2.h" -#include "platform/base/byte_array.h" -#include "platform/base/input_stream.h" -#include "platform/base/nsd_service_info.h" -#include "platform/base/output_stream.h" -#include "platform/impl/g3/multi_thread_executor.h" -#include "platform/impl/g3/pipe.h" - -namespace location { -namespace nearby { -namespace g3 { - -class WifiLanMediumV2; - -class WifiLanSocketV2 : public api::WifiLanSocketV2 { - public: - WifiLanSocketV2() = default; - ~WifiLanSocketV2() override; - - // Connect to another WifiLanSocket, to form a functional low-level channel. - // from this point on, and until Close is called, connection exists. - void Connect(WifiLanSocketV2& other) ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns the InputStream of this connected WifiLanSocket. - InputStream& GetInputStream() override ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns the OutputStream of this connected WifiLanSocket. - // This stream is for local side to write. - OutputStream& GetOutputStream() override ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns address of a remote WifiLanSocket or nullptr. - WifiLanSocketV2* GetRemoteSocket() ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns true if connection exists to the (possibly closed) remote socket. - bool IsConnected() const ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns true if socket is closed. - bool IsClosed() const ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns Exception::kIo on error, Exception::kSuccess otherwise. - Exception Close() override ABSL_LOCKS_EXCLUDED(mutex_); - - private: - void DoClose() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Returns true if connection exists to the (possibly closed) remote socket. - bool IsConnectedLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - // Returns InputStream of our side of a connection. - // This is what the remote side is supposed to read from. - // This is a helper for GetInputStream() method. - InputStream& GetLocalInputStream() ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns OutputStream of our side of a connection. - // This is what the local size is supposed to write to. - // This is a helper for GetOutputStream() method. - OutputStream& GetLocalOutputStream() ABSL_LOCKS_EXCLUDED(mutex_); - - // Output pipe is initialized by constructor, it remains always valid, until - // it is closed. it represents output part of a local socket. Input part of a - // local socket comes from the peer socket, after connection. - std::shared_ptr output_{new Pipe}; - std::shared_ptr input_; - mutable absl::Mutex mutex_; - WifiLanSocketV2* remote_socket_ ABSL_GUARDED_BY(mutex_) = nullptr; - bool closed_ ABSL_GUARDED_BY(mutex_) = false; -}; - -class WifiLanServerSocketV2 : public api::WifiLanServerSocketV2 { - public: - static std::string GetName(const std::string& ip_address, int port); - - ~WifiLanServerSocketV2() override; - - // Gets ip address. - std::string GetIPAddress() const override ABSL_LOCKS_EXCLUDED(mutex_) { - absl::MutexLock lock(&mutex_); - return ip_address_; - } - - // Sets the ip address. - void SetIPAddress(const std::string& ip_address) ABSL_LOCKS_EXCLUDED(mutex_) { - absl::MutexLock lock(&mutex_); - ip_address_ = ip_address; - } - - // Gets the port. - int GetPort() const override ABSL_LOCKS_EXCLUDED(mutex_) { - absl::MutexLock lock(&mutex_); - return port_; - } - - // Sets the port. - void SetPort(int port) ABSL_LOCKS_EXCLUDED(mutex_) { - absl::MutexLock lock(&mutex_); - port_ = port; - } - - // Blocks until either: - // - at least one incoming connection request is available, or - // - ServerSocket is closed. - // On success, returns connected socket, ready to exchange data. - // Returns nullptr on error. - // Once error is reported, it is permanent, and ServerSocket has to be closed. - // - // Called by the server side of a connection. - // Returns WifiLanSocket to the server side. - // If not null, returned socket is connected to its remote (client-side) peer. - std::unique_ptr Accept() override - ABSL_LOCKS_EXCLUDED(mutex_); - - // Blocks until either: - // - connection is available, or - // - server socket is closed, or - // - error happens. - // - // Called by the client side of a connection. - // Returns true, if socket is successfully connected. - bool Connect(WifiLanSocketV2& socket) ABSL_LOCKS_EXCLUDED(mutex_); - - // Called by the server side of a connection before passing ownership of - // WifiLanServerSocker to user, to track validity of a pointer to this - // server socket. - void SetCloseNotifier(std::function notifier) - ABSL_LOCKS_EXCLUDED(mutex_); - - // Returns Exception::kIo on error, Exception::kSuccess otherwise. - // Calls close_notifier if it was previously set, and marks socket as closed. - Exception Close() override ABSL_LOCKS_EXCLUDED(mutex_); - - private: - Exception DoClose() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - - mutable absl::Mutex mutex_; - std::string ip_address_ ABSL_GUARDED_BY(mutex_); - int port_ ABSL_GUARDED_BY(mutex_); - absl::CondVar cond_; - absl::flat_hash_set pending_sockets_ - ABSL_GUARDED_BY(mutex_); - std::function close_notifier_ ABSL_GUARDED_BY(mutex_); - bool closed_ ABSL_GUARDED_BY(mutex_) = false; -}; - -// Container of operations that can be performed over the WifiLan medium. -class WifiLanMediumV2 : public api::WifiLanMediumV2 { - public: - WifiLanMediumV2(); - ~WifiLanMediumV2() override; - - // Starts WifiLan advertising. - // - // nsd_service_info - NsdServiceInfo data that's advertised through mDNS - // service. - // On success if the service is now advertising. - // On error if the service cannot start to advertise or the service type in - // NsdServiceInfo has been passed previously which StopAdvertising is not - // been called. - bool StartAdvertising(const NsdServiceInfo& nsd_service_info) override - ABSL_LOCKS_EXCLUDED(mutex_); - - // Stops WifiLan advertising. - // - // nsd_service_info - NsdServiceInfo data that's advertised through mDNS - // service. - // On success if the service stops advertising. - // On error if the service cannot stop advertising or the service type in - // NsdServiceInfo cannot be found. - bool StopAdvertising(const NsdServiceInfo& nsd_service_info) override - ABSL_LOCKS_EXCLUDED(mutex_); - - // Starts the discovery of nearby WifiLan services. - // - // Returns true once the WifiLan discovery has been initiated. The - // service_type is associated with callback. - bool StartDiscovery(const std::string& service_type, - DiscoveredServiceCallback callback) override - ABSL_LOCKS_EXCLUDED(mutex_); - - // Stops the discovery of nearby WifiLan services. - // - // service_type - The one assigend in StartDiscovery. - // On success if service_type is matched to the callback and will be removed - // from the list. If list is empty then stops the WifiLan discovery - // service. - // On error if the service_type is not existed, then return immediately. - bool StopDiscovery(const std::string& service_type) override - ABSL_LOCKS_EXCLUDED(mutex_); - - // Connects to a WifiLan service. - // On success, returns a new WifiLanSocket. - // On error, returns nullptr. - std::unique_ptr ConnectToService( - const NsdServiceInfo& remote_service_info, - CancellationFlag* cancellation_flag) override; - - // Connects to a WifiLan service by ip address and port. - // On success, returns a new WifiLanSocket. - // On error, returns nullptr. - std::unique_ptr ConnectToService( - const std::string& ip_address, int port, - CancellationFlag* cancellation_flag) override; - - // Listens for incoming connection. - // - // port - A port number. - // 0 : use a random port. - // 1~65536 : open a server socket on that exact port. - // On success, returns a new WifiLanServerSocket. - // On error, returns nullptr. - std::unique_ptr ListenForService( - int port = 0) override; - - private: - struct AdvertisingInfo { - bool Empty() const { return service_types.empty(); } - void Clear() { service_types.clear(); } - void Add(const std::string& service_type) { - service_types.insert(service_type); - } - void Remove(const std::string& service_type) { - service_types.erase(service_type); - } - bool Existed(const std::string& service_type) const { - return service_types.contains(service_type); - } - - absl::flat_hash_set service_types; - }; - struct DiscoveringInfo { - bool Empty() const { return service_types.empty(); } - void Clear() { service_types.clear(); } - void Add(const std::string& service_type) { - service_types.insert(service_type); - } - void Remove(const std::string& service_type) { - service_types.erase(service_type); - } - bool Existed(const std::string& service_type) const { - return service_types.contains(service_type); - } - - absl::flat_hash_set service_types; - }; - - absl::Mutex mutex_; - AdvertisingInfo advertising_info_ ABSL_GUARDED_BY(mutex_); - DiscoveringInfo discovering_info_ ABSL_GUARDED_BY(mutex_); - absl::flat_hash_map server_sockets_ - ABSL_GUARDED_BY(mutex_); -}; - -} // namespace g3 -} // namespace nearby -} // namespace location - -#endif // PLATFORM_IMPL_G3_WIFI_LAN_V2_H_ diff --git a/cpp/platform/impl/windows/BUILD b/cpp/platform/impl/windows/BUILD index 8bd81cb8..603cb1ab 100644 --- a/cpp/platform/impl/windows/BUILD +++ b/cpp/platform/impl/windows/BUILD @@ -64,7 +64,6 @@ cc_library( "thread_pool.h", "webrtc.h", "wifi.h", - "wifi_lan.h", ], compatible_with = ["//buildenv/target:non_prod"], visibility = ["//visibility:private"], @@ -105,9 +104,6 @@ cc_library( "system_clock.cc", "thread_pool.cc", "utils.cc", - "wifi_lan_medium.cc", - "wifi_lan_nsd.cc", - "wifi_lan_socket.cc", ], compatible_with = ["//buildenv/target:non_prod"], copts = ["-Ithird_party/nearby_connections/cpp/platform/impl/windows/generated"], diff --git a/cpp/platform/impl/windows/platform.cc b/cpp/platform/impl/windows/platform.cc index 01bf64f1..d2b08779 100644 --- a/cpp/platform/impl/windows/platform.cc +++ b/cpp/platform/impl/windows/platform.cc @@ -34,7 +34,6 @@ #include "platform/impl/windows/submittable_executor.h" #include "platform/impl/windows/webrtc.h" #include "platform/impl/windows/wifi.h" -#include "platform/impl/windows/wifi_lan.h" namespace location { namespace nearby { @@ -141,13 +140,7 @@ std::unique_ptr ImplementationPlatform::CreateWifiMedium() { // TODO(b/184975123): replace with real implementation. std::unique_ptr ImplementationPlatform::CreateWifiLanMedium() { - return absl::make_unique(); -} - -// TODO(b/184975123): replace with real implementation. -std::unique_ptr -ImplementationPlatform::CreateWifiLanMediumV2() { - return std::unique_ptr(); + return std::unique_ptr(); } // TODO(b/184975123): replace with real implementation. diff --git a/cpp/platform/public/BUILD b/cpp/platform/public/BUILD index 79e0d389..d1e122de 100644 --- a/cpp/platform/public/BUILD +++ b/cpp/platform/public/BUILD @@ -78,7 +78,6 @@ cc_library( "bluetooth_classic.cc", "file.cc", "wifi_lan.cc", - "wifi_lan_v2.cc", ], hdrs = [ "ble.h", @@ -86,7 +85,6 @@ cc_library( "bluetooth_classic.h", "webrtc.h", "wifi_lan.h", - "wifi_lan_v2.h", ], compatible_with = ["//buildenv/target:non_prod"], copts = ["-DCORE_ADAPTER_DLL"], @@ -150,7 +148,6 @@ cc_test( "scheduled_executor_test.cc", "single_thread_executor_test.cc", "wifi_lan_test.cc", - "wifi_lan_test_v2.cc", ], copts = ["-DCORE_ADAPTER_DLL"], shard_count = 16, diff --git a/cpp/platform/public/wifi_lan.cc b/cpp/platform/public/wifi_lan.cc index 3b962a4b..fd2d0336 100644 --- a/cpp/platform/public/wifi_lan.cc +++ b/cpp/platform/public/wifi_lan.cc @@ -14,148 +14,132 @@ #include "platform/public/wifi_lan.h" -#include "platform/public/logging.h" #include "platform/public/mutex_lock.h" namespace location { namespace nearby { -bool WifiLanMedium::StartAdvertising(const std::string& service_id, - const NsdServiceInfo& nsd_service_info) { - return impl_->StartAdvertising(service_id, nsd_service_info); +bool WifiLanMedium::StartAdvertising(const NsdServiceInfo& nsd_service_info) { + return impl_->StartAdvertising(nsd_service_info); } -bool WifiLanMedium::StopAdvertising(const std::string& service_id) { - return impl_->StopAdvertising(service_id); +bool WifiLanMedium::StopAdvertising(const NsdServiceInfo& nsd_service_info) { + return impl_->StopAdvertising(nsd_service_info); } bool WifiLanMedium::StartDiscovery(const std::string& service_id, + const std::string& service_type, DiscoveredServiceCallback callback) { { MutexLock lock(&mutex_); - discovered_service_callback_ = std::move(callback); - services_.clear(); + if (discovery_callbacks_.contains(service_type)) { + NEARBY_LOGS(INFO) << "WifiLan Discovery already start with service_type=" + << service_type << "; impl=" << &GetImpl(); + return false; + } } - return impl_->StartDiscovery( - service_id, - { - .service_discovered_cb = - [this](api::WifiLanService& wifi_lan_service, - const std::string& service_id) { - MutexLock lock(&mutex_); - auto pair = services_.emplace( - &wifi_lan_service, - absl::make_unique()); - auto& context = *pair.first->second; - if (!pair.second) { - NEARBY_LOG(INFO, - "Discovering (again) service=%p, impl=%p, " - "service_info_name=%s", - &context.wifi_lan_service, &wifi_lan_service, - wifi_lan_service.GetServiceInfo() - .GetServiceName() - .c_str()); - return; - } else { - context.wifi_lan_service = WifiLanService(&wifi_lan_service); - NEARBY_LOG( - INFO, - "Discovering wifi_lan_service=%p, service_info_name=%s", - &wifi_lan_service, - wifi_lan_service.GetServiceInfo() - .GetServiceName() - .c_str()); - } - discovered_service_callback_.service_discovered_cb( - context.wifi_lan_service, service_id); - }, - .service_lost_cb = - [this](api::WifiLanService& wifi_lan_service, - const std::string& service_id) { - MutexLock lock(&mutex_); - if (services_.empty()) return; - auto context = services_.find(&wifi_lan_service); - if (context == services_.end()) return; - NEARBY_LOG(INFO, "Removing wifi_lan_service=%p, impl=%p", - &(context->second->wifi_lan_service), - &wifi_lan_service); - discovered_service_callback_.service_lost_cb( - context->second->wifi_lan_service, service_id); - }, - }); -} - -bool WifiLanMedium::StopDiscovery(const std::string& service_id) { + api::WifiLanMedium::DiscoveredServiceCallback api_callback = { + .service_discovered_cb = + [this](NsdServiceInfo service_info) { + MutexLock lock(&mutex_); + std::string service_type = service_info.GetServiceType(); + auto pair = discovery_services_.insert(service_type); + if (!pair.second) { + NEARBY_LOGS(INFO) + << "Discovering (again) service_info=" << &service_info + << ", service_type=" << service_type + << ", service_name=" << service_info.GetServiceName(); + return; + } + NEARBY_LOGS(INFO) + << "Adding service_info=" << &service_info + << ", service_type=" << service_type + << ", service_name=" << service_info.GetServiceName(); + // Callback service found. + const auto& it = discovery_callbacks_.find(service_type); + if (it != discovery_callbacks_.end()) { + std::string service_id = it->second->service_id; + DiscoveredServiceCallback medium_callback = + it->second->medium_callback; + medium_callback.service_discovered_cb(service_info, service_id); + } else { + NEARBY_LOGS(ERROR) + << "There is no callback found for service_type=" + << service_type; + } + }, + .service_lost_cb = + [this](NsdServiceInfo service_info) { + MutexLock lock(&mutex_); + std::string service_type = service_info.GetServiceType(); + auto item = discovery_services_.extract(service_type); + if (item.empty()) return; + NEARBY_LOGS(INFO) + << "Removing service_info=" << &service_info + << ", service_type=" << service_type + << ", service_info_name=" << service_info.GetServiceName(); + // Callback service lost. + const auto& it = discovery_callbacks_.find(service_type); + if (it != discovery_callbacks_.end()) { + std::string service_id = it->second->service_id; + DiscoveredServiceCallback medium_callback = + it->second->medium_callback; + medium_callback.service_lost_cb(service_info, service_id); + } + }, + }; { + // Insert callback to the map first no matter it succeeds or not. MutexLock lock(&mutex_); - discovered_service_callback_ = {}; - services_.clear(); - NEARBY_LOG(INFO, "WifiLan Discovery disabled: impl=%p", &GetImpl()); + auto pair = discovery_callbacks_.insert( + {service_type, absl::make_unique()}); + auto& context = *pair.first->second; + context.medium_callback = std::move(callback); + context.service_id = service_id; } - return impl_->StopDiscovery(service_id); -} -bool WifiLanMedium::StartAcceptingConnections( - const std::string& service_id, AcceptedConnectionCallback callback) { - { + bool success = impl_->StartDiscovery(service_type, std::move(api_callback)); + if (!success) { + // If failed, then revert back the insertion. MutexLock lock(&mutex_); - accepted_connection_callback_ = std::move(callback); + discovery_callbacks_.erase(service_type); } - return impl_->StartAcceptingConnections( - service_id, - { - .accepted_cb = - [this](api::WifiLanSocket& socket, - const std::string& service_id) { - MutexLock lock(&mutex_); - auto pair = sockets_.emplace( - &socket, absl::make_unique()); - auto& context = *pair.first->second; - if (!pair.second) { - NEARBY_LOG(INFO, "Accepting (again) socket=%p, impl=%p", - &context.socket, &socket); - } else { - context.socket = WifiLanSocket(&socket); - NEARBY_LOG(INFO, "Accepting socket=%p, impl=%p", - &context.socket, &socket); - } - accepted_connection_callback_.accepted_cb(context.socket, - service_id); - }, - }); + NEARBY_LOGS(INFO) << "WifiLan Discovery started for service_type=" + << service_type << ", impl=" << &GetImpl() + << ", success=" << success; + return success; } -bool WifiLanMedium::StopAcceptingConnections(const std::string& service_id) { - { - MutexLock lock(&mutex_); - accepted_connection_callback_ = {}; - sockets_.clear(); - NEARBY_LOG(INFO, "WifiLan accepted connection disabled: impl=%p", - &GetImpl()); +bool WifiLanMedium::StopDiscovery(const std::string& service_type) { + MutexLock lock(&mutex_); + if (!discovery_callbacks_.contains(service_type)) { + return false; } - return impl_->StopAcceptingConnections(service_id); + discovery_callbacks_.erase(service_type); + if (discovery_services_.contains(service_type)) { + discovery_services_.erase(service_type); + } + NEARBY_LOGS(INFO) << "WifiLan Discovery disabled for service_type=" + << service_type << ", impl=" << &GetImpl(); + return impl_->StopDiscovery(service_type); } -WifiLanSocket WifiLanMedium::Connect(WifiLanService& wifi_lan_service, - const std::string& service_id, - CancellationFlag* cancellation_flag) { - NEARBY_LOG( - INFO, - "WifiLanMedium::Connect: service=%p [impl=%p, service_info_name=%s]", - &wifi_lan_service, &wifi_lan_service.GetImpl(), - wifi_lan_service.GetServiceInfo().GetServiceName().c_str()); - return WifiLanSocket(impl_->Connect(wifi_lan_service.GetImpl(), service_id, - cancellation_flag)); +WifiLanSocket WifiLanMedium::ConnectToService( + const NsdServiceInfo& remote_service_info, + CancellationFlag* cancellation_flag) { + NEARBY_LOGS(INFO) << "WifiLanMedium::ConnectToService: remote_service_name=" + << remote_service_info.GetServiceName(); + return WifiLanSocket( + impl_->ConnectToService(remote_service_info, cancellation_flag)); } -WifiLanService WifiLanMedium::GetRemoteService(const std::string& ip_address, - int port) { - return WifiLanService(impl_->GetRemoteService(ip_address, port)); -} - -std::pair WifiLanMedium::GetCredentials( - const std::string& service_id) { - return impl_->GetCredentials(service_id); +WifiLanSocket WifiLanMedium::ConnectToService( + const std::string& ip_address, int port, + CancellationFlag* cancellation_flag) { + NEARBY_LOGS(INFO) << "WifiLanMedium::ConnectToService: ip address=" + << ip_address << ", port=" << port; + return WifiLanSocket( + impl_->ConnectToService(ip_address, port, cancellation_flag)); } } // namespace nearby diff --git a/cpp/platform/public/wifi_lan.h b/cpp/platform/public/wifi_lan.h index 9ebce4ce..9bf50926 100644 --- a/cpp/platform/public/wifi_lan.h +++ b/cpp/platform/public/wifi_lan.h @@ -23,37 +23,20 @@ #include "platform/base/input_stream.h" #include "platform/base/nsd_service_info.h" #include "platform/base/output_stream.h" +#include "platform/public/logging.h" #include "platform/public/mutex.h" namespace location { namespace nearby { -// Opaque wrapper over a WifiLan service which contains |NsdServiceInfo|. -class WifiLanService final { - public: - WifiLanService() = default; - WifiLanService(const WifiLanService&) = default; - WifiLanService& operator=(const WifiLanService&) = default; - explicit WifiLanService(api::WifiLanService* service) : impl_(service) {} - ~WifiLanService() = default; - - NsdServiceInfo GetServiceInfo() const { return impl_->GetServiceInfo(); } - api::WifiLanService& GetImpl() { return *impl_; } - bool IsValid() const { return impl_ != nullptr; } - - private: - api::WifiLanService* impl_; -}; - class WifiLanSocket final { public: WifiLanSocket() = default; WifiLanSocket(const WifiLanSocket&) = default; WifiLanSocket& operator=(const WifiLanSocket&) = default; - explicit WifiLanSocket(api::WifiLanSocket* socket) : impl_(socket) {} - explicit WifiLanSocket(std::unique_ptr socket) - : impl_(socket.release()) {} ~WifiLanSocket() = default; + explicit WifiLanSocket(std::unique_ptr socket) + : impl_(std::move(socket)) {} // Returns the InputStream of the WifiLanSocket. // On error, returned stream will report Exception::kIo on any operation. @@ -72,10 +55,6 @@ class WifiLanSocket final { // Returns Exception::kIo on error, Exception::kSuccess otherwise. Exception Close() { return impl_->Close(); } - WifiLanService GetRemoteWifiLanService() { - return WifiLanService(impl_->GetRemoteWifiLanService()); - } - // Returns true if a socket is usable. If this method returns false, // it is not safe to call any other method. // NOTE(socket validity): @@ -98,84 +77,126 @@ class WifiLanSocket final { std::shared_ptr impl_; }; +class WifiLanServerSocket final { + public: + WifiLanServerSocket() = default; + WifiLanServerSocket(const WifiLanServerSocket&) = default; + WifiLanServerSocket& operator=(const WifiLanServerSocket&) = default; + ~WifiLanServerSocket() = default; + explicit WifiLanServerSocket(std::unique_ptr socket) + : impl_(std::move(socket)) {} + + // Returns ip address. + std::string GetIPAddress() { return impl_->GetIPAddress(); } + + // Returns port. + int GetPort() { return impl_->GetPort(); } + + // Blocks until either: + // - at least one incoming connection request is available, or + // - ServerSocket is closed. + // On success, returns connected socket, ready to exchange data. + // Returns nullptr on error. + // Once error is reported, it is permanent, and ServerSocket has to be closed. + WifiLanSocket Accept() { + std::unique_ptr socket = impl_->Accept(); + if (!socket) { + NEARBY_LOGS(INFO) + << "WifiLanServerSocket Accept() failed on server socket: " << this; + } + return WifiLanSocket(std::move(socket)); + } + + // Returns Exception::kIo on error, Exception::kSuccess otherwise. + Exception Close() { + NEARBY_LOGS(INFO) << "WifiLanServerSocket Closing:: " << this; + return impl_->Close(); + } + + bool IsValid() const { return impl_ != nullptr; } + api::WifiLanServerSocket& GetImpl() { return *impl_; } + + private: + std::shared_ptr impl_; +}; + // Container of operations that can be performed over the WifiLan medium. -class WifiLanMedium final { +class WifiLanMedium { public: using Platform = api::ImplementationPlatform; struct DiscoveredServiceCallback { - std::function + std::function service_discovered_cb = - DefaultCallback(); - std::function - service_lost_cb = - DefaultCallback(); + DefaultCallback(); + std::function + service_lost_cb = DefaultCallback(); }; - struct ServiceDiscoveryInfo { - WifiLanService wifi_lan_service; - }; - - struct AcceptedConnectionCallback { - std::function - accepted_cb = DefaultCallback(); - }; - - struct AcceptedConnectionInfo { - WifiLanSocket socket; + struct DiscoveryCallbackInfo { + std::string service_id; + DiscoveredServiceCallback medium_callback; }; WifiLanMedium() : impl_(Platform::CreateWifiLanMedium()) {} ~WifiLanMedium() = default; - bool StartAdvertising(const std::string& service_id, - const NsdServiceInfo& nsd_service_info); - bool StopAdvertising(const std::string& service_id); + // Starts WifiLan advertising. + // + // nsd_service_info - NsdServiceInfo data that's advertised through mDNS + // service. + // On success if the service is now advertising. + // On error if the service cannot start to advertise or the nsd_type in + // NsdServiceInfo has been passed previously which StopAdvertising is not + // been called. + bool StartAdvertising(const NsdServiceInfo& nsd_service_info); + + // Stops WifiLan advertising. + // + // nsd_service_info - NsdServiceInfo data that's advertised through mDNS + // service. + // On success if the service stops advertising. + // On error if the service cannot stop advertising or the nsd_type in + // NsdServiceInfo cannot be found. + bool StopAdvertising(const NsdServiceInfo& nsd_service_info); // Returns true once the WifiLan discovery has been initiated. bool StartDiscovery(const std::string& service_id, + const std::string& service_type, DiscoveredServiceCallback callback); - // Returns true once WifiLan discovery for service_id is well and truly - // stopped; after this returns, there must be no more invocations of the - // DiscoveredServiceCallback passed in to StartDiscovery() for service_id. - bool StopDiscovery(const std::string& service_id); + // Returns true once service_type is associated to existing callback. If the + // callback is the last found then WifiLan discovery will be stopped. + bool StopDiscovery(const std::string& service_type); - // Returns true once WifiLan socket connection requests to service_id can be - // accepted. - bool StartAcceptingConnections(const std::string& service_id, - AcceptedConnectionCallback callback); - bool StopAcceptingConnections(const std::string& service_id); + // Returns a new WifiLanSocket. + // On Success, WifiLanSocket::IsValid() returns true. + WifiLanSocket ConnectToService(const NsdServiceInfo& remote_service_info, + CancellationFlag* cancellation_flag); - // Returns a new WifiLanSocket. On Success, WifiLanSocket::IsValid() - // returns true. - WifiLanSocket Connect(WifiLanService& wifi_lan_service, - const std::string& service_id, - CancellationFlag* cancellation_flag); + // Returns a new WifiLanSocket by ip address and port. + // On Success, WifiLanSocket::IsValid()returns true. + WifiLanSocket ConnectToService(const std::string& ip_address, int port, + CancellationFlag* cancellation_flag); + + // Returns a new WifiLanServerSocket. + // On Success, WifiLanServerSocket::IsValid() returns true. + WifiLanServerSocket ListenForService(int port = 0) { + return WifiLanServerSocket(impl_->ListenForService(port)); + } bool IsValid() const { return impl_ != nullptr; } api::WifiLanMedium& GetImpl() { return *impl_; } - WifiLanService GetRemoteService(const std::string& ip_address, int port); - - std::pair GetCredentials(const std::string& service_id); - private: Mutex mutex_; std::unique_ptr impl_; - absl::flat_hash_map> - services_ ABSL_GUARDED_BY(mutex_); - absl::flat_hash_map> - sockets_ ABSL_GUARDED_BY(mutex_); - DiscoveredServiceCallback discovered_service_callback_ - ABSL_GUARDED_BY(mutex_); - AcceptedConnectionCallback accepted_connection_callback_ - ABSL_GUARDED_BY(mutex_); + absl::flat_hash_map> + discovery_callbacks_ ABSL_GUARDED_BY(mutex_); + absl::flat_hash_set discovery_services_ ABSL_GUARDED_BY(mutex_); }; } // namespace nearby diff --git a/cpp/platform/public/wifi_lan_test.cc b/cpp/platform/public/wifi_lan_test.cc index b46a8bc0..93eb0a54 100644 --- a/cpp/platform/public/wifi_lan_test.cc +++ b/cpp/platform/public/wifi_lan_test.cc @@ -38,7 +38,9 @@ constexpr FeatureFlags kTestCases[] = { }, }; -constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; +constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); +constexpr absl::string_view kServiceId{"service_id"}; +constexpr absl::string_view kServiceType{"_service.tcp_"}; constexpr absl::string_view kServiceInfoName{"Simulated service info name"}; constexpr absl::string_view kEndpointName{"Simulated endpoint name"}; constexpr absl::string_view kEndpointInfoKey{"n"}; @@ -46,71 +48,81 @@ constexpr absl::string_view kEndpointInfoKey{"n"}; class WifiLanMediumTest : public ::testing::TestWithParam { protected: using DiscoveredServiceCallback = WifiLanMedium::DiscoveredServiceCallback; - using AcceptedConnectionCallback = WifiLanMedium::AcceptedConnectionCallback; WifiLanMediumTest() { env_.Stop(); } MediumEnvironment& env_{MediumEnvironment::Instance()}; }; -TEST_P(WifiLanMediumTest, CanStartAcceptingConnectionsAndConnect) { +TEST_P(WifiLanMediumTest, CanConnectToService) { FeatureFlags feature_flags = GetParam(); env_.SetFeatureFlags(feature_flags); env_.Start(); - WifiLanMedium wifi_a; - WifiLanMedium wifi_b; - std::string service_id(kServiceID); - std::string service_info_name{kServiceInfoName}; - std::string endpoint_info_name{kEndpointName}; - CountDownLatch found_latch(1); - CountDownLatch accepted_latch(1); - CancellationFlag flag; + WifiLanMedium wifi_lan_a; + WifiLanMedium wifi_lan_b; + std::string service_id(kServiceId); + std::string service_type(kServiceType); + std::string service_info_name(kServiceInfoName); + std::string endpoint_info_name(kEndpointName); + CountDownLatch discovered_latch(1); + CountDownLatch lost_latch(1); - WifiLanService* discovered_service = nullptr; - wifi_a.StartDiscovery( - service_id, - DiscoveredServiceCallback{ - .service_discovered_cb = - [&found_latch, &discovered_service]( - WifiLanService& service, const std::string& service_id) { - NEARBY_LOG(INFO, "Service discovered: %s, %p", - service.GetServiceInfo().GetServiceName().c_str(), - &service); - discovered_service = &service; - found_latch.CountDown(); - }, - }); + WifiLanServerSocket server_socket = wifi_lan_b.ListenForService(); + EXPECT_TRUE(server_socket.IsValid()); NsdServiceInfo nsd_service_info; nsd_service_info.SetServiceName(service_info_name); nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), endpoint_info_name); - wifi_b.StartAdvertising(service_id, nsd_service_info); - wifi_b.StartAcceptingConnections( - service_id, - AcceptedConnectionCallback{ - .accepted_cb = [&accepted_latch](WifiLanSocket socket, - const std::string& service_id) { - NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s", - &socket, service_id.c_str()); - accepted_latch.CountDown(); - }}); - EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result()); + nsd_service_info.SetServiceType(service_type); + nsd_service_info.SetIPAddress(server_socket.GetIPAddress()); + nsd_service_info.SetPort(server_socket.GetPort()); + wifi_lan_b.StartAdvertising(nsd_service_info); + NsdServiceInfo discovered_service_info; + wifi_lan_a.StartDiscovery( + service_id, service_type, + DiscoveredServiceCallback{ + .service_discovered_cb = + [&discovered_latch, &discovered_service_info]( + NsdServiceInfo service_info, + const std::string& service_type) { + discovered_service_info = service_info; + discovered_latch.CountDown(); + }, + .service_lost_cb = + [&lost_latch](NsdServiceInfo service_info, + const std::string& service_type) { + lost_latch.CountDown(); + }, + }); + EXPECT_TRUE(discovered_latch.Await(absl::Milliseconds(1000)).result()); WifiLanSocket socket_a; + WifiLanSocket socket_b; EXPECT_FALSE(socket_a.IsValid()); + EXPECT_FALSE(socket_b.IsValid()); { + CancellationFlag flag; + SingleThreadExecutor server_executor; SingleThreadExecutor client_executor; - client_executor.Execute( - [&wifi_a, &socket_a, discovered_service, &service_id, &flag]() { - socket_a = wifi_a.Connect(*discovered_service, service_id, &flag); - }); + client_executor.Execute([&wifi_lan_a, &socket_a, + discovered_service_info = discovered_service_info, + service_type, &server_socket, &flag]() { + socket_a = wifi_lan_a.ConnectToService(discovered_service_info, &flag); + if (!socket_a.IsValid()) { + server_socket.Close(); + } + }); + server_executor.Execute([&socket_b, &server_socket]() { + socket_b = server_socket.Accept(); + if (!socket_b.IsValid()) { + server_socket.Close(); + } + }); } - EXPECT_TRUE(accepted_latch.Await(absl::Milliseconds(1000)).result()); EXPECT_TRUE(socket_a.IsValid()); - wifi_b.StopAcceptingConnections(service_id); - wifi_b.StopAdvertising(service_id); - wifi_a.StopDiscovery(service_id); + EXPECT_TRUE(socket_b.IsValid()); + server_socket.Close(); env_.Stop(); } @@ -118,68 +130,77 @@ TEST_P(WifiLanMediumTest, CanCancelConnect) { FeatureFlags feature_flags = GetParam(); env_.SetFeatureFlags(feature_flags); env_.Start(); - WifiLanMedium wifi_a; - WifiLanMedium wifi_b; - std::string service_id(kServiceID); - std::string service_info_name{kServiceInfoName}; - std::string endpoint_info_name{kEndpointName}; - CountDownLatch found_latch(1); - CountDownLatch accepted_latch(1); - CancellationFlag flag(true); + WifiLanMedium wifi_lan_a; + WifiLanMedium wifi_lan_b; + std::string service_id(kServiceId); + std::string service_type(kServiceType); + std::string service_info_name(kServiceInfoName); + std::string endpoint_info_name(kEndpointName); + CountDownLatch discovered_latch(1); + CountDownLatch lost_latch(1); - WifiLanService* discovered_service = nullptr; - wifi_a.StartDiscovery( - service_id, - DiscoveredServiceCallback{ - .service_discovered_cb = - [&found_latch, &discovered_service]( - WifiLanService& service, const std::string& service_id) { - NEARBY_LOG(INFO, "Service discovered: %s, %p", - service.GetServiceInfo().GetServiceName().c_str(), - &service); - discovered_service = &service; - found_latch.CountDown(); - }, - }); + WifiLanServerSocket server_socket = wifi_lan_b.ListenForService(); + EXPECT_TRUE(server_socket.IsValid()); NsdServiceInfo nsd_service_info; nsd_service_info.SetServiceName(service_info_name); nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), endpoint_info_name); - wifi_b.StartAdvertising(service_id, nsd_service_info); - wifi_b.StartAcceptingConnections( - service_id, - AcceptedConnectionCallback{ - .accepted_cb = [&accepted_latch](WifiLanSocket socket, - const std::string& service_id) { - NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s", - &socket, service_id.c_str()); - accepted_latch.CountDown(); - }}); - EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result()); + nsd_service_info.SetServiceType(service_type); + nsd_service_info.SetIPAddress(server_socket.GetIPAddress()); + nsd_service_info.SetPort(server_socket.GetPort()); + wifi_lan_b.StartAdvertising(nsd_service_info); + NsdServiceInfo discovered_service_info; + wifi_lan_a.StartDiscovery( + service_id, service_type, + DiscoveredServiceCallback{ + .service_discovered_cb = + [&discovered_latch, &discovered_service_info]( + NsdServiceInfo service_info, + const std::string& service_type) { + discovered_service_info = service_info; + discovered_latch.CountDown(); + }, + .service_lost_cb = + [&lost_latch](NsdServiceInfo service_info, + const std::string& service_type) { + lost_latch.CountDown(); + }, + }); + EXPECT_TRUE(discovered_latch.Await(absl::Milliseconds(1000)).result()); WifiLanSocket socket_a; + WifiLanSocket socket_b; EXPECT_FALSE(socket_a.IsValid()); + EXPECT_FALSE(socket_b.IsValid()); { + CancellationFlag flag(true); + SingleThreadExecutor server_executor; SingleThreadExecutor client_executor; - client_executor.Execute( - [&wifi_a, &socket_a, discovered_service, &service_id, &flag]() { - socket_a = wifi_a.Connect(*discovered_service, service_id, &flag); - }); + client_executor.Execute([&wifi_lan_a, &socket_a, + discovered_service_info = discovered_service_info, + service_type, &server_socket, &flag]() { + socket_a = wifi_lan_a.ConnectToService(discovered_service_info, &flag); + if (!socket_a.IsValid()) { + server_socket.Close(); + } + }); + server_executor.Execute([&socket_b, &server_socket]() { + socket_b = server_socket.Accept(); + if (!socket_b.IsValid()) { + server_socket.Close(); + } + }); } - // If FeatureFlag is disabled, Cancelled is false as no-op. if (!feature_flags.enable_cancellation_flag) { - EXPECT_TRUE(accepted_latch.Await(absl::Milliseconds(1000)).result()); EXPECT_TRUE(socket_a.IsValid()); + EXPECT_TRUE(socket_b.IsValid()); } else { - EXPECT_FALSE(accepted_latch.Await(absl::Milliseconds(1000)).result()); EXPECT_FALSE(socket_a.IsValid()); + EXPECT_FALSE(socket_b.IsValid()); } - - wifi_b.StopAcceptingConnections(service_id); - wifi_b.StopAdvertising(service_id); - wifi_a.StopDiscovery(service_id); + server_socket.Close(); env_.Stop(); } @@ -188,117 +209,179 @@ INSTANTIATE_TEST_SUITE_P(ParametrisedWifiLanMediumTest, WifiLanMediumTest, TEST_F(WifiLanMediumTest, ConstructorDestructorWorks) { env_.Start(); - WifiLanMedium wifi_a; - WifiLanMedium wifi_b; + WifiLanMedium wifi_lan_a; + WifiLanMedium wifi_lan_b; // Make sure we can create functional mediums. - ASSERT_TRUE(wifi_a.IsValid()); - ASSERT_TRUE(wifi_b.IsValid()); + ASSERT_TRUE(wifi_lan_a.IsValid()); + ASSERT_TRUE(wifi_lan_b.IsValid()); // Make sure we can create 2 distinct mediums. - EXPECT_NE(&wifi_a.GetImpl(), &wifi_b.GetImpl()); + EXPECT_NE(&wifi_lan_a.GetImpl(), &wifi_lan_b.GetImpl()); env_.Stop(); } TEST_F(WifiLanMediumTest, CanStartAdvertising) { env_.Start(); - WifiLanMedium wifi_a; - WifiLanMedium wifi_b; - std::string service_id(kServiceID); - std::string service_info_name{kServiceInfoName}; - std::string endpoint_info_name{kEndpointName}; - CountDownLatch found_latch(1); + WifiLanMedium wifi_lan_a; + std::string service_type(kServiceType); + std::string service_info_name(kServiceInfoName); + std::string endpoint_info_name(kEndpointName); + + WifiLanServerSocket server_socket = wifi_lan_a.ListenForService(); + EXPECT_TRUE(server_socket.IsValid()); NsdServiceInfo nsd_service_info; nsd_service_info.SetServiceName(service_info_name); nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), endpoint_info_name); - wifi_a.StartAdvertising(service_id, nsd_service_info); + nsd_service_info.SetServiceType(service_type); + EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info)); + EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info)); + env_.Stop(); +} - EXPECT_TRUE(wifi_b.StartDiscovery( - service_id, DiscoveredServiceCallback{ - .service_discovered_cb = - [&found_latch](WifiLanService& service, - const std::string& service_id) { - found_latch.CountDown(); - }, - })); - EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result()); - EXPECT_TRUE(wifi_a.StopAdvertising(service_id)); - EXPECT_TRUE(wifi_b.StopDiscovery(service_id)); +TEST_F(WifiLanMediumTest, CanStartMultipleAdvertising) { + env_.Start(); + WifiLanMedium wifi_lan_a; + std::string service_type_1(kServiceType); + std::string service_type_2("_service_1.tcp_"); + std::string service_info_name_1(kServiceInfoName); + std::string service_info_name_2(kServiceInfoName); + std::string endpoint_info_name(kEndpointName); + + WifiLanServerSocket server_socket = wifi_lan_a.ListenForService(); + EXPECT_TRUE(server_socket.IsValid()); + + NsdServiceInfo nsd_service_info_1; + nsd_service_info_1.SetServiceName(service_info_name_1); + nsd_service_info_1.SetTxtRecord(std::string(kEndpointInfoKey), + endpoint_info_name); + nsd_service_info_1.SetServiceType(service_type_1); + + NsdServiceInfo nsd_service_info_2; + nsd_service_info_2.SetServiceName(service_info_name_2); + nsd_service_info_2.SetTxtRecord(std::string(kEndpointInfoKey), + endpoint_info_name); + nsd_service_info_2.SetServiceType(service_type_2); + + EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info_1)); + EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info_2)); + EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info_1)); + EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info_2)); env_.Stop(); } TEST_F(WifiLanMediumTest, CanStartDiscovery) { env_.Start(); - WifiLanMedium wifi_a; - WifiLanMedium wifi_b; - std::string service_id(kServiceID); - std::string service_info_name{kServiceInfoName}; - std::string endpoint_info_name{kEndpointName}; - CountDownLatch found_latch(1); - CountDownLatch lost_latch(1); + WifiLanMedium wifi_lan_a; + std::string service_id(kServiceId); + std::string service_type(kServiceType); - wifi_a.StartDiscovery(service_id, - DiscoveredServiceCallback{ - .service_discovered_cb = - [&found_latch](WifiLanService& service, - absl::string_view service_id) { - found_latch.CountDown(); - }, - .service_lost_cb = - [&lost_latch](WifiLanService& service, - absl::string_view service_id) { - lost_latch.CountDown(); - }, - }); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - EXPECT_TRUE(wifi_b.StartAdvertising(service_id, nsd_service_info)); - EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result()); - EXPECT_TRUE(wifi_b.StopAdvertising(service_id)); - EXPECT_TRUE(lost_latch.Await(absl::Milliseconds(1000)).result()); - EXPECT_TRUE(wifi_a.StopDiscovery(service_id)); + EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id, service_type, + DiscoveredServiceCallback{})); + EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type)); env_.Stop(); } -TEST_F(WifiLanMediumTest, CanStopDiscovery) { +TEST_F(WifiLanMediumTest, CanStartMultipleDiscovery) { env_.Start(); - WifiLanMedium wifi_a; - WifiLanMedium wifi_b; - std::string service_id(kServiceID); - std::string service_info_name{kServiceInfoName}; - std::string endpoint_info_name{kEndpointName}; - CountDownLatch found_latch(1); + WifiLanMedium wifi_lan_a; + std::string service_id_1(kServiceId); + std::string service_id_2("service_id_2"); + std::string service_type_1(kServiceType); + std::string service_type_2("_service_1.tcp_"); + + EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id_1, service_type_1, + DiscoveredServiceCallback{})); + EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id_2, service_type_2, + DiscoveredServiceCallback{})); + EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type_1)); + EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type_2)); + env_.Stop(); +} + +TEST_F(WifiLanMediumTest, CanAdvertiseThatOtherMediumDiscover) { + env_.Start(); + WifiLanMedium wifi_lan_a; + WifiLanMedium wifi_lan_b; + std::string service_id(kServiceId); + std::string service_type(kServiceType); + std::string service_info_name(kServiceInfoName); + std::string endpoint_info_name(kEndpointName); + CountDownLatch discovered_latch(1); CountDownLatch lost_latch(1); - wifi_a.StartDiscovery(service_id, - DiscoveredServiceCallback{ - .service_discovered_cb = - [&found_latch](WifiLanService& service, - absl::string_view service_id) { - found_latch.CountDown(); - }, - .service_lost_cb = - [&lost_latch](WifiLanService& service, - absl::string_view service_id) { - lost_latch.CountDown(); - }, - }); + wifi_lan_b.StartDiscovery( + service_id, service_type, + DiscoveredServiceCallback{ + .service_discovered_cb = + [&discovered_latch](NsdServiceInfo service_info, + const std::string& service_type) { + discovered_latch.CountDown(); + }, + .service_lost_cb = + [&lost_latch](NsdServiceInfo service_info, + const std::string& service_id) { + lost_latch.CountDown(); + }, + }); + + WifiLanServerSocket server_socket = wifi_lan_a.ListenForService(); + EXPECT_TRUE(server_socket.IsValid()); NsdServiceInfo nsd_service_info; nsd_service_info.SetServiceName(service_info_name); nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), endpoint_info_name); + nsd_service_info.SetServiceType(service_type); + EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info)); + EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info)); + EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(wifi_lan_b.StopDiscovery(service_type)); + env_.Stop(); +} - EXPECT_TRUE(wifi_b.StartAdvertising(service_id, nsd_service_info)); - EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result()); - EXPECT_TRUE(wifi_a.StopDiscovery(service_id)); - EXPECT_TRUE(wifi_b.StopAdvertising(service_id)); - EXPECT_FALSE(lost_latch.Await(absl::Milliseconds(1000)).result()); +TEST_F(WifiLanMediumTest, CanDiscoverThatOtherMediumAdvertise) { + env_.Start(); + WifiLanMedium wifi_lan_a; + WifiLanMedium wifi_lan_b; + std::string service_id(kServiceId); + std::string service_type(kServiceType); + std::string service_info_name(kServiceInfoName); + std::string endpoint_info_name(kEndpointName); + CountDownLatch discovered_latch(1); + CountDownLatch lost_latch(1); + + wifi_lan_a.StartDiscovery( + service_id, service_type, + DiscoveredServiceCallback{ + .service_discovered_cb = + [&discovered_latch](NsdServiceInfo service_info, + const std::string& service_type) { + discovered_latch.CountDown(); + }, + .service_lost_cb = + [&lost_latch](NsdServiceInfo service_info, + const std::string& service_type) { + lost_latch.CountDown(); + }, + }); + + WifiLanServerSocket server_socket = wifi_lan_a.ListenForService(); + EXPECT_TRUE(server_socket.IsValid()); + + NsdServiceInfo nsd_service_info; + nsd_service_info.SetServiceName(service_info_name); + nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), + endpoint_info_name); + nsd_service_info.SetServiceType(service_type); + EXPECT_TRUE(wifi_lan_b.StartAdvertising(nsd_service_info)); + EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(wifi_lan_b.StopAdvertising(nsd_service_info)); + EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type)); env_.Stop(); } diff --git a/cpp/platform/public/wifi_lan_test_v2.cc b/cpp/platform/public/wifi_lan_test_v2.cc deleted file mode 100644 index 57eafd72..00000000 --- a/cpp/platform/public/wifi_lan_test_v2.cc +++ /dev/null @@ -1,389 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "platform/base/medium_environment.h" -#include "platform/public/count_down_latch.h" -#include "platform/public/logging.h" -#include "platform/public/wifi_lan_v2.h" - -namespace location { -namespace nearby { -namespace { - -using FeatureFlags = FeatureFlags::Flags; - -constexpr FeatureFlags kTestCases[] = { - FeatureFlags{ - .enable_cancellation_flag = true, - }, - FeatureFlags{ - .enable_cancellation_flag = false, - }, -}; - -constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); -constexpr absl::string_view kServiceId{"service_id"}; -constexpr absl::string_view kServiceType{"_service.tcp_"}; -constexpr absl::string_view kServiceInfoName{"Simulated service info name"}; -constexpr absl::string_view kEndpointName{"Simulated endpoint name"}; -constexpr absl::string_view kEndpointInfoKey{"n"}; - -class WifiLanMediumV2Test : public ::testing::TestWithParam { - protected: - using DiscoveredServiceCallback = WifiLanMediumV2::DiscoveredServiceCallback; - - WifiLanMediumV2Test() { env_.Stop(); } - - MediumEnvironment& env_{MediumEnvironment::Instance()}; -}; - -TEST_P(WifiLanMediumV2Test, CanConnectToService) { - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - env_.Start(); - WifiLanMediumV2 wifi_lan_a; - WifiLanMediumV2 wifi_lan_b; - std::string service_id(kServiceId); - std::string service_type(kServiceType); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch lost_latch(1); - - WifiLanServerSocketV2 server_socket = wifi_lan_b.ListenForService(); - EXPECT_TRUE(server_socket.IsValid()); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - nsd_service_info.SetServiceType(service_type); - nsd_service_info.SetIPAddress(server_socket.GetIPAddress()); - nsd_service_info.SetPort(server_socket.GetPort()); - wifi_lan_b.StartAdvertising(nsd_service_info); - - NsdServiceInfo discovered_service_info; - wifi_lan_a.StartDiscovery( - service_id, service_type, - DiscoveredServiceCallback{ - .service_discovered_cb = - [&discovered_latch, &discovered_service_info]( - NsdServiceInfo service_info, - const std::string& service_type) { - discovered_service_info = service_info; - discovered_latch.CountDown(); - }, - .service_lost_cb = - [&lost_latch](NsdServiceInfo service_info, - const std::string& service_type) { - lost_latch.CountDown(); - }, - }); - EXPECT_TRUE(discovered_latch.Await(absl::Milliseconds(1000)).result()); - WifiLanSocketV2 socket_a; - WifiLanSocketV2 socket_b; - EXPECT_FALSE(socket_a.IsValid()); - EXPECT_FALSE(socket_b.IsValid()); - { - CancellationFlag flag; - SingleThreadExecutor server_executor; - SingleThreadExecutor client_executor; - client_executor.Execute([&wifi_lan_a, &socket_a, - discovered_service_info = discovered_service_info, - service_type, &server_socket, &flag]() { - socket_a = wifi_lan_a.ConnectToService(discovered_service_info, &flag); - if (!socket_a.IsValid()) { - server_socket.Close(); - } - }); - server_executor.Execute([&socket_b, &server_socket]() { - socket_b = server_socket.Accept(); - if (!socket_b.IsValid()) { - server_socket.Close(); - } - }); - } - EXPECT_TRUE(socket_a.IsValid()); - EXPECT_TRUE(socket_b.IsValid()); - server_socket.Close(); - env_.Stop(); -} - -TEST_P(WifiLanMediumV2Test, CanCancelConnect) { - FeatureFlags feature_flags = GetParam(); - env_.SetFeatureFlags(feature_flags); - env_.Start(); - WifiLanMediumV2 wifi_lan_a; - WifiLanMediumV2 wifi_lan_b; - std::string service_id(kServiceId); - std::string service_type(kServiceType); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch lost_latch(1); - - WifiLanServerSocketV2 server_socket = wifi_lan_b.ListenForService(); - EXPECT_TRUE(server_socket.IsValid()); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - nsd_service_info.SetServiceType(service_type); - nsd_service_info.SetIPAddress(server_socket.GetIPAddress()); - nsd_service_info.SetPort(server_socket.GetPort()); - wifi_lan_b.StartAdvertising(nsd_service_info); - - NsdServiceInfo discovered_service_info; - wifi_lan_a.StartDiscovery( - service_id, service_type, - DiscoveredServiceCallback{ - .service_discovered_cb = - [&discovered_latch, &discovered_service_info]( - NsdServiceInfo service_info, - const std::string& service_type) { - discovered_service_info = service_info; - discovered_latch.CountDown(); - }, - .service_lost_cb = - [&lost_latch](NsdServiceInfo service_info, - const std::string& service_type) { - lost_latch.CountDown(); - }, - }); - EXPECT_TRUE(discovered_latch.Await(absl::Milliseconds(1000)).result()); - WifiLanSocketV2 socket_a; - WifiLanSocketV2 socket_b; - EXPECT_FALSE(socket_a.IsValid()); - EXPECT_FALSE(socket_b.IsValid()); - { - CancellationFlag flag(true); - SingleThreadExecutor server_executor; - SingleThreadExecutor client_executor; - client_executor.Execute([&wifi_lan_a, &socket_a, - discovered_service_info = discovered_service_info, - service_type, &server_socket, &flag]() { - socket_a = wifi_lan_a.ConnectToService(discovered_service_info, &flag); - if (!socket_a.IsValid()) { - server_socket.Close(); - } - }); - server_executor.Execute([&socket_b, &server_socket]() { - socket_b = server_socket.Accept(); - if (!socket_b.IsValid()) { - server_socket.Close(); - } - }); - } - // If FeatureFlag is disabled, Cancelled is false as no-op. - if (!feature_flags.enable_cancellation_flag) { - EXPECT_TRUE(socket_a.IsValid()); - EXPECT_TRUE(socket_b.IsValid()); - } else { - EXPECT_FALSE(socket_a.IsValid()); - EXPECT_FALSE(socket_b.IsValid()); - } - server_socket.Close(); - env_.Stop(); -} - -INSTANTIATE_TEST_SUITE_P(ParametrisedWifiLanMediumTest, WifiLanMediumV2Test, - ::testing::ValuesIn(kTestCases)); - -TEST_F(WifiLanMediumV2Test, ConstructorDestructorWorks) { - env_.Start(); - WifiLanMediumV2 wifi_lan_a; - WifiLanMediumV2 wifi_lan_b; - - // Make sure we can create functional mediums. - ASSERT_TRUE(wifi_lan_a.IsValid()); - ASSERT_TRUE(wifi_lan_b.IsValid()); - - // Make sure we can create 2 distinct mediums. - EXPECT_NE(&wifi_lan_a.GetImpl(), &wifi_lan_b.GetImpl()); - env_.Stop(); -} - -TEST_F(WifiLanMediumV2Test, CanStartAdvertising) { - env_.Start(); - WifiLanMediumV2 wifi_lan_a; - std::string service_type(kServiceType); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - - WifiLanServerSocketV2 server_socket = wifi_lan_a.ListenForService(); - EXPECT_TRUE(server_socket.IsValid()); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - nsd_service_info.SetServiceType(service_type); - EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info)); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info)); - env_.Stop(); -} - -TEST_F(WifiLanMediumV2Test, CanStartMultipleAdvertising) { - env_.Start(); - WifiLanMediumV2 wifi_lan_a; - std::string service_type_1(kServiceType); - std::string service_type_2("_service_1.tcp_"); - std::string service_info_name_1(kServiceInfoName); - std::string service_info_name_2(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - - WifiLanServerSocketV2 server_socket = wifi_lan_a.ListenForService(); - EXPECT_TRUE(server_socket.IsValid()); - - NsdServiceInfo nsd_service_info_1; - nsd_service_info_1.SetServiceName(service_info_name_1); - nsd_service_info_1.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - nsd_service_info_1.SetServiceType(service_type_1); - - NsdServiceInfo nsd_service_info_2; - nsd_service_info_2.SetServiceName(service_info_name_2); - nsd_service_info_2.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - nsd_service_info_2.SetServiceType(service_type_2); - - EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info_1)); - EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info_2)); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info_1)); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info_2)); - env_.Stop(); -} - -TEST_F(WifiLanMediumV2Test, CanStartDiscovery) { - env_.Start(); - WifiLanMediumV2 wifi_lan_a; - std::string service_id(kServiceId); - std::string service_type(kServiceType); - - EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id, service_type, - DiscoveredServiceCallback{})); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type)); - env_.Stop(); -} - -TEST_F(WifiLanMediumV2Test, CanStartMultipleDiscovery) { - env_.Start(); - WifiLanMediumV2 wifi_lan_a; - std::string service_id_1(kServiceId); - std::string service_id_2("service_id_2"); - std::string service_type_1(kServiceType); - std::string service_type_2("_service_1.tcp_"); - - EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id_1, service_type_1, - DiscoveredServiceCallback{})); - EXPECT_TRUE(wifi_lan_a.StartDiscovery(service_id_2, service_type_2, - DiscoveredServiceCallback{})); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type_1)); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type_2)); - env_.Stop(); -} - -TEST_F(WifiLanMediumV2Test, CanAdvertiseThatOtherMediumDiscover) { - env_.Start(); - WifiLanMediumV2 wifi_lan_a; - WifiLanMediumV2 wifi_lan_b; - std::string service_id(kServiceId); - std::string service_type(kServiceType); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch lost_latch(1); - - wifi_lan_b.StartDiscovery( - service_id, service_type, - DiscoveredServiceCallback{ - .service_discovered_cb = - [&discovered_latch](NsdServiceInfo service_info, - const std::string& service_type) { - discovered_latch.CountDown(); - }, - .service_lost_cb = - [&lost_latch](NsdServiceInfo service_info, - const std::string& service_id) { - lost_latch.CountDown(); - }, - }); - - WifiLanServerSocketV2 server_socket = wifi_lan_a.ListenForService(); - EXPECT_TRUE(server_socket.IsValid()); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - nsd_service_info.SetServiceType(service_type); - EXPECT_TRUE(wifi_lan_a.StartAdvertising(nsd_service_info)); - EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_a.StopAdvertising(nsd_service_info)); - EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_b.StopDiscovery(service_type)); - env_.Stop(); -} - -TEST_F(WifiLanMediumV2Test, CanDiscoverThatOtherMediumAdvertise) { - env_.Start(); - WifiLanMediumV2 wifi_lan_a; - WifiLanMediumV2 wifi_lan_b; - std::string service_id(kServiceId); - std::string service_type(kServiceType); - std::string service_info_name(kServiceInfoName); - std::string endpoint_info_name(kEndpointName); - CountDownLatch discovered_latch(1); - CountDownLatch lost_latch(1); - - wifi_lan_a.StartDiscovery( - service_id, service_type, - DiscoveredServiceCallback{ - .service_discovered_cb = - [&discovered_latch](NsdServiceInfo service_info, - const std::string& service_type) { - discovered_latch.CountDown(); - }, - .service_lost_cb = - [&lost_latch](NsdServiceInfo service_info, - const std::string& service_type) { - lost_latch.CountDown(); - }, - }); - - WifiLanServerSocketV2 server_socket = wifi_lan_a.ListenForService(); - EXPECT_TRUE(server_socket.IsValid()); - - NsdServiceInfo nsd_service_info; - nsd_service_info.SetServiceName(service_info_name); - nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey), - endpoint_info_name); - nsd_service_info.SetServiceType(service_type); - EXPECT_TRUE(wifi_lan_b.StartAdvertising(nsd_service_info)); - EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_b.StopAdvertising(nsd_service_info)); - EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); - EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_type)); - env_.Stop(); -} - -} // namespace -} // namespace nearby -} // namespace location diff --git a/cpp/platform/public/wifi_lan_v2.cc b/cpp/platform/public/wifi_lan_v2.cc deleted file mode 100644 index d52e5b30..00000000 --- a/cpp/platform/public/wifi_lan_v2.cc +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "platform/public/wifi_lan_v2.h" - -#include "platform/public/mutex_lock.h" - -namespace location { -namespace nearby { - -bool WifiLanMediumV2::StartAdvertising(const NsdServiceInfo& nsd_service_info) { - return impl_->StartAdvertising(nsd_service_info); -} - -bool WifiLanMediumV2::StopAdvertising(const NsdServiceInfo& nsd_service_info) { - return impl_->StopAdvertising(nsd_service_info); -} - -bool WifiLanMediumV2::StartDiscovery(const std::string& service_id, - const std::string& service_type, - DiscoveredServiceCallback callback) { - { - MutexLock lock(&mutex_); - if (discovery_callbacks_.contains(service_type)) { - NEARBY_LOGS(INFO) << "WifiLan Discovery already start with service_type=" - << service_type << "; impl=" << &GetImpl(); - return false; - } - } - api::WifiLanMediumV2::DiscoveredServiceCallback api_callback = { - .service_discovered_cb = - [this](NsdServiceInfo service_info) { - MutexLock lock(&mutex_); - std::string service_type = service_info.GetServiceType(); - auto pair = discovery_services_.insert(service_type); - if (!pair.second) { - NEARBY_LOGS(INFO) - << "Discovering (again) service_info=" << &service_info - << ", service_type=" << service_type - << ", service_name=" << service_info.GetServiceName(); - return; - } - NEARBY_LOGS(INFO) - << "Adding service_info=" << &service_info - << ", service_type=" << service_type - << ", service_name=" << service_info.GetServiceName(); - // Callback service found. - const auto& it = discovery_callbacks_.find(service_type); - if (it != discovery_callbacks_.end()) { - std::string service_id = it->second->service_id; - DiscoveredServiceCallback medium_callback = - it->second->medium_callback; - medium_callback.service_discovered_cb(service_info, service_id); - } else { - NEARBY_LOGS(ERROR) - << "There is no callback found for service_type=" - << service_type; - } - }, - .service_lost_cb = - [this](NsdServiceInfo service_info) { - MutexLock lock(&mutex_); - std::string service_type = service_info.GetServiceType(); - auto item = discovery_services_.extract(service_type); - if (item.empty()) return; - NEARBY_LOGS(INFO) - << "Removing service_info=" << &service_info - << ", service_type=" << service_type - << ", service_info_name=" << service_info.GetServiceName(); - // Callback service lost. - const auto& it = discovery_callbacks_.find(service_type); - if (it != discovery_callbacks_.end()) { - std::string service_id = it->second->service_id; - DiscoveredServiceCallback medium_callback = - it->second->medium_callback; - medium_callback.service_lost_cb(service_info, service_id); - } - }, - }; - { - // Insert callback to the map first no matter it succeeds or not. - MutexLock lock(&mutex_); - auto pair = discovery_callbacks_.insert( - {service_type, absl::make_unique()}); - auto& context = *pair.first->second; - context.medium_callback = std::move(callback); - context.service_id = service_id; - } - - bool success = impl_->StartDiscovery(service_type, std::move(api_callback)); - if (!success) { - // If failed, then revert back the insertion. - MutexLock lock(&mutex_); - discovery_callbacks_.erase(service_type); - } - NEARBY_LOGS(INFO) << "WifiLan Discovery started for service_type=" - << service_type << ", impl=" << &GetImpl() - << ", success=" << success; - return success; -} - -bool WifiLanMediumV2::StopDiscovery(const std::string& service_type) { - MutexLock lock(&mutex_); - if (!discovery_callbacks_.contains(service_type)) { - return false; - } - discovery_callbacks_.erase(service_type); - if (discovery_services_.contains(service_type)) { - discovery_services_.erase(service_type); - } - NEARBY_LOGS(INFO) << "WifiLan Discovery disabled for service_type=" - << service_type << ", impl=" << &GetImpl(); - return impl_->StopDiscovery(service_type); -} - -WifiLanSocketV2 WifiLanMediumV2::ConnectToService( - const NsdServiceInfo& remote_service_info, - CancellationFlag* cancellation_flag) { - NEARBY_LOGS(INFO) << "WifiLanMedium::ConnectToService: remote_service_name=" - << remote_service_info.GetServiceName(); - return WifiLanSocketV2( - impl_->ConnectToService(remote_service_info, cancellation_flag)); -} - -WifiLanSocketV2 WifiLanMediumV2::ConnectToService( - const std::string& ip_address, int port, - CancellationFlag* cancellation_flag) { - NEARBY_LOGS(INFO) << "WifiLanMedium::ConnectToService: ip address=" - << ip_address << ", port=" << port; - return WifiLanSocketV2( - impl_->ConnectToService(ip_address, port, cancellation_flag)); -} - -} // namespace nearby -} // namespace location diff --git a/cpp/platform/public/wifi_lan_v2.h b/cpp/platform/public/wifi_lan_v2.h deleted file mode 100644 index 9da601b7..00000000 --- a/cpp/platform/public/wifi_lan_v2.h +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef PLATFORM_PUBLIC_WIFI_LAN_V2_H_ -#define PLATFORM_PUBLIC_WIFI_LAN_V2_H_ - -#include "absl/container/flat_hash_map.h" -#include "platform/api/platform.h" -#include "platform/api/wifi_lan_v2.h" -#include "platform/base/byte_array.h" -#include "platform/base/cancellation_flag.h" -#include "platform/base/input_stream.h" -#include "platform/base/nsd_service_info.h" -#include "platform/base/output_stream.h" -#include "platform/public/logging.h" -#include "platform/public/mutex.h" - -namespace location { -namespace nearby { - -class WifiLanSocketV2 final { - public: - WifiLanSocketV2() = default; - WifiLanSocketV2(const WifiLanSocketV2&) = default; - WifiLanSocketV2& operator=(const WifiLanSocketV2&) = default; - ~WifiLanSocketV2() = default; - explicit WifiLanSocketV2(std::unique_ptr socket) - : impl_(std::move(socket)) {} - - // Returns the InputStream of the WifiLanSocket. - // On error, returned stream will report Exception::kIo on any operation. - // - // The returned object is not owned by the caller, and can be invalidated once - // the WifiLanSocket object is destroyed. - InputStream& GetInputStream() { return impl_->GetInputStream(); } - - // Returns the OutputStream of the WifiLanSocket. - // On error, returned stream will report Exception::kIo on any operation. - // - // The returned object is not owned by the caller, and can be invalidated once - // the WifiLanSocket object is destroyed. - OutputStream& GetOutputStream() { return impl_->GetOutputStream(); } - - // Returns Exception::kIo on error, Exception::kSuccess otherwise. - Exception Close() { return impl_->Close(); } - - // Returns true if a socket is usable. If this method returns false, - // it is not safe to call any other method. - // NOTE(socket validity): - // Socket created by a default public constructor is not valid, because - // it is missing platform implementation. - // The only way to obtain a valid socket is through connection, such as - // an object returned by WifiLanMedium::Connect - // These methods may also return an invalid socket if connection failed for - // any reason. - bool IsValid() const { return impl_ != nullptr; } - - // Returns reference to platform implementation. - // This is used to communicate with platform code, and for debugging purposes. - // Returned reference will remain valid for while WifiLanSocket object is - // itself valid. Typically WifiLanSocket lifetime matches duration of the - // connection, and is controlled by end user, since they hold the instance. - api::WifiLanSocketV2& GetImpl() { return *impl_; } - - private: - std::shared_ptr impl_; -}; - -class WifiLanServerSocketV2 final { - public: - WifiLanServerSocketV2() = default; - WifiLanServerSocketV2(const WifiLanServerSocketV2&) = default; - WifiLanServerSocketV2& operator=(const WifiLanServerSocketV2&) = default; - ~WifiLanServerSocketV2() = default; - explicit WifiLanServerSocketV2( - std::unique_ptr socket) - : impl_(std::move(socket)) {} - - // Returns ip address. - std::string GetIPAddress() { return impl_->GetIPAddress(); } - - // Returns port. - int GetPort() { return impl_->GetPort(); } - - // Blocks until either: - // - at least one incoming connection request is available, or - // - ServerSocket is closed. - // On success, returns connected socket, ready to exchange data. - // Returns nullptr on error. - // Once error is reported, it is permanent, and ServerSocket has to be closed. - WifiLanSocketV2 Accept() { - std::unique_ptr socket = impl_->Accept(); - if (!socket) { - NEARBY_LOGS(INFO) - << "WifiLanServerSocket Accept() failed on server socket: " << this; - } - return WifiLanSocketV2(std::move(socket)); - } - - // Returns Exception::kIo on error, Exception::kSuccess otherwise. - Exception Close() { - NEARBY_LOGS(INFO) << "WifiLanServerSocket Closing:: " << this; - return impl_->Close(); - } - - bool IsValid() const { return impl_ != nullptr; } - api::WifiLanServerSocketV2& GetImpl() { return *impl_; } - - private: - std::shared_ptr impl_; -}; - -// Container of operations that can be performed over the WifiLan medium. -class WifiLanMediumV2 { - public: - using Platform = api::ImplementationPlatform; - - struct DiscoveredServiceCallback { - std::function - service_discovered_cb = - DefaultCallback(); - std::function - service_lost_cb = DefaultCallback(); - }; - - struct DiscoveryCallbackInfo { - std::string service_id; - DiscoveredServiceCallback medium_callback; - }; - - WifiLanMediumV2() : impl_(Platform::CreateWifiLanMediumV2()) {} - ~WifiLanMediumV2() = default; - - // Starts WifiLan advertising. - // - // nsd_service_info - NsdServiceInfo data that's advertised through mDNS - // service. - // On success if the service is now advertising. - // On error if the service cannot start to advertise or the nsd_type in - // NsdServiceInfo has been passed previously which StopAdvertising is not - // been called. - bool StartAdvertising(const NsdServiceInfo& nsd_service_info); - - // Stops WifiLan advertising. - // - // nsd_service_info - NsdServiceInfo data that's advertised through mDNS - // service. - // On success if the service stops advertising. - // On error if the service cannot stop advertising or the nsd_type in - // NsdServiceInfo cannot be found. - bool StopAdvertising(const NsdServiceInfo& nsd_service_info); - - // Returns true once the WifiLan discovery has been initiated. - bool StartDiscovery(const std::string& service_id, - const std::string& service_type, - DiscoveredServiceCallback callback); - - // Returns true once service_type is associated to existing callback. If the - // callback is the last found then WifiLan discovery will be stopped. - bool StopDiscovery(const std::string& service_type); - - // Returns a new WifiLanSocket. - // On Success, WifiLanSocket::IsValid() returns true. - WifiLanSocketV2 ConnectToService(const NsdServiceInfo& remote_service_info, - CancellationFlag* cancellation_flag); - - // Returns a new WifiLanSocket by ip address and port. - // On Success, WifiLanSocket::IsValid()returns true. - WifiLanSocketV2 ConnectToService(const std::string& ip_address, int port, - CancellationFlag* cancellation_flag); - - // Returns a new WifiLanServerSocket. - // On Success, WifiLanServerSocket::IsValid() returns true. - WifiLanServerSocketV2 ListenForService(int port = 0) { - return WifiLanServerSocketV2(impl_->ListenForService(port)); - } - - bool IsValid() const { return impl_ != nullptr; } - - api::WifiLanMediumV2& GetImpl() { return *impl_; } - - private: - Mutex mutex_; - std::unique_ptr impl_; - absl::flat_hash_map> - discovery_callbacks_ ABSL_GUARDED_BY(mutex_); - absl::flat_hash_set discovery_services_ ABSL_GUARDED_BY(mutex_); -}; - -} // namespace nearby -} // namespace location - -#endif // PLATFORM_PUBLIC_WIFI_LAN_V2_H_