summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@qt.io>2017-01-18 09:14:19 +0100
committerAlex Blasche <alexander.blasche@qt.io>2017-01-24 14:49:21 +0000
commit2e60c570b46e69599861969fc949551a058e902d (patch)
tree13fb3cb6f33af3f63f173f155056626ebba1ea20
parent6b0595b64ea46554a8a63f026c15ab07ea804285 (diff)
Android: Implement QLEService::descriptorWritten() signals for peripheral
Change-Id: I60e5bdce4256804754909c2538aebe581897e1e9 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLEServer.java4
-rw-r--r--src/bluetooth/android/jni_android.cpp2
-rw-r--r--src/bluetooth/android/lowenergynotificationhub.cpp22
-rw-r--r--src/bluetooth/android/lowenergynotificationhub_p.h3
-rw-r--r--src/bluetooth/qlowenergycontroller_android.cpp67
-rw-r--r--src/bluetooth/qlowenergycontroller_p.h1
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);