Implement AWDL in connection layer (part 2)

PiperOrigin-RevId: 744206141
This commit is contained in:
hai007
2025-04-05 01:49:16 -07:00
committed by Copybara-Service
parent 190bb141cc
commit cc2c6c527b
16 changed files with 742 additions and 12 deletions
+4
View File
@@ -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;
+2 -1
View File
@@ -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 {
+6
View File
@@ -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] =
+1
View File
@@ -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)
};
+2 -1
View File
@@ -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",
@@ -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 <string>
#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
@@ -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 <string>
#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_
@@ -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<ConnectionsLog::OperationResultWithMedium>
@@ -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)
@@ -93,6 +93,9 @@ constexpr auto kDisableInstantOnLostOnBleWithoutExtended =
constexpr auto kEnableMultiplexAwdl =
flags::Flag<bool>(kConfigPackage, "45696647", true);
// Enable/Disable AWDL in Nearby connections SDK.
constexpr auto kEnableAwdl =
flags::Flag<bool>(kConfigPackage, "45669531", true);
} // namespace nearby_connections_feature
} // namespace config_package_nearby
} // namespace connections
@@ -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<Medium> 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<ConnectionsLog::OperationResultWithMedium>
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<Medium> 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>(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<ConnectionsLog::OperationResultWithMedium>
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<Medium> 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<ConnectionsLog::OperationResultWithMedium>
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<Medium> 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<AwdlEndpoint*>(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<ConnectionsLog::OperationResultWithMedium>
operation_result_with_medium =
GetOperationResultWithMediumByResultCode(
client, AWDL, update_index,
OperationResultCode::DETAIL_SUCCESS);
operation_result_with_mediums.push_back(*operation_result_with_medium);
} else {
ErrorOr<Medium> 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<ConnectionsLog::OperationResultWithMedium>
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<ConnectionsLog::OperationResultWithMedium>
operation_result_with_medium =
GetOperationResultWithMediumByResultCode(
client, AWDL, update_index,
OperationResultCode::DETAIL_SUCCESS);
operation_result_with_mediums.push_back(*operation_result_with_medium);
} else {
ErrorOr<Medium> 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<ConnectionsLog::OperationResultWithMedium>
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<AwdlEndpointChannel>(
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<Medium> 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<bool> 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<int>(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<bool> 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<Medium> 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<Medium> P2pClusterPcpHandler::StartWifiLanAdvertising(
return {WIFI_LAN};
}
ErrorOr<Medium> P2pClusterPcpHandler::StartAwdlDiscovery(
ClientProxy* client, const std::string& service_id) {
ErrorOr<bool> 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<Medium> P2pClusterPcpHandler::StartWifiLanDiscovery(
ClientProxy* client, const std::string& service_id) {
ErrorOr<bool> result = wifi_lan_medium_.StartDiscovery(
@@ -2907,6 +3284,42 @@ ErrorOr<Medium> 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<AwdlSocket> 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<AwdlEndpointChannel>(
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()
@@ -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<location::nearby::proto::connections::Medium> StartAwdlAdvertising(
ClientProxy* client, const std::string& service_id,
const std::string& local_endpoint_id,
const ByteArray& local_endpoint_info, WebRtcState web_rtc_state);
ErrorOr<location::nearby::proto::connections::Medium> 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_;
@@ -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),
@@ -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<OfflineServiceController>(bwu_config);
} else {
@@ -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
+7 -3
View File
@@ -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;
}
};