From cc2c6c527b1661b8c90ac7203828bfa2ea61383f Mon Sep 17 00:00:00 2001 From: hai007 Date: Sat, 5 Apr 2025 01:47:51 -0700 Subject: [PATCH] Implement AWDL in connection layer (part 2) PiperOrigin-RevId: 744206141 --- connections/c/nc.cc | 4 + connections/c/nc_types.h | 3 +- connections/dart/nc_adapter_dart.cc | 6 + connections/dart/nc_adapter_types.h | 1 + connections/implementation/BUILD | 3 +- .../implementation/awdl_endpoint_channel.cc | 54 +++ .../implementation/awdl_endpoint_channel.h | 44 ++ .../implementation/base_pcp_handler.cc | 7 + connections/implementation/base_pcp_handler.h | 8 + .../flags/nearby_connections_feature_flags.h | 3 + .../implementation/p2p_cluster_pcp_handler.cc | 419 +++++++++++++++++- .../implementation/p2p_cluster_pcp_handler.h | 25 +- .../p2p_cluster_pcp_handler_test.cc | 158 +++++++ .../service_controller_router.cc | 3 +- .../service_controller_router_test.cc | 6 +- connections/medium_selector.h | 10 +- 16 files changed, 742 insertions(+), 12 deletions(-) create mode 100644 connections/implementation/awdl_endpoint_channel.cc create mode 100644 connections/implementation/awdl_endpoint_channel.h diff --git a/connections/c/nc.cc b/connections/c/nc.cc index 4ef62a63..9c170fd1 100644 --- a/connections/c/nc.cc +++ b/connections/c/nc.cc @@ -287,6 +287,8 @@ void NcStartAdvertising( std::string(advertising_options->fast_advertisement_service_uuid.data, advertising_options->fast_advertisement_service_uuid.size); } + cpp_advertising_options.allowed.awdl = + advertising_options->common_options.allowed_mediums[NC_MEDIUM_AWDL]; cpp_advertising_options.is_out_of_band_connection = advertising_options->is_out_of_band_connection; @@ -378,6 +380,8 @@ void NcStartDiscovery(NC_INSTANCE instance, const NC_DATA* service_id, discovery_options->common_options.allowed_mediums[NC_MEDIUM_WIFI_HOTSPOT]; cpp_discovery_options.allowed.web_rtc = discovery_options->common_options.allowed_mediums[NC_MEDIUM_WEB_RTC]; + cpp_discovery_options.allowed.awdl = + discovery_options->common_options.allowed_mediums[NC_MEDIUM_AWDL]; NC_DISCOVERY_LISTENER discovery_listener_copy = *discovery_listener; ::nearby::connections::DiscoveryListener listener; diff --git a/connections/c/nc_types.h b/connections/c/nc_types.h index 7d62a800..63422436 100644 --- a/connections/c/nc_types.h +++ b/connections/c/nc_types.h @@ -51,7 +51,8 @@ typedef enum NC_MEDIUM { NC_MEDIUM_WEB_RTC = 9, NC_MEDIUM_BLE_L2CAP = 10, NC_MEDIUM_USB = 11, - NC_MEDIUM_MAX = 12 + NC_MEDIUM_AWDL = 12, + NC_MEDIUM_MAX = 13 } NC_MEDIUM; typedef enum NC_CONNECTION_TYPE { diff --git a/connections/dart/nc_adapter_dart.cc b/connections/dart/nc_adapter_dart.cc index 3aeade4f..b54a5ed4 100644 --- a/connections/dart/nc_adapter_dart.cc +++ b/connections/dart/nc_adapter_dart.cc @@ -491,6 +491,8 @@ void StartAdvertisingDart(NC_INSTANCE instance, DataDart service_id, options_dart.mediums.wifi_hotspot; advertising_options.common_options.allowed_mediums[NC_MEDIUM_WEB_RTC] = options_dart.mediums.web_rtc; + advertising_options.common_options.allowed_mediums[NC_MEDIUM_AWDL] = + options_dart.mediums.awdl != 0; NC_CONNECTION_REQUEST_INFO request_info{}; @@ -567,6 +569,8 @@ void StartDiscoveryDart(NC_INSTANCE instance, DataDart service_id, options_dart.mediums.ble != 0; discovery_options.common_options.allowed_mediums[NC_MEDIUM_WIFI_LAN] = options_dart.mediums.wifi_lan != 0; + discovery_options.common_options.allowed_mediums[NC_MEDIUM_AWDL] = + options_dart.mediums.awdl != 0; discovery_options.common_options.allowed_mediums[NC_MEDIUM_WIFI_HOTSPOT] = options_dart.mediums.wifi_hotspot; discovery_options.common_options.allowed_mediums[NC_MEDIUM_WEB_RTC] = @@ -647,6 +651,8 @@ void RequestConnectionDart(NC_INSTANCE instance, int endpoint_id, options_dart.mediums.ble != 0; connection_options.common_options.allowed_mediums[NC_MEDIUM_WIFI_LAN] = options_dart.mediums.wifi_lan != 0; + connection_options.common_options.allowed_mediums[NC_MEDIUM_AWDL] = + options_dart.mediums.awdl != 0; connection_options.common_options.allowed_mediums[NC_MEDIUM_WIFI_HOTSPOT] = options_dart.mediums.wifi_hotspot; connection_options.common_options.allowed_mediums[NC_MEDIUM_WEB_RTC] = diff --git a/connections/dart/nc_adapter_types.h b/connections/dart/nc_adapter_types.h index 15cac067..2a19af3c 100644 --- a/connections/dart/nc_adapter_types.h +++ b/connections/dart/nc_adapter_types.h @@ -46,6 +46,7 @@ struct MediumsDart { int64_t wifi_lan; int64_t wifi_hotspot; int64_t web_rtc; + int64_t awdl; // LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/plugins/nearby_connections/platform/lib/types/mediums.dart) }; diff --git a/connections/implementation/BUILD b/connections/implementation/BUILD index e5f2f69a..9d11ff1b 100644 --- a/connections/implementation/BUILD +++ b/connections/implementation/BUILD @@ -52,6 +52,7 @@ cc_library( cc_library( name = "internal", srcs = [ + "awdl_endpoint_channel.cc", "base_bwu_handler.cc", "base_endpoint_channel.cc", "base_pcp_handler.cc", @@ -92,6 +93,7 @@ cc_library( "wifi_lan_service_info.cc", ], hdrs = [ + "awdl_endpoint_channel.h", "base_bwu_handler.h", "base_endpoint_channel.h", "base_pcp_handler.h", @@ -293,7 +295,6 @@ cc_test( ], shard_count = 8, deps = [ - ":ble_advertisement", ":internal", ":internal_test", ":types", diff --git a/connections/implementation/awdl_endpoint_channel.cc b/connections/implementation/awdl_endpoint_channel.cc new file mode 100644 index 00000000..cf056952 --- /dev/null +++ b/connections/implementation/awdl_endpoint_channel.cc @@ -0,0 +1,54 @@ +// 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 "connections/implementation/awdl_endpoint_channel.h" + +#include + +#include "connections/implementation/base_endpoint_channel.h" +#include "internal/platform/logging.h" +#include "internal/platform/awdl.h" + +namespace nearby { +namespace connections { +AwdlEndpointChannel::AwdlEndpointChannel(const std::string& service_id, + const std::string& channel_name, + AwdlSocket socket) + : BaseEndpointChannel(service_id, channel_name, &socket.GetInputStream(), + &socket.GetOutputStream()), + socket_(std::move(socket)) {} + +location::nearby::proto::connections::Medium AwdlEndpointChannel::GetMedium() + const { + return location::nearby::proto::connections::Medium::AWDL; +} + +void AwdlEndpointChannel::CloseImpl() { + auto status = socket_.Close(); + if (!status.Ok()) { + NEARBY_LOGS(INFO) + << "Failed to close underlying socket for AwdlEndpointChannel " + << GetName() << " : exception = " << status.value; + } +} + +bool AwdlEndpointChannel::EnableMultiplexSocket() { + NEARBY_LOGS(INFO) << "AwdlEndpointChannel MultiplexSocket will be " + "enabled if the Awdl MultiplexSocket is valid"; + socket_.EnableMultiplexSocket(); + return true; +} + +} // namespace connections +} // namespace nearby diff --git a/connections/implementation/awdl_endpoint_channel.h b/connections/implementation/awdl_endpoint_channel.h new file mode 100644 index 00000000..e3949152 --- /dev/null +++ b/connections/implementation/awdl_endpoint_channel.h @@ -0,0 +1,44 @@ +// 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_AWDL_ENDPOINT_CHANNEL_H_ +#define CORE_INTERNAL_AWDL_ENDPOINT_CHANNEL_H_ + +#include + +#include "connections/implementation/base_endpoint_channel.h" +#include "internal/platform/awdl.h" + +namespace nearby { +namespace connections { + +class AwdlEndpointChannel final : public BaseEndpointChannel { + public: + // Creates both outgoing and incoming AWDL channels. + AwdlEndpointChannel(const std::string& service_id, + const std::string& channel_name, AwdlSocket socket); + + location::nearby::proto::connections::Medium GetMedium() const override; + bool EnableMultiplexSocket() override; + + private: + void CloseImpl() override; + + AwdlSocket socket_; +}; + +} // namespace connections +} // namespace nearby + +#endif // CORE_INTERNAL_AWDL_ENDPOINT_CHANNEL_H_ diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 5b8ea72b..fcb2e41e 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -359,6 +359,10 @@ void BasePcpHandler::OptionsAllowed(const BooleanMediumSelector& allowed, Medium::WIFI_DIRECT) << " "; } + if (allowed.awdl) { + result << location::nearby::proto::connections::Medium_Name(Medium::AWDL) + << " "; + } result << "}"; } @@ -1170,6 +1174,9 @@ void BasePcpHandler::StripOutUnavailableMediums( if (allowed.wifi_direct) { allowed.wifi_direct = mediums_->GetWifiDirect().IsGOAvailable(); } + if (allowed.awdl) { + allowed.awdl = mediums_->GetAwdl().IsAvailable(); + } } std::unique_ptr diff --git a/connections/implementation/base_pcp_handler.h b/connections/implementation/base_pcp_handler.h index 7cf1adb6..1b318870 100644 --- a/connections/implementation/base_pcp_handler.h +++ b/connections/implementation/base_pcp_handler.h @@ -251,6 +251,14 @@ class BasePcpHandler : public PcpHandler, BleV2Peripheral ble_peripheral; }; + struct AwdlEndpoint : public DiscoveredEndpoint { + AwdlEndpoint(DiscoveredEndpoint endpoint, + const NsdServiceInfo& service_info) + : DiscoveredEndpoint(std::move(endpoint)), service_info(service_info) {} + + NsdServiceInfo service_info; + }; + struct WifiLanEndpoint : public DiscoveredEndpoint { WifiLanEndpoint(DiscoveredEndpoint endpoint, const NsdServiceInfo& service_info) diff --git a/connections/implementation/flags/nearby_connections_feature_flags.h b/connections/implementation/flags/nearby_connections_feature_flags.h index 79828a65..29bf758e 100644 --- a/connections/implementation/flags/nearby_connections_feature_flags.h +++ b/connections/implementation/flags/nearby_connections_feature_flags.h @@ -93,6 +93,9 @@ constexpr auto kDisableInstantOnLostOnBleWithoutExtended = constexpr auto kEnableMultiplexAwdl = flags::Flag(kConfigPackage, "45696647", true); +// Enable/Disable AWDL in Nearby connections SDK. +constexpr auto kEnableAwdl = + flags::Flag(kConfigPackage, "45669531", true); } // namespace nearby_connections_feature } // namespace config_package_nearby } // namespace connections diff --git a/connections/implementation/p2p_cluster_pcp_handler.cc b/connections/implementation/p2p_cluster_pcp_handler.cc index acbcfacf..91f142a5 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.cc +++ b/connections/implementation/p2p_cluster_pcp_handler.cc @@ -29,6 +29,7 @@ #include "absl/strings/string_view.h" #include "connections/advertising_options.h" #include "connections/discovery_options.h" +#include "connections/implementation/awdl_endpoint_channel.h" #include "connections/implementation/base_pcp_handler.h" #include "connections/implementation/ble_advertisement.h" #include "connections/implementation/ble_endpoint_channel.h" @@ -61,6 +62,7 @@ #include "connections/v3/connection_listening_options.h" #include "internal/flags/nearby_flags.h" #include "internal/interop/device.h" +#include "internal/platform/awdl.h" #include "internal/platform/ble.h" #include "internal/platform/ble_v2.h" #include "internal/platform/bluetooth_adapter.h" @@ -81,6 +83,7 @@ namespace connections { namespace { using ::location::nearby::analytics::proto::ConnectionsLog; using ::location::nearby::proto::connections::OperationResultCode; +using ::location::nearby::proto::connections::Medium::AWDL; using ::location::nearby::proto::connections::Medium::BLE; using ::location::nearby::proto::connections::Medium::BLUETOOTH; using ::location::nearby::proto::connections::Medium::UNKNOWN_MEDIUM; @@ -110,6 +113,7 @@ P2pClusterPcpHandler::P2pClusterPcpHandler( InjectedBluetoothDeviceStore& injected_bluetooth_device_store, Pcp pcp) : BasePcpHandler(mediums, endpoint_manager, endpoint_channel_manager, bwu_manager, pcp), + awdl_medium_(mediums->GetAwdl()), bluetooth_radio_(mediums->GetBluetoothRadio()), bluetooth_medium_(mediums->GetBluetoothClassic()), ble_medium_(mediums->GetBle()), @@ -165,6 +169,32 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl( WebRtcState web_rtc_state{WebRtcState::kUnconnectable}; + // AWDL + if (advertising_options.allowed.awdl && + NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature::kEnableAwdl)) { + ErrorOr awdl_result = + StartAwdlAdvertising(client, service_id, local_endpoint_id, + local_endpoint_info, web_rtc_state); + + Medium awdl_medium = UNKNOWN_MEDIUM; + if (awdl_result.has_value()) { + awdl_medium = awdl_result.value(); + } + if (awdl_medium != UNKNOWN_MEDIUM) { + LOG(INFO) << "P2pClusterPcpHandler::StartAdvertisingImpl: Awdl added"; + mediums_started_successfully.push_back(awdl_medium); + } + std::unique_ptr + operation_result_with_medium = GetOperationResultWithMediumByResultCode( + client, AWDL, /*update_index=*/0, + awdl_result.has_error() + ? awdl_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS); + operation_result_with_mediums.push_back(*operation_result_with_medium); + } + + // WifiLan if (advertising_options.allowed.wifi_lan) { ErrorOr wifi_lan_result = StartWifiLanAdvertising(client, service_id, local_endpoint_id, @@ -347,6 +377,12 @@ Status P2pClusterPcpHandler::StopAdvertisingImpl(ClientProxy* client) { wifi_lan_medium_.StopAdvertising(client->GetAdvertisingServiceId()); wifi_lan_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId()); + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature::kEnableAwdl)) { + awdl_medium_.StopAdvertising(client->GetAdvertisingServiceId()); + awdl_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId()); + } + return {Status::kSuccess}; } @@ -1006,7 +1042,96 @@ void P2pClusterPcpHandler::BleV2LegacyDeviceDiscoveredHandler() { }); } -bool P2pClusterPcpHandler::IsRecognizedWifiLanEndpoint( +void P2pClusterPcpHandler::AwdlServiceDiscoveredHandler( + ClientProxy* client, NsdServiceInfo service_info, + const std::string& service_id) { + RunOnPcpHandlerThread( + "p2p-awdl-service-discovered", + [this, client, service_id, service_info]() RUN_ON_PCP_HANDLER_THREAD() { + // Make sure we are still discovering before proceeding. + if (!client->IsDiscovering()) { + LOG(WARNING) << "Skipping discovery of NsdServiceInfo " + << service_info.GetServiceName() + << " because we are no longer discovering."; + return; + } + + // Parse the WifiLanServiceInfo. + WifiLanServiceInfo wifi_lan_service_info(service_info); + // Make sure the medium service name points to a valid + // endpoint we're discovering. + if (!IsRecognizedWifiServiceEndpoint(service_id, + wifi_lan_service_info)) { + return; + } + + // Report the discovered endpoint to the client. + LOG(INFO) << "Found NsdServiceInfo " << service_info.GetServiceName() + << " (with endpoint_id=" + << wifi_lan_service_info.GetEndpointId() + << "and endpoint_info=" + << absl::BytesToHexString( + wifi_lan_service_info.GetEndpointInfo().data()) + << ")."; + StopEndpointLostByMediumAlarm(wifi_lan_service_info.GetEndpointId(), + AWDL); + OnEndpointFound(client, std::make_shared(AwdlEndpoint{ + { + wifi_lan_service_info.GetEndpointId(), + wifi_lan_service_info.GetEndpointInfo(), + service_id, + AWDL, + wifi_lan_service_info.GetWebRtcState(), + }, + service_info, + })); + }); +} + +void P2pClusterPcpHandler::AwdlServiceLostHandler( + ClientProxy* client, NsdServiceInfo service_info, + const std::string& service_id) { + LOG(INFO) << "Awdl: [LOST, SCHED] service_info=" << &service_info + << ", service_name=" << service_info.GetServiceName(); + RunOnPcpHandlerThread( + "p2p-wifi-service-lost", + [this, client, service_id, service_info]() RUN_ON_PCP_HANDLER_THREAD() { + // Make sure we are still discovering before proceeding. + if (!client->IsDiscovering()) { + LOG(WARNING) << "Ignoring lost NsdServiceInfo " + << service_info.GetServiceName() + << " because we are no longer " + "discovering."; + return; + } + + // Parse the WifiLanServiceInfo. + WifiLanServiceInfo wifi_lan_service_info(service_info); + + // Make sure the medium service name points to a valid + // endpoint we're discovering. + if (!IsRecognizedWifiServiceEndpoint(service_id, wifi_lan_service_info)) + return; + + // Report the lost endpoint to the client. + LOG(INFO) << "Lost NsdServiceInfo " << service_info.GetServiceName() + << " (with endpoint_id=" + << wifi_lan_service_info.GetEndpointId() + << " and endpoint_info=" + << absl::BytesToHexString( + wifi_lan_service_info.GetEndpointInfo().data()) + << ")."; + OnEndpointLost(client, DiscoveredEndpoint{ + wifi_lan_service_info.GetEndpointId(), + wifi_lan_service_info.GetEndpointInfo(), + service_id, + AWDL, + WebRtcState::kUndefined, + }); + }); +} + +bool P2pClusterPcpHandler::IsRecognizedWifiServiceEndpoint( const std::string& service_id, const WifiLanServiceInfo& wifi_lan_service_info) const { if (!wifi_lan_service_info.IsValid()) { @@ -1056,7 +1181,8 @@ void P2pClusterPcpHandler::WifiLanServiceDiscoveredHandler( WifiLanServiceInfo wifi_lan_service_info(service_info); // Make sure the WifiLan service name points to a valid // endpoint we're discovering. - if (!IsRecognizedWifiLanEndpoint(service_id, wifi_lan_service_info)) { + if (!IsRecognizedWifiServiceEndpoint(service_id, + wifi_lan_service_info)) { return; } @@ -1106,7 +1232,7 @@ void P2pClusterPcpHandler::WifiLanServiceLostHandler( // Make sure the WifiLan service name points to a valid // endpoint we're discovering. - if (!IsRecognizedWifiLanEndpoint(service_id, wifi_lan_service_info)) + if (!IsRecognizedWifiServiceEndpoint(service_id, wifi_lan_service_info)) return; // Report the lost endpoint to the client. @@ -1141,6 +1267,31 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( std::vector operation_result_with_mediums; + // Due to singleton, apple only allow start discovery once. So need to keep + // the start discovery order of awdl before the wifi_lan. + if (discovery_options.allowed.awdl && + NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature::kEnableAwdl)) { + ErrorOr awdl_result = StartAwdlDiscovery(client, service_id); + Medium awdl_medium = UNKNOWN_MEDIUM; + if (awdl_result.has_value()) { + awdl_medium = awdl_result.value(); + } + if (awdl_medium != UNKNOWN_MEDIUM) { + LOG(INFO) << "P2pClusterPcpHandler::StartDiscoveryImpl: AWDL added"; + mediums_started_successfully.push_back(awdl_medium); + } + std::unique_ptr + operation_result_with_medium = GetOperationResultWithMediumByResultCode( + client, AWDL, + /*update_index=*/0, + awdl_result.has_error() + ? awdl_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS); + operation_result_with_mediums.push_back(*operation_result_with_medium); + } + + // WifiLan if (discovery_options.allowed.wifi_lan) { ErrorOr wifi_lan_result = StartWifiLanDiscovery(client, service_id); Medium wifi_lan_medium = UNKNOWN_MEDIUM; @@ -1247,6 +1398,11 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( Status P2pClusterPcpHandler::StopDiscoveryImpl(ClientProxy* client) { wifi_lan_medium_.StopDiscovery(client->GetDiscoveryServiceId()); + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature::kEnableAwdl)) { + awdl_medium_.StopDiscovery(client->GetDiscoveryServiceId()); + } + if (bluetooth_classic_client_id_to_service_id_map_.contains( client->GetClientId())) { bluetooth_medium_.StopDiscovery( @@ -1340,6 +1496,13 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::ConnectImpl( } break; } + case AWDL: { + auto* awdl_endpoint = down_cast(endpoint); + if (awdl_endpoint) { + return AwdlConnectImpl(client, awdl_endpoint); + } + break; + } case WEB_RTC: { break; } @@ -1540,6 +1703,15 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl( mediums_->GetBle().StopAcceptingConnections(std::string(service_id)); } } + // awdl + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature::kEnableAwdl) && + (NeedsToTurnOffAdvertisingMedium(AWDL, old_options, + advertising_options) || + needs_restart)) { + mediums_->GetAwdl().StopAdvertising(std::string(service_id)); + mediums_->GetAwdl().StopAcceptingConnections(std::string(service_id)); + } // wifi lan if (NeedsToTurnOffAdvertisingMedium(WIFI_LAN, old_options, advertising_options) || @@ -1627,6 +1799,37 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl( operation_result_with_mediums.push_back(*operation_result_with_medium); } } + // awdl + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature::kEnableAwdl) && + new_mediums.awdl && !advertising_options.low_power) { + if (old_mediums.awdl && !needs_restart) { + restarted_mediums.push_back(AWDL); + std::unique_ptr + operation_result_with_medium = + GetOperationResultWithMediumByResultCode( + client, AWDL, update_index, + OperationResultCode::DETAIL_SUCCESS); + operation_result_with_mediums.push_back(*operation_result_with_medium); + } else { + ErrorOr awdl_result = StartAwdlAdvertising( + client, std::string(service_id), std::string(local_endpoint_id), + ByteArray(std::string(local_endpoint_info)), web_rtc_state); + if (awdl_result.has_value() && awdl_result.value() != UNKNOWN_MEDIUM) { + restarted_mediums.push_back(AWDL); + } else { + status = {Status::kWifiLanError}; + } + std::unique_ptr + operation_result_with_medium = + GetOperationResultWithMediumByResultCode( + client, AWDL, update_index, + awdl_result.has_error() + ? awdl_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS); + operation_result_with_mediums.push_back(*operation_result_with_medium); + } + } // wifi lan if (new_mediums.wifi_lan && !advertising_options.low_power) { if (old_mediums.wifi_lan && !needs_restart) { @@ -1782,6 +1985,14 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( bluetooth_medium_.StopDiscovery(std::string(service_id)); StartEndpointLostByMediumAlarms(client, BLUETOOTH); } + // awdl + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature::kEnableAwdl) && + (NeedsToTurnOffDiscoveryMedium(AWDL, old_options, discovery_options) || + needs_restart)) { + mediums_->GetAwdl().StopDiscovery(std::string(service_id)); + StartEndpointLostByMediumAlarms(client, AWDL); + } // wifi lan if (NeedsToTurnOffDiscoveryMedium(WIFI_LAN, old_options, discovery_options) || needs_restart) { @@ -1882,6 +2093,38 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl( } } } + // awdl (note: keep the awdl logic before the wifi lan logic) + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_connections_feature::kEnableAwdl) && + new_mediums.awdl && !discovery_options.low_power) { + should_start_discovery = true; + if (!needs_restart && old_mediums.awdl) { + restarted_mediums.push_back(AWDL); + std::unique_ptr + operation_result_with_medium = + GetOperationResultWithMediumByResultCode( + client, AWDL, update_index, + OperationResultCode::DETAIL_SUCCESS); + operation_result_with_mediums.push_back(*operation_result_with_medium); + } else { + ErrorOr awdl_result = + StartAwdlDiscovery(client, std::string(service_id)); + if (awdl_result.has_value()) { + restarted_mediums.push_back(AWDL); + } else { + LOG(WARNING) << "UpdateDiscoveryOptionsImpl: unable to restart " + "awdl scanning"; + } + std::unique_ptr + operation_result_with_medium = + GetOperationResultWithMediumByResultCode( + client, AWDL, update_index, + awdl_result.has_error() + ? awdl_result.error().operation_result_code().value() + : OperationResultCode::DETAIL_SUCCESS); + operation_result_with_mediums.push_back(*operation_result_with_medium); + } + } // wifi lan if (new_mediums.wifi_lan && !discovery_options.low_power) { should_start_discovery = true; @@ -2772,6 +3015,30 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BleV2ConnectImpl( }; } +void P2pClusterPcpHandler::AwdlConnectionAcceptedHandler( + ClientProxy* client, absl::string_view local_endpoint_id, + absl::string_view local_endpoint_info, NearbyDevice::Type device_type, + const std::string& service_id, AwdlSocket socket) { + if (!socket.IsValid()) { + LOG(WARNING) << "Invalid socket in accept callback(" + << absl::BytesToHexString(local_endpoint_info) + << "), client=" << client->GetClientId(); + return; + } + RunOnPcpHandlerThread( + "p2p-awdl-on-incoming-connection", + [this, client, local_endpoint_id, service_id, device_type, + socket = std::move(socket)]() RUN_ON_PCP_HANDLER_THREAD() mutable { + std::string remote_service_name = std::string(local_endpoint_id); + auto channel = std::make_unique( + service_id, /*channel_name=*/remote_service_name, socket); + ByteArray remote_service_name_byte{remote_service_name}; + + OnIncomingConnection(client, remote_service_name_byte, + std::move(channel), AWDL, device_type); + }); +} + void P2pClusterPcpHandler::WifiLanConnectionAcceptedHandler( ClientProxy* client, absl::string_view local_endpoint_id, absl::string_view local_endpoint_info, NearbyDevice::Type device_type, @@ -2796,6 +3063,92 @@ void P2pClusterPcpHandler::WifiLanConnectionAcceptedHandler( }); } +ErrorOr P2pClusterPcpHandler::StartAwdlAdvertising( + 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. + LOG(INFO) << "P2pClusterPcpHandler::StartAwdlAdvertising: service=" + << service_id << ": start"; + if (!awdl_medium_.IsAcceptingConnections(service_id)) { + ErrorOr awdl_result = awdl_medium_.StartAcceptingConnections( + service_id, + absl::bind_front(&P2pClusterPcpHandler::AwdlConnectionAcceptedHandler, + this, client, local_endpoint_id, + local_endpoint_info.AsStringView(), + NearbyDevice::Type::kConnectionsDevice)); + if (awdl_result.has_error()) { + LOG(WARNING) + << "In StartAwdlAdvertising(" + << absl::BytesToHexString(local_endpoint_info.data()) + << "), client=" << client->GetClientId() + << " failed to start listening for incoming Awdl connections " + "to service_id=" + << service_id; + return {Error(awdl_result.error().operation_result_code().value())}; + } + LOG(INFO) << "In StartAwdlAdvertising(" + << absl::BytesToHexString(local_endpoint_info.data()) + << "), client=" << client->GetClientId() + << " started listening for incoming Awdl connections " + "to service_id = " + << service_id; + } + + // Generate a WifiLanServiceInfo with which to become AWDL discoverable. + 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()) { + LOG(WARNING) << "In StartAwdlAdvertising(" + << 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()) << "}."; + awdl_medium_.StopAcceptingConnections(service_id); + return { + Error(OperationResultCode::NEARBY_WIFI_LAN_ADVERTISE_TO_BYTES_FAILURE)}; + } + LOG(INFO) << "In StartAwdlAdvertising(" + << absl::BytesToHexString(local_endpoint_info.data()) + << "), client=" << client->GetClientId() + << " generated WifiLanServiceInfo " + << nsd_service_info.GetServiceName() + << " with service_id=" << service_id; + + ErrorOr awdl_result = + awdl_medium_.StartAdvertising(service_id, nsd_service_info); + if (awdl_result.has_error()) { + LOG(INFO) << "In StartAwdlAdvertising(" + << absl::BytesToHexString(local_endpoint_info.data()) + << "), client=" << client->GetClientId() + << " couldn't advertise with WifiLanServiceInfo " + << nsd_service_info.GetServiceName(); + awdl_medium_.StopAcceptingConnections(service_id); + return {Error(awdl_result.error().operation_result_code().value())}; + } + LOG(INFO) << "In StartAwdlAdvertising(" + << absl::BytesToHexString(local_endpoint_info.data()) + << "), client=" << client->GetClientId() + << " advertised with WifiLanServiceInfo " + << nsd_service_info.GetServiceName(); + return {AWDL}; +} + ErrorOr P2pClusterPcpHandler::StartWifiLanAdvertising( ClientProxy* client, const std::string& service_id, const std::string& local_endpoint_id, const ByteArray& local_endpoint_info, @@ -2883,6 +3236,30 @@ ErrorOr P2pClusterPcpHandler::StartWifiLanAdvertising( return {WIFI_LAN}; } +ErrorOr P2pClusterPcpHandler::StartAwdlDiscovery( + ClientProxy* client, const std::string& service_id) { + ErrorOr result = awdl_medium_.StartDiscovery( + service_id, + { + .service_discovered_cb = absl::bind_front( + &P2pClusterPcpHandler::AwdlServiceDiscoveredHandler, this, + client), + .service_lost_cb = absl::bind_front( + &P2pClusterPcpHandler::AwdlServiceLostHandler, this, client), + }); + if (!result.has_error()) { + LOG(INFO) << "In StartAwdlDiscovery(), client=" << client->GetClientId() + << " started scanning for Wifi devices for service_id=" + << service_id; + return {AWDL}; + } else { + LOG(INFO) << "In StartAwdlDiscovery(), client=" << client->GetClientId() + << " couldn't start scanning on Wifi for service_id=" + << service_id; + return {Error(result.error().operation_result_code().value())}; + } +} + ErrorOr P2pClusterPcpHandler::StartWifiLanDiscovery( ClientProxy* client, const std::string& service_id) { ErrorOr result = wifi_lan_medium_.StartDiscovery( @@ -2907,6 +3284,42 @@ ErrorOr P2pClusterPcpHandler::StartWifiLanDiscovery( } } +BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::AwdlConnectImpl( + ClientProxy* client, AwdlEndpoint* endpoint) { + LOG(INFO) << "Client " << client->GetClientId() + << " is attempting to connect to endpoint(id=" + << endpoint->endpoint_id << ") over Awdl."; + ErrorOr socket_result = + awdl_medium_.Connect(endpoint->service_id, endpoint->service_info, + client->GetCancellationFlag(endpoint->endpoint_id)); + if (socket_result.has_error()) { + LOG(ERROR) << "In AwdlConnectImpl(), failed to connect to service " + << endpoint->service_info.GetServiceName() + << " for endpoint(id=" << endpoint->endpoint_id << ")."; + return BasePcpHandler::ConnectImplResult{ + .status = {Status::kWifiLanError}, + .operation_result_code = + socket_result.error().operation_result_code().value(), + }; + } + LOG(INFO) << "In AwdlConnectImpl(), connect to service " + << " socket=" << &socket_result.value().GetImpl() + << " for endpoint(id=" << endpoint->endpoint_id << ")."; + + auto channel = std::make_unique( + endpoint->service_id, /*channel_name=*/endpoint->endpoint_id, + socket_result.value()); + LOG(INFO) << "Client " << client->GetClientId() + << " created Awdl endpoint channel to endpoint(id=" + << endpoint->endpoint_id << ")."; + return BasePcpHandler::ConnectImplResult{ + .medium = AWDL, + .status = {Status::kSuccess}, + .operation_result_code = OperationResultCode::DETAIL_SUCCESS, + .endpoint_channel = std::move(channel), + }; +} + BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::WifiLanConnectImpl( ClientProxy* client, WifiLanEndpoint* endpoint) { LOG(INFO) << "Client " << client->GetClientId() diff --git a/connections/implementation/p2p_cluster_pcp_handler.h b/connections/implementation/p2p_cluster_pcp_handler.h index 3b63ad73..510849f2 100644 --- a/connections/implementation/p2p_cluster_pcp_handler.h +++ b/connections/implementation/p2p_cluster_pcp_handler.h @@ -32,6 +32,7 @@ #include "connections/implementation/endpoint_channel_manager.h" #include "connections/implementation/endpoint_manager.h" #include "connections/implementation/injected_bluetooth_device_store.h" +#include "connections/implementation/mediums/awdl.h" #include "connections/implementation/mediums/ble.h" #include "connections/implementation/mediums/ble_v2.h" #include "connections/implementation/mediums/bluetooth_classic.h" @@ -166,6 +167,7 @@ class P2pClusterPcpHandler : public BasePcpHandler { using BleDiscoveredPeripheralCallback = Ble::DiscoveredPeripheralCallback; using BleV2DiscoveredPeripheralCallback = BleV2::DiscoveredPeripheralCallback; using WifiLanDiscoveredServiceCallback = WifiLan::DiscoveredServiceCallback; + using AwdlDiscoveredServiceCallback = Awdl::DiscoveredServiceCallback; static constexpr BluetoothDeviceName::Version kBluetoothDeviceNameVersion = BluetoothDeviceName::Version::kV1; @@ -279,9 +281,29 @@ class P2pClusterPcpHandler : public BasePcpHandler { const DiscoveryOptions& discovery_options); BasePcpHandler::ConnectImplResult BleV2ConnectImpl(ClientProxy* client, BleV2Endpoint* endpoint); + // Awdl + void AwdlServiceDiscoveredHandler(ClientProxy* client, + NsdServiceInfo service_info, + const std::string& service_id); + void AwdlServiceLostHandler(ClientProxy* client, NsdServiceInfo service_info, + const std::string& service_id); + void AwdlConnectionAcceptedHandler(ClientProxy* client, + absl::string_view local_endpoint_id, + absl::string_view local_endpoint_info, + NearbyDevice::Type device_type, + const std::string& service_id, + AwdlSocket socket); + BasePcpHandler::ConnectImplResult AwdlConnectImpl(ClientProxy* client, + AwdlEndpoint* endpoint); + ErrorOr StartAwdlAdvertising( + ClientProxy* client, const std::string& service_id, + const std::string& local_endpoint_id, + const ByteArray& local_endpoint_info, WebRtcState web_rtc_state); + ErrorOr StartAwdlDiscovery( + ClientProxy* client, const std::string& service_id); // WifiLan - bool IsRecognizedWifiLanEndpoint( + bool IsRecognizedWifiServiceEndpoint( const std::string& service_id, const WifiLanServiceInfo& wifi_lan_service_info) const; void WifiLanServiceDiscoveredHandler(ClientProxy* client, @@ -305,6 +327,7 @@ class P2pClusterPcpHandler : public BasePcpHandler { BasePcpHandler::ConnectImplResult WifiLanConnectImpl( ClientProxy* client, WifiLanEndpoint* endpoint); + Awdl& awdl_medium_; BluetoothRadio& bluetooth_radio_; BluetoothClassic& bluetooth_medium_; Ble& ble_medium_; diff --git a/connections/implementation/p2p_cluster_pcp_handler_test.cc b/connections/implementation/p2p_cluster_pcp_handler_test.cc index ef183012..4c404b76 100644 --- a/connections/implementation/p2p_cluster_pcp_handler_test.cc +++ b/connections/implementation/p2p_cluster_pcp_handler_test.cc @@ -1186,6 +1186,164 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, env_.Stop(); } +TEST_F(P2pClusterPcpHandlerTest, CanAwdlDiscovery) { + std::string endpoint_name{"endpoint_name"}; + + env_.Start(); + Mediums mediums_a; + EndpointChannelManager ecm_a; + EndpointManager em_a(&ecm_a); + InjectedBluetoothDeviceStore ibds_a; + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, {}); + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a, ibds_a); + + EXPECT_EQ(handler_a.StartDiscovery(&client_a_, service_id_, + DiscoveryOptions{ + {Strategy::kP2pCluster, + BooleanMediumSelector{ + .awdl = true, + }}, + }, + {}), + Status{Status::kSuccess}); + + EXPECT_TRUE(mediums_a.GetAwdl().IsDiscovering(service_id_)); + + handler_a.StopDiscovery(&client_a_); + env_.Stop(); +} + +TEST_F(P2pClusterPcpHandlerTest, CanAwdlWifiLanDiscovery) { + std::string endpoint_name{"endpoint_name"}; + + env_.Start(); + Mediums mediums_a; + EndpointChannelManager ecm_a; + EndpointManager em_a(&ecm_a); + InjectedBluetoothDeviceStore ibds_a; + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, {}); + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a, ibds_a); + + EXPECT_EQ(handler_a.StartDiscovery(&client_a_, service_id_, + DiscoveryOptions{ + {Strategy::kP2pCluster, + BooleanMediumSelector{ + .wifi_lan = true, + .awdl = true, + }}, + }, + {}), + Status{Status::kSuccess}); + + EXPECT_TRUE(mediums_a.GetAwdl().IsDiscovering(service_id_)); + EXPECT_TRUE(mediums_a.GetWifiLan().IsDiscovering(service_id_)); + + handler_a.StopDiscovery(&client_a_); + env_.Stop(); +} + +TEST_F(P2pClusterPcpHandlerTest, CanAwdlAdvertise) { + env_.Start(); + std::string endpoint_name{"endpoint_name"}; + Mediums mediums_a; + EndpointChannelManager ecm_a; + EndpointManager em_a(&ecm_a); + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, {}); + InjectedBluetoothDeviceStore ibds_a; + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a, ibds_a); + EXPECT_EQ( + handler_a.StartAdvertising(&client_a_, service_id_, + AdvertisingOptions{{Strategy::kP2pCluster, + BooleanMediumSelector{ + .awdl = true, + }}}, + {.endpoint_info = ByteArray{endpoint_name}}), + Status{Status::kSuccess}); + EXPECT_TRUE(mediums_a.GetAwdl().IsAdvertising(service_id_)); + EXPECT_FALSE(mediums_a.GetWifiLan().IsAdvertising(service_id_)); + handler_a.StopAdvertising(&client_a_); + env_.Stop(); +} + +TEST_F(P2pClusterPcpHandlerTest, CanAwdlWifiLanAdvertise) { + env_.Start(); + std::string endpoint_name{"endpoint_name"}; + Mediums mediums_a; + EndpointChannelManager ecm_a; + EndpointManager em_a(&ecm_a); + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, {}); + InjectedBluetoothDeviceStore ibds_a; + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a, ibds_a); + EXPECT_EQ( + handler_a.StartAdvertising(&client_a_, service_id_, + AdvertisingOptions{{Strategy::kP2pCluster, + BooleanMediumSelector{ + .wifi_lan = true, + .awdl = true, + }}}, + {.endpoint_info = ByteArray{endpoint_name}}), + Status{Status::kSuccess}); + EXPECT_TRUE(mediums_a.GetAwdl().IsAdvertising(service_id_)); + EXPECT_TRUE(mediums_a.GetWifiLan().IsAdvertising(service_id_)); + handler_a.StopAdvertising(&client_a_); + env_.Stop(); +} + +TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateAwdlDiscoveryOptions) { + env_.Start(); + std::string endpoint_name{"endpoint_name"}; + Mediums mediums_a; + EndpointChannelManager ecm_a; + EndpointManager em_a(&ecm_a); + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, {}); + InjectedBluetoothDeviceStore ibds_a; + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a, ibds_a); + discovery_options_.allowed.wifi_lan = true; + discovery_options_.allowed.awdl = false; + EXPECT_EQ( + handler_a.StartDiscovery(&client_a_, service_id_, discovery_options_, {}), + Status{Status::kSuccess}); + EXPECT_TRUE(mediums_a.GetWifiLan().IsDiscovering(service_id_)); + EXPECT_FALSE(mediums_a.GetAwdl().IsDiscovering(service_id_)); + discovery_options_.allowed.wifi_lan = false; + discovery_options_.allowed.awdl = true; + EXPECT_EQ(handler_a.UpdateDiscoveryOptions(&client_a_, service_id_, + discovery_options_), + Status{Status::kSuccess}); + EXPECT_FALSE(mediums_a.GetWifiLan().IsDiscovering(service_id_)); + EXPECT_TRUE(mediums_a.GetAwdl().IsDiscovering(service_id_)); + handler_a.StopDiscovery(&client_a_); + env_.Stop(); +} + +TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateAwdlAdvertisingOptions) { + env_.Start(); + std::string endpoint_name{"endpoint_name"}; + Mediums mediums_a; + EndpointChannelManager ecm_a; + EndpointManager em_a(&ecm_a); + BwuManager bwu_a(mediums_a, em_a, ecm_a, {}, {}); + InjectedBluetoothDeviceStore ibds_a; + P2pClusterPcpHandler handler_a(&mediums_a, &em_a, &ecm_a, &bwu_a, ibds_a); + advertising_options_.allowed.wifi_lan = true; + EXPECT_EQ( + handler_a.StartAdvertising(&client_a_, service_id_, advertising_options_, + {.endpoint_info = ByteArray{endpoint_name}}), + Status{Status::kSuccess}); + // EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsAdvertising(service_id_)); + EXPECT_TRUE(mediums_a.GetWifiLan().IsAdvertising(service_id_)); + EXPECT_FALSE(mediums_a.GetAwdl().IsAdvertising(service_id_)); + advertising_options_.allowed.wifi_lan = false; + advertising_options_.allowed.awdl = true; + EXPECT_EQ(handler_a.UpdateAdvertisingOptions(&client_a_, service_id_, + advertising_options_), + Status{Status::kSuccess}); + EXPECT_FALSE(mediums_a.GetWifiLan().IsAdvertising(service_id_)); + EXPECT_TRUE(mediums_a.GetAwdl().IsAdvertising(service_id_)); + handler_a.StopAdvertising(&client_a_); + env_.Stop(); +} + INSTANTIATE_TEST_SUITE_P( ParametrisedPcpHandlerTest, P2pClusterPcpHandlerTestWithParam, ::testing::Combine(/*mediums=*/::testing::ValuesIn(kTestCases), diff --git a/connections/implementation/service_controller_router.cc b/connections/implementation/service_controller_router.cc index 9ae8f3e1..1cf666f9 100644 --- a/connections/implementation/service_controller_router.cc +++ b/connections/implementation/service_controller_router.cc @@ -741,7 +741,8 @@ ServiceController* ServiceControllerRouter::GetServiceController() { /*web_rtc=*/true, /*wifi_lan=*/true, /*wifi_hotspot=*/false, - /*wifi_direct=*/true}; + /*wifi_direct=*/true, + /*awdl=*/false}; service_controller_ = std::make_unique(bwu_config); } else { diff --git a/connections/implementation/service_controller_router_test.cc b/connections/implementation/service_controller_router_test.cc index c55a7671..b55a0c40 100644 --- a/connections/implementation/service_controller_router_test.cc +++ b/connections/implementation/service_controller_router_test.cc @@ -1347,7 +1347,8 @@ TEST(ServiceControllerRouterCheckHpRealtekDeviceTest, testing::FieldsAre(/*bluetooth=*/false, /*ble=*/false, /*web_rtc_no_cellular=*/false, /*web_rtc=*/true, /*wifi_lan=*/true, - /*wifi_hotspot=*/false, /*wifi_direct=*/true)); + /*wifi_hotspot=*/false, /*wifi_direct=*/true, + /*awdl=*/false)); } TEST(ServiceControllerRouterCheckHpRealtekDeviceTest, @@ -1363,7 +1364,8 @@ TEST(ServiceControllerRouterCheckHpRealtekDeviceTest, testing::FieldsAre(/*bluetooth=*/false, /*ble=*/false, /*web_rtc_no_cellular=*/false, /*web_rtc=*/true, /*wifi_lan=*/true, - /*wifi_hotspot=*/true, /*wifi_direct=*/true)); + /*wifi_hotspot=*/true, /*wifi_direct=*/true, + /*awdl=*/false)); } } // namespace diff --git a/connections/medium_selector.h b/connections/medium_selector.h index d6237166..9a0b3a77 100644 --- a/connections/medium_selector.h +++ b/connections/medium_selector.h @@ -31,22 +31,24 @@ struct BooleanMediumSelector { bool wifi_lan = false; bool wifi_hotspot = false; bool wifi_direct = false; - + bool awdl = false; constexpr bool Any(bool value) const { return bluetooth == value || ble == value || web_rtc_no_cellular == value || web_rtc == value || wifi_lan == value || wifi_hotspot == value || - wifi_direct == value; + wifi_direct == value || awdl == value; } constexpr bool All(bool value) const { return bluetooth == value && ble == value && (web_rtc == value || web_rtc_no_cellular == value) && - wifi_lan == value && wifi_hotspot == value && wifi_direct == value; + awdl == value && wifi_lan == value && wifi_hotspot == value && + wifi_direct == value; } constexpr int Count(bool value) const { int count = 0; + if (awdl == value) count++; if (bluetooth == value) count++; if (ble == value) count++; if (wifi_lan == value) count++; @@ -63,6 +65,7 @@ struct BooleanMediumSelector { wifi_lan = value; wifi_hotspot = value; wifi_direct = value; + awdl = value; return *this; } @@ -83,6 +86,7 @@ struct BooleanMediumSelector { } if (bluetooth == value) mediums.push_back(Medium::BLUETOOTH); if (ble == value) mediums.push_back(Medium::BLE); + if (awdl == value) mediums.push_back(Medium::AWDL); return mediums; } };