mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-15 07:06:11 -04:00
Internal crash fix
PiperOrigin-RevId: 651635619
This commit is contained in:
committed by
Copybara-Service
parent
ca435ad75f
commit
0f4f02c7f0
@@ -37,6 +37,7 @@
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/flags/nearby_platform_feature_flags.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/uuid.h"
|
||||
@@ -101,28 +102,33 @@ std::string GattCommunicationStatusToString(GattCommunicationStatus status) {
|
||||
|
||||
BleGattClient::BleGattClient(BluetoothLEDevice ble_device)
|
||||
: ble_device_(ble_device) {
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": GATT client is created.";
|
||||
if (ble_device_ == nullptr) {
|
||||
NEARBY_LOGS(WARNING) << __func__ << ": ble_device is null.";
|
||||
} else {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": GATT client is created, address: "
|
||||
<< uint64_to_mac_address_string(
|
||||
ble_device_.BluetoothAddress());
|
||||
}
|
||||
}
|
||||
|
||||
BleGattClient::~BleGattClient() {
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": GATT client is released.";
|
||||
NEARBY_LOGS(INFO) << __func__ << ": GATT client is released.";
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
bool BleGattClient::DiscoverServiceAndCharacteristics(
|
||||
const Uuid& service_uuid, const std::vector<Uuid>& characteristic_uuids) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
if (!NearbyFlags::GetInstance().GetBoolFlag(
|
||||
platform::config_package_nearby::nearby_platform_feature::
|
||||
kEnableBleV2Gatt)) {
|
||||
auto windows_bluetooth_adapter_ = ::winrt::Windows::Devices::Bluetooth::
|
||||
BluetoothAdapter::GetDefaultAsync()
|
||||
.get();
|
||||
if (windows_bluetooth_adapter_.IsExtendedAdvertisingSupported()) {
|
||||
BluetoothAdapter bluetooth_adapter;
|
||||
if (bluetooth_adapter.IsExtendedAdvertisingSupported()) {
|
||||
NEARBY_LOGS(WARNING) << __func__ << ": GATT is disabled.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!windows_bluetooth_adapter_.IsCentralRoleSupported()) {
|
||||
if (!bluetooth_adapter.IsCentralRoleSupported()) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Bluetooth Hardware does not support Central "
|
||||
"Role, which is required to start GATT client.";
|
||||
@@ -192,9 +198,8 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
|
||||
winrt::to_string(winrt::to_hstring(service.Uuid())));
|
||||
});
|
||||
|
||||
NEARBY_LOGS(VERBOSE) << __func__
|
||||
<< ": Found GATT services=" << flat_services
|
||||
<< " from BLE device.";
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Found GATT services=" << flat_services
|
||||
<< " from BLE device.";
|
||||
|
||||
// Needs to check each service to make sure it includes all characteristic
|
||||
// uuids. Services may include duplicate service UUID, but each of them may
|
||||
@@ -269,8 +274,8 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
|
||||
return true;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(VERBOSE) << __func__
|
||||
<< ": Failed to find service and all characteristics.";
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Failed to find service and all characteristics.";
|
||||
} catch (std::exception exception) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Failed to get GATT services. exception: "
|
||||
@@ -288,10 +293,10 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
|
||||
absl::optional<api::ble_v2::GattCharacteristic>
|
||||
BleGattClient::GetCharacteristic(const Uuid& service_uuid,
|
||||
const Uuid& characteristic_uuid) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Stared to get characteristic UUID="
|
||||
<< std::string(characteristic_uuid)
|
||||
<< " in service UUID=" << std::string(service_uuid);
|
||||
absl::MutexLock lock(&mutex_);
|
||||
try {
|
||||
std::optional<GattCharacteristic> gatt_characteristic =
|
||||
GetNativeCharacteristic(service_uuid, characteristic_uuid);
|
||||
@@ -355,6 +360,7 @@ BleGattClient::GetCharacteristic(const Uuid& service_uuid,
|
||||
|
||||
absl::optional<std::string> BleGattClient::ReadCharacteristic(
|
||||
const api::ble_v2::GattCharacteristic& characteristic) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Read characteristic="
|
||||
<< std::string(characteristic.uuid);
|
||||
try {
|
||||
@@ -411,9 +417,9 @@ absl::optional<std::string> BleGattClient::ReadCharacteristic(
|
||||
bool BleGattClient::WriteCharacteristic(
|
||||
const api::ble_v2::GattCharacteristic& characteristic,
|
||||
absl::string_view value, api::ble_v2::GattClient::WriteType write_type) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": write characteristic: "
|
||||
<< std::string(characteristic.uuid);
|
||||
absl::MutexLock lock(&mutex_);
|
||||
try {
|
||||
std::optional<GattCharacteristic> gatt_characteristic =
|
||||
native_characteristic_map_[characteristic].native_characteristic;
|
||||
@@ -466,6 +472,7 @@ bool BleGattClient::SetCharacteristicSubscription(
|
||||
const api::ble_v2::GattCharacteristic& characteristic, bool enable,
|
||||
absl::AnyInvocable<void(absl::string_view value)>
|
||||
on_characteristic_changed_cb) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(VERBOSE) << __func__
|
||||
<< ": Started to set Characteristic Subscription.";
|
||||
GattClientCharacteristicConfigurationDescriptorValue gcccd_value =
|
||||
@@ -484,11 +491,9 @@ bool BleGattClient::SetCharacteristicSubscription(
|
||||
}
|
||||
|
||||
std::optional<GattCharacteristic> gatt_characteristic;
|
||||
{
|
||||
absl::MutexLock lock(&mutex_);
|
||||
gatt_characteristic =
|
||||
native_characteristic_map_[characteristic].native_characteristic;
|
||||
}
|
||||
|
||||
gatt_characteristic =
|
||||
native_characteristic_map_[characteristic].native_characteristic;
|
||||
|
||||
if (!gatt_characteristic.has_value()) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
@@ -505,7 +510,6 @@ bool BleGattClient::SetCharacteristicSubscription(
|
||||
return false;
|
||||
}
|
||||
|
||||
absl::MutexLock lock(&mutex_);
|
||||
// Set value changed handler
|
||||
try {
|
||||
if (enable) {
|
||||
@@ -643,10 +647,10 @@ bool BleGattClient::WriteCharacteristicConfigurationDescriptor(
|
||||
"configuration descriptor";
|
||||
return true;
|
||||
}
|
||||
NEARBY_LOGS(VERBOSE) << __func__
|
||||
<< ": Failed to write client characteristic "
|
||||
"configuration descriptor with error: "
|
||||
<< GattCommunicationStatusToString(status);
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Failed to write client characteristic "
|
||||
"configuration descriptor with error: "
|
||||
<< GattCommunicationStatusToString(status);
|
||||
} catch (std::exception exception) {
|
||||
// This usually happens when a device reports that it support notify, but
|
||||
// it actually doesn't.
|
||||
|
||||
@@ -23,10 +23,15 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/uuid.h"
|
||||
#include "winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h"
|
||||
#include "winrt/Windows.Devices.Bluetooth.h"
|
||||
#include "winrt/base.h"
|
||||
@@ -42,25 +47,29 @@ class BleGattClient : public api::ble_v2::GattClient {
|
||||
|
||||
bool DiscoverServiceAndCharacteristics(
|
||||
const Uuid& service_uuid,
|
||||
const std::vector<Uuid>& characteristic_uuids) override;
|
||||
const std::vector<Uuid>& characteristic_uuids) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
absl::optional<api::ble_v2::GattCharacteristic> GetCharacteristic(
|
||||
const Uuid& service_uuid, const Uuid& characteristic_uuid) override;
|
||||
const Uuid& service_uuid, const Uuid& characteristic_uuid) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
absl::optional<std::string> ReadCharacteristic(
|
||||
const api::ble_v2::GattCharacteristic& characteristic) override;
|
||||
const api::ble_v2::GattCharacteristic& characteristic) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
bool WriteCharacteristic(
|
||||
const api::ble_v2::GattCharacteristic& characteristic,
|
||||
absl::string_view value,
|
||||
api::ble_v2::GattClient::WriteType write_type) override;
|
||||
api::ble_v2::GattClient::WriteType write_type) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
bool SetCharacteristicSubscription(
|
||||
const api::ble_v2::GattCharacteristic& characteristic, bool enable,
|
||||
absl::AnyInvocable<void(absl::string_view value)>
|
||||
on_characteristic_changed_cb) override;
|
||||
on_characteristic_changed_cb) override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
void Disconnect() override;
|
||||
void Disconnect() override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
// Used to save native data related to the GATT characteristic.
|
||||
@@ -75,13 +84,15 @@ class BleGattClient : public api::ble_v2::GattClient {
|
||||
std::optional<::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
|
||||
GattCharacteristic>
|
||||
GetNativeCharacteristic(const Uuid& service_uuid,
|
||||
const Uuid& characteristic_uuid);
|
||||
const Uuid& characteristic_uuid)
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
bool WriteCharacteristicConfigurationDescriptor(
|
||||
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
|
||||
GattCharacteristic& characteristic,
|
||||
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
|
||||
GattClientCharacteristicConfigurationDescriptorValue value);
|
||||
GattClientCharacteristicConfigurationDescriptorValue value)
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
void OnCharacteristicValueChanged(
|
||||
const api::ble_v2::GattCharacteristic& characteristic,
|
||||
@@ -90,9 +101,11 @@ class BleGattClient : public api::ble_v2::GattClient {
|
||||
|
||||
absl::Mutex mutex_;
|
||||
|
||||
::winrt::Windows::Devices::Bluetooth::BluetoothLEDevice ble_device_;
|
||||
::winrt::Windows::Devices::Bluetooth::BluetoothLEDevice ble_device_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
|
||||
GattDeviceServicesResult gatt_devices_services_result_ = nullptr;
|
||||
GattDeviceServicesResult gatt_devices_services_result_
|
||||
ABSL_GUARDED_BY(mutex_) = nullptr;
|
||||
|
||||
absl::flat_hash_map<api::ble_v2::GattCharacteristic, GattCharacteristicData>
|
||||
native_characteristic_map_ ABSL_GUARDED_BY(mutex_);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "internal/platform/implementation/windows/ble_gatt_server.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
@@ -29,11 +30,17 @@
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/implementation/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/uuid.h"
|
||||
#include "winrt/Windows.Foundation.Collections.h"
|
||||
#include "winrt/Windows.Storage.Streams.h"
|
||||
#include "winrt/base.h"
|
||||
@@ -81,6 +88,9 @@ using ::winrt::Windows::Storage::Streams::DataWriter;
|
||||
using Permission = api::ble_v2::GattCharacteristic::Permission;
|
||||
using Property = api::ble_v2::GattCharacteristic::Property;
|
||||
|
||||
constexpr absl::Duration kGattServerTimeout = absl::Milliseconds(500);
|
||||
constexpr int kGattServerCheckIntervalInMills = 50;
|
||||
|
||||
std::string ConvertGattStatusToString(
|
||||
GattServiceProviderAdvertisementStatus status) {
|
||||
switch (status) {
|
||||
@@ -113,9 +123,10 @@ BleGattServer::CreateCharacteristic(
|
||||
const Uuid& service_uuid, const Uuid& characteristic_uuid,
|
||||
api::ble_v2::GattCharacteristic::Permission permission,
|
||||
api::ble_v2::GattCharacteristic::Property property) {
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": create characteristic, service_uuid: "
|
||||
<< std::string(service_uuid) << ", characteristic_uuid: "
|
||||
<< std::string(characteristic_uuid);
|
||||
absl::MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(INFO) << __func__ << ": create characteristic, service_uuid: "
|
||||
<< std::string(service_uuid) << ", characteristic_uuid: "
|
||||
<< std::string(characteristic_uuid);
|
||||
|
||||
if (!service_uuid_.IsEmpty() && service_uuid_ != service_uuid) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
@@ -142,8 +153,9 @@ BleGattServer::CreateCharacteristic(
|
||||
bool BleGattServer::UpdateCharacteristic(
|
||||
const api::ble_v2::GattCharacteristic& characteristic,
|
||||
const nearby::ByteArray& value) {
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": update characteristic: "
|
||||
<< std::string(characteristic.uuid);
|
||||
absl::MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(INFO) << __func__ << ": update characteristic: "
|
||||
<< std::string(characteristic.uuid);
|
||||
|
||||
if (characteristic.service_uuid != service_uuid_) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Cannot found the GATT service.";
|
||||
@@ -184,6 +196,7 @@ bool BleGattServer::UpdateCharacteristic(
|
||||
absl::Status BleGattServer::NotifyCharacteristicChanged(
|
||||
const api::ble_v2::GattCharacteristic& characteristic, bool confirm,
|
||||
const ByteArray& new_value) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
// Currently, the method is not hooked up at platform layer.
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Notify characteristic="
|
||||
<< std::string(characteristic.uuid) << " changed.";
|
||||
@@ -191,6 +204,7 @@ absl::Status BleGattServer::NotifyCharacteristicChanged(
|
||||
}
|
||||
|
||||
void BleGattServer::Stop() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Start to stop GATT server.";
|
||||
try {
|
||||
if (gatt_service_provider_ == nullptr) {
|
||||
@@ -373,6 +387,8 @@ bool BleGattServer::InitializeGattServer() {
|
||||
|
||||
bool BleGattServer::StartAdvertisement(const ByteArray& service_data,
|
||||
bool is_connectable) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
|
||||
try {
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": service_data="
|
||||
<< absl::BytesToHexString(service_data.AsStringView())
|
||||
@@ -385,13 +401,11 @@ bool BleGattServer::StartAdvertisement(const ByteArray& service_data,
|
||||
|
||||
if (!is_gatt_server_inited_ && !InitializeGattServer()) {
|
||||
NEARBY_LOGS(ERROR) << ":Failed to initalize GATT service.";
|
||||
is_advertising_ = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gatt_service_provider_ == nullptr) {
|
||||
NEARBY_LOGS(WARNING) << __func__ << ": no GATT server is running.";
|
||||
is_advertising_ = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -399,7 +413,6 @@ bool BleGattServer::StartAdvertisement(const ByteArray& service_data,
|
||||
GattServiceProviderAdvertisementStatus::Started) {
|
||||
NEARBY_LOGS(WARNING) << __func__
|
||||
<< ": GATT server is already in advertising.";
|
||||
is_advertising_ = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -408,12 +421,9 @@ bool BleGattServer::StartAdvertisement(const ByteArray& service_data,
|
||||
<< __func__
|
||||
<< ": Bluetooth Hardware does not support Peripheral Role, which is "
|
||||
"required to start GATT server.";
|
||||
is_advertising_ = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
is_advertising_ = true;
|
||||
|
||||
// Start the GATT server advertising
|
||||
GattServiceProviderAdvertisingParameters advertisement_parameters;
|
||||
advertisement_parameters.IsConnectable(is_connectable);
|
||||
@@ -427,6 +437,21 @@ bool BleGattServer::StartAdvertisement(const ByteArray& service_data,
|
||||
advertisement_parameters.ServiceData(data_writer.DetachBuffer());
|
||||
|
||||
gatt_service_provider_.StartAdvertising(advertisement_parameters);
|
||||
|
||||
// Wait for the advertising to start.
|
||||
int wait_milliseconds = 0;
|
||||
while (gatt_service_provider_.AdvertisementStatus() !=
|
||||
GattServiceProviderAdvertisementStatus::Started) {
|
||||
absl::SleepFor(absl::Milliseconds(kGattServerCheckIntervalInMills));
|
||||
wait_milliseconds += kGattServerCheckIntervalInMills;
|
||||
if (absl::Milliseconds(wait_milliseconds) > kGattServerTimeout) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__ << ": Failed to start GATT advertising due to timeout.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
is_advertising_ = true;
|
||||
NEARBY_LOGS(INFO) << __func__ << ": GATT server started.";
|
||||
|
||||
return true;
|
||||
@@ -445,6 +470,8 @@ bool BleGattServer::StartAdvertisement(const ByteArray& service_data,
|
||||
}
|
||||
|
||||
bool BleGattServer::StopAdvertisement() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
|
||||
try {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": stop advertisement.";
|
||||
|
||||
@@ -467,6 +494,11 @@ bool BleGattServer::StopAdvertisement() {
|
||||
}
|
||||
|
||||
gatt_service_provider_.StopAdvertising();
|
||||
|
||||
// Don't wait for the advertising to stop, because the advertisement status
|
||||
// cannot back to stopped. Based on the observation, the advertisement
|
||||
// status is stopped after the stop advertising is called.
|
||||
|
||||
is_advertising_ = false;
|
||||
NEARBY_LOGS(INFO) << __func__ << ": GATT server stopped.";
|
||||
return true;
|
||||
@@ -487,9 +519,9 @@ bool BleGattServer::StopAdvertisement() {
|
||||
GattLocalCharacteristic const& gatt_local_characteristic,
|
||||
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
|
||||
GattReadRequestedEventArgs args) {
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Read characteristic. uuid: "
|
||||
<< winrt::to_string(winrt::to_hstring(
|
||||
gatt_local_characteristic.Uuid()));
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Read characteristic. uuid: "
|
||||
<< winrt::to_string(
|
||||
winrt::to_hstring(gatt_local_characteristic.Uuid()));
|
||||
|
||||
auto deferral = args.GetDeferral();
|
||||
|
||||
@@ -542,7 +574,7 @@ bool BleGattServer::StopAdvertisement() {
|
||||
GattLocalCharacteristic const& gatt_local_characteristic,
|
||||
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
|
||||
GattWriteRequestedEventArgs args) {
|
||||
// In Nearby Connctions, don't support write charaterisctics right now.
|
||||
// In Nearby Connections, don't support write characteristics right now.
|
||||
throw std::logic_error("Not implemented.");
|
||||
}
|
||||
|
||||
@@ -550,10 +582,10 @@ void BleGattServer::Characteristic_SubscribedClientsChanged(
|
||||
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
|
||||
GattLocalCharacteristic const& gatt_local_characteristic,
|
||||
::winrt::Windows::Foundation::IInspectable const& args) {
|
||||
NEARBY_LOGS(VERBOSE) << __func__
|
||||
<< ": Subscribed clients changed. characteristic="
|
||||
<< ::winrt::to_string(::winrt::to_hstring(
|
||||
gatt_local_characteristic.Uuid()));
|
||||
NEARBY_LOGS(INFO) << __func__
|
||||
<< ": Subscribed clients changed. characteristic="
|
||||
<< ::winrt::to_string(::winrt::to_hstring(
|
||||
gatt_local_characteristic.Uuid()));
|
||||
|
||||
try {
|
||||
std::vector<api::ble_v2::GattCharacteristic>
|
||||
@@ -637,8 +669,9 @@ void BleGattServer::ServiceProvider_AdvertisementStatusChanged(
|
||||
GattServiceProvider const& sender,
|
||||
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
|
||||
GattServiceProviderAdvertisementStatusChangedEventArgs const& args) {
|
||||
NEARBY_LOGS(VERBOSE) << __func__ << ": Advertisement status changed. status="
|
||||
<< ConvertGattStatusToString(args.Status());
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Advertisement status changed. status="
|
||||
<< ConvertGattStatusToString(args.Status())
|
||||
<< ", error=" << static_cast<int>(args.Error());
|
||||
}
|
||||
|
||||
void BleGattServer::NotifyValueChanged(
|
||||
|
||||
@@ -17,13 +17,19 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <optional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/implementation/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/windows/ble_v2_peripheral.h"
|
||||
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
|
||||
#include "internal/platform/uuid.h"
|
||||
@@ -43,20 +49,22 @@ class BleGattServer : public api::ble_v2::GattServer {
|
||||
absl::optional<api::ble_v2::GattCharacteristic> CreateCharacteristic(
|
||||
const Uuid& service_uuid, const Uuid& characteristic_uuid,
|
||||
api::ble_v2::GattCharacteristic::Permission permission,
|
||||
api::ble_v2::GattCharacteristic::Property property) override;
|
||||
api::ble_v2::GattCharacteristic::Property property) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
bool UpdateCharacteristic(
|
||||
const api::ble_v2::GattCharacteristic& characteristic,
|
||||
const nearby::ByteArray& value) override;
|
||||
const nearby::ByteArray& value) override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
absl::Status NotifyCharacteristicChanged(
|
||||
const api::ble_v2::GattCharacteristic& characteristic, bool confirm,
|
||||
const ByteArray& new_value) override;
|
||||
const ByteArray& new_value) override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
void Stop() override;
|
||||
void Stop() override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
bool StartAdvertisement(const ByteArray& service_data, bool is_connectable);
|
||||
bool StopAdvertisement();
|
||||
bool StartAdvertisement(const ByteArray& service_data, bool is_connectable)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
bool StopAdvertisement() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
api::ble_v2::BlePeripheral& GetBlePeripheral() override {
|
||||
return peripheral_;
|
||||
@@ -109,6 +117,8 @@ class BleGattServer : public api::ble_v2::GattServer {
|
||||
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
|
||||
GattServiceProviderAdvertisementStatusChangedEventArgs const& args);
|
||||
|
||||
absl::Mutex mutex_;
|
||||
|
||||
BluetoothAdapter* adapter_ = nullptr;
|
||||
BleV2Peripheral peripheral_;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
@@ -29,18 +30,21 @@
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/bluetooth_adapter.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/flags/nearby_platform_feature_flags.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/implementation/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/windows/ble_gatt_client.h"
|
||||
#include "internal/platform/implementation/windows/ble_gatt_server.h"
|
||||
#include "internal/platform/implementation/windows/ble_v2_peripheral.h"
|
||||
#include "internal/platform/implementation/windows/ble_v2_server_socket.h"
|
||||
#include "internal/platform/implementation/windows/ble_v2_socket.h"
|
||||
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/prng.h"
|
||||
@@ -116,6 +120,9 @@ static constexpr uint64_t kGenerateSessionIdRetryLimit = 3;
|
||||
// Indicating failed to generate unused session id.
|
||||
static constexpr uint64_t kFailedGenerateSessionId = 0;
|
||||
|
||||
constexpr absl::Duration kMediumTimeout = absl::Milliseconds(500);
|
||||
constexpr int kMediumCheckIntervalInMills = 50;
|
||||
|
||||
// Remove lost/unused peripherals after a timeout.
|
||||
constexpr absl::Duration kPeripheralExpiryTime = absl::Minutes(15);
|
||||
// Prevent too frequent cleanup tasks.
|
||||
@@ -128,6 +135,7 @@ 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) +
|
||||
@@ -160,6 +168,7 @@ 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_) {
|
||||
@@ -222,6 +231,7 @@ 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);
|
||||
@@ -270,6 +280,22 @@ bool BleV2Medium::StartScanning(const Uuid& service_uuid,
|
||||
watcher_.AdvertisementFilter(advertisement_filter);
|
||||
watcher_.Start();
|
||||
|
||||
// Wait for the watcher to start.
|
||||
int wait_milliseconds = 0;
|
||||
while (watcher_.Status() !=
|
||||
BluetoothLEAdvertisementWatcherStatus::Started) {
|
||||
absl::SleepFor(absl::Milliseconds(kMediumCheckIntervalInMills));
|
||||
wait_milliseconds += kMediumCheckIntervalInMills;
|
||||
if (absl::Milliseconds(wait_milliseconds) > kMediumTimeout) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Failed to start BLE scan due to timeout..";
|
||||
watcher_.Stopped(watcher_token_);
|
||||
watcher_.Received(advertisement_received_token_);
|
||||
watcher_ = nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
is_watcher_started_ = true;
|
||||
|
||||
NEARBY_LOGS(INFO) << __func__ << ": BLE scanning started.";
|
||||
@@ -414,6 +440,7 @@ 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.";
|
||||
|
||||
if (!NearbyFlags::GetInstance().GetBoolFlag(
|
||||
@@ -442,6 +469,7 @@ 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);
|
||||
@@ -482,6 +510,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 {
|
||||
@@ -498,9 +528,26 @@ bool BleV2Medium::StopScanning() {
|
||||
|
||||
watcher_.Stop();
|
||||
|
||||
// Don't need to wait for the status becomes to `Stopped`. If application
|
||||
// starts to scanning immediately, the scanning still needs to wait the
|
||||
// stopping to finish.
|
||||
// Wait for the watcher to stop.
|
||||
int wait_milliseconds = 0;
|
||||
while (watcher_.Status() !=
|
||||
BluetoothLEAdvertisementWatcherStatus::Stopped) {
|
||||
absl::SleepFor(absl::Milliseconds(kMediumCheckIntervalInMills));
|
||||
wait_milliseconds += kMediumCheckIntervalInMills;
|
||||
if (absl::Milliseconds(wait_milliseconds) > kMediumTimeout) {
|
||||
NEARBY_LOGS(ERROR) << __func__
|
||||
<< ": Failed to stop BLE scan due to timeout.";
|
||||
watcher_.Stopped(watcher_token_);
|
||||
watcher_.Received(advertisement_received_token_);
|
||||
watcher_ = nullptr;
|
||||
is_watcher_started_ = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
watcher_.Stopped(watcher_token_);
|
||||
watcher_.Received(advertisement_received_token_);
|
||||
watcher_ = nullptr;
|
||||
is_watcher_started_ = false;
|
||||
|
||||
NEARBY_LOGS(ERROR)
|
||||
@@ -662,6 +709,22 @@ bool BleV2Medium::StartBleAdvertising(
|
||||
|
||||
publisher_.Start();
|
||||
|
||||
// Wait for the publisher to start.
|
||||
int wait_milliseconds = 0;
|
||||
while (publisher_.Status() !=
|
||||
BluetoothLEAdvertisementPublisherStatus::Started) {
|
||||
absl::SleepFor(absl::Milliseconds(kMediumCheckIntervalInMills));
|
||||
wait_milliseconds += kMediumCheckIntervalInMills;
|
||||
if (absl::Milliseconds(wait_milliseconds) > kMediumTimeout) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__ << ": BLE advertising failed to start due to timeout.";
|
||||
publisher_.StatusChanged(publisher_token_);
|
||||
publisher_ = nullptr;
|
||||
is_ble_publisher_started_ = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
is_ble_publisher_started_ = true;
|
||||
NEARBY_LOGS(INFO) << "BLE advertising started.";
|
||||
return true;
|
||||
@@ -697,15 +760,34 @@ bool BleV2Medium::StopBleAdvertising() {
|
||||
}
|
||||
|
||||
// publisher_ may be null when status changed during advertising.
|
||||
if (publisher_ != nullptr &&
|
||||
publisher_.Status() ==
|
||||
if (publisher_ == nullptr ||
|
||||
publisher_.Status() !=
|
||||
BluetoothLEAdvertisementPublisherStatus::Started) {
|
||||
publisher_.Stop();
|
||||
NEARBY_LOGS(WARNING) << "No started publisher is running.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't need to wait for the status becomes to `Stopped`. If application
|
||||
// starts to scanning immediately, the scanning still needs to wait the
|
||||
// stopping to finish.
|
||||
publisher_.Stop();
|
||||
|
||||
// Wait for the publisher to stop.
|
||||
int wait_milliseconds = 0;
|
||||
while (publisher_.Status() !=
|
||||
BluetoothLEAdvertisementPublisherStatus::Stopped) {
|
||||
absl::SleepFor(absl::Milliseconds(kMediumCheckIntervalInMills));
|
||||
wait_milliseconds += kMediumCheckIntervalInMills;
|
||||
if (absl::Milliseconds(wait_milliseconds) > kMediumTimeout) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__ << ": BLE advertising failed to stop due to timeout.";
|
||||
publisher_.StatusChanged(publisher_token_);
|
||||
publisher_ = nullptr;
|
||||
is_ble_publisher_started_ = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset publisher.
|
||||
publisher_.StatusChanged(publisher_token_);
|
||||
publisher_ = nullptr;
|
||||
is_ble_publisher_started_ = false;
|
||||
|
||||
return true;
|
||||
@@ -912,14 +994,6 @@ void BleV2Medium::PublisherHandler(
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// The publisher is stopped. Clean up the running publisher
|
||||
if (publisher_ != nullptr) {
|
||||
NEARBY_LOGS(ERROR) << "Nearby BLE Medium cleaned the publisher.";
|
||||
publisher_.StatusChanged(publisher_token_);
|
||||
publisher_ = nullptr;
|
||||
is_ble_publisher_started_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void BleV2Medium::WatcherHandler(
|
||||
@@ -972,16 +1046,6 @@ void BleV2Medium::WatcherHandler(
|
||||
<< "Nearby BLE Medium stoped to scan due to unknown errors.";
|
||||
break;
|
||||
}
|
||||
|
||||
// No matter the reason, should clean up the watcher if it is not empty.
|
||||
// The BLE V1 interface doesn't have API to return the error to upper layer.
|
||||
if (watcher_ != nullptr) {
|
||||
NEARBY_LOGS(ERROR) << "Nearby BLE Medium cleaned the watcher.";
|
||||
watcher_.Stopped(watcher_token_);
|
||||
watcher_.Received(advertisement_received_token_);
|
||||
watcher_ = nullptr;
|
||||
is_watcher_started_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void BleV2Medium::AdvertisementReceivedHandler(
|
||||
|
||||
@@ -15,18 +15,24 @@
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_V2_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_V2_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/implementation/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/windows/ble_gatt_server.h"
|
||||
#include "internal/platform/implementation/windows/ble_v2_peripheral.h"
|
||||
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/windows/bluetooth_classic.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
#include "internal/platform/uuid.h"
|
||||
#include "winrt/Windows.Devices.Bluetooth.Advertisement.h"
|
||||
|
||||
@@ -42,8 +48,9 @@ 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,
|
||||
@@ -52,41 +59,48 @@ class BleV2Medium : public api::ble_v2::BleMedium {
|
||||
|
||||
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;
|
||||
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;
|
||||
CancellationFlag* cancellation_flag) override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
bool IsExtendedAdvertisementsAvailable() override;
|
||||
|
||||
bool GetRemotePeripheral(const std::string& mac_address,
|
||||
GetRemotePeripheralCallback callback) override;
|
||||
GetRemotePeripheralCallback callback) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
bool GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id,
|
||||
GetRemotePeripheralCallback callback) override;
|
||||
GetRemotePeripheralCallback callback) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
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::
|
||||
@@ -120,6 +134,8 @@ class BleV2Medium : public api::ble_v2::BleMedium {
|
||||
void RemoveExpiredPeripherals()
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(peripheral_map_mutex_);
|
||||
|
||||
absl::Mutex mutex_;
|
||||
|
||||
BluetoothAdapter* adapter_;
|
||||
Uuid service_uuid_;
|
||||
api::ble_v2::TxPowerLevel tx_power_level_;
|
||||
|
||||
Reference in New Issue
Block a user