mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
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:
committed by
Copybara-Service
parent
69f4feaf55
commit
0901aec6e2
@@ -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();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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_; }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user