summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bluetooth/android/servicediscoverybroadcastreceiver.cpp3
-rw-r--r--src/bluetooth/osx/osxbtcentralmanager.mm24
-rw-r--r--src/bluetooth/osx/osxbtnotifier_p.h1
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_android.cpp15
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_android.cpp91
-rw-r--r--src/bluetooth/qbluetoothsocket.cpp7
-rw-r--r--src/bluetooth/qbluetoothsocket_android.cpp78
-rw-r--r--src/bluetooth/qbluetoothsocket_android_p.h2
-rw-r--r--src/bluetooth/qbluetoothsocket_winrt.cpp2
-rw-r--r--src/bluetooth/qlowenergycontroller_osx.mm17
-rw-r--r--src/bluetooth/qlowenergycontroller_osx_p.h1
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt.cpp20
-rw-r--r--tests/bttestui/btlocaldevice.cpp6
13 files changed, 177 insertions, 90 deletions
diff --git a/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp b/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp
index be1953d5..283db623 100644
--- a/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp
+++ b/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp
@@ -99,7 +99,6 @@ QList<QBluetoothUuid> ServiceDiscoveryBroadcastReceiver::convertParcelableArray(
{
QList<QBluetoothUuid> result;
QAndroidJniEnvironment env;
- QAndroidJniObject p;
jobjectArray parcels = parcelUuidArray.object<jobjectArray>();
if (!parcels)
@@ -107,7 +106,7 @@ QList<QBluetoothUuid> ServiceDiscoveryBroadcastReceiver::convertParcelableArray(
jint size = env->GetArrayLength(parcels);
for (int i = 0; i < size; i++) {
- p = env->GetObjectArrayElement(parcels, i);
+ auto p = QAndroidJniObject::fromLocalRef(env->GetObjectArrayElement(parcels, i));
QBluetoothUuid uuid(p.callObjectMethod<jstring>("toString").toString());
//qCDebug(QT_BT_ANDROID) << uuid.toString();
diff --git a/src/bluetooth/osx/osxbtcentralmanager.mm b/src/bluetooth/osx/osxbtcentralmanager.mm
index 41713909..6b742684 100644
--- a/src/bluetooth/osx/osxbtcentralmanager.mm
+++ b/src/bluetooth/osx/osxbtcentralmanager.mm
@@ -1373,6 +1373,30 @@ QT_USE_NAMESPACE
[self discoverIncludedServices];
}
+- (void)peripheral:(CBPeripheral *)aPeripheral
+ didModifyServices:(NSArray<CBService *> *)invalidatedServices
+{
+ Q_UNUSED(aPeripheral)
+ Q_UNUSED(invalidatedServices)
+
+ qCWarning(QT_BT_OSX) << "The peripheral has modified its services.";
+ // "This method is invoked whenever one or more services of a peripheral have changed.
+ // A peripheral’s services have changed if:
+ // * A service is removed from the peripheral’s database
+ // * A new service is added to the peripheral’s database
+ // * A service that was previously removed from the peripheral’s
+ // database is readded to the database at a different location"
+
+ // In case new services were added - we have to discover them.
+ // In case some were removed - we can end up with dangling pointers
+ // (see our 'watchdogs', for example). To handle the situation
+ // we stop all current operations here, report to QLowEnergyController
+ // so that it can trigger re-discovery.
+ [self reset];
+ managerState = OSXBluetooth::CentralManagerIdle;
+ if (notifier)
+ emit notifier->servicesWereModified();
+}
- (void)peripheral:(CBPeripheral *)aPeripheral didDiscoverIncludedServicesForService:(CBService *)service
error:(NSError *)error
diff --git a/src/bluetooth/osx/osxbtnotifier_p.h b/src/bluetooth/osx/osxbtnotifier_p.h
index 47ee6ba1..dca6c268 100644
--- a/src/bluetooth/osx/osxbtnotifier_p.h
+++ b/src/bluetooth/osx/osxbtnotifier_p.h
@@ -89,6 +89,7 @@ Q_SIGNALS:
void descriptorRead(QLowEnergyHandle descHandle, const QByteArray &value);
void descriptorWritten(QLowEnergyHandle descHandle, const QByteArray &value);
void notificationEnabled(QLowEnergyHandle charHandle, bool enabled);
+ void servicesWereModified();
void LEnotSupported();
void CBManagerError(QBluetoothDeviceDiscoveryAgent::Error error);
diff --git a/src/bluetooth/qbluetoothlocaldevice_android.cpp b/src/bluetooth/qbluetoothlocaldevice_android.cpp
index b46923eb..40e4c2d4 100644
--- a/src/bluetooth/qbluetoothlocaldevice_android.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_android.cpp
@@ -90,23 +90,16 @@ static QAndroidJniObject getDefaultAdapter()
QAndroidJniObject adapter = QAndroidJniObject::callStaticObjectMethod(
"android/bluetooth/BluetoothAdapter", "getDefaultAdapter",
"()Landroid/bluetooth/BluetoothAdapter;");
+ QAndroidJniExceptionCleaner exCleaner{QAndroidJniExceptionCleaner::OutputMode::Verbose};
if (!adapter.isValid()) {
- QAndroidJniEnvironment env;
- if (env->ExceptionCheck()) {
- env->ExceptionDescribe();
- env->ExceptionClear();
- }
+ exCleaner.clean();
// workaround stupid bt implementations where first call of BluetoothAdapter.getDefaultAdapter() always fails
adapter = QAndroidJniObject::callStaticObjectMethod(
"android/bluetooth/BluetoothAdapter", "getDefaultAdapter",
"()Landroid/bluetooth/BluetoothAdapter;");
- if (!adapter.isValid()) {
- if (env->ExceptionCheck()) {
- env->ExceptionDescribe();
- env->ExceptionClear();
- }
- }
+ if (!adapter.isValid())
+ exCleaner.clean();
}
return adapter;
}
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
index ddc53421..3ab0d580 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
@@ -47,6 +47,7 @@
#include <QtBluetooth/QBluetoothServiceDiscoveryAgent>
#include "qbluetoothservicediscoveryagent_p.h"
+#include "qbluetoothsocket_android_p.h"
#include "android/servicediscoverybroadcastreceiver_p.h"
#include "android/localdevicebroadcastreceiver_p.h"
@@ -335,42 +336,62 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_processFetchedUuids(
void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QBluetoothDeviceInfo &remoteDevice, const QList<QBluetoothUuid> &uuids)
{
- /* Android doesn't provide decent SDP data. A list of uuids is close to meaning-less
+ /* Android doesn't provide decent SDP data. A flat list of uuids is all we get.
*
* The following approach is chosen:
* - If we see an SPP service class and we see
- * one or more custom uuids we match them up. Such services will always be SPP services.
+ * one or more custom uuids we match them up. Such services will always
+ * be SPP services. There is the chance that a custom uuid is eronously
+ * mapped as being an SPP service. In addition, the SPP uuid will be mapped as
+ * standalone SPP service.
* - If we see a custom uuid but no SPP uuid then we return
- * BluetoothServiceInfo instance with just a servuceUuid (no service class set)
+ * BluetoothServiceInfo instance with just a serviceUuid (no service class set)
+ * - If we don't find any custom uuid but the SPP uuid, we return a
+ * BluetoothServiceInfo instance where classId and serviceUuid() are set to SPP.
* - Any other service uuid will stand on its own.
* */
Q_Q(QBluetoothServiceDiscoveryAgent);
//find SPP and custom uuid
- QBluetoothUuid uuid;
- int sppIndex = -1;
+ bool haveSppClass = false;
QVector<int> customUuids;
for (int i = 0; i < uuids.count(); i++) {
- uuid = uuids.at(i);
+ const QBluetoothUuid uuid = uuids.at(i);
if (uuid.isNull())
continue;
//check for SPP protocol
bool ok = false;
- quint16 uuid16 = uuid.toUInt16(&ok);
- if (ok && uuid16 == QBluetoothUuid::SerialPort)
- sppIndex = i;
+ auto uuid16 = uuid.toUInt16(&ok);
+ haveSppClass |= ok && uuid16 == QBluetoothUuid::SerialPort;
//check for custom uuid
if (uuid.minimumSize() == 16)
customUuids.append(i);
}
+ auto rfcommProtocolDescriptorList = []() -> QBluetoothServiceInfo::Sequence {
+ QBluetoothServiceInfo::Sequence protocol;
+ protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
+ << QVariant::fromValue(0);
+ return protocol;
+ };
+
+ auto sppProfileDescriptorList = []() -> QBluetoothServiceInfo::Sequence {
+ QBluetoothServiceInfo::Sequence profileSequence;
+ QBluetoothServiceInfo::Sequence classId;
+ classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+ classId << QVariant::fromValue(quint16(0x100));
+ profileSequence.append(QVariant::fromValue(classId));
+ return profileSequence;
+ };
+
for (int i = 0; i < uuids.count(); i++) {
- if (i == sppIndex && !customUuids.isEmpty())
+ const QBluetoothUuid &uuid = uuids.at(i);
+ if (uuid.isNull())
continue;
QBluetoothServiceInfo serviceInfo;
@@ -383,52 +404,38 @@ void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QB
protocolDescriptorList.append(QVariant::fromValue(protocol));
}
- if (customUuids.contains(i) && sppIndex > -1) {
+ if (customUuids.contains(i) && haveSppClass) {
//we have a custom uuid of service class type SPP
//set rfcomm protocol
- QBluetoothServiceInfo::Sequence protocol;
- protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
- << QVariant::fromValue(0);
- protocolDescriptorList.append(QVariant::fromValue(protocol));
+ protocolDescriptorList.append(QVariant::fromValue(rfcommProtocolDescriptorList()));
- QBluetoothServiceInfo::Sequence profileSequence;
- QBluetoothServiceInfo::Sequence classId;
- classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
- classId << QVariant::fromValue(quint16(0x100));
- profileSequence.append(QVariant::fromValue(classId));
+ //set SPP profile descriptor list
serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
- profileSequence);
+ sppProfileDescriptorList());
- classId.clear();
+ QBluetoothServiceInfo::Sequence classId;
//set SPP service class uuid
- classId << QVariant::fromValue(uuids.at(i));
+ classId << QVariant::fromValue(uuid);
classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Serial Port Profile"));
- serviceInfo.setServiceUuid(uuids.at(i));
- } else if (sppIndex == i && customUuids.isEmpty()) {
+ serviceInfo.setServiceUuid(uuid);
+ } else if (uuid == QBluetoothUuid{QBluetoothUuid::SerialPort}) {
//set rfcomm protocol
- QBluetoothServiceInfo::Sequence protocol;
- protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
- << QVariant::fromValue(0);
- protocolDescriptorList.append(QVariant::fromValue(protocol));
+ protocolDescriptorList.append(QVariant::fromValue(rfcommProtocolDescriptorList()));
- QBluetoothServiceInfo::Sequence profileSequence;
- QBluetoothServiceInfo::Sequence classId;
- classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
- classId << QVariant::fromValue(quint16(0x100));
- profileSequence.append(QVariant::fromValue(classId));
+ //set SPP profile descriptor list
serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
- profileSequence);
+ sppProfileDescriptorList());
//also we need to set the custom uuid to the SPP uuid
//otherwise QBluetoothSocket::connectToService() would fail due to a missing service uuid
- serviceInfo.setServiceUuid(uuids.at(i));
+ serviceInfo.setServiceUuid(uuid);
} else if (customUuids.contains(i)) {
//custom uuid but no serial port
- serviceInfo.setServiceUuid(uuids.at(i));
+ serviceInfo.setServiceUuid(uuid);
}
serviceInfo.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList);
@@ -439,18 +446,20 @@ void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QB
if (!customUuids.contains(i)) {
//if we don't have custom uuid use it as class id as well
QBluetoothServiceInfo::Sequence classId;
- classId << QVariant::fromValue(uuids.at(i));
+ classId << QVariant::fromValue(uuid);
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
- QBluetoothUuid::ServiceClassUuid clsId
- = static_cast<QBluetoothUuid::ServiceClassUuid>(uuids.at(i).toUInt16());
+ auto clsId = QBluetoothUuid::ServiceClassUuid(uuid.toUInt16());
serviceInfo.setServiceName(QBluetoothUuid::serviceClassToString(clsId));
}
//Check if the service is in the uuidFilter
if (!uuidFilter.isEmpty()) {
bool match = uuidFilter.contains(serviceInfo.serviceUuid());
- for (const auto &uuid : qAsConst(uuidFilter))
+ match |= uuidFilter.contains(QBluetoothSocketPrivateAndroid::reverseUuid(serviceInfo.serviceUuid()));
+ for (const auto &uuid : qAsConst(uuidFilter)) {
match |= serviceInfo.serviceClassUuids().contains(uuid);
+ match |= serviceInfo.serviceClassUuids().contains(QBluetoothSocketPrivateAndroid::reverseUuid(uuid));
+ }
if (!match)
continue;
diff --git a/src/bluetooth/qbluetoothsocket.cpp b/src/bluetooth/qbluetoothsocket.cpp
index eecb1401..daa589bb 100644
--- a/src/bluetooth/qbluetoothsocket.cpp
+++ b/src/bluetooth/qbluetoothsocket.cpp
@@ -360,8 +360,8 @@ qint64 QBluetoothSocket::bytesToWrite() const
/*!
Attempts to connect to the service described by \a service.
- The socket is opened in the given \a openMode. The \l socketType() may change
- depending on the protocol required by \a service.
+ The socket is opened in the given \a openMode. The \l socketType() is ignored
+ if \a service specifies a differing \l QBluetoothServiceInfo::socketProtocol().
The socket first enters ConnectingState and attempts to connect to the device providing
\a service. If a connection is established, QBluetoothSocket enters ConnectedState and
@@ -372,6 +372,9 @@ qint64 QBluetoothSocket::bytesToWrite() const
Note that most platforms require a pairing prior to connecting to the remote device. Otherwise
the connection process may fail.
+ On Android, only RFCOMM connections are possible. This function ignores any socket protocol indicator
+ and assumes RFCOMM.
+
\sa state(), disconnectFromService()
*/
void QBluetoothSocket::connectToService(const QBluetoothServiceInfo &service, OpenMode openMode)
diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp
index d7f17d17..85da325b 100644
--- a/src/bluetooth/qbluetoothsocket_android.cpp
+++ b/src/bluetooth/qbluetoothsocket_android.cpp
@@ -182,30 +182,6 @@ private:
QPointer<SocketConnectWorker> workerPointer;
};
-/*
- * This function is part of a workaround for QTBUG-61392
- *
- * Returns null uuid if the given \a serviceUuid is not a uuid
- * derived from the Bluetooth base uuid.
- */
-static QBluetoothUuid reverseUuid(const QBluetoothUuid &serviceUuid)
-{
- if (serviceUuid.isNull())
- return QBluetoothUuid();
-
- bool isBaseUuid = false;
- serviceUuid.toUInt32(&isBaseUuid);
- if (isBaseUuid)
- return serviceUuid;
-
- const quint128 original = serviceUuid.toUInt128();
- quint128 reversed;
- for (int i = 0; i < 16; i++)
- reversed.data[15-i] = original.data[i];
-
- return QBluetoothUuid(reversed);
-}
-
QBluetoothSocketPrivateAndroid::QBluetoothSocketPrivateAndroid()
:
inputThread(0)
@@ -518,7 +494,33 @@ void QBluetoothSocketPrivateAndroid::connectToService(
return;
}
- if (!ensureNativeSocket(service.socketProtocol())) {
+ // Workaround for QTBUG-75035
+ /* Not all Android devices publish or discover the SPP uuid for serial services.
+ * Also, Android does not permit the detection of the protocol used by a serial
+ * Bluetooth connection.
+ *
+ * Therefore, QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices()
+ * may have to guess what protocol a potential custom uuid uses. The guessing works
+ * reasonably well as long as the SDP discovery finds the SPP uuid. Otherwise
+ * the SPP and rfcomm protocol info is missing in \a service.
+ *
+ * Android only supports RFCOMM (no L2CP). We assume (in favor of user experience)
+ * that a non-RFCOMM protocol implies a missing SPP uuid during discovery but the user
+ * still wanting to connect with the given \a service instance.
+ */
+
+ auto protocol = service.socketProtocol();
+ switch (protocol) {
+ case QBluetoothServiceInfo::L2capProtocol:
+ case QBluetoothServiceInfo::UnknownProtocol:
+ qCWarning(QT_BT_ANDROID) << "Changing socket protocol to RFCOMM";
+ protocol = QBluetoothServiceInfo::RfcommProtocol;
+ break;
+ case QBluetoothServiceInfo::RfcommProtocol:
+ break;
+ }
+
+ if (!ensureNativeSocket(protocol)) {
errorString = QBluetoothSocket::tr("Socket type not supported");
q->setSocketError(QBluetoothSocket::UnsupportedProtocolError);
return;
@@ -942,6 +944,32 @@ qint64 QBluetoothSocketPrivateAndroid::bytesToWrite() const
return 0; // nothing because always unbuffered
}
+/*
+ * This function is part of a workaround for QTBUG-61392
+ *
+ * Returns null uuid if the given \a serviceUuid is not a uuid
+ * derived from the Bluetooth base uuid.
+ */
+QBluetoothUuid QBluetoothSocketPrivateAndroid::reverseUuid(const QBluetoothUuid &serviceUuid)
+{
+ if (QtAndroid::androidSdkVersion() < 23)
+ return serviceUuid;
+
+ if (serviceUuid.isNull())
+ return QBluetoothUuid();
+
+ bool isBaseUuid = false;
+ serviceUuid.toUInt32(&isBaseUuid);
+ if (isBaseUuid)
+ return serviceUuid;
+
+ const quint128 original = serviceUuid.toUInt128();
+ quint128 reversed;
+ for (int i = 0; i < 16; i++)
+ reversed.data[15-i] = original.data[i];
+ return QBluetoothUuid{reversed};
+}
+
bool QBluetoothSocketPrivateAndroid::canReadLine() const
{
// We cannot access buffer directly as it is part of different thread
diff --git a/src/bluetooth/qbluetoothsocket_android_p.h b/src/bluetooth/qbluetoothsocket_android_p.h
index 7bf42e32..042e1bcd 100644
--- a/src/bluetooth/qbluetoothsocket_android_p.h
+++ b/src/bluetooth/qbluetoothsocket_android_p.h
@@ -112,6 +112,8 @@ public:
bool canReadLine() const override;
qint64 bytesToWrite() const override;
+ static QBluetoothUuid reverseUuid(const QBluetoothUuid &serviceUuid);
+
QAndroidJniObject adapter;
QAndroidJniObject socketObject;
QAndroidJniObject remoteDevice;
diff --git a/src/bluetooth/qbluetoothsocket_winrt.cpp b/src/bluetooth/qbluetoothsocket_winrt.cpp
index 79dccdd6..a4af8f72 100644
--- a/src/bluetooth/qbluetoothsocket_winrt.cpp
+++ b/src/bluetooth/qbluetoothsocket_winrt.cpp
@@ -765,7 +765,7 @@ HRESULT QBluetoothSocketPrivateWinRT::handleConnectOpFinished(ABI::Windows::Foun
return S_OK;
}
- HRESULT hr = action->GetResults();
+ DWORD hr = action->GetResults();
switch (hr) {
case 0x8007274c: // A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
errorString = QBluetoothSocket::tr("Connection timed out");
diff --git a/src/bluetooth/qlowenergycontroller_osx.mm b/src/bluetooth/qlowenergycontroller_osx.mm
index 8cef621c..8bcdc22e 100644
--- a/src/bluetooth/qlowenergycontroller_osx.mm
+++ b/src/bluetooth/qlowenergycontroller_osx.mm
@@ -339,6 +339,21 @@ void QLowEnergyControllerPrivateOSX::_q_serviceDetailsDiscoveryFinished(QSharedP
qtService->setState(QLowEnergyService::ServiceDiscovered);
}
+void QLowEnergyControllerPrivateOSX::_q_servicesWereModified()
+{
+ if (!(controllerState == QLowEnergyController::DiscoveringState
+ || controllerState == QLowEnergyController::DiscoveredState)) {
+ qCWarning(QT_BT_OSX) << "services were modified while controller is not in Discovered/Discovering state";
+ return;
+ }
+
+ if (controllerState == QLowEnergyController::DiscoveredState)
+ invalidateServices();
+
+ controllerState = QLowEnergyController::ConnectedState;
+ q_ptr->discoverServices();
+}
+
void QLowEnergyControllerPrivateOSX::_q_characteristicRead(QLowEnergyHandle charHandle,
const QByteArray &value)
{
@@ -989,6 +1004,8 @@ bool QLowEnergyControllerPrivateOSX::connectSlots(OSXBluetooth::LECBManagerNotif
this, &QLowEnergyControllerPrivateOSX::_q_serviceDiscoveryFinished);
ok = ok && connect(notifier, &LECBManagerNotifier::serviceDetailsDiscoveryFinished,
this, &QLowEnergyControllerPrivateOSX::_q_serviceDetailsDiscoveryFinished);
+ ok = ok && connect(notifier, &LECBManagerNotifier::servicesWereModified,
+ this, &QLowEnergyControllerPrivateOSX::_q_servicesWereModified);
ok = ok && connect(notifier, &LECBManagerNotifier::characteristicRead,
this, &QLowEnergyControllerPrivateOSX::_q_characteristicRead);
ok = ok && connect(notifier, &LECBManagerNotifier::characteristicWritten,
diff --git a/src/bluetooth/qlowenergycontroller_osx_p.h b/src/bluetooth/qlowenergycontroller_osx_p.h
index 24b7c6e9..da959895 100644
--- a/src/bluetooth/qlowenergycontroller_osx_p.h
+++ b/src/bluetooth/qlowenergycontroller_osx_p.h
@@ -98,6 +98,7 @@ private Q_SLOTS:
void _q_serviceDiscoveryFinished();
void _q_serviceDetailsDiscoveryFinished(QSharedPointer<QLowEnergyServicePrivate> service);
+ void _q_servicesWereModified();
void _q_characteristicRead(QLowEnergyHandle charHandle, const QByteArray &value);
void _q_characteristicWritten(QLowEnergyHandle charHandle, const QByteArray &value);
diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp
index 6efa2231..f946b541 100644
--- a/src/bluetooth/qlowenergycontroller_winrt.cpp
+++ b/src/bluetooth/qlowenergycontroller_winrt.cpp
@@ -779,7 +779,7 @@ void QLowEnergyControllerPrivateWinRT::readDescriptor(const QSharedPointer<QLowE
HRESULT hr;
hr = QEventDispatcherWinRT::runOnXamlThread([charHandle, descHandle, service, this]() {
- QLowEnergyServicePrivate::CharData charData = service->characteristicList.value(charHandle);
+ const QLowEnergyServicePrivate::CharData charData = service->characteristicList.value(charHandle);
ComPtr<IGattCharacteristic> characteristic = getNativeCharacteristic(service->uuid, charData.uuid);
if (!characteristic) {
qCDebug(QT_BT_WINRT) << "Could not obtain native characteristic" << charData.uuid
@@ -791,12 +791,13 @@ void QLowEnergyControllerPrivateWinRT::readDescriptor(const QSharedPointer<QLowE
// Get native descriptor
if (!charData.descriptorList.contains(descHandle))
qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "cannot be found in characteristic" << charHandle;
- QLowEnergyServicePrivate::DescData descData = charData.descriptorList.value(descHandle);
- if (descData.uuid == QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration)) {
+ const QLowEnergyServicePrivate::DescData descData = charData.descriptorList.value(descHandle);
+ const QBluetoothUuid descUuid = descData.uuid;
+ if (descUuid == QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration)) {
ComPtr<IAsyncOperation<ClientCharConfigDescriptorResult *>> readOp;
HRESULT hr = characteristic->ReadClientCharacteristicConfigurationDescriptorAsync(&readOp);
Q_ASSERT_SUCCEEDED(hr);
- auto readCompletedLambda = [&charData, charHandle, &descData, descHandle, service]
+ auto readCompletedLambda = [charHandle, descHandle, service]
(IAsyncOperation<ClientCharConfigDescriptorResult *> *op, AsyncStatus status)
{
if (status == AsyncStatus::Canceled || status == AsyncStatus::Error) {
@@ -837,9 +838,11 @@ void QLowEnergyControllerPrivateWinRT::readDescriptor(const QSharedPointer<QLowE
service->setError(QLowEnergyService::DescriptorReadError);
return S_OK;
}
+ QLowEnergyServicePrivate::DescData descData;
+ descData.uuid = QBluetoothUuid::ClientCharacteristicConfiguration;
descData.value = QByteArray(2, Qt::Uninitialized);
qToLittleEndian(result, descData.value.data());
- charData.descriptorList.insert(descHandle, descData);
+ service->characteristicList[charHandle].descriptorList[descHandle] = descData;
emit service->descriptorRead(QLowEnergyDescriptor(service, charHandle, descHandle),
descData.value);
return S_OK;
@@ -857,7 +860,7 @@ void QLowEnergyControllerPrivateWinRT::readDescriptor(const QSharedPointer<QLowE
ComPtr<IAsyncOperation<GattReadResult*>> readOp;
hr = descriptor->ReadValueWithCacheModeAsync(BluetoothCacheMode_Uncached, &readOp);
Q_ASSERT_SUCCEEDED(hr);
- auto readCompletedLambda = [&charData, charHandle, &descData, descHandle, service]
+ auto readCompletedLambda = [charHandle, descHandle, descUuid, service]
(IAsyncOperation<GattReadResult*> *op, AsyncStatus status)
{
if (status == AsyncStatus::Canceled || status == AsyncStatus::Error) {
@@ -873,11 +876,12 @@ void QLowEnergyControllerPrivateWinRT::readDescriptor(const QSharedPointer<QLowE
service->setError(QLowEnergyService::DescriptorReadError);
return S_OK;
}
- if (descData.uuid == QBluetoothUuid::CharacteristicUserDescription)
+ QLowEnergyServicePrivate::DescData descData;
+ if (descUuid == QBluetoothUuid::CharacteristicUserDescription)
descData.value = byteArrayFromGattResult(descriptorValue, true);
else
descData.value = byteArrayFromGattResult(descriptorValue);
- charData.descriptorList.insert(descHandle, descData);
+ service->characteristicList[charHandle].descriptorList[descHandle] = descData;
emit service->descriptorRead(QLowEnergyDescriptor(service, charHandle, descHandle),
descData.value);
return S_OK;
diff --git a/tests/bttestui/btlocaldevice.cpp b/tests/bttestui/btlocaldevice.cpp
index fb3a0270..55b99fc3 100644
--- a/tests/bttestui/btlocaldevice.cpp
+++ b/tests/bttestui/btlocaldevice.cpp
@@ -93,6 +93,9 @@ BtLocalDevice::BtLocalDevice(QObject *parent) :
connect(socket, &QBluetoothSocket::connected, this, &BtLocalDevice::socketConnected);
connect(socket, &QBluetoothSocket::disconnected, this, &BtLocalDevice::socketDisconnected);
connect(socket, &QIODevice::readyRead, this, &BtLocalDevice::readData);
+ connect(socket, &QBluetoothSocket::bytesWritten, this, [](qint64 bytesWritten){
+ qDebug() << "Bytes Written to Client socket:" << bytesWritten;
+ });
setSecFlags(static_cast<int>(socket->preferredSecurityFlags()));
server = new QBluetoothServer(SOCKET_PROTOCOL, this);
@@ -682,6 +685,9 @@ void BtLocalDevice::serverNewConnection()
connect(client, QOverload<QBluetoothSocket::SocketError>::of(&QBluetoothSocket::error),
this, &BtLocalDevice::socketError);
connect(client, &QBluetoothSocket::connected, this, &BtLocalDevice::socketConnected);
+ connect(client, &QBluetoothSocket::bytesWritten, this, [](qint64 bytesWritten){
+ qDebug() << "Bytes Written to Server socket:" << bytesWritten;
+ });
serverSockets.append(client);
}