1
/****************************************************************************
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the QtBluetooth module of the Qt Toolkit.
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 Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
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 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
42
#include "qbluetoothsocket.h"
43
#include "qbluetoothsocket_p.h"
45
#include "qbluetoothdeviceinfo.h"
46
#include "qbluetoothserviceinfo.h"
47
#include "qbluetoothservicediscoveryagent.h"
51
#include <QSocketNotifier>
53
QT_BEGIN_NAMESPACE_BLUETOOTH
56
\class QBluetoothSocket
58
\brief The QBluetoothSocket class enables connection to a Bluetooth device
59
running an RFCOMM server.
61
QBluetoothSocket supports two socket types, \l {QBluetoothSocket::L2capSocket}{L2CAP} and
62
\l {QBluetoothSocket::RfcommSocket}{RFCOMM}.
64
\l {QBluetoothSocket::L2capSocket}{L2CAP} is a low level datagram-oriented Bluetooth socket.
66
\l {QBluetoothSocket::RfcommSocket}{RFCOMM} is a reliable, stream-oriented socket. RFCOMM
67
sockets emulate an RS-232 serial port.
69
To create a connection to a Bluetooth service, create a socket of the appropriate type and call
70
connectToService() passing the Bluetooth address and port number. QBluetoothSocket will emit
71
the connected() signal when the connection is established.
77
\enum QBluetoothSocket::SocketType
79
This enum describes the Bluetooth socket type.
81
\value UnknownSocketType Unknown socket type.
82
\value L2capSocket L2CAP socket.
83
\value RfcommSocket RFCOMM socket.
87
\enum QBluetoothSocket::SocketState
89
This enum describes the state of the Bluetooth socket.
91
\value UnconnectedState Socket is not connected.
92
\value ServiceLookupState Socket is querying connection parameters.
93
\value ConnectingState Socket is attempting to connect to a device.
94
\value ConnectedState Socket is connected to a device.
95
\value BoundState Socket is bound to a local address and port.
96
\value ClosingState Socket is connected and will be closed once all pending data is
97
written to the socket.
98
\value ListeningState Socket is listening for incoming connections.
102
\enum QBluetoothSocket::SocketError
104
This enum describes Bluetooth socket error types.
106
\value UnknownSocketError An unknown error has occurred.
107
\value NoSocketError No error. Used for testing.
108
\value ConnectionRefusedError Connection refused or device not available.
109
\value RemoteHostClosedError The remote host closed the socket
110
\value HostNotFoundError Could not find the remote host
111
\value ServiceNotFoundError Could not find the service UUID on remote host
112
\value NetworkError Attempt to read or write from socket returned an error
116
\fn void QBluetoothSocket::connected()
118
This signal is emitted when a connection is established.
120
\sa QBluetoothSocket::ConnectedState, stateChanged()
124
\fn void QBluetoothSocket::disconnected()
126
This signal is emitted when the socket is disconnected.
128
\sa QBluetoothSocket::UnconnectedState, stateChanged()
132
\fn void QBluetoothSocket::error(QBluetoothSocket::SocketError error)
134
This signal is emitted when an \a error occurs.
140
\fn QBluetoothSocket::stateChanged(QBluetoothSocket::SocketState state)
142
This signal is emitted when the socket state changes to \a state.
144
\sa connected(), disconnected(), state(), QBluetoothSocket::SocketState
148
\fn void QBluetoothSocket::abort()
150
Aborts the current connection and resets the socket. Unlike disconnectFromService(), this
151
function immediately closes the socket, discarding any pending data in the write buffer.
153
\sa disconnectFromService(), close()
157
\fn void QBluetoothSocket::close()
159
Disconnects the socket's connection with the device.
163
\fn void QBluetoothSocket::disconnectFromService()
165
Attempts to close the socket. If there is pending data waiting to be written QBluetoothSocket
166
will enter ClosingState and wait until all data has been written. Eventually, it will enter
167
UnconnectedState and emit the disconnected() signal.
169
\sa connectToService()
173
\fn QString QBluetoothSocket::localName() const
175
Returns the name of the local device.
179
\fn QBluetoothAddress QBluetoothSocket::localAddress() const
181
Returns the address of the local device.
185
\fn quint16 QBluetoothSocket::localPort() const
187
Returns the port number of the local socket if available, otherwise returns 0.
191
\fn QString QBluetoothSocket::peerName() const
193
Returns the name of the peer device.
197
\fn QBluetoothAddress QBluetoothSocket::peerAddress() const
199
Returns the address of the peer device.
203
\fn quint16 QBluetoothSocket::peerPort() const
205
Return the port number of the peer socket if available, otherwise returns 0.
209
\fn qint64 QBluetoothSocket::readData(char *data, qint64 maxSize)
215
\fn qint64 QBluetoothSocket::writeData(const char *data, qint64 maxSize)
221
Constructs a Bluetooth socket of \a socketType type, with \a parent.
223
QBluetoothSocket::QBluetoothSocket(QBluetoothSocket::SocketType socketType, QObject *parent)
224
: QIODevice(parent), d_ptr(new QBluetoothSocketPrivate)
228
Q_D(QBluetoothSocket);
229
d->ensureNativeSocket(socketType);
231
setOpenMode(QIODevice::ReadWrite);
235
Constructs a Bluetooth socket with \a parent.
237
QBluetoothSocket::QBluetoothSocket(QObject *parent)
238
: QIODevice(parent), d_ptr(new QBluetoothSocketPrivate)
241
setOpenMode(QIODevice::ReadWrite);
245
Destroys the Bluetooth socket.
247
QBluetoothSocket::~QBluetoothSocket()
256
bool QBluetoothSocket::isSequential() const
262
Returns the number of incoming bytes that are waiting to be read.
264
\sa bytesToWrite(), read()
266
qint64 QBluetoothSocket::bytesAvailable() const
268
Q_D(const QBluetoothSocket);
269
return QIODevice::bytesAvailable() + d->bytesAvailable();
273
Returns the number of bytes that are waiting to be written. The bytes are written when control
274
goes back to the event loop.
276
qint64 QBluetoothSocket::bytesToWrite() const
278
Q_D(const QBluetoothSocket);
279
return d->txBuffer.size();
283
Attempts to connect to the service described by \a service.
285
The socket is opened in the given \a openMode.
287
For BlueZ, the socket first enters ConnectingState and attempts to connect to the device providing
288
\a service. If a connection is established, QBluetoothSocket enters ConnectedState and
291
On QNX the service connection can be established directly using the UUID of the remote service.
293
At any point, the socket can emit error() to siganl that an error occurred.
295
\sa state(), disconnectFromService()
297
void QBluetoothSocket::connectToService(const QBluetoothServiceInfo &service, OpenMode openMode)
299
Q_D(QBluetoothSocket);
300
setOpenMode(openMode);
302
#ifdef QTM_QNX_BLUETOOTH
303
d->connectToService(service.device().address(), service.serviceUuid(), openMode);
305
if (service.protocolServiceMultiplexer() > 0) {
306
if (!d->ensureNativeSocket(L2capSocket)) {
307
emit error(UnknownSocketError);
310
d->connectToService(service.device().address(), service.protocolServiceMultiplexer(), openMode);
311
} else if (service.serverChannel() > 0) {
312
if (!d->ensureNativeSocket(RfcommSocket)) {
313
emit error(UnknownSocketError);
316
d->connectToService(service.device().address(), service.serverChannel(), openMode);
318
// try doing service discovery to see if we can find the socket
319
if(service.serviceUuid().isNull()){
320
qWarning() << "No port, no PSM, and no UUID provided, unable to connect";
323
qDebug() << "Need a port/psm, doing discovery";
324
doDeviceDiscovery(service, openMode);
330
Attempts to make a connection to the service identified by \a uuid on the device with address
333
The socket is opened in the given \a openMode.
335
For BlueZ, the socket first enters the ServiceLookupState and queries the connection parameters for
336
\a uuid. If the service parameters are successfully retrieved the socket enters
337
ConnectingState, and attempts to connect to \a address. If a connection is established,
338
QBluetoothSocket enters Connected State and emits connected().
340
On QNX the service connection can be established directly using the UUID of the remote service.
342
At any point, the socket can emit error() to signal that an error occurred.
344
\sa state(), disconnectFromService()
346
void QBluetoothSocket::connectToService(const QBluetoothAddress &address, const QBluetoothUuid &uuid, OpenMode openMode)
348
#ifdef QTM_QNX_BLUETOOTH
349
Q_D(QBluetoothSocket);
350
d->connectToService(address, uuid, openMode);
352
QBluetoothServiceInfo service;
353
QBluetoothDeviceInfo device(address, QString(), QBluetoothDeviceInfo::MiscellaneousDevice);
354
service.setDevice(device);
355
service.setServiceUuid(uuid);
356
doDeviceDiscovery(service, openMode);
361
Attempts to make a connection with \a address on the given \a port.
363
The socket is opened in the given \a openMode.
365
The socket first enters ConnectingState, and attempts to connect to \a address. If a
366
connection is established, QBluetoothSocket enters ConnectedState and emits connected().
368
At any point, the socket can emit error() to signal that an error occurred.
370
On QNX a connection to a service can not be established using a port.
372
\sa state(), disconnectFromService()
374
void QBluetoothSocket::connectToService(const QBluetoothAddress &address, quint16 port, OpenMode openMode)
376
#ifdef QTM_QNX_BLUETOOTH
380
qWarning("Connecting to port is not supported on QNX");
382
Q_D(QBluetoothSocket);
383
setOpenMode(openMode);
384
d->connectToService(address, port, openMode);
389
Returns the socket type.
391
QBluetoothSocket::SocketType QBluetoothSocket::socketType() const
393
Q_D(const QBluetoothSocket);
394
return d->socketType;
398
Returns the current state of the socket.
400
QBluetoothSocket::SocketState QBluetoothSocket::state() const
402
Q_D(const QBluetoothSocket);
407
Returns the last error.
409
QBluetoothSocket::SocketError QBluetoothSocket::error() const
411
Q_D(const QBluetoothSocket);
412
return d->socketError;
416
Returns a user displayable text string for the error.
418
QString QBluetoothSocket::errorString() const
420
Q_D(const QBluetoothSocket);
421
return d->errorString;
425
Sets the socket state to \a state.
427
void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state)
429
Q_D(QBluetoothSocket);
430
SocketState old = d->state;
433
emit stateChanged(state);
434
if(state == ListeningState){
435
// TODO: look at this, is this really correct?
436
// if we're a listening socket we can't handle connects?
437
if (d->readNotifier) {
438
d->readNotifier->setEnabled(false);
444
Returns true if you can read at least one line from the device
447
bool QBluetoothSocket::canReadLine() const
449
Q_D(const QBluetoothSocket);
450
return d->buffer.canReadLine() || QIODevice::canReadLine();
454
Sets the type of error that last occurred to \a error_.
456
void QBluetoothSocket::setSocketError(QBluetoothSocket::SocketError error_)
458
Q_D(QBluetoothSocket);
459
d->socketError = error_;
464
Start device discovery for \a service and open the socket with \a openMode. If the socket
465
is created with a service uuid device address, use service discovery to find the
466
port number to connect to.
469
void QBluetoothSocket::doDeviceDiscovery(const QBluetoothServiceInfo &service, OpenMode openMode)
471
Q_D(QBluetoothSocket);
473
qDebug() << "Starting discovery";
475
if(d->discoveryAgent) {
476
delete d->discoveryAgent;
479
d->discoveryAgent = new QBluetoothServiceDiscoveryAgent(service.device().address(),this);
481
qDebug() << "Got agent";
483
connect(d->discoveryAgent, SIGNAL(serviceDiscovered(QBluetoothServiceInfo)), this, SLOT(serviceDiscovered(QBluetoothServiceInfo)));
484
connect(d->discoveryAgent, SIGNAL(finished()), this, SLOT(discoveryFinished()));
486
d->openMode = openMode;
488
if(!service.serviceUuid().isNull())
489
d->discoveryAgent->setUuidFilter(service.serviceUuid());
491
if(!service.serviceClassUuids().isEmpty())
492
d->discoveryAgent->setUuidFilter(service.serviceClassUuids());
494
// we have to ID the service somehow
495
Q_ASSERT(!d->discoveryAgent->uuidFilter().isEmpty());
497
qDebug() << "UUID filter" << d->discoveryAgent->uuidFilter();
499
d->discoveryAgent->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
502
void QBluetoothSocket::serviceDiscovered(const QBluetoothServiceInfo &service)
504
Q_D(QBluetoothSocket);
505
qDebug() << "FOUND SERVICE!" << service;
506
if(service.protocolServiceMultiplexer() != 0 || service.serverChannel() != 0) {
507
connectToService(service, d->openMode);
508
d->discoveryAgent->deleteLater();
509
d->discoveryAgent = 0;
513
void QBluetoothSocket::discoveryFinished()
515
qDebug() << "Socket discovery finished";
516
Q_D(QBluetoothSocket);
517
if(d->discoveryAgent){
518
qDebug() << "Didn't find any";
519
emit error(QBluetoothSocket::ServiceNotFoundError);
520
d->discoveryAgent->deleteLater();
521
d->discoveryAgent = 0;
525
void QBluetoothSocket::abort()
527
Q_D(QBluetoothSocket);
529
setSocketState(QBluetoothSocket::UnconnectedState);
532
void QBluetoothSocket::disconnectFromService()
534
// TODO: is this all we need to do?
535
Q_D(QBluetoothSocket);
539
QString QBluetoothSocket::localName() const
541
Q_D(const QBluetoothSocket);
542
return d->localName();
545
QBluetoothAddress QBluetoothSocket::localAddress() const
547
Q_D(const QBluetoothSocket);
548
return d->localAddress();
551
quint16 QBluetoothSocket::localPort() const
553
Q_D(const QBluetoothSocket);
554
return d->localPort();
557
QString QBluetoothSocket::peerName() const
559
Q_D(const QBluetoothSocket);
560
return d->peerName();
563
QBluetoothAddress QBluetoothSocket::peerAddress() const
565
Q_D(const QBluetoothSocket);
566
return d->peerAddress();
569
quint16 QBluetoothSocket::peerPort() const
571
Q_D(const QBluetoothSocket);
572
return d->peerPort();
575
qint64 QBluetoothSocket::writeData(const char *data, qint64 maxSize)
577
Q_D(QBluetoothSocket);
578
return d->writeData(data, maxSize);
581
qint64 QBluetoothSocket::readData(char *data, qint64 maxSize)
583
Q_D(QBluetoothSocket);
584
return d->readData(data, maxSize);
587
void QBluetoothSocket::close()
589
Q_D(QBluetoothSocket);
590
setSocketState(ClosingState);
594
setSocketState(UnconnectedState);
598
Set the socket to use \a socketDescriptor with a type of \a socketType,
599
which is in state, \a socketState, and mode, \a openMode.
601
Returns true on success
605
bool QBluetoothSocket::setSocketDescriptor(int socketDescriptor, SocketType socketType,
606
SocketState socketState, OpenMode openMode)
608
Q_D(QBluetoothSocket);
609
return d->setSocketDescriptor(socketDescriptor, socketType, socketState, openMode);
613
Returns the platform-specific socket descriptor, if available.
616
int QBluetoothSocket::socketDescriptor() const
618
Q_D(const QBluetoothSocket);
624
#ifndef QT_NO_DEBUG_STREAM
625
QDebug operator<<(QDebug debug, QBluetoothSocket::SocketError error)
628
case QBluetoothSocket::UnknownSocketError:
629
debug << "QBluetoothSocket::UnknownSocketError";
631
case QBluetoothSocket::ConnectionRefusedError:
632
debug << "QBluetoothSocket::ConnectionRefusedError";
634
case QBluetoothSocket::RemoteHostClosedError:
635
debug << "QBluetoothSocket::RemoteHostClosedError";
637
case QBluetoothSocket::HostNotFoundError:
638
debug << "QBluetoothSocket::HostNotFoundError";
640
case QBluetoothSocket::ServiceNotFoundError:
641
debug << "QBluetoothSocket::ServiceNotFoundError";
643
case QBluetoothSocket::NetworkError:
644
debug << "QBluetoothSocket::NetworkError";
647
debug << "QBluetoothSocket::SocketError(" << (int)error << ")";
652
QDebug operator<<(QDebug debug, QBluetoothSocket::SocketState state)
655
case QBluetoothSocket::UnconnectedState:
656
debug << "QBluetoothSocket::UnconnectedState";
658
case QBluetoothSocket::ConnectingState:
659
debug << "QBluetoothSocket::ConnectingState";
661
case QBluetoothSocket::ConnectedState:
662
debug << "QBluetoothSocket::ConnectedState";
664
case QBluetoothSocket::BoundState:
665
debug << "QBluetoothSocket::BoundState";
667
case QBluetoothSocket::ClosingState:
668
debug << "QBluetoothSocket::ClosingState";
670
case QBluetoothSocket::ListeningState:
671
debug << "QBluetoothSocket::ListeningState";
674
debug << "QBluetoothSocket::SocketState(" << (int)state << ")";
680
#include "moc_qbluetoothsocket.cpp"
682
QT_END_NAMESPACE_BLUETOOTH