Added timeout to discover GATT and BT service

PiperOrigin-RevId: 538352588
This commit is contained in:
Guogang Li
2023-06-07 19:16:07 +00:00
committed by Suet-fei Li
parent 64c715e531
commit ee262121c3
2 changed files with 55 additions and 32 deletions
@@ -41,6 +41,7 @@
#include "winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h"
#include "winrt/Windows.Devices.Bluetooth.h"
#include "winrt/Windows.Foundation.Collections.h"
#include "winrt/Windows.Foundation.h"
#include "winrt/Windows.Storage.Streams.h"
namespace nearby {
@@ -69,6 +70,7 @@ using ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattValueChangedEventArgs;
using ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattWriteOption;
using ::winrt::Windows::Foundation::TimeSpan;
using ::winrt::Windows::Foundation::Collections::IVectorView;
using ::winrt::Windows::Storage::Streams::Buffer;
using ::winrt::Windows::Storage::Streams::DataReader;
@@ -77,6 +79,8 @@ using Property = api::ble_v2::GattCharacteristic::Property;
using Permission = api::ble_v2::GattCharacteristic::Permission;
using WriteType = api::ble_v2::GattClient::WriteType;
constexpr int kGattTimeoutInSeconds = 5;
std::string GattCommunicationStatusToString(GattCommunicationStatus status) {
switch (status) {
case GattCommunicationStatus::Success:
@@ -121,8 +125,26 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
}
// Gets the GATT services on the BLE device.
gatt_devices_services_result_ =
ble_device_.GetGattServicesAsync(BluetoothCacheMode::Uncached).get();
auto get_gatt_services_async =
ble_device_.GetGattServicesAsync(BluetoothCacheMode::Cached);
switch (get_gatt_services_async.wait_for(
TimeSpan(std::chrono::seconds(kGattTimeoutInSeconds)))) {
case winrt::Windows::Foundation::AsyncStatus::Completed:
gatt_devices_services_result_ = get_gatt_services_async.GetResults();
break;
case winrt::Windows::Foundation::AsyncStatus::Started:
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to get GATT services due to timeout.";
get_gatt_services_async.Cancel();
return false;
default:
NEARBY_LOGS(ERROR)
<< __func__
<< ": Failed to get GATT services due to unknown reasons.";
return false;
}
if (gatt_devices_services_result_.Status() !=
GattCommunicationStatus::Success) {
NEARBY_LOGS(ERROR) << __func__
@@ -475,9 +497,9 @@ bool BleGattClient::SetCharacteristicSubscription(
return false;
}
} else if (native_characteristic_map_[characteristic].notification_token) {
gatt_characteristic->ValueChanged(std::exchange(
native_characteristic_map_[characteristic].notification_token, {}));
}
gatt_characteristic->ValueChanged(std::exchange(
native_characteristic_map_[characteristic].notification_token, {}));
}
NEARBY_LOGS(ERROR) << __func__
<< ": Successfully set Characteristic Subscription.";
return true;
@@ -29,9 +29,15 @@
#include "internal/platform/implementation/windows/generated/winrt/base.h"
#include "internal/platform/implementation/windows/utils.h"
#include "internal/platform/logging.h"
#include "winrt/Windows.Foundation.h"
namespace nearby {
namespace windows {
namespace {
constexpr int kBluetoothTimeoutInSeconds = 10;
using ::winrt::Windows::Foundation::TimeSpan;
} // namespace
BluetoothDevice::~BluetoothDevice() {}
@@ -70,35 +76,30 @@ RfcommDeviceService BluetoothDevice::GetRfcommServiceForIdAsync(
NEARBY_LOGS(INFO) << __func__ << ": Get RF services for service id:"
<< winrt::to_string(serviceId.AsString());
// Check cache first
RfcommDeviceServicesResult rfcomm_device_services =
windows_bluetooth_device_
.GetRfcommServicesForIdAsync(serviceId, BluetoothCacheMode::Cached)
.get();
if (rfcomm_device_services != nullptr &&
rfcomm_device_services.Services().Size() > 0) {
NEARBY_LOGS(INFO) << __func__ << ": Get "
<< rfcomm_device_services.Services().Size()
<< " services from cache.";
// found the matched service.
for (auto rfcomm_device_service : rfcomm_device_services.Services()) {
if (rfcomm_device_service.Device() != nullptr &&
winrt::to_string(rfcomm_device_service.Device().DeviceId()) ==
id_) {
NEARBY_LOGS(INFO) << __func__ << ": Found service from cache.";
return rfcomm_device_service;
}
}
RfcommDeviceServicesResult rfcomm_device_services = nullptr;
// Try to get service from un cached mode.
auto rfcomm_device_services_async =
windows_bluetooth_device_.GetRfcommServicesForIdAsync(
serviceId, BluetoothCacheMode::Uncached);
switch (rfcomm_device_services_async.wait_for(
TimeSpan(std::chrono::seconds(kBluetoothTimeoutInSeconds)))) {
case winrt::Windows::Foundation::AsyncStatus::Completed:
rfcomm_device_services = rfcomm_device_services_async.GetResults();
break;
case winrt::Windows::Foundation::AsyncStatus::Started:
NEARBY_LOGS(ERROR)
<< __func__
<< ": Failed to get RfcommDeviceService due to timeout.";
rfcomm_device_services_async.Cancel();
return nullptr;
default:
NEARBY_LOGS(ERROR)
<< __func__
<< ": Failed to get RfcommDeviceService due to unknown reasons.";
return nullptr;
}
NEARBY_LOGS(INFO) << __func__
<< ": Try to found service with no-cache mode.";
// Try to get service from un cached mode.
rfcomm_device_services = windows_bluetooth_device_
.GetRfcommServicesForIdAsync(
serviceId, BluetoothCacheMode::Uncached)
.get();
if (rfcomm_device_services != nullptr &&
rfcomm_device_services.Services().Size() > 0) {
NEARBY_LOGS(INFO) << __func__ << ": Get "