Added thread protection to BLE V2 APIs

PiperOrigin-RevId: 521774807
This commit is contained in:
Guogang Li
2023-04-04 08:49:44 -07:00
committed by Copybara-Service
parent d6f66237b0
commit 3d752bc256
2 changed files with 75 additions and 38 deletions
@@ -105,6 +105,8 @@ BleV2Medium::BleV2Medium(api::BluetoothAdapter& adapter)
// Advertisement packet and populate accordingly.
bool BleV2Medium::StartAdvertising(const BleAdvertisementData& advertising_data,
AdvertiseParameters advertising_parameters) {
absl::MutexLock lock(&mutex_);
std::string service_data_info;
for (const auto& it : advertising_data.service_data) {
service_data_info += "{uuid:" + std::string(it.first) +
@@ -137,6 +139,8 @@ bool BleV2Medium::StartAdvertising(const BleAdvertisementData& advertising_data,
}
bool BleV2Medium::StopAdvertising() {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << __func__ << ": Stop advertising.";
bool result;
if (is_gatt_publisher_started_) {
@@ -163,6 +167,8 @@ std::unique_ptr<BleV2Medium::AdvertisingSession> BleV2Medium::StartAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertise_parameters,
BleV2Medium::AdvertisingCallback callback) {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << __func__
<< ": advertising_data.is_extended_advertisement="
<< advertising_data.is_extended_advertisement
@@ -179,6 +185,8 @@ std::unique_ptr<BleV2Medium::AdvertisingSession> BleV2Medium::StartAdvertising(
bool BleV2Medium::StartScanning(const Uuid& service_uuid,
TxPowerLevel tx_power_level,
ScanCallback callback) {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << __func__
<< ": service UUID: " << std::string(service_uuid)
<< ", TxPowerLevel: " << TxPowerLevelToName(tx_power_level);
@@ -238,6 +246,8 @@ bool BleV2Medium::StartScanning(const Uuid& service_uuid,
std::unique_ptr<BleV2Medium::ScanningSession> BleV2Medium::StartScanning(
const Uuid& service_uuid, TxPowerLevel tx_power_level,
BleV2Medium::ScanningCallback callback) {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << __func__ << ": Start scanning.";
// TODO(hais): add real impl for windows StartAdvertising.
@@ -246,6 +256,8 @@ std::unique_ptr<BleV2Medium::ScanningSession> BleV2Medium::StartScanning(
std::unique_ptr<api::ble_v2::GattServer> BleV2Medium::StartGattServer(
api::ble_v2::ServerGattConnectionCallback callback) {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << __func__ << ": Start GATT server.";
auto gatt_server =
@@ -259,6 +271,8 @@ std::unique_ptr<api::ble_v2::GattServer> BleV2Medium::StartGattServer(
std::unique_ptr<api::ble_v2::GattClient> BleV2Medium::ConnectToGattServer(
api::ble_v2::BlePeripheral& peripheral, TxPowerLevel tx_power_level,
api::ble_v2::ClientGattConnectionCallback callback) {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << "ConnectToGattServer is called, address: "
<< peripheral.GetAddress()
<< ", power:" << TxPowerLevelToName(tx_power_level);
@@ -280,6 +294,8 @@ std::unique_ptr<api::ble_v2::GattClient> BleV2Medium::ConnectToGattServer(
}
bool BleV2Medium::StopScanning() {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << __func__ << ": BLE StopScanning: service_uuid: "
<< std::string(service_uuid_);
try {
@@ -321,6 +337,8 @@ bool BleV2Medium::StopScanning() {
std::unique_ptr<api::ble_v2::BleServerSocket> BleV2Medium::OpenServerSocket(
const std::string& service_id) {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << "OpenServerSocket is called";
auto server_socket = std::make_unique<BleV2ServerSocket>(adapter_);
@@ -337,6 +355,8 @@ std::unique_ptr<api::ble_v2::BleSocket> BleV2Medium::Connect(
const std::string& service_id, TxPowerLevel tx_power_level,
api::ble_v2::BlePeripheral& remote_peripheral,
CancellationFlag* cancellation_flag) {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << __func__ << ": Connect to service_id=" << service_id;
if (cancellation_flag == nullptr) {
@@ -367,6 +387,8 @@ std::unique_ptr<api::ble_v2::BleSocket> BleV2Medium::Connect(
}
bool BleV2Medium::IsExtendedAdvertisementsAvailable() {
absl::MutexLock lock(&mutex_);
return adapter_->IsExtendedAdvertisingSupported();
}
@@ -612,6 +634,8 @@ bool BleV2Medium::StopGattAdvertising() {
void BleV2Medium::PublisherHandler(
BluetoothLEAdvertisementPublisher publisher,
BluetoothLEAdvertisementPublisherStatusChangedEventArgs args) {
absl::MutexLock lock(&mutex_);
// This method is called when publisher's status is changed.
switch (args.Status()) {
case BluetoothLEAdvertisementPublisherStatus::Created:
@@ -703,6 +727,8 @@ void BleV2Medium::PublisherHandler(
void BleV2Medium::WatcherHandler(
BluetoothLEAdvertisementWatcher watcher,
BluetoothLEAdvertisementWatcherStoppedEventArgs args) {
absl::MutexLock lock(&mutex_);
// This method is called when watcher stopped. Args give more detailed
// information on the reason.
switch (args.Error()) {
@@ -765,6 +791,8 @@ void BleV2Medium::WatcherHandler(
void BleV2Medium::AdvertisementReceivedHandler(
BluetoothLEAdvertisementWatcher watcher,
BluetoothLEAdvertisementReceivedEventArgs args) {
absl::MutexLock lock(&mutex_);
// Handle all BLE advertisements and determine whether the BLE Medium
// Advertisement Scan Response packet (containing Copresence UUID 0xFEF3 in
// 0x16 Service Data) has been received in the handler
@@ -807,16 +835,13 @@ void BleV2Medium::AdvertisementReceivedHandler(
uint64_to_mac_address_string(args.BluetoothAddress());
peripheral->SetAddress(mac_address_string);
BleV2Peripheral* peripheral_ptr = nullptr;
{
absl::MutexLock lock(&peripheral_map_mutex_);
if (!peripheral_map_.contains(mac_address_string)) {
peripheral_map_[mac_address_string] = std::move(peripheral);
} else {
peripheral_map_[mac_address_string]->SetAddress(
uint64_to_mac_address_string(args.BluetoothAddress()));
}
peripheral_ptr = peripheral_map_[mac_address_string].get();
if (!peripheral_map_.contains(mac_address_string)) {
peripheral_map_[mac_address_string] = std::move(peripheral);
} else {
peripheral_map_[mac_address_string]->SetAddress(
uint64_to_mac_address_string(args.BluetoothAddress()));
}
peripheral_ptr = peripheral_map_[mac_address_string].get();
NEARBY_LOGS(VERBOSE) << "New BLE peripheral: " << peripheral_ptr
<< ", address: " << peripheral_ptr->GetAddress();
@@ -18,6 +18,7 @@
#include <memory>
#include <string>
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble_v2.h"
@@ -42,65 +43,75 @@ class BleV2Medium : public api::ble_v2::BleMedium {
// Returns true once the Ble advertising has been initiated.
bool StartAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertising_parameters) override;
bool StopAdvertising() override;
api::ble_v2::AdvertiseParameters advertising_parameters) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopAdvertising() override ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<AdvertisingSession> StartAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertise_set_parameters,
AdvertisingCallback callback) override;
AdvertisingCallback callback) override ABSL_LOCKS_EXCLUDED(mutex_);
bool StartScanning(const Uuid& service_uuid,
api::ble_v2::TxPowerLevel tx_power_level,
ScanCallback callback) override;
bool StopScanning() override;
ScanCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopScanning() override ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<ScanningSession> StartScanning(
const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level,
ScanningCallback callback) override;
ScanningCallback callback) override ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<api::ble_v2::GattServer> StartGattServer(
api::ble_v2::ServerGattConnectionCallback callback) override;
api::ble_v2::ServerGattConnectionCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<api::ble_v2::GattClient> ConnectToGattServer(
api::ble_v2::BlePeripheral& peripheral,
api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::ClientGattConnectionCallback callback) override;
api::ble_v2::ClientGattConnectionCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<api::ble_v2::BleServerSocket> OpenServerSocket(
const std::string& service_id) override;
const std::string& service_id) override ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<api::ble_v2::BleSocket> Connect(
const std::string& service_id, api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::BlePeripheral& remote_peripheral,
CancellationFlag* cancellation_flag) override;
bool IsExtendedAdvertisementsAvailable() override;
CancellationFlag* cancellation_flag) override ABSL_LOCKS_EXCLUDED(mutex_);
bool IsExtendedAdvertisementsAvailable() override ABSL_LOCKS_EXCLUDED(mutex_);
BluetoothAdapter& GetAdapter() { return *adapter_; }
private:
bool StartBleAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertising_parameters);
bool StopBleAdvertising();
api::ble_v2::AdvertiseParameters advertising_parameters)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
bool StopBleAdvertising() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
bool StartGattAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertising_parameters);
bool StopGattAdvertising();
api::ble_v2::AdvertiseParameters advertising_parameters)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
bool StopGattAdvertising() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void PublisherHandler(
winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementPublisher publisher,
winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementPublisherStatusChangedEventArgs args);
BluetoothLEAdvertisementPublisherStatusChangedEventArgs args)
ABSL_LOCKS_EXCLUDED(mutex_);
void AdvertisementReceivedHandler(
winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcher watcher,
winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementReceivedEventArgs args);
BluetoothLEAdvertisementReceivedEventArgs args)
ABSL_LOCKS_EXCLUDED(mutex_);
void WatcherHandler(winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcher watcher,
winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcherStoppedEventArgs args);
BluetoothLEAdvertisementWatcherStoppedEventArgs args)
ABSL_LOCKS_EXCLUDED(mutex_);
mutable absl::Mutex mutex_;
BluetoothAdapter* adapter_;
Uuid service_uuid_;
api::ble_v2::TxPowerLevel tx_power_level_;
@@ -108,25 +119,26 @@ class BleV2Medium : public api::ble_v2::BleMedium {
// Map to protect the pointer for BlePeripheral because
// DiscoveredPeripheralCallback only keeps the pointer to the object
absl::Mutex peripheral_map_mutex_;
absl::flat_hash_map<std::string, std::unique_ptr<BleV2Peripheral>>
peripheral_map_ ABSL_GUARDED_BY(peripheral_map_mutex_);
peripheral_map_ ABSL_GUARDED_BY(mutex_);
// WinRT objects
::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementPublisher publisher_ = nullptr;
BluetoothLEAdvertisementPublisher publisher_ ABSL_GUARDED_BY(mutex_) =
nullptr;
::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcher watcher_ = nullptr;
BluetoothLEAdvertisementWatcher watcher_ ABSL_GUARDED_BY(mutex_) =
nullptr;
bool is_ble_publisher_started_ = false;
bool is_gatt_publisher_started_ = false;
bool is_watcher_started_ = false;
bool is_ble_publisher_started_ ABSL_GUARDED_BY(mutex_) = false;
bool is_gatt_publisher_started_ ABSL_GUARDED_BY(mutex_) = false;
bool is_watcher_started_ ABSL_GUARDED_BY(mutex_) = false;
::winrt::event_token publisher_token_;
::winrt::event_token watcher_token_;
::winrt::event_token advertisement_received_token_;
::winrt::event_token publisher_token_ ABSL_GUARDED_BY(mutex_);
::winrt::event_token watcher_token_ ABSL_GUARDED_BY(mutex_);
::winrt::event_token advertisement_received_token_ ABSL_GUARDED_BY(mutex_);
BleGattServer* ble_gatt_server_ = nullptr;
BleGattServer* ble_gatt_server_ ABSL_GUARDED_BY(mutex_) = nullptr;
};
} // namespace windows