summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2021-12-20 16:19:42 +0100
committerIvan Solovev <ivan.solovev@qt.io>2022-02-01 09:59:09 +0100
commit2441ef9db5df4bbcb3f1506cf89675b3692b5f34 (patch)
tree8887da019af81eb2ea8ac2dbac43072f603788d3
parent8e3dfed66e12551b2b3df01222dd4339436ce751 (diff)
Windows Bluetooth: replace deprecated methods (part 3)
Replace deprecated BluetoothLEDevice::GetGattService() call with its async version during device discovery. The fix is done by moving part of the method to a new callback. As a drive-by: add processing of the result status. Task-number: QTBUG-94001 Change-Id: Ie20db9eed3a57eae41275bb4d3e975eb2ec368b3 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Juha Vuolle <juha.vuolle@insta.fi> (cherry picked from commit 478fd1e51962fbf75f2f768c7498d6b7b7250ba2)
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp102
1 files changed, 84 insertions, 18 deletions
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
index 6a091095..af32e382 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
@@ -151,6 +151,8 @@ private:
HRESULT onRfcommServicesReceived(IAsyncOperation<Rfcomm::RfcommDeviceServicesResult *> *op,
AsyncStatus status, UINT64 address, UINT32 classOfDeviceInt,
const QString &btName);
+ HRESULT onLeServicesReceived(IAsyncOperation<GenericAttributeProfile::GattDeviceServicesResult *> *op,
+ AsyncStatus status, QBluetoothDeviceInfo &info);
void decrementPairedDevicesAndCheckFinished();
@@ -726,6 +728,17 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFoundAsync(IAsy
return onBluetoothLEDeviceFound(device);
}
+static void invokeDeviceFoundWithDebug(QWinRTBluetoothDeviceDiscoveryWorker *worker,
+ const QBluetoothDeviceInfo &info)
+{
+ qCDebug(QT_BT_WINDOWS) << "Discovered BTLE device: " << info.address() << info.name()
+ << "Num UUIDs" << info.serviceUuids().count() << "RSSI:" << info.rssi()
+ << "Num manufacturer data" << info.manufacturerData().count();
+
+ QMetaObject::invokeMethod(worker, "deviceFound", Qt::AutoConnection,
+ Q_ARG(QBluetoothDeviceInfo, info));
+}
+
HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFound(ComPtr<IBluetoothLEDevice> device)
{
if (!device) {
@@ -774,17 +787,78 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFound(ComPtr<IB
EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain pairing status",
QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
return S_OK);
- QList<QBluetoothUuid> uuids;
const LEAdvertisingInfo adInfo = m_foundLEDevicesMap.value(address);
const ManufacturerData manufacturerData = adInfo.manufacturerData;
const qint16 rssi = adInfo.rssi;
+
+ QBluetoothDeviceInfo info(QBluetoothAddress(address), btName, 0);
+ info.setCoreConfigurations(QBluetoothDeviceInfo::LowEnergyCoreConfiguration);
+ info.setRssi(rssi);
+ for (quint16 key : manufacturerData.keys())
+ info.setManufacturerData(key, manufacturerData.value(key));
+ info.setCached(true);
+
// Use the services obtained from the advertisement data if the device is not paired
if (!isPaired) {
- uuids = adInfo.services;
+ info.setServiceUuids(adInfo.services);
+ invokeDeviceFoundWithDebug(this, info);
} else {
- IVectorView <GenericAttributeProfile::GattDeviceService *> *deviceServices;
- hr = device->get_GattServices(&deviceServices);
+ ComPtr<IBluetoothLEDevice3> device3;
+ hr = device.As(&device3);
+ EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Failed to obtain IBluetoothLEDevice3 instance",
+ QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
+ return S_OK);
+
+ ComPtr<IAsyncOperation<GenericAttributeProfile::GattDeviceServicesResult *>> servicesOp;
+ hr = device3->GetGattServicesAsync(&servicesOp);
+ EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Failed to execute async services request",
+ QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
+ return S_OK);
+
+ QPointer<QWinRTBluetoothDeviceDiscoveryWorker> thisPtr(this);
+ hr = servicesOp->put_Completed(
+ Callback<IAsyncOperationCompletedHandler<
+ GenericAttributeProfile::GattDeviceServicesResult *>>([thisPtr, info](
+ IAsyncOperation<GenericAttributeProfile::GattDeviceServicesResult *> *op,
+ AsyncStatus status) mutable {
+ if (thisPtr)
+ thisPtr->onLeServicesReceived(op, status, info);
+ return S_OK;
+ }).Get());
+ EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not add LE services discovery callback",
+ QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
+ return S_OK);
+ }
+
+ return S_OK;
+}
+
+HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onLeServicesReceived(
+ IAsyncOperation<GenericAttributeProfile::GattDeviceServicesResult *> *op,
+ AsyncStatus status, QBluetoothDeviceInfo &info)
+{
+ if (status != AsyncStatus::Completed) {
+ qCWarning(QT_BT_WINDOWS) << "LE service request finished with status"
+ << static_cast<int>(status);
+ return S_OK;
+ }
+
+ ComPtr<GenericAttributeProfile::IGattDeviceServicesResult> servicesResult;
+ HRESULT hr = op->GetResults(&servicesResult);
+ EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not get async operation result for LE services",
+ QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
+ return S_OK);
+
+ GenericAttributeProfile::GattCommunicationStatus commStatus;
+ hr = servicesResult->get_Status(&commStatus);
+ EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain services status",
+ QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
+ return S_OK);
+
+ if (commStatus == GenericAttributeProfile::GattCommunicationStatus_Success) {
+ IVectorView<GenericAttributeProfile::GattDeviceService *> *deviceServices;
+ hr = servicesResult->get_Services(&deviceServices);
EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain gatt service list",
QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
return S_OK);
@@ -793,6 +867,7 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFound(ComPtr<IB
EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain gatt service list size",
QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
return S_OK);
+ QList<QBluetoothUuid> uuids;
for (uint i = 0; i < serviceCount; ++i) {
ComPtr<GenericAttributeProfile::IGattDeviceService> service;
hr = deviceServices->GetAt(i, &service);
@@ -806,22 +881,13 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFound(ComPtr<IB
return S_OK);
uuids.append(QBluetoothUuid(uuid));
}
+ info.setServiceUuids(uuids);
+ } else {
+ qCWarning(QT_BT_WINDOWS) << "Obtaining LE services finished with status"
+ << static_cast<int>(commStatus);
}
+ invokeDeviceFoundWithDebug(this, info);
- qCDebug(QT_BT_WINDOWS) << "Discovered BTLE device: " << QString::number(address) << btName
- << "Num UUIDs" << uuids.count() << "RSSI:" << rssi
- << "Num manufacturer data" << manufacturerData.count();
-
- QBluetoothDeviceInfo info(QBluetoothAddress(address), btName, 0);
- info.setCoreConfigurations(QBluetoothDeviceInfo::LowEnergyCoreConfiguration);
- info.setServiceUuids(uuids);
- info.setRssi(rssi);
- for (quint16 key : manufacturerData.keys())
- info.setManufacturerData(key, manufacturerData.value(key));
- info.setCached(true);
-
- QMetaObject::invokeMethod(this, "deviceFound", Qt::AutoConnection,
- Q_ARG(QBluetoothDeviceInfo, info));
return S_OK;
}