diff options
author | Alex Blasche <alexander.blasche@theqtcompany.com> | 2014-11-07 15:51:02 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@theqtcompany.com> | 2014-11-11 09:14:55 +0100 |
commit | a57a9a6598eb8fa2578ea8511b351b49d5b55ff0 (patch) | |
tree | 2b357b3aad43cfeaf14713a4d0c2900582d23c81 /src/bluetooth/android | |
parent | 327b6b7f8ff9acda74f403f2ff286e67f4202dfd (diff) |
The service->characteristic->descriptor tree becomes available in Qt
At the same time this fixes bugs the following bugs:
1.) Non-readable characteristics were not visible
2.) Crashes when descriptor/characteristic values were empty
3.) QLEService::discoverServiceDetails always finished with an
UnknownError
Missing/incorrect are still service details such as included services and
the service type (which currently always defaults to primary service).
Change-Id: Id73013a3784cd3c3f632102f13f5459ab37e95a6
Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com>
Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
Diffstat (limited to 'src/bluetooth/android')
-rw-r--r-- | src/bluetooth/android/jni_android.cpp | 4 | ||||
-rw-r--r-- | src/bluetooth/android/lowenergynotificationhub.cpp | 72 | ||||
-rw-r--r-- | src/bluetooth/android/lowenergynotificationhub_p.h | 13 |
3 files changed, 73 insertions, 16 deletions
diff --git a/src/bluetooth/android/jni_android.cpp b/src/bluetooth/android/jni_android.cpp index b75ca2df..745a0c98 100644 --- a/src/bluetooth/android/jni_android.cpp +++ b/src/bluetooth/android/jni_android.cpp @@ -203,10 +203,12 @@ static JNINativeMethod methods_le[] = { (void *) LowEnergyNotificationHub::lowEnergy_connectionChange}, {"leServicesDiscovered", "(JILjava/lang/String;)V", (void *) LowEnergyNotificationHub::lowEnergy_servicesDiscovered}, - {"leServiceDetailDiscoveryFinished", "(JLjava/lang/String;)V", + {"leServiceDetailDiscoveryFinished", "(JLjava/lang/String;II)V", (void *) LowEnergyNotificationHub::lowEnergy_serviceDetailsDiscovered}, {"leCharacteristicRead", "(JLjava/lang/String;ILjava/lang/String;I[B)V", (void *) LowEnergyNotificationHub::lowEnergy_characteristicRead}, + {"leDescriptorRead", "(JLjava/lang/String;Ljava/lang/String;ILjava/lang/String;[B)V", + (void *) LowEnergyNotificationHub::lowEnergy_descriptorRead}, }; static JNINativeMethod methods_server[] = { diff --git a/src/bluetooth/android/lowenergynotificationhub.cpp b/src/bluetooth/android/lowenergynotificationhub.cpp index 71aa5a02..709bbc68 100644 --- a/src/bluetooth/android/lowenergynotificationhub.cpp +++ b/src/bluetooth/android/lowenergynotificationhub.cpp @@ -123,7 +123,8 @@ void LowEnergyNotificationHub::lowEnergy_servicesDiscovered( } void LowEnergyNotificationHub::lowEnergy_serviceDetailsDiscovered( - JNIEnv *, jobject, jlong qtObject, jobject uuid) + JNIEnv *, jobject, jlong qtObject, jobject uuid, jint startHandle, + jint endHandle) { lock.lockForRead(); LowEnergyNotificationHub *hub = hubMap()->value(qtObject); @@ -134,7 +135,9 @@ void LowEnergyNotificationHub::lowEnergy_serviceDetailsDiscovered( const QString serviceUuid = QAndroidJniObject(uuid).toString(); QMetaObject::invokeMethod(hub, "serviceDetailsDiscoveryFinished", Qt::QueuedConnection, - Q_ARG(QString, serviceUuid)); + Q_ARG(QString, serviceUuid), + Q_ARG(int, startHandle), + Q_ARG(int, endHandle)); } void LowEnergyNotificationHub::lowEnergy_characteristicRead( @@ -147,29 +150,74 @@ void LowEnergyNotificationHub::lowEnergy_characteristicRead( if (!hub) return; - const QBluetoothUuid serviceUuid(QAndroidJniObject(sUuid).toString()); if (serviceUuid.isNull()) return; const QBluetoothUuid charUuid(QAndroidJniObject(cUuid).toString()); - - jsize length = env->GetArrayLength(data); - jbyte* nativeData = (jbyte*) malloc(length * sizeof(jbyte)); - if (!nativeData) + if (charUuid.isNull()) return; - env->GetByteArrayRegion(data, 0, length, nativeData); - const QByteArray qtArray(reinterpret_cast<const char*>(nativeData), - length); //takes ownership of data + QByteArray payload; + if (data) { //empty Java byte array is 0x0 + jsize length = env->GetArrayLength(data); + jbyte* nativeData = (jbyte*) malloc(length * sizeof(jbyte)); + if (!nativeData) + return; + + env->GetByteArrayRegion(data, 0, length, nativeData); + payload = QByteArray(reinterpret_cast<const char*>(nativeData), + length); //takes deep copy of data + free(nativeData); + } QMetaObject::invokeMethod(hub, "characteristicRead", Qt::QueuedConnection, Q_ARG(QBluetoothUuid, serviceUuid), Q_ARG(int, handle), Q_ARG(QBluetoothUuid, charUuid), Q_ARG(int, properties), - Q_ARG(QByteArray, qtArray)); - free(nativeData); + Q_ARG(QByteArray, payload)); + +} + +void LowEnergyNotificationHub::lowEnergy_descriptorRead( + JNIEnv *env, jobject, jlong qtObject, jobject sUuid, jobject cUuid, + jint handle, jobject dUuid, jbyteArray data) +{ + lock.lockForRead(); + LowEnergyNotificationHub *hub = hubMap()->value(qtObject); + lock.unlock(); + if (!hub) + return; + + const QBluetoothUuid serviceUuid(QAndroidJniObject(sUuid).toString()); + if (serviceUuid.isNull()) + return; + + const QBluetoothUuid charUuid(QAndroidJniObject(cUuid).toString()); + const QBluetoothUuid descUuid(QAndroidJniObject(dUuid).toString()); + if (charUuid.isNull() || descUuid.isNull()) + return; + + QByteArray payload; + if (data) { //empty Java byte array is 0x0 + jsize length = env->GetArrayLength(data); + jbyte* nativeData = (jbyte*) malloc(length * sizeof(jbyte)); + if (!nativeData) + return; + + env->GetByteArrayRegion(data, 0, length, nativeData); + payload = QByteArray(reinterpret_cast<const char*>(nativeData), + length); //takes deep copy of data + free(nativeData); + } + + QMetaObject::invokeMethod(hub, "descriptorRead", Qt::QueuedConnection, + Q_ARG(QBluetoothUuid, serviceUuid), + Q_ARG(QBluetoothUuid, charUuid), + Q_ARG(int, handle), + Q_ARG(QBluetoothUuid, descUuid), + Q_ARG(QByteArray, payload)); } QT_END_NAMESPACE diff --git a/src/bluetooth/android/lowenergynotificationhub_p.h b/src/bluetooth/android/lowenergynotificationhub_p.h index 7a1e2d79..39008a65 100644 --- a/src/bluetooth/android/lowenergynotificationhub_p.h +++ b/src/bluetooth/android/lowenergynotificationhub_p.h @@ -59,11 +59,15 @@ public: static void lowEnergy_servicesDiscovered(JNIEnv*, jobject, jlong qtObject, jint errorCode, jobject uuidList); static void lowEnergy_serviceDetailsDiscovered(JNIEnv *, jobject, - jlong qtObject, jobject uuid); + jlong qtObject, jobject uuid, + jint startHandle, jint endHandle); static void lowEnergy_characteristicRead(JNIEnv*env, jobject, jlong qtObject, jobject serviceUuid, jint handle, jobject charUuid, jint properties, jbyteArray data); + static void lowEnergy_descriptorRead(JNIEnv *env, jobject, jlong qtObject, + jobject sUuid, jobject cUuid, + jint handle, jobject dUuid, jbyteArray data); QAndroidJniObject javaObject() { @@ -74,10 +78,13 @@ signals: void connectionUpdated(QLowEnergyController::ControllerState newState, QLowEnergyController::Error errorCode); void servicesDiscovered(QLowEnergyController::Error errorCode, const QString &uuids); - void serviceDetailsDiscoveryFinished(const QString& serviceUuid); + void serviceDetailsDiscoveryFinished(const QString& serviceUuid, + int startHandle, int endHandle); void characteristicRead(const QBluetoothUuid &serviceUuid, int handle, const QBluetoothUuid &charUuid, - int properties, const QByteArray& data); + int properties, const QByteArray &data); + void descriptorRead(const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid, + int handle, const QBluetoothUuid &descUuid, const QByteArray &data); public slots: private: |