diff options
author | Alex Blasche <alexander.blasche@qt.io> | 2017-01-18 09:14:19 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@qt.io> | 2017-01-24 14:49:21 +0000 |
commit | 2e60c570b46e69599861969fc949551a058e902d (patch) | |
tree | 13fb3cb6f33af3f63f173f155056626ebba1ea20 /src | |
parent | 6b0595b64ea46554a8a63f026c15ab07ea804285 (diff) |
Android: Implement QLEService::descriptorWritten() signals for peripheral
Change-Id: I60e5bdce4256804754909c2538aebe581897e1e9
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src')
6 files changed, 99 insertions, 0 deletions
diff --git a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLEServer.java b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLEServer.java index b283a4b3..d256fe8c 100644 --- a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLEServer.java +++ b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLEServer.java @@ -213,6 +213,7 @@ public class QtBluetoothLEServer { if (!preparedWrite) { // regular write if (offset == 0) { descriptor.setValue(value); + leServerDescriptorWritten(qtObject, descriptor, value); } else { // This should not really happen as per Bluetooth spec Log.w(TAG, "onDescriptorWriteRequest: !preparedWrite, offset " + offset + ", Not supported"); @@ -349,4 +350,7 @@ public class QtBluetoothLEServer { public native void leServerCharacteristicChanged(long qtObject, BluetoothGattCharacteristic characteristic, byte[] newValue); + public native void leServerDescriptorWritten(long qtObject, + BluetoothGattDescriptor descriptor, + byte[] newValue); } diff --git a/src/bluetooth/android/jni_android.cpp b/src/bluetooth/android/jni_android.cpp index 7f08ea85..68e291e5 100644 --- a/src/bluetooth/android/jni_android.cpp +++ b/src/bluetooth/android/jni_android.cpp @@ -234,6 +234,8 @@ static JNINativeMethod methods_leServer[] = { (void *) LowEnergyNotificationHub::lowEnergy_advertisementError}, {"leServerCharacteristicChanged", "(JLandroid/bluetooth/BluetoothGattCharacteristic;[B)V", (void *) LowEnergyNotificationHub::lowEnergy_serverCharacteristicChanged}, + {"leServerDescriptorWritten", "(JLandroid/bluetooth/BluetoothGattDescriptor;[B)V", + (void *) LowEnergyNotificationHub::lowEnergy_serverDescriptorWritten}, }; static JNINativeMethod methods_server[] = { diff --git a/src/bluetooth/android/lowenergynotificationhub.cpp b/src/bluetooth/android/lowenergynotificationhub.cpp index b0d8b0a2..53f2d6cc 100644 --- a/src/bluetooth/android/lowenergynotificationhub.cpp +++ b/src/bluetooth/android/lowenergynotificationhub.cpp @@ -273,6 +273,28 @@ void LowEnergyNotificationHub::lowEnergy_descriptorWritten( (QLowEnergyService::ServiceError)errorCode)); } +void LowEnergyNotificationHub::lowEnergy_serverDescriptorWritten( + JNIEnv *env, jobject, jlong qtObject, jobject descriptor, jbyteArray newValue) +{ + lock.lockForRead(); + LowEnergyNotificationHub *hub = hubMap()->value(qtObject); + lock.unlock(); + if (!hub) + return; + + QByteArray payload; + if (newValue) { //empty Java byte array is 0x0 + jsize length = env->GetArrayLength(newValue); + payload.resize(length); + env->GetByteArrayRegion(newValue, 0, length, + reinterpret_cast<signed char*>(payload.data())); + } + + QMetaObject::invokeMethod(hub, "serverDescriptorWritten", Qt::QueuedConnection, + Q_ARG(QAndroidJniObject, descriptor), + Q_ARG(QByteArray, payload)); +} + void LowEnergyNotificationHub::lowEnergy_characteristicChanged( JNIEnv *env, jobject, jlong qtObject, jint charHandle, jbyteArray data) { diff --git a/src/bluetooth/android/lowenergynotificationhub_p.h b/src/bluetooth/android/lowenergynotificationhub_p.h index b3962190..7a328204 100644 --- a/src/bluetooth/android/lowenergynotificationhub_p.h +++ b/src/bluetooth/android/lowenergynotificationhub_p.h @@ -91,6 +91,8 @@ public: static void lowEnergy_descriptorWritten(JNIEnv *, jobject, jlong qtObject, jint descHandle, jbyteArray data, jint errorCode); + static void lowEnergy_serverDescriptorWritten(JNIEnv *, jobject, jlong qtObject, + jobject descriptor, jbyteArray newValue); static void lowEnergy_characteristicChanged(JNIEnv *, jobject, jlong qtObject, jint charHandle, jbyteArray data); static void lowEnergy_serverCharacteristicChanged(JNIEnv *, jobject, jlong qtObject, @@ -120,6 +122,7 @@ signals: QLowEnergyService::ServiceError errorCode); void descriptorWritten(int descHandle, const QByteArray &data, QLowEnergyService::ServiceError errorCode); + void serverDescriptorWritten(const QAndroidJniObject &descriptor, const QByteArray newValue); void characteristicChanged(int charHandle, const QByteArray &data); void serverCharacteristicChanged(const QAndroidJniObject& characteristic, const QByteArray& newValue); void serviceError(int attributeHandle, QLowEnergyService::ServiceError errorCode); diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp index 9efd6045..52afbd15 100644 --- a/src/bluetooth/qlowenergycontroller_android.cpp +++ b/src/bluetooth/qlowenergycontroller_android.cpp @@ -96,6 +96,8 @@ void QLowEnergyControllerPrivate::init() this, &QLowEnergyControllerPrivate::advertisementError); connect(hub, &LowEnergyNotificationHub::serverCharacteristicChanged, this, &QLowEnergyControllerPrivate::serverCharacteristicChanged); + connect(hub, &LowEnergyNotificationHub::serverDescriptorWritten, + this, &QLowEnergyControllerPrivate::serverDescriptorWritten); } else { if (version < 18) { qWarning() << "Qt Bluetooth LE Central/Client support not available" @@ -643,6 +645,71 @@ void QLowEnergyControllerPrivate::descriptorWritten( emit service->descriptorWritten(descriptor, data); } +void QLowEnergyControllerPrivate::serverDescriptorWritten( + const QAndroidJniObject &jniDesc, const QByteArray &newValue) +{ + qCDebug(QT_BT_ANDROID) << "Server descriptor change notification" << newValue.toHex(); + + // retrieve service, char and desc uuids + QAndroidJniObject jniChar = jniDesc.callObjectMethod( + "getCharacteristic", "()Landroid/bluetooth/BluetoothGattCharacteristic;"); + if (!jniChar.isValid()) + return; + + QAndroidJniObject jniService = jniChar.callObjectMethod( + "getService", "()Landroid/bluetooth/BluetoothGattService;"); + if (!jniService.isValid()) + return; + + QAndroidJniObject jniUuid = jniService.callObjectMethod("getUuid", "()Ljava/util/UUID;"); + const QBluetoothUuid serviceUuid(jniUuid.toString()); + if (serviceUuid.isNull()) + return; + + // TODO test if two service with same uuid exist + if (!localServices.contains(serviceUuid)) + return; + + jniUuid = jniChar.callObjectMethod("getUuid", "()Ljava/util/UUID;"); + const QBluetoothUuid characteristicUuid(jniUuid.toString()); + if (characteristicUuid.isNull()) + return; + + jniUuid = jniDesc.callObjectMethod("getUuid", "()Ljava/util/UUID;"); + const QBluetoothUuid descriptorUuid(jniUuid.toString()); + if (descriptorUuid.isNull()) + return; + + // find matching QLEDescriptor + auto servicePrivate = localServices.value(serviceUuid); + // TODO test if service contains two characteristics with same uuid + // or characteristic contains two descriptors with same uuid + const auto handleList = servicePrivate->characteristicList.keys(); + for (const auto charHandle : handleList) { + const auto &charData = servicePrivate->characteristicList.value(charHandle); + if (charData.uuid != characteristicUuid) + continue; + + const auto &descHandleList = charData.descriptorList.keys(); + for (const auto descHandle : descHandleList) { + const auto &descData = charData.descriptorList.value(descHandle); + if (descData.uuid != descriptorUuid) + continue; + + qCDebug(QT_BT_ANDROID) << "serverDescriptorChanged: Matching descriptor" + << descriptorUuid << "in char" << characteristicUuid + << "of service" << serviceUuid; + + servicePrivate->characteristicList[charHandle].descriptorList[descHandle].value = newValue; + + emit servicePrivate->descriptorWritten( + QLowEnergyDescriptor(servicePrivate, charHandle, descHandle), + newValue); + return; + } + } +} + void QLowEnergyControllerPrivate::characteristicChanged( int charHandle, const QByteArray &data) { diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h index 4ac9f3f4..1c309c95 100644 --- a/src/bluetooth/qlowenergycontroller_p.h +++ b/src/bluetooth/qlowenergycontroller_p.h @@ -440,6 +440,7 @@ private slots: QLowEnergyService::ServiceError errorCode); void descriptorWritten(int descHandle, const QByteArray &data, QLowEnergyService::ServiceError errorCode); + void serverDescriptorWritten(const QAndroidJniObject &jniDesc, const QByteArray &newValue); void characteristicChanged(int charHandle, const QByteArray &data); void serverCharacteristicChanged(const QAndroidJniObject &jniChar, const QByteArray &newValue); void serviceError(int attributeHandle, QLowEnergyService::ServiceError errorCode); |