summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2023-03-07 17:31:33 +0100
committerIvan Solovev <ivan.solovev@qt.io>2023-03-27 15:27:45 +0100
commit4eac30923466e31d16288949979973d1db4e035f (patch)
treea5156e4d52f0c291a35164e746cf4987a5633385
parentefc852b0ea327831fcceaa925be8e6721ce93297 (diff)
downloadqtconnectivity-4eac30923466e31d16288949979973d1db4e035f.tar.gz
Windows: optimize BTLE device discovery
Previously we were doing full service discovery every time when the BluetoothLEAdvertisementWatcher reports a new advertisement. This results in a very high CPU usage during BTLE device discovery on some configurations. In practice such approach might not be needed, because most BTLE devices repeatedly advertise the same data. With this patch we do a detailed service discovery only when a new device is added, or when the list of advertised services has changed. Note that we still need to handle all the incoming advertisements, because we want to report changes in other parameters, such as RSSI. Fixes: QTBUG-111116 Pick-to: 6.5 6.5.0 6.2 Change-Id: I0863739a2fb21d04e9a728adc68e3f197f1966e3 Reviewed-by: Juha Vuolle <juha.vuolle@qt.io> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp41
1 files changed, 22 insertions, 19 deletions
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
index e0d3111a..48929d35 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
@@ -406,6 +406,7 @@ void QWinRTBluetoothDeviceDiscoveryWorker::onAdvertisementDataReceived(
const ServiceData &serviceData, const QList<QBluetoothUuid> &uuids)
{
// Merge newly found services with list of currently found ones
+ bool needDiscoverServices = false;
{
QMutexLocker locker(&m_leDevicesMutex);
if (m_foundLEDevicesMap.contains(address)) {
@@ -426,14 +427,13 @@ void QWinRTBluetoothDeviceDiscoveryWorker::onAdvertisementDataReceived(
if (adInfo.serviceData != m_foundLEDevicesMap[address].serviceData)
changedFields.setFlag((QBluetoothDeviceInfo::Field::ServiceData));
}
- bool newServiceAdded = false;
for (const QBluetoothUuid &uuid : std::as_const(uuids)) {
if (!foundServices.contains(uuid)) {
foundServices.append(uuid);
- newServiceAdded = true;
+ needDiscoverServices = true;
}
}
- if (!newServiceAdded) {
+ if (!needDiscoverServices) {
if (!changedFields.testFlag(QBluetoothDeviceInfo::Field::None)) {
QMetaObject::invokeMethod(this, "deviceDataChanged", Qt::AutoConnection,
Q_ARG(QBluetoothAddress, QBluetoothAddress(address)),
@@ -445,6 +445,7 @@ void QWinRTBluetoothDeviceDiscoveryWorker::onAdvertisementDataReceived(
}
m_foundLEDevicesMap[address].services = foundServices;
} else {
+ needDiscoverServices = true;
LEAdvertisingInfo info;
info.services = std::move(uuids);
info.manufacturerData = std::move(manufacturerData);
@@ -453,24 +454,26 @@ void QWinRTBluetoothDeviceDiscoveryWorker::onAdvertisementDataReceived(
m_foundLEDevicesMap.insert(address, info);
}
}
- ++m_pendingDevices; // as if we discovered a new LE device
- auto thisPtr = shared_from_this();
- auto asyncOp = BluetoothLEDevice::FromBluetoothAddressAsync(address);
- asyncOp.Completed([thisPtr, address](auto &&op, AsyncStatus status) {
- if (thisPtr) {
- if (status == AsyncStatus::Completed) {
- BluetoothLEDevice device = op.GetResults();
- if (device) {
- thisPtr->handleLowEnergyDevice(device);
- return;
+ if (needDiscoverServices) {
+ ++m_pendingDevices; // as if we discovered a new LE device
+ auto thisPtr = shared_from_this();
+ auto asyncOp = BluetoothLEDevice::FromBluetoothAddressAsync(address);
+ asyncOp.Completed([thisPtr, address](auto &&op, AsyncStatus status) {
+ if (thisPtr) {
+ if (status == AsyncStatus::Completed) {
+ BluetoothLEDevice device = op.GetResults();
+ if (device) {
+ thisPtr->handleLowEnergyDevice(device);
+ return;
+ }
}
+ // status != Completed or failed to extract result
+ qCDebug(QT_BT_WINDOWS) << "Failed to get LE device from address"
+ << QBluetoothAddress(address);
+ invokeDecrementPendingDevicesCountAndCheckFinished(thisPtr);
}
- // status != Completed or failed to extract result
- qCDebug(QT_BT_WINDOWS) << "Failed to get LE device from address"
- << QBluetoothAddress(address);
- invokeDecrementPendingDevicesCountAndCheckFinished(thisPtr);
- }
- });
+ });
+ }
}
void QWinRTBluetoothDeviceDiscoveryWorker::stopAdvertisementWatcher()