diff options
6 files changed, 87 insertions, 1 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 50e2f293..93b4a50d 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 @@ -168,6 +168,14 @@ public class QtBluetoothLE { GattEntry entry = entries.get(runningHandle); entry.valueKnown = true; entries.set(runningHandle, entry); + String data = new String(characteristic.getValue()); + // Qt manages handles starting at 1, in Java we use a system starting with 0 + characteristic.getService().getUuid().toString(); + + //TODO avoid sending service uuid -> service handle should be sufficient + leCharacteristicRead(qtObject, characteristic.getService().getUuid().toString(), + runningHandle+1, characteristic.getUuid().toString(), + characteristic.getProperties(), characteristic.getValue()); performServiceDiscoveryForHandle(runningHandle+1, false); } @@ -431,5 +439,8 @@ public class QtBluetoothLE { public native void leConnectionStateChange(long qtObject, int wasErrorTransition, int newState); public native void leServicesDiscovered(long qtObject, int errorCode, String uuidList); public native void leServiceDetailDiscoveryFinished(long qtObject, final String serviceUuid); + public native void leCharacteristicRead(long qtObject, String serviceUuid, + int charHandle, String charUuid, + int properties, byte[] data); } diff --git a/src/bluetooth/android/jni_android.cpp b/src/bluetooth/android/jni_android.cpp index 5ae18161..b75ca2df 100644 --- a/src/bluetooth/android/jni_android.cpp +++ b/src/bluetooth/android/jni_android.cpp @@ -205,6 +205,8 @@ static JNINativeMethod methods_le[] = { (void *) LowEnergyNotificationHub::lowEnergy_servicesDiscovered}, {"leServiceDetailDiscoveryFinished", "(JLjava/lang/String;)V", (void *) LowEnergyNotificationHub::lowEnergy_serviceDetailsDiscovered}, + {"leCharacteristicRead", "(JLjava/lang/String;ILjava/lang/String;I[B)V", + (void *) LowEnergyNotificationHub::lowEnergy_characteristicRead}, }; static JNINativeMethod methods_server[] = { diff --git a/src/bluetooth/android/lowenergynotificationhub.cpp b/src/bluetooth/android/lowenergynotificationhub.cpp index e009e5f7..71aa5a02 100644 --- a/src/bluetooth/android/lowenergynotificationhub.cpp +++ b/src/bluetooth/android/lowenergynotificationhub.cpp @@ -137,4 +137,39 @@ void LowEnergyNotificationHub::lowEnergy_serviceDetailsDiscovered( Q_ARG(QString, serviceUuid)); } +void LowEnergyNotificationHub::lowEnergy_characteristicRead( + JNIEnv *env, jobject, jlong qtObject, jobject sUuid, jint handle, + jobject cUuid, jint properties, 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()); + + jsize length = env->GetArrayLength(data); + jbyte* nativeData = (jbyte*) malloc(length * sizeof(jbyte)); + if (!nativeData) + return; + + env->GetByteArrayRegion(data, 0, length, nativeData); + const QByteArray qtArray(reinterpret_cast<const char*>(nativeData), + length); //takes ownership of data + + 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); +} + QT_END_NAMESPACE diff --git a/src/bluetooth/android/lowenergynotificationhub_p.h b/src/bluetooth/android/lowenergynotificationhub_p.h index 06c7b3ff..7a1e2d79 100644 --- a/src/bluetooth/android/lowenergynotificationhub_p.h +++ b/src/bluetooth/android/lowenergynotificationhub_p.h @@ -41,6 +41,7 @@ #include <QtBluetooth/QBluetoothAddress> #include <jni.h> +#include <QtBluetooth/QLowEnergyCharacteristic> #include "qlowenergycontroller_p.h" QT_BEGIN_NAMESPACE @@ -59,6 +60,10 @@ public: jint errorCode, jobject uuidList); static void lowEnergy_serviceDetailsDiscovered(JNIEnv *, jobject, jlong qtObject, jobject uuid); + static void lowEnergy_characteristicRead(JNIEnv*env, jobject, jlong qtObject, + jobject serviceUuid, + jint handle, jobject charUuid, + jint properties, jbyteArray data); QAndroidJniObject javaObject() { @@ -67,9 +72,12 @@ public: signals: void connectionUpdated(QLowEnergyController::ControllerState newState, - QLowEnergyController::Error errorCode); + QLowEnergyController::Error errorCode); void servicesDiscovered(QLowEnergyController::Error errorCode, const QString &uuids); void serviceDetailsDiscoveryFinished(const QString& serviceUuid); + void characteristicRead(const QBluetoothUuid &serviceUuid, + int handle, const QBluetoothUuid &charUuid, + int properties, const QByteArray& data); public slots: private: diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp index 3a7ca98d..c3cdde83 100644 --- a/src/bluetooth/qlowenergycontroller_android.cpp +++ b/src/bluetooth/qlowenergycontroller_android.cpp @@ -70,6 +70,9 @@ void QLowEnergyControllerPrivate::connectToDevice() this, &QLowEnergyControllerPrivate::servicesDiscovered); connect(hub, &LowEnergyNotificationHub::serviceDetailsDiscoveryFinished, this, &QLowEnergyControllerPrivate::serviceDetailsDiscoveryFinished); + connect(hub, &LowEnergyNotificationHub::characteristicRead, + this, &QLowEnergyControllerPrivate::characteristicRead); + } if (!hub->javaObject().isValid()) { @@ -230,4 +233,28 @@ void QLowEnergyControllerPrivate::serviceDetailsDiscoveryFinished( pointer->setState(QLowEnergyService::ServiceDiscovered); } +void QLowEnergyControllerPrivate::characteristicRead( + const QBluetoothUuid& serviceUuid, int handle, + const QBluetoothUuid &charUuid, int properties, const QByteArray &data) +{ + if (!serviceList.contains(serviceUuid)) + return; + + QSharedPointer<QLowEnergyServicePrivate> service = + serviceList.value(serviceUuid); + QLowEnergyHandle charHandle = handle; + + QLowEnergyServicePrivate::CharData &charDetails = + service->characteristicList[charHandle]; + + //Android uses same properties value as Qt which is the Bluetooth LE standard + charDetails.properties = QLowEnergyCharacteristic::PropertyType(properties); + charDetails.uuid = charUuid; + charDetails.value = data; + //value handle always one larger than characteristics value handle + charDetails.valueHandle = charHandle + 1; + + //service->characteristicList[charHandle] = charDetails; +} + QT_END_NAMESPACE diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h index 7676c19e..6f416b11 100644 --- a/src/bluetooth/qlowenergycontroller_p.h +++ b/src/bluetooth/qlowenergycontroller_p.h @@ -180,6 +180,9 @@ private slots: void servicesDiscovered(QLowEnergyController::Error errorCode, const QString &foundServices); void serviceDetailsDiscoveryFinished(const QString& serviceUuid); + void characteristicRead(const QBluetoothUuid &serviceUuid, int handle, + const QBluetoothUuid &charUuid, int properties, + const QByteArray& data); #endif private: |