Introduce basic handling for on lost advertisements.

PiperOrigin-RevId: 602910198
This commit is contained in:
Anay Wadhera
2024-01-30 19:33:35 -08:00
committed by Copybara-Service
parent 9be93ae23d
commit 80c0d0916e
5 changed files with 132 additions and 2 deletions
+1
View File
@@ -97,6 +97,7 @@ cc_library(
"//connections/implementation/proto:offline_wire_formats_cc_proto",
"//internal/platform:base",
"//internal/platform:types",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/strings",
],
@@ -49,6 +49,7 @@ cc_library(
"//internal/platform:types",
"//internal/platform:util",
"//internal/platform:uuid",
"//internal/platform/implementation:comm",
"//proto/mediums:ble_frames_cc_proto",
"@aappleby_smhasher//:libmurmur3",
"@com_google_absl//absl/base:core_headers",
@@ -21,6 +21,7 @@
#include <utility>
#include <vector>
#include "absl/status/statusor.h"
#include "absl/strings/escaping.h"
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
#include "connections/implementation/mediums/ble_v2/advertisement_read_result.h"
@@ -29,13 +30,17 @@
#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_callback.h"
#include "connections/implementation/mediums/ble_v2/instant_on_lost_advertisement.h"
#include "internal/flags/nearby_flags.h"
#include "internal/platform/ble_v2.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/logging.h"
#include "internal/platform/multi_thread_executor.h"
#include "internal/platform/mutex_lock.h"
using ::nearby::api::ble_v2::BleAdvertisementData;
namespace nearby {
namespace connections {
namespace mediums {
@@ -98,8 +103,7 @@ void DiscoveredPeripheralTracker::StopTracking(const std::string& service_id) {
}
void DiscoveredPeripheralTracker::ProcessFoundBleAdvertisement(
BleV2Peripheral peripheral,
::nearby::api::ble_v2::BleAdvertisementData advertisement_data,
BleV2Peripheral peripheral, BleAdvertisementData advertisement_data,
AdvertisementFetcher advertisement_fetcher) {
MutexLock lock(&mutex_);
@@ -116,6 +120,10 @@ void DiscoveredPeripheralTracker::ProcessFoundBleAdvertisement(
return;
}
if (HandleOnLostAdvertisementLocked(peripheral, advertisement_data)) {
return;
}
if (IsSkippableGattAdvertisement(advertisement_data)) {
NEARBY_LOGS(INFO)
<< "Ignore GATT advertisement and wait for extended advertisement.";
@@ -127,6 +135,49 @@ void DiscoveredPeripheralTracker::ProcessFoundBleAdvertisement(
std::move(advertisement_fetcher));
}
bool DiscoveredPeripheralTracker::HandleOnLostAdvertisementLocked(
BleV2Peripheral peripheral,
const BleAdvertisementData& advertisement_data) {
auto service_data =
advertisement_data.service_data.find(bleutils::kCopresenceServiceUuid);
if (service_data == advertisement_data.service_data.end()) {
return false;
}
absl::StatusOr<InstantOnLostAdvertisement> on_lost_advertisement =
InstantOnLostAdvertisement::CreateFromBytes(
service_data->second.AsStringView());
if (!on_lost_advertisement.ok()) {
return false;
}
NEARBY_LOGS(INFO) << __func__ << ": Found OnLost advertisement for hash:"
<< absl::BytesToHexString(on_lost_advertisement->GetHash());
for (const auto& it : gatt_advertisement_infos_) {
if (it.second.advertisement_header.GetAdvertisementHash().string_data() ==
on_lost_advertisement->GetHash()) {
auto discovery_cb_it = service_id_infos_.find(it.second.service_id);
if (discovery_cb_it == service_id_infos_.end()) {
NEARBY_LOGS(INFO)
<< __func__
<< ": Discarding OnLost advertisement for untracked service_id";
return false;
}
auto advertisements =
gatt_advertisements_[it.second.advertisement_header];
for (const auto& advertisement : advertisements) {
if (advertisement.IsValid()) {
discovery_cb_it->second.discovered_peripheral_callback
.peripheral_lost_cb(peripheral, it.second.service_id,
advertisement.GetData(), false);
NEARBY_LOGS(INFO) << __func__ << ": OnLost triggered for service_id "
<< it.second.service_id;
return true;
}
}
}
}
return false;
}
void DiscoveredPeripheralTracker::ProcessLostGattAdvertisements() {
MutexLock lock(&mutex_);
@@ -29,6 +29,7 @@
#include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h"
#include "connections/implementation/mediums/ble_v2/discovered_peripheral_callback.h"
#include "connections/implementation/mediums/lost_entity_tracker.h"
#include "internal/platform/ble_v2.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/multi_thread_executor.h"
#include "internal/platform/mutex.h"
@@ -244,6 +245,15 @@ class DiscoveredPeripheralTracker {
const BleAdvertisementHeader& advertisement_header)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Processes on lost advertisements. Returns true when the advertisement:
// 1. Is an Instant On Lost BLE advertisement.
// 2. Matches a peripheral's advertisement hash that has previously been
// discovered.
bool HandleOnLostAdvertisementLocked(
BleV2Peripheral peripheral,
const ::nearby::api::ble_v2::BleAdvertisementData& advertisement_data)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
Mutex mutex_;
bool is_extended_advertisement_available_;
@@ -17,10 +17,13 @@
#include <memory>
#include <string>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "connections/implementation/mediums/ble_v2/advertisement_read_result.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/instant_on_lost_advertisement.h"
#include "internal/platform/ble_v2.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/medium_environment.h"
@@ -956,6 +959,70 @@ TEST_F(DiscoveredPeripheralTrackerTest,
EXPECT_FALSE(lost_latch.Await(kWaitDuration).result());
}
TEST_F(DiscoveredPeripheralTrackerTest, LostPeripheralForInstantOnLost) {
std::vector<std::string> service_ids = {std::string(kServiceIdA)};
ByteArray advertisement_hash = GenerateRandomAdvertisementHash();
ByteArray advertisement_header_bytes =
CreateBleAdvertisementHeader(advertisement_hash, service_ids);
ByteArray advertisement_bytes = CreateBleAdvertisement(
std::string(kServiceIdA), ByteArray(std::string(kData)),
ByteArray(std::string(kDeviceToken)));
CountDownLatch found_latch(1);
CountDownLatch lost_latch(1);
CountDownLatch fetch_latch(1);
discovered_peripheral_tracker_.StartTracking(
std::string(kServiceIdA),
{
.peripheral_discovered_cb =
[&found_latch](BleV2Peripheral peripheral,
const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
EXPECT_EQ(advertisement_bytes, ByteArray(std::string(kData)));
EXPECT_FALSE(fast_advertisement);
found_latch.CountDown();
},
.peripheral_lost_cb =
[&lost_latch](
BleV2Peripheral peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { lost_latch.CountDown(); },
},
{});
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_data.insert(
{bleutils::kCopresenceServiceUuid, advertisement_header_bytes});
}
FindAdvertisement(advertisement_data, {advertisement_bytes}, fetch_latch);
// We should receive a client callback of a peripheral discovery.
fetch_latch.Await(kWaitDuration);
ASSERT_TRUE(found_latch.Await(kWaitDuration).result());
EXPECT_EQ(GetFetchAdvertisementCallbackCount(), 1);
auto advertisement = InstantOnLostAdvertisement::CreateFromHash(
advertisement_hash.AsStringView());
ASSERT_OK(advertisement);
api::ble_v2::BleAdvertisementData loss_advertisement_data;
loss_advertisement_data.service_data.insert(
{bleutils::kCopresenceServiceUuid, ByteArray(advertisement->ToBytes())});
FindAdvertisement(loss_advertisement_data,
{ByteArray(advertisement->ToBytes())}, fetch_latch);
// Then, go through a cycle of onLost. Since we triggered a forced loss via
// the instant on los advertisement, the lost call should trigger the onLost
// client callback.
discovered_peripheral_tracker_.ProcessLostGattAdvertisements();
// We should receive a client callback of a lost peripheral
EXPECT_TRUE(lost_latch.Await(kWaitDuration).result());
}
} // namespace
} // namespace mediums