| 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 | */ |
| 120 | QLlcpSocket::QLlcpSocket(QObject *parent) |
| 121 | : QIODevice(parent), d_ptr(new QLlcpSocketPrivate(this)) |
| 122 | { |
| 123 | setOpenMode(QIODevice::NotOpen); |
| 124 | } |
| 125 | |
| 126 | /*! |
| 127 | \internal |
| 128 | */ |
| 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 | */ |
| 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 | */ |
| 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 | */ |
| 157 | void QLlcpSocket::disconnectFromService() |
| 158 | { |
| 159 | Q_D(QLlcpSocket); |
| 160 | |
| 161 | d->disconnectFromService(); |
| 162 | } |
| 163 | |
| 164 | /*! |
| 165 | Disconnects the socket. |
| 166 | */ |
| 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 | */ |
| 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 | */ |
| 192 | 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 | */ |
| 205 | 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 | */ |
| 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 | */ |
| 228 | 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 | */ |
| 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 | */ |
| 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 | */ |
| 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 | */ |
| 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 | */ |
| 295 | 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 | */ |
| 305 | QLlcpSocket::SocketState QLlcpSocket::state() const |
| 306 | { |
| 307 | Q_D(const QLlcpSocket); |
| 308 | |
| 309 | return d->state(); |
| 310 | } |
| 311 | |
| 312 | /*! |
| 313 | \reimp |
| 314 | */ |
| 315 | qint64 QLlcpSocket::bytesAvailable() const |
| 316 | { |
| 317 | Q_D(const QLlcpSocket); |
| 318 | |
| 319 | return d->bytesAvailable() + QIODevice::bytesAvailable(); |
| 320 | } |
| 321 | |
| 322 | /*! |
| 323 | \reimp |
| 324 | */ |
| 325 | bool QLlcpSocket::canReadLine() const |
| 326 | { |
| 327 | Q_D(const QLlcpSocket); |
| 328 | |
| 329 | return d->canReadLine() || QIODevice::canReadLine(); |
| 330 | } |
| 331 | |
| 332 | /*! |
| 333 | \reimp |
| 334 | */ |
| 335 | bool QLlcpSocket::waitForReadyRead(int msecs) |
| 336 | { |
| 337 | Q_D(QLlcpSocket); |
| 338 | |
| 339 | return d->waitForReadyRead(msecs); |
| 340 | } |
| 341 | |
| 342 | /*! |
| 343 | \reimp |
| 344 | */ |
| 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 | */ |
| 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 | */ |
| 373 | bool QLlcpSocket::waitForDisconnected(int msecs) |
| 374 | { |
| 375 | Q_D(QLlcpSocket); |
| 376 | |
| 377 | return d->waitForDisconnected(msecs); |
| 378 | } |
| 379 | |
| 380 | /*! |
| 381 | \internal |
| 382 | */ |
| 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 | */ |
| 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 | |