diff options
author | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-04-10 15:13:25 +0200 |
---|---|---|
committer | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-04-15 08:31:11 +0000 |
commit | 0cf802e9dd963e5eb881a3e849beb4143d7c304c (patch) | |
tree | 5ff6238e02a0ba777098e746fdf6276d2b5c2c15 | |
parent | 6bb265e12c1e59078da9e9190bb11f6ac957b2cd (diff) |
Android: Fix read/write error reports when failure during initial call
The BluetoothGatt.[read|write][Characteristic|Descriptor]() functions
may immediately return under certain circumstances such as writing a
read-only characteristic. So far, this "synchronous" form of error
reporting was not handled.
Any read error during the initial service dioscovery and its related
cache population continues to surpress any read errors.
Change-Id: I4987f67f4a0d2afe58cd144a577a19e0f0d43b33
Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com>
-rw-r--r-- | src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java | 32 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_android.cpp | 6 |
2 files changed, 38 insertions, 0 deletions
diff --git a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java index 40286271..7118ce24 100644 --- a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java +++ b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java @@ -1031,6 +1031,38 @@ public class QtBluetoothLE { if (skip) { Log.w(TAG, "Skipping: " + nextJob.entry.type); + + /* + BluetoothGatt.[read|write][Characteristic|Descriptor]() immediately + return in cases where meta data doesn't match the intended action + (e.g. trying to write to read-only char). When this happens + we have to report an error back to Qt. This is not required during + the initial service discovery though. + */ + final boolean isServiceDiscoveryRun = (runningHandle != -1); + if (!isServiceDiscoveryRun) { + int handle = -1; + if (nextJob.entry.type == GattEntryType.Characteristic) + handle = handleForCharacteristic(nextJob.entry.characteristic); + else + handle = handleForDescriptor(nextJob.entry.descriptor); + + if (handle != -1) { + int errorCode = 0; + + // The error codes below must be in sync with QLowEnergyService::ServiceError + if (nextJob.jobType == IoJobType.Read) { + errorCode = (nextJob.entry.type == GattEntryType.Characteristic) ? + 5 : 6; // CharacteristicReadError : DescriptorReadError + } else { + errorCode = (nextJob.entry.type == GattEntryType.Characteristic) ? + 2 : 3; // CharacteristicWriteError : DescriptorWriteError + } + + leServiceError(qtObject, handle + 1, errorCode); + } + } + performNextIO(); } } diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp index 992427ff..f48c0e85 100644 --- a/src/bluetooth/qlowenergycontroller_android.cpp +++ b/src/bluetooth/qlowenergycontroller_android.cpp @@ -80,6 +80,8 @@ void QLowEnergyControllerPrivate::connectToDevice() this, &QLowEnergyControllerPrivate::descriptorWritten); connect(hub, &LowEnergyNotificationHub::characteristicChanged, this, &QLowEnergyControllerPrivate::characteristicChanged); + connect(hub, &LowEnergyNotificationHub::serviceError, + this, &QLowEnergyControllerPrivate::serviceError); } if (!hub->javaObject().isValid()) { @@ -563,6 +565,10 @@ void QLowEnergyControllerPrivate::characteristicChanged( void QLowEnergyControllerPrivate::serviceError( int attributeHandle, QLowEnergyService::ServiceError errorCode) { + // ignore call if it isn't really an error + if (errorCode == QLowEnergyService::NoError) + return; + QSharedPointer<QLowEnergyServicePrivate> service = serviceForHandle(attributeHandle); Q_ASSERT(!service.isNull()); |