From 3d752bc2569a9cf9eac811d1b5b3816b46e8fc10 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Tue, 4 Apr 2023 08:47:48 -0700 Subject: [PATCH] Added thread protection to BLE V2 APIs PiperOrigin-RevId: 521774807 --- .../platform/implementation/windows/ble_v2.cc | 43 +++++++++--- .../platform/implementation/windows/ble_v2.h | 70 +++++++++++-------- 2 files changed, 75 insertions(+), 38 deletions(-) diff --git a/internal/platform/implementation/windows/ble_v2.cc b/internal/platform/implementation/windows/ble_v2.cc index 4cba7592..ed3dfc9a 100644 --- a/internal/platform/implementation/windows/ble_v2.cc +++ b/internal/platform/implementation/windows/ble_v2.cc @@ -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::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::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::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::StartScanning( std::unique_ptr 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 BleV2Medium::StartGattServer( std::unique_ptr 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 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 BleV2Medium::OpenServerSocket( const std::string& service_id) { + absl::MutexLock lock(&mutex_); + NEARBY_LOGS(INFO) << "OpenServerSocket is called"; auto server_socket = std::make_unique(adapter_); @@ -337,6 +355,8 @@ std::unique_ptr 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 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(); diff --git a/internal/platform/implementation/windows/ble_v2.h b/internal/platform/implementation/windows/ble_v2.h index ea70f29e..a12e981a 100644 --- a/internal/platform/implementation/windows/ble_v2.h +++ b/internal/platform/implementation/windows/ble_v2.h @@ -18,6 +18,7 @@ #include #include +#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 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 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 StartGattServer( - api::ble_v2::ServerGattConnectionCallback callback) override; + api::ble_v2::ServerGattConnectionCallback callback) override + ABSL_LOCKS_EXCLUDED(mutex_); std::unique_ptr 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 OpenServerSocket( - const std::string& service_id) override; + const std::string& service_id) override ABSL_LOCKS_EXCLUDED(mutex_); std::unique_ptr 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> - 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