mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Add start/stop legacyDeviceAdvertising in connections ble v2
PiperOrigin-RevId: 621303221
This commit is contained in:
committed by
Copybara-Service
parent
734014a841
commit
ca936891c8
@@ -30,6 +30,7 @@
|
||||
#include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h"
|
||||
#include "connections/implementation/mediums/ble_v2/ble_utils.h"
|
||||
#include "connections/implementation/mediums/ble_v2/bloom_filter.h"
|
||||
#include "connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h"
|
||||
#include "connections/implementation/mediums/bluetooth_radio.h"
|
||||
#include "connections/implementation/mediums/utils.h"
|
||||
#include "connections/power_level.h"
|
||||
@@ -230,6 +231,96 @@ bool BleV2::IsAdvertising(const std::string& service_id) const {
|
||||
return IsAdvertisingLocked(service_id);
|
||||
}
|
||||
|
||||
bool BleV2::StartLegacyAdvertising(
|
||||
const std::string& input_service_id, const std::string& local_endpoint_id,
|
||||
const std::string& fast_advertisement_service_uuid) {
|
||||
NEARBY_LOGS(INFO) << "StartLegacyAdvertising: " << input_service_id.c_str()
|
||||
<< ", local_endpoint_id: " << local_endpoint_id.c_str();
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
if (!radio_.IsEnabled()) {
|
||||
NEARBY_LOGS(INFO) << "Can't start BLE v2 legacy advertising because "
|
||||
"Bluetooth was never turned on";
|
||||
return false;
|
||||
}
|
||||
if (!IsAvailableLocked()) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Can't turn on BLE v2 legacy advertising. BLE is not available.";
|
||||
return false;
|
||||
}
|
||||
// Checking to avoid conflicts to the bool StartAdvertsing invokes.
|
||||
// TODO(hais) remove this if check after deprecating bool StartAdvertising.
|
||||
if (IsAdvertisingLocked(input_service_id)) {
|
||||
NEARBY_LOGS(INFO) << "Failed to BLE v2 legacy device advertise as ble is "
|
||||
"already advertising.";
|
||||
return false;
|
||||
}
|
||||
std::string service_id = input_service_id + "-Legacy";
|
||||
if (service_ids_to_advertising_sessions_.find(service_id) !=
|
||||
service_ids_to_advertising_sessions_.end()) {
|
||||
NEARBY_LOGS(INFO) << "Already started legacy device advertising for "
|
||||
<< service_id;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::ble_v2::BleMedium::AdvertisingSession>
|
||||
legacy_device_advertizing_session = medium_.StartAdvertising(
|
||||
CreateAdvertisingDataForLegacyDevice(),
|
||||
{.tx_power_level = TxPowerLevel::kMedium, .is_connectable = true},
|
||||
api::ble_v2::BleMedium::AdvertisingCallback{
|
||||
.start_advertising_result =
|
||||
[this, &service_id](absl::Status status) mutable {
|
||||
AssumeHeld(mutex_);
|
||||
if (status.ok()) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "BLE V2 advertising for legacy device started "
|
||||
"successfully for service ID "
|
||||
<< &service_id;
|
||||
} else {
|
||||
NEARBY_LOGS(ERROR) << "BLE V2 advertising for legacy "
|
||||
"device failed for service ID "
|
||||
<< &service_id << ": " << status;
|
||||
service_ids_to_advertising_sessions_.erase(service_id);
|
||||
}
|
||||
},
|
||||
});
|
||||
if (legacy_device_advertizing_session == nullptr) {
|
||||
NEARBY_LOGS(ERROR) << "Failed to turn on BLE v2 advertising for legacy "
|
||||
"device for service ID "
|
||||
<< service_id;
|
||||
return false;
|
||||
}
|
||||
|
||||
service_ids_to_advertising_sessions_.insert(
|
||||
{std::string(service_id), std::move(legacy_device_advertizing_session)});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BleV2::StopLegacyAdvertising(const std::string& input_service_id) {
|
||||
NEARBY_LOGS(INFO) << "StopLegacyAdvertising:" << input_service_id.c_str();
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
std::string service_id = input_service_id + "-Legacy";
|
||||
auto legacy_device_advertising_session =
|
||||
service_ids_to_advertising_sessions_.find(service_id);
|
||||
if (legacy_device_advertising_session ==
|
||||
service_ids_to_advertising_sessions_.end()) {
|
||||
NEARBY_LOGS(INFO) << "Can't find session to turn off legacy device BLE "
|
||||
"advertisingfor this service ID: "
|
||||
<< service_id;
|
||||
return false;
|
||||
}
|
||||
absl::Status status =
|
||||
legacy_device_advertising_session->second->stop_advertising();
|
||||
|
||||
if (!status.ok()) {
|
||||
NEARBY_LOGS(WARNING) << "StopLegacyAdvertising error: " << status;
|
||||
}
|
||||
service_ids_to_advertising_sessions_.erase(legacy_device_advertising_session);
|
||||
NEARBY_LOGS(INFO) << "Removed advertising-session for " << service_id;
|
||||
return status.ok();
|
||||
}
|
||||
|
||||
bool BleV2::StartScanning(const std::string& service_id, PowerLevel power_level,
|
||||
DiscoveredPeripheralCallback callback) {
|
||||
MutexLock lock(&mutex_);
|
||||
@@ -763,6 +854,19 @@ ByteArray BleV2::CreateAdvertisementHeader(
|
||||
advertisement_hash, psm));
|
||||
}
|
||||
|
||||
api::ble_v2::BleAdvertisementData
|
||||
BleV2::CreateAdvertisingDataForLegacyDevice() {
|
||||
BleAdvertisementData advertising_data;
|
||||
advertising_data.is_extended_advertisement = false;
|
||||
|
||||
ByteArray encoded_bytes{
|
||||
mediums::DiscoveredPeripheralTracker::kDummyAdvertisementValue};
|
||||
|
||||
advertising_data.service_data.insert(
|
||||
{mediums::bleutils::kCopresenceServiceUuid, encoded_bytes});
|
||||
return advertising_data;
|
||||
}
|
||||
|
||||
bool BleV2::StartAdvertisingLocked(const std::string& service_id) {
|
||||
const auto it = advertising_infos_.find(service_id);
|
||||
if (it == advertising_infos_.end()) {
|
||||
|
||||
@@ -78,6 +78,18 @@ class BleV2 final {
|
||||
bool IsAdvertising(const std::string& service_id) const
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Use dummy bytes to do ble advertising, only for legacy devices.
|
||||
// Returns true, if data is successfully set, and false otherwise.
|
||||
bool StartLegacyAdvertising(
|
||||
const std::string& service_id, const std::string& local_endpoint_id,
|
||||
const std::string& fast_advertisement_service_uuid)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// (TODO:hais) update this after ble_v2 async api refactor.
|
||||
// Stop Ble advertising with dummy bytes for legagy device.
|
||||
bool StopLegacyAdvertising(const std::string& service_id)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Enables BLE scanning for a service ID. Will report any discoverable
|
||||
// advertisement data through a callback.
|
||||
// Returns true, if the scanning is successfully enabled, false otherwise.
|
||||
@@ -167,6 +179,10 @@ class BleV2 final {
|
||||
ByteArray CreateAdvertisementHeader(int psm,
|
||||
bool extended_advertisement_advertised)
|
||||
ABSL_SHARED_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
// For devices that don't have extended nor gatt adverting.
|
||||
api::ble_v2::BleAdvertisementData CreateAdvertisingDataForLegacyDevice();
|
||||
|
||||
bool StartAdvertisingLocked(const std::string& service_id)
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
bool StartFastAdvertisingLocked(
|
||||
@@ -216,6 +232,11 @@ class BleV2 final {
|
||||
absl::flat_hash_map<std::string,
|
||||
std::unique_ptr<api::ble_v2::BleMedium::ScanningSession>>
|
||||
service_ids_to_scanning_sessions_ ABSL_GUARDED_BY(mutex_);
|
||||
// Save advertising sessions by service id, used by the async StartAdvertising
|
||||
// method.
|
||||
absl::flat_hash_map<
|
||||
std::string, std::unique_ptr<api::ble_v2::BleMedium::AdvertisingSession>>
|
||||
service_ids_to_advertising_sessions_ ABSL_GUARDED_BY(mutex_);
|
||||
std::unique_ptr<CancelableAlarm> lost_alarm_;
|
||||
mediums::DiscoveredPeripheralTracker discovered_peripheral_tracker_
|
||||
ABSL_GUARDED_BY(mutex_){medium_.IsExtendedAdvertisementsAvailable()};
|
||||
|
||||
@@ -47,6 +47,8 @@ constexpr absl::string_view kServiceIDB =
|
||||
"com.google.location.nearby.apps.test.b";
|
||||
constexpr absl::string_view kAdvertisementString = "\x0a\x0b\x0c\x0d";
|
||||
constexpr absl::string_view kAdvertisementStringB = "\x01\x02\x03\x04";
|
||||
constexpr absl::string_view kLocalEndpointId = "local_endpoint_id";
|
||||
constexpr absl::string_view kFastAdvertisementServiceUuid{"\xf3\xfe"};
|
||||
|
||||
class BleV2Test : public testing::TestWithParam<FeatureFlags> {
|
||||
public:
|
||||
@@ -578,6 +580,126 @@ TEST_F(BleV2Test, StartScanningDiscoverButNoPeripheralLostAfterStopScanning) {
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(BleV2Test, CanStartAndStopLegacyAdvertising) {
|
||||
env_.SetFeatureFlags(
|
||||
{FeatureFlags{.enable_ble_v2_async_scanning_advertising = true}});
|
||||
env_.Start();
|
||||
BluetoothRadio radio_a;
|
||||
BleV2 ble_a{radio_a};
|
||||
radio_a.Enable();
|
||||
std::string service_id(kServiceIDA);
|
||||
EXPECT_TRUE(
|
||||
ble_a.StartLegacyAdvertising(service_id, std::string(kLocalEndpointId),
|
||||
std::string(kFastAdvertisementServiceUuid)));
|
||||
EXPECT_FALSE(ble_a.IsAdvertising(service_id));
|
||||
EXPECT_TRUE(ble_a.StopLegacyAdvertising(service_id));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(BleV2Test, CanNotStartLegacyAdvertisingWhenRadioNotEnabled) {
|
||||
env_.SetFeatureFlags(
|
||||
{FeatureFlags{.enable_ble_v2_async_scanning_advertising = true}});
|
||||
env_.Start();
|
||||
BluetoothRadio radio_a;
|
||||
BleV2 ble_a{radio_a};
|
||||
radio_a.Disable();
|
||||
std::string service_id(kServiceIDA);
|
||||
EXPECT_FALSE(
|
||||
ble_a.StartLegacyAdvertising(service_id, std::string(kLocalEndpointId),
|
||||
std::string(kFastAdvertisementServiceUuid)));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(BleV2Test, CanNotStopLegacyAdvertisingForNonExistingServiceId) {
|
||||
env_.SetFeatureFlags(
|
||||
{FeatureFlags{.enable_ble_v2_async_scanning_advertising = true}});
|
||||
env_.Start();
|
||||
BluetoothRadio radio_a;
|
||||
BleV2 ble_a{radio_a};
|
||||
radio_a.Enable();
|
||||
std::string service_id(kServiceIDA);
|
||||
EXPECT_FALSE(ble_a.StopLegacyAdvertising(service_id));
|
||||
EXPECT_TRUE(
|
||||
ble_a.StartLegacyAdvertising(service_id, std::string(kLocalEndpointId),
|
||||
std::string(kFastAdvertisementServiceUuid)));
|
||||
EXPECT_TRUE(ble_a.StopLegacyAdvertising(service_id));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(BleV2Test, StartLegacyAdvertisingBlockedByRegularAdvertising) {
|
||||
env_.Start();
|
||||
BluetoothRadio radio_a;
|
||||
BleV2 ble_a{radio_a};
|
||||
radio_a.Enable();
|
||||
std::string service_id(kServiceIDA);
|
||||
ByteArray advertisement_bytes((std::string(kAdvertisementString)));
|
||||
|
||||
ble_a.StartAdvertising(std::string(kServiceIDA), advertisement_bytes,
|
||||
PowerLevel::kHighPower,
|
||||
/*is_fast_advertisement=*/false);
|
||||
EXPECT_TRUE(ble_a.IsAdvertising(service_id));
|
||||
EXPECT_FALSE(
|
||||
ble_a.StartLegacyAdvertising(service_id, std::string(kLocalEndpointId),
|
||||
std::string(kFastAdvertisementServiceUuid)));
|
||||
ble_a.StopAdvertising(std::string(kServiceIDA));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(BleV2Test, DuplicateStartLegacyAdvertisingReturnsFalse) {
|
||||
env_.Start();
|
||||
BluetoothRadio radio_a;
|
||||
BleV2 ble_a{radio_a};
|
||||
radio_a.Enable();
|
||||
std::string service_id(kServiceIDA);
|
||||
EXPECT_TRUE(
|
||||
ble_a.StartLegacyAdvertising(service_id, std::string(kLocalEndpointId),
|
||||
std::string(kFastAdvertisementServiceUuid)));
|
||||
EXPECT_FALSE(
|
||||
ble_a.StartLegacyAdvertising(service_id, std::string(kLocalEndpointId),
|
||||
std::string(kFastAdvertisementServiceUuid)));
|
||||
EXPECT_TRUE(ble_a.StopLegacyAdvertising(service_id));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(BleV2Test, HandleLegacyAdvertising) {
|
||||
env_.SetFeatureFlags(
|
||||
{FeatureFlags{.enable_ble_v2_async_scanning_advertising = true,
|
||||
.enable_invoking_legacy_device_discovered_cb = true}});
|
||||
env_.Start();
|
||||
BluetoothRadio radio_a;
|
||||
BluetoothRadio radio_b;
|
||||
BleV2 ble_a(radio_a);
|
||||
BleV2 ble_b(radio_b);
|
||||
radio_a.Enable();
|
||||
radio_b.Enable();
|
||||
ByteArray advertisement_bytes((std::string(kAdvertisementString)));
|
||||
CountDownLatch legacy_device_found_latch(1);
|
||||
|
||||
ble_b.StartLegacyAdvertising(std::string(kServiceIDA),
|
||||
std::string(kLocalEndpointId),
|
||||
std::string(kFastAdvertisementServiceUuid));
|
||||
std::string legacy_service_id("NearbySharing");
|
||||
EXPECT_TRUE(ble_a.StartScanning(
|
||||
legacy_service_id, PowerLevel::kHighPower,
|
||||
mediums::DiscoveredPeripheralCallback{
|
||||
.peripheral_discovered_cb =
|
||||
[](BleV2Peripheral peripheral, const std::string& service_id,
|
||||
const ByteArray& advertisement_bytes,
|
||||
bool fast_advertisement) {
|
||||
FAIL() << "Legacy device shouldn't be reported here.";
|
||||
},
|
||||
.legacy_device_discovered_cb =
|
||||
[&legacy_device_found_latch]() {
|
||||
legacy_device_found_latch.CountDown();
|
||||
},
|
||||
}));
|
||||
|
||||
EXPECT_TRUE(legacy_device_found_latch.Await(kWaitDuration).result());
|
||||
ble_b.StopAdvertising(std::string(kServiceIDA));
|
||||
EXPECT_TRUE(ble_a.StopScanning(legacy_service_id));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(BleV2Test, CanStartAsyncScanning) {
|
||||
env_.SetFeatureFlags(
|
||||
{FeatureFlags{.enable_ble_v2_async_scanning_advertising = true}});
|
||||
|
||||
Reference in New Issue
Block a user