Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
lowenergynotificationhub.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
7#include <QCoreApplication>
8#include <QtCore/QHash>
9#include <QtCore/QLoggingCategory>
10#include <QtCore/QRandomGenerator>
11#include <QtCore/QJniEnvironment>
12
14
15typedef QHash<long, LowEnergyNotificationHub*> HubMapType;
17
18QReadWriteLock LowEnergyNotificationHub::lock;
19
20Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
21
23 bool isPeripheral, QObject *parent)
24 : QObject(parent), javaToCtoken(0)
25{
27
28 if (isPeripheral) {
29 qCDebug(QT_BT_ANDROID) << "Creating Android Peripheral/Server support for BTLE";
30 jBluetoothLe = QJniObject::construct<QtJniTypes::QtBtLEServer>(
31 QNativeInterface::QAndroidApplication::context());
32 } else {
33 qCDebug(QT_BT_ANDROID) << "Creating Android Central/Client support for BTLE";
34 const QJniObject address =
35 QJniObject::fromString(remote.toString());
36 jBluetoothLe = QJniObject::construct<QtJniTypes::QtBtLECentral>(
37 address.object<jstring>(), QNativeInterface::QAndroidApplication::context());
38 }
39
40 if (!jBluetoothLe.isValid()) return;
41
42 // register C++ class pointer in Java
43 lock.lockForWrite();
44
45 while (true) {
46 javaToCtoken = QRandomGenerator::global()->generate();
47 if (!hubMap()->contains(javaToCtoken))
48 break;
49 }
50
51 hubMap()->insert(javaToCtoken, this);
52 lock.unlock();
53
54 jBluetoothLe.setField<jlong>("qtObject", javaToCtoken);
55}
56
58{
59 lock.lockForWrite();
60 hubMap()->remove(javaToCtoken);
61 lock.unlock();
62}
63
64// runs in Java thread
65void LowEnergyNotificationHub::lowEnergy_connectionChange(JNIEnv *, jobject, jlong qtObject, jint errorCode, jint newState)
66{
67 lock.lockForRead();
68 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
69 lock.unlock();
70 if (!hub)
71 return;
72
73 QMetaObject::invokeMethod(hub, "connectionUpdated", Qt::QueuedConnection,
78}
79
80void LowEnergyNotificationHub::lowEnergy_mtuChanged(
81 JNIEnv *, jobject, jlong qtObject, jint mtu)
82{
83 lock.lockForRead();
84 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
85 lock.unlock();
86 if (!hub)
87 return;
88
90}
91
92void LowEnergyNotificationHub::lowEnergy_remoteRssiRead(JNIEnv *, jobject, jlong qtObject,
93 int rssi, bool success)
94{
95 lock.lockForRead();
96 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
97 lock.unlock();
98 if (!hub)
99 return;
100
101 QMetaObject::invokeMethod(hub, "remoteRssiRead", Qt::QueuedConnection,
102 Q_ARG(int, rssi), Q_ARG(bool, success));
103}
104
105
107 JNIEnv *, jobject, jlong qtObject, jint errorCode, jstring uuidList)
108{
109 lock.lockForRead();
110 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
111 lock.unlock();
112 if (!hub)
113 return;
114
115 const QString uuids = QJniObject(uuidList).toString();
116 QMetaObject::invokeMethod(hub, "servicesDiscovered", Qt::QueuedConnection,
119 Q_ARG(QString, uuids));
120}
121
122void LowEnergyNotificationHub::lowEnergy_serviceDetailsDiscovered(
123 JNIEnv *, jobject, jlong qtObject, jstring uuid, jint startHandle,
124 jint endHandle)
125{
126 lock.lockForRead();
127 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
128 lock.unlock();
129 if (!hub)
130 return;
131
132 const QString serviceUuid = QJniObject(uuid).toString();
133 QMetaObject::invokeMethod(hub, "serviceDetailsDiscoveryFinished",
136 Q_ARG(int, startHandle),
137 Q_ARG(int, endHandle));
138}
139
140void LowEnergyNotificationHub::lowEnergy_characteristicRead(
141 JNIEnv *env, jobject, jlong qtObject, jstring sUuid, jint handle,
142 jstring cUuid, jint properties, jbyteArray data)
143{
144 lock.lockForRead();
145 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
146 lock.unlock();
147 if (!hub)
148 return;
149
151 if (serviceUuid.isNull())
152 return;
153
155 if (charUuid.isNull())
156 return;
157
158 QByteArray payload;
159 if (data) { //empty Java byte array is 0x0
160 jsize length = env->GetArrayLength(data);
161 payload.resize(length);
162 env->GetByteArrayRegion(data, 0, length,
163 reinterpret_cast<signed char*>(payload.data()));
164 }
165
166 QMetaObject::invokeMethod(hub, "characteristicRead", Qt::QueuedConnection,
168 Q_ARG(int, handle),
170 Q_ARG(int, properties),
171 Q_ARG(QByteArray, payload));
172
173}
174
175void LowEnergyNotificationHub::lowEnergy_descriptorRead(
176 JNIEnv *env, jobject, jlong qtObject, jstring sUuid, jstring cUuid,
177 jint handle, jstring dUuid, jbyteArray data)
178{
179 lock.lockForRead();
180 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
181 lock.unlock();
182 if (!hub)
183 return;
184
186 if (serviceUuid.isNull())
187 return;
188
190 const QBluetoothUuid descUuid(QJniObject(dUuid).toString());
191 if (charUuid.isNull() || descUuid.isNull())
192 return;
193
194 QByteArray payload;
195 if (data) { //empty Java byte array is 0x0
196 jsize length = env->GetArrayLength(data);
197 payload.resize(length);
198 env->GetByteArrayRegion(data, 0, length,
199 reinterpret_cast<signed char*>(payload.data()));
200 }
201
202 QMetaObject::invokeMethod(hub, "descriptorRead", Qt::QueuedConnection,
205 Q_ARG(int, handle),
206 Q_ARG(QBluetoothUuid, descUuid),
207 Q_ARG(QByteArray, payload));
208}
209
211 JNIEnv *env, jobject, jlong qtObject, jint charHandle,
212 jbyteArray data, jint errorCode)
213{
214 lock.lockForRead();
215 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
216 lock.unlock();
217 if (!hub)
218 return;
219
220 QByteArray payload;
221 if (data) { //empty Java byte array is 0x0
222 jsize length = env->GetArrayLength(data);
223 payload.resize(length);
224 env->GetByteArrayRegion(data, 0, length,
225 reinterpret_cast<signed char*>(payload.data()));
226 }
227
228 QMetaObject::invokeMethod(hub, "characteristicWritten", Qt::QueuedConnection,
229 Q_ARG(int, charHandle),
230 Q_ARG(QByteArray, payload),
233}
234
235void LowEnergyNotificationHub::lowEnergy_descriptorWritten(
236 JNIEnv *env, jobject, jlong qtObject, jint descHandle,
237 jbyteArray data, jint errorCode)
238{
239 lock.lockForRead();
240 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
241 lock.unlock();
242 if (!hub)
243 return;
244
245 QByteArray payload;
246 if (data) { //empty Java byte array is 0x0
247 jsize length = env->GetArrayLength(data);
248 payload.resize(length);
249 env->GetByteArrayRegion(data, 0, length,
250 reinterpret_cast<signed char*>(payload.data()));
251 }
252
253 QMetaObject::invokeMethod(hub, "descriptorWritten", Qt::QueuedConnection,
254 Q_ARG(int, descHandle),
255 Q_ARG(QByteArray, payload),
258}
259
260void LowEnergyNotificationHub::lowEnergy_serverDescriptorWritten(
261 JNIEnv *env, jobject, jlong qtObject, QtJniTypes::BluetoothGattDescriptor descriptor,
262 jbyteArray newValue)
263{
264 lock.lockForRead();
265 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
266 lock.unlock();
267 if (!hub)
268 return;
269
270 QByteArray payload;
271 if (newValue) { //empty Java byte array is 0x0
272 jsize length = env->GetArrayLength(newValue);
273 payload.resize(length);
274 env->GetByteArrayRegion(newValue, 0, length,
275 reinterpret_cast<signed char*>(payload.data()));
276 }
277
278 QMetaObject::invokeMethod(hub, "serverDescriptorWritten", Qt::QueuedConnection,
280 Q_ARG(QByteArray, payload));
281}
282
283void LowEnergyNotificationHub::lowEnergy_characteristicChanged(
284 JNIEnv *env, jobject, jlong qtObject, jint charHandle, jbyteArray data)
285{
286 lock.lockForRead();
287 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
288 lock.unlock();
289 if (!hub)
290 return;
291
292 QByteArray payload;
293 if (data) { //empty Java byte array is 0x0
294 jsize length = env->GetArrayLength(data);
295 payload.resize(length);
296 env->GetByteArrayRegion(data, 0, length,
297 reinterpret_cast<signed char*>(payload.data()));
298 }
299
300 QMetaObject::invokeMethod(hub, "characteristicChanged", Qt::QueuedConnection,
301 Q_ARG(int, charHandle), Q_ARG(QByteArray, payload));
302}
303
304void LowEnergyNotificationHub::lowEnergy_serverCharacteristicChanged(
305 JNIEnv *env, jobject, jlong qtObject,
306 QtJniTypes::BluetoothGattCharacteristic characteristic, jbyteArray newValue)
307{
308 lock.lockForRead();
309 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
310 lock.unlock();
311 if (!hub)
312 return;
313
314 QByteArray payload;
315 if (newValue) { //empty Java byte array is 0x0
316 jsize length = env->GetArrayLength(newValue);
317 payload.resize(length);
318 env->GetByteArrayRegion(newValue, 0, length,
319 reinterpret_cast<signed char*>(payload.data()));
320 }
321
322 QMetaObject::invokeMethod(hub, "serverCharacteristicChanged", Qt::QueuedConnection,
324 Q_ARG(QByteArray, payload));
325}
326
327void LowEnergyNotificationHub::lowEnergy_serviceError(
328 JNIEnv *, jobject, jlong qtObject, jint attributeHandle, int errorCode)
329{
330 lock.lockForRead();
331 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
332 lock.unlock();
333 if (!hub)
334 return;
335
340}
341
343 JNIEnv *, jobject, jlong qtObject, jint status)
344{
345 lock.lockForRead();
346 LowEnergyNotificationHub *hub = hubMap()->value(qtObject);
347 lock.unlock();
348 if (!hub)
349 return;
350
351 QMetaObject::invokeMethod(hub, "advertisementError", Qt::QueuedConnection,
352 Q_ARG(int, status));
353}
354
quint8 rssi
static void lowEnergy_advertisementError(JNIEnv *, jobject, jlong qtObject, jint status)
jlong QtJniTypes::BluetoothGattDescriptor descriptor
jlong QtJniTypes::BluetoothGattCharacteristic characteristic
jlong jstring jstring jint jstring dUuid
jlong jstring jint jstring jint properties
static void lowEnergy_connectionChange(JNIEnv *, jobject, jlong qtObject, jint errorCode, jint newState)
static void lowEnergy_characteristicWritten(JNIEnv *, jobject, jlong qtObject, jint charHandle, jbyteArray data, jint errorCode)
jlong jstring jint jstring charUuid
jlong QtJniTypes::BluetoothGattDescriptor jbyteArray newValue
jlong jstring jint jint endHandle
static void lowEnergy_servicesDiscovered(JNIEnv *, jobject, jlong qtObject, jint errorCode, jstring uuidList)
jlong jint jbyteArray jint errorCode
\inmodule QtBluetooth
\inmodule QtBluetooth
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:611
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
\inmodule QtCore
\inmodule QtCore
ControllerState
Indicates the state of the controller object.
Error
Indicates all possible error conditions found during the controller's existence.
ServiceError
This enum describes all possible error conditions during the service's existence.
\inmodule QtCore
Definition qobject.h:103
static Q_DECL_CONST_FUNCTION QRandomGenerator * global()
\threadsafe
Definition qrandom.h:275
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
QT_BEGIN_NAMESPACE typedef QHash< long, LowEnergyNotificationHub * > HubMapType
Combined button and popup list for selecting options.
@ QueuedConnection
static const QCssKnownValue properties[NumProperties - 1]
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
#define Q_ARG(Type, data)
Definition qobjectdefs.h:63
static bool contains(const QJsonArray &haystack, unsigned needle)
Definition qopengl.cpp:116
GLuint64 GLenum void * handle
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint GLuint64EXT address
QReadWriteLock lock
[0]
char * toString(const MyType &t)
[31]
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...