diff options
author | Alex Blasche <alexander.blasche@digia.com> | 2014-02-28 15:15:03 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-01 20:09:28 +0100 |
commit | 17d38319d205fd186ffbb638e53e43fde011c753 (patch) | |
tree | 7aac0462c81781547e797060e002c72f43f72537 | |
parent | 6c90b603cff92834ac7f58610fc6982ec801f2fd (diff) |
Fix qrfcomm unit test
The patch also aligns the error behavior of QBluetoothServer::listen()
across the various platforms.
Task-number: QTBUG-22017
Change-Id: Ic81808c94d060ca07bd125afa842452e53efaec7
Reviewed-by: Nedim Hadzic <nedimhadzija@gmail.com>
Reviewed-by: Fabian Bumberger <fbumberger@rim.com>
-rw-r--r-- | src/bluetooth/qbluetoothserver_android.cpp | 20 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothserver_bluez.cpp | 18 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothserver_p.cpp | 7 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothserver_qnx.cpp | 17 | ||||
-rw-r--r-- | tests/auto/qrfcommserver/qrfcommserver.pro | 1 | ||||
-rw-r--r-- | tests/auto/qrfcommserver/tst_qrfcommserver.cpp | 303 |
6 files changed, 158 insertions, 208 deletions
diff --git a/src/bluetooth/qbluetoothserver_android.cpp b/src/bluetooth/qbluetoothserver_android.cpp index c7c798d3..f90c540e 100644 --- a/src/bluetooth/qbluetoothserver_android.cpp +++ b/src/bluetooth/qbluetoothserver_android.cpp @@ -127,9 +127,20 @@ void QBluetoothServer::close() bool QBluetoothServer::listen(const QBluetoothAddress &localAdapter, quint16 port) { + Q_D(QBluetoothServer); + if (serverType() != QBluetoothServiceInfo::RfcommProtocol) { + d->m_lastError = UnsupportedProtocolError; + emit error(d->m_lastError); + return false; + } + const QList<QBluetoothHostInfo> localDevices = QBluetoothLocalDevice::allDevices(); - if (!localDevices.count()) + if (!localDevices.count()) { + qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth"; + d->m_lastError = QBluetoothServer::UnknownError; + emit error(d->m_lastError); return false; //no Bluetooth device + } if (!localAdapter.isNull()) { bool found = false; @@ -146,13 +157,6 @@ bool QBluetoothServer::listen(const QBluetoothAddress &localAdapter, quint16 por } } - Q_D(QBluetoothServer); - if (serverType() != QBluetoothServiceInfo::RfcommProtocol) { - d->m_lastError = UnsupportedProtocolError; - emit error(d->m_lastError); - return false; - } - if (d->isListening()) return false; diff --git a/src/bluetooth/qbluetoothserver_bluez.cpp b/src/bluetooth/qbluetoothserver_bluez.cpp index b78fb526..1ee055de 100644 --- a/src/bluetooth/qbluetoothserver_bluez.cpp +++ b/src/bluetooth/qbluetoothserver_bluez.cpp @@ -42,6 +42,7 @@ #include "qbluetoothserver.h" #include "qbluetoothserver_p.h" #include "qbluetoothsocket.h" +#include "qbluetoothlocaldevice.h" #include <QtCore/QLoggingCategory> #include <QtCore/QSocketNotifier> @@ -110,6 +111,23 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port) return false; //already listening, nothing to do } + QBluetoothLocalDevice device(address); + if (!device.isValid()) { + qCWarning(QT_BT_BLUEZ) << "Device does not support Bluetooth or" + << address.toString() << "is not a valid local adapter"; + d->m_lastError = QBluetoothServer::UnknownError; + emit error(d->m_lastError); + return false; + } + + QBluetoothLocalDevice::HostMode hostMode = device.hostMode(); + if (hostMode == QBluetoothLocalDevice::HostPoweredOff) { + d->m_lastError = QBluetoothServer::PoweredOffError; + emit error(d->m_lastError); + qCWarning(QT_BT_BLUEZ) << "Bluetooth device is powered off"; + return false; + } + int sock = d->socket->socketDescriptor(); if (sock < 0) { /* Negative socket descriptor is not always an error case diff --git a/src/bluetooth/qbluetoothserver_p.cpp b/src/bluetooth/qbluetoothserver_p.cpp index 213d73f1..d9efcf2f 100644 --- a/src/bluetooth/qbluetoothserver_p.cpp +++ b/src/bluetooth/qbluetoothserver_p.cpp @@ -46,12 +46,17 @@ QT_BEGIN_NAMESPACE QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType) - : serverType(sType), m_lastError(QBluetoothServer::NoError) + : maxPendingConnections(1), serverType(sType), m_lastError(QBluetoothServer::NoError) { + if (sType == QBluetoothServiceInfo::RfcommProtocol) + socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol); + else + socket = new QBluetoothSocket(QBluetoothServiceInfo::L2capProtocol); } QBluetoothServerPrivate::~QBluetoothServerPrivate() { + delete socket; } void QBluetoothServer::close() diff --git a/src/bluetooth/qbluetoothserver_qnx.cpp b/src/bluetooth/qbluetoothserver_qnx.cpp index 5dfacfb2..63e92f4f 100644 --- a/src/bluetooth/qbluetoothserver_qnx.cpp +++ b/src/bluetooth/qbluetoothserver_qnx.cpp @@ -163,6 +163,23 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port) return false; } + QBluetoothLocalDevice device(address); + if (!device.isValid()) { + qCWarning(QT_BT_QNX) << "Device does not support Bluetooth or" + << address.toString() << "is not a valid local adapter"; + d->m_lastError = QBluetoothServer::UnknownError; + emit error(d->m_lastError); + return false; + } + + QBluetoothLocalDevice::HostMode hostMode= device.hostMode(); + if (hostMode == QBluetoothLocalDevice::HostPoweredOff) { + d->m_lastError = QBluetoothServer::PoweredOffError; + emit error(d->m_lastError); + qCWarning(QT_BT_QNX) << "Bluetooth device is powered off"; + return false; + } + // listen has already been called before if (!d->socket) d->socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol); diff --git a/tests/auto/qrfcommserver/qrfcommserver.pro b/tests/auto/qrfcommserver/qrfcommserver.pro index b6472ca4..546b9ccb 100644 --- a/tests/auto/qrfcommserver/qrfcommserver.pro +++ b/tests/auto/qrfcommserver/qrfcommserver.pro @@ -7,5 +7,4 @@ QT = core concurrent bluetooth testlib OTHER_FILES += \ README.txt -CONFIG += insignificant_test # QTBUG-22017 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qrfcommserver/tst_qrfcommserver.cpp b/tests/auto/qrfcommserver/tst_qrfcommserver.cpp index cc64826c..068e8fdc 100644 --- a/tests/auto/qrfcommserver/tst_qrfcommserver.cpp +++ b/tests/auto/qrfcommserver/tst_qrfcommserver.cpp @@ -49,7 +49,11 @@ QT_USE_NAMESPACE -Q_DECLARE_METATYPE(QBluetooth::SecurityFlags); +//same uuid as tests/bttestui +#define TEST_SERVICE_UUID "e8e10f95-1a70-4b27-9ccf-02010264e9c8" + +Q_DECLARE_METATYPE(QBluetooth::SecurityFlags) +Q_DECLARE_METATYPE(QBluetoothServer::Error) // Max time to wait for connection static const int MaxConnectTime = 60 * 1000; // 1 minute in ms @@ -64,24 +68,18 @@ public: private slots: void initTestCase(); + void cleanupTestCase(); void tst_construction(); - void tst_listen_data(); - void tst_listen(); - - void tst_secureFlags(); - - void tst_pendingConnections_data(); - void tst_pendingConnections(); - void tst_receive_data(); void tst_receive(); - void tst_error(); + void setHostMode(const QBluetoothAddress &localAdapter, QBluetoothLocalDevice::HostMode newHostMode); private: QBluetoothLocalDevice localDevice; + QBluetoothLocalDevice::HostMode initialHostMode; }; tst_QRfcommServer::tst_QRfcommServer() @@ -92,242 +90,151 @@ tst_QRfcommServer::~tst_QRfcommServer() { } -void tst_QRfcommServer::initTestCase() +void tst_QRfcommServer::setHostMode(const QBluetoothAddress &localAdapter, + QBluetoothLocalDevice::HostMode newHostMode) { - qRegisterMetaType<QBluetooth::SecurityFlags>("QBluetooth::SecurityFlags"); + QBluetoothLocalDevice device(localAdapter); + QSignalSpy hostModeSpy(&device, SIGNAL(hostModeStateChanged(QBluetoothLocalDevice::HostMode))); + + if (!device.isValid()) + return; + + if (device.hostMode() == newHostMode) + return; + + //We distinguish powerOn() and setHostMode(HostConnectable) because + //Android uses different permission levels, we want to avoid interaction with user + //which implies usage of powerOn -> unfortunately powerOn() is not equivalent to HostConnectable + //Unfortunately the discoverable mode always requires a user confirmation + switch (newHostMode) { + case QBluetoothLocalDevice::HostPoweredOff: + case QBluetoothLocalDevice::HostDiscoverable: + case QBluetoothLocalDevice::HostDiscoverableLimitedInquiry: + device.setHostMode(newHostMode); + break; + case QBluetoothLocalDevice::HostConnectable: + device.powerOn(); + break; + } - if (!QBluetoothLocalDevice::allDevices().count()) - QSKIP("Skipping test due to missing Bluetooth device"); - - // turn on BT in case it is not on - if (localDevice.hostMode() == QBluetoothLocalDevice::HostPoweredOff) { - QSignalSpy hostModeSpy(&localDevice, SIGNAL(hostModeStateChanged(QBluetoothLocalDevice::HostMode))); - QVERIFY(hostModeSpy.isEmpty()); - localDevice.powerOn(); - int connectTime = 5000; // ms - while (hostModeSpy.count() < 1 && connectTime > 0) { - QTest::qWait(500); - connectTime -= 500; - } - QVERIFY(hostModeSpy.count() > 0); + int connectTime = 5000; // ms + while (hostModeSpy.count() < 1 && connectTime > 0) { + QTest::qWait(500); + connectTime -= 500; } - QBluetoothLocalDevice::HostMode hostMode= localDevice.hostMode(); - QVERIFY(hostMode == QBluetoothLocalDevice::HostConnectable - || hostMode == QBluetoothLocalDevice::HostDiscoverable - || hostMode == QBluetoothLocalDevice::HostDiscoverableLimitedInquiry); } -void tst_QRfcommServer::tst_construction() +void tst_QRfcommServer::initTestCase() { - { - QBluetoothServer server(QBluetoothServiceInfo::RfcommProtocol); + qRegisterMetaType<QBluetooth::SecurityFlags>("QBluetooth::SecurityFlags"); + qRegisterMetaType<QBluetoothServer::Error>("QBluetoothServer::Error"); - QVERIFY(!server.isListening()); - QCOMPARE(server.maxPendingConnections(), 1); - QVERIFY(!server.hasPendingConnections()); - QVERIFY(server.nextPendingConnection() == 0); - QVERIFY(server.serverAddress().isNull()); - QCOMPARE(server.serverPort(), quint16(0)); - } -} + QBluetoothLocalDevice device; + if (!device.isValid()) + return; -void tst_QRfcommServer::tst_listen_data() -{ - QTest::addColumn<QBluetoothAddress>("address"); - QTest::addColumn<quint16>("port"); + initialHostMode = device.hostMode(); + + setHostMode(device.address(), QBluetoothLocalDevice::HostConnectable); + + QBluetoothLocalDevice::HostMode hostMode= localDevice.hostMode(); - QTest::newRow("default") << QBluetoothAddress() << quint16(0); - QTest::newRow("specified address") << QBluetoothAddress("00:11:B1:08:AD:B8") << quint16(0); - QTest::newRow("specified port") << QBluetoothAddress() << quint16(10); - QTest::newRow("specified address/port") << QBluetoothAddress("00:11:B1:08:AD:B8") << quint16(10); + QVERIFY(hostMode != QBluetoothLocalDevice::HostPoweredOff); } -void tst_QRfcommServer::tst_listen() +void tst_QRfcommServer::cleanupTestCase() { - QFETCH(QBluetoothAddress, address); - QFETCH(quint16, port); + QBluetoothLocalDevice device; + setHostMode(device.address(), initialHostMode); +} +void tst_QRfcommServer::tst_construction() +{ { QBluetoothServer server(QBluetoothServiceInfo::RfcommProtocol); - qDebug() << "tst_listen() address=" << address.toString() << "port=" << port; - bool result = server.listen(address, port); - QTest::qWait(1000); - - QVERIFY(result); - QVERIFY(server.isListening()); - - if (!address.isNull()) - QCOMPARE(server.serverAddress(), address); - - qDebug()<<"Server Port="<<server.serverPort(); - if (port != 0) - QCOMPARE(server.serverPort(), port); - else - QVERIFY(server.serverPort() != 0); + QVERIFY(!server.isListening()); QCOMPARE(server.maxPendingConnections(), 1); - QVERIFY(!server.hasPendingConnections()); QVERIFY(server.nextPendingConnection() == 0); + QCOMPARE(server.error(), QBluetoothServer::NoError); + QCOMPARE(server.serverType(), QBluetoothServiceInfo::RfcommProtocol); + } - server.close(); - QTest::qWait(2000); + { + QBluetoothServer server(QBluetoothServiceInfo::L2capProtocol); QVERIFY(!server.isListening()); - - QVERIFY(server.serverAddress().isNull()); - QVERIFY(server.serverPort() == 0); - - QVERIFY(server.hasPendingConnections() == false); + QCOMPARE(server.maxPendingConnections(), 1); + QVERIFY(!server.hasPendingConnections()); QVERIFY(server.nextPendingConnection() == 0); + QCOMPARE(server.error(), QBluetoothServer::NoError); + QCOMPARE(server.serverType(), QBluetoothServiceInfo::L2capProtocol); } } -void tst_QRfcommServer::tst_pendingConnections_data() +void tst_QRfcommServer::tst_receive_data() { - QTest::addColumn<int>("maxConnections"); - - QTest::newRow("1 connection") << 1; - //QTest::newRow("2 connections") << 2; + QTest::addColumn<QBluetoothLocalDevice::HostMode>("hostmode"); + QTest::newRow("offline mode") << QBluetoothLocalDevice::HostPoweredOff; + QTest::newRow("online mode") << QBluetoothLocalDevice::HostConnectable; } -void tst_QRfcommServer::tst_pendingConnections() +void tst_QRfcommServer::tst_receive() { - QFETCH(int, maxConnections); + QFETCH(QBluetoothLocalDevice::HostMode, hostmode); - QBluetoothServer server(QBluetoothServiceInfo::RfcommProtocol); QBluetoothLocalDevice localDev; + const QBluetoothAddress address = localDev.address(); - QBluetoothAddress address = localDev.address(); - server.setMaxPendingConnections(maxConnections); - bool result = server.listen(address, 20); // port == 20 - QTest::qWait(1000); - - QVERIFY(result); - QVERIFY(server.isListening()); - - qDebug() << "tst_pendingConnections() Listening on address " << address.toString() << "RFCOMM channel:" << server.serverPort(); - - QCOMPARE(server.maxPendingConnections(), maxConnections); - - QVERIFY(!server.hasPendingConnections()); - QVERIFY(server.nextPendingConnection() == 0); - - /* wait for maxConnections simultaneous connections */ - qDebug() << "Waiting for" << maxConnections << "simultaneous connections."; + bool localDeviceAvailable = localDev.isValid(); - QSignalSpy connectionSpy(&server, SIGNAL(newConnection())); + if (localDeviceAvailable) { + setHostMode(address, hostmode); - int connectTime = MaxConnectTime; - while (connectionSpy.count() < maxConnections && connectTime > 0) { - QTest::qWait(1000); - connectTime -= 1000; - } - - QList<QBluetoothSocket *> sockets; - while (server.hasPendingConnections()) - sockets.append(server.nextPendingConnection()); - - QCOMPARE(connectionSpy.count(), maxConnections); - QCOMPARE(sockets.count(), maxConnections); - - foreach (QBluetoothSocket *socket, sockets) { - qDebug() << socket->state(); - QVERIFY(socket->state() == QBluetoothSocket::ConnectedState); - QVERIFY(socket->openMode() == QIODevice::ReadWrite); - } - - QVERIFY(!server.hasPendingConnections()); - QVERIFY(server.nextPendingConnection() == 0); - - while (!sockets.isEmpty()) { - QBluetoothSocket *socket = sockets.takeFirst(); - socket->close(); - delete socket; + if (hostmode == QBluetoothLocalDevice::HostPoweredOff) + QCOMPARE(localDevice.hostMode(), hostmode); + else + QVERIFY(localDevice.hostMode() != QBluetoothLocalDevice::HostPoweredOff); } - - server.close(); -} - -void tst_QRfcommServer::tst_receive_data() -{ - QTest::addColumn<QByteArray>("expected"); - - QTest::newRow("test") << QByteArray("hello\r\n"); -} - -void tst_QRfcommServer::tst_receive() -{ - QFETCH(QByteArray, expected); - QBluetoothServer server(QBluetoothServiceInfo::RfcommProtocol); - QBluetoothLocalDevice localDev; + QSignalSpy errorSpy(&server, SIGNAL(error(QBluetoothServer::Error))); - QBluetoothAddress address = localDev.address(); bool result = server.listen(address, 20); // port == 20 QTest::qWait(1000); - QVERIFY(result); - QVERIFY(server.isListening()); - - qDebug() << "Listening on address " << address.toString() << "RFCOMM channel:" << server.serverPort(); - - int connectTime = MaxConnectTime; - while (!server.hasPendingConnections() && connectTime > 0) { - QTest::qWait(1000); - connectTime -= 1000; - } - - QVERIFY(server.hasPendingConnections()); - - qDebug() << "Got connection"; - - QBluetoothSocket *socket = server.nextPendingConnection(); - - QVERIFY(socket->state() == QBluetoothSocket::ConnectedState); - QVERIFY(socket->openMode() == QIODevice::ReadWrite); - - QSignalSpy readyReadSpy(socket, SIGNAL(readyRead())); - - int readyReadTime = 60000; - while (readyReadSpy.isEmpty() && readyReadTime > 0) { - QTest::qWait(1000); - readyReadTime -= 1000; + if (!result) { + QCOMPARE(server.serverAddress(), QBluetoothAddress()); + QCOMPARE(server.serverPort(), quint16(0)); + QVERIFY(errorSpy.count() > 0); + QVERIFY(!server.isListening()); + if (!localDeviceAvailable) { + QVERIFY(server.error() != QBluetoothServer::NoError); + } else { + //local device but poweredOff + QCOMPARE(server.error(), QBluetoothServer::PoweredOffError); + } + return; } - QVERIFY(!readyReadSpy.isEmpty()); - - const QByteArray data = socket->readAll(); - - QCOMPARE(data, expected); -} - -void tst_QRfcommServer::tst_secureFlags() -{ - QBluetoothServer server(QBluetoothServiceInfo::RfcommProtocol); + QVERIFY(result); - server.setSecurityFlags(QBluetooth::NoSecurity); - QCOMPARE(server.securityFlags(), QBluetooth::NoSecurity); + QVERIFY(QBluetoothLocalDevice::allDevices().count()); + QCOMPARE(server.error(), QBluetoothServer::NoError); + QCOMPARE(server.serverAddress(), address); + QCOMPARE(server.serverPort(), quint16(20)); + QVERIFY(server.isListening()); + QVERIFY(!server.hasPendingConnections()); - server.setSecurityFlags(QBluetooth::Encryption); - QCOMPARE(server.securityFlags(), QBluetooth::Encryption); + server.close(); + QCOMPARE(server.error(), QBluetoothServer::NoError); + QVERIFY(server.serverAddress() == address || server.serverAddress() == QBluetoothAddress()); + QVERIFY(server.serverPort() == 0); + QVERIFY(!server.isListening()); + QVERIFY(!server.hasPendingConnections()); } -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" |