diff options
author | Lubomir I. Ivanov (VMware) <neolit123@gmail.com> | 2018-03-06 16:20:22 +0200 |
---|---|---|
committer | Lubomir I. Ivanov <neolit123@gmail.com> | 2018-03-29 19:31:19 +0000 |
commit | 785462c02a4c793be0801232f5bd0c97351d950e (patch) | |
tree | 5f5c10571a290ac4fac85c11050c26124263750d | |
parent | 43eebc049aef3b858dd1d38ebe4bf9b395891722 (diff) | |
download | qtconnectivity-785462c02a4c793be0801232f5bd0c97351d950e.tar.gz |
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.cpp | 62 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_win_p.h | 10 |
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 |