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
4#include "qnearfieldtarget.h"
5#include "qnearfieldtarget_p.h"
6#include "qndefmessage.h"
7
8#include <QtCore/QString>
9#include <QtCore/QUrl>
10
11#include <QtCore/QDebug>
12
13#include <QCoreApplication>
14
15QT_BEGIN_NAMESPACE
16
17QT_IMPL_METATYPE_EXTERN_TAGGED(QNearFieldTarget::RequestId, QNearFieldTarget__RequestId)
18
19/*!
20 \class QNearFieldTarget
21 \brief The QNearFieldTarget class provides an interface for communicating with a target
22 device.
23
24 \ingroup connectivity-nfc
25 \inmodule QtNfc
26 \since 5.2
27
28 QNearFieldTarget provides a generic interface for communicating with an NFC target device.
29 Both NFC Forum devices and NFC Forum Tag targets are supported by this class. All target
30 specific classes subclass this class.
31
32 The type() function can be used to get the type of the target device. The uid() function
33 returns the unique identifier of the target. The AccessMethods flags returns from the
34 accessMethods() function can be tested to determine which access methods are supported by the
35 target.
36
37 If the target supports NdefAccess, hasNdefMessage() can be called to test if the target has a
38 stored NDEF message, readNdefMessages() and writeNdefMessages() functions can be used to get
39 and set the NDEF message.
40
41 If the target supports TagTypeSpecificAccess, sendCommand() can be used to send a single
42 proprietary command to the target and retrieve the response.
43*/
44
45/*!
46 \enum QNearFieldTarget::Type
47
48 This enum describes the type of tag the target is detected as.
49
50 \value ProprietaryTag An unidentified proprietary target tag.
51 \value NfcTagType1 An NFC tag type 1 target.
52 \value NfcTagType2 An NFC tag type 2 target.
53 \value NfcTagType3 An NFC tag type 3 target.
54 \value NfcTagType4 An NFC tag type 4 target. This value is used if the NfcTagType4
55 cannot be further refined by NfcTagType4A or NfcTagType4B below.
56 \value NfcTagType4A An NFC tag type 4 target based on ISO/IEC 14443-3A.
57 \value NfcTagType4B An NFC tag type 4 target based on ISO/IEC 14443-3B.
58 \value MifareTag A Mifare target.
59*/
60
61/*!
62 \enum QNearFieldTarget::AccessMethod
63
64 This enum describes the access methods a near field target supports.
65
66 \value UnknownAccess The target supports an unknown access type.
67 \value NdefAccess The target supports reading and writing NDEF messages using
68 readNdefMessages() and writeNdefMessages().
69 \value TagTypeSpecificAccess The target supports sending tag type specific commands using
70 sendCommand().
71 \value AnyAccess The target supports any of the known access types.
72*/
73
74/*!
75 \enum QNearFieldTarget::Error
76
77 This enum describes the error codes that a near field target reports.
78
79 \value NoError No error has occurred.
80 \value UnknownError An unidentified error occurred.
81 \value UnsupportedError The requested operation is unsupported by this near field
82 target.
83 \value TargetOutOfRangeError The target is no longer within range.
84 \value NoResponseError The target did not respond.
85 \value ChecksumMismatchError The checksum has detected a corrupted response.
86 \value InvalidParametersError Invalid parameters were passed to a tag type specific function.
87 \value ConnectionError Failed to connect to the target.
88 \value NdefReadError Failed to read NDEF messages from the target.
89 \value NdefWriteError Failed to write NDEF messages to the target.
90 \value CommandError Failed to send a command to the target.
91 \value TimeoutError The request could not be completed within the time
92 specified in waitForRequestCompleted().
93 \value UnsupportedTargetError The target used is unsupported. As example this can occur on missing
94 required entitlement and/or privacy settings from the client app.
95*/
96
97/*!
98 \fn void QNearFieldTarget::disconnected()
99
100 This signal is emitted when the near field target moves out of proximity.
101*/
102
103/*!
104 \fn void QNearFieldTarget::ndefMessageRead(const QNdefMessage &message)
105
106 This signal is emitted when a complete NDEF \a message has been read from the target.
107
108 \sa readNdefMessages()
109*/
110
111/*!
112 \fn void QNearFieldTarget::requestCompleted(const QNearFieldTarget::RequestId &id)
113
114 This signal is emitted when a request \a id completes.
115
116 \sa sendCommand()
117*/
118
119/*!
120 \fn void QNearFieldTarget::error(QNearFieldTarget::Error error, const QNearFieldTarget::RequestId &id)
121
122 This signal is emitted when an error occurs while processing request \a id. The \a error
123 parameter describes the error.
124*/
125
126/*!
127 \class QNearFieldTarget::RequestId
128 \inmodule QtNfc
129 \inheaderfile QNearFieldTarget
130 \brief A request id handle.
131*/
132
133/*!
134 Constructs a new invalid request id handle.
135*/
136QNearFieldTarget::RequestId::RequestId()
137{
138}
139
140/*!
141 Constructs a new request id handle that is a copy of \a other.
142*/
143QNearFieldTarget::RequestId::RequestId(const RequestId &other)
144: d(other.d)
145{
146}
147
148/*!
149 \internal
150*/
151QNearFieldTarget::RequestId::RequestId(RequestIdPrivate *p)
152: d(p)
153{
154}
155
156/*!
157 Destroys the request id handle.
158*/
159QNearFieldTarget::RequestId::~RequestId()
160{
161}
162
163/*!
164 Returns \c true if this is a valid request id; otherwise returns \c false.
165*/
166bool QNearFieldTarget::RequestId::isValid() const
167{
168 return d;
169}
170
171/*!
172 Returns the current reference count of the request id.
173*/
174int QNearFieldTarget::RequestId::refCount() const
175{
176 if (d)
177 return d->ref.loadRelaxed();
178
179 return 0;
180}
181
182/*!
183 \internal
184*/
185bool QNearFieldTarget::RequestId::operator<(const RequestId &other) const
186{
187 return std::less<const RequestIdPrivate*>()(d.constData(), other.d.constData());
188}
189
190/*!
191 \internal
192*/
193bool QNearFieldTarget::RequestId::operator==(const RequestId &other) const
194{
195 return d == other.d;
196}
197
198/*!
199 \internal
200*/
201bool QNearFieldTarget::RequestId::operator!=(const RequestId &other) const
202{
203 return d != other.d;
204}
205
206/*!
207 Assigns a copy of \a other to this request id and returns a reference to this request id.
208*/
209QNearFieldTarget::RequestId &QNearFieldTarget::RequestId::operator=(const RequestId &other)
210{
211 d = other.d;
212 return *this;
213}
214
215/*!
216 Constructs a new near field target with \a parent.
217*/
218QNearFieldTarget::QNearFieldTarget(QObject *parent)
219: QNearFieldTarget(new QNearFieldTargetPrivate(this), parent)
220{
221}
222
223/*!
224 Destroys the near field target.
225*/
226QNearFieldTarget::~QNearFieldTarget()
227{
228 Q_D(QNearFieldTarget);
229
230 d->disconnect();
231}
232
233/*!
234 Returns the UID of the near field target.
235
236 \note On iOS, this function returns an empty QByteArray for
237 a near field target discovered using NdefAccess method.
238
239 \sa QNearFieldTarget::AccessMethod
240*/
241QByteArray QNearFieldTarget::uid() const
242{
243 Q_D(const QNearFieldTarget);
244
245 return d->uid();
246}
247
248/*!
249 Returns the type of tag type of this near field target.
250*/
251QNearFieldTarget::Type QNearFieldTarget::type() const
252{
253 Q_D(const QNearFieldTarget);
254
255 return d->type();
256}
257
258/*!
259 Returns the access methods supported by this near field target.
260*/
261QNearFieldTarget::AccessMethods QNearFieldTarget::accessMethods() const
262{
263 Q_D(const QNearFieldTarget);
264
265 return d->accessMethods();
266}
267
268/*!
269 \since 5.9
270
271 Closes the connection to the target to enable communication with the target
272 from a different instance. The connection will also be closed, when the
273 QNearFieldTarget is destroyed. A connection to the target device is
274 (re)created to process a command or read/write a NDEF messages.
275
276 Returns \c true only if an existing connection was successfully closed;
277 otherwise returns \c false.
278*/
279bool QNearFieldTarget::disconnect()
280{
281 Q_D(QNearFieldTarget);
282
283 return d->disconnect();
284}
285
286/*!
287 Returns \c true if at least one NDEF message is stored on the near field
288 target; otherwise returns \c false.
289*/
290bool QNearFieldTarget::hasNdefMessage()
291{
292 Q_D(QNearFieldTarget);
293
294 return d->hasNdefMessage();
295}
296
297/*!
298 Starts reading NDEF messages stored on the near field target. Returns a request id which can
299 be used to track the completion status of the request. An invalid request id will be returned
300 if the target does not support reading NDEF messages.
301
302 An ndefMessageRead() signal will be emitted for each NDEF message. The requestCompleted()
303 signal will be emitted was all NDEF messages have been read. The error() signal is emitted if
304 an error occurs.
305
306 \note An attempt to read an NDEF message from a tag, that is in INITIALIZED
307 state as defined by NFC Forum, will fail with the \l NdefReadError, as the
308 tag is formatted to support NDEF but does not contain a message yet.
309*/
310QNearFieldTarget::RequestId QNearFieldTarget::readNdefMessages()
311{
312 Q_D(QNearFieldTarget);
313
314 return d->readNdefMessages();
315}
316
317/*!
318 Writes the NDEF messages in \a messages to the target. Returns a request id which can be used
319 to track the completion status of the request. An invalid request id will be returned if the
320 target does not support reading NDEF messages.
321
322 The requestCompleted() signal will be emitted when the write operation completes
323 successfully; otherwise the error() signal is emitted.
324*/
325QNearFieldTarget::RequestId QNearFieldTarget::writeNdefMessages(const QList<QNdefMessage> &messages)
326{
327 Q_D(QNearFieldTarget);
328
329 return d->writeNdefMessages(messages);
330}
331
332/*!
333 \since 5.9
334
335 Returns the maximum number of bytes that can be sent with sendCommand. 0 will
336 be returned if the target does not support sending tag type specific commands.
337
338 \sa sendCommand()
339*/
340int QNearFieldTarget::maxCommandLength() const
341{
342 Q_D(const QNearFieldTarget);
343
344 return d->maxCommandLength();
345}
346
347/*!
348 Sends \a command to the near field target. Returns a request id which can be used to track the
349 completion status of the request. An invalid request id will be returned if the target does not
350 support sending tag type specific commands.
351
352 The requestCompleted() signal will be emitted on successful completion of the request;
353 otherwise the error() signal will be emitted.
354
355 Once the request completes successfully the response can be retrieved from the
356 requestResponse() function. The response of this request will be a QByteArray.
357
358 \sa requestCompleted(), waitForRequestCompleted()
359*/
360QNearFieldTarget::RequestId QNearFieldTarget::sendCommand(const QByteArray &command)
361{
362 Q_D(QNearFieldTarget);
363
364 return d->sendCommand(command);
365}
366
367/*!
368 Waits up to \a msecs milliseconds for the request \a id to complete.
369 Returns \c true if the request completes successfully and the
370 requestCompeted() signal is emitted; otherwise returns \c false.
371*/
372bool QNearFieldTarget::waitForRequestCompleted(const RequestId &id, int msecs)
373{
374 Q_D(QNearFieldTarget);
375
376 return d->waitForRequestCompleted(id, msecs);
377}
378
379/*!
380 Returns the decoded response for request \a id. If the request is unknown or has not yet been
381 completed an invalid QVariant is returned.
382*/
383QVariant QNearFieldTarget::requestResponse(const RequestId &id) const
384{
385 Q_D(const QNearFieldTarget);
386
387 return d->requestResponse(id);
388}
389
390/*!
391 \internal
392*/
393QNearFieldTarget::QNearFieldTarget(QNearFieldTargetPrivate *backend, QObject *parent)
394: QObject(parent), d_ptr(backend)
395{
396 Q_D(QNearFieldTarget);
397
398 d->q_ptr = this;
399 d->setParent(this);
400
401 qRegisterMetaType<QNearFieldTarget::RequestId>();
402 qRegisterMetaType<QNearFieldTarget::Error>();
403 qRegisterMetaType<QNdefMessage>();
404
405 connect(sender: d, signal: &QNearFieldTargetPrivate::disconnected,
406 context: this, slot: &QNearFieldTarget::disconnected);
407 connect(sender: d, signal: &QNearFieldTargetPrivate::ndefMessageRead,
408 context: this, slot: &QNearFieldTarget::ndefMessageRead);
409 connect(sender: d, signal: &QNearFieldTargetPrivate::requestCompleted,
410 context: this, slot: &QNearFieldTarget::requestCompleted);
411 connect(sender: d, signal: &QNearFieldTargetPrivate::error,
412 context: this, slot: &QNearFieldTarget::error);
413}
414
415QT_END_NAMESPACE
416
417#include "moc_qnearfieldtarget.cpp"
418

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtconnectivity/src/nfc/qnearfieldtarget.cpp