From 2e60c570b46e69599861969fc949551a058e902d Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Wed, 18 Jan 2017 09:14:19 +0100 Subject: Android: Implement QLEService::descriptorWritten() signals for peripheral Change-Id: I60e5bdce4256804754909c2538aebe581897e1e9 Reviewed-by: Timur Pocheptsov --- src/bluetooth/qlowenergycontroller_android.cpp | 67 ++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'src/bluetooth/qlowenergycontroller_android.cpp') 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) { -- cgit v1.2.3