[BLE Refactor] Add Extended advertisement support.

PiperOrigin-RevId: 449619994
This commit is contained in:
edwinwu
2022-05-18 17:45:04 -07:00
committed by Copybara-Service
parent 8f1623d293
commit 01f439b9ad
20 changed files with 513 additions and 384 deletions
+1
View File
@@ -50,6 +50,7 @@ cc_library(
"//internal/platform:logging",
"//internal/platform:types",
"//proto/mediums:web_rtc_signaling_frames_cc_proto",
"@com_google_absl//absl/container:btree",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/functional:bind_front",
+237 -130
View File
@@ -19,7 +19,6 @@
#include <utility>
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h"
#include "connections/implementation/mediums/ble_v2/ble_utils.h"
@@ -40,7 +39,7 @@ namespace {
using ::location::nearby::api::ble_v2::BleAdvertisementData;
using ::location::nearby::api::ble_v2::GattCharacteristic;
using ::location::nearby::api::ble_v2::PowerMode;
using ::location::nearby::api::ble_v2::TxPowerLevel;
constexpr int kMaxAdvertisementLength = 512;
constexpr int kDummyServiceIdLength = 128;
@@ -62,8 +61,8 @@ BleV2::~BleV2() {
while (!scanned_service_ids_.empty()) {
StopScanning(*scanned_service_ids_.begin());
}
while (!advertising_service_ids_.empty()) {
StopAdvertising(*advertising_service_ids_.begin());
while (!advertising_infos_.empty()) {
StopAdvertising(advertising_infos_.begin()->first);
}
serial_executor_.Shutdown();
@@ -76,7 +75,6 @@ bool BleV2::IsAvailable() const {
return IsAvailableLocked();
}
// TODO(edwinwu): Break down the function.
bool BleV2::StartAdvertising(const std::string& service_id,
const ByteArray& advertisement_bytes,
PowerLevel power_level,
@@ -117,152 +115,99 @@ bool BleV2::StartAdvertising(const std::string& service_id,
// Wrap the connections advertisement to the medium advertisement.
ByteArray service_id_hash = mediums::bleutils::GenerateHash(
service_id, mediums::BleAdvertisement::kServiceIdHashLength);
ByteArray medium_advertisement_bytes{mediums::BleAdvertisement{
// Get psm value from L2CAP server if L2CAP is supported. Now just use the
// default value.
int psm = mediums::BleAdvertisementHeader::kDefaultPsmValue;
mediums::BleAdvertisement medium_advertisement = {
mediums::BleAdvertisement::Version::kV2,
mediums::BleAdvertisement::SocketVersion::kV2,
/*service_id_hash=*/is_fast_advertisement ? ByteArray{} : service_id_hash,
advertisement_bytes, mediums::bleutils::GenerateDeviceToken(),
mediums::BleAdvertisementHeader::kDefaultPsmValue}};
if (medium_advertisement_bytes.Empty()) {
advertisement_bytes,
mediums::bleutils::GenerateDeviceToken(),
psm};
if (!medium_advertisement.IsValid()) {
NEARBY_LOGS(INFO) << "Failed to BLE advertise because we could not wrap a "
"connection advertisement to medium advertisement.";
return false;
}
// Assemble AdvertisingData and ScanResponseData.
BleAdvertisementData advertising_data;
BleAdvertisementData scan_response_data;
if (is_fast_advertisement) {
advertising_data.is_connectable = true;
advertising_data.tx_power_level =
BleAdvertisementData::kUnspecifiedTxPowerLevel;
advertising_data.service_uuids.insert(
std::string(mediums::bleutils::kCopresenceServiceUuid));
advertising_infos_.insert(
{service_id,
AdvertisingInfo{.medium_advertisement = medium_advertisement,
.power_level = power_level,
.is_fast_advertisement = is_fast_advertisement}});
scan_response_data.is_connectable = true;
scan_response_data.tx_power_level =
BleAdvertisementData::kUnspecifiedTxPowerLevel;
scan_response_data.service_data.insert(
{std::string(mediums::bleutils::kCopresenceServiceUuid),
medium_advertisement_bytes});
} else {
// Stop the current advertisement GATT server if there are no incoming
// sockets connected to this device.
//
// The reason for aggressively restarting a GATT server is to make sure this
// class is not using a stale server object that may not be actually running
// anymore (possibly due to Bluetooth being turned off).
//
// Changing one's GATT server while a remote device is connected to it leads
// to a loss of GATT callbacks for that remote device. The only time a
// remote device is indefinitely connected to this device's GATT server is
// when it has a BLE socket connection.
// TODO(b/213835576): Check the BLE Connections is off. We set the fake
// value for the time being till connections is implemented.
bool no_incoming_ble_sockets = true;
if (no_incoming_ble_sockets) {
NEARBY_LOGS(VERBOSE)
<< "Aggressively stopping any pre-existing advertisement GATT "
"servers because no incoming BLE sockets are connected";
StopAdvertisementGattServerLocked();
}
// Stop the pre-existing BLE advertisement if there is one.
medium_.StopAdvertising();
// Start a GATT server to deliver the full advertisement data. If fail to
// advertise the header, we must shut this down before the method returns.
if (!IsAdvertisementGattServerRunningLocked()) {
if (!StartAdvertisementGattServerLocked(service_id,
medium_advertisement_bytes)) {
NEARBY_LOGS(ERROR)
<< "Failed to start BLE advertising for service_id=" << service_id
<< " because the advertisement GATT server failed to start.";
return false;
}
}
ByteArray advertisement_header_bytes(CreateAdvertisementHeader());
if (advertisement_header_bytes.Empty()) {
NEARBY_LOGS(INFO) << "Failed to BLE advertise because we could not "
"create an advertisement header.";
// Failed to start BLE advertising, so stop the advertisement GATT
// server.
StopAdvertisementGattServerLocked();
return false;
}
advertising_data.is_connectable = true;
advertising_data.tx_power_level =
BleAdvertisementData::kUnspecifiedTxPowerLevel;
scan_response_data.is_connectable = true;
scan_response_data.tx_power_level =
BleAdvertisementData::kUnspecifiedTxPowerLevel;
scan_response_data.service_uuids.insert(
std::string(mediums::bleutils::kCopresenceServiceUuid));
scan_response_data.service_data.insert(
{std::string(mediums::bleutils::kCopresenceServiceUuid),
advertisement_header_bytes});
}
if (!medium_.StartAdvertising(advertising_data, scan_response_data,
PowerLevelToPowerMode(power_level))) {
NEARBY_LOGS(ERROR)
<< "Failed to turn on BLE advertising with advertisement bytes="
<< absl::BytesToHexString(advertisement_bytes.data())
<< ", is_fast_advertisement=" << is_fast_advertisement;
// If BLE advertising was not successful, stop the advertisement GATT
// server.
StopAdvertisementGattServerLocked();
if (!StartAdvertisingLocked(service_id)) {
advertising_infos_.erase(service_id);
return false;
}
NEARBY_LOGS(INFO) << "Started BLE advertising with advertisement bytes="
<< absl::BytesToHexString(advertisement_bytes.data())
<< " for service_id=" << service_id;
advertising_service_ids_.insert(service_id);
return true;
}
bool BleV2::StopAdvertising(const std::string& service_id) {
MutexLock lock(&mutex_);
if (!IsAdvertisingLocked(service_id)) {
NEARBY_LOGS(INFO) << "Cannot stop BLE advertising for service_id="
<< service_id << " because it never started.";
return false;
}
// Stop the BLE advertisement. We will restart it later if necessary.
NEARBY_LOGS(INFO) << "Turned off BLE advertising with service_id="
<< service_id;
advertising_infos_.erase(service_id);
medium_.StopAdvertising();
// Remove the GATT advertisements.
gatt_advertisements_.clear();
// Restart the BLE advertisement if there is still an advertiser.
// TODO(b/213835576): Check the BLE Connections is off. We set the fake
// value for the time being till connections is implemented.
bool no_incoming_ble_sockets = true;
// Set the value of characteristic to empty if there is still an advertiser.
if (!hosted_gatt_characteristics_.empty()) {
ByteArray empty_value = {};
for (const auto& characteristic : hosted_gatt_characteristics_) {
if (!gatt_server_->UpdateCharacteristic(characteristic, empty_value)) {
NEARBY_LOGS(ERROR)
<< "Failed to clear characteristic uuid=" << characteristic.uuid
<< " after stopping BLE advertisement for service_id="
<< service_id;
if (advertising_infos_.empty() && !no_incoming_ble_sockets) {
return true;
}
if (!advertising_infos_.empty()) {
if (!hosted_gatt_characteristics_.empty()) {
// Set the value of characteristic to empty if there is still an
// advertiser.
ByteArray empty_value = {};
for (const auto& characteristic : hosted_gatt_characteristics_) {
if (!gatt_server_->UpdateCharacteristic(characteristic, empty_value)) {
NEARBY_LOGS(ERROR)
<< "Failed to clear characteristic uuid=" << characteristic.uuid
<< " after stopping BLE advertisement for service_id="
<< service_id;
}
}
hosted_gatt_characteristics_.clear();
}
hosted_gatt_characteristics_.clear();
} else if (no_incoming_ble_sockets) {
// Otherwise, if we aren't restarting the BLE advertisement, then shutdown
// the gatt server if it's not in use.
NEARBY_LOGS(VERBOSE)
<< "Aggressively stopping any pre-existing advertisement GATT servers "
"because no incoming BLE sockets are connected.";
StopAdvertisementGattServerLocked();
// Get the next service_id to restart BLE advertisement.
const std::string& service_id = advertising_infos_.begin()->first;
if (!StartAdvertisingLocked(service_id)) {
NEARBY_LOGS(ERROR)
<< "Failed to restart BLE advertisement after stopping "
"BLE advertisement for service_id="
<< service_id;
advertising_infos_.erase(service_id);
return false;
}
NEARBY_LOGS(INFO) << "Restart BLE advertising with service_id="
<< service_id;
return true;
}
NEARBY_LOGS(INFO) << "Turned off BLE advertising with service_id="
<< service_id;
advertising_service_ids_.erase(service_id);
return medium_.StopAdvertising();
// If we aren't restarting the BLE advertisement, then shutdown
// the gatt server if it's not in use.
NEARBY_LOGS(VERBOSE) << "Aggressively stopping any pre-existing "
"advertisement GATT servers "
"because no incoming BLE sockets are connected.";
StopAdvertisementGattServerLocked();
return true;
}
bool BleV2::IsAdvertising(const std::string& service_id) const {
@@ -317,7 +262,7 @@ bool BleV2::StartScanning(const std::string& service_id, PowerLevel power_level,
// changed.
if (!medium_.StartScanning(
std::string(mediums::bleutils::kCopresenceServiceUuid),
PowerLevelToPowerMode(power_level),
PowerLevelToTxPowerLevel(power_level),
{
.advertisement_found_cb =
[this](BleV2Peripheral peripheral,
@@ -406,7 +351,7 @@ bool BleV2::IsScanning(const std::string& service_id) const {
bool BleV2::IsAvailableLocked() const { return medium_.IsValid(); }
bool BleV2::IsAdvertisingLocked(const std::string& service_id) const {
return advertising_service_ids_.contains(service_id);
return advertising_infos_.contains(service_id);
}
bool BleV2::IsScanningLocked(const std::string& service_id) const {
@@ -499,7 +444,7 @@ void BleV2::ProcessFetchGattAdvertisementsRequest(
// from the GATT server.
bool read_success = true;
std::unique_ptr<GattClient> gatt_client = medium_.ConnectToGattServer(
std::move(peripheral), PowerLevelToPowerMode(PowerLevel::kHighPower),
std::move(peripheral), PowerLevelToTxPowerLevel(PowerLevel::kHighPower),
/*ClientGattConnectionCallback=*/{});
if (!gatt_client || !gatt_client->IsValid()) {
advertisement_read_result.RecordLastReadStatus(false);
@@ -565,7 +510,8 @@ bool BleV2::StopAdvertisementGattServerLocked() {
return true;
}
ByteArray BleV2::CreateAdvertisementHeader() {
ByteArray BleV2::CreateAdvertisementHeader(
int psm, bool extended_advertisement_advertised) {
// Create a randomized dummy service id to anonymize the header with.
ByteArray dummy_service_id_bytes =
Utils::GenerateRandomBytes(kDummyServiceIdLength);
@@ -583,8 +529,7 @@ ByteArray BleV2::CreateAdvertisementHeader() {
const ByteArray& gatt_advertisement = item.second.second;
bloom_filter.Add(service_id);
// Compute the next hash according to the algorithm in
// https://source.corp.google.com/piper///depot/google3/java/com/google/android/gmscore/integ/modules/nearby/src/com/google/android/gms/nearby/mediums/bluetooth/BluetoothLowEnergy.java;rcl=428397891;l=1043
// Compute the next hash.
std::string advertisement_bodies = absl::StrCat(
advertisement_hash.AsStringView(), gatt_advertisement.AsStringView());
@@ -594,21 +539,183 @@ ByteArray BleV2::CreateAdvertisementHeader() {
return ByteArray(mediums::BleAdvertisementHeader(
mediums::BleAdvertisementHeader::Version::kV2,
/*extended_advertisement=*/false,
extended_advertisement_advertised,
/*num_slots=*/gatt_advertisements_.size(), ByteArray(bloom_filter),
advertisement_hash, /*psm=*/0));
advertisement_hash, psm));
}
PowerMode BleV2::PowerLevelToPowerMode(PowerLevel power_level) {
bool BleV2::StartAdvertisingLocked(const std::string& service_id) {
const auto it = advertising_infos_.find(service_id);
if (it == advertising_infos_.end()) {
NEARBY_LOGS(WARNING) << "Failed to BLE advertise with service_id="
<< service_id;
return false;
}
const AdvertisingInfo& info = it->second;
if (info.is_fast_advertisement) {
return StartFastAdvertisingLocked(info.power_level,
info.medium_advertisement);
} else {
return StartRegularAdvertisingLocked(service_id, info.power_level,
info.medium_advertisement);
}
}
bool BleV2::StartFastAdvertisingLocked(
PowerLevel power_level,
const mediums::BleAdvertisement& medium_advertisement) {
// Begin building the fast BLE advertisement.
BleAdvertisementData advertising_data;
ByteArray medium_advertisement_bytes = ByteArray(medium_advertisement);
advertising_data.is_extended_advertisement = false;
advertising_data.service_data.insert(
{std::string(mediums::bleutils::kCopresenceServiceUuid),
medium_advertisement_bytes});
// Finally, start the fast advertising operation.
if (!medium_.StartAdvertising(
advertising_data,
{.tx_power_level = PowerLevelToTxPowerLevel(power_level),
.is_connectable = true})) {
NEARBY_LOGS(ERROR) << "Failed to turn on BLE fast advertising with "
"advertisement bytes="
<< absl::BytesToHexString(
medium_advertisement_bytes.data());
return false;
}
return true;
}
bool BleV2::StartRegularAdvertisingLocked(
const std::string& service_id, PowerLevel power_level,
const mediums::BleAdvertisement& medium_advertisement) {
// Begin building the regular BLE advertisement.
BleAdvertisementData advertising_data;
ByteArray medium_advertisement_bytes =
medium_.IsExtendedAdvertisementsAvailable()
? medium_advertisement.ByteArrayWithExtraField()
: ByteArray(medium_advertisement);
// Start extended advertisement first if available.
bool extended_regular_advertisement_success = false;
if (medium_.IsExtendedAdvertisementsAvailable()) {
advertising_data.is_extended_advertisement = true;
advertising_data.service_data.insert(
{std::string(mediums::bleutils::kCopresenceServiceUuid),
medium_advertisement_bytes});
// Start the extended regular advertising operation.
extended_regular_advertisement_success = medium_.StartAdvertising(
advertising_data,
{.tx_power_level = PowerLevelToTxPowerLevel(power_level),
.is_connectable = true});
if (!extended_regular_advertisement_success) {
NEARBY_LOGS(ERROR)
<< "Failed to turn on BLE extended regular advertising with "
"advertisement bytes="
<< absl::BytesToHexString(medium_advertisement_bytes.data());
}
}
// Start GATT advertisement no matter extended advertisment succeeded or not.
// This is to ensure that legacy devices which don't support extended
// advertisement can get the advertisement via GATT connection.
bool gatt_advertisement_success = StartGattAdvertisingLocked(
service_id, power_level, medium_advertisement.GetPsm(),
medium_advertisement_bytes, extended_regular_advertisement_success);
return extended_regular_advertisement_success || gatt_advertisement_success;
}
bool BleV2::StartGattAdvertisingLocked(
const std::string& service_id, PowerLevel power_level, int psm,
const ByteArray& medium_advertisement_bytes,
bool extended_advertisement_advertised) {
// Begin building the GATT BLE advertisement header.
BleAdvertisementData advertising_data;
advertising_data.is_extended_advertisement = false;
// Stop the current advertisement GATT server if there are no incoming
// sockets connected to this device.
//
// The reason for aggressively restarting a GATT server is to make sure this
// class is not using a stale server object that may not be actually running
// anymore (possibly due to Bluetooth being turned off).
//
// Changing one's GATT server while a remote device is connected to it leads
// to a loss of GATT callbacks for that remote device. The only time a
// remote device is indefinitely connected to this device's GATT server is
// when it has a BLE socket connection.
// TODO(b/213835576): Check the BLE Connections is off. We set the fake
// value for the time being till connections is implemented.
bool no_incoming_ble_sockets = true;
if (no_incoming_ble_sockets) {
NEARBY_LOGS(VERBOSE)
<< "Aggressively stopping any pre-existing advertisement GATT "
"servers because no incoming BLE sockets are connected";
StopAdvertisementGattServerLocked();
}
// Start a GATT server to deliver the full advertisement data. If fail to
// advertise the header, we must shut this down before the method returns.
if (!IsAdvertisementGattServerRunningLocked()) {
if (!StartAdvertisementGattServerLocked(service_id,
medium_advertisement_bytes)) {
NEARBY_LOGS(ERROR)
<< "Failed to turn on BLE GATT advertising for service_id="
<< service_id
<< " because the advertisement GATT server failed to start.";
return false;
}
}
// Begin building the regular BLE advertisement (backed by a GATT server).
// Add the advertisement header.
ByteArray advertisement_header_bytes =
CreateAdvertisementHeader(psm, extended_advertisement_advertised);
if (advertisement_header_bytes.Empty()) {
NEARBY_LOGS(ERROR)
<< "Failed to turn on BLE GATT advertising because we could not "
"create an advertisement header.";
// Failed to create an advertisement header, so stop the advertisement
// GATT server.
StopAdvertisementGattServerLocked();
return false;
}
advertising_data.service_data.insert(
{std::string(mediums::bleutils::kCopresenceServiceUuid),
advertisement_header_bytes});
// Finally, start the regular advertising operation.
if (!medium_.StartAdvertising(
advertising_data,
{.tx_power_level = PowerLevelToTxPowerLevel(power_level),
.is_connectable = true})) {
NEARBY_LOGS(ERROR) << "Failed to turn on BLE GATT advertising with "
"advertisement bytes="
<< absl::BytesToHexString(
medium_advertisement_bytes.data());
// If BLE advertising was not successful, stop the advertisement GATT
// server.
StopAdvertisementGattServerLocked();
return false;
}
return true;
}
TxPowerLevel BleV2::PowerLevelToTxPowerLevel(PowerLevel power_level) {
switch (power_level) {
case PowerLevel::kHighPower:
return PowerMode::kHigh;
return TxPowerLevel::kHigh;
case PowerLevel::kLowPower:
// Medium power is about the size of a conference room.
// Any lower and we won't be visible at a distance.
return PowerMode::kMedium;
return TxPowerLevel::kMedium;
default:
return PowerMode::kUnknown;
return TxPowerLevel::kUnknown;
}
}
+29 -5
View File
@@ -20,9 +20,11 @@
#include <string>
#include <utility>
#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "connections/implementation/mediums/ble_v2/advertisement_read_result.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement.h"
#include "connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h"
#include "connections/implementation/mediums/bluetooth_radio.h"
#include "connections/power_level.h"
@@ -63,8 +65,7 @@ class BleV2 final {
// but much more efficient to discover.
bool StartAdvertising(const std::string& service_id,
const ByteArray& advertisement_bytes,
PowerLevel power_level,
bool is_fast_advertisement)
PowerLevel power_level, bool is_fast_advertisement)
ABSL_LOCKS_EXCLUDED(mutex_);
// Disables BLE advertising.
@@ -101,6 +102,12 @@ class BleV2 final {
}
private:
struct AdvertisingInfo {
mediums::BleAdvertisement medium_advertisement;
PowerLevel power_level;
bool is_fast_advertisement;
};
// Same as IsAvailable(), but must be called with `mutex_` held.
bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
@@ -129,9 +136,26 @@ class BleV2 final {
bool StopAdvertisementGattServerLocked()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
ByteArray CreateAdvertisementHeader() ABSL_SHARED_LOCKS_REQUIRED(mutex_);
ByteArray CreateAdvertisementHeader(int psm,
bool extended_advertisement_advertised)
ABSL_SHARED_LOCKS_REQUIRED(mutex_);
bool StartAdvertisingLocked(const std::string& service_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
bool StartFastAdvertisingLocked(
PowerLevel power_level,
const mediums::BleAdvertisement& medium_advertisement)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
bool StartRegularAdvertisingLocked(
const std::string& service_id, PowerLevel power_level,
const mediums::BleAdvertisement& medium_advertisement)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
bool StartGattAdvertisingLocked(const std::string& service_id,
PowerLevel power_level, int psm,
const ByteArray& medium_advertisement_bytes,
bool extended_advertisement_advertised)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
api::ble_v2::PowerMode PowerLevelToPowerMode(PowerLevel power_level);
api::ble_v2::TxPowerLevel PowerLevelToTxPowerLevel(PowerLevel power_level);
void RunOnBleThread(Runnable runnable);
@@ -142,7 +166,7 @@ class BleV2 final {
BluetoothRadio& radio_ ABSL_GUARDED_BY(mutex_);
BluetoothAdapter& adapter_ ABSL_GUARDED_BY(mutex_);
BleV2Medium medium_ ABSL_GUARDED_BY(mutex_){adapter_};
absl::flat_hash_set<std::string> advertising_service_ids_
absl::btree_map<std::string, AdvertisingInfo> advertising_infos_
ABSL_GUARDED_BY(mutex_);
std::unique_ptr<GattServer> gatt_server_ ABSL_GUARDED_BY(mutex_);
absl::flat_hash_map<int, std::pair<std::string, ByteArray>>
@@ -98,6 +98,7 @@ class BleAdvertisement {
const ByteArray &&GetData() const && { return std::move(data_); }
ByteArray GetDeviceToken() const { return device_token_; }
int GetPsm() const { return psm_; }
void SetPsm(int psm) { psm_ = psm; }
private:
// Represents the extra fields of the `BleAdvertisement` used in Advertising +
@@ -20,7 +20,6 @@
#include <utility>
#include "absl/strings/str_cat.h"
#include "internal/platform/base64_utils.h"
#include "internal/platform/base_input_stream.h"
#include "internal/platform/logging.h"
@@ -36,7 +35,7 @@ constexpr int BleAdvertisementHeader::kDefaultPsmValue;
constexpr int BleAdvertisementHeader::kPsmValueByteLength;
BleAdvertisementHeader::BleAdvertisementHeader(
Version version, bool extended_advertisement, int num_slots,
Version version, bool support_extended_advertisement, int num_slots,
const ByteArray &service_id_bloom_filter,
const ByteArray &advertisement_hash, int psm) {
if (version != Version::kV2 || num_slots < 0 ||
@@ -46,7 +45,7 @@ BleAdvertisementHeader::BleAdvertisementHeader(
}
version_ = version;
extended_advertisement_ = extended_advertisement;
support_extended_advertisement_ = support_extended_advertisement;
num_slots_ = num_slots;
service_id_bloom_filter_ = service_id_bloom_filter;
advertisement_hash_ = advertisement_hash;
@@ -87,7 +86,7 @@ BleAdvertisementHeader::BleAdvertisementHeader(
return;
}
// The next 1 bit is supposed to be the extended advertisement flag.
extended_advertisement_ =
support_extended_advertisement_ =
((version_and_num_slots_byte & kExtendedAdvertismentBitMask) >> 4) == 1;
// The lower 4 bits are supposed to be the number of slots.
num_slots_ = static_cast<int>(version_and_num_slots_byte & kNumSlotsBitmask);
@@ -120,7 +119,7 @@ BleAdvertisementHeader::operator ByteArray() const {
(static_cast<char>(version_) << 5) & kVersionBitmask;
// The next 1 bit is extended advertisement flag.
version_and_num_slots_byte |=
(static_cast<char>(extended_advertisement_) << 4) &
(static_cast<char>(support_extended_advertisement_) << 4) &
kExtendedAdvertismentBitMask;
// The next 5 bits are the number of slots.
version_and_num_slots_byte |=
@@ -145,7 +144,8 @@ BleAdvertisementHeader::operator ByteArray() const {
bool BleAdvertisementHeader::operator==(
const BleAdvertisementHeader &rhs) const {
return GetVersion() == rhs.GetVersion() &&
IsExtendedAdvertisement() == rhs.IsExtendedAdvertisement() &&
IsSupportExtendedAdvertisement() ==
rhs.IsSupportExtendedAdvertisement() &&
GetNumSlots() == rhs.GetNumSlots() &&
GetServiceIdBloomFilter() == rhs.GetServiceIdBloomFilter() &&
GetAdvertisementHash() == rhs.GetAdvertisementHash() &&
@@ -60,13 +60,14 @@ class BleAdvertisementHeader {
bool operator==(const BleAdvertisementHeader &rhs) const;
template <typename H>
friend H AbslHashValue(H h, const BleAdvertisementHeader &b) {
return H::combine(std::move(h), b.version_, b.extended_advertisement_,
b.num_slots_, b.service_id_bloom_filter_,
b.advertisement_hash_, b.psm_);
return H::combine(std::move(h), b.version_,
b.support_extended_advertisement_, b.num_slots_,
b.service_id_bloom_filter_, b.advertisement_hash_,
b.psm_);
}
BleAdvertisementHeader() = default;
BleAdvertisementHeader(Version version, bool extended_advertisement,
BleAdvertisementHeader(Version version, bool support_extended_advertisement,
int num_slots,
const ByteArray &service_id_bloom_filter,
const ByteArray &advertisement_hash, int psm);
@@ -82,7 +83,9 @@ class BleAdvertisementHeader {
bool IsValid() const { return version_ == Version::kV2; }
Version GetVersion() const { return version_; }
bool IsExtendedAdvertisement() const { return extended_advertisement_; }
bool IsSupportExtendedAdvertisement() const {
return support_extended_advertisement_;
}
int GetNumSlots() const { return num_slots_; }
ByteArray GetServiceIdBloomFilter() const { return service_id_bloom_filter_; }
ByteArray GetAdvertisementHash() const { return advertisement_hash_; }
@@ -99,7 +102,7 @@ class BleAdvertisementHeader {
static constexpr int kNumSlotsBitmask = 0x00F;
Version version_ = Version::kUndefined;
bool extended_advertisement_ = false;
bool support_extended_advertisement_ = false;
int num_slots_ = 0;
ByteArray service_id_bloom_filter_;
ByteArray advertisement_hash_;
@@ -18,7 +18,6 @@
#include "gtest/gtest.h"
#include "absl/hash/hash_testing.h"
#include "internal/platform/base64_utils.h"
namespace location {
namespace nearby {
@@ -44,7 +43,7 @@ TEST(BleAdvertisementHeaderTest, ConstructionWorks) {
EXPECT_TRUE(ble_advertisement_header.IsValid());
EXPECT_EQ(kVersion, ble_advertisement_header.GetVersion());
EXPECT_FALSE(ble_advertisement_header.IsExtendedAdvertisement());
EXPECT_FALSE(ble_advertisement_header.IsSupportExtendedAdvertisement());
EXPECT_EQ(kNumSlots, ble_advertisement_header.GetNumSlots());
EXPECT_EQ(service_id_bloom_filter,
ble_advertisement_header.GetServiceIdBloomFilter());
@@ -161,7 +160,7 @@ TEST(BleAdvertisementHeaderTest, ConstructionFromSerializedStringWorks) {
EXPECT_TRUE(ble_advertisement_header.IsValid());
EXPECT_EQ(kVersion, ble_advertisement_header.GetVersion());
EXPECT_FALSE(ble_advertisement_header.IsExtendedAdvertisement());
EXPECT_FALSE(ble_advertisement_header.IsSupportExtendedAdvertisement());
EXPECT_EQ(kNumSlots, ble_advertisement_header.GetNumSlots());
EXPECT_EQ(service_id_bloom_filter,
ble_advertisement_header.GetServiceIdBloomFilter());
@@ -188,7 +187,7 @@ TEST(BleAdvertisementHeaderTest, ConstructionFromExtraBytesWorks) {
EXPECT_TRUE(long_ble_advertisement_header.IsValid());
EXPECT_EQ(kVersion, long_ble_advertisement_header.GetVersion());
EXPECT_FALSE(ble_advertisement_header.IsExtendedAdvertisement());
EXPECT_FALSE(ble_advertisement_header.IsSupportExtendedAdvertisement());
EXPECT_EQ(kNumSlots, long_ble_advertisement_header.GetNumSlots());
EXPECT_EQ(service_id_bloom_filter,
long_ble_advertisement_header.GetServiceIdBloomFilter());
@@ -15,6 +15,7 @@
#include "connections/implementation/mediums/ble_v2/discovered_peripheral_tracker.h"
#include <algorithm>
#include <iterator>
#include <memory>
#include <string>
#include <utility>
@@ -84,6 +85,12 @@ void DiscoveredPeripheralTracker::ProcessFoundBleAdvertisement(
return;
}
if (IsSkippableGattAdvertisement(advertisement_data)) {
NEARBY_LOGS(INFO)
<< "Ignore GATT advertisement and wait for extended advertisement.";
return;
}
HandleAdvertisement(peripheral, advertisement_data);
HandleAdvertisementHeader(peripheral, advertisement_data,
std::move(advertisement_fetcher));
@@ -129,6 +136,21 @@ void DiscoveredPeripheralTracker::ClearDataForServiceId(
}
}
bool DiscoveredPeripheralTracker::IsSkippableGattAdvertisement(
const api::ble_v2::BleAdvertisementData& advertisement_data) {
if (!is_extended_advertisement_available_) {
// Don't skip any advertisement if the scanner doesn't support extended
// advertisement.
return false;
}
BleAdvertisementHeader advertisement_header(
ExtractAdvertisementHeaderBytes(advertisement_data));
return advertisement_header.IsValid() &&
advertisement_header.IsSupportExtendedAdvertisement();
}
void DiscoveredPeripheralTracker::ClearGattAdvertisement(
const BleAdvertisement& gatt_advertisement) {
const auto gai_it = gatt_advertisement_infos_.find(gatt_advertisement);
@@ -176,18 +198,17 @@ void DiscoveredPeripheralTracker::HandleAdvertisement(
// First filter out kCopresenceServiceUuid and see if any Caller UUID
// existed; if not then just take the kCopresenceServiceUuid as
// |service_uuid|.
std::vector<std::string> extracted_uuids;
absl::flat_hash_map<std::string, location::nearby::ByteArray> extracted_uuids;
// Filter out kCoprsence service uuid.
std::remove_copy_if(advertisement_data.service_uuids.begin(),
advertisement_data.service_uuids.end(),
std::back_inserter(extracted_uuids),
[](const std::string& advertisement_data_service_uuid) {
return advertisement_data_service_uuid ==
bleutils::kCopresenceServiceUuid;
});
std::remove_copy_if(
advertisement_data.service_data.begin(),
advertisement_data.service_data.end(),
std::inserter(extracted_uuids, extracted_uuids.end()),
[](const std::pair<const std::string, location::nearby::ByteArray>&
pair) { return pair.first == bleutils::kCopresenceServiceUuid; });
std::string service_uuid;
if (!extracted_uuids.empty()) {
service_uuid = extracted_uuids.front();
service_uuid = extracted_uuids.begin()->first;
} else {
service_uuid = std::string(bleutils::kCopresenceServiceUuid);
}
@@ -214,9 +235,9 @@ ByteArray DiscoveredPeripheralTracker::ExtractInterestingAdvertisementBytes(
// advertisements are contained within this BLE advertisement.
for (const auto& item : service_id_infos_) {
const ServiceIdInfo& service_id_info = item.second;
// Check if there's service data for this fast advertisement
// service UUID. If so, we can short-circuit since all BLE
// advertisements can contain at most ONE fast advertisement.
// Check if there's service data for this fast advertisement service UUID.
// If so, we can short-circuit since all BLE advertisements can contain at
// most ONE fast advertisement.
const auto sd_it = advertisement_data.service_data.find(
service_id_info.fast_advertisement_service_uuid);
if (sd_it != advertisement_data.service_data.end()) {
@@ -410,10 +431,7 @@ bool DiscoveredPeripheralTracker::ShouldRemoveHeader(
// remove the physical header for the new incoming regular extended
// advertisement. Otherwise, it make the device to fetch advertisement when
// received a physical header again.
// TODO(b/213835576) : Implement API to fetch the support for extended
// advertisement from platform impl.
bool is_extended_advertisement_available = false;
if (is_extended_advertisement_available) {
if (is_extended_advertisement_available_) {
if (!IsDummyAdvertisementHeader(old_advertisement_header) &&
IsDummyAdvertisementHeader(new_advertisement_header)) {
return false;
@@ -59,6 +59,11 @@ class DiscoveredPeripheralTracker {
mediums::AdvertisementReadResult&>();
};
explicit DiscoveredPeripheralTracker(
bool is_extended_advertisement_available = false)
: is_extended_advertisement_available_(
is_extended_advertisement_available) {}
// Starts tracking discoveries for a particular service Id.
//
// service_id - The service ID to track.
@@ -138,6 +143,13 @@ class DiscoveredPeripheralTracker {
void ClearDataForServiceId(const std::string& service_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Returns true if `advertisement_data` is AdvertisementHeader and is marked
// as exented_advertisement. This is to avoid reading advertisement from GATT
// connection, which has been advertised by extended advertisement.
bool IsSkippableGattAdvertisement(
const api::ble_v2::BleAdvertisementData& advertisement_data)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Clears out all data related to the provided GATT advertisement. This
// includes:
// 1. Removing the corresponding GATT advertisement from
@@ -237,6 +249,7 @@ class DiscoveredPeripheralTracker {
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
Mutex mutex_;
bool is_extended_advertisement_available_;
// ------------ SERVICE ID MAPS ------------
// Entries in these maps all follow the same lifecycle. Entries are added in
@@ -211,8 +211,6 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kFastAdvertisementServiceUuid));
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
@@ -252,8 +250,6 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kFastAdvertisementServiceUuid));
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
@@ -298,8 +294,6 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kFastAdvertisementServiceUuid));
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
@@ -357,14 +351,10 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kCopresenceServiceUuid));
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
}
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kFastAdvertisementServiceUuid));
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
@@ -406,8 +396,6 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kCopresenceServiceUuid));
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
}
@@ -444,8 +432,6 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kCopresenceServiceUuid));
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
}
@@ -492,8 +478,6 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kCopresenceServiceUuid));
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
}
@@ -540,8 +524,6 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kCopresenceServiceUuid));
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
}
@@ -585,8 +567,6 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kCopresenceServiceUuid));
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
}
@@ -636,14 +616,10 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kCopresenceServiceUuid));
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
}
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kFastAdvertisementServiceUuid));
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
@@ -700,14 +676,10 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kCopresenceServiceUuid));
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
}
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kFastAdvertisementServiceUuid));
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
@@ -761,8 +733,6 @@ TEST_F(DiscoveredPeripheralTrackerTest, LostPeripheralForAdvertisementLost) {
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kCopresenceServiceUuid));
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
}
@@ -841,14 +811,10 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kCopresenceServiceUuid));
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
}
if (!fast_advertisement_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kFastAdvertisementServiceUuid));
advertisement_data.service_data.insert(
{std::string(kFastAdvertisementServiceUuid), fast_advertisement_bytes});
}
@@ -907,8 +873,6 @@ TEST_F(DiscoveredPeripheralTrackerTest,
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertisement_header_bytes.Empty()) {
advertisement_data.service_uuids.insert(
std::string(kCopresenceServiceUuid));
advertisement_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_header_bytes});
}
+12 -8
View File
@@ -28,26 +28,26 @@ namespace nearby {
using ::location::nearby::api::ble_v2::BleAdvertisementData;
using ::location::nearby::api::ble_v2::GattCharacteristic;
using ::location::nearby::api::ble_v2::PowerMode;
using ::location::nearby::api::ble_v2::TxPowerLevel;
bool BleV2Medium::StartAdvertising(
const BleAdvertisementData& advertising_data,
const BleAdvertisementData& scan_response_data, PowerMode power_mode) {
return impl_->StartAdvertising(advertising_data, scan_response_data,
power_mode);
api::ble_v2::AdvertiseParameters advertise_parameters) {
return impl_->StartAdvertising(advertising_data, advertise_parameters);
}
bool BleV2Medium::StopAdvertising() { return impl_->StopAdvertising(); }
bool BleV2Medium::StartScanning(const std::string& service_uuid,
PowerMode power_mode, ScanCallback callback) {
TxPowerLevel tx_power_level,
ScanCallback callback) {
MutexLock lock(&mutex_);
if (scanning_enabled_) {
NEARBY_LOGS(INFO) << "Ble Scanning already enabled; impl=" << GetImpl();
return false;
}
bool success = impl_->StartScanning(
service_uuid, power_mode,
service_uuid, tx_power_level,
{
.advertisement_found_cb =
[this](api::ble_v2::BlePeripheral& peripheral,
@@ -119,7 +119,7 @@ std::unique_ptr<GattServer> BleV2Medium::StartGattServer(
}
std::unique_ptr<GattClient> BleV2Medium::ConnectToGattServer(
BleV2Peripheral peripheral, PowerMode power_mode,
BleV2Peripheral peripheral, TxPowerLevel tx_power_level,
ClientGattConnectionCallback callback) {
{
MutexLock lock(&mutex_);
@@ -128,7 +128,7 @@ std::unique_ptr<GattClient> BleV2Medium::ConnectToGattServer(
std::unique_ptr<api::ble_v2::GattClient> api_gatt_client =
impl_->ConnectToGattServer(
peripheral.GetImpl(), power_mode,
peripheral.GetImpl(), tx_power_level,
{
.disconnected_cb =
[this]() {
@@ -139,5 +139,9 @@ std::unique_ptr<GattClient> BleV2Medium::ConnectToGattServer(
return std::make_unique<GattClient>(std::move(api_gatt_client));
}
bool BleV2Medium::IsExtendedAdvertisementsAvailable() {
return impl_->IsExtendedAdvertisementsAvailable();
}
} // namespace nearby
} // namespace location
+7 -4
View File
@@ -24,6 +24,7 @@
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/platform.h"
#include "internal/platform/mutex.h"
namespace location {
@@ -153,13 +154,13 @@ class BleV2Medium final {
// Returns true once the BLE advertising has been initiated.
bool StartAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
const api::ble_v2::BleAdvertisementData& scan_response_data,
api::ble_v2::PowerMode power_mode);
api::ble_v2::AdvertiseParameters advertise_parameters);
bool StopAdvertising();
// Returns true once the BLE scan has been initiated.
bool StartScanning(const std::string& service_uuid,
api::ble_v2::PowerMode power_mode, ScanCallback callback);
api::ble_v2::TxPowerLevel tx_power_level,
ScanCallback callback);
bool StopScanning();
// Starts Gatt Server for waiting to client connection.
@@ -169,9 +170,11 @@ class BleV2Medium final {
// Returns a new GattClient connection to a gatt server.
// There is only one instance of GattServer can run at a time.
std::unique_ptr<GattClient> ConnectToGattServer(
BleV2Peripheral peripheral, api::ble_v2::PowerMode power_mode,
BleV2Peripheral peripheral, api::ble_v2::TxPowerLevel tx_power_level,
ClientGattConnectionCallback callback);
bool IsExtendedAdvertisementsAvailable();
bool IsValid() const { return impl_ != nullptr; }
api::ble_v2::BleMedium* GetImpl() const { return impl_.get(); }
+42 -23
View File
@@ -30,13 +30,14 @@ namespace {
using ::location::nearby::api::ble_v2::BleAdvertisementData;
using ::location::nearby::api::ble_v2::GattCharacteristic;
using ::location::nearby::api::ble_v2::PowerMode;
using ::location::nearby::api::ble_v2::TxPowerLevel;
using ::testing::Optional;
constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000);
constexpr absl::string_view kAdvertisementString = "\x0a\x0b\x0c\x0d";
constexpr absl::string_view kAdvertisementHeaderString = "\x0x\x0y\x0z";
constexpr absl::string_view kCopresenceServiceUuid = "F3FE";
constexpr PowerMode kPowerMode(PowerMode::kHigh);
constexpr TxPowerLevel kTxPowerLevel(TxPowerLevel::kHigh);
// A stub BlePeripheral implementation.
class BlePeripheralStub : public api::ble_v2::BlePeripheral {
@@ -80,10 +81,11 @@ TEST_F(BleV2MediumTest, CanStartFastScanningAndFastAdvertising) {
BluetoothAdapter adapter_b;
BleV2Medium ble_a(adapter_a);
BleV2Medium ble_b(adapter_b);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
CountDownLatch found_latch(1);
EXPECT_TRUE(ble_a.StartScanning(
std::string(kCopresenceServiceUuid), kPowerMode,
{std::string(kCopresenceServiceUuid)}, kTxPowerLevel,
{
.advertisement_found_cb =
[&found_latch](BleV2Peripheral peripheral,
@@ -92,16 +94,23 @@ TEST_F(BleV2MediumTest, CanStartFastScanningAndFastAdvertising) {
},
}));
// Assemble fast advertising and scan response data.
// Fail to start extended advertisement due to g3 Ble medium does not support.
BleAdvertisementData advertising_data;
advertising_data.service_uuids.insert(std::string(kCopresenceServiceUuid));
BleAdvertisementData scan_response_data;
scan_response_data.service_data.insert(
{std::string(kCopresenceServiceUuid),
ByteArray(std::string(kAdvertisementString))});
advertising_data.is_extended_advertisement = true;
advertising_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_bytes});
EXPECT_FALSE(ble_b.StartAdvertising(
advertising_data,
{.tx_power_level = kTxPowerLevel, .is_connectable = true}));
// Succeed to start regular advertisement.
advertising_data.is_extended_advertisement = false;
advertising_data.service_data = {
{std::string(kCopresenceServiceUuid), advertisement_bytes}};
EXPECT_TRUE(ble_b.StartAdvertising(
advertising_data,
{.tx_power_level = kTxPowerLevel, .is_connectable = true}));
EXPECT_TRUE(
ble_b.StartAdvertising(advertising_data, scan_response_data, kPowerMode));
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
EXPECT_TRUE(ble_a.StopScanning());
EXPECT_TRUE(ble_b.StopAdvertising());
@@ -114,10 +123,12 @@ TEST_F(BleV2MediumTest, CanStartScanningAndAdvertising) {
BluetoothAdapter adapter_b;
BleV2Medium ble_a(adapter_a);
BleV2Medium ble_b(adapter_b);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
ByteArray advertisement_header_bytes{std::string(kAdvertisementHeaderString)};
CountDownLatch found_latch(1);
EXPECT_TRUE(ble_a.StartScanning(
std::string(kCopresenceServiceUuid), kPowerMode,
{std::string(kCopresenceServiceUuid)}, kTxPowerLevel,
{
.advertisement_found_cb =
[&found_latch](BleV2Peripheral peripheral,
@@ -126,16 +137,23 @@ TEST_F(BleV2MediumTest, CanStartScanningAndAdvertising) {
},
}));
// Assemble regular advertising and scan response data.
BleAdvertisementData advertising_data = {};
BleAdvertisementData scan_response_data;
scan_response_data.service_uuids.insert(std::string(kCopresenceServiceUuid));
scan_response_data.service_data.insert(
{std::string(kCopresenceServiceUuid),
ByteArray(std::string(kAdvertisementString))});
// Fail to start extended advertisement due to g3 Ble medium does not support.
BleAdvertisementData advertising_data;
advertising_data.is_extended_advertisement = true;
advertising_data.service_data.insert(
{std::string(kCopresenceServiceUuid), advertisement_bytes});
EXPECT_FALSE(ble_b.StartAdvertising(
advertising_data,
{.tx_power_level = kTxPowerLevel, .is_connectable = true}));
// Succeed to start regular advertisement.
advertising_data.is_extended_advertisement = false;
advertising_data.service_data = {
{std::string(kCopresenceServiceUuid), advertisement_header_bytes}};
EXPECT_TRUE(ble_b.StartAdvertising(
advertising_data,
{.tx_power_level = kTxPowerLevel, .is_connectable = true}));
EXPECT_TRUE(
ble_b.StartAdvertising(advertising_data, scan_response_data, kPowerMode));
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
EXPECT_TRUE(ble_a.StopScanning());
EXPECT_TRUE(ble_b.StopAdvertising());
@@ -145,7 +163,7 @@ TEST_F(BleV2MediumTest, CanStartScanningAndAdvertising) {
TEST_F(BleV2MediumTest, CanStartGattServer) {
env_.Start();
BluetoothAdapter adapter;
BleV2Medium ble{adapter};
BleV2Medium ble(adapter);
std::string characteristic_uuid = "characteristic_uuid";
std::unique_ptr<GattServer> gatt_server =
@@ -157,6 +175,7 @@ TEST_F(BleV2MediumTest, CanStartGattServer) {
GattCharacteristic::Permission::kRead};
std::vector<GattCharacteristic::Property> properties = {
GattCharacteristic::Property::kRead};
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<GattCharacteristic> gatt_characteristic =
gatt_server->CreateCharacteristic(std::string(kCopresenceServiceUuid),
characteristic_uuid, permissions,
@@ -207,7 +226,7 @@ TEST_F(BleV2MediumTest, GattClientConnectToGattServerWorks) {
auto ble_peripheral =
std::make_unique<BlePeripheralStub>(/*mac_address=*/"ABCD");
std::unique_ptr<GattClient> gatt_client = ble_b.ConnectToGattServer(
BleV2Peripheral(ble_peripheral.get()), kPowerMode,
BleV2Peripheral(ble_peripheral.get()), kTxPowerLevel,
/*ClientGattConnectionCallback=*/{});
ASSERT_NE(gatt_client, nullptr);
+30 -33
View File
@@ -24,7 +24,6 @@
#include <string>
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/string_view.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
@@ -38,7 +37,7 @@ namespace api {
namespace ble_v2 {
// Coarse representation of power settings throughout all BLE operations.
enum class PowerMode {
enum class TxPowerLevel {
kUnknown = 0,
kUltraLow = 1,
kLow = 2,
@@ -46,6 +45,16 @@ enum class PowerMode {
kHigh = 4,
};
// https://developer.android.com/reference/android/bluetooth/le/AdvertisingSetParameters.Builder
//
// The preferences for Advertising.
struct AdvertiseParameters {
// The transmission power level for the advertising.
TxPowerLevel tx_power_level;
// Whether the advertisement type should be connectable or non-connectable.
bool is_connectable;
};
// https://developer.android.com/reference/android/bluetooth/le/AdvertiseData
//
// Bundle of data found in a BLE advertisement.
@@ -54,27 +63,17 @@ enum class PowerMode {
// 0000xxxx-0000-1000-8000-00805F9B34FB. This makes it possible to store two
// byte service UUIDs in the advertisement.
struct BleAdvertisementData {
using TxPowerLevel = std::int8_t;
static constexpr TxPowerLevel kUnspecifiedTxPowerLevel =
std::numeric_limits<TxPowerLevel>::min();
bool is_connectable;
// If tx_power_level is not set to kUnspecifiedTxPowerLevel, platform
// implementer needs to set the TxPowerLevel.
TxPowerLevel tx_power_level;
// If the set is not empty, the platform implementer needs to add the
// service_uuids in the advertisement data.
absl::flat_hash_set<std::string> service_uuids;
// Broadcasts a BLE extended advertisement if it is true.
bool is_extended_advertisement;
// Maps service UUIDs to their service data.
//
// Note if platform can't advertise data from Data type (0x16)
// (reaonly in iOS), then (iOS) should advertise data via LocalName data
// type (0x08). It means the iOS should take the first index of service_data
// as the data for LocalName type.
// For each platform should follow to set the service UUID(key) and service
// data(value):
//
// iOS : 16 bit service UUID (type=0x03) + LocalName data (type=0x08)
// Windows: Service data (type=0x16)
// Android: 16 bit service UUID (type=0x03) + Service data (type=0x16)
absl::flat_hash_map<std::string, location::nearby::ByteArray> service_data;
};
@@ -274,15 +273,9 @@ class BleMedium {
// https://developer.android.com/reference/android/bluetooth/le/BluetoothLeAdvertiser.html#startAdvertising(android.bluetooth.le.AdvertiseSettings,%20android.bluetooth.le.AdvertiseData,%20android.bluetooth.le.AdvertiseData,%20android.bluetooth.le.AdvertiseCallback)
//
// Starts BLE advertising and returns whether or not it was successful.
//
// Power mode should be interpreted in the following way:
// LOW:
// - TX power = medium
// HIGH:
// - TX power = high
virtual bool StartAdvertising(const BleAdvertisementData& advertising_data,
const BleAdvertisementData& scan_response_data,
PowerMode power_mode) = 0;
virtual bool StartAdvertising(
const BleAdvertisementData& advertising_data,
AdvertiseParameters advertise_set_parameters) = 0;
// https://developer.android.com/reference/android/bluetooth/le/BluetoothLeAdvertiser.html#stopAdvertising(android.bluetooth.le.AdvertiseCallback)
//
@@ -312,7 +305,7 @@ class BleMedium {
//
// Starts scanning and returns whether or not it was successful.
//
// Power mode should be interpreted in the following way:
// TX Power level should be interpreted in the following way:
// LOW:
// - Scan window = ~512ms
// - Scan interval = ~5120ms
@@ -320,7 +313,8 @@ class BleMedium {
// - Scan window = ~4096ms
// - Scan interval = ~4096ms
virtual bool StartScanning(const std::string& service_uuid,
PowerMode power_mode, ScanCallback callback) = 0;
TxPowerLevel tx_power_level,
ScanCallback callback) = 0;
// https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner.html#stopScan(android.bluetooth.le.ScanCallback)
//
@@ -347,13 +341,13 @@ class BleMedium {
// Connects to a GATT server and negotiates the specified connection
// parameters. Returns nullptr upon error.
//
// Power mode should be interpreted in the following way:
// TX Power level should be interpreted in the following way:
// HIGH:
// - Connection interval = ~11.25ms - 15ms
// LOW:
// - Connection interval = ~100ms - 125ms
virtual std::unique_ptr<GattClient> ConnectToGattServer(
BlePeripheral& peripheral, PowerMode power_mode,
BlePeripheral& peripheral, TxPowerLevel tx_power_level,
ClientGattConnectionCallback callback) = 0;
// Establishes a BLE socket to the specified remote peripheral. Returns
@@ -361,6 +355,9 @@ class BleMedium {
virtual std::unique_ptr<BleSocket> EstablishBleSocket(
BlePeripheral* peripheral,
const BleSocketLifeCycleCallback& callback) = 0;
// Requests if support extended advertisement.
virtual bool IsExtendedAdvertisementsAvailable() = 0;
};
} // namespace ble_v2
+28 -27
View File
@@ -35,19 +35,19 @@ namespace {
using ::location::nearby::api::ble_v2::BleAdvertisementData;
using ::location::nearby::api::ble_v2::BleSocket;
using ::location::nearby::api::ble_v2::BleSocketLifeCycleCallback;
using ::location::nearby::api::ble_v2::PowerMode;
using ::location::nearby::api::ble_v2::TxPowerLevel;
std::string PowerModeToName(PowerMode power_mode) {
std::string TxPowerLevelToName(TxPowerLevel power_mode) {
switch (power_mode) {
case PowerMode::kUltraLow:
case TxPowerLevel::kUltraLow:
return "UltraLow";
case PowerMode::kLow:
case TxPowerLevel::kLow:
return "Low";
case PowerMode::kMedium:
case TxPowerLevel::kMedium:
return "Medium";
case PowerMode::kHigh:
case TxPowerLevel::kHigh:
return "High";
case PowerMode::kUnknown:
case TxPowerLevel::kUnknown:
return "Unknown";
}
}
@@ -67,28 +67,24 @@ BleV2Medium::~BleV2Medium() {
bool BleV2Medium::StartAdvertising(
const BleAdvertisementData& advertising_data,
const BleAdvertisementData& scan_response_data, PowerMode power_mode) {
api::ble_v2::AdvertiseParameters advertise_parameters) {
NEARBY_LOGS(INFO)
<< "G3 Ble StartAdvertising:, advertising_data.service_uuids size="
<< advertising_data.service_uuids.size()
<< ", scan_response_data.service_data size="
<< scan_response_data.service_data.size()
<< ", power_mode=" << PowerModeToName(power_mode);
<< "G3 Ble StartAdvertising: advertising_data.is_extended_advertisement="
<< advertising_data.is_extended_advertisement
<< ", advertising_data.service_data size="
<< advertising_data.service_data.size() << ", tx_power_level="
<< TxPowerLevelToName(advertise_parameters.tx_power_level)
<< ", is_connectable=" << advertise_parameters.is_connectable;
if (advertising_data.is_extended_advertisement &&
!is_support_extended_advertisement_) {
NEARBY_LOGS(INFO)
<< "G3 Ble StartAdvertising does not support extended advertisement";
return false;
}
absl::MutexLock lock(&mutex_);
// Reassemble advertisement data from advertising and scan response
// data.
api::ble_v2::BleAdvertisementData advertisement_data;
if (!advertising_data.service_uuids.empty()) {
advertisement_data.service_uuids = advertising_data.service_uuids;
} else {
advertisement_data.service_uuids = scan_response_data.service_uuids;
}
advertisement_data.service_data = scan_response_data.service_data;
MediumEnvironment::Instance().UpdateBleV2MediumForAdvertising(
/*enabled=*/true, *this, adapter_->GetPeripheralV2(), advertisement_data);
/*enabled=*/true, *this, adapter_->GetPeripheralV2(), advertising_data);
return true;
}
@@ -104,7 +100,8 @@ bool BleV2Medium::StopAdvertising() {
}
bool BleV2Medium::StartScanning(const std::string& service_uuid,
PowerMode power_mode, ScanCallback callback) {
TxPowerLevel tx_power_level,
ScanCallback callback) {
NEARBY_LOGS(INFO) << "G3 Ble StartScanning";
absl::MutexLock lock(&mutex_);
@@ -136,7 +133,7 @@ bool BleV2Medium::StartListeningForIncomingBleSockets(
void BleV2Medium::StopListeningForIncomingBleSockets() {}
std::unique_ptr<api::ble_v2::GattClient> BleV2Medium::ConnectToGattServer(
api::ble_v2::BlePeripheral& peripheral, PowerMode power_mode,
api::ble_v2::BlePeripheral& peripheral, TxPowerLevel tx_power_level,
api::ble_v2::ClientGattConnectionCallback callback) {
return std::make_unique<GattClient>();
}
@@ -147,6 +144,10 @@ std::unique_ptr<BleSocket> BleV2Medium::EstablishBleSocket(
return nullptr;
}
bool BleV2Medium::IsExtendedAdvertisementsAvailable() {
return is_support_extended_advertisement_;
}
std::optional<api::ble_v2::GattCharacteristic>
BleV2Medium::GattServer::CreateCharacteristic(
absl::string_view service_uuid, absl::string_view characteristic_uuid,
+9 -4
View File
@@ -38,12 +38,12 @@ class BleV2Medium : public api::ble_v2::BleMedium {
// Returns true once the Ble advertising has been initiated.
bool StartAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
const api::ble_v2::BleAdvertisementData& scan_response_data,
api::ble_v2::PowerMode power_mode) override ABSL_LOCKS_EXCLUDED(mutex_);
api::ble_v2::AdvertiseParameters advertise_parameters) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopAdvertising() override ABSL_LOCKS_EXCLUDED(mutex_);
bool StartScanning(const std::string& service_uuid,
api::ble_v2::PowerMode power_mode,
api::ble_v2::TxPowerLevel tx_power_level,
ScanCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopScanning() override ABSL_LOCKS_EXCLUDED(mutex_);
@@ -56,7 +56,8 @@ class BleV2Medium : public api::ble_v2::BleMedium {
void StopListeningForIncomingBleSockets() override
ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<api::ble_v2::GattClient> ConnectToGattServer(
api::ble_v2::BlePeripheral& peripheral, api::ble_v2::PowerMode power_mode,
api::ble_v2::BlePeripheral& peripheral,
api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::ClientGattConnectionCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<api::ble_v2::BleSocket> EstablishBleSocket(
@@ -64,6 +65,8 @@ class BleV2Medium : public api::ble_v2::BleMedium {
const api::ble_v2::BleSocketLifeCycleCallback& callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool IsExtendedAdvertisementsAvailable() override;
BluetoothAdapter& GetAdapter() { return *adapter_; }
private:
@@ -113,6 +116,8 @@ class BleV2Medium : public api::ble_v2::BleMedium {
absl::Mutex mutex_;
BluetoothAdapter* adapter_; // Our device adapter; read-only.
// TODO(edwinwu): Adds extended advertisement for testing.
bool is_support_extended_advertisement_ = false;
};
} // namespace g3
@@ -20,7 +20,6 @@
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/shared/count_down_latch.h"
#include "internal/platform/logging.h"
#include "winrt/Windows.Devices.Bluetooth.Advertisement.h"
#include "winrt/Windows.Devices.Bluetooth.h"
@@ -32,12 +31,13 @@ namespace windows {
namespace {
using ::location::nearby::api::ble_v2::AdvertiseParameters;
using ::location::nearby::api::ble_v2::BleAdvertisementData;
using ::location::nearby::api::ble_v2::BleSocket;
using ::location::nearby::api::ble_v2::BleSocketLifeCycleCallback;
using ::location::nearby::api::ble_v2::GattClient;
using ::location::nearby::api::ble_v2::PowerMode;
using ::location::nearby::api::ble_v2::ServerGattConnectionCallback;
using ::location::nearby::api::ble_v2::TxPowerLevel;
using ::winrt::Windows::Devices::Bluetooth::BluetoothError;
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisement;
@@ -61,22 +61,23 @@ using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcherStoppedEventArgs;
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEScanningMode;
using ::winrt::Windows::Storage::Streams::Buffer;
using ::winrt::Windows::Storage::Streams::DataWriter;
template <typename T>
using IVector = winrt::Windows::Foundation::Collections::IVector<T>;
std::string PowerModeToName(PowerMode power_mode) {
switch (power_mode) {
case PowerMode::kUltraLow:
std::string TxPowerLevelToName(TxPowerLevel tx_power_level) {
switch (tx_power_level) {
case TxPowerLevel::kUltraLow:
return "UltraLow";
case PowerMode::kLow:
case TxPowerLevel::kLow:
return "Low";
case PowerMode::kMedium:
case TxPowerLevel::kMedium:
return "Medium";
case PowerMode::kHigh:
case TxPowerLevel::kHigh:
return "High";
case PowerMode::kUnknown:
case TxPowerLevel::kUnknown:
return "Unknown";
}
}
@@ -90,66 +91,33 @@ BleV2Medium::BleV2Medium(api::BluetoothAdapter& adapter)
BleV2Medium::~BleV2Medium() {}
// TODO(edwinwu): Modify advertising abstraction APIs and fit all data into one
// advertisement packet and populate accordingly
bool BleV2Medium::StartAdvertising(
const BleAdvertisementData& advertising_data,
const BleAdvertisementData& scan_response_data, PowerMode power_mode) {
bool BleV2Medium::StartAdvertising(const BleAdvertisementData& advertising_data,
AdvertiseParameters advertising_parameters) {
NEARBY_LOGS(INFO)
<< "Windows Ble StartAdvertising:, advertising_data.service_uuids size="
<< advertising_data.service_uuids.size()
<< ", scan_response_data.service_data size="
<< scan_response_data.service_data.size()
<< ", power_mode=" << PowerModeToName(power_mode);
<< "Windows Ble StartAdvertising:, advertising_data.service_data size="
<< advertising_data.service_data.size() << ", tx_power_level="
<< TxPowerLevelToName(advertising_parameters.tx_power_level);
if (advertising_data.service_data.empty()) return false;
absl::MutexLock lock(&mutex_);
// (AD type 0x16) Service Data
constexpr uint8_t kCopresenceServiceUuid[] = {0xf3, 0xfe};
DataWriter data_writer;
auto it = advertising_data.service_data.begin();
const std::string& service_uuid = it->first;
const ByteArray& service_bytes = it->second;
// (2 bytes) 16-bit Service UUID 0xf3fe
data_writer.WriteByte(kCopresenceServiceUuid[1]); // 0xfe
data_writer.WriteByte(kCopresenceServiceUuid[0]); // 0xf3
// (1 byte) version [3-bits] + socket_version [3-bits] +
// fast_advertisement_flag [1-bit] + reserved [1-bit]
data_writer.WriteByte(0x00);
// (1 byte) body_length
data_writer.WriteByte(0x00);
// (1 byte) Nearby Connection version [3-bits] + pcp [5-bits]
data_writer.WriteByte(0x00);
// (4 bytes) endpoint_id
for (int i = 0; i < 4; ++i) {
data_writer.WriteByte(0x00);
if (service_uuid.size() < 2) {
return false;
}
data_writer.WriteByte(service_uuid[0]);
data_writer.WriteByte(service_uuid[1]);
// (1 byte) endpoint_info_size
data_writer.WriteByte(0x11); // always 17-bytes for Fast Advertisement
// =========endpoint_info [17-bytes]============
// (1 byte) Nearby Share version [3-bits] + visibility [1-bit] + reserved
// [4-bits]
data_writer.WriteByte(0x00);
// (2 bytes) salt
for (int i = 0; i < 2; ++i) {
data_writer.WriteByte(0x00);
}
// (14 bytes) encrypted_metadata_key
for (int i = 0; i < 14; ++i) {
data_writer.WriteByte(0x00);
}
// =========endpoint_info [17-bytes]============
// (2 bytes) device_token
for (int i = 0; i < 2; ++i) {
data_writer.WriteByte(0x00);
}
Buffer buffer(service_bytes.size());
std::memcpy(buffer.data(), service_bytes.data(), service_bytes.size());
data_writer.WriteBuffer(buffer);
BluetoothLEAdvertisementDataSection service_data =
BluetoothLEAdvertisementDataSection(0x16, data_writer.DetachBuffer());
@@ -217,7 +185,8 @@ bool BleV2Medium::StopAdvertising() {
}
bool BleV2Medium::StartScanning(const std::string& service_uuid,
PowerMode power_mode, ScanCallback callback) {
TxPowerLevel tx_power_level,
ScanCallback callback) {
NEARBY_LOGS(INFO) << "Windows Ble StartScanning";
absl::MutexLock lock(&mutex_);
watcher_started_callback_ = [this]() {
@@ -290,7 +259,7 @@ bool BleV2Medium::StartListeningForIncomingBleSockets(
void BleV2Medium::StopListeningForIncomingBleSockets() {}
std::unique_ptr<GattClient> BleV2Medium::ConnectToGattServer(
api::ble_v2::BlePeripheral& peripheral, PowerMode power_mode,
api::ble_v2::BlePeripheral& peripheral, TxPowerLevel tx_power_level,
api::ble_v2::ClientGattConnectionCallback callback) {
return nullptr;
}
@@ -19,9 +19,6 @@
#include <memory>
#include <string>
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/escaping.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble_v2.h"
@@ -49,12 +46,12 @@ class BleV2Medium : public api::ble_v2::BleMedium {
// Returns true once the Ble advertising has been initiated.
bool StartAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
const api::ble_v2::BleAdvertisementData& scan_response_data,
api::ble_v2::PowerMode power_mode) override ABSL_LOCKS_EXCLUDED(mutex_);
api::ble_v2::AdvertiseParameters advertising_parameters) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopAdvertising() override ABSL_LOCKS_EXCLUDED(mutex_);
bool StartScanning(const std::string& service_uuid,
api::ble_v2::PowerMode power_mode,
api::ble_v2::TxPowerLevel tx_power_level,
ScanCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopScanning() override ABSL_LOCKS_EXCLUDED(mutex_);
@@ -67,13 +64,15 @@ class BleV2Medium : public api::ble_v2::BleMedium {
void StopListeningForIncomingBleSockets() override
ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<api::ble_v2::GattClient> ConnectToGattServer(
api::ble_v2::BlePeripheral& peripheral, api::ble_v2::PowerMode power_mode,
api::ble_v2::BlePeripheral& peripheral,
api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::ClientGattConnectionCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<api::ble_v2::BleSocket> EstablishBleSocket(
api::ble_v2::BlePeripheral* peripheral,
const api::ble_v2::BleSocketLifeCycleCallback& callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool IsExtendedAdvertisementsAvailable() override { return false; }
BluetoothAdapter& GetAdapter() { return *adapter_; }
@@ -34,7 +34,8 @@ TEST(BleV2Medium, DISABLED_StartAdvertising) {
api::ble_v2::BleAdvertisementData scan_response_data;
EXPECT_TRUE(blev2_medium.StartAdvertising(
advertising_data, scan_response_data, api::ble_v2::PowerMode::kHigh));
advertising_data, {.tx_power_level = api::ble_v2::TxPowerLevel::kHigh,
.is_connectable = true}));
}
TEST(BleV2Medium, DISABLED_StopAdvertising) {
@@ -42,10 +43,10 @@ TEST(BleV2Medium, DISABLED_StopAdvertising) {
BleV2Medium blev2_medium(bluetoothAdapter);
api::ble_v2::BleAdvertisementData advertising_data;
api::ble_v2::BleAdvertisementData scan_response_data;
EXPECT_TRUE(blev2_medium.StartAdvertising(
advertising_data, scan_response_data, api::ble_v2::PowerMode::kHigh));
advertising_data, {.tx_power_level = api::ble_v2::TxPowerLevel::kHigh,
.is_connectable = true}));
EXPECT_TRUE(blev2_medium.StopAdvertising());
}
@@ -67,7 +68,7 @@ TEST(BleV2Medium, DISABLED_StartScanning) {
};
EXPECT_TRUE(blev2_medium.StartScanning(
service_uuid, api::ble_v2::PowerMode::kHigh, callback));
service_uuid, api::ble_v2::TxPowerLevel::kHigh, callback));
EXPECT_TRUE(scan_response_notification.WaitForNotificationWithTimeout(
absl::Seconds(5)));
@@ -85,7 +86,7 @@ TEST(BleV2Medium, DISABLED_StopScanning) {
const api::ble_v2::BleAdvertisementData& advertisement_data) {};
EXPECT_TRUE(blev2_medium.StartScanning(
service_uuid, api::ble_v2::PowerMode::kHigh, callback));
service_uuid, api::ble_v2::TxPowerLevel::kHigh, callback));
EXPECT_TRUE(blev2_medium.StopScanning());
}
+10 -9
View File
@@ -539,9 +539,9 @@ void MediumEnvironment::UpdateBleV2MediumForAdvertising(
BleV2MediumContext& remote_context = medium_info.second;
// Do not send notification to the same medium.
if (remote_medium == &medium) continue;
if (!context.advertisement_data.service_uuids.contains(
remote_context.scanning_service_uuid))
continue;
auto const it = context.advertisement_data.service_data.find(
remote_context.scanning_service_uuid);
if (it == context.advertisement_data.service_data.end()) continue;
NEARBY_LOGS(INFO)
<< "G3 UpdateBleV2MediumForAdvertising, found other medium="
<< remote_medium << ", remote_medium_context=" << &remote_context
@@ -583,8 +583,9 @@ void MediumEnvironment::UpdateBleV2MediumForScanning(
// medium.
if (remote_medium == &medium || !remote_context.advertising)
continue;
if (!remote_context.advertisement_data.service_uuids.contains(
context.scanning_service_uuid))
auto const it = remote_context.advertisement_data.service_data.find(
context.scanning_service_uuid);
if (it == remote_context.advertisement_data.service_data.end())
continue;
NEARBY_LOGS(INFO)
<< "G3 UpdateBleV2MediumForScanning, found other medium="
@@ -894,8 +895,8 @@ api::WifiHotspotMedium* MediumEnvironment::GetWifiHotspotMedium(
}
void MediumEnvironment::UpdateWifiHotspotMediumForStartOrConnect(
api::WifiHotspotMedium& medium, HotspotCredentials* hotspot_credentials,
bool is_ap, bool enabled) {
api::WifiHotspotMedium& medium, HotspotCredentials* hotspot_credentials,
bool is_ap, bool enabled) {
if (!enabled_) return;
CountDownLatch latch(1);
@@ -913,8 +914,8 @@ void MediumEnvironment::UpdateWifiHotspotMediumForStartOrConnect(
<< "; ssid=" << hotspot_credentials->GetSSID()
<< "; password=" << hotspot_credentials->GetPassword();
} else {
NEARBY_LOGS(INFO) << "Reset WifiHotspot medium for Hotspot: this="
<< this << "; medium=" << &medium << role_status;
NEARBY_LOGS(INFO) << "Reset WifiHotspot medium for Hotspot: this=" << this
<< "; medium=" << &medium << role_status;
}
MutexLock lock(&mutex_);