summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2023-03-07 17:31:33 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-03-28 03:20:20 +0000
commitfd9c9a6ead6407eb55d337399a375dd70d81be09 (patch)
tree561945f13974a36b72f8fb1cd61822421145d9c4
parent58213e56de9f11e1c0eff30e26ede9c4be9e4cf8 (diff)
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.cpp41
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()