mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Add advertising logic for DCT
PiperOrigin-RevId: 733752366
This commit is contained in:
committed by
Copybara-Service
parent
18f52de400
commit
553f5dbf01
@@ -119,6 +119,8 @@ cc_library(
|
||||
"//connections/implementation/flags:connections_flags",
|
||||
"//connections/implementation/mediums",
|
||||
"//connections/implementation/mediums:utils",
|
||||
"//connections/implementation/mediums/advertisements:dct_advertisement",
|
||||
"//connections/implementation/mediums/advertisements:util",
|
||||
"//connections/implementation/proto:offline_wire_formats_cc_proto",
|
||||
"//connections/v3:v3_types",
|
||||
"//internal/analytics:event_logger",
|
||||
@@ -146,6 +148,7 @@ cc_library(
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/functional:bind_front",
|
||||
"@com_google_absl//absl/log:check",
|
||||
"@com_google_absl//absl/random",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@@ -43,6 +44,7 @@
|
||||
#include "connections/implementation/endpoint_channel_manager.h"
|
||||
#include "connections/implementation/endpoint_manager.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/implementation/mediums/advertisements/advertisement_util.h"
|
||||
#include "connections/implementation/mediums/mediums.h"
|
||||
#include "connections/implementation/mediums/utils.h"
|
||||
#include "connections/implementation/mediums/webrtc_peer_id.h"
|
||||
@@ -249,6 +251,18 @@ Status BasePcpHandler::StartAdvertising(
|
||||
}
|
||||
}
|
||||
|
||||
if (client->IsDctEnabled()) {
|
||||
// Update the device name.
|
||||
std::optional<std::string> device_name =
|
||||
nearby::connections::advertisements::ReadDeviceName(
|
||||
info.endpoint_info);
|
||||
if (device_name.has_value()) {
|
||||
client->UpdateDctDeviceName(device_name.value());
|
||||
} else {
|
||||
LOG(ERROR) << "DCT only supports everyone mode for now.";
|
||||
}
|
||||
}
|
||||
|
||||
auto result = StartAdvertisingImpl(
|
||||
client, service_id, client->GetLocalEndpointId(),
|
||||
info.endpoint_info, compatible_advertising_options);
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/random/random.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "connections/advertising_options.h"
|
||||
#include "connections/connection_options.h"
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "connections/implementation/analytics/analytics_recorder.h"
|
||||
#include "connections/implementation/analytics/discovery_metadata_params.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/implementation/mediums/advertisements/dct_advertisement.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/payload.h"
|
||||
@@ -107,6 +108,9 @@ ClientProxy::ClientProxy(::nearby::analytics::EventLogger* event_logger)
|
||||
NEARBY_LOGS(INFO) << "[safe-to-disconnect]: Local enabled: "
|
||||
<< supports_safe_to_disconnect_
|
||||
<< "; Version: " << local_safe_to_disconnect_version_;
|
||||
// Generate a 7 bits dedup value.
|
||||
absl::BitGen bitgen;
|
||||
dct_dedup_ = absl::Uniform(bitgen, 0, 1 << 7);
|
||||
}
|
||||
|
||||
ClientProxy::~ClientProxy() { Reset(); }
|
||||
@@ -115,24 +119,29 @@ std::int64_t ClientProxy::GetClientId() const { return client_id_; }
|
||||
|
||||
std::string ClientProxy::GetLocalEndpointId() {
|
||||
MutexLock lock(&mutex_);
|
||||
if (!local_endpoint_id_.empty()) {
|
||||
NEARBY_LOGS(INFO) << __func__
|
||||
<< ": Reusing cached endpoint id: " << local_endpoint_id_;
|
||||
if (IsDctEnabled() && GetEndpointIdForDct().has_value()) {
|
||||
NEARBY_LOGS(INFO) << "DCT is using genereted endpoint id.";
|
||||
return GetEndpointIdForDct().value();
|
||||
} else {
|
||||
if (!local_endpoint_id_.empty()) {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Reusing cached endpoint id: "
|
||||
<< local_endpoint_id_;
|
||||
return local_endpoint_id_;
|
||||
}
|
||||
if (external_device_provider_ == nullptr) {
|
||||
local_endpoint_id_ = GenerateLocalEndpointId();
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Locally generating endpoint id: "
|
||||
<< local_endpoint_id_;
|
||||
} else {
|
||||
local_endpoint_id_ =
|
||||
external_device_provider_->GetLocalDevice()->GetEndpointId();
|
||||
NEARBY_LOGS(INFO)
|
||||
<< __func__
|
||||
<< ": From external device provider, populating endpoint id: "
|
||||
<< local_endpoint_id_;
|
||||
}
|
||||
return local_endpoint_id_;
|
||||
}
|
||||
if (external_device_provider_ == nullptr) {
|
||||
local_endpoint_id_ = GenerateLocalEndpointId();
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Locally generating endpoint id: "
|
||||
<< local_endpoint_id_;
|
||||
} else {
|
||||
local_endpoint_id_ =
|
||||
external_device_provider_->GetLocalDevice()->GetEndpointId();
|
||||
NEARBY_LOGS(INFO)
|
||||
<< __func__
|
||||
<< ": From external device provider, populating endpoint id: "
|
||||
<< local_endpoint_id_;
|
||||
}
|
||||
return local_endpoint_id_;
|
||||
}
|
||||
|
||||
const NearbyDevice* ClientProxy::GetLocalDevice() {
|
||||
@@ -1301,6 +1310,48 @@ void ClientProxy::SetWebRtcNonCellular(bool webrtc_non_cellular) {
|
||||
webrtc_non_cellular_ = webrtc_non_cellular;
|
||||
}
|
||||
|
||||
bool ClientProxy::IsDctEnabled() const {
|
||||
if (api::ImplementationPlatform::GetCurrentOS() != api::OSName::kApple) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(NC_IOS_SDK)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t ClientProxy::GetDctDedup() const { return dct_dedup_; }
|
||||
|
||||
void ClientProxy::UpdateDctDeviceName(absl::string_view device_name) {
|
||||
if (!dct_device_name_.empty() && dct_device_name_ != device_name) {
|
||||
// Need to update dedup value if device name is changed.
|
||||
absl::BitGen bitgen;
|
||||
dct_dedup_ = absl::Uniform(bitgen, 0, 1 << 7);
|
||||
}
|
||||
|
||||
dct_device_name_ = device_name;
|
||||
|
||||
// The DCT endpoint ID should be derived from device name and dedup value.
|
||||
std::optional<std::string> dct_endpoint_id =
|
||||
advertisements::ble::DctAdvertisement::GenerateEndpointId(
|
||||
dct_dedup_, dct_device_name_);
|
||||
if (dct_endpoint_id.has_value()) {
|
||||
dct_endpoint_id_ = *dct_endpoint_id;
|
||||
} else {
|
||||
dct_endpoint_id_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::string> ClientProxy::GetEndpointIdForDct() const {
|
||||
if (dct_endpoint_id_.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return dct_endpoint_id_;
|
||||
}
|
||||
|
||||
std::string ClientProxy::ToString(PayloadProgressInfo::Status status) const {
|
||||
switch (status) {
|
||||
case PayloadProgressInfo::Status::kSuccess:
|
||||
|
||||
@@ -339,6 +339,17 @@ class ClientProxy final {
|
||||
// Sets the WebRTC non cellular network status.
|
||||
void SetWebRtcNonCellular(bool webrtc_non_cellular);
|
||||
|
||||
// Returns true if DCT advertising/scanning is enabled.
|
||||
bool IsDctEnabled() const;
|
||||
|
||||
// Gets the DCT dedup value. This is used to dedup the same device name when
|
||||
// scanning for multiple devices.
|
||||
// It is 7 bits derived from the local endpoint ID.
|
||||
uint8_t GetDctDedup() const;
|
||||
|
||||
// Updates the DCT device name before advertising.
|
||||
void UpdateDctDeviceName(absl::string_view device_name);
|
||||
|
||||
/** Bitmask for bt multiplex connection support. */
|
||||
// Note. Deprecates the first and second bit of BT_MULTIPLEX_ENABLED and
|
||||
// WIFI_LAN_MULTIPLEX_ENABLED and shift them to the third and the forth bit.
|
||||
@@ -436,6 +447,15 @@ class ClientProxy final {
|
||||
|
||||
std::string ToString(PayloadProgressInfo::Status status) const;
|
||||
|
||||
std::optional<std::string> GetEndpointIdForDct() const;
|
||||
|
||||
// The device name used for DCT advertising.
|
||||
std::string dct_device_name_;
|
||||
// The dedup value used for DCT advertising.
|
||||
uint8_t dct_dedup_ = 0;
|
||||
// The endpoint ID used for DCT advertising.
|
||||
std::string dct_endpoint_id_;
|
||||
|
||||
mutable RecursiveMutex mutex_;
|
||||
std::int64_t client_id_;
|
||||
std::string local_endpoint_id_;
|
||||
|
||||
@@ -22,7 +22,6 @@ cc_library(
|
||||
name = "common",
|
||||
srcs = ["data_element.cc"],
|
||||
hdrs = ["data_element.h"],
|
||||
compatible_with = ["//buildenv/target:non_prod"],
|
||||
deps = [
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:logging",
|
||||
@@ -35,7 +34,6 @@ cc_library(
|
||||
name = "dct_advertisement",
|
||||
srcs = ["dct_advertisement.cc"],
|
||||
hdrs = ["dct_advertisement.h"],
|
||||
compatible_with = ["//buildenv/target:non_prod"],
|
||||
deps = [
|
||||
":common",
|
||||
"//internal/crypto_cros",
|
||||
@@ -51,7 +49,6 @@ cc_library(
|
||||
name = "util",
|
||||
srcs = ["advertisement_util.cc"],
|
||||
hdrs = ["advertisement_util.h"],
|
||||
compatible_with = ["//buildenv/target:non_prod"],
|
||||
deps = [
|
||||
":dct_advertisement",
|
||||
"//internal/platform:base",
|
||||
|
||||
@@ -149,6 +149,27 @@ ErrorOr<bool> BleV2::StartAdvertising(const std::string& service_id,
|
||||
return {Error(OperationResultCode::MEDIUM_UNAVAILABLE_BLE_NOT_AVAILABLE)};
|
||||
}
|
||||
|
||||
if (advertising_type == AdvertisingType::kDct) {
|
||||
advertising_infos_.insert(
|
||||
{service_id, AdvertisingInfo{.dct_advertisement = advertisement_bytes,
|
||||
.power_level = power_level,
|
||||
.advertising_type = advertising_type}});
|
||||
|
||||
if (!StartDctAdvertisingLocked(service_id, power_level,
|
||||
advertisement_bytes)) {
|
||||
LOG(ERROR) << "Failed to start BLE DCT advertising for service_id="
|
||||
<< service_id;
|
||||
advertising_infos_.erase(service_id);
|
||||
return {Error(
|
||||
OperationResultCode::CONNECTIVITY_BLE_START_ADVERTISING_FAILURE)};
|
||||
}
|
||||
|
||||
LOG(INFO) << "Successfully started BLE DCT advertising for service_id="
|
||||
<< service_id << " with advetsiement data "
|
||||
<< absl::BytesToHexString(advertisement_bytes.AsStringView());
|
||||
return {true};
|
||||
}
|
||||
|
||||
// Wrap the connections advertisement to the medium advertisement.
|
||||
ByteArray service_id_hash = mediums::bleutils::GenerateHash(
|
||||
service_id, mediums::BleAdvertisement::kServiceIdHashLength);
|
||||
@@ -171,11 +192,9 @@ ErrorOr<bool> BleV2::StartAdvertising(const std::string& service_id,
|
||||
}
|
||||
|
||||
advertising_infos_.insert(
|
||||
{service_id,
|
||||
AdvertisingInfo{.medium_advertisement = medium_advertisement,
|
||||
.power_level = power_level,
|
||||
.is_fast_advertisement =
|
||||
advertising_type == AdvertisingType::kFast}});
|
||||
{service_id, AdvertisingInfo{.medium_advertisement = medium_advertisement,
|
||||
.power_level = power_level,
|
||||
.advertising_type = advertising_type}});
|
||||
|
||||
// TODO(hais): need to update here after cros support RAII StartAdvertising.
|
||||
// After all platforms support RAII StartAdvertising, then we can stop
|
||||
@@ -908,7 +927,7 @@ bool BleV2::StartAdvertisingLocked(const std::string& service_id) {
|
||||
}
|
||||
|
||||
const AdvertisingInfo& info = it->second;
|
||||
if (info.is_fast_advertisement) {
|
||||
if (info.advertising_type == AdvertisingType::kFast) {
|
||||
return StartFastAdvertisingLocked(service_id, info.power_level,
|
||||
info.medium_advertisement);
|
||||
} else {
|
||||
@@ -1078,6 +1097,20 @@ bool BleV2::StartGattAdvertisingLocked(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BleV2::StartDctAdvertisingLocked(const std::string& service_id,
|
||||
PowerLevel power_level,
|
||||
const ByteArray& dct_advertisement) {
|
||||
BleAdvertisementData advertising_data;
|
||||
advertising_data.is_extended_advertisement = false;
|
||||
advertising_data.service_data.insert(
|
||||
{mediums::bleutils::kDctServiceUuid, dct_advertisement});
|
||||
|
||||
return medium_.StartAdvertising(
|
||||
advertising_data,
|
||||
{.tx_power_level = PowerLevelToTxPowerLevel(power_level),
|
||||
.is_connectable = false});
|
||||
}
|
||||
|
||||
bool BleV2::StartAsyncScanningLocked(absl::string_view service_id,
|
||||
PowerLevel power_level) {
|
||||
CHECK(FeatureFlags::GetInstance().GetFlags().enable_ble_v2_async_scanning);
|
||||
|
||||
@@ -166,8 +166,9 @@ class BleV2 final {
|
||||
private:
|
||||
struct AdvertisingInfo {
|
||||
mediums::BleAdvertisement medium_advertisement;
|
||||
ByteArray dct_advertisement;
|
||||
PowerLevel power_level;
|
||||
bool is_fast_advertisement;
|
||||
AdvertisingType advertising_type;
|
||||
};
|
||||
|
||||
// Same as IsAvailable(), but must be called with `mutex_` held.
|
||||
@@ -230,6 +231,10 @@ class BleV2 final {
|
||||
const ByteArray& medium_advertisement_bytes,
|
||||
bool extended_advertisement_advertised)
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
bool StartDctAdvertisingLocked(const std::string& service_id,
|
||||
PowerLevel power_level,
|
||||
const ByteArray& dct_advertisement)
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
// Called by StartScanning when using the async methods.
|
||||
bool StartAsyncScanningLocked(absl::string_view service_id,
|
||||
PowerLevel power_level)
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -39,6 +41,8 @@
|
||||
#include "connections/implementation/endpoint_manager.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/implementation/injected_bluetooth_device_store.h"
|
||||
#include "connections/implementation/mediums/advertisements/advertisement_util.h"
|
||||
#include "connections/implementation/mediums/advertisements/dct_advertisement.h"
|
||||
#include "connections/implementation/mediums/ble_v2.h"
|
||||
#include "connections/implementation/mediums/bluetooth_classic.h"
|
||||
#include "connections/implementation/mediums/mediums.h"
|
||||
@@ -2538,7 +2542,24 @@ ErrorOr<Medium> P2pClusterPcpHandler::StartBleV2Advertising(
|
||||
local_endpoint_info, bluetooth_mac_address,
|
||||
/*uwb_address=*/ByteArray{}, web_rtc_state));
|
||||
}
|
||||
if (advertisement_bytes.Empty()) {
|
||||
|
||||
ByteArray dct_advertisement_bytes;
|
||||
if (client->IsDctEnabled()) {
|
||||
// Try to read device name from local_endpoint_info.
|
||||
std::optional<std::string> device_name =
|
||||
advertisements::ReadDeviceName(local_endpoint_info);
|
||||
// TODO(b/399740422): Get the real PSM from the L2CAP medium.
|
||||
uint16_t psm = 0x11;
|
||||
if (device_name.has_value()) {
|
||||
std::optional<advertisements::ble::DctAdvertisement> dct_advertisement =
|
||||
advertisements::ble::DctAdvertisement::Create(
|
||||
service_id, *device_name, psm, client->GetDctDedup());
|
||||
if (dct_advertisement.has_value()) {
|
||||
dct_advertisement_bytes = ByteArray(dct_advertisement->ToData());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (advertisement_bytes.Empty() && dct_advertisement_bytes.Empty()) {
|
||||
LOG(WARNING) << "In StartBleV2Advertising("
|
||||
<< absl::BytesToHexString(local_endpoint_info.data())
|
||||
<< "), client=" << client->GetClientId()
|
||||
@@ -2552,12 +2573,19 @@ ErrorOr<Medium> P2pClusterPcpHandler::StartBleV2Advertising(
|
||||
<< "), client=" << client->GetClientId()
|
||||
<< " generated BleAdvertisement with service_id=" << service_id;
|
||||
|
||||
ErrorOr<bool> ble_v2_result = ble_v2_medium_.StartAdvertising(
|
||||
service_id, power_level,
|
||||
advertising_options.fast_advertisement_service_uuid.empty()
|
||||
? BleV2::AdvertisingType::kRegular
|
||||
: BleV2::AdvertisingType::kFast,
|
||||
advertisement_bytes);
|
||||
ErrorOr<bool> ble_v2_result = false;
|
||||
if (dct_advertisement_bytes.Empty()) {
|
||||
ble_v2_result = ble_v2_medium_.StartAdvertising(
|
||||
service_id, power_level,
|
||||
advertising_options.fast_advertisement_service_uuid.empty()
|
||||
? BleV2::AdvertisingType::kRegular
|
||||
: BleV2::AdvertisingType::kFast,
|
||||
advertisement_bytes);
|
||||
} else {
|
||||
ble_v2_result = ble_v2_medium_.StartAdvertising(
|
||||
service_id, power_level, BleV2::AdvertisingType::kDct,
|
||||
dct_advertisement_bytes);
|
||||
}
|
||||
if (ble_v2_result.has_error()) {
|
||||
LOG(WARNING) << "In StartBleV2Advertising("
|
||||
<< absl::BytesToHexString(local_endpoint_info.data())
|
||||
|
||||
Reference in New Issue
Block a user