summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabian Bumberger <fbumberger@rim.com>2013-09-20 15:29:39 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-20 17:47:15 +0200
commitc231e60cd3aa982b10512c5c23bbca04223ed407 (patch)
treefabf340c905e4237d466f28e17e7dd83e664f804
parentac2edceb02a61c1d670312385b1d709417961799 (diff)
Error handling for QBluetoothServer
Task-number: QTBUG-32669 Change-Id: I0f12b19f7989972b7c8305f6e11a95f7f25a281d Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
-rw-r--r--src/bluetooth/qbluetoothserver.cpp32
-rw-r--r--src/bluetooth/qbluetoothserver.h11
-rw-r--r--src/bluetooth/qbluetoothserver_bluez.cpp28
-rw-r--r--src/bluetooth/qbluetoothserver_p.cpp5
-rw-r--r--src/bluetooth/qbluetoothserver_p.h1
-rw-r--r--src/bluetooth/qbluetoothserver_qnx.cpp27
-rw-r--r--src/bluetooth/qbluetoothsocket.cpp8
-rw-r--r--src/bluetooth/qbluetoothsocket.h2
-rw-r--r--src/imports/bluetooth/qdeclarativebluetoothsocket.cpp2
-rw-r--r--src/imports/bluetooth/qdeclarativebluetoothsocket_p.h2
-rw-r--r--tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp4
-rw-r--r--tests/auto/qrfcommserver/tst_qrfcommserver.cpp17
12 files changed, 109 insertions, 30 deletions
diff --git a/src/bluetooth/qbluetoothserver.cpp b/src/bluetooth/qbluetoothserver.cpp
index 3cf99bc9..6cb9ba01 100644
--- a/src/bluetooth/qbluetoothserver.cpp
+++ b/src/bluetooth/qbluetoothserver.cpp
@@ -80,12 +80,34 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn void QBluetoothServer::error(QBluetoothServer::Error error)
+
+ This signal is emitted when an \a error occurs.
+
+ \sa error(), QBluetoothServer::Error
+*/
+
+/*!
\fn void QBluetoothServer::close()
Closes and resets the listening socket.
*/
/*!
+ \enum QBluetoothServer::Error
+
+ This enum describes Bluetooth server error types.
+
+ \value NoError No error.
+ \value UnknownError An unknown error occurred.
+ \value PoweredOffError The Bluetooth adapter is powered off.
+ \value InputOutputError An input output error occurred.
+ \value ServiceAlreadyRegisteredError The service or port was already registered
+ \value UnsupportedProtocolError The \l {QBluetoothServiceInfo::Protocol}{Protocol} is not
+ supported on this platform.
+*/
+
+/*!
\fn bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
Start listening for incoming connections to \a address on \a port.
@@ -253,6 +275,16 @@ QBluetoothServiceInfo::Protocol QBluetoothServer::serverType() const
return d->serverType;
}
+/*!
+ \fn QBluetoothServer::Error QBluetoothServer::error() const
+ Returns the last error of the QBluetoothServer.
+*/
+QBluetoothServer::Error QBluetoothServer::error() const
+{
+ Q_D(const QBluetoothServer);
+ return d->m_lastError;
+}
+
#include "moc_qbluetoothserver.cpp"
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothserver.h b/src/bluetooth/qbluetoothserver.h
index ad651667..d4468cb6 100644
--- a/src/bluetooth/qbluetoothserver.h
+++ b/src/bluetooth/qbluetoothserver.h
@@ -62,6 +62,14 @@ class Q_BLUETOOTH_EXPORT QBluetoothServer : public QObject
Q_OBJECT
public:
+ enum Error {
+ NoError,
+ UnknownError,
+ PoweredOffError,
+ InputOutputError,
+ ServiceAlreadyRegisteredError,
+ UnsupportedProtocolError
+ };
QBluetoothServer(QBluetoothServiceInfo::Protocol serverType, QObject *parent = 0);
~QBluetoothServer();
@@ -85,8 +93,11 @@ public:
QBluetoothServiceInfo::Protocol serverType() const;
+ Error error() const;
+
Q_SIGNALS:
void newConnection();
+ void error(Error);
protected:
QBluetoothServerPrivate *d_ptr;
diff --git a/src/bluetooth/qbluetoothserver_bluez.cpp b/src/bluetooth/qbluetoothserver_bluez.cpp
index 5e1fc701..83d0b073 100644
--- a/src/bluetooth/qbluetoothserver_bluez.cpp
+++ b/src/bluetooth/qbluetoothserver_bluez.cpp
@@ -66,12 +66,13 @@ static inline void convertAddress(quint64 from, quint8 (&to)[6])
}
QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType)
- : maxPendingConnections(1), serverType(sType), socketNotifier(0)
+ : maxPendingConnections(1), serverType(sType), m_lastError(QBluetoothServer::NoError),
+ socketNotifier(0)
{
if (sType == QBluetoothServiceInfo::RfcommProtocol)
socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
else
- socket = new QBluetoothSocket(QBluetoothServiceInfo::L2capProtocol);
+ socket = new QBluetoothSocket(QBluetoothServiceInfo::L2capProtocol);
}
QBluetoothServerPrivate::~QBluetoothServerPrivate()
@@ -104,8 +105,10 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
Q_D(QBluetoothServer);
int sock = d->socket->socketDescriptor();
- if (sock < 0)
+ if (sock < 0) {
+ d->m_lastError = InputOutputError;
return false;
+ }
if (d->serverType == QBluetoothServiceInfo::RfcommProtocol) {
sockaddr_rc addr;
@@ -119,8 +122,11 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
convertAddress(Q_UINT64_C(0), addr.rc_bdaddr.b);
- if (::bind(sock, reinterpret_cast<sockaddr *>(&addr), sizeof(sockaddr_rc)) < 0)
+ if (::bind(sock, reinterpret_cast<sockaddr *>(&addr), sizeof(sockaddr_rc)) < 0) {
+ d->m_lastError = InputOutputError;
+ emit error(d->m_lastError);
return false;
+ }
} else {
sockaddr_l2 addr;
@@ -133,12 +139,18 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
else
convertAddress(Q_UINT64_C(0), addr.l2_bdaddr.b);
- if (::bind(sock, reinterpret_cast<sockaddr *>(&addr), sizeof(sockaddr_l2)) < 0)
+ if (::bind(sock, reinterpret_cast<sockaddr *>(&addr), sizeof(sockaddr_l2)) < 0) {
+ d->m_lastError = InputOutputError;
+ emit error(d->m_lastError);
return false;
+ }
}
- if (::listen(sock, d->maxPendingConnections) < 0)
+ if (::listen(sock, d->maxPendingConnections) < 0) {
+ d->m_lastError = InputOutputError;
+ emit error(d->m_lastError);
return false;
+ }
d->socket->setSocketState(QBluetoothSocket::ListeningState);
@@ -244,6 +256,8 @@ void QBluetoothServer::setSecurityFlags(QBluetooth::SecurityFlags security)
if (setsockopt(d->socket->socketDescriptor(), SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0){
qWarning() << "Failed to set socket option, closing socket for safety" << errno;
qWarning() << "Error: " << strerror(errno);
+ d->m_lastError = InputOutputError;
+ emit error(d->m_lastError);
d->socket->close();
}
} else {
@@ -259,6 +273,8 @@ void QBluetoothServer::setSecurityFlags(QBluetooth::SecurityFlags security)
if (setsockopt(d->socket->socketDescriptor(), SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0){
qWarning() << "Failed to set socket option, closing socket for safety" << errno;
qWarning() << "Error: " << strerror(errno);
+ d->m_lastError = InputOutputError;
+ emit error(d->m_lastError);
d->socket->close();
}
}
diff --git a/src/bluetooth/qbluetoothserver_p.cpp b/src/bluetooth/qbluetoothserver_p.cpp
index 1a123c4d..213d73f1 100644
--- a/src/bluetooth/qbluetoothserver_p.cpp
+++ b/src/bluetooth/qbluetoothserver_p.cpp
@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType)
- : serverType(sType)
+ : serverType(sType), m_lastError(QBluetoothServer::NoError)
{
}
@@ -62,6 +62,9 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
{
Q_UNUSED(address);
Q_UNUSED(port);
+ Q_D(QBluetoothServer);
+ d->m_lastError = UnsupportedProtocolError;
+ emit error(d->m_lastError);
return false;
}
diff --git a/src/bluetooth/qbluetoothserver_p.h b/src/bluetooth/qbluetoothserver_p.h
index b9847aaf..29055fbd 100644
--- a/src/bluetooth/qbluetoothserver_p.h
+++ b/src/bluetooth/qbluetoothserver_p.h
@@ -97,6 +97,7 @@ protected:
QBluetoothServer *q_ptr;
private:
+ QBluetoothServer::Error m_lastError;
#ifdef QT_QNX_BLUETOOTH
QBluetoothUuid m_uuid;
bool serverRegistered;
diff --git a/src/bluetooth/qbluetoothserver_qnx.cpp b/src/bluetooth/qbluetoothserver_qnx.cpp
index bc222b85..d937a275 100644
--- a/src/bluetooth/qbluetoothserver_qnx.cpp
+++ b/src/bluetooth/qbluetoothserver_qnx.cpp
@@ -54,7 +54,8 @@ QT_BEGIN_NAMESPACE
extern QHash<QBluetoothServerPrivate*, int> __fakeServerPorts;
QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType)
- : socket(0),maxPendingConnections(1),securityFlags(QBluetooth::NoSecurity), serverType(sType)
+ : socket(0),maxPendingConnections(1), securityFlags(QBluetooth::NoSecurity), serverType(sType),
+ m_lastError(QBluetoothServer::NoError)
{
ppsRegisterControl();
}
@@ -79,10 +80,16 @@ void QBluetoothServerPrivate::controlReply(ppsResult result)
int socketFD = ::open(result.dat.first().toStdString().c_str(), O_RDWR | O_NONBLOCK);
if (socketFD == -1) {
+ m_lastError = QBluetoothServer::InputOutputError;
+ emit q->error(m_lastError);
qWarning() << Q_FUNC_INFO << "RFCOMM Server: Could not open socket FD" << errno;
} else {
- if (!socket)
+ if (!socket) { // Should never happen
+ qWarning() << "Socket not valid";
+ m_lastError = QBluetoothServer::UnknownError;
+ emit q->error(m_lastError);
return;
+ }
socket->setSocketDescriptor(socketFD, QBluetoothServiceInfo::RfcommProtocol,
QBluetoothSocket::ConnectedState);
@@ -97,6 +104,7 @@ void QBluetoothServerPrivate::controlReply(ppsResult result)
void QBluetoothServerPrivate::controlEvent(ppsResult result)
{
+ Q_Q(QBluetoothServer);
if (result.msg == QStringLiteral("service_connected")) {
qBBBluetoothDebug() << "SPP: Server: Sending request for mount point path";
qBBBluetoothDebug() << result.dat;
@@ -113,6 +121,8 @@ void QBluetoothServerPrivate::controlEvent(ppsResult result)
ppsSendControlMessage("get_mount_point_path", 0x1101, m_uuid, nextClientAddress,
m_serviceName, this, BT_SPP_SERVER_SUBTYPE);
} else {
+ m_lastError = QBluetoothServer::InputOutputError;
+ emit q->error(m_lastError);
qWarning() << Q_FUNC_INFO << "address not specified in service connect reply";
}
}
@@ -122,8 +132,8 @@ void QBluetoothServer::close()
{
Q_D(QBluetoothServer);
if (!d->socket) {
- // there is no way to propagate the error to user
- // so just ignore the problem ;)
+ d->m_lastError = UnknownError;
+ emit error(d->m_lastError);
return;
}
d->socket->close();
@@ -137,10 +147,13 @@ void QBluetoothServer::close()
bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
{
Q_UNUSED(address)
- if (serverType() != QBluetoothServiceInfo::RfcommProtocol)
+ Q_D(QBluetoothServer);
+ if (serverType() != QBluetoothServiceInfo::RfcommProtocol) {
+ d->m_lastError = UnsupportedProtocolError;
+ emit error(d->m_lastError);
return false;
+ }
- Q_D(QBluetoothServer);
// listen has already been called before
if (d->socket && d->socket->state() == QBluetoothSocket::ListeningState)
return true;
@@ -164,6 +177,8 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
qBBBluetoothDebug() << "Port" << port << "registered";
} else {
qWarning() << "server with port" << port << "already registered or port invalid";
+ d->m_lastError = ServiceAlreadyRegisteredError;
+ emit error(d->m_lastError);
return false;
}
diff --git a/src/bluetooth/qbluetoothsocket.cpp b/src/bluetooth/qbluetoothsocket.cpp
index 5bd01730..38697756 100644
--- a/src/bluetooth/qbluetoothsocket.cpp
+++ b/src/bluetooth/qbluetoothsocket.cpp
@@ -98,8 +98,6 @@ QT_BEGIN_NAMESPACE
\value UnknownSocketError An unknown error has occurred.
\value NoSocketError No error. Used for testing.
- \value ConnectionRefusedError Connection refused or device not available.
- \value RemoteHostClosedError The remote host closed the socket.
\value HostNotFoundError Could not find the remote host.
\value ServiceNotFoundError Could not find the service UUID on remote host.
\value NetworkError Attempt to read or write from socket returned an error
@@ -641,12 +639,6 @@ QDebug operator<<(QDebug debug, QBluetoothSocket::SocketError error)
case QBluetoothSocket::UnknownSocketError:
debug << "QBluetoothSocket::UnknownSocketError";
break;
- case QBluetoothSocket::ConnectionRefusedError:
- debug << "QBluetoothSocket::ConnectionRefusedError";
- break;
- case QBluetoothSocket::RemoteHostClosedError:
- debug << "QBluetoothSocket::RemoteHostClosedError";
- break;
case QBluetoothSocket::HostNotFoundError:
debug << "QBluetoothSocket::HostNotFoundError";
break;
diff --git a/src/bluetooth/qbluetoothsocket.h b/src/bluetooth/qbluetoothsocket.h
index 055508a2..cc580d0b 100644
--- a/src/bluetooth/qbluetoothsocket.h
+++ b/src/bluetooth/qbluetoothsocket.h
@@ -79,8 +79,6 @@ public:
enum SocketError {
NoSocketError = -2,
UnknownSocketError = QAbstractSocket::UnknownSocketError,
- ConnectionRefusedError = QAbstractSocket::ConnectionRefusedError,
- RemoteHostClosedError = QAbstractSocket::RemoteHostClosedError,
HostNotFoundError = QAbstractSocket::HostNotFoundError,
ServiceNotFoundError = QAbstractSocket::SocketAddressNotAvailableError,
NetworkError = QAbstractSocket::NetworkError,
diff --git a/src/imports/bluetooth/qdeclarativebluetoothsocket.cpp b/src/imports/bluetooth/qdeclarativebluetoothsocket.cpp
index a864910a..02c6d308 100644
--- a/src/imports/bluetooth/qdeclarativebluetoothsocket.cpp
+++ b/src/imports/bluetooth/qdeclarativebluetoothsocket.cpp
@@ -248,8 +248,6 @@ void QDeclarativeBluetoothSocket::setConnected(bool connected)
\list
\li \c{NoError}
\li \c{UnknownSocketError}
- \li \c{ConnectionRefusedError}
- \li \c{RemoteHostClosedError}
\li \c{HostNotFoundError}
\li \c{ServiceNotFoundError}
\li \c{NetworkError}
diff --git a/src/imports/bluetooth/qdeclarativebluetoothsocket_p.h b/src/imports/bluetooth/qdeclarativebluetoothsocket_p.h
index 03145522..ec63a829 100644
--- a/src/imports/bluetooth/qdeclarativebluetoothsocket_p.h
+++ b/src/imports/bluetooth/qdeclarativebluetoothsocket_p.h
@@ -72,8 +72,6 @@ public:
enum Error {
NoError = QBluetoothSocket::NoSocketError,
UnknownSocketError = QBluetoothSocket::UnknownSocketError,
- ConnectionRefusedError = QBluetoothSocket::ConnectionRefusedError,
- RemoteHostClosedError = QBluetoothSocket::RemoteHostClosedError,
HostNotFoundError = QBluetoothSocket::HostNotFoundError,
ServiceNotFoundError = QBluetoothSocket::ServiceNotFoundError,
NetworkError = QBluetoothSocket::NetworkError,
diff --git a/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp b/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
index a34f289d..e9ad44c1 100644
--- a/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+++ b/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
@@ -755,10 +755,8 @@ void tst_QBluetoothSocket::tst_error()
QCOMPARE(errorSpy.count(), 0);
const QBluetoothSocket::SocketError e = socket.error();
- QVERIFY(e != QBluetoothSocket::ConnectionRefusedError
- && e != QBluetoothSocket::HostNotFoundError
+ QVERIFY(e != QBluetoothSocket::HostNotFoundError
&& e != QBluetoothSocket::NetworkError
- && e != QBluetoothSocket::RemoteHostClosedError
&& e != QBluetoothSocket::ServiceNotFoundError
&& e != QBluetoothSocket::UnknownSocketError);
diff --git a/tests/auto/qrfcommserver/tst_qrfcommserver.cpp b/tests/auto/qrfcommserver/tst_qrfcommserver.cpp
index d8324c33..cc64826c 100644
--- a/tests/auto/qrfcommserver/tst_qrfcommserver.cpp
+++ b/tests/auto/qrfcommserver/tst_qrfcommserver.cpp
@@ -78,6 +78,8 @@ private slots:
void tst_receive_data();
void tst_receive();
+ void tst_error();
+
private:
QBluetoothLocalDevice localDevice;
};
@@ -311,6 +313,21 @@ void tst_QRfcommServer::tst_secureFlags()
QCOMPARE(server.securityFlags(), QBluetooth::Encryption);
}
+
+void tst_QRfcommServer::tst_error()
+{
+ QBluetoothServer server(QBluetoothServiceInfo::RfcommProtocol);
+ QSignalSpy errorSpy(&server, SIGNAL(error(QBluetoothServer::Error)));
+ QCOMPARE(errorSpy.count(), 0);
+ const QBluetoothServer::Error e = server.error();
+
+ QVERIFY(e != QBluetoothServer::UnknownError
+ && e != QBluetoothServer::PoweredOffError
+ && e != QBluetoothServer::InputOutputError
+ && e != QBluetoothServer::ServiceAlreadyRegisteredError
+ && e != QBluetoothServer::UnsupportedProtocolError);
+}
+
QTEST_MAIN(tst_QRfcommServer)
#include "tst_qrfcommserver.moc"