1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtNfc module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qllcpsocket_p.h"
41 
42 #if defined(QT_SIMULATOR)
43 #include "qllcpsocket_simulator_p.h"
44 #else
45 #include "qllcpsocket_p_p.h"
46 #endif
47 
48 QT_BEGIN_NAMESPACE
49 
50 /*!
51     \class QLlcpSocket
52     \brief The QLlcpSocket class provides an NFC LLCP socket.
53     \internal
54 
55     \ingroup connectivity-nfc
56     \inmodule QtNfc
57 
58     NFC LLCP protocol is a peer-to-peer communication protocol between two NFC compliant devices.
59 */
60 
61 /*!
62     \enum QLlcpSocket::SocketError
63 
64     This enum describes the errors that can occur. The most recent error can be retrieved through a
65     call to error().
66 
67     \value UnknownSocketError       An unidentified error has occurred.
68     \value RemoteHostClosedError    The remote host closed the connection.
69     \value SocketAccessError        The socket operation failed because the application lacked the
70                                     required privileges.
71     \value SocketResourceError      The local system ran out of resources (e.g., too many sockets).
72 */
73 
74 /*!
75     \enum QLlcpSocket::SocketState
76 
77     This enum describes the different state in which a socket can be.
78 
79     \value UnconnectedState The socket is not connected.
80     \value ConnectingState  The socket has started establishing a connection.
81     \value ConnectedState   A connection is established.
82     \value ClosingState     The socket is about to close.
83     \value BoundState       The socket is bound to a local port (for servers).
84     \value ListeningState   The socket is listening for incoming connections (for internal use).
85 */
86 
87 /*!
88     \fn QLlcpSocket::connected()
89 
90     This signal is emitted after connectToService() has been called and a connection has been
91     successfully established.
92 
93     \sa connectToService(), disconnected()
94 */
95 
96 /*!
97     \fn QLlcpSocket::disconnected()
98 
99     This signal is emitted when the socket has been disconnected.
100 
101     \sa disconnectFromService(),
102 */
103 
104 /*!
105     \fn QLlcpSocket::error(QLlcpSocket::SocketError socketError)
106 
107     This signal is emitted when an error occurs. The \a socketError parameter describes the error.
108 */
109 
110 /*!
111     \fn QLlcpSocket::stateChanged(QLlcpSocket::SocketState socketState)
112 
113     This signal is emitted when the state of the socket changes. The \a socketState parameter
114     describes the new state.
115 */
116 
117 /*!
118     Construct a new unconnected LLCP socket with \a parent.
119 */
QLlcpSocket(QObject * parent)120 QLlcpSocket::QLlcpSocket(QObject *parent)
121 :   QIODevice(parent), d_ptr(new QLlcpSocketPrivate(this))
122 {
123     setOpenMode(QIODevice::NotOpen);
124 }
125 
126 /*!
127     \internal
128 */
QLlcpSocket(QLlcpSocketPrivate * d,QObject * parent)129 QLlcpSocket::QLlcpSocket(QLlcpSocketPrivate *d, QObject *parent)
130 :   QIODevice(parent), d_ptr(d)
131 {
132     setOpenMode(QIODevice::ReadWrite);
133     d_ptr->q_ptr = this;
134 }
135 
136 /*!
137     Destroys the LLCP socket.
138 */
~QLlcpSocket()139 QLlcpSocket::~QLlcpSocket()
140 {
141     delete d_ptr;
142 }
143 
144 /*!
145     Connects to the service identified by the URI \a serviceUri on \a target.
146 */
connectToService(QNearFieldTarget * target,const QString & serviceUri)147 void QLlcpSocket::connectToService(QNearFieldTarget *target, const QString &serviceUri)
148 {
149     Q_D(QLlcpSocket);
150 
151     d->connectToService(target, serviceUri);
152 }
153 
154 /*!
155     Disconnects the socket.
156 */
disconnectFromService()157 void QLlcpSocket::disconnectFromService()
158 {
159     Q_D(QLlcpSocket);
160 
161     d->disconnectFromService();
162 }
163 
164 /*!
165     Disconnects the socket.
166 */
close()167 void QLlcpSocket::close()
168 {
169     Q_D(QLlcpSocket);
170 
171     QIODevice::close();
172 
173     d->disconnectFromService();
174 }
175 
176 /*!
177     Binds the LLCP socket to local \a port. Returns true on success; otherwise returns false.
178 */
bind(quint8 port)179 bool QLlcpSocket::bind(quint8 port)
180 {
181     Q_D(QLlcpSocket);
182 
183     return d->bind(port);
184 }
185 
186 /*!
187     Returns true if at least one datagram (service data units) is waiting to be read; otherwise
188     returns false.
189 
190     \sa pendingDatagramSize(), readDatagram()
191 */
hasPendingDatagrams() const192 bool QLlcpSocket::hasPendingDatagrams() const
193 {
194     Q_D(const QLlcpSocket);
195 
196     return d->hasPendingDatagrams();
197 }
198 
199 /*!
200     Returns the size of the first pending datagram (service data unit). If there is no datagram
201     available, this function returns -1.
202 
203     \sa hasPendingDatagrams(), readDatagram()
204 */
pendingDatagramSize() const205 qint64 QLlcpSocket::pendingDatagramSize() const
206 {
207     Q_D(const QLlcpSocket);
208 
209     return d->pendingDatagramSize();
210 }
211 
212 /*!
213     Sends the datagram at \a data of size \a size to the service that this socket is connected to.
214     Returns the number of bytes sent on success; otherwise return -1;
215 */
writeDatagram(const char * data,qint64 size)216 qint64 QLlcpSocket::writeDatagram(const char *data, qint64 size)
217 {
218     Q_D(QLlcpSocket);
219 
220     return d->writeDatagram(data, size);
221 }
222 
223 /*!
224     \reimp
225 
226     Always returns true.
227 */
isSequential() const228 bool QLlcpSocket::isSequential() const
229 {
230     return true;
231 }
232 
233 /*!
234     \overload
235 
236     Sends the datagram \a datagram to the service that this socket is connected to.
237 */
writeDatagram(const QByteArray & datagram)238 qint64 QLlcpSocket::writeDatagram(const QByteArray &datagram)
239 {
240     Q_D(QLlcpSocket);
241 
242     return d->writeDatagram(datagram);
243 }
244 
245 /*!
246     Receives a datagram no larger than \a maxSize bytes and stores it in \a data. The sender's
247     details are stored in \a target and \a port (unless the pointers are 0).
248 
249     Returns the size of the datagram on success; otherwise returns -1.
250 
251     If maxSize is too small, the rest of the datagram will be lost. To avoid loss of data, call
252     pendingDatagramSize() to determine the size of the pending datagram before attempting to read
253     it. If maxSize is 0, the datagram will be discarded.
254 
255     \sa writeDatagram(), hasPendingDatagrams(), pendingDatagramSize()
256 */
readDatagram(char * data,qint64 maxSize,QNearFieldTarget ** target,quint8 * port)257 qint64 QLlcpSocket::readDatagram(char *data, qint64 maxSize, QNearFieldTarget **target,
258                                  quint8 *port)
259 {
260     Q_D(QLlcpSocket);
261 
262     return d->readDatagram(data, maxSize, target, port);
263 }
264 
265 /*!
266     Sends the datagram at \a data of size \a size to the service identified by the URI
267     \a port on \a target. Returns the number of bytes sent on success; otherwise returns -1.
268 
269     \sa readDatagram()
270 */
writeDatagram(const char * data,qint64 size,QNearFieldTarget * target,quint8 port)271 qint64 QLlcpSocket::writeDatagram(const char *data, qint64 size, QNearFieldTarget *target,
272                                   quint8 port)
273 {
274     Q_D(QLlcpSocket);
275 
276     return d->writeDatagram(data, size, target, port);
277 }
278 
279 /*!
280     \overload
281 
282     Sends the datagram \a datagram to the service identified by the URI \a port on \a target.
283 */
writeDatagram(const QByteArray & datagram,QNearFieldTarget * target,quint8 port)284 qint64 QLlcpSocket::writeDatagram(const QByteArray &datagram, QNearFieldTarget *target,
285                                   quint8 port)
286 {
287     Q_D(QLlcpSocket);
288 
289     return d->writeDatagram(datagram, target, port);
290 }
291 
292 /*!
293     Returns the type of error that last occurred.
294 */
error() const295 QLlcpSocket::SocketError QLlcpSocket::error() const
296 {
297     Q_D(const QLlcpSocket);
298 
299     return d->error();
300 }
301 
302 /*!
303     Returns the state of the socket.
304 */
state() const305 QLlcpSocket::SocketState QLlcpSocket::state() const
306 {
307     Q_D(const QLlcpSocket);
308 
309     return d->state();
310 }
311 
312 /*!
313     \reimp
314 */
bytesAvailable() const315 qint64 QLlcpSocket::bytesAvailable() const
316 {
317     Q_D(const QLlcpSocket);
318 
319     return d->bytesAvailable() + QIODevice::bytesAvailable();
320 }
321 
322 /*!
323     \reimp
324 */
canReadLine() const325 bool QLlcpSocket::canReadLine() const
326 {
327     Q_D(const QLlcpSocket);
328 
329     return d->canReadLine() || QIODevice::canReadLine();
330 }
331 
332 /*!
333     \reimp
334 */
waitForReadyRead(int msecs)335 bool QLlcpSocket::waitForReadyRead(int msecs)
336 {
337     Q_D(QLlcpSocket);
338 
339     return d->waitForReadyRead(msecs);
340 }
341 
342 /*!
343     \reimp
344 */
waitForBytesWritten(int msecs)345 bool QLlcpSocket::waitForBytesWritten(int msecs)
346 {
347     Q_D(QLlcpSocket);
348 
349     return d->waitForBytesWritten(msecs);
350 }
351 
352 /*!
353     Waits until the socket is connected, up to \a msecs milliseconds. If the connection has been
354     established, this function returns true; otherwise it returns false. In the case where it
355     returns false, you can call error() to determine the cause of the error.
356 
357     If msecs is -1, this function will not time out.
358 */
waitForConnected(int msecs)359 bool QLlcpSocket::waitForConnected(int msecs)
360 {
361     Q_D(QLlcpSocket);
362 
363     return d->waitForConnected(msecs);
364 }
365 
366 /*!
367     Waits until the socket is disconnected, up to \a msecs milliseconds. If the connection has been
368     disconnected, this function returns true; otherwise it returns false. In the case where it
369     returns false, you can call error() to determine the cause of the error.
370 
371     If msecs is -1, this function will not time out.
372 */
waitForDisconnected(int msecs)373 bool QLlcpSocket::waitForDisconnected(int msecs)
374 {
375     Q_D(QLlcpSocket);
376 
377     return d->waitForDisconnected(msecs);
378 }
379 
380 /*!
381     \internal
382 */
readData(char * data,qint64 maxlen)383 qint64 QLlcpSocket::readData(char *data, qint64 maxlen)
384 {
385     Q_D(QLlcpSocket);
386 
387     return d->readData(data, maxlen);
388 }
389 
390 /*!
391     \internal
392 */
writeData(const char * data,qint64 len)393 qint64 QLlcpSocket::writeData(const char *data, qint64 len)
394 {
395     Q_D(QLlcpSocket);
396 
397     return d->writeData(data, len);
398 }
399 
400 QT_END_NAMESPACE
401