diff options
Diffstat (limited to 'tests/auto/qrfcommserver')
-rw-r--r-- | tests/auto/qrfcommserver/README.txt | 50 | ||||
-rw-r--r-- | tests/auto/qrfcommserver/qrfcommserver.pro | 12 | ||||
-rw-r--r-- | tests/auto/qrfcommserver/rfcommclient/main.cpp | 111 | ||||
-rw-r--r-- | tests/auto/qrfcommserver/rfcommclient/rfcommclient.cpp | 210 | ||||
-rw-r--r-- | tests/auto/qrfcommserver/rfcommclient/rfcommclient.h | 115 | ||||
-rw-r--r-- | tests/auto/qrfcommserver/rfcommclient/rfcommclient.pro | 7 | ||||
-rw-r--r-- | tests/auto/qrfcommserver/tst_qrfcommserver.cpp | 318 |
7 files changed, 823 insertions, 0 deletions
diff --git a/tests/auto/qrfcommserver/README.txt b/tests/auto/qrfcommserver/README.txt new file mode 100644 index 00000000..8f3d2ef8 --- /dev/null +++ b/tests/auto/qrfcommserver/README.txt @@ -0,0 +1,50 @@ +This test currently can not be run automatically. + +To make this test work, manual connections must be started from a client +machine. There are 2 options for doing this, either use the rfcommclient application in the subdirectory, +or run the test manually as described below. When using rfcommclient, start qrfcommserver first and then +start rfcommclient on the other device. There might be some timing issues, so beware. + +Steps to run this test manually: + +1. start tst_qrfcommserver + +2. Wait for test display: + +QDEBUG : tst_QRfcommServer::tst_pendingConnections(1 connection) Waiting for 1 simultaneous connections + +On a linux machine run: + +rfcomm connect hci0 00:1A:9F:92:9E:5A + +On the linux machine you will see: + +Connected /dev/rfcomm0 to 00:1A:9F:92:9E:5A on channel 1 +Press CTRL-C for hangup +Disconnected + +and the test will pass. + +3. Wait for the test to then display: + +QDEBUG : tst_QRfcommServer::tst_receive(test) Listening on RFCOMM channel: 1 + +On the linux machine run: + +rfcomm connect hci0 00:1A:9F:92:9E:5A + +You will see: + +Connected /dev/rfcomm0 to 00:1A:9F:92:9E:5A on channel 1 +Press CTRL-C for hangup + +now run: + +echo -en "hello\r\n" > /dev/rfcomm0 + +The test should then pass. + +A linux machine is not required, but simple used as an example for how to make +easy rfcomm connections. Any system that will connect to a device and rfcomm +port will work. The format of the string for the second test is very important +for the test to pass. diff --git a/tests/auto/qrfcommserver/qrfcommserver.pro b/tests/auto/qrfcommserver/qrfcommserver.pro new file mode 100644 index 00000000..75459b83 --- /dev/null +++ b/tests/auto/qrfcommserver/qrfcommserver.pro @@ -0,0 +1,12 @@ +SOURCES += tst_qrfcommserver.cpp +TARGET = tst_qrfcommserver +CONFIG += testcase + +QT = core bluetooth testlib + +symbian: TARGET.CAPABILITY = LocalServices NetworkControl WriteDeviceData + +OTHER_FILES += \ + README.txt + + diff --git a/tests/auto/qrfcommserver/rfcommclient/main.cpp b/tests/auto/qrfcommserver/rfcommclient/main.cpp new file mode 100644 index 00000000..ee6b8584 --- /dev/null +++ b/tests/auto/qrfcommserver/rfcommclient/main.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QCoreApplication> +#include <QStringList> +#include "rfcommclient.h" +#include <qbluetoothdeviceinfo.h> +//#include <qbluetoothlocaldevice.h> +//#include <QtTest/QtTest> + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + RfCommClient client; + QBluetoothLocalDevice localDevice; + MyThread mythread; + + QObject::connect(&client, SIGNAL(done()), &app, SLOT(quit())); + + QString address; + QString port; + QStringList args = QCoreApplication::arguments(); + + if (args.length() >= 2){ + address = args.at(1); + if (args.length() >= 3){ + port = args.at(2); + } + } + + // use previous value for client, stored earlier +// if (address.isEmpty()){ +// QSettings settings("QtDF", "bttennis"); +// address = settings.value("lastclient").toString(); +// } + + // hard-code address and port number if not provided + if (address.isEmpty()){ + address = "6C:9B:02:0C:91:D3"; // "J C7-2" + port = QString("20"); + } + + if (!address.isEmpty()){ + qDebug() << "Connecting to" << address << port; + QBluetoothDeviceInfo device = QBluetoothDeviceInfo(QBluetoothAddress(address), "", + QBluetoothDeviceInfo::MiscellaneousDevice); + QBluetoothServiceInfo service; + if (!port.isEmpty()) { + QBluetoothServiceInfo::Sequence protocolDescriptorList; + QBluetoothServiceInfo::Sequence protocol; + protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm)) + << QVariant::fromValue(port.toUShort()); + protocolDescriptorList.append(QVariant::fromValue(protocol)); + service.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, + protocolDescriptorList); + qDebug() << "port" << port.toUShort() << service.protocolServiceMultiplexer(); + } + else { + service.setServiceUuid(QBluetoothUuid(serviceUuid)); + } + service.setDevice(device); + // delay so that server is in waiting state + qDebug() << "Starting sleep"; + mythread.sleep(10); // seconds + qDebug() << "Finished sleeping"; + client.startClient(service); + } else { + qDebug() << "failed because address and/or port is missing " << address << port; + } + + return app.exec(); +} + diff --git a/tests/auto/qrfcommserver/rfcommclient/rfcommclient.cpp b/tests/auto/qrfcommserver/rfcommclient/rfcommclient.cpp new file mode 100644 index 00000000..f3e33f56 --- /dev/null +++ b/tests/auto/qrfcommserver/rfcommclient/rfcommclient.cpp @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "rfcommclient.h" + +#include <qbluetoothsocket.h> +#include <qbluetoothlocaldevice.h> + +#include <QtCore/QDataStream> +#include <QtCore/QByteArray> + +#include <QtCore/QStringList> + +void MyThread::sleep(int seconds) +{ + QThread::sleep(seconds); +} + +RfCommClient::RfCommClient(QObject *parent) +: QObject(parent), socket(0), stream(0), elapsed(new QTime), lagTimeout(0), state(listening) +{ + lagTimer.setSingleShot(true); + lagTimer.setInterval(5000); +} + +RfCommClient::~RfCommClient() +{ + stopClient(); +} + +bool RfCommClient::powerOn() +{ + qDebug() << __PRETTY_FUNCTION__ << ">>"; + // turn on BT in case it is not on + if (localDevice.hostMode() == QBluetoothLocalDevice::HostPoweredOff) { + connect(&localDevice, SIGNAL(hostModeStateChanged(QBluetoothLocalDevice::HostMode)), + this, SLOT(hostModeStateChanged(QBluetoothLocalDevice::HostMode))); +// connect(localDevice, SIGNAL(hostModeStateChanged(QBluetoothLocalDevice::HostMode)), +// this, SLOT(hostModeStateChanged(QBluetoothLocalDevice::HostMode))); + qDebug() << __PRETTY_FUNCTION__ << "Turning power on"; + localDevice.powerOn(); + } else { + qDebug() << __PRETTY_FUNCTION__ << "<< Power already on! returning true"; + return true; + } + qDebug() << __PRETTY_FUNCTION__ << "<< returning false"; + return false; +} + +void RfCommClient::hostModeStateChanged(QBluetoothLocalDevice::HostMode mode) +{ + qDebug() << __PRETTY_FUNCTION__ << mode; + if (mode != QBluetoothLocalDevice::HostPoweredOff) + startClient(serviceInfo); +} +//! [startClient] +void RfCommClient::startClient(const QBluetoothServiceInfo &remoteService) +{ + qDebug() << __PRETTY_FUNCTION__ << ">>"; + serviceInfo = remoteService; + + // make sure preconditions are met + if (!powerOn() || socket) { + qDebug() << __PRETTY_FUNCTION__ << "<< power not on or socket already exists!"; + return; + } + + // Connect to service + if (state == listening) + state = pendingConnections; + socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket); + qDebug() << "Create socket"; + socket->connectToService(remoteService); + qDebug() << "ConnecttoService done"; + + connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket())); + connect(socket, SIGNAL(connected()), this, SLOT(connected())); + connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); + connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(error(QBluetoothSocket::SocketError))); + + qDebug() << __PRETTY_FUNCTION__ << "<<"; +} +//! [startClient] + +//! [stopClient] +void RfCommClient::stopClient() +{ + qDebug() << __PRETTY_FUNCTION__ << "closing client!"; + + lagTimer.stop(); + + delete stream; + stream = 0; + + socket->deleteLater(); + socket = 0; +} +//! [stopClient] + +//! [socketDisconnected] +void RfCommClient::socketDisconnected() +{ + // Note: it seems that the "disconnected" signal is not emitted by the socket, so this never gets called + qDebug() << __PRETTY_FUNCTION__ << "Got socketDisconnected"; + emit disconnected(); + stopClient(); + + // now reconnect and send text string + startClient(serviceInfo); + connect(&lagTimer, SIGNAL(timeout()), this, SLOT(sendText())); + lagTimer.start(); +} +//! [socketDisconnected] + +//! [readSocket] +void RfCommClient::readSocket() +{ + if (!socket) + return; + QString str; + + while (socket->bytesAvailable()) { + *stream >> str; + } + qDebug() << __PRETTY_FUNCTION__ << "socket read=" << str; +} +//! [readSocket] + +//! [connected] +void RfCommClient::connected() +{ + qDebug() << __PRETTY_FUNCTION__ << "connected to " << socket->peerName(); + stream = new QDataStream(socket); + emit connected(socket->peerName()); +} +//! [connected] + +void RfCommClient::error(QBluetoothSocket::SocketError err) +{ + qDebug() << __PRETTY_FUNCTION__ << "Got socket error" << err; + // remote side has closed the socket, effectively disconnecting it + if (state == pendingConnections) { + state = dataTransfer; + emit disconnected(); + stopClient(); + + // now reconnect and send text string + MyThread mythread; + mythread.sleep(5); + startClient(serviceInfo); + connect(&lagTimer, SIGNAL(timeout()), this, SLOT(sendText())); + lagTimer.start(); + } else { + qDebug() << __PRETTY_FUNCTION__ << "emitting done"; + emit done(); + } +} + +void RfCommClient::sendText() +{ + qDebug() << __PRETTY_FUNCTION__ << ">>"; + lagTimer.stop(); + if (stream) { + buffer.clear(); + buffer.append(QString("hello\r\n")); // ideally we would use QDataStream here + socket->write(buffer); + } + // terminate client program + emit done(); + qDebug() << __PRETTY_FUNCTION__ << "<< Terminating program"; +} + + diff --git a/tests/auto/qrfcommserver/rfcommclient/rfcommclient.h b/tests/auto/qrfcommserver/rfcommclient/rfcommclient.h new file mode 100644 index 00000000..6825576a --- /dev/null +++ b/tests/auto/qrfcommserver/rfcommclient/rfcommclient.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef RFCOMMCLIENT_H +#define RFCOMMCLIENT_H + +#include <qbluetoothserviceinfo.h> +#include <qbluetoothsocket.h> + +#include <QtCore/QObject> +#include <QtCore/QTime> +#include <QtCore/QTimer> +#include <QBluetoothLocalDevice.h> +#include <QThread> + +static const QLatin1String serviceUuid("e8e10f95-1a70-4b27-9ccf-02010264e9c9"); + +class QBluetoothSocket; + +class QDataStream; + +class MyThread : public QThread +{ +public: + void sleep(int seconds); +}; + + +//! [declaration] +class RfCommClient : public QObject +{ + Q_OBJECT + + enum States { + listening, + pendingConnections, + dataTransfer + }; +public: + explicit RfCommClient(QObject *parent = 0); + ~RfCommClient(); + + void startClient(const QBluetoothServiceInfo &remoteService); + void stopClient(); + +public slots: + void error(QBluetoothSocket::SocketError); + +signals: + void connected(const QString &name); + void disconnected(); + void done(); + void lag(int ms); + +private slots: + void readSocket(); + void connected(); + void sendText(); + void socketDisconnected(); + void hostModeStateChanged(QBluetoothLocalDevice::HostMode); + +private: + bool powerOn(); + +private: + QBluetoothSocket *socket; + QDataStream *stream; + QByteArray buffer; + QBluetoothServiceInfo serviceInfo; + QBluetoothLocalDevice localDevice; + QTime *elapsed; + QTimer lagTimer; + int lagTimeout; + RfCommClient::States state; +}; +//! [declaration] + +#endif // RFCOMMCLIENT_H diff --git a/tests/auto/qrfcommserver/rfcommclient/rfcommclient.pro b/tests/auto/qrfcommserver/rfcommclient/rfcommclient.pro new file mode 100644 index 00000000..7a1834c6 --- /dev/null +++ b/tests/auto/qrfcommserver/rfcommclient/rfcommclient.pro @@ -0,0 +1,7 @@ +TARGET = rfcommclient +SOURCES += main.cpp rfcommclient.cpp +HEADERS += rfcommclient.h + +QT = core + +symbian: TARGET.CAPABILITY = LocalServices NetworkControl WriteDeviceData diff --git a/tests/auto/qrfcommserver/tst_qrfcommserver.cpp b/tests/auto/qrfcommserver/tst_qrfcommserver.cpp new file mode 100644 index 00000000..df2a10bc --- /dev/null +++ b/tests/auto/qrfcommserver/tst_qrfcommserver.cpp @@ -0,0 +1,318 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QDebug> + +#include <qrfcommserver.h> +#include <qbluetoothsocket.h> +#include <qbluetoothlocaldevice.h> + +Q_DECLARE_METATYPE(QBluetooth::SecurityFlags); + +// Max time to wait for connection +static const int MaxConnectTime = 60 * 1000; // 1 minute in ms + +class tst_QRfcommServer : public QObject +{ + Q_OBJECT + +public: + tst_QRfcommServer(); + ~tst_QRfcommServer(); + +private slots: + void initTestCase(); + + 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(); + +private: + QBluetoothLocalDevice localDevice; +}; + +tst_QRfcommServer::tst_QRfcommServer() +{ +} + +tst_QRfcommServer::~tst_QRfcommServer() +{ +} + +void tst_QRfcommServer::initTestCase() +{ + qRegisterMetaType<QBluetooth::SecurityFlags>("QBluetooth::SecurityFlags"); + + // 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); + } + QBluetoothLocalDevice::HostMode hostMode= localDevice.hostMode(); + QVERIFY(hostMode == QBluetoothLocalDevice::HostConnectable + || hostMode == QBluetoothLocalDevice::HostDiscoverable + || hostMode == QBluetoothLocalDevice::HostDiscoverableLimitedInquiry); +} + +void tst_QRfcommServer::tst_construction() +{ + { + QRfcommServer server; + + QVERIFY(!server.isListening()); + QCOMPARE(server.maxPendingConnections(), 1); + QVERIFY(!server.hasPendingConnections()); + QVERIFY(server.nextPendingConnection() == 0); + QVERIFY(server.serverAddress().isNull()); + QCOMPARE(server.serverPort(), quint16(0)); + } +} + +void tst_QRfcommServer::tst_listen_data() +{ + QTest::addColumn<QBluetoothAddress>("address"); + QTest::addColumn<quint16>("port"); + + QTest::newRow("default") << QBluetoothAddress() << quint16(0); +#ifdef Q_OS_SYMBIAN + //use localdevice address for listen address. + QTest::newRow("specified address") << localDevice.address() << quint16(0); + QTest::newRow("specified port") << QBluetoothAddress() << quint16(20); + QTest::newRow("specified address/port") << localDevice.address() << quint16(27); // port 21 returns KErrInUse +#else + 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); +#endif +} + +void tst_QRfcommServer::tst_listen() +{ + QFETCH(QBluetoothAddress, address); + QFETCH(quint16, port); + + { + QRfcommServer server; + 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); + + QCOMPARE(server.maxPendingConnections(), 1); + + QVERIFY(!server.hasPendingConnections()); + QVERIFY(server.nextPendingConnection() == 0); + + server.close(); + QTest::qWait(2000); + + QVERIFY(!server.isListening()); + + QVERIFY(server.serverAddress().isNull()); + QVERIFY(server.serverPort() == 0); + + QVERIFY(server.hasPendingConnections() == false); + QVERIFY(server.nextPendingConnection() == 0); + } +} + +void tst_QRfcommServer::tst_pendingConnections_data() +{ + QTest::addColumn<int>("maxConnections"); + + QTest::newRow("1 connection") << 1; + //QTest::newRow("2 connections") << 2; +} + +void tst_QRfcommServer::tst_pendingConnections() +{ + QFETCH(int, maxConnections); + + QRfcommServer server; + QBluetoothLocalDevice localDev; + + 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."; + + QSignalSpy connectionSpy(&server, SIGNAL(newConnection())); + + 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; + } + + 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); + + QRfcommServer server; + QBluetoothLocalDevice localDev; + + 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; + } + + QVERIFY(!readyReadSpy.isEmpty()); + + const QByteArray data = socket->readAll(); + + QCOMPARE(data, expected); +} + +void tst_QRfcommServer::tst_secureFlags() +{ + QRfcommServer server; + + server.setSecurityFlags(QBluetooth::NoSecurity); + QCOMPARE(server.securityFlags(), QBluetooth::NoSecurity); + + server.setSecurityFlags(QBluetooth::Encryption); + QCOMPARE(server.securityFlags(), QBluetooth::Encryption); +} + +QTEST_MAIN(tst_QRfcommServer) + +#include "tst_qrfcommserver.moc" |