diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2023-03-07 17:31:33 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-03-28 03:20:20 +0000 |
commit | fd9c9a6ead6407eb55d337399a375dd70d81be09 (patch) | |
tree | 561945f13974a36b72f8fb1cd61822421145d9c4 | |
parent | 58213e56de9f11e1c0eff30e26ede9c4be9e4cf8 (diff) | |
download | qtconnectivity-fd9c9a6ead6407eb55d337399a375dd70d81be09.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
Change-Id: I0863739a2fb21d04e9a728adc68e3f197f1966e3
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit 4eac30923466e31d16288949979973d1db4e035f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp index 3839b2d6..d34685b1 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() |