diff options
6 files changed, 80 insertions, 17 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 6a283fb0..40286271 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 @@ -174,10 +174,16 @@ public class QtBluetoothLE { android.bluetooth.BluetoothGattCharacteristic characteristic, int status) { - // TODO test error handling for read requests + //runningHandle is only used during serviceDetailsDiscovery + //If it is -1 we got an update outside of the details discovery process + final boolean isServiceDiscoveryRun = (runningHandle != -1); + if (status != BluetoothGatt.GATT_SUCCESS) { Log.w(TAG, "onCharacteristicRead error: " + status); - return; + + // read errors during serviceDiscovery are ignored + if (isServiceDiscoveryRun) + return; } synchronized (this) { @@ -185,10 +191,12 @@ public class QtBluetoothLE { return; } - //runningHandle is only used during serviceDetailsDiscovery - //If it is -1 we got an update outside of the details discovery process - if (runningHandle == -1) { - List<Integer> handles = uuidToEntry.get(characteristic.getService().getUuid()); + // once we have a service discovery run we report regular changes + if (!isServiceDiscoveryRun) { + List<Integer> handles; + synchronized (this) { + handles = uuidToEntry.get(characteristic.getService().getUuid()); + } if (handles == null || handles.isEmpty()) { Log.w(TAG, "Received Characteristic read update for unknown characteristic"); return; @@ -227,9 +235,15 @@ public class QtBluetoothLE { ioJobPending = false; } - leCharacteristicRead(qtObject, characteristic.getService().getUuid().toString(), - foundHandle+1, characteristic.getUuid().toString(), - characteristic.getProperties(), characteristic.getValue()); + if (status == BluetoothGatt.GATT_SUCCESS) { + leCharacteristicRead(qtObject, characteristic.getService().getUuid().toString(), + foundHandle + 1, characteristic.getUuid().toString(), + characteristic.getProperties(), characteristic.getValue()); + } else { + // This must be in sync with QLowEnergyService::CharacteristicReadError + final int characteristicReadError = 5; + leServiceError(qtObject, foundHandle +1, characteristicReadError); + } performNextIO(); return; @@ -292,9 +306,16 @@ public class QtBluetoothLE { android.bluetooth.BluetoothGattDescriptor descriptor, int status) { + //runningHandle is only used during serviceDetailsDiscovery + //If it is -1 we got an update outside of the details discovery process + final boolean isServiceDiscoveryRun = (runningHandle != -1); + if (status != BluetoothGatt.GATT_SUCCESS) { Log.w(TAG, "onDescriptorRead error: " + status); - return; + + // read errors during serviceDiscovery are ignored + if (isServiceDiscoveryRun) + return; } synchronized (this) { @@ -302,10 +323,12 @@ public class QtBluetoothLE { return; } - //runningHandle is only used during serviceDetailsDiscovery - //If it is -1 we got an update outside of the details discovery process - if (runningHandle == -1) { - List<Integer> handles = uuidToEntry.get(descriptor.getCharacteristic().getService().getUuid()); + + if (!isServiceDiscoveryRun) { + List<Integer> handles; + synchronized (this) { + handles = uuidToEntry.get(descriptor.getCharacteristic().getService().getUuid()); + } if (handles == null || handles.isEmpty()) { Log.w(TAG, "Received Descriptor read update for unknown descriptor"); return; @@ -343,9 +366,15 @@ public class QtBluetoothLE { ioJobPending = false; } - leDescriptorRead(qtObject, descriptor.getCharacteristic().getService().getUuid().toString(), - descriptor.getCharacteristic().getUuid().toString(), foundHandle+1, - descriptor.getUuid().toString(), descriptor.getValue()); + if (status == BluetoothGatt.GATT_SUCCESS) { + leDescriptorRead(qtObject, descriptor.getCharacteristic().getService().getUuid().toString(), + descriptor.getCharacteristic().getUuid().toString(), foundHandle + 1, + descriptor.getUuid().toString(), descriptor.getValue()); + } else { + // This must be in sync with QLowEnergyService::DescriptorReadError + final int descriptorReadError = 6; + leServiceError(qtObject, foundHandle + 1, descriptorReadError); + } performNextIO(); return; @@ -1105,5 +1134,6 @@ public class QtBluetoothLE { public native void leDescriptorWritten(long qtObject, int charHandle, byte[] newData, int errorCode); public native void leCharacteristicChanged(long qtObject, int charHandle, byte[] newData); + public native void leServiceError(long qtObject, int attributeHandle, int errorCode); } diff --git a/src/bluetooth/android/jni_android.cpp b/src/bluetooth/android/jni_android.cpp index a91b7c88..b4209500 100644 --- a/src/bluetooth/android/jni_android.cpp +++ b/src/bluetooth/android/jni_android.cpp @@ -215,6 +215,8 @@ static JNINativeMethod methods_le[] = { (void *) LowEnergyNotificationHub::lowEnergy_descriptorWritten}, {"leCharacteristicChanged", "(JI[B)V", (void *) LowEnergyNotificationHub::lowEnergy_characteristicChanged}, + {"leServiceError", "(JII)V", + (void *) LowEnergyNotificationHub::lowEnergy_serviceError}, }; static JNINativeMethod methods_server[] = { diff --git a/src/bluetooth/android/lowenergynotificationhub.cpp b/src/bluetooth/android/lowenergynotificationhub.cpp index 325178b2..9e95ece6 100644 --- a/src/bluetooth/android/lowenergynotificationhub.cpp +++ b/src/bluetooth/android/lowenergynotificationhub.cpp @@ -281,4 +281,19 @@ void LowEnergyNotificationHub::lowEnergy_characteristicChanged( Q_ARG(int, charHandle), Q_ARG(QByteArray, payload)); } +void LowEnergyNotificationHub::lowEnergy_serviceError( + JNIEnv *, jobject, jlong qtObject, jint attributeHandle, int errorCode) +{ + lock.lockForRead(); + LowEnergyNotificationHub *hub = hubMap()->value(qtObject); + lock.unlock(); + if (!hub) + return; + + QMetaObject::invokeMethod(hub, "serviceError", Qt::QueuedConnection, + Q_ARG(int, attributeHandle), + Q_ARG(QLowEnergyService::ServiceError, + (QLowEnergyService::ServiceError)errorCode)); +} + QT_END_NAMESPACE diff --git a/src/bluetooth/android/lowenergynotificationhub_p.h b/src/bluetooth/android/lowenergynotificationhub_p.h index b4c67b85..0395f9db 100644 --- a/src/bluetooth/android/lowenergynotificationhub_p.h +++ b/src/bluetooth/android/lowenergynotificationhub_p.h @@ -76,6 +76,8 @@ public: jint errorCode); static void lowEnergy_characteristicChanged(JNIEnv *, jobject, jlong qtObject, jint charHandle, jbyteArray data); + static void lowEnergy_serviceError(JNIEnv *, jobject, jlong qtObject, + jint attributeHandle, int errorCode); QAndroidJniObject javaObject() { @@ -98,6 +100,7 @@ signals: void descriptorWritten(int descHandle, const QByteArray &data, QLowEnergyService::ServiceError errorCode); void characteristicChanged(int charHandle, const QByteArray &data); + void serviceError(int attributeHandle, QLowEnergyService::ServiceError errorCode); public slots: private: diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp index c1fa0813..992427ff 100644 --- a/src/bluetooth/qlowenergycontroller_android.cpp +++ b/src/bluetooth/qlowenergycontroller_android.cpp @@ -560,4 +560,16 @@ void QLowEnergyControllerPrivate::characteristicChanged( emit service->characteristicChanged(characteristic, data); } +void QLowEnergyControllerPrivate::serviceError( + int attributeHandle, QLowEnergyService::ServiceError errorCode) +{ + QSharedPointer<QLowEnergyServicePrivate> service = + serviceForHandle(attributeHandle); + Q_ASSERT(!service.isNull()); + + // ATM we don't really use attributeHandle but later on we might + // want to associate the error code with a char or desc + service->setError(errorCode); +} + QT_END_NAMESPACE diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h index 9e2cedbc..ab90ab84 100644 --- a/src/bluetooth/qlowenergycontroller_p.h +++ b/src/bluetooth/qlowenergycontroller_p.h @@ -217,6 +217,7 @@ private slots: void descriptorWritten(int descHandle, const QByteArray &data, QLowEnergyService::ServiceError errorCode); void characteristicChanged(int charHandle, const QByteArray &data); + void serviceError(int attributeHandle, QLowEnergyService::ServiceError errorCode); #endif private: QLowEnergyController *q_ptr; |