summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLubomir I. Ivanov (VMware) <neolit123@gmail.com>2018-03-06 16:20:22 +0200
committerLubomir I. Ivanov <neolit123@gmail.com>2018-03-29 19:31:19 +0000
commit785462c02a4c793be0801232f5bd0c97351d950e (patch)
tree5f5c10571a290ac4fac85c11050c26124263750d
parent43eebc049aef3b858dd1d38ebe4bf9b395891722 (diff)
qlecontroller_win: read characteristics in a separate thread
Add support for the ThreadWorkerJob type ReadChar in QLowEnergyControllerPrivateWin32. This type of job is responsible for reading GATT characteristics in a separate thread using the previously implemented ThreadWorkerJob scheme: - ThreadWorker::runPendingJob() - QLowEnergyControllerPrivateWin32::jobFinished() The blocking function in this case is getGattCharacteristicValue(). Change-Id: Idc87267a44aab51febae4addaca4b61d7e582a8a Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
-rw-r--r--src/bluetooth/qlowenergycontroller_win.cpp62
-rw-r--r--src/bluetooth/qlowenergycontroller_win_p.h10
2 files changed, 49 insertions, 23 deletions
diff --git a/src/bluetooth/qlowenergycontroller_win.cpp b/src/bluetooth/qlowenergycontroller_win.cpp
index 27bfb7c7..627ce545 100644
--- a/src/bluetooth/qlowenergycontroller_win.cpp
+++ b/src/bluetooth/qlowenergycontroller_win.cpp
@@ -988,38 +988,27 @@ void QLowEnergyControllerPrivateWin32::readCharacteristic(
qCWarning(QT_BT_WINDOWS) << "Reading non-readable char" << charHandle;
}
- int systemErrorCode = NO_ERROR;
-
- const HANDLE hService = openSystemService(
- remoteDevice, service->uuid, QIODevice::ReadOnly, &systemErrorCode);
+ ReadCharData data;
+ data.systemErrorCode = NO_ERROR;
+ data.hService = openSystemService(
+ remoteDevice, service->uuid, QIODevice::ReadOnly, &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::CharacteristicReadError);
return;
}
- BTH_LE_GATT_CHARACTERISTIC gattCharacteristic = recoverNativeLeGattCharacteristic(
+ data.gattCharacteristic = recoverNativeLeGattCharacteristic(
service->startHandle, charHandle, charDetails);
- const QByteArray characteristicValue = getGattCharacteristicValue(
- hService, &gattCharacteristic, &systemErrorCode);
- closeSystemDevice(hService);
-
- if (systemErrorCode != NO_ERROR) {
- qCWarning(QT_BT_WINDOWS) << "Unable to get value for characteristic"
- << charDetails.uuid.toString()
- << "of the service" << service->uuid.toString()
- << ":" << qt_error_string(systemErrorCode);
- service->setError(QLowEnergyService::CharacteristicReadError);
- return;
- }
-
- updateValueOfCharacteristic(charHandle, characteristicValue, false);
+ ThreadWorkerJob job;
+ job.operation = ThreadWorkerJob::ReadChar;
+ job.data = QVariant::fromValue(data);
- const QLowEnergyCharacteristic ch(service, charHandle);
- emit service->characteristicRead(ch, characteristicValue);
+ QMetaObject::invokeMethod(threadWorker, "putJob", Qt::QueuedConnection,
+ Q_ARG(ThreadWorkerJob, job));
}
void QLowEnergyControllerPrivateWin32::writeCharacteristic(
@@ -1096,6 +1085,27 @@ void QLowEnergyControllerPrivateWin32::jobFinished(const ThreadWorkerJob &job)
}
break;
case ThreadWorkerJob::ReadChar:
+ {
+ const ReadCharData data = job.data.value<ReadCharData>();
+ closeSystemDevice(data.hService);
+ const QLowEnergyHandle charHandle = static_cast<QLowEnergyHandle>(data.gattCharacteristic.AttributeHandle);
+ const QSharedPointer<QLowEnergyServicePrivate> service = serviceForHandle(charHandle);
+
+ if (data.systemErrorCode != NO_ERROR) {
+ const QLowEnergyServicePrivate::CharData &charDetails = service->characteristicList[charHandle];
+ qCWarning(QT_BT_WINDOWS) << "Unable to get value for characteristic"
+ << charDetails.uuid.toString()
+ << "of the service" << service->uuid.toString()
+ << ":" << qt_error_string(data.systemErrorCode);
+ service->setError(QLowEnergyService::CharacteristicReadError);
+ return;
+ }
+
+ updateValueOfCharacteristic(charHandle, data.value, false);
+
+ const QLowEnergyCharacteristic ch(service, charHandle);
+ emit service->characteristicRead(ch, data.value);
+ }
case ThreadWorkerJob::WriteDescr:
case ThreadWorkerJob::ReadDescr:
break;
@@ -1278,6 +1288,12 @@ void ThreadWorker::runPendingJob()
}
break;
case ThreadWorkerJob::ReadChar:
+ {
+ ReadCharData data = job.data.value<ReadCharData>();
+ data.value = getGattCharacteristicValue(
+ data.hService, &data.gattCharacteristic, &data.systemErrorCode);
+ job.data = QVariant::fromValue(data);
+ }
case ThreadWorkerJob::WriteDescr:
case ThreadWorkerJob::ReadDescr:
break;
diff --git a/src/bluetooth/qlowenergycontroller_win_p.h b/src/bluetooth/qlowenergycontroller_win_p.h
index 64f824e6..fc20a349 100644
--- a/src/bluetooth/qlowenergycontroller_win_p.h
+++ b/src/bluetooth/qlowenergycontroller_win_p.h
@@ -88,6 +88,16 @@ struct WriteCharData
Q_DECLARE_METATYPE(WriteCharData)
+struct ReadCharData
+{
+ QByteArray value;
+ HANDLE hService;
+ BTH_LE_GATT_CHARACTERISTIC gattCharacteristic;
+ int systemErrorCode;
+};
+
+Q_DECLARE_METATYPE(ReadCharData)
+
class ThreadWorker : public QObject
{
Q_OBJECT