From a584dad4a95053c7f9f39dd3d7174264f75cc2af Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Wed, 28 Sep 2022 19:40:41 -0700 Subject: [PATCH] Fixed the WiFi issue to handle service discovery PiperOrigin-RevId: 477613253 --- internal/platform/medium_environment.cc | 12 +++-- internal/platform/wifi_lan.cc | 45 +++++++++++------- internal/platform/wifi_lan_test.cc | 63 ++++++++++++++++++++++++- 3 files changed, 96 insertions(+), 24 deletions(-) diff --git a/internal/platform/medium_environment.cc b/internal/platform/medium_environment.cc index a965dc68..10218f3c 100644 --- a/internal/platform/medium_environment.cc +++ b/internal/platform/medium_environment.cc @@ -262,8 +262,9 @@ void MediumEnvironment::OnWifiLanServiceStateChanged( WifiLanMediumContext& info, const NsdServiceInfo& service_info, bool enabled) { if (!enabled_) return; + std::string service_name = service_info.GetServiceName(); std::string service_type = service_info.GetServiceType(); - auto item = info.discovered_services.find(service_type); + auto item = info.discovered_services.find(service_name); if (item == info.discovered_services.end()) { NEARBY_LOGS(INFO) << "G3 OnWifiLanServiceStateChanged; context=" << &info << "; service_type=" << service_type @@ -273,7 +274,7 @@ void MediumEnvironment::OnWifiLanServiceStateChanged( // Find advertising service with matched service_type. Report it as // discovered. NsdServiceInfo discovered_service_info(service_info); - info.discovered_services.insert({service_type, discovered_service_info}); + info.discovered_services.insert({service_name, discovered_service_info}); if (enable_notifications_) { RunOnMediumEnvironmentThread( [&info, discovered_service_info, service_type]() { @@ -843,10 +844,11 @@ void MediumEnvironment::UpdateWifiLanMediumForAdvertising( if (!enabled_) return; RunOnMediumEnvironmentThread([this, &medium, service_info = service_info, enabled]() { + std::string service_name = service_info.GetServiceName(); std::string service_type = service_info.GetServiceType(); NEARBY_LOGS(INFO) << "Update WifiLan medium for advertising: this=" << this << "; medium=" << &medium - << "; service_name=" << service_info.GetServiceName() + << "; service_name=" << service_name << "; service_type=" << service_type << ", enabled=" << enabled; for (auto& medium_info : wifi_lan_mediums_) { @@ -856,9 +858,9 @@ void MediumEnvironment::UpdateWifiLanMediumForAdvertising( // service info map. if (local_medium == &medium) { if (enabled) { - info.advertising_services.insert({service_type, service_info}); + info.advertising_services.insert({service_name, service_info}); } else { - info.advertising_services.erase(service_type); + info.advertising_services.erase(service_name); } continue; } diff --git a/internal/platform/wifi_lan.cc b/internal/platform/wifi_lan.cc index 481509f2..2e3ce3ee 100644 --- a/internal/platform/wifi_lan.cc +++ b/internal/platform/wifi_lan.cc @@ -14,6 +14,9 @@ #include "internal/platform/wifi_lan.h" +#include +#include + #include "internal/platform/mutex_lock.h" namespace location { @@ -43,7 +46,19 @@ bool WifiLanMedium::StartDiscovery(const std::string& service_id, [this](NsdServiceInfo service_info) { MutexLock lock(&mutex_); std::string service_type = service_info.GetServiceType(); - auto pair = discovery_services_.insert(service_type); + // Check callback for the service type. + const auto& it = discovery_callbacks_.find(service_type); + + if (it == discovery_callbacks_.end()) { + NEARBY_LOGS(ERROR) + << "There is no callback found for service_type=" + << service_type; + return; + } + + // Check whether service name is in cache. + std::string service_name = service_info.GetServiceName(); + auto pair = discovery_services_.insert(service_name); if (!pair.second) { NEARBY_LOGS(INFO) << "Discovering (again) service_info=" << &service_info @@ -51,33 +66,27 @@ bool WifiLanMedium::StartDiscovery(const std::string& service_id, << ", 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; - } + + std::string service_id = it->second->service_id; + DiscoveredServiceCallback medium_callback = + it->second->medium_callback; + medium_callback.service_discovered_cb(service_info, service_id); }, .service_lost_cb = [this](NsdServiceInfo service_info) { MutexLock lock(&mutex_); std::string service_type = service_info.GetServiceType(); - auto item = discovery_services_.extract(service_type); + std::string service_name = service_info.GetServiceName(); + auto item = discovery_services_.extract(service_name); if (item.empty()) return; - NEARBY_LOGS(INFO) - << "Removing service_info=" << &service_info - << ", service_type=" << service_type - << ", service_info_name=" << service_info.GetServiceName(); + NEARBY_LOGS(INFO) << "Removing service_info=" << &service_info + << ", service_type=" << service_type + << ", service_info_name=" << service_name; // Callback service lost. const auto& it = discovery_callbacks_.find(service_type); if (it != discovery_callbacks_.end()) { diff --git a/internal/platform/wifi_lan_test.cc b/internal/platform/wifi_lan_test.cc index f96cf15e..74df9844 100644 --- a/internal/platform/wifi_lan_test.cc +++ b/internal/platform/wifi_lan_test.cc @@ -20,9 +20,9 @@ #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/strings/string_view.h" -#include "internal/platform/medium_environment.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/logging.h" +#include "internal/platform/medium_environment.h" namespace location { namespace nearby { @@ -344,6 +344,67 @@ TEST_F(WifiLanMediumTest, CanAdvertiseThatOtherMediumDiscover) { env_.Stop(); } +TEST_F(WifiLanMediumTest, CanDiscoverMultipleAdvertisementsOnSameService) { + env_.Start(); + WifiLanMedium wifi_lan_discovery; + WifiLanMedium wifi_lan_advertising_1; + WifiLanMedium wifi_lan_advertising_2; + std::string service_id(kServiceId); + std::string service_type(kServiceType); + + CountDownLatch discovered_latch(2); + CountDownLatch lost_latch(2); + + wifi_lan_discovery.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(); + }, + }); + + // Setup first advertising device. + WifiLanServerSocket server_socket_1 = + wifi_lan_advertising_1.ListenForService(); + EXPECT_TRUE(server_socket_1.IsValid()); + + NsdServiceInfo nsd_service_info_1; + nsd_service_info_1.SetServiceName("service1"); + nsd_service_info_1.SetTxtRecord(std::string(kEndpointInfoKey), + "endpoint1"); + nsd_service_info_1.SetServiceType(service_type); + + // Setup second advertising device. + WifiLanServerSocket server_socket_2 = + wifi_lan_advertising_2.ListenForService(); + EXPECT_TRUE(server_socket_2.IsValid()); + + NsdServiceInfo nsd_service_info_2; + nsd_service_info_2.SetServiceName("service2"); + nsd_service_info_2.SetTxtRecord(std::string(kEndpointInfoKey), + "endpoint2"); + nsd_service_info_2.SetServiceType(service_type); + + EXPECT_TRUE(wifi_lan_advertising_1.StartAdvertising(nsd_service_info_1)); + EXPECT_TRUE(wifi_lan_advertising_2.StartAdvertising(nsd_service_info_2)); + EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result()); + EXPECT_TRUE(wifi_lan_advertising_1.StopAdvertising(nsd_service_info_1)); + EXPECT_TRUE(wifi_lan_advertising_2.StopAdvertising(nsd_service_info_2)); + EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); + + + // Stop to descovery + EXPECT_TRUE(wifi_lan_discovery.StopDiscovery(service_type)); + env_.Stop(); +} + TEST_F(WifiLanMediumTest, CanDiscoverThatOtherMediumAdvertise) { env_.Start(); WifiLanMedium wifi_lan_a;