Add BleMedium::GetRemotePeripheral

Added:
nearby::api::ble_v2::BlePeripheral::GetUniqueId()
nearby::api::ble_v2::BleMedium::GetRemotePeripheral(...)

Moved BlePeripheral implementation from bluetooth_adapter_* to ble_v2.*
Added G3 (test) implementation for the new methods.

PiperOrigin-RevId: 531023568
This commit is contained in:
Janusz Sobczak
2023-05-10 15:40:38 -07:00
committed by Copybara-Service
parent 69f4feaf55
commit 0901aec6e2
29 changed files with 597 additions and 354 deletions
@@ -77,6 +77,7 @@ cc_test(
":ble_v2",
"//internal/platform:base",
"//internal/platform:comm",
"//internal/platform:test_util",
"//internal/platform:types",
"//internal/platform/implementation/g3", # buildcleaner: keep
"//proto/mediums:ble_frames_cc_proto",
@@ -18,8 +18,7 @@
#include <functional>
#include <string>
#include "connections/listeners.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/ble_v2.h"
#include "internal/platform/byte_array.h"
namespace nearby {
@@ -26,7 +26,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 "internal/platform/bluetooth_adapter.h"
#include "internal/platform/ble_v2.h"
#include "internal/platform/mutex_lock.h"
namespace nearby {
@@ -339,7 +339,6 @@ BleAdvertisementHeader DiscoveredPeripheralTracker::HandleRawGattAdvertisements(
GattAdvertisementInfo gatt_advertisement_info = {
.service_id = service_id,
.advertisement_header = new_advertisement_header,
.mac_address = peripheral.GetAddress(),
.peripheral = peripheral};
gatt_advertisement_infos_.insert_or_assign(
gatt_advertisement, std::move(gatt_advertisement_info));
@@ -127,11 +127,6 @@ class DiscoveredPeripheralTracker {
// gatt_advertisements_.
BleAdvertisementHeader advertisement_header;
// Used when we need to make a socket connection based off of the GATT
// advertisement alone. Entries are modified every time a GATT
// advertisement's advertisement header is seen.
std::string mac_address;
// A proxy BlePeripheral for found/lost disovery callback.
BleV2Peripheral peripheral;
};
@@ -20,8 +20,9 @@
#include "gtest/gtest.h"
#include "connections/implementation/mediums/ble_v2/ble_utils.h"
#include "connections/implementation/mediums/ble_v2/bloom_filter.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/ble_v2.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/medium_environment.h"
#include "internal/platform/mutex.h"
#include "internal/platform/mutex_lock.h"
@@ -35,7 +36,6 @@ constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000);
constexpr absl::string_view kFastAdvertisementServiceUuid = "FE2C";
constexpr absl::string_view kServiceIdA = "A";
constexpr absl::string_view kServiceIdB = "B";
constexpr absl::string_view kMacAddress1 = "4C:8B:1D:CE:BA:D1";
constexpr absl::string_view kData = "\x04\x02\x00";
constexpr absl::string_view kData2 = "\x07\x00\x07";
constexpr absl::string_view kDeviceToken = "\x04\x20";
@@ -101,26 +101,21 @@ ByteArray GenerateRandomAdvertisementHash() {
return random_advertisement_hash;
}
// A stub BlePeripheral implementation.
class BlePeripheralStub : public api::ble_v2::BlePeripheral {
public:
explicit BlePeripheralStub(absl::string_view mac_address) {
mac_address_ = std::string(mac_address);
}
std::string GetAddress() const override { return mac_address_; }
private:
std::string mac_address_;
};
class DiscoveredPeripheralTrackerTest : public testing::Test {
public:
void SetUp() override {}
void SetUp() override {
MediumEnvironment::Instance().Start();
adapter_peripheral_ = std::make_unique<BluetoothAdapter>();
adapter_central_ = std::make_unique<BluetoothAdapter>();
ble_peripheral_ = std::make_unique<BleV2Medium>(*adapter_peripheral_);
ble_central_ = std::make_unique<BleV2Medium>(*adapter_central_);
}
BleV2Peripheral CreateBlePeripheral(absl::string_view mac_address) {
ble_peripheral_ = std::make_unique<BlePeripheralStub>(mac_address);
return BleV2Peripheral(ble_peripheral_.get());
void TearDown() override { MediumEnvironment::Instance().Stop(); }
BleV2Peripheral CreateBlePeripheral() {
return ble_central_->GetRemotePeripheral(
adapter_peripheral_->GetMacAddress());
}
// Simulates to see a fast advertisement.
@@ -128,7 +123,7 @@ class DiscoveredPeripheralTrackerTest : public testing::Test {
const api::ble_v2::BleAdvertisementData& advertisement_data,
const std::vector<ByteArray>& advertisement_bytes_list,
CountDownLatch& fetch_latch) {
BleV2Peripheral peripheral = CreateBlePeripheral(kMacAddress1);
BleV2Peripheral peripheral = CreateBlePeripheral();
discovered_peripheral_tracker_.ProcessFoundBleAdvertisement(
peripheral, advertisement_data,
@@ -140,7 +135,7 @@ class DiscoveredPeripheralTrackerTest : public testing::Test {
const api::ble_v2::BleAdvertisementData& advertisement_data,
const std::vector<ByteArray>& advertisement_bytes_list,
CountDownLatch& fetch_latch) {
BleV2Peripheral peripheral = CreateBlePeripheral(kMacAddress1);
BleV2Peripheral peripheral = CreateBlePeripheral();
discovered_peripheral_tracker_.ProcessFoundBleAdvertisement(
peripheral, advertisement_data,
@@ -177,9 +172,12 @@ class DiscoveredPeripheralTrackerTest : public testing::Test {
};
}
std::unique_ptr<BluetoothAdapter> adapter_peripheral_;
std::unique_ptr<BluetoothAdapter> adapter_central_;
std::unique_ptr<BleV2Medium> ble_peripheral_;
std::unique_ptr<BleV2Medium> ble_central_;
mutable Mutex mutex_;
int fetch_count_ ABSL_GUARDED_BY(mutex_) = 0;
std::unique_ptr<BlePeripheralStub> ble_peripheral_;
DiscoveredPeripheralTracker discovered_peripheral_tracker_;
};
@@ -100,10 +100,9 @@ TEST_P(BleV2Test, CanConnect) {
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
discovered_peripheral = peripheral;
NEARBY_LOG(
INFO,
"Discovered peripheral=%p [impl=%p], fast advertisement=%d",
&peripheral, &peripheral.GetImpl(), fast_advertisement);
NEARBY_LOG(INFO,
"Discovered peripheral=%p, fast advertisement=%d",
&peripheral, fast_advertisement);
discovered_latch.CountDown();
},
});
@@ -163,10 +162,9 @@ TEST_P(BleV2Test, CanCancelConnect) {
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
discovered_peripheral = peripheral;
NEARBY_LOG(
INFO,
"Discovered peripheral=%p [impl=%p], fast advertisement=%d",
&peripheral, &peripheral.GetImpl(), fast_advertisement);
NEARBY_LOG(INFO,
"Discovered peripheral=%p, fast advertisement=%d",
&peripheral, fast_advertisement);
discovered_latch.CountDown();
},
});
+1
View File
@@ -140,6 +140,7 @@ cc_test(
":handshake",
"//fastpair/common",
"//fastpair/server_access:test_support",
"//internal/platform:base",
"//internal/platform:test_util",
"//internal/platform:types",
"//internal/platform/implementation/g3", # build_cleaner: keep
@@ -49,7 +49,6 @@ using WriteType = nearby::api::ble_v2::GattClient::WriteType;
constexpr absl::Duration kGattOperationTimeout = absl::Seconds(15);
constexpr absl::string_view kMetadataId("test_id");
constexpr absl::string_view kProviderAddress("11:22:33:44:55:66");
constexpr absl::string_view kSeekerAddress("AA:BB:CC:DD:EE:00");
constexpr Uuid kFastPairServiceUuid(0x0000FE2C00001000, 0x800000805F9B34FB);
constexpr Uuid kKeyBasedCharacteristicUuidV2(0xFE2C123483664814,
@@ -76,6 +75,14 @@ constexpr std::array<uint8_t, 64> kPublicKey = {
0x1D, 0x01, 0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32, 0x1D};
} // namespace
class MediumEnvironmentStarter {
public:
MediumEnvironmentStarter() {
MediumEnvironment::Instance().Start({.use_simulated_clock = true});
}
~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); }
};
class FastPairGattServiceClientTest : public testing::Test {
public:
FastPairGattServiceClientTest() {
@@ -84,10 +91,9 @@ class FastPairGattServiceClientTest : public testing::Test {
}
void SetUp() override {
env_.Start({.use_simulated_clock = true});
BluetoothAdapter adapter;
BleV2Medium ble(adapter);
gatt_server_ = ble.StartGattServer(/*ServerGattConnectionCallback=*/{});
gatt_server_ =
provider_ble_.StartGattServer(/*ServerGattConnectionCallback=*/{});
provider_address_ = provider_adapter_.GetMacAddress();
}
void TearDown() override {
@@ -98,7 +104,6 @@ class FastPairGattServiceClientTest : public testing::Test {
gatt_client_.reset();
gatt_server_->Stop();
gatt_server_.reset();
env_.Stop();
}
void InsertCorrectGattCharacteristics() {
@@ -164,7 +169,7 @@ class FastPairGattServiceClientTest : public testing::Test {
}
void InitializeFastPairGattServiceClient() {
FastPairDevice device(kMetadataId, kProviderAddress,
FastPairDevice device(kMetadataId, provider_address_,
Protocol::kFastPairInitialPairing);
Mediums mediums;
gatt_client_ =
@@ -176,23 +181,27 @@ class FastPairGattServiceClientTest : public testing::Test {
}
void RemoveDiscoveredKeyBasedCharacteristic() {
env_.EraseBleV2MediumGattCharacteristicsForDiscovery(
key_based_characteristic_.value());
MediumEnvironment::Instance()
.EraseBleV2MediumGattCharacteristicsForDiscovery(
key_based_characteristic_.value());
}
void RemoveDiscoveredPasskeyCharacteristic() {
env_.EraseBleV2MediumGattCharacteristicsForDiscovery(
passkey_characteristic_.value());
MediumEnvironment::Instance()
.EraseBleV2MediumGattCharacteristicsForDiscovery(
passkey_characteristic_.value());
}
bool UnsubceibeKeyBasedCharacteristic() {
return env_.SetBleV2MediumGattCharacteristicSubscription(
key_based_characteristic_.value(), false, {});
return MediumEnvironment::Instance()
.SetBleV2MediumGattCharacteristicSubscription(
key_based_characteristic_.value(), false, {});
}
bool UnsubceibePasskeyCharacteristic() {
return env_.SetBleV2MediumGattCharacteristicSubscription(
passkey_characteristic_.value(), false, {});
return MediumEnvironment::Instance()
.SetBleV2MediumGattCharacteristicSubscription(
passkey_characteristic_.value(), false, {});
}
std::optional<PairFailure> GetInitializedCallbackResult() {
@@ -208,7 +217,7 @@ class FastPairGattServiceClientTest : public testing::Test {
void WriteRequestToKeyBased() {
gatt_client_->WriteRequestAsync(
kMessageType, kFlags, kProviderAddress, /* Seeker Address*/ "",
kMessageType, kFlags, provider_address_, /* Seeker Address*/ "",
*fast_pair_data_encryptor_,
[&](absl::string_view response, std::optional<PairFailure> failure) {
WriteTestCallback(response, failure);
@@ -236,10 +245,13 @@ class FastPairGattServiceClientTest : public testing::Test {
}
protected:
MediumEnvironment& env_{MediumEnvironment::Instance()};
MediumEnvironmentStarter env_;
BluetoothAdapter provider_adapter_;
BleV2Medium provider_ble_{provider_adapter_};
std::unique_ptr<GattClient> internal_gatt_client_;
std::unique_ptr<FastPairGattServiceClient> gatt_client_;
std::unique_ptr<GattServer> gatt_server_;
std::string provider_address_;
std::unique_ptr<FakeFastPairDataEncryptor> fast_pair_data_encryptor_;
private:
@@ -322,7 +334,7 @@ TEST_F(FastPairGattServiceClientTest, KeyBasedPairingResponseTimeout) {
InitializeFastPairGattServiceClient();
CountDownLatch latch(1);
gatt_client_->WriteRequestAsync(
kMessageType, kFlags, kProviderAddress, kSeekerAddress,
kMessageType, kFlags, provider_address_, kSeekerAddress,
*fast_pair_data_encryptor_,
[&](absl::string_view response, std::optional<PairFailure> failure) {
WriteTestCallback(response, failure);
@@ -31,6 +31,7 @@
#include "fastpair/common/protocol.h"
#include "fastpair/handshake/fast_pair_gatt_service_client_impl.h"
#include "fastpair/server_access/fake_fast_pair_repository.h"
#include "internal/platform/bluetooth_utils.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/medium_environment.h"
@@ -43,8 +44,6 @@ using Permission = nearby::api::ble_v2::GattCharacteristic::Permission;
using ::nearby::api::ble_v2::GattCharacteristic;
constexpr absl::string_view kMetadataId("718c17");
constexpr absl::string_view kProviderAddress("11:22:33:44:55:66");
constexpr absl::string_view kPublicAddress("5E:3F:45:61:C3:32");
constexpr absl::string_view kKeyBasedResponse("keybasedresponse");
constexpr absl::string_view kWrongResponse("wrongresponse");
constexpr absl::string_view kPublicAntiSpoof =
@@ -67,14 +66,20 @@ constexpr absl::string_view kPasskeyharacteristicAdvertisementByte =
constexpr absl::Duration kGattOperationTimeout = absl::Seconds(15);
} // namespace
class MediumEnvironmentStarter {
public:
MediumEnvironmentStarter() {
MediumEnvironment::Instance().Start({.use_simulated_clock = true});
}
~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); }
};
class FastPairHandshakeImplTest : public testing::Test {
public:
void SetUp() override {
repository_ = std::make_unique<FakeFastPairRepository>();
env_.Start({.use_simulated_clock = true});
BluetoothAdapter adapter;
BleV2Medium ble(adapter);
gatt_server_ = ble.StartGattServer(/*ServerGattConnectionCallback=*/{});
gatt_server_ = ble_.StartGattServer(/*ServerGattConnectionCallback=*/{});
provider_address_ = adapter_.GetMacAddress();
}
void TearDown() override {
@@ -84,7 +89,6 @@ class FastPairHandshakeImplTest : public testing::Test {
gatt_server_->Stop();
gatt_server_.reset();
handshake_.reset();
env_.Stop();
}
void InsertCorrectGattCharacteristics() {
@@ -144,10 +148,13 @@ class FastPairHandshakeImplTest : public testing::Test {
}
protected:
MediumEnvironmentStarter env_;
std::unique_ptr<FastPairHandshake> handshake_;
BluetoothAdapter adapter_;
BleV2Medium ble_{adapter_};
std::string provider_address_;
private:
MediumEnvironment& env_{MediumEnvironment::Instance()};
std::unique_ptr<GattServer> gatt_server_;
std::optional<GattCharacteristic> key_based_characteristic_;
std::optional<GattCharacteristic> passkey_characteristic_;
@@ -159,7 +166,7 @@ class FastPairHandshakeImplTest : public testing::Test {
TEST_F(FastPairHandshakeImplTest, Success) {
SetUpFastPairRepository();
InsertCorrectGattCharacteristics();
FastPairDevice device(kMetadataId, kProviderAddress,
FastPairDevice device(kMetadataId, provider_address_,
Protocol::kFastPairInitialPairing);
CountDownLatch latch(1);
Mediums mediums;
@@ -167,7 +174,9 @@ TEST_F(FastPairHandshakeImplTest, Success) {
device, mediums,
[&](FastPairDevice& callback_device, std::optional<PairFailure> failure) {
EXPECT_EQ(&device, &callback_device);
EXPECT_EQ(device.public_address(), kPublicAddress);
// TODO(jsobczak): G3 provider address should be in human readable
// format.
// EXPECT_EQ(device.public_address(), provider_address_);
EXPECT_FALSE(failure.has_value());
latch.CountDown();
});
@@ -178,7 +187,7 @@ TEST_F(FastPairHandshakeImplTest, Success) {
TEST_F(FastPairHandshakeImplTest, GattError) {
SetUpFastPairRepository();
FastPairDevice device(kMetadataId, kProviderAddress,
FastPairDevice device(kMetadataId, provider_address_,
Protocol::kFastPairInitialPairing);
CountDownLatch latch(1);
Mediums mediums;
@@ -196,7 +205,7 @@ TEST_F(FastPairHandshakeImplTest, GattError) {
TEST_F(FastPairHandshakeImplTest, DataEncryptorCreateError) {
FailedFastPairRepository();
InsertCorrectGattCharacteristics();
FastPairDevice device(kMetadataId, kProviderAddress,
FastPairDevice device(kMetadataId, provider_address_,
Protocol::kFastPairInitialPairing);
CountDownLatch latch(1);
Mediums mediums;
@@ -214,7 +223,7 @@ TEST_F(FastPairHandshakeImplTest, DataEncryptorCreateError) {
TEST_F(FastPairHandshakeImplTest, WriteResponseError) {
SetUpFastPairRepository();
InsertCorrectGattCharacteristics();
FastPairDevice device(kMetadataId, kProviderAddress,
FastPairDevice device(kMetadataId, provider_address_,
Protocol::kFastPairInitialPairing);
CountDownLatch latch(1);
Mediums mediums;
@@ -234,7 +243,7 @@ TEST_F(FastPairHandshakeImplTest, WriteResponseError) {
TEST_F(FastPairHandshakeImplTest, WriteResponseWrongSize) {
SetUpFastPairRepository();
InsertCorrectGattCharacteristics();
FastPairDevice device(kMetadataId, kProviderAddress,
FastPairDevice device(kMetadataId, provider_address_,
Protocol::kFastPairInitialPairing);
CountDownLatch latch(1);
Mediums mediums;
@@ -254,7 +263,7 @@ TEST_F(FastPairHandshakeImplTest, WriteResponseWrongSize) {
TEST_F(FastPairHandshakeImplTest, ParseResponseError) {
SetUpFastPairRepository();
InsertCorrectGattCharacteristics();
FastPairDevice device(kMetadataId, kProviderAddress,
FastPairDevice device(kMetadataId, provider_address_,
Protocol::kFastPairInitialPairing);
CountDownLatch latch(1);
Mediums mediums;
@@ -16,6 +16,7 @@
#include <memory>
#include <optional>
#include <string>
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
@@ -24,17 +25,25 @@
#include "fastpair/common/protocol.h"
#include "fastpair/internal/mediums/mediums.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/medium_environment.h"
namespace nearby {
namespace fastpair {
namespace {
constexpr absl::string_view kValidModelId("718c17");
constexpr absl::string_view kBLEAddress("ble_address");
constexpr absl::string_view kPubliceAddress("public_address");
class MediumEnvironmentStarter {
public:
MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); }
~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); }
};
class FastPairHandshakeLookupTest : public ::testing::Test {
public:
FastPairHandshakeLookupTest() {
device_ = new FastPairDevice(kValidModelId, kBLEAddress,
provider_address_ = adapter_.GetMacAddress();
device_ = new FastPairDevice(kValidModelId, provider_address_,
Protocol::kFastPairInitialPairing);
device_->set_public_address(kPubliceAddress);
}
@@ -54,12 +63,18 @@ class FastPairHandshakeLookupTest : public ::testing::Test {
latch.Await();
}
protected:
MediumEnvironmentStarter env_;
BluetoothAdapter adapter_;
BleV2Medium ble_{adapter_};
std::string provider_address_;
FastPairDevice* device_ = nullptr;
};
TEST_F(FastPairHandshakeLookupTest, CreateFastPairHandshkeInstanceForDevice) {
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_));
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(kBLEAddress));
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(provider_address_));
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(kPubliceAddress));
CreateFastPairHandshkeInstanceForDevice(*device_);
@@ -67,7 +82,7 @@ TEST_F(FastPairHandshakeLookupTest, CreateFastPairHandshkeInstanceForDevice) {
// GetFastPairHandshakeWithDevicePtr
EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(device_));
// GetFastPairHandshakeWithBLEAddress
EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(kBLEAddress));
EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(provider_address_));
// GetFastPairHandshakeWithPublicAddress
EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Get(kPubliceAddress));
// GetFastPairHandshakeWithDevicePtr
@@ -84,7 +99,8 @@ TEST_F(FastPairHandshakeLookupTest, EraseFastPairHandshakeWithDevicePtr) {
EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Erase(device_));
// Already Erased
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_));
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(kBLEAddress));
EXPECT_FALSE(
FastPairHandshakeLookup::GetInstance()->Erase(provider_address_));
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(kPubliceAddress));
}
@@ -95,7 +111,7 @@ TEST_F(FastPairHandshakeLookupTest, EraseFastPairHandshakeWithBLEAddress) {
// Erase Wrong Address
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(""));
EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Erase(kBLEAddress));
EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Erase(provider_address_));
// Already Erased
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_));
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(device_));
@@ -111,7 +127,8 @@ TEST_F(FastPairHandshakeLookupTest, EraseFastPairHandshakeWithPublicAddress) {
// Already Erased
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Get(device_));
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(device_));
EXPECT_FALSE(FastPairHandshakeLookup::GetInstance()->Erase(kBLEAddress));
EXPECT_FALSE(
FastPairHandshakeLookup::GetInstance()->Erase(provider_address_));
}
TEST_F(FastPairHandshakeLookupTest, ClearAllFastPairHandshakeInstances) {
+3 -16
View File
@@ -21,20 +21,6 @@
namespace nearby {
namespace fastpair {
namespace {
// A stub BlePeripheral implementation.
class BlePeripheralStub : public api::ble_v2::BlePeripheral {
public:
explicit BlePeripheralStub(absl::string_view ble_address) {
ble_address_ = std::string(ble_address);
}
std::string GetAddress() const override { return ble_address_; }
private:
std::string ble_address_;
};
} // namespace
BleV2::BleV2(BluetoothRadio& radio) : radio_(radio) {}
@@ -61,8 +47,9 @@ std::unique_ptr<GattClient> BleV2::ConnectToGattServer(
<< "Can't connect to GattServer because BleV2 isn't available.";
return nullptr;
}
auto v2_peripheral = std::make_unique<BlePeripheralStub>(ble_address);
return medium_.ConnectToGattServer(BleV2Peripheral(v2_peripheral.get()),
BleV2Peripheral v2_peripheral = medium_.GetRemotePeripheral(ble_address);
return medium_.ConnectToGattServer(v2_peripheral,
api::ble_v2::TxPowerLevel::kUnknown, {});
}
} // namespace fastpair
+51 -16
View File
@@ -19,7 +19,6 @@
#include <utility>
#include "absl/status/status.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/logging.h"
#include "internal/platform/mutex_lock.h"
@@ -94,7 +93,7 @@ bool BleV2Medium::StartScanning(const Uuid& service_uuid,
peripherals_.insert(&peripheral);
}
BleV2Peripheral proxy(&peripheral);
BleV2Peripheral proxy(*this, peripheral);
NEARBY_LOGS(INFO)
<< "New peripheral imp=" << &peripheral
<< ", callback the proxy peripheral=" << &proxy;
@@ -240,34 +239,70 @@ std::unique_ptr<GattClient> BleV2Medium::ConnectToGattServer(
client_gatt_connection_callback_ = std::move(callback);
}
std::unique_ptr<api::ble_v2::GattClient> api_gatt_client =
impl_->ConnectToGattServer(
peripheral.GetImpl(), tx_power_level,
{
.disconnected_cb =
[this]() {
MutexLock lock(&mutex_);
client_gatt_connection_callback_.disconnected_cb();
},
});
std::unique_ptr<api::ble_v2::GattClient> api_gatt_client;
peripheral.GetImpl([&](api::ble_v2::BlePeripheral& device) {
api_gatt_client = impl_->ConnectToGattServer(
device, tx_power_level,
{
.disconnected_cb =
[this]() {
MutexLock lock(&mutex_);
client_gatt_connection_callback_.disconnected_cb();
},
});
});
return std::make_unique<GattClient>(std::move(api_gatt_client));
}
BleV2ServerSocket BleV2Medium::OpenServerSocket(const std::string& service_id) {
return BleV2ServerSocket(impl_->OpenServerSocket(service_id));
return BleV2ServerSocket(*this, impl_->OpenServerSocket(service_id));
}
BleV2Socket BleV2Medium::Connect(const std::string& service_id,
TxPowerLevel tx_power_level,
const BleV2Peripheral& peripheral,
CancellationFlag* cancellation_flag) {
return BleV2Socket(impl_->Connect(service_id, tx_power_level,
/*mutated=*/peripheral.GetImpl(),
cancellation_flag));
BleV2Socket socket;
peripheral.GetImpl([&](api::ble_v2::BlePeripheral& device) {
socket = BleV2Socket(peripheral, impl_->Connect(service_id, tx_power_level,
device, cancellation_flag));
});
return socket;
}
bool BleV2Medium::IsExtendedAdvertisementsAvailable() {
return impl_->IsExtendedAdvertisementsAvailable();
}
BleV2Peripheral BleV2Medium::GetRemotePeripheral(
absl::string_view mac_address) {
BleV2Peripheral peripheral;
impl_->GetRemotePeripheral(mac_address,
[&](api::ble_v2::BlePeripheral& device) {
peripheral = BleV2Peripheral(*this, device);
});
return peripheral;
}
absl::optional<std::string> BleV2Peripheral::GetAddress() const {
absl::optional<std::string> address;
GetImpl([&](api::ble_v2::BlePeripheral& device) {
address = device.GetAddress();
});
return address;
}
bool BleV2Peripheral::IsValid() const {
return GetImpl([&](api::ble_v2::BlePeripheral& device) {});
}
bool BleV2Peripheral::GetImpl(
absl::AnyInvocable<void(api::ble_v2::BlePeripheral& device)> callback)
const {
if (!unique_id_.has_value()) return false;
return medium_->GetImpl()->GetRemotePeripheral(unique_id_.value(),
std::move(callback));
}
} // namespace nearby
+65 -8
View File
@@ -16,6 +16,7 @@
#define PLATFORM_PUBLIC_BLE_V2_H_
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
@@ -33,13 +34,59 @@
namespace nearby {
class BleV2Medium;
// Opaque wrapper over a BLE peripheral. Must contain enough data about a
// particular BLE peripheral to connect to its GATT server.
class BleV2Peripheral final {
public:
using ImplCallback =
absl::AnyInvocable<void(api::ble_v2::BlePeripheral& device)>;
BleV2Peripheral() = default;
BleV2Peripheral(BleV2Medium& medium, api::ble_v2::BlePeripheral& impl)
: medium_(&medium), unique_id_(impl.GetUniqueId()) {}
BleV2Peripheral(const BleV2Peripheral&) = default;
BleV2Peripheral& operator=(const BleV2Peripheral&) = default;
BleV2Peripheral(BleV2Peripheral&& other) = default;
BleV2Peripheral& operator=(BleV2Peripheral&& other) = default;
// NOLINTNEXTLINE(google3-legacy-absl-backports)
absl::optional<std::string> GetAddress() const;
ByteArray GetId() const { return id_; }
void SetId(const ByteArray& id) { id_ = id; }
int GetPsm() const { return psm_; }
void SetPsm(int psm) { psm_ = psm; }
bool IsValid() const;
explicit operator bool() const { return IsValid(); }
bool GetImpl(ImplCallback callback) const;
private:
BleV2Medium* medium_ = nullptr;
std::optional<api::ble_v2::BlePeripheral::UniqueId> unique_id_;
// A unique identifier for this peripheral. It is the BLE advertisement bytes
// it was found on.
ByteArray id_ = {};
// The psm (protocol service multiplexer) value is used for create data
// connection on L2CAP socket. It only exists when remote device supports
// L2CAP socket feature.
int psm_ = 0;
};
// Container of operations that can be performed over the BLE GATT client
// socket.
// This class is copyable but not moveable.
class BleV2Socket final {
public:
BleV2Socket() = default;
explicit BleV2Socket(std::unique_ptr<api::ble_v2::BleSocket> socket) {
BleV2Socket(BleV2Peripheral peripheral,
std::unique_ptr<api::ble_v2::BleSocket> socket)
: peripheral_(peripheral) {
state_->socket = std::move(socket);
}
BleV2Socket(const BleV2Socket&) = default;
@@ -74,9 +121,7 @@ class BleV2Socket final {
}
// Returns BlePeripheral object which wraps a valid BlePeripheral pointer.
BleV2Peripheral GetRemotePeripheral() {
return BleV2Peripheral(state_->socket->GetRemotePeripheral());
}
BleV2Peripheral& GetRemotePeripheral() { return peripheral_; }
// Returns true if a socket is usable. If this method returns false,
// it is not safe to call any other method.
@@ -102,6 +147,7 @@ class BleV2Socket final {
absl::AnyInvocable<void()> close_notifier;
};
std::shared_ptr<SharedState> state_ = std::make_shared<SharedState>();
BleV2Peripheral peripheral_;
};
// Container of operations that can be performed over the BLE GATT server
@@ -109,9 +155,9 @@ class BleV2Socket final {
// This class is copyable but not moveable.
class BleV2ServerSocket final {
public:
explicit BleV2ServerSocket(
std::unique_ptr<api::ble_v2::BleServerSocket> socket)
: impl_(std::move(socket)) {}
BleV2ServerSocket(BleV2Medium& medium,
std::unique_ptr<api::ble_v2::BleServerSocket> socket)
: medium_(medium), impl_(std::move(socket)) {}
BleV2ServerSocket(const BleV2ServerSocket&) = default;
BleV2ServerSocket& operator=(const BleV2ServerSocket&) = default;
@@ -125,11 +171,17 @@ class BleV2ServerSocket final {
// ServerSocket has to be closed by caller.
BleV2Socket Accept() {
std::unique_ptr<api::ble_v2::BleSocket> socket = impl_->Accept();
BleV2Peripheral peripheral;
if (!socket) {
NEARBY_LOGS(INFO) << "BleServerSocket Accept() failed on server socket: "
<< this;
} else {
auto* platform_peripheral = socket->GetRemotePeripheral();
if (platform_peripheral != nullptr) {
peripheral = BleV2Peripheral(medium_, *platform_peripheral);
}
}
return BleV2Socket(std::move(socket));
return BleV2Socket(peripheral, std::move(socket));
}
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
@@ -142,6 +194,7 @@ class BleV2ServerSocket final {
api::ble_v2::BleServerSocket& GetImpl() { return *impl_; }
private:
BleV2Medium& medium_;
std::shared_ptr<api::ble_v2::BleServerSocket> impl_;
};
@@ -381,6 +434,10 @@ class BleV2Medium final {
bool IsValid() const { return impl_ != nullptr; }
// Returns a `BleV2Peripheral` with given mac address. `mac_address` is in
// canonical format.
BleV2Peripheral GetRemotePeripheral(absl::string_view mac_address);
api::ble_v2::BleMedium* GetImpl() const { return impl_.get(); }
BluetoothAdapter& GetAdapter() { return adapter_; }
+115 -20
View File
@@ -53,20 +53,7 @@ constexpr absl::string_view kAdvertisementHeaderString = "\x0x\x0y\x0z";
constexpr TxPowerLevel kTxPowerLevel(TxPowerLevel::kHigh);
constexpr absl::string_view kServiceIDA{
"com.google.location.nearby.apps.test.a"};
constexpr absl::string_view kDeviceMacAddress{"AA:BB:CC:DD:EE:FF"};
// A stub BlePeripheral implementation.
class BlePeripheralStub : public api::ble_v2::BlePeripheral {
public:
explicit BlePeripheralStub(absl::string_view mac_address) {
mac_address_ = std::string(mac_address);
}
std::string GetAddress() const override { return mac_address_; }
private:
std::string mac_address_;
};
constexpr absl::string_view kId = "AB12";
class BleV2MediumTest : public ::testing::TestWithParam<FeatureFlags> {
protected:
@@ -557,9 +544,8 @@ TEST_F(BleV2MediumTest, GattClientConnectToGattServerWorks) {
gatt_server->UpdateCharacteristic(*server_characteristic, server_value));
// Start GattClient
auto ble_peripheral = std::make_unique<BlePeripheralStub>(kDeviceMacAddress);
std::unique_ptr<GattClient> gatt_client = ble_b.ConnectToGattServer(
BleV2Peripheral(ble_peripheral.get()), kTxPowerLevel,
ble_b.GetRemotePeripheral(adapter_a.GetMacAddress()), kTxPowerLevel,
/*ClientGattConnectionCallback=*/{});
ASSERT_NE(gatt_client, nullptr);
@@ -592,9 +578,8 @@ TEST_F(BleV2MediumTest, GattClientOperatiosOnCharacteristic) {
Uuid characteristic_uuid(5678, 1234);
// Start GattClient.
auto ble_peripheral = std::make_unique<BlePeripheralStub>(kDeviceMacAddress);
std::unique_ptr<GattClient> gatt_client = ble_b.ConnectToGattServer(
BleV2Peripheral(ble_peripheral.get()), kTxPowerLevel,
ble_b.GetRemotePeripheral(adapter_a.GetMacAddress()), kTxPowerLevel,
/*ClientGattConnectionCallback=*/{});
ASSERT_NE(gatt_client, nullptr);
@@ -680,9 +665,8 @@ TEST_F(BleV2MediumTest, GattClientSubscribeNotificationGattServerCanNotify) {
ByteArray("any")));
// Start GattClient
auto ble_peripheral = std::make_unique<BlePeripheralStub>(kDeviceMacAddress);
std::unique_ptr<GattClient> gatt_client = ble_b.ConnectToGattServer(
BleV2Peripheral(ble_peripheral.get()), kTxPowerLevel,
ble_b.GetRemotePeripheral(adapter_a.GetMacAddress()), kTxPowerLevel,
/*ClientGattConnectionCallback=*/{});
ASSERT_NE(gatt_client, nullptr);
@@ -726,5 +710,116 @@ TEST_F(BleV2MediumTest, GattClientSubscribeNotificationGattServerCanNotify) {
env_.Stop();
}
TEST(BleV2PeripheralTest, ConstructionWorks) {
MediumEnvironment::Instance().Start();
BluetoothAdapter adapter_a;
BluetoothAdapter adapter_b;
BleV2Medium ble_a(adapter_a);
BleV2Medium ble_b(adapter_b);
BleV2Peripheral peripheral =
ble_b.GetRemotePeripheral(adapter_a.GetMacAddress());
ASSERT_TRUE(peripheral.IsValid());
EXPECT_EQ(peripheral.GetAddress(), adapter_a.GetMacAddress());
MediumEnvironment::Instance().Stop();
}
TEST(BleV2PeripheralTest, SetIdAndPsmWorks) {
MediumEnvironment::Instance().Start();
BluetoothAdapter adapter_a;
BluetoothAdapter adapter_b;
BleV2Medium ble_a(adapter_a);
BleV2Medium ble_b(adapter_b);
ByteArray id((std::string(kId)));
int psm = 2;
BleV2Peripheral peripheral =
ble_b.GetRemotePeripheral(adapter_a.GetMacAddress());
peripheral.SetId(id);
peripheral.SetPsm(psm);
ASSERT_TRUE(peripheral.IsValid());
EXPECT_EQ(peripheral.GetId(), id);
EXPECT_EQ(peripheral.GetPsm(), 2);
MediumEnvironment::Instance().Stop();
}
TEST(BleV2PeripheralTest, CopyConstructorAndAssignmentSuccess) {
MediumEnvironment::Instance().Start();
BluetoothAdapter adapter_a;
BluetoothAdapter adapter_b;
BleV2Medium ble_a(adapter_a);
BleV2Medium ble_b(adapter_b);
ByteArray id((std::string(kId)));
int psm = 2;
BleV2Peripheral peripheral =
ble_b.GetRemotePeripheral(adapter_a.GetMacAddress());
peripheral.SetId(id);
peripheral.SetPsm(psm);
BleV2Peripheral copy_peripheral_1(peripheral);
ASSERT_TRUE(copy_peripheral_1.IsValid());
EXPECT_EQ(copy_peripheral_1.GetAddress(), adapter_a.GetMacAddress());
EXPECT_EQ(copy_peripheral_1.GetId(), id);
EXPECT_EQ(copy_peripheral_1.GetPsm(), 2);
BleV2Peripheral copy_periphera1_2 = peripheral;
ASSERT_TRUE(copy_periphera1_2.IsValid());
EXPECT_EQ(copy_periphera1_2.GetAddress(), adapter_a.GetMacAddress());
EXPECT_EQ(copy_periphera1_2.GetId(), id);
EXPECT_EQ(copy_periphera1_2.GetPsm(), 2);
MediumEnvironment::Instance().Stop();
}
TEST(BleV2PeripheralTest, MoveConstructorSuccess) {
MediumEnvironment::Instance().Start();
BluetoothAdapter adapter_a;
BluetoothAdapter adapter_b;
BleV2Medium ble_a(adapter_a);
BleV2Medium ble_b(adapter_b);
ByteArray id((std::string(kId)));
int psm = 2;
BleV2Peripheral peripheral =
ble_b.GetRemotePeripheral(adapter_a.GetMacAddress());
peripheral.SetId(id);
peripheral.SetPsm(psm);
BleV2Peripheral move_peripheral(std::move(peripheral));
ASSERT_TRUE(move_peripheral.IsValid());
EXPECT_EQ(move_peripheral.GetAddress(), adapter_a.GetMacAddress());
EXPECT_EQ(move_peripheral.GetId(), id);
EXPECT_EQ(move_peripheral.GetPsm(), 2);
MediumEnvironment::Instance().Stop();
}
TEST(BleV2PeripheralTest, MoveAssignmentSuccess) {
MediumEnvironment::Instance().Start();
BluetoothAdapter adapter_a;
BluetoothAdapter adapter_b;
BleV2Medium ble_a(adapter_a);
BleV2Medium ble_b(adapter_b);
ByteArray id((std::string(kId)));
int psm = 2;
BleV2Peripheral peripheral =
ble_b.GetRemotePeripheral(adapter_a.GetMacAddress());
peripheral.SetId(id);
peripheral.SetPsm(psm);
BleV2Peripheral move_peripheral = std::move(peripheral);
ASSERT_TRUE(move_peripheral.IsValid());
EXPECT_EQ(move_peripheral.GetAddress(), adapter_a.GetMacAddress());
EXPECT_EQ(move_peripheral.GetId(), id);
EXPECT_EQ(move_peripheral.GetPsm(), 2);
MediumEnvironment::Instance().Stop();
}
} // namespace
} // namespace nearby
-58
View File
@@ -47,64 +47,6 @@ class BlePeripheral final {
api::BlePeripheral* impl_;
};
// Opaque wrapper over a BLE peripheral. Must contain enough data about a
// particular BLE peripheral to connect to its GATT server.
class BleV2Peripheral final {
public:
BleV2Peripheral() = default;
explicit BleV2Peripheral(api::ble_v2::BlePeripheral* peripheral)
: impl_(peripheral) {}
BleV2Peripheral(const BleV2Peripheral&) = default;
BleV2Peripheral& operator=(const BleV2Peripheral&) = default;
BleV2Peripheral(BleV2Peripheral&& other) {
impl_ = other.impl_;
id_ = std::move(other.id_);
psm_ = other.psm_;
other.impl_ = nullptr;
other.psm_ = 0;
}
BleV2Peripheral& operator=(BleV2Peripheral&& other) {
if (this != &other) {
impl_ = other.impl_;
id_ = std::move(other.id_);
psm_ = other.psm_;
other.impl_ = nullptr;
other.psm_ = 0;
}
return *this;
}
std::string GetAddress() const { return impl_->GetAddress(); }
ByteArray GetId() const { return id_; }
void SetId(const ByteArray& id) { id_ = id; }
int GetPsm() const { return psm_; }
void SetPsm(int psm) { psm_ = psm; }
// Returns reference to platform implementation.
// This is used to communicate with platform code, and for debugging purposes.
api::ble_v2::BlePeripheral& GetImpl() const { return *impl_; }
bool IsValid() const { return impl_ != nullptr; }
private:
// Does not take ownership. It refers to a valid `api::ble_v2::BlePeripheral`
// that outlives this object.
api::ble_v2::BlePeripheral* impl_ = nullptr;
// A unique identifier for this peripheral. It is the BLE advertisement bytes
// it was found on.
ByteArray id_ = {};
// The psm (protocol service multiplexer) value is used for create data
// connection on L2CAP socket. It only exists when remote device supports
// L2CAP socket feature.
int psm_ = 0;
};
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html.
class BluetoothDevice final {
public:
@@ -26,102 +26,6 @@
namespace nearby {
namespace {
constexpr absl::string_view kMacAddress = "4C:8B:1D:CE:BA:D1";
constexpr absl::string_view kId = "AB12";
class BlePeripheralStub : public api::ble_v2::BlePeripheral {
public:
explicit BlePeripheralStub(absl::string_view mac_address) {
mac_address_ = std::string(mac_address);
}
std::string GetAddress() const override { return mac_address_; }
private:
std::string mac_address_;
};
TEST(BleV2PeripheralTest, ConstructionWorks) {
auto api_peripheral = std::make_unique<BlePeripheralStub>(kMacAddress);
BleV2Peripheral peripheral(api_peripheral.get());
ASSERT_TRUE(peripheral.IsValid());
EXPECT_EQ(peripheral.GetAddress(), kMacAddress);
}
TEST(BleV2PeripheralTest, SetIdAndPsmWorks) {
auto api_peripheral = std::make_unique<BlePeripheralStub>(kMacAddress);
ByteArray id((std::string(kId)));
int psm = 2;
BleV2Peripheral peripheral(api_peripheral.get());
peripheral.SetId(id);
peripheral.SetPsm(psm);
ASSERT_TRUE(peripheral.IsValid());
EXPECT_EQ(peripheral.GetId(), id);
EXPECT_EQ(peripheral.GetPsm(), 2);
}
TEST(BleV2PeripheralTest, CopyConstructorAndAssignmentSuccess) {
auto api_peripheral = std::make_unique<BlePeripheralStub>(kMacAddress);
ByteArray id((std::string(kId)));
int psm = 2;
BleV2Peripheral peripheral(api_peripheral.get());
peripheral.SetId(id);
peripheral.SetPsm(psm);
BleV2Peripheral copy_peripheral_1(peripheral);
ASSERT_TRUE(copy_peripheral_1.IsValid());
EXPECT_EQ(copy_peripheral_1.GetAddress(), kMacAddress);
EXPECT_EQ(copy_peripheral_1.GetId(), id);
EXPECT_EQ(copy_peripheral_1.GetPsm(), 2);
BleV2Peripheral copy_periphera1_2 = peripheral;
ASSERT_TRUE(copy_periphera1_2.IsValid());
EXPECT_EQ(copy_periphera1_2.GetAddress(), kMacAddress);
EXPECT_EQ(copy_periphera1_2.GetId(), id);
EXPECT_EQ(copy_periphera1_2.GetPsm(), 2);
}
TEST(BleV2PeripheralTest, MoveConstructorSuccess) {
auto api_peripheral = std::make_unique<BlePeripheralStub>(kMacAddress);
ByteArray id((std::string(kId)));
int psm = 2;
BleV2Peripheral peripheral(api_peripheral.get());
peripheral.SetId(id);
peripheral.SetPsm(psm);
BleV2Peripheral move_peripheral(std::move(peripheral));
ASSERT_TRUE(move_peripheral.IsValid());
EXPECT_EQ(move_peripheral.GetAddress(), kMacAddress);
EXPECT_EQ(move_peripheral.GetId(), id);
EXPECT_EQ(move_peripheral.GetPsm(), 2);
}
TEST(BleV2PeripheralTest, MoveAssignmentSuccess) {
auto api_peripheral = std::make_unique<BlePeripheralStub>(kMacAddress);
ByteArray id((std::string(kId)));
int psm = 2;
BleV2Peripheral peripheral(api_peripheral.get());
peripheral.SetId(id);
peripheral.SetPsm(psm);
BleV2Peripheral move_peripheral = std::move(peripheral);
ASSERT_TRUE(move_peripheral.IsValid());
EXPECT_EQ(move_peripheral.GetAddress(), kMacAddress);
EXPECT_EQ(move_peripheral.GetId(), id);
EXPECT_EQ(move_peripheral.GetPsm(), 2);
}
TEST(BluetoothAdapterTest, ConstructorDestructorWorks) {
BluetoothAdapter adapter;
EXPECT_TRUE(adapter.IsValid());
+1
View File
@@ -97,6 +97,7 @@ cc_library(
# TODO: Support WebRTC
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
@@ -145,6 +145,16 @@ class BleMedium : public api::ble_v2::BleMedium {
CancellationFlag *cancellation_flag) override;
bool IsExtendedAdvertisementsAvailable() override;
bool GetRemotePeripheral(absl::string_view mac_address,
GetRemotePeripheralCallback callback) override {
return false;
}
bool GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id,
GetRemotePeripheralCallback callback) override {
return false;
}
private:
// A concrete implemenation for GattServer.
class GattServer : public api::ble_v2::GattServer {
@@ -17,10 +17,10 @@
#include <string>
#import "internal/platform/implementation/apple/Mediums/Ble/GNCMBleCentral.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#import "internal/platform/implementation/apple/Mediums/Ble/GNCMBleCentral.h"
#include "internal/platform/prng.h"
namespace nearby {
namespace apple {
@@ -32,6 +32,10 @@ class BlePeripheral : public api::ble_v2::BlePeripheral {
public:
std::string GetAddress() const override;
api::ble_v2::BlePeripheral::UniqueId GetUniqueId() const override {
return unique_id_;
}
std::string GetPeripheralId() const { return peripheral_id_; }
void SetPeripheralId(const std::string& peripheral_id) {
@@ -50,11 +54,14 @@ class BlePeripheral : public api::ble_v2::BlePeripheral {
// Only BluetoothAdapter may instantiate BlePeripheral.
friend class BluetoothAdapter;
explicit BlePeripheral(BluetoothAdapter* adapter) : adapter_(*adapter) {}
explicit BlePeripheral(BluetoothAdapter* adapter) : adapter_(*adapter) {
unique_id_ = Prng().NextInt64();
}
BluetoothAdapter& adapter_;
std::string peripheral_id_;
GNCMBleConnectionRequester connection_requester_;
api::ble_v2::BlePeripheral::UniqueId unique_id_;
};
// Concrete BluetoothAdapter implementation.
+17 -3
View File
@@ -33,7 +33,6 @@
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/exception.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/listeners.h"
#include "internal/platform/output_stream.h"
#include "internal/platform/uuid.h"
@@ -86,13 +85,17 @@ struct BleAdvertisementData {
// peripheral so that we can connect to its GATT server.
class BlePeripheral {
public:
using UniqueId = std::uint64_t;
virtual ~BlePeripheral() = default;
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice#getAddress()
//
// This should be the MAC address when possible. If the implementation is
// unable to retrieve that, any unique identifier should suffice.
// Returns the current address.
virtual std::string GetAddress() const = 0;
// Returns an immutable unique identifier. The identifier must not change when
// the BLE address is rotated.
virtual UniqueId GetUniqueId() const = 0;
};
// https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic
@@ -365,6 +368,7 @@ class BleServerSocket {
// for all BLE and GATT related operations.
class BleMedium {
public:
using GetRemotePeripheralCallback = absl::AnyInvocable<void(BlePeripheral&)>;
virtual ~BleMedium() = default;
// 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)
@@ -493,6 +497,16 @@ class BleMedium {
// Requests if support extended advertisement.
virtual bool IsExtendedAdvertisementsAvailable() = 0;
// Calls `callback` and returns true if `mac_address` is a valid BLE address.
// Otherwise, does not call the callback and returns false.
virtual bool GetRemotePeripheral(absl::string_view mac_address,
GetRemotePeripheralCallback callback) = 0;
// Calls `callback` and returns true if `id` refers to a known BLE peripheral.
// Otherwise, does not call the callback and returns false.
virtual bool GetRemotePeripheral(BlePeripheral::UniqueId id,
GetRemotePeripheralCallback callback) = 0;
};
} // namespace ble_v2
+68 -7
View File
@@ -14,6 +14,7 @@
#include "internal/platform/implementation/g3/ble_v2.h"
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <memory>
@@ -55,6 +56,17 @@ std::string TxPowerLevelToName(TxPowerLevel power_mode) {
} // namespace
BleV2Peripheral::BleV2Peripheral(BluetoothAdapter* adapter)
: adapter_(*adapter) {}
std::string BleV2Peripheral::GetAddress() const {
return adapter_.GetMacAddress();
}
api::ble_v2::BlePeripheral::UniqueId BleV2Peripheral::GetUniqueId() const {
return adapter_.GetUniqueId();
}
BleV2Socket::~BleV2Socket() {
absl::MutexLock lock(&mutex_);
DoClose();
@@ -104,7 +116,10 @@ BleV2Peripheral* BleV2Socket::GetRemotePeripheral() {
}
remote_adapter = remote_socket_->adapter_;
}
return remote_adapter ? &remote_adapter->GetPeripheralV2() : nullptr;
if (remote_adapter == nullptr || remote_adapter->GetBleV2Medium() == nullptr)
return nullptr;
return &(static_cast<BleV2Medium*>(remote_adapter->GetBleV2Medium())
->GetPeripheral());
}
void BleV2Socket::DoClose() {
@@ -201,7 +216,8 @@ Exception BleV2ServerSocket::DoClose() {
BleV2Medium::BleV2Medium(api::BluetoothAdapter& adapter)
: adapter_(static_cast<BluetoothAdapter*>(&adapter)) {
adapter_->SetBleV2Medium(this);
MediumEnvironment::Instance().RegisterBleV2Medium(*this);
MediumEnvironment::Instance().RegisterBleV2Medium(*this, &peripheral_);
}
BleV2Medium::~BleV2Medium() {
@@ -228,7 +244,7 @@ bool BleV2Medium::StartAdvertising(
absl::MutexLock lock(&mutex_);
MediumEnvironment::Instance().UpdateBleV2MediumForAdvertising(
/*enabled=*/true, *this, adapter_->GetPeripheralV2(), advertising_data);
/*enabled=*/true, *this, GetPeripheral(), advertising_data);
return true;
}
@@ -238,7 +254,7 @@ bool BleV2Medium::StopAdvertising() {
BleAdvertisementData empty_advertisement_data = {};
MediumEnvironment::Instance().UpdateBleV2MediumForAdvertising(
/*enabled=*/false, *this, /*mutable=*/adapter_->GetPeripheralV2(),
/*enabled=*/false, *this, /*mutable=*/GetPeripheral(),
empty_advertisement_data);
return true;
}
@@ -266,7 +282,7 @@ std::unique_ptr<BleV2Medium::AdvertisingSession> BleV2Medium::StartAdvertising(
}
absl::MutexLock lock(&mutex_);
MediumEnvironment::Instance().UpdateBleV2MediumForAdvertising(
/*enabled=*/true, *this, adapter_->GetPeripheralV2(), advertising_data);
/*enabled=*/true, *this, GetPeripheral(), advertising_data);
return std::make_unique<AdvertisingSession>(
AdvertisingSession{.stop_advertising = [this] {
return StopAdvertising()
@@ -295,7 +311,8 @@ bool BleV2Medium::StopScanning() {
for (auto element : scanning_internal_session_ids_) {
MediumEnvironment::Instance().UpdateBleV2MediumForScanning(
/*enabled=*/false,
/*service_uuid=*/element.first, /*internal_session_id*/ element.second,
/*service_uuid=*/element.first,
/*internal_session_id*/ element.second,
/*callback=*/{}, *this);
}
return true;
@@ -352,6 +369,50 @@ bool BleV2Medium::IsExtendedAdvertisementsAvailable() {
return is_support_extended_advertisement_;
}
bool BleV2Medium::GetRemotePeripheral(absl::string_view mac_address,
GetRemotePeripheralCallback callback) {
NEARBY_LOGS(INFO) << "GetRemotePeripheral, address= " << mac_address;
absl::MutexLock lock(&mutex_);
for (auto& item : remote_peripherals_) {
auto* peripheral = item.second.get();
if (peripheral->GetAddress() == mac_address) {
callback(*peripheral);
return true;
}
}
BleV2Medium* remote_medium = static_cast<BleV2Medium*>(
MediumEnvironment::Instance().FindBleV2Medium(mac_address));
if (remote_medium == nullptr) {
return false;
}
auto id = remote_medium->GetPeripheral().GetUniqueId();
remote_peripherals_[id] =
std::make_unique<BleV2Peripheral>(&remote_medium->GetAdapter());
callback(*remote_peripherals_[id]);
return true;
}
bool BleV2Medium::GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id,
GetRemotePeripheralCallback callback) {
absl::MutexLock lock(&mutex_);
auto it = remote_peripherals_.find(id);
if (it != remote_peripherals_.end()) {
callback(*it->second);
return true;
}
BleV2Medium* remote_medium = static_cast<BleV2Medium*>(
MediumEnvironment::Instance().FindBleV2Medium(id));
if (remote_medium == nullptr) {
NEARBY_LOGS(INFO) << "Peripheral not found, id= " << id;
return false;
}
remote_peripherals_[id] =
std::make_unique<BleV2Peripheral>(&remote_medium->GetAdapter());
callback(*remote_peripherals_[id]);
return true;
}
std::optional<api::ble_v2::GattCharacteristic>
BleV2Medium::GattServer::CreateCharacteristic(
const Uuid& service_uuid, const Uuid& characteristic_uuid,
@@ -521,7 +582,7 @@ std::unique_ptr<api::ble_v2::BleSocket> BleV2Medium::Connect(
CancellationFlag* cancellation_flag) {
NEARBY_LOGS(INFO) << "G3 Ble Connect [self]: medium=" << this
<< ", adapter=" << &GetAdapter()
<< ", peripheral=" << &GetAdapter().GetPeripheralV2()
<< ", peripheral=" << &GetPeripheral()
<< ", service_id=" << service_id;
// First, find an instance of remote medium, that exposed this peripheral.
auto& remote_adapter =
+24 -1
View File
@@ -33,7 +33,18 @@
namespace nearby {
namespace g3 {
class BleV2nMedium;
// BlePeripheral implementation.
class BleV2Peripheral : public api::ble_v2::BlePeripheral {
public:
explicit BleV2Peripheral(BluetoothAdapter* adapter);
std::string GetAddress() const override;
api::ble_v2::BlePeripheral::UniqueId GetUniqueId() const override;
BluetoothAdapter& GetAdapter() { return adapter_; }
private:
BluetoothAdapter& adapter_;
};
class BleV2Socket : public api::ble_v2::BleSocket {
public:
@@ -205,6 +216,14 @@ class BleV2Medium : public api::ble_v2::BleMedium {
BluetoothAdapter& GetAdapter() { return *adapter_; }
BleV2Peripheral& GetPeripheral() { return peripheral_; }
bool GetRemotePeripheral(absl::string_view mac_address,
GetRemotePeripheralCallback callback) override;
bool GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id,
GetRemotePeripheralCallback callback) override;
private:
// A concrete implementation for GattServer.
class GattServer : public api::ble_v2::GattServer {
@@ -261,6 +280,10 @@ class BleV2Medium : public api::ble_v2::BleMedium {
absl::Mutex mutex_;
BluetoothAdapter* adapter_; // Our device adapter; read-only.
BleV2Peripheral peripheral_{adapter_};
absl::flat_hash_map<api::ble_v2::BlePeripheral::UniqueId,
std::unique_ptr<BleV2Peripheral>>
remote_peripherals_ ABSL_GUARDED_BY(mutex_);
absl::flat_hash_map<std::string, BleV2ServerSocket*> server_sockets_
ABSL_GUARDED_BY(mutex_);
absl::flat_hash_set<std::pair<Uuid, std::uint32_t>>
@@ -38,13 +38,6 @@ void BlePeripheral::SetAdvertisementBytes(
advertisement_bytes_ = advertisement_bytes;
}
BleV2Peripheral::BleV2Peripheral(BluetoothAdapter* adapter)
: adapter_(*adapter) {}
std::string BleV2Peripheral::GetAddress() const {
return adapter_.GetMacAddress();
}
BluetoothDevice::BluetoothDevice(BluetoothAdapter* adapter)
: adapter_(*adapter) {}
@@ -57,7 +50,7 @@ std::string BluetoothDevice::GetMacAddress() const {
BluetoothAdapter::BluetoothAdapter() {
std::string mac_address;
mac_address.resize(6);
int64_t raw_mac_addr = Prng().NextInt64();
std::uint64_t raw_mac_addr = Prng().NextInt64();
mac_address[0] = static_cast<char>(raw_mac_addr >> 40);
mac_address[1] = static_cast<char>(raw_mac_addr >> 32);
mac_address[2] = static_cast<char>(raw_mac_addr >> 24);
@@ -65,6 +58,7 @@ BluetoothAdapter::BluetoothAdapter() {
mac_address[4] = static_cast<char>(raw_mac_addr >> 8);
mac_address[5] = static_cast<char>(raw_mac_addr >> 0);
SetMacAddress(mac_address);
unique_id_ = raw_mac_addr;
}
BluetoothAdapter::~BluetoothAdapter() { SetStatus(Status::kDisabled); }
@@ -15,7 +15,9 @@
#ifndef PLATFORM_IMPL_G3_BLUETOOTH_ADAPTER_H_
#define PLATFORM_IMPL_G3_BLUETOOTH_ADAPTER_H_
#include <memory>
#include <string>
#include <utility>
#include "absl/base/thread_annotations.h"
#include "absl/strings/string_view.h"
@@ -54,21 +56,6 @@ class BlePeripheral : public api::BlePeripheral {
ByteArray advertisement_bytes_;
};
// BlePeripheral implementation.
class BleV2Peripheral : public api::ble_v2::BlePeripheral {
public:
std::string GetAddress() const override;
BluetoothAdapter& GetAdapter() { return adapter_; }
private:
// Only BluetoothAdapter may instantiate BlePeripheral.
friend class BluetoothAdapter;
explicit BleV2Peripheral(BluetoothAdapter* adapter);
BluetoothAdapter& adapter_;
};
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html.
class BluetoothDevice : public api::BluetoothDevice {
public:
@@ -134,7 +121,6 @@ class BluetoothAdapter : public api::BluetoothAdapter {
}
BlePeripheral& GetPeripheral() { return peripheral_; }
BleV2Peripheral& GetPeripheralV2() { return peripheral_v2_; }
void SetBleMedium(api::BleMedium* medium);
api::BleMedium* GetBleMedium() { return ble_medium_; }
@@ -144,11 +130,12 @@ class BluetoothAdapter : public api::BluetoothAdapter {
void SetMacAddress(std::string& mac_address) { mac_address_ = mac_address; }
std::uint64_t GetUniqueId() { return unique_id_; }
private:
mutable absl::Mutex mutex_;
BluetoothDevice device_{this};
BlePeripheral peripheral_{this};
BleV2Peripheral peripheral_v2_{this};
api::BluetoothClassicMedium* bluetooth_classic_medium_ = nullptr;
api::BleMedium* ble_medium_ = nullptr;
api::ble_v2::BleMedium* ble_v2_medium_ = nullptr;
@@ -156,6 +143,7 @@ class BluetoothAdapter : public api::BluetoothAdapter {
ScanMode mode_ ABSL_GUARDED_BY(mutex_) = ScanMode::kNone;
std::string name_ ABSL_GUARDED_BY(mutex_) = "unknown G3 BT device";
bool enabled_ ABSL_GUARDED_BY(mutex_) = true;
std::uint64_t unique_id_;
};
} // namespace g3
@@ -26,6 +26,7 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/cancellation_flag_listener.h"
#include "internal/platform/implementation/ble_v2.h"
@@ -842,5 +843,34 @@ void BleV2Medium::AdvertisementReceivedHandler(
}
}
bool BleV2Medium::GetRemotePeripheral(absl::string_view mac_address,
GetRemotePeripheralCallback callback) {
for (auto& item : peripherals_) {
if (item.second->GetAddress() == mac_address) {
callback(*(item.second));
return true;
}
}
auto peripheral = std::make_unique<BleV2Peripheral>();
peripheral->SetAddress(mac_address);
if (peripheral->GetUniqueId() == 0) {
return false;
}
BleV2Peripheral* ptr = peripheral.get();
peripherals_[peripheral->GetUniqueId()] = std::move(peripheral);
callback(*ptr);
return true;
}
bool BleV2Medium::GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id,
GetRemotePeripheralCallback callback) {
auto it = peripherals_.find(id);
if (it == peripherals_.end()) {
return false;
}
callback(*(it->second));
return true;
}
} // namespace windows
} // namespace nearby
@@ -73,6 +73,12 @@ class BleV2Medium : public api::ble_v2::BleMedium {
BluetoothAdapter& GetAdapter() { return *adapter_; }
bool GetRemotePeripheral(absl::string_view mac_address,
GetRemotePeripheralCallback callback) override;
bool GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id,
GetRemotePeripheralCallback callback) override;
private:
bool StartBleAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
@@ -127,6 +133,10 @@ class BleV2Medium : public api::ble_v2::BleMedium {
::winrt::event_token advertisement_received_token_;
BleGattServer* ble_gatt_server_ = nullptr;
absl::flat_hash_map<BleV2Peripheral::UniqueId,
std::unique_ptr<BleV2Peripheral>>
peripherals_;
};
} // namespace windows
@@ -19,6 +19,7 @@
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/prng.h"
namespace nearby {
namespace windows {
@@ -27,18 +28,23 @@ namespace windows {
// about a particular BLE device to connect to its GATT server.
class BleV2Peripheral : public api::ble_v2::BlePeripheral {
public:
BleV2Peripheral() { unique_id_ = Prng().NextInt64(); }
~BleV2Peripheral() override = default;
// Returns the MAC address of the peripheral. The format is in
// "00:B0:D0:63:C2:26".
std::string GetAddress() const override { return address_; }
api::ble_v2::BlePeripheral::UniqueId GetUniqueId() const override {
return unique_id_;
}
// Sets the MAC address of the peripheral. The address format must be in
// pattern of "00:B0:D0:63:C2:26".
bool SetAddress(absl::string_view address);
private:
std::string address_;
api::ble_v2::BlePeripheral::UniqueId unique_id_;
};
} // namespace windows
+67 -21
View File
@@ -230,6 +230,51 @@ api::BluetoothDevice* MediumEnvironment::FindBluetoothDevice(
return device;
}
api::ble_v2::BleMedium* MediumEnvironment::FindBleV2Medium(
absl::string_view address) {
api::ble_v2::BleMedium* device = nullptr;
CountDownLatch latch(1);
NEARBY_LOGS(INFO) << "FindBleV2Medium " << address;
RunOnMediumEnvironmentThread([&]() {
for (auto& item : ble_v2_mediums_) {
auto* medium = item.first;
auto* peripheral = item.second.ble_peripheral;
if (peripheral != nullptr && peripheral->GetAddress() == address) {
device = medium;
break;
}
}
latch.CountDown();
});
latch.Await();
if (device == nullptr) {
NEARBY_LOGS(INFO) << "FindBleV2Medium, not found: " << address;
}
return device;
}
api::ble_v2::BleMedium* MediumEnvironment::FindBleV2Medium(uint64_t id) {
api::ble_v2::BleMedium* device = nullptr;
CountDownLatch latch(1);
NEARBY_LOGS(INFO) << "FindBleV2Medium " << id;
RunOnMediumEnvironmentThread([&]() {
for (auto& item : ble_v2_mediums_) {
auto* medium = item.first;
auto* peripheral = item.second.ble_peripheral;
if (peripheral != nullptr && peripheral->GetUniqueId() == id) {
device = medium;
break;
}
}
latch.CountDown();
});
latch.Await();
if (device == nullptr) {
NEARBY_LOGS(INFO) << "FindBleV2Medium, not found: " << id;
}
return device;
}
void MediumEnvironment::OnBlePeripheralStateChanged(
BleMediumContext& info, api::BlePeripheral& peripheral,
const std::string& service_id, bool fast_advertisement, bool enabled) {
@@ -525,10 +570,12 @@ void MediumEnvironment::CallBleAcceptedConnectionCallback(
});
}
void MediumEnvironment::RegisterBleV2Medium(api::ble_v2::BleMedium& medium) {
void MediumEnvironment::RegisterBleV2Medium(
api::ble_v2::BleMedium& medium, api::ble_v2::BlePeripheral* peripheral) {
if (!enabled_) return;
RunOnMediumEnvironmentThread([this, &medium]() {
ble_v2_mediums_.insert({&medium, BleV2MediumContext{}});
RunOnMediumEnvironmentThread([this, &medium, peripheral]() {
ble_v2_mediums_.insert(
{&medium, BleV2MediumContext{.ble_peripheral = peripheral}});
NEARBY_LOGS(INFO) << "G3 Registered: medium:" << &medium;
});
}
@@ -675,25 +722,24 @@ bool MediumEnvironment::DiscoverBleV2MediumGattCharacteristics(
if (!enabled_) return false;
int found_characteristic = 0;
CountDownLatch latch(1);
RunOnMediumEnvironmentThread(
[this, &found_characteristic, &latch, &service_uuid,
&characteristic_uuids]() {
for (const auto& item : gatt_advertisement_bytes_) {
if (item.first.service_uuid == service_uuid) {
Uuid char_uuid_key = item.first.uuid;
auto it = std::find_if(characteristic_uuids.rbegin(),
characteristic_uuids.rend(),
[char_uuid_key](const auto& char_uuid) {
return char_uuid == char_uuid_key;
});
if (it != characteristic_uuids.rend()) {
discovered_gatt_advertisement_bytes_[item.first] = item.second;
found_characteristic++;
}
}
RunOnMediumEnvironmentThread([this, &found_characteristic, &latch,
&service_uuid, &characteristic_uuids]() {
for (const auto& item : gatt_advertisement_bytes_) {
if (item.first.service_uuid == service_uuid) {
Uuid char_uuid_key = item.first.uuid;
auto it = std::find_if(characteristic_uuids.rbegin(),
characteristic_uuids.rend(),
[char_uuid_key](const auto& char_uuid) {
return char_uuid == char_uuid_key;
});
if (it != characteristic_uuids.rend()) {
discovered_gatt_advertisement_bytes_[item.first] = item.second;
found_characteristic++;
}
latch.CountDown();
});
}
}
latch.CountDown();
});
latch.Await();
return found_characteristic == characteristic_uuids.size();
}
+5 -1
View File
@@ -229,7 +229,8 @@ class MediumEnvironment {
// expects they should communicate.
// The registered `medium` must refer to a valid instance that outlives this
// object.
void RegisterBleV2Medium(api::ble_v2::BleMedium& medium);
void RegisterBleV2Medium(api::ble_v2::BleMedium& medium,
api::ble_v2::BlePeripheral* peripheral);
// Updates advertising info to indicate the current medium is exposing
// advertising event.
@@ -385,6 +386,9 @@ class MediumEnvironment {
absl::optional<FakeClock*> GetSimulatedClock();
api::ble_v2::BleMedium* FindBleV2Medium(absl::string_view address);
api::ble_v2::BleMedium* FindBleV2Medium(uint64_t id);
// Configures the BluetoothPairingContext for remote BluetoothDevice.
void ConfigBluetoothPairingContext(api::BluetoothDevice* device,
api::PairingParams pairing_params);