summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLubomir I. Ivanov (VMware) <neolit123@gmail.com>2018-03-12 19:57:19 +0200
committerLubomir I. Ivanov <neolit123@gmail.com>2018-03-29 19:31:31 +0000
commitd75664c75d82accc1cbca0032750dd7d28d1777c (patch)
tree6890ad6bec2e454fb412bd75fe5bb94634b501e8
parent785462c02a4c793be0801232f5bd0c97351d950e (diff)
qlecontroller_win: write descriptors in a separate thread
Add support for the ThreadWorkerJob type WriteDesc in QLowEnergyControllerPrivateWin32. This type of job is responsible for writing GATT descriptors in a separate thread using the previously implemented ThreadWorkerJob scheme: - ThreadWorker::runPendingJob() - QLowEnergyControllerPrivateWin32::jobFinished() The blocking function in this case is setGattDescriptorValue(). Change-Id: Ib221862d50cdbe5af951d4ad82850bea4f9a6645 Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
-rw-r--r--src/bluetooth/qlowenergycontroller_win.cpp145
-rw-r--r--src/bluetooth/qlowenergycontroller_win_p.h10
2 files changed, 93 insertions, 62 deletions
diff --git a/src/bluetooth/qlowenergycontroller_win.cpp b/src/bluetooth/qlowenergycontroller_win.cpp
index 627ce545..bb968194 100644
--- a/src/bluetooth/qlowenergycontroller_win.cpp
+++ b/src/bluetooth/qlowenergycontroller_win.cpp
@@ -1107,6 +1107,69 @@ void QLowEnergyControllerPrivateWin32::jobFinished(const ThreadWorkerJob &job)
emit service->characteristicRead(ch, data.value);
}
case ThreadWorkerJob::WriteDescr:
+ {
+ WriteDescData data = job.data.value<WriteDescData>();
+ const QLowEnergyHandle descriptorHandle = static_cast<QLowEnergyHandle>(data.gattDescriptor.AttributeHandle);
+ const QLowEnergyHandle charHandle = static_cast<QLowEnergyHandle>(data.gattDescriptor.CharacteristicHandle);
+ const QSharedPointer<QLowEnergyServicePrivate> service = serviceForHandle(charHandle);
+ QLowEnergyServicePrivate::CharData &charDetails = service->characteristicList[charHandle];
+ const QLowEnergyServicePrivate::DescData &dscrDetails = charDetails.descriptorList[descriptorHandle];
+
+ if (data.systemErrorCode != NO_ERROR) {
+ closeSystemDevice(data.hService);
+ qCWarning(QT_BT_WINDOWS) << "Unable to set value for descriptor"
+ << dscrDetails.uuid.toString()
+ << "for characteristic"
+ << charDetails.uuid.toString()
+ << "of the service" << service->uuid.toString()
+ << ":" << qt_error_string(data.systemErrorCode);
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return;
+ }
+
+ if (data.gattDescriptor.DescriptorType == ClientCharacteristicConfiguration) {
+
+ QDataStream in(data.newValue);
+ quint8 u;
+ in >> u;
+
+ if (u & ClientCharacteristicConfigurationValue::UseNotifications
+ || u & ClientCharacteristicConfigurationValue::UseIndications) {
+ if (!charDetails.hValueChangeEvent) {
+ BTH_LE_GATT_CHARACTERISTIC gattCharacteristic = recoverNativeLeGattCharacteristic(
+ service->startHandle, charHandle, charDetails);
+
+ charDetails.hValueChangeEvent = registerEvent(
+ data.hService, gattCharacteristic, this, &data.systemErrorCode);
+ }
+ } else {
+ if (charDetails.hValueChangeEvent) {
+ unregisterEvent(charDetails.hValueChangeEvent, &data.systemErrorCode);
+ charDetails.hValueChangeEvent = NULL;
+ }
+ }
+
+ closeSystemDevice(data.hService);
+
+ if (data.systemErrorCode != NO_ERROR) {
+ qCWarning(QT_BT_WINDOWS) << "Unable to subscribe events for descriptor"
+ << dscrDetails.uuid.toString()
+ << "for characteristic"
+ << charDetails.uuid.toString()
+ << "of the service" << service->uuid.toString()
+ << ":" << qt_error_string(data.systemErrorCode);
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return;
+ }
+ } else {
+ closeSystemDevice(data.hService);
+ }
+
+ updateValueOfDescriptor(charHandle, descriptorHandle, data.newValue, false);
+
+ const QLowEnergyDescriptor dscr(service, charHandle, descriptorHandle);
+ emit service->descriptorWritten(dscr, data.newValue);
+ }
case ThreadWorkerJob::ReadDescr:
break;
}
@@ -1183,14 +1246,15 @@ void QLowEnergyControllerPrivateWin32::writeDescriptor(
if (!charDetails.descriptorList.contains(descriptorHandle))
return;
- int systemErrorCode = NO_ERROR;
-
- const HANDLE hService = openSystemService(
- remoteDevice, service->uuid, QIODevice::ReadWrite, &systemErrorCode);
+ WriteDescData data;
+ data.systemErrorCode = NO_ERROR;
+ data.newValue = newValue;
+ data.hService = openSystemService(
+ remoteDevice, service->uuid, QIODevice::ReadWrite, &data.systemErrorCode);
- if (systemErrorCode != NO_ERROR) {
+ if (data.systemErrorCode != NO_ERROR) {
qCWarning(QT_BT_WINDOWS) << "Unable to open service" << service->uuid.toString()
- << ":" << qt_error_string(systemErrorCode);
+ << ":" << qt_error_string(data.systemErrorCode);
service->setError(QLowEnergyService::DescriptorWriteError);
return;
}
@@ -1198,65 +1262,15 @@ void QLowEnergyControllerPrivateWin32::writeDescriptor(
const QLowEnergyServicePrivate::DescData &dscrDetails
= charDetails.descriptorList[descriptorHandle];
- BTH_LE_GATT_DESCRIPTOR gattDescriptor = recoverNativeLeGattDescriptor(
+ data.gattDescriptor = recoverNativeLeGattDescriptor(
service->startHandle, charHandle, descriptorHandle, dscrDetails);
- setGattDescriptorValue(hService, &gattDescriptor, newValue, &systemErrorCode);
-
- if (systemErrorCode != NO_ERROR) {
- closeSystemDevice(hService);
- qCWarning(QT_BT_WINDOWS) << "Unable to set value for descriptor"
- << dscrDetails.uuid.toString()
- << "for characteristic"
- << charDetails.uuid.toString()
- << "of the service" << service->uuid.toString()
- << ":" << qt_error_string(systemErrorCode);
- service->setError(QLowEnergyService::DescriptorWriteError);
- return;
- }
-
- if (gattDescriptor.DescriptorType == ClientCharacteristicConfiguration) {
-
- QDataStream in(newValue);
- quint8 u;
- in >> u;
-
- if (u & ClientCharacteristicConfigurationValue::UseNotifications
- || u & ClientCharacteristicConfigurationValue::UseIndications) {
- if (!charDetails.hValueChangeEvent) {
- BTH_LE_GATT_CHARACTERISTIC gattCharacteristic = recoverNativeLeGattCharacteristic(
- service->startHandle, charHandle, charDetails);
-
- charDetails.hValueChangeEvent = registerEvent(
- hService, gattCharacteristic, this, &systemErrorCode);
- }
- } else {
- if (charDetails.hValueChangeEvent) {
- unregisterEvent(charDetails.hValueChangeEvent, &systemErrorCode);
- charDetails.hValueChangeEvent = NULL;
- }
- }
-
- closeSystemDevice(hService);
-
- if (systemErrorCode != NO_ERROR) {
- qCWarning(QT_BT_WINDOWS) << "Unable to subscribe events for descriptor"
- << dscrDetails.uuid.toString()
- << "for characteristic"
- << charDetails.uuid.toString()
- << "of the service" << service->uuid.toString()
- << ":" << qt_error_string(systemErrorCode);
- service->setError(QLowEnergyService::DescriptorWriteError);
- return;
- }
- } else {
- closeSystemDevice(hService);
- }
-
- updateValueOfDescriptor(charHandle, descriptorHandle, newValue, false);
+ ThreadWorkerJob job;
+ job.operation = ThreadWorkerJob::WriteDescr;
+ job.data = QVariant::fromValue(data);
- const QLowEnergyDescriptor dscr(service, charHandle, descriptorHandle);
- emit service->descriptorWritten(dscr, newValue);
+ QMetaObject::invokeMethod(threadWorker, "putJob", Qt::QueuedConnection,
+ Q_ARG(ThreadWorkerJob, job));
}
void QLowEnergyControllerPrivateWin32::addToGenericAttributeList(const QLowEnergyServiceData &, QLowEnergyHandle)
@@ -1294,7 +1308,14 @@ void ThreadWorker::runPendingJob()
data.hService, &data.gattCharacteristic, &data.systemErrorCode);
job.data = QVariant::fromValue(data);
}
+ break;
case ThreadWorkerJob::WriteDescr:
+ {
+ WriteDescData data = job.data.value<WriteDescData>();
+ setGattDescriptorValue(data.hService, &data.gattDescriptor,
+ data.newValue, &data.systemErrorCode);
+ job.data = QVariant::fromValue(data);
+ }
case ThreadWorkerJob::ReadDescr:
break;
}
diff --git a/src/bluetooth/qlowenergycontroller_win_p.h b/src/bluetooth/qlowenergycontroller_win_p.h
index fc20a349..8f2f78e5 100644
--- a/src/bluetooth/qlowenergycontroller_win_p.h
+++ b/src/bluetooth/qlowenergycontroller_win_p.h
@@ -98,6 +98,16 @@ struct ReadCharData
Q_DECLARE_METATYPE(ReadCharData)
+struct WriteDescData
+{
+ QByteArray newValue;
+ HANDLE hService;
+ BTH_LE_GATT_DESCRIPTOR gattDescriptor;
+ int systemErrorCode;
+};
+
+Q_DECLARE_METATYPE(WriteDescData)
+
class ThreadWorker : public QObject
{
Q_OBJECT