diff options
author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2024-01-22 22:33:45 +0200 |
---|---|---|
committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2024-02-20 15:20:01 +0000 |
commit | 9c1fe537717255453f86822c959f44360cfa9a27 (patch) | |
tree | bbd27b74963847a409ef476dff106327d37d8b48 | |
parent | 32748a3b04f67af77573eefdc36586d4f7f49e98 (diff) | |
parent | ddfb06fb8a2df4d9bf13eabb52edd3ad858b8c14 (diff) |
Merge remote-tracking branch 'origin/tqtc/lts-6.2.8' into tqtc/lts-6.2-opensource
Conflicts solved in a file:
dependencies.yaml
Change-Id: Id3187c943acccb6d77a377f205a7822e2d0a54d4
-rw-r--r-- | .cmake.conf | 2 | ||||
-rw-r--r-- | .qmake.conf | 2 | ||||
-rw-r--r-- | cmake/FindBlueZ.cmake | 6 | ||||
-rw-r--r-- | dependencies.yaml | 4 | ||||
-rw-r--r-- | src/bluetooth/configure.cmake | 2 | ||||
-rw-r--r-- | src/bluetooth/doc/src/bluetooth-le-overview.qdoc | 8 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicewatcher_winrt_p.h | 1 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothutils_winrt_p.h | 1 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt.cpp | 64 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt_p.h | 1 | ||||
-rw-r--r-- | src/tools/sdpscanner/main.cpp | 15 |
11 files changed, 73 insertions, 33 deletions
diff --git a/.cmake.conf b/.cmake.conf index 07d90b8a..e62fae5e 100644 --- a/.cmake.conf +++ b/.cmake.conf @@ -1,2 +1,2 @@ -set(QT_REPO_MODULE_VERSION "6.2.7") +set(QT_REPO_MODULE_VERSION "6.2.8") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "") diff --git a/.qmake.conf b/.qmake.conf index 24e796fe..a0cf48b9 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -2,4 +2,4 @@ load(qt_build_config) DEFINES += QT_NO_FOREACH QT_NO_JAVA_STYLE_ITERATORS -MODULE_VERSION = 6.2.7 +MODULE_VERSION = 6.2.8 diff --git a/cmake/FindBlueZ.cmake b/cmake/FindBlueZ.cmake index aa192f10..6a0cbbe0 100644 --- a/cmake/FindBlueZ.cmake +++ b/cmake/FindBlueZ.cmake @@ -1,7 +1,9 @@ +set(BlueZ_FOUND 0) + find_package(PkgConfig QUIET) pkg_check_modules(BLUEZ bluez IMPORTED_TARGET) -if (NOT TARGET PkgConfig::BLUEZ) - set(BLUEZ_FOUND 0) +if(TARGET PkgConfig::BLUEZ) + set(BlueZ_FOUND 1) endif() diff --git a/dependencies.yaml b/dependencies.yaml index b12c2dd5..734f5d12 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1,7 +1,7 @@ dependencies: ../tqtc-qtbase: - ref: 694575a59b5370afc494fbf700eee8db1d1ec091 + ref: 67934c103800bae50c2ec1977758d40fa8e4e507 required: true ../tqtc-qtdeclarative: - ref: 02277e3753613d9e19bbb36367c7d2b1d13d7545 + ref: 302ab20d46280e11042f3896460c55d8b8146e41 required: false diff --git a/src/bluetooth/configure.cmake b/src/bluetooth/configure.cmake index 2090a255..f9a2b3c3 100644 --- a/src/bluetooth/configure.cmake +++ b/src/bluetooth/configure.cmake @@ -6,7 +6,7 @@ #### Libraries -qt_find_package(BlueZ PROVIDED_TARGETS PkgConfig::BlueZ) +qt_find_package(BlueZ PROVIDED_TARGETS PkgConfig::BLUEZ) #### Tests diff --git a/src/bluetooth/doc/src/bluetooth-le-overview.qdoc b/src/bluetooth/doc/src/bluetooth-le-overview.qdoc index 7fc7d7c6..e4e66db4 100644 --- a/src/bluetooth/doc/src/bluetooth-le-overview.qdoc +++ b/src/bluetooth/doc/src/bluetooth-le-overview.qdoc @@ -34,11 +34,9 @@ Low Energy devices. \tableofcontents - The Qt Bluetooth Low Energy API for the central role was introduced by Qt 5.4. - Since Qt 5.5 that part of the API is final and a compatibility guarantee is given for - future releases. - Since Qt 5.7, additional API supporting the peripheral role was added as a Technology Preview, - with the backend implemented for Linux/BlueZ, iOS and macOS. + The Qt Bluetooth Low Energy API supports the peripheral/server and central/client roles. + It is supported on all major Qt platforms. The only exception is the missing peripheral role + support on Windows. \section1 What Is Bluetooth Low Energy diff --git a/src/bluetooth/qbluetoothdevicewatcher_winrt_p.h b/src/bluetooth/qbluetoothdevicewatcher_winrt_p.h index b3dc4ec9..8f1bf423 100644 --- a/src/bluetooth/qbluetoothdevicewatcher_winrt_p.h +++ b/src/bluetooth/qbluetoothdevicewatcher_winrt_p.h @@ -57,6 +57,7 @@ #include <private/qbluetoothutils_winrt_p.h> #include <winrt/base.h> +#include <QtCore/private/qfactorycacheregistration_p.h> #include <winrt/Windows.Devices.Enumeration.h> QT_BEGIN_NAMESPACE diff --git a/src/bluetooth/qbluetoothutils_winrt_p.h b/src/bluetooth/qbluetoothutils_winrt_p.h index 96cfd8d6..42ec3a4f 100644 --- a/src/bluetooth/qbluetoothutils_winrt_p.h +++ b/src/bluetooth/qbluetoothutils_winrt_p.h @@ -54,6 +54,7 @@ // Workaround for Windows SDK bug. // See https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/issues/47 #include <winrt/base.h> +#include <QtCore/private/qfactorycacheregistration_p.h> namespace winrt::impl { template <typename Async> diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp index d82732ea..376ee58e 100644 --- a/src/bluetooth/qlowenergycontroller_winrt.cpp +++ b/src/bluetooth/qlowenergycontroller_winrt.cpp @@ -138,13 +138,14 @@ static QByteArray byteArrayFromGattResult(const ComPtr<IGattReadResult> &gattRes return byteArrayFromBuffer(buffer, isWCharString); } -static void closeDeviceService(ComPtr<IGattDeviceService> service) +template <typename T> +static void closeDeviceService(ComPtr<T> service) { ComPtr<IClosable> closableService; HRESULT hr = service.As(&closableService); - RETURN_IF_FAILED("Could not cast service to closable", return); + RETURN_IF_FAILED("Could not cast type to closable", return); hr = closableService->Close(); - RETURN_IF_FAILED("Service Close() failed", return); + RETURN_IF_FAILED("Close() call failed", return); } class QWinRTLowEnergyServiceHandler : public QObject @@ -161,12 +162,16 @@ public: ~QWinRTLowEnergyServiceHandler() { + if (mAbortRequested) + closeDeviceService(mDeviceService); qCDebug(QT_BT_WINDOWS) << __FUNCTION__; } public slots: void obtainCharList() { + auto exitCondition = [this]() { return mAbortRequested; }; + mIndicateChars.clear(); qCDebug(QT_BT_WINDOWS) << __FUNCTION__; ComPtr<IAsyncOperation<GattCharacteristicsResult *>> characteristicsOp; @@ -174,7 +179,8 @@ public slots: HRESULT hr = mDeviceService->GetCharacteristicsAsync(&characteristicsOp); EMIT_WORKER_ERROR_AND_QUIT_IF_FAILED(hr); hr = QWinRTFunctions::await(characteristicsOp, characteristicsResult.GetAddressOf(), - QWinRTFunctions::ProcessMainThreadEvents, 5000); + QWinRTFunctions::ProcessMainThreadEvents, 5000, + exitCondition); EMIT_WORKER_ERROR_AND_QUIT_IF_FAILED(hr); GattCommunicationStatus status; hr = characteristicsResult->get_Status(&status); @@ -192,7 +198,7 @@ public slots: EMIT_WORKER_ERROR_AND_QUIT_IF_FAILED(hr); mCharacteristicsCountToBeDiscovered = characteristicsCount; - for (uint i = 0; i < characteristicsCount; ++i) { + for (uint i = 0; !mAbortRequested && (i < characteristicsCount); ++i) { ComPtr<IGattCharacteristic> characteristic; hr = characteristics->GetAt(i, &characteristic); if (FAILED(hr)) { @@ -218,7 +224,9 @@ public slots: DEC_CHAR_COUNT_AND_CONTINUE_IF_FAILED(hr, "Could not obtain list of descriptors") ComPtr<IGattDescriptorsResult> descResult; - hr = QWinRTFunctions::await(descAsyncOp, descResult.GetAddressOf()); + hr = QWinRTFunctions::await(descAsyncOp, descResult.GetAddressOf(), + QWinRTFunctions::ProcessMainThreadEvents, 5000, + exitCondition); DEC_CHAR_COUNT_AND_CONTINUE_IF_FAILED(hr, "Could not obtain descriptor read result") quint16 handle; @@ -247,7 +255,9 @@ public slots: &readOp); DEC_CHAR_COUNT_AND_CONTINUE_IF_FAILED(hr, "Could not read characteristic") ComPtr<IGattReadResult> readResult; - hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf()); + hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf(), + QWinRTFunctions::ProcessMainThreadEvents, 5000, + exitCondition); DEC_CHAR_COUNT_AND_CONTINUE_IF_FAILED(hr, "Could not obtain characteristic read result") if (!readResult) @@ -273,7 +283,7 @@ public slots: uint descriptorCount; hr = descriptors->get_Size(&descriptorCount); DEC_CHAR_COUNT_AND_CONTINUE_IF_FAILED(hr, "Could not obtain list of descriptors' size") - for (uint j = 0; j < descriptorCount; ++j) { + for (uint j = 0; !mAbortRequested && (j < descriptorCount); ++j) { QLowEnergyServicePrivate::DescData descData; ComPtr<IGattDescriptor> descriptor; hr = descriptors->GetAt(j, &descriptor); @@ -293,7 +303,9 @@ public slots: &readOp); WARN_AND_CONTINUE_IF_FAILED(hr, "Could not read descriptor value") ComPtr<IClientCharConfigDescriptorResult> readResult; - hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf()); + hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf(), + QWinRTFunctions::ProcessMainThreadEvents, 5000, + exitCondition); WARN_AND_CONTINUE_IF_FAILED(hr, "Could not await descriptor read result") GattClientCharacteristicConfigurationDescriptorValue value; hr = readResult->get_ClientCharacteristicConfigurationDescriptor(&value); @@ -325,8 +337,10 @@ public slots: &readOp); WARN_AND_CONTINUE_IF_FAILED(hr, "Could not read descriptor value") ComPtr<IGattReadResult> readResult; - hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf()); - WARN_AND_CONTINUE_IF_FAILED(hr, "Could await descriptor read result") + hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf(), + QWinRTFunctions::ProcessMainThreadEvents, 5000, + exitCondition); + WARN_AND_CONTINUE_IF_FAILED(hr, "Could not await descriptor read result") if (descData.uuid == QBluetoothUuid::DescriptorType::CharacteristicUserDescription) descData.value = byteArrayFromGattResult(readResult, true); else @@ -342,8 +356,13 @@ public slots: checkAllCharacteristicsDiscovered(); } + void setAbortRequested() + { + mAbortRequested = true; + } + private: - bool checkAllCharacteristicsDiscovered(); + void checkAllCharacteristicsDiscovered(); void emitErrorAndQuitThread(HRESULT hr); void emitErrorAndQuitThread(const QString &error); @@ -356,6 +375,7 @@ public: quint16 mStartHandle = 0; quint16 mEndHandle = 0; QList<QBluetoothUuid> mIndicateChars; + bool mAbortRequested = false; signals: void charListObtained(const QBluetoothUuid &service, @@ -365,16 +385,13 @@ signals: void errorOccured(const QString &error); }; -bool QWinRTLowEnergyServiceHandler::checkAllCharacteristicsDiscovered() +void QWinRTLowEnergyServiceHandler::checkAllCharacteristicsDiscovered() { - if (mCharacteristicsCountToBeDiscovered == 0) { + if (!mAbortRequested && (mCharacteristicsCountToBeDiscovered == 0)) { emit charListObtained(mService, mCharacteristicList, mIndicateChars, mStartHandle, mEndHandle); - QThread::currentThread()->quit(); - return true; } - - return false; + QThread::currentThread()->quit(); } void QWinRTLowEnergyServiceHandler::emitErrorAndQuitThread(HRESULT hr) @@ -384,6 +401,7 @@ void QWinRTLowEnergyServiceHandler::emitErrorAndQuitThread(HRESULT hr) void QWinRTLowEnergyServiceHandler::emitErrorAndQuitThread(const QString &error) { + mAbortRequested = true; // so that the service is closed during cleanup emit errorOccured(error); QThread::currentThread()->quit(); } @@ -1175,6 +1193,12 @@ HRESULT QLowEnergyControllerPrivateWinRT::onServiceDiscoveryFinished(ABI::Window void QLowEnergyControllerPrivateWinRT::clearAllServices() { + // These services will be closed in the respective + // QWinRTLowEnergyServiceHandler workers (in background threads). + for (auto &uuid : m_requestDetailsServiceUuids) + m_openedServices.remove(uuid); + m_requestDetailsServiceUuids.clear(); + for (auto service : m_openedServices) { closeDeviceService(service); } @@ -1312,11 +1336,14 @@ void QLowEnergyControllerPrivateWinRT::discoverServiceDetailsHelper( QWinRTLowEnergyServiceHandler *worker = new QWinRTLowEnergyServiceHandler(service, deviceService3, mode); + m_requestDetailsServiceUuids.insert(service); QThread *thread = new QThread; worker->moveToThread(thread); connect(thread, &QThread::started, worker, &QWinRTLowEnergyServiceHandler::obtainCharList); connect(thread, &QThread::finished, worker, &QObject::deleteLater); connect(worker, &QObject::destroyed, thread, &QObject::deleteLater); + connect(this, &QLowEnergyControllerPrivateWinRT::abortConnection, + worker, &QWinRTLowEnergyServiceHandler::setAbortRequested); connect(worker, &QWinRTLowEnergyServiceHandler::errorOccured, this, &QLowEnergyControllerPrivateWinRT::handleServiceHandlerError); connect(worker, &QWinRTLowEnergyServiceHandler::charListObtained, this, @@ -1328,6 +1355,7 @@ void QLowEnergyControllerPrivateWinRT::discoverServiceDetailsHelper( << "Discovery complete for unknown service:" << service.toString(); return; } + m_requestDetailsServiceUuids.remove(service); QSharedPointer<QLowEnergyServicePrivate> pointer = serviceList.value(service); pointer->startHandle = startHandle; diff --git a/src/bluetooth/qlowenergycontroller_winrt_p.h b/src/bluetooth/qlowenergycontroller_winrt_p.h index 984e2e77..e1806d6c 100644 --- a/src/bluetooth/qlowenergycontroller_winrt_p.h +++ b/src/bluetooth/qlowenergycontroller_winrt_p.h @@ -162,6 +162,7 @@ private: using GattDeviceServiceComPtr = Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattDeviceService>; QMap<QBluetoothUuid, GattDeviceServiceComPtr> m_openedServices; + QSet<QBluetoothUuid> m_requestDetailsServiceUuids; using NativeServiceCallback = std::function<void(GattDeviceServiceComPtr)>; HRESULT getNativeService(const QBluetoothUuid &serviceUuid, NativeServiceCallback callback); diff --git a/src/tools/sdpscanner/main.cpp b/src/tools/sdpscanner/main.cpp index 7e09ca6e..c39ff8f3 100644 --- a/src/tools/sdpscanner/main.cpp +++ b/src/tools/sdpscanner/main.cpp @@ -39,6 +39,7 @@ #include <QtCore/QByteArray> #include <QtCore/QDebug> +#include <QtCore/QUrl> #include <stdio.h> #include <string> #include <bluetooth/bluetooth.h> @@ -159,7 +160,9 @@ static void parseAttributeValues(sdp_data_t *data, int indentation, QByteArray & break; } else if (!isprint(text[i])) { hasNonPrintableChar = true; - text.resize(text.indexOf('\0')); // cut trailing content + const auto firstNullIdx = text.indexOf('\0'); + if (firstNullIdx > 0) + text.resize(firstNullIdx); // cut trailing content break; } } @@ -211,11 +214,17 @@ static void parseAttributeValues(sdp_data_t *data, int indentation, QByteArray & case SDP_URL_STR8: case SDP_URL_STR16: case SDP_URL_STR32: - strncpy(snBuffer, data->val.str, data->unitSize - 1); + { xmlOutput.append("<url value=\""); - xmlOutput.append(snBuffer); + const QByteArray urlData = + QByteArray::fromRawData(data->val.str, qstrnlen(data->val.str, data->unitSize)); + const QUrl url = QUrl::fromEncoded(urlData); + // Encoded url %-encodes all of the XML special characters except '&', + // so we need to do that manually + xmlOutput.append(url.toEncoded().replace('&', "&")); xmlOutput.append("\"/>\n"); break; + } default: fprintf(stderr, "Unknown dtd type\n"); } |